



from __future__ import annotations

import math





def 							A     (					_UpperCAmelCase    :       list							,       _UpperCAmelCase    :       list   )    ->			list:







			'''simple docstring'''
			if len(_UpperCAmelCase   ) != 2 or len(a[0]   ) != 2 or len(_UpperCAmelCase   ) != 2 or len(b[0]   ) != 2:
						raise Exception('Matrices are not 2x2'   )
			_UpperCAmelCase			=       [
			    [a[0][0] * b[0][0] + a[0][1] * b[1][0], a[0][0] * b[0][1] + a[0][1] * b[1][1]],
			    [a[1][0] * b[0][0] + a[1][1] * b[1][0], a[1][0] * b[0][1] + a[1][1] * b[1][1]],
			]
			return new_matrix





def 							A     (					_UpperCAmelCase    :       list							,       _UpperCAmelCase    :       list   )    ->			Tuple:







			'''simple docstring'''
			return [
			    [matrix_a[row][col] + matrix_b[row][col] for col in range(len(matrix_a[row]   )   )]
			    for row in range(len(_UpperCAmelCase   )   )
			]





def 							A     (					_UpperCAmelCase    :       list							,       _UpperCAmelCase    :       list   )    ->			List[str]:







			'''simple docstring'''
			return [
			    [matrix_a[row][col] - matrix_b[row][col] for col in range(len(matrix_a[row]   )   )]
			    for row in range(len(_UpperCAmelCase   )   )
			]





def 							A     (					_UpperCAmelCase    :       list   )    ->			tuple[list, list, list, list]:







			'''simple docstring'''
			if len(_UpperCAmelCase   ) % 2 != 0 or len(a[0]   ) % 2 != 0:
						raise Exception('Odd matrices are not supported!'   )

			_UpperCAmelCase			=       len(_UpperCAmelCase   )
			_UpperCAmelCase			=       matrix_length // 2

			_UpperCAmelCase			=       [[a[i][j] for j in range(_UpperCAmelCase							,       _UpperCAmelCase   )] for i in range(_UpperCAmelCase   )]
			_UpperCAmelCase			=       [
			    [a[i][j] for j in range(_UpperCAmelCase							,       _UpperCAmelCase   )] for i in range(_UpperCAmelCase							,       _UpperCAmelCase   )
			]

			_UpperCAmelCase			=       [[a[i][j] for j in range(_UpperCAmelCase   )] for i in range(_UpperCAmelCase   )]
			_UpperCAmelCase			=       [[a[i][j] for j in range(_UpperCAmelCase   )] for i in range(_UpperCAmelCase							,       _UpperCAmelCase   )]

			return top_left, top_right, bot_left, bot_right





def 							A     (					_UpperCAmelCase    :       list   )    ->			tuple[int, int]:







			'''simple docstring'''
			return len(_UpperCAmelCase   ), len(matrix[0]   )





def 							A     (					_UpperCAmelCase    :       list   )    ->			None:







			'''simple docstring'''
			print('\n'.join(str(_UpperCAmelCase   ) for line in matrix   )   )





def 							A     (					_UpperCAmelCase    :       list							,       _UpperCAmelCase    :       list   )    ->			list:







			'''simple docstring'''
			if matrix_dimensions(_UpperCAmelCase   ) == (2, 2):
						return default_matrix_multiplication(_UpperCAmelCase							,       _UpperCAmelCase   )

			_UpperCAmelCase	,					_UpperCAmelCase	,					_UpperCAmelCase	,					_UpperCAmelCase			=       split_matrix(_UpperCAmelCase   )
			_UpperCAmelCase	,					_UpperCAmelCase	,					_UpperCAmelCase	,					_UpperCAmelCase			=       split_matrix(_UpperCAmelCase   )

			_UpperCAmelCase			=       actual_strassen(_UpperCAmelCase							,       matrix_subtraction(_UpperCAmelCase							,       _UpperCAmelCase   )   )
			_UpperCAmelCase			=       actual_strassen(matrix_addition(_UpperCAmelCase							,       _UpperCAmelCase   )							,       _UpperCAmelCase   )
			_UpperCAmelCase			=       actual_strassen(matrix_addition(_UpperCAmelCase							,       _UpperCAmelCase   )							,       _UpperCAmelCase   )
			_UpperCAmelCase			=       actual_strassen(_UpperCAmelCase							,       matrix_subtraction(_UpperCAmelCase							,       _UpperCAmelCase   )   )
			_UpperCAmelCase			=       actual_strassen(matrix_addition(_UpperCAmelCase							,       _UpperCAmelCase   )							,       matrix_addition(_UpperCAmelCase							,       _UpperCAmelCase   )   )
			_UpperCAmelCase			=       actual_strassen(matrix_subtraction(_UpperCAmelCase							,       _UpperCAmelCase   )							,       matrix_addition(_UpperCAmelCase							,       _UpperCAmelCase   )   )
			_UpperCAmelCase			=       actual_strassen(matrix_subtraction(_UpperCAmelCase							,       _UpperCAmelCase   )							,       matrix_addition(_UpperCAmelCase							,       _UpperCAmelCase   )   )

			_UpperCAmelCase			=       matrix_addition(matrix_subtraction(matrix_addition(_UpperCAmelCase							,       _UpperCAmelCase   )							,       _UpperCAmelCase   )							,       _UpperCAmelCase   )
			_UpperCAmelCase			=       matrix_addition(_UpperCAmelCase							,       _UpperCAmelCase   )
			_UpperCAmelCase			=       matrix_addition(_UpperCAmelCase							,       _UpperCAmelCase   )
			_UpperCAmelCase			=       matrix_subtraction(matrix_subtraction(matrix_addition(_UpperCAmelCase							,       _UpperCAmelCase   )							,       _UpperCAmelCase   )							,       _UpperCAmelCase   )

			# construct the new matrix from our 4 quadrants
			_UpperCAmelCase			=       []
			for i in range(len(_UpperCAmelCase   )   ):
						new_matrix.append(top_left[i] + top_right[i]   )
			for i in range(len(_UpperCAmelCase   )   ):
						new_matrix.append(bot_left[i] + bot_right[i]   )
			return new_matrix





def 							A     (					_UpperCAmelCase    :       list							,       _UpperCAmelCase    :       list   )    ->			list:







			'''simple docstring'''
			if matrix_dimensions(_UpperCAmelCase   )[1] != matrix_dimensions(_UpperCAmelCase   )[0]:
						_UpperCAmelCase			=       (
						    'Unable to multiply these matrices, please check the dimensions.\n'
						    F"Matrix A: {matrixa}\n"
						    F"Matrix B: {matrixa}"
						)
						raise Exception(_UpperCAmelCase   )
			_UpperCAmelCase			=       matrix_dimensions(_UpperCAmelCase   )
			_UpperCAmelCase			=       matrix_dimensions(_UpperCAmelCase   )

			if dimensiona[0] == dimensiona[1] and dimensiona[0] == dimensiona[1]:
						return [matrixa, matrixa]

			_UpperCAmelCase			=       max(*_UpperCAmelCase							,       *_UpperCAmelCase   )
			_UpperCAmelCase			=       int(math.pow(2							,       math.ceil(math.loga(_UpperCAmelCase   )   )   )   )
			_UpperCAmelCase			=       matrixa
			_UpperCAmelCase			=       matrixa

			# Adding zeros to the matrices so that the arrays dimensions are the same and also
			# power of 2
			for i in range(0							,       _UpperCAmelCase   ):
						if i < dimensiona[0]:
									for _ in range(dimensiona[1]							,       _UpperCAmelCase   ):
												new_matrixa[i].append(0   )
						else:
									new_matrixa.append([0] * maxim   )
						if i < dimensiona[0]:
									for _ in range(dimensiona[1]							,       _UpperCAmelCase   ):
												new_matrixa[i].append(0   )
						else:
									new_matrixa.append([0] * maxim   )

			_UpperCAmelCase			=       actual_strassen(_UpperCAmelCase							,       _UpperCAmelCase   )

			# Removing the additional zeros
			for i in range(0							,       _UpperCAmelCase   ):
						if i < dimensiona[0]:
									for _ in range(dimensiona[1]							,       _UpperCAmelCase   ):
												final_matrix[i].pop()
						else:
									final_matrix.pop()
			return final_matrix


if __name__ == "__main__":
							UpperCAmelCase__       =	[
							    [2, 3, 4, 5],
							    [6, 4, 3, 1],
							    [2, 3, 6, 7],
							    [3, 1, 2, 4],
							    [2, 3, 4, 5],
							    [6, 4, 3, 1],
							    [2, 3, 6, 7],
							    [3, 1, 2, 4],
							    [2, 3, 4, 5],
							    [6, 2, 3, 1],
							]
							UpperCAmelCase__       =	[[0, 2, 1, 1], [16, 2, 3, 3], [2, 2, 7, 7], [13, 11, 22, 4]]
							print(strassen(matrixa, matrixa))











from typing import TYPE_CHECKING

from ...utils import (
    OptionalDependencyNotAvailable,
    _LazyModule,
    is_flax_available,
    is_tf_available,
    is_tokenizers_available,
    is_torch_available,
    is_vision_available,
)


UpperCAmelCase__       =	{
    "configuration_clip": [
        "CLIP_PRETRAINED_CONFIG_ARCHIVE_MAP",
        "CLIPConfig",
        "CLIPOnnxConfig",
        "CLIPTextConfig",
        "CLIPVisionConfig",
    ],
    "processing_clip": ["CLIPProcessor"],
    "tokenization_clip": ["CLIPTokenizer"],
}

try:
							if not is_tokenizers_available():
														raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
							pass
else:
							UpperCAmelCase__       =	["CLIPTokenizerFast"]

try:
							if not is_vision_available():
														raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
							pass
else:
							UpperCAmelCase__       =	["CLIPFeatureExtractor"]
							UpperCAmelCase__       =	["CLIPImageProcessor"]

try:
							if not is_torch_available():
														raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
							pass
else:
							UpperCAmelCase__       =	[
							    "CLIP_PRETRAINED_MODEL_ARCHIVE_LIST",
							    "CLIPModel",
							    "CLIPPreTrainedModel",
							    "CLIPTextModel",
							    "CLIPTextModelWithProjection",
							    "CLIPVisionModel",
							    "CLIPVisionModelWithProjection",
							]

try:
							if not is_tf_available():
														raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
							pass
else:
							UpperCAmelCase__       =	[
							    "TF_CLIP_PRETRAINED_MODEL_ARCHIVE_LIST",
							    "TFCLIPModel",
							    "TFCLIPPreTrainedModel",
							    "TFCLIPTextModel",
							    "TFCLIPVisionModel",
							]

try:
							if not is_flax_available():
														raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
							pass
else:
							UpperCAmelCase__       =	[
							    "FlaxCLIPModel",
							    "FlaxCLIPPreTrainedModel",
							    "FlaxCLIPTextModel",
							    "FlaxCLIPTextPreTrainedModel",
							    "FlaxCLIPVisionModel",
							    "FlaxCLIPVisionPreTrainedModel",
							]


if TYPE_CHECKING:
							from .configuration_clip import (
							    CLIP_PRETRAINED_CONFIG_ARCHIVE_MAP,
							    CLIPConfig,
							    CLIPOnnxConfig,
							    CLIPTextConfig,
							    CLIPVisionConfig,
							)
							from .processing_clip import CLIPProcessor
							from .tokenization_clip import CLIPTokenizer

							try:
														if not is_tokenizers_available():
																					raise OptionalDependencyNotAvailable()
							except OptionalDependencyNotAvailable:
														pass
							else:
														from .tokenization_clip_fast import CLIPTokenizerFast

							try:
														if not is_vision_available():
																					raise OptionalDependencyNotAvailable()
							except OptionalDependencyNotAvailable:
														pass
							else:
														from .feature_extraction_clip import CLIPFeatureExtractor
														from .image_processing_clip import CLIPImageProcessor

							try:
														if not is_torch_available():
																					raise OptionalDependencyNotAvailable()
							except OptionalDependencyNotAvailable:
														pass
							else:
														from .modeling_clip import (
														    CLIP_PRETRAINED_MODEL_ARCHIVE_LIST,
														    CLIPModel,
														    CLIPPreTrainedModel,
														    CLIPTextModel,
														    CLIPTextModelWithProjection,
														    CLIPVisionModel,
														    CLIPVisionModelWithProjection,
														)

							try:
														if not is_tf_available():
																					raise OptionalDependencyNotAvailable()
							except OptionalDependencyNotAvailable:
														pass
							else:
														from .modeling_tf_clip import (
														    TF_CLIP_PRETRAINED_MODEL_ARCHIVE_LIST,
														    TFCLIPModel,
														    TFCLIPPreTrainedModel,
														    TFCLIPTextModel,
														    TFCLIPVisionModel,
														)

							try:
														if not is_flax_available():
																					raise OptionalDependencyNotAvailable()
							except OptionalDependencyNotAvailable:
														pass
							else:
														from .modeling_flax_clip import (
														    FlaxCLIPModel,
														    FlaxCLIPPreTrainedModel,
														    FlaxCLIPTextModel,
														    FlaxCLIPTextPreTrainedModel,
														    FlaxCLIPVisionModel,
														    FlaxCLIPVisionPreTrainedModel,
														)


else:
							import sys

							UpperCAmelCase__       =	_LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__)
