
"""simple docstring"""





from __future__ import annotations

import math



def 		_lowerCAmelCase							(							UpperCamelCase_    ,							UpperCamelCase_							):
		if len(snake_case__							) != 2 or len(a[0]							) != 2 or len(snake_case__							) != 2 or len(b[0]							) != 2:
				raise Exception("""Matrices are not 2x2"""							)
		__SCREAMING_SNAKE_CASE				=					[
		    [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 		_lowerCAmelCase							(							UpperCamelCase_    ,							UpperCamelCase_							):
		return [
		    [matrix_a[row][col] + matrix_b[row][col] for col in range(len(matrix_a[row]							)							)]
		    for row in range(len(snake_case__							)							)
		]



def 		_lowerCAmelCase							(							UpperCamelCase_    ,							UpperCamelCase_							):
		return [
		    [matrix_a[row][col] - matrix_b[row][col] for col in range(len(matrix_a[row]							)							)]
		    for row in range(len(snake_case__							)							)
		]



def 		_lowerCAmelCase							(							UpperCamelCase_							):
		if len(snake_case__							) % 2 != 0 or len(a[0]							) % 2 != 0:
				raise Exception("""Odd matrices are not supported!"""							)

		__SCREAMING_SNAKE_CASE				=					len(snake_case__							)
		__SCREAMING_SNAKE_CASE				=					matrix_length // 2

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

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

		return top_left, top_right, bot_left, bot_right



def 		_lowerCAmelCase							(							UpperCamelCase_							):
		return len(snake_case__							), len(matrix[0]							)



def 		_lowerCAmelCase							(							UpperCamelCase_							):
		print("""\n""".join(str(snake_case__							) for line in matrix							)							)



def 		_lowerCAmelCase							(							UpperCamelCase_    ,							UpperCamelCase_							):
		if matrix_dimensions(snake_case__							) == (2, 2):
				return default_matrix_multiplication(snake_case__    ,							snake_case__							)

		__SCREAMING_SNAKE_CASE				=					split_matrix(snake_case__							)
		__SCREAMING_SNAKE_CASE				=					split_matrix(snake_case__							)

		__SCREAMING_SNAKE_CASE				=					actual_strassen(snake_case__    ,							matrix_subtraction(snake_case__    ,							snake_case__							)							)
		__SCREAMING_SNAKE_CASE				=					actual_strassen(matrix_addition(snake_case__    ,							snake_case__							)    ,							snake_case__							)
		__SCREAMING_SNAKE_CASE				=					actual_strassen(matrix_addition(snake_case__    ,							snake_case__							)    ,							snake_case__							)
		__SCREAMING_SNAKE_CASE				=					actual_strassen(snake_case__    ,							matrix_subtraction(snake_case__    ,							snake_case__							)							)
		__SCREAMING_SNAKE_CASE				=					actual_strassen(matrix_addition(snake_case__    ,							snake_case__							)    ,							matrix_addition(snake_case__    ,							snake_case__							)							)
		__SCREAMING_SNAKE_CASE				=					actual_strassen(matrix_subtraction(snake_case__    ,							snake_case__							)    ,							matrix_addition(snake_case__    ,							snake_case__							)							)
		__SCREAMING_SNAKE_CASE				=					actual_strassen(matrix_subtraction(snake_case__    ,							snake_case__							)    ,							matrix_addition(snake_case__    ,							snake_case__							)							)

		__SCREAMING_SNAKE_CASE				=					matrix_addition(matrix_subtraction(matrix_addition(snake_case__    ,							snake_case__							)    ,							snake_case__							)    ,							snake_case__							)
		__SCREAMING_SNAKE_CASE				=					matrix_addition(snake_case__    ,							snake_case__							)
		__SCREAMING_SNAKE_CASE				=					matrix_addition(snake_case__    ,							snake_case__							)
		__SCREAMING_SNAKE_CASE				=					matrix_subtraction(matrix_subtraction(matrix_addition(snake_case__    ,							snake_case__							)    ,							snake_case__							)    ,							snake_case__							)

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



def 		_lowerCAmelCase							(							UpperCamelCase_    ,							UpperCamelCase_							):
		if matrix_dimensions(snake_case__							)[1] != matrix_dimensions(snake_case__							)[0]:
				__SCREAMING_SNAKE_CASE				=					(
				    """Unable to multiply these matrices, please check the dimensions.\n"""
				    f"Matrix A: {matrixa}\n"
				    f"Matrix B: {matrixa}"
				)
				raise Exception(snake_case__							)
		__SCREAMING_SNAKE_CASE				=					matrix_dimensions(snake_case__							)
		__SCREAMING_SNAKE_CASE				=					matrix_dimensions(snake_case__							)

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

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

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

		__SCREAMING_SNAKE_CASE				=					actual_strassen(snake_case__    ,							snake_case__							)

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


if __name__ == "__main__":
							__magic_name__			=     [
							    [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],
							]
							__magic_name__			=     [[0, 2, 1, 1], [16, 2, 3, 3], [2, 2, 7, 7], [13, 11, 22, 4]]
							print(strassen(matrixa, matrixa))












"""simple docstring"""
_lowerCAmelCase       =				[
    "Audio",
    "Array2D",
    "Array3D",
    "Array4D",
    "Array5D",
    "ClassLabel",
    "Features",
    "Sequence",
    "Value",
    "Image",
    "Translation",
    "TranslationVariableLanguages",
]
from .audio import Audio
from .features import ArrayaD, ArrayaD, ArrayaD, ArrayaD, ClassLabel, Features, Sequence, Value
from .image import Image
from .translation import Translation, TranslationVariableLanguages

