




from statistics import mean, stdev




def        _SCREAMING_SNAKE_CASE      (		snake_case			,     snake_case = 3       )						->				list:
						_UpperCAmelCase      =			min(snake_case       )
						_UpperCAmelCase      =			max(snake_case       )
						# normalize data
						return [round((x - x_min) / (x_max - x_min)			,     snake_case       ) for x in data]




def        _SCREAMING_SNAKE_CASE      (		snake_case			,     snake_case = 3       )						->				list:
						_UpperCAmelCase      =			mean(snake_case       )
						_UpperCAmelCase      =			stdev(snake_case       )
						# standardize data
						return [round((x - mu) / (sigma)			,     snake_case       ) for x in data]





import unittest

import numpy as np




def        _SCREAMING_SNAKE_CASE      (		snake_case			,     snake_case			,     snake_case			,     snake_case = None			,     )						->				np.ndarray:
						_UpperCAmelCase      =			np.shape(snake_case       )
						_UpperCAmelCase      =			np.shape(snake_case       )
						_UpperCAmelCase      =			np.shape(snake_case       )

						if shape_a[0] != shape_b[0]:
												_UpperCAmelCase      =			(
												    """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]:
												_UpperCAmelCase      =			(
												    """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       )

						_UpperCAmelCase      =			pseudo_inv
						if a_inv is None:
												try:
																		_UpperCAmelCase      =			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       _A				(		unittest.TestCase     ):






		def 				UpperCAmelCase (    self			):
								_UpperCAmelCase      =			np.array([[1, 2, 1], [2, 1, 2], [3, 2, 4]]			)
								_UpperCAmelCase      =			np.array([[0, 3], [3, 0], [2, 3]]			)
								_UpperCAmelCase      =			np.array([[2, 1], [6, 3]]			)

								_UpperCAmelCase      =			schur_complement(_SCREAMING_SNAKE_CASE						,		_SCREAMING_SNAKE_CASE						,		_SCREAMING_SNAKE_CASE			)

								_UpperCAmelCase      =			np.block([[a, b], [b.T, c]]			)

								_UpperCAmelCase      =			np.linalg.det(_SCREAMING_SNAKE_CASE			)
								_UpperCAmelCase      =			np.linalg.det(_SCREAMING_SNAKE_CASE			)
								_UpperCAmelCase      =			np.linalg.det(_SCREAMING_SNAKE_CASE			)

								self.assertAlmostEqual(_SCREAMING_SNAKE_CASE						,		det_a * det_s			)






		def 				UpperCAmelCase (    self			):
								_UpperCAmelCase      =			np.array([[1, 2, 1], [2, 1, 2], [3, 2, 4]]			)
								_UpperCAmelCase      =			np.array([[0, 3], [3, 0], [2, 3]]			)
								_UpperCAmelCase      =			np.array([[2, 1], [6, 3]]			)

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






		def 				UpperCAmelCase (    self			):
								_UpperCAmelCase      =			np.array([[1, 2, 1], [2, 1, 2], [3, 2, 4]]			)
								_UpperCAmelCase      =			np.array([[0, 3], [3, 0], [2, 3]]			)
								_UpperCAmelCase      =			np.array([[2, 1, 3], [6, 3, 5]]			)

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


if __name__ == "__main__":
				import doctest

				doctest.testmod()
				unittest.main()