


'''simple docstring'''



import gc
import os
import tempfile
import unittest

import torch
import torch.nn as nn
import torch.nn.functional as F
from transformers import CLIPTextConfig, CLIPTextModel, CLIPTokenizer

from diffusers import AutoencoderKL, DDIMScheduler, StableDiffusionPipeline, UNetaDConditionModel
from diffusers.loaders import AttnProcsLayers, LoraLoaderMixin
from diffusers.models.attention_processor import (
    Attention,
    AttnProcessor,
    AttnProcessor2_0,
    LoRAAttnProcessor,
    LoRAAttnProcessor2_0,
    LoRAXFormersAttnProcessor,
    XFormersAttnProcessor,
)
from diffusers.utils import TEXT_ENCODER_ATTN_MODULE, floats_tensor, torch_device




def 	_a	(						_lowercase					:	nn.Module  ):





     '''simple docstring'''






     __UpperCAmelCase	: Dict  							=			{}
     for name in unet.attn_processors.keys():
          __UpperCAmelCase	: int  							=			None if name.endswith('''attn1.processor'''  ) else unet.config.cross_attention_dim
          if name.startswith('''mid_block'''  ):
               __UpperCAmelCase	: List[str]  							=			unet.config.block_out_channels[-1]
          elif name.startswith('''up_blocks'''  ):
               __UpperCAmelCase	: Optional[int]  							=			int(name[len('''up_blocks.'''  )]  )
               __UpperCAmelCase	: Dict  							=			list(reversed(unet.config.block_out_channels  )  )[block_id]
          elif name.startswith('''down_blocks'''  ):
               __UpperCAmelCase	: Optional[Any]  							=			int(name[len('''down_blocks.'''  )]  )
               __UpperCAmelCase	: List[str]  							=			unet.config.block_out_channels[block_id]
          __UpperCAmelCase	: Optional[int]  							=			(
              LoRAAttnProcessor2_0 if hasattr(_lowercase			,					'''scaled_dot_product_attention'''  ) else LoRAAttnProcessor
          )
          __UpperCAmelCase	: Union[str, Any]  							=			lora_attn_processor_class(
              hidden_size=_lowercase			,					cross_attention_dim=_lowercase  )
     __UpperCAmelCase	: Optional[Any]  							=			AttnProcsLayers(_lowercase  )
     return lora_attn_procs, unet_lora_layers




def 	_a	(						_lowercase					:	nn.Module  ):





     '''simple docstring'''






     __UpperCAmelCase	: Dict  							=			{}
     __UpperCAmelCase	: int  							=			(
         LoRAAttnProcessor2_0 if hasattr(_lowercase			,					'''scaled_dot_product_attention'''  ) else LoRAAttnProcessor
     )
     for name, module in text_encoder.named_modules():
          if name.endswith(_lowercase  ):
               __UpperCAmelCase	: List[str]  							=			lora_attn_processor_class(
                   hidden_size=module.out_proj.out_features			,					cross_attention_dim=_lowercase  )
     return text_lora_attn_procs




def 	_a	(						_lowercase					:	nn.Module  ):





     '''simple docstring'''






     __UpperCAmelCase	: List[str]  							=			create_text_encoder_lora_attn_procs(_lowercase  )
     __UpperCAmelCase	: List[Any]  							=			AttnProcsLayers(_lowercase  )
     return text_encoder_lora_layers




def 	_a	(						_lowercase					:	Optional[Any]			,					_lowercase					:	List[str]=False  ):





     '''simple docstring'''






     for _, attn_proc in text_lora_attn_procs.items():
          # set up.weights
          for layer_name, layer_module in attn_proc.named_modules():
               if layer_name.endswith('''_lora'''  ):
                    __UpperCAmelCase	: str  							=			(
                        torch.randn_like(layer_module.up.weight  )
                        if randn_weight
                        else torch.zeros_like(layer_module.up.weight  )
                    )
                    __UpperCAmelCase	: str  							=			torch.nn.Parameter(_lowercase  )



class 	a				(		unittest.TestCase       ):


     """simple docstring"""






     def  lowerCamelCase__ (				self     :		List[str]			)						->							List[str]:
          torch.manual_seed(0			)
          __UpperCAmelCase	: Optional[Any]  							=			UNetaDConditionModel(
              block_out_channels=(32, 64)							, layers_per_block=2							, sample_size=32							, in_channels=4							, out_channels=4							, down_block_types=('''DownBlock2D''', '''CrossAttnDownBlock2D''')							, up_block_types=('''CrossAttnUpBlock2D''', '''UpBlock2D''')							, cross_attention_dim=32							, )
          __UpperCAmelCase	: int  							=			DDIMScheduler(
              beta_start=0.00_085							, beta_end=0.012							, beta_schedule='''scaled_linear'''							, clip_sample=A_							, set_alpha_to_one=A_							, steps_offset=1							, )
          torch.manual_seed(0			)
          __UpperCAmelCase	: Tuple  							=			AutoencoderKL(
              block_out_channels=[32, 64]							, in_channels=3							, out_channels=3							, down_block_types=['''DownEncoderBlock2D''', '''DownEncoderBlock2D''']							, up_block_types=['''UpDecoderBlock2D''', '''UpDecoderBlock2D''']							, latent_channels=4							, )
          __UpperCAmelCase	: Optional[int]  							=			CLIPTextConfig(
              bos_token_id=0							, eos_token_id=2							, hidden_size=32							, intermediate_size=37							, layer_norm_eps=1E-05							, num_attention_heads=4							, num_hidden_layers=5							, pad_token_id=1							, vocab_size=1000							, )
          __UpperCAmelCase	: List[str]  							=			CLIPTextModel(A_			)
          __UpperCAmelCase	: str  							=			CLIPTokenizer.from_pretrained('''hf-internal-testing/tiny-random-clip'''			)

          __UpperCAmelCase							,   __UpperCAmelCase	: List[str]  							=			create_unet_lora_layers(A_			)
          __UpperCAmelCase	: Any  							=			create_text_encoder_lora_layers(A_			)

          __UpperCAmelCase	: str  							=			{
              '''unet''': unet,
              '''scheduler''': scheduler,
              '''vae''': vae,
              '''text_encoder''': text_encoder,
              '''tokenizer''': tokenizer,
              '''safety_checker''': None,
              '''feature_extractor''': None,
          }
          __UpperCAmelCase	: Union[str, Any]  							=			{
              '''unet_lora_layers''': unet_lora_layers,
              '''text_encoder_lora_layers''': text_encoder_lora_layers,
              '''unet_lora_attn_procs''': unet_lora_attn_procs,
          }
          return pipeline_components, lora_components

     def  lowerCamelCase__ (				self     :		Optional[int]			)						->							Dict:
          __UpperCAmelCase	: Any  							=			1
          __UpperCAmelCase	: Any  							=			10
          __UpperCAmelCase	: Optional[int]  							=			4
          __UpperCAmelCase	: List[Any]  							=			(32, 32)

          __UpperCAmelCase	: List[str]  							=			torch.manual_seed(0			)
          __UpperCAmelCase	: Optional[Any]  							=			floats_tensor((batch_size, num_channels) + sizes			)
          __UpperCAmelCase	: Dict  							=			torch.randint(1							, A_							, size=(batch_size, sequence_length)							, generator=A_			)

          __UpperCAmelCase	: Tuple  							=			{
              '''prompt''': '''A painting of a squirrel eating a burger''',
              '''generator''': generator,
              '''num_inference_steps''': 2,
              '''guidance_scale''': 6.0,
              '''output_type''': '''numpy''',
          }

          return noise, input_ids, pipeline_inputs

          # copied from: https://colab.research.google.com/gist/sayakpaul/df2ef6e1ae6d8c10a49d859883b10860/scratchpad.ipynb

     def  lowerCamelCase__ (				self     :		Dict			)						->							List[str]:
          __UpperCAmelCase	: str  							=			77

          __UpperCAmelCase	: int  							=			torch.randint(2							, 56							, size=(1, max_seq_length)							, generator=torch.manual_seed(0			)			)

          __UpperCAmelCase	: Union[str, Any]  							=			{}
          __UpperCAmelCase	: Optional[Any]  							=			inputs
          return prepared_inputs

     def  lowerCamelCase__ (				self     :		List[str]							, snake_case     :		List[str]			)						->							List[str]:
          __UpperCAmelCase							,   __UpperCAmelCase	: int  							=			self.get_dummy_components()
          LoraLoaderMixin.save_lora_weights(
              save_directory=A_							, unet_lora_layers=lora_components['''unet_lora_layers''']							, text_encoder_lora_layers=lora_components['''text_encoder_lora_layers''']							, )
          self.assertTrue(os.path.isfile(os.path.join(A_							, '''pytorch_lora_weights.bin'''			)			)			)

     def  lowerCamelCase__ (				self     :		Dict			)						->							int:
          __UpperCAmelCase							,   __UpperCAmelCase	: str  							=			self.get_dummy_components()
          __UpperCAmelCase	: Union[str, Any]  							=			StableDiffusionPipeline(**A_			)
          __UpperCAmelCase	: Dict  							=			sd_pipe.to(A_			)
          sd_pipe.set_progress_bar_config(disable=A_			)

          __UpperCAmelCase							,   __UpperCAmelCase							,   __UpperCAmelCase	: List[str]  							=			self.get_dummy_inputs()

          __UpperCAmelCase	: int  							=			sd_pipe(**A_			).images
          __UpperCAmelCase	: str  							=			original_images[0, -3:, -3:, -1]

          with tempfile.TemporaryDirectory() as tmpdirname:
               LoraLoaderMixin.save_lora_weights(
                   save_directory=A_							, unet_lora_layers=lora_components['''unet_lora_layers''']							, text_encoder_lora_layers=lora_components['''text_encoder_lora_layers''']							, )
               self.assertTrue(os.path.isfile(os.path.join(A_							, '''pytorch_lora_weights.bin'''			)			)			)
               sd_pipe.load_lora_weights(A_			)

          __UpperCAmelCase	: Optional[Any]  							=			sd_pipe(**A_			).images
          __UpperCAmelCase	: str  							=			lora_images[0, -3:, -3:, -1]

          # Outputs shouldn't match.
          self.assertFalse(torch.allclose(torch.from_numpy(A_			)							, torch.from_numpy(A_			)			)			)

     def  lowerCamelCase__ (				self     :		int			)						->							Tuple:
          __UpperCAmelCase							,   __UpperCAmelCase	: Dict  							=			self.get_dummy_components()
          __UpperCAmelCase	: int  							=			StableDiffusionPipeline(**A_			)
          __UpperCAmelCase	: List[str]  							=			sd_pipe.to(A_			)
          sd_pipe.set_progress_bar_config(disable=A_			)

          __UpperCAmelCase							,   __UpperCAmelCase							,   __UpperCAmelCase	: Dict  							=			self.get_dummy_inputs()

          __UpperCAmelCase	: Tuple  							=			sd_pipe(**A_			).images
          __UpperCAmelCase	: Any  							=			original_images[0, -3:, -3:, -1]

          with tempfile.TemporaryDirectory() as tmpdirname:
               LoraLoaderMixin.save_lora_weights(
                   save_directory=A_							, unet_lora_layers=lora_components['''unet_lora_layers''']							, text_encoder_lora_layers=lora_components['''text_encoder_lora_layers''']							, safe_serialization=A_							, )
               self.assertTrue(os.path.isfile(os.path.join(A_							, '''pytorch_lora_weights.safetensors'''			)			)			)
               sd_pipe.load_lora_weights(A_			)

          __UpperCAmelCase	: Tuple  							=			sd_pipe(**A_			).images
          __UpperCAmelCase	: str  							=			lora_images[0, -3:, -3:, -1]

          # Outputs shouldn't match.
          self.assertFalse(torch.allclose(torch.from_numpy(A_			)							, torch.from_numpy(A_			)			)			)

     def  lowerCamelCase__ (				self     :		Tuple			)						->							List[Any]:
          __UpperCAmelCase							,   __UpperCAmelCase	: List[Any]  							=			self.get_dummy_components()
          __UpperCAmelCase	: Tuple  							=			lora_components['''unet_lora_attn_procs''']
          __UpperCAmelCase	: List[Any]  							=			StableDiffusionPipeline(**A_			)
          __UpperCAmelCase	: Tuple  							=			sd_pipe.to(A_			)
          sd_pipe.set_progress_bar_config(disable=A_			)

          __UpperCAmelCase							,   __UpperCAmelCase							,   __UpperCAmelCase	: Dict  							=			self.get_dummy_inputs()

          __UpperCAmelCase	: Union[str, Any]  							=			sd_pipe(**A_			).images
          __UpperCAmelCase	: List[str]  							=			original_images[0, -3:, -3:, -1]

          with tempfile.TemporaryDirectory() as tmpdirname:
               __UpperCAmelCase	: int  							=			sd_pipe.unet
               unet.set_attn_processor(A_			)
               unet.save_attn_procs(A_			)
               self.assertTrue(os.path.isfile(os.path.join(A_							, '''pytorch_lora_weights.bin'''			)			)			)
               sd_pipe.load_lora_weights(A_			)

          __UpperCAmelCase	: str  							=			sd_pipe(**A_			).images
          __UpperCAmelCase	: str  							=			lora_images[0, -3:, -3:, -1]

          # Outputs shouldn't match.
          self.assertFalse(torch.allclose(torch.from_numpy(A_			)							, torch.from_numpy(A_			)			)			)

     def  lowerCamelCase__ (				self     :		Optional[int]			)						->							Union[str, Any]:
          __UpperCAmelCase							,   __UpperCAmelCase	: Optional[int]  							=			self.get_dummy_components()
          __UpperCAmelCase	: str  							=			StableDiffusionPipeline(**A_			)

          __UpperCAmelCase	: int  							=			self.get_dummy_tokens()

          # inference without lora
          __UpperCAmelCase	: Tuple  							=			pipe.text_encoder(**A_			)[0]
          assert outputs_without_lora.shape == (1, 77, 32)

          # create lora_attn_procs with zeroed out up.weights
          __UpperCAmelCase	: str  							=			create_text_encoder_lora_attn_procs(pipe.text_encoder			)
          set_lora_up_weights(A_							, randn_weight=A_			)

          # monkey patch
          pipe._modify_text_encoder(A_			)

          # verify that it's okay to release the text_attn_procs which holds the LoRAAttnProcessor.
          del text_attn_procs
          gc.collect()

          # inference with lora
          __UpperCAmelCase	: int  							=			pipe.text_encoder(**A_			)[0]
          assert outputs_with_lora.shape == (1, 77, 32)

          assert torch.allclose(
              A_							, A_			), "lora_up_weight are all zero, so the lora outputs should be the same to without lora outputs"

          # create lora_attn_procs with randn up.weights
          __UpperCAmelCase	: Any  							=			create_text_encoder_lora_attn_procs(pipe.text_encoder			)
          set_lora_up_weights(A_							, randn_weight=A_			)

          # monkey patch
          pipe._modify_text_encoder(A_			)

          # verify that it's okay to release the text_attn_procs which holds the LoRAAttnProcessor.
          del text_attn_procs
          gc.collect()

          # inference with lora
          __UpperCAmelCase	: int  							=			pipe.text_encoder(**A_			)[0]
          assert outputs_with_lora.shape == (1, 77, 32)

          assert not torch.allclose(
              A_							, A_			), "lora_up_weight are not zero, so the lora outputs should be different to without lora outputs"

     def  lowerCamelCase__ (				self     :		List[str]			)						->							Optional[int]:
          __UpperCAmelCase							,   __UpperCAmelCase	: Any  							=			self.get_dummy_components()
          __UpperCAmelCase	: Tuple  							=			StableDiffusionPipeline(**A_			)

          __UpperCAmelCase	: List[Any]  							=			self.get_dummy_tokens()

          # inference without lora
          __UpperCAmelCase	: Tuple  							=			pipe.text_encoder(**A_			)[0]
          assert outputs_without_lora.shape == (1, 77, 32)

          # create lora_attn_procs with randn up.weights
          __UpperCAmelCase	: int  							=			create_text_encoder_lora_attn_procs(pipe.text_encoder			)
          set_lora_up_weights(A_							, randn_weight=A_			)

          # monkey patch
          pipe._modify_text_encoder(A_			)

          # verify that it's okay to release the text_attn_procs which holds the LoRAAttnProcessor.
          del text_attn_procs
          gc.collect()

          # inference with lora
          __UpperCAmelCase	: Optional[int]  							=			pipe.text_encoder(**A_			)[0]
          assert outputs_with_lora.shape == (1, 77, 32)

          assert not torch.allclose(
              A_							, A_			), "lora outputs should be different to without lora outputs"

          # remove monkey patch
          pipe._remove_text_encoder_monkey_patch()

          # inference with removed lora
          __UpperCAmelCase	: int  							=			pipe.text_encoder(**A_			)[0]
          assert outputs_without_lora_removed.shape == (1, 77, 32)

          assert torch.allclose(
              A_							, A_			), "remove lora monkey patch should restore the original outputs"

     def  lowerCamelCase__ (				self     :		Any			)						->							Union[str, Any]:
          __UpperCAmelCase							,   __UpperCAmelCase	: Optional[Any]  							=			self.get_dummy_components()
          __UpperCAmelCase	: Tuple  							=			StableDiffusionPipeline(**A_			)
          __UpperCAmelCase	: List[Any]  							=			sd_pipe.to(A_			)
          sd_pipe.set_progress_bar_config(disable=A_			)

          __UpperCAmelCase							,   __UpperCAmelCase							,   __UpperCAmelCase	: int  							=			self.get_dummy_inputs()

          with tempfile.TemporaryDirectory() as tmpdirname:
               LoraLoaderMixin.save_lora_weights(
                   save_directory=A_							, unet_lora_layers=lora_components['''unet_lora_layers''']							, text_encoder_lora_layers=lora_components['''text_encoder_lora_layers''']							, )
               self.assertTrue(os.path.isfile(os.path.join(A_							, '''pytorch_lora_weights.bin'''			)			)			)
               sd_pipe.load_lora_weights(A_			)

          __UpperCAmelCase	: Optional[int]  							=			sd_pipe(**A_			).images
          __UpperCAmelCase	: List[str]  							=			lora_images[0, -3:, -3:, -1]

          __UpperCAmelCase	: Optional[Any]  							=			sd_pipe(**A_							, cross_attention_kwargs={'''scale''': 0.5}			).images
          __UpperCAmelCase	: Union[str, Any]  							=			lora_images_with_scale[0, -3:, -3:, -1]

          # Outputs shouldn't match.
          self.assertFalse(
              torch.allclose(torch.from_numpy(A_			)							, torch.from_numpy(A_			)			)			)

     def  lowerCamelCase__ (				self     :		List[str]			)						->							str:






          with tempfile.TemporaryDirectory() as tmpdirname:
               self.create_lora_weight_file(A_			)

               __UpperCAmelCase							,   __UpperCAmelCase	: List[Any]  							=			self.get_dummy_components()
               __UpperCAmelCase	: List[Any]  							=			StableDiffusionPipeline(**A_			)
               __UpperCAmelCase	: Optional[int]  							=			sd_pipe.to(A_			)
               sd_pipe.set_progress_bar_config(disable=A_			)

               # check if vanilla attention processors are used
               for _, module in sd_pipe.unet.named_modules():
                    if isinstance(A_							, A_			):
                         self.assertIsInstance(module.processor							, (AttnProcessor, AttnProcessor2_0)			)

            # load LoRA weight file
               sd_pipe.load_lora_weights(A_			)

               # check if lora attention processors are used
               for _, module in sd_pipe.unet.named_modules():
                    if isinstance(A_							, A_			):
                         __UpperCAmelCase	: Optional[Any]  							=			(
                             LoRAAttnProcessor2_0 if hasattr(A_							, '''scaled_dot_product_attention'''			) else LoRAAttnProcessor
                         )
                         self.assertIsInstance(module.processor							, A_			)

     @unittest.skipIf(torch_device != '''cuda'''							, '''This test is supposed to run on GPU'''			)
     def  lowerCamelCase__ (				self     :		Dict			)						->							Dict:






          with tempfile.TemporaryDirectory() as tmpdirname:
               self.create_lora_weight_file(A_			)

               __UpperCAmelCase							,   __UpperCAmelCase	: Dict  							=			self.get_dummy_components()
               __UpperCAmelCase	: List[Any]  							=			StableDiffusionPipeline(**A_			)
               __UpperCAmelCase	: List[str]  							=			sd_pipe.to(A_			)
               sd_pipe.set_progress_bar_config(disable=A_			)

               # enable XFormers
               sd_pipe.enable_xformers_memory_efficient_attention()

               # check if xFormers attention processors are used
               for _, module in sd_pipe.unet.named_modules():
                    if isinstance(A_							, A_			):
                         self.assertIsInstance(module.processor							, A_			)

            # load LoRA weight file
               sd_pipe.load_lora_weights(A_			)

               # check if lora attention processors are used
               for _, module in sd_pipe.unet.named_modules():
                    if isinstance(A_							, A_			):
                         self.assertIsInstance(module.processor							, A_			)






     @unittest.skipIf(torch_device != '''cuda'''							, '''This test is supposed to run on GPU'''			)
     def  lowerCamelCase__ (				self     :		Tuple			)						->							Tuple:
          __UpperCAmelCase							,   __UpperCAmelCase	: Dict  							=			self.get_dummy_components()
          __UpperCAmelCase	: str  							=			StableDiffusionPipeline(**A_			)
          __UpperCAmelCase	: str  							=			sd_pipe.to(A_			)
          sd_pipe.set_progress_bar_config(disable=A_			)

          __UpperCAmelCase							,   __UpperCAmelCase							,   __UpperCAmelCase	: Any  							=			self.get_dummy_inputs()

          # enable XFormers
          sd_pipe.enable_xformers_memory_efficient_attention()

          __UpperCAmelCase	: List[str]  							=			sd_pipe(**A_			).images
          __UpperCAmelCase	: int  							=			original_images[0, -3:, -3:, -1]

          with tempfile.TemporaryDirectory() as tmpdirname:
               LoraLoaderMixin.save_lora_weights(
                   save_directory=A_							, unet_lora_layers=lora_components['''unet_lora_layers''']							, text_encoder_lora_layers=lora_components['''text_encoder_lora_layers''']							, )
               self.assertTrue(os.path.isfile(os.path.join(A_							, '''pytorch_lora_weights.bin'''			)			)			)
               sd_pipe.load_lora_weights(A_			)

          __UpperCAmelCase	: Dict  							=			sd_pipe(**A_			).images
          __UpperCAmelCase	: List[str]  							=			lora_images[0, -3:, -3:, -1]

          # Outputs shouldn't match.
          self.assertFalse(torch.allclose(torch.from_numpy(A_			)							, torch.from_numpy(A_			)			)			)

'''simple docstring'''
from typing import SupportsIndex

import numpy as np
from scipy.ndimage import convolve







def 						A_(			A		:						np.ndarray						,			A		:						np.ndarray						,			A		:						np.ndarray):
							UpperCamelCase					       =			np.stack((horizontal_flow, vertical_flow)						,			2)

							# Create a grid of all pixel coordinates and subtract the flow to get the
							# target pixels coordinates
							UpperCamelCase					       =			np.stack(
							    np.meshgrid(np.arange(0						,			image.shape[1])						,			np.arange(0						,			image.shape[0]))						,			2)
							UpperCamelCase					       =			np.round(grid - flow).astype(np.intaa)

							# Find the locations outside of the original image
							UpperCamelCase					       =			(grid < 0) | (grid >= np.array([image.shape[1], image.shape[0]]))
							UpperCamelCase					       =			0

							UpperCamelCase					       =			image[grid[:, :, 1], grid[:, :, 0]]

							# Set pixels at invalid locations to 0
							UpperCamelCase					       =			0

							return warped







def 						A_(			A		:						np.ndarray						,			A		:						np.ndarray						,			A		:						SupportsIndex						,			A		:						float | None = None						,			):
							if alpha is None:
														UpperCamelCase					       =			0.1

							# Initialize flow
							UpperCamelCase					       =			np.zeros_like(A)
							UpperCamelCase					       =			np.zeros_like(A)

							# Prepare kernels for the calculation of the derivatives and the average velocity
							UpperCamelCase					       =			np.array([[-1, 1], [-1, 1]]) * 0.25
							UpperCamelCase					       =			np.array([[-1, -1], [1, 1]]) * 0.25
							UpperCamelCase					       =			np.array([[1, 1], [1, 1]]) * 0.25
							UpperCamelCase					       =			np.array(
							    [[1 / 12, 1 / 6, 1 / 12], [1 / 6, 0, 1 / 6], [1 / 12, 1 / 6, 1 / 12]])

							# Iteratively refine the flow
							for _ in range(A):
														UpperCamelCase					       =			warp(A						,			A						,			A)
														UpperCamelCase					       =			convolve(A						,			A) + convolve(A						,			A)
														UpperCamelCase					       =			convolve(A						,			A) + convolve(A						,			A)
														UpperCamelCase					       =			convolve(A						,			A) + convolve(A						,			-kernel_t)

														UpperCamelCase					       =			convolve(A						,			A)
														UpperCamelCase					       =			convolve(A						,			A)

														# This updates the flow as proposed in the paper (Step 12)
														UpperCamelCase					       =			(
														    derivative_x * avg_horizontal_velocity
														    + derivative_y * avg_vertical_velocity
														    + derivative_t
														)
														UpperCamelCase					       =			update / (alpha**2 + derivative_x**2 + derivative_y**2)

														UpperCamelCase					       =			avg_horizontal_velocity - derivative_x * update
														UpperCamelCase					       =			avg_vertical_velocity - derivative_y * update

							return horizontal_flow, vertical_flow


if __name__ == "__main__":
						import doctest

						doctest.testmod()




