






import unittest

import numpy as np





def 					lowercase_ (    __snake_case     :							np.ndarray	,	__snake_case     :							np.ndarray	,	__snake_case     :							np.ndarray	,	__snake_case     :							np.ndarray | None = None	,	)     -> np.ndarray:





				'''simple docstring'''


				snake_case__      :Any         =   np.shape(__snake_case      )
				snake_case__      :Dict         =   np.shape(__snake_case      )
				snake_case__      :Tuple         =   np.shape(__snake_case      )

				if shape_a[0] != shape_b[0]:
								snake_case__      :int         =   (
								    "Expected the same number of rows for A and B. "
								    F'Instead found A of size {shape_a} and B of size {shape_b}'
								)
								raise ValueError(__snake_case      )

				if shape_b[1] != shape_c[1]:
								snake_case__      :Dict         =   (
								    "Expected the same number of columns for B and C. "
								    F'Instead found B of size {shape_b} and C of size {shape_c}'
								)
								raise ValueError(__snake_case      )

				snake_case__      :List[Any]         =   pseudo_inv
				if a_inv is None:
								try:
												snake_case__      :Dict         =   np.linalg.inv(__snake_case      )
								except np.linalg.LinAlgError:
												raise ValueError(
												    "Input matrix A is not invertible. Cannot compute Schur complement."      )

				return mat_c - mat_b.T @ a_inv @ mat_b


class 					_snake_case						(			unittest.TestCase ):






	def    lowerCAmelCase_							(		self       )						->    None:
					snake_case__      :Any         =   np.array([[1, 2, 1], [2, 1, 2], [3, 2, 4]]       )
					snake_case__      :Optional[int]         =   np.array([[0, 3], [3, 0], [2, 3]]       )
					snake_case__      :List[str]         =   np.array([[2, 1], [6, 3]]       )

					snake_case__      :List[str]         =   schur_complement(UpperCamelCase					,UpperCamelCase					,UpperCamelCase       )

					snake_case__      :Any         =   np.block([[a, b], [b.T, c]]       )

					snake_case__      :List[str]         =   np.linalg.det(UpperCamelCase       )
					snake_case__      :Dict         =   np.linalg.det(UpperCamelCase       )
					snake_case__      :Any         =   np.linalg.det(UpperCamelCase       )

					self.assertAlmostEqual(UpperCamelCase					,det_a * det_s       )






	def    lowerCAmelCase_							(		self       )						->    None:
					snake_case__      :Tuple         =   np.array([[1, 2, 1], [2, 1, 2], [3, 2, 4]]       )
					snake_case__      :List[str]         =   np.array([[0, 3], [3, 0], [2, 3]]       )
					snake_case__      :Union[str, Any]         =   np.array([[2, 1], [6, 3]]       )

					with self.assertRaises(UpperCamelCase       ):
									schur_complement(UpperCamelCase					,UpperCamelCase					,UpperCamelCase       )






	def    lowerCAmelCase_							(		self       )						->    None:
					snake_case__      :Any         =   np.array([[1, 2, 1], [2, 1, 2], [3, 2, 4]]       )
					snake_case__      :str         =   np.array([[0, 3], [3, 0], [2, 3]]       )
					snake_case__      :Dict         =   np.array([[2, 1, 3], [6, 3, 5]]       )

					with self.assertRaises(UpperCamelCase       ):
									schur_complement(UpperCamelCase					,UpperCamelCase					,UpperCamelCase       )


if __name__ == "__main__":
	import doctest

	doctest.testmod()
	unittest.main()







from __future__ import annotations


class 					_snake_case						:






	def __init__(		self					,UpperCamelCase       )						->    None:
					snake_case__      :Union[str, Any]         =   data
					snake_case__      :Node | None         =   None
					snake_case__      :Node | None         =   None





def 					lowercase_ (    __snake_case     :							Node | None      )     -> None:  # In Order traversal of the tree





				'''simple docstring'''


				if tree:
								display(tree.left      )
								print(tree.data      )
								display(tree.right      )





def 					lowercase_ (    __snake_case     :							Node | None      )     -> int:





				'''simple docstring'''


				return 1 + max(depth_of_tree(tree.left      )	,	depth_of_tree(tree.right      )      ) if tree else 0





def 					lowercase_ (    __snake_case     :							Node      )     -> bool:





				'''simple docstring'''


				if not tree:
								return True
				if tree.left and tree.right:
								return is_full_binary_tree(tree.left      ) and is_full_binary_tree(tree.right      )
				else:
								return not tree.left and not tree.right





def 					lowercase_ (    )     -> None:  # Main function for testing.





				'''simple docstring'''


				snake_case__      :Dict         =   Node(1      )
				snake_case__      :int         =   Node(2      )
				snake_case__      :Optional[Any]         =   Node(3      )
				snake_case__      :Tuple         =   Node(4      )
				snake_case__      :str         =   Node(5      )
				snake_case__      :Optional[Any]         =   Node(6      )
				snake_case__      :List[Any]         =   Node(7      )
				snake_case__      :List[str]         =   Node(8      )
				snake_case__      :Tuple         =   Node(9      )

				print(is_full_binary_tree(__snake_case      )      )
				print(depth_of_tree(__snake_case      )      )
				print("Tree is: "      )
				display(__snake_case      )


if __name__ == "__main__":
	main()