

import numpy as np

def       a__					(		UpperCAmelCase							:      int    ,			UpperCAmelCase							:      List[str]    ,			UpperCAmelCase							:      str = 1E-12    ,			UpperCAmelCase							:      Tuple = 100    ,			)  ->						tuple[float, np.ndarray]:
		assert np.shape(UpperCAmelCase      )[0] == np.shape(UpperCAmelCase      )[1]
		# Ensure proper dimensionality.
		assert np.shape(UpperCAmelCase      )[0] == np.shape(UpperCAmelCase      )[0]
		# Ensure inputs are either both complex or both real
		assert np.iscomplexobj(UpperCAmelCase      ) == np.iscomplexobj(UpperCAmelCase      )
		UpperCAmelCase	:							Union[str, Any]						=			np.iscomplexobj(UpperCAmelCase      )
		if is_complex:
				# Ensure complex input_matrix is Hermitian
				assert np.array_equal(UpperCAmelCase    ,			input_matrix.conj().T      )

		# Set convergence to False. Will define convergence when we exceed max_iterations
		# or when we have small changes from one iteration to next.

		UpperCAmelCase	:							List[str]						=			False
		UpperCAmelCase	:							List[Any]						=			0
		UpperCAmelCase	:							Union[str, Any]						=			0
		UpperCAmelCase	:							int						=			1E12

		while not convergence:
				# Multiple matrix by the vector.
				UpperCAmelCase	:							Union[str, Any]						=			np.dot(UpperCAmelCase    ,			UpperCAmelCase      )
				# Normalize the resulting output vector.
				UpperCAmelCase	:							List[Any]						=			w / np.linalg.norm(UpperCAmelCase      )
				# Find rayleigh quotient
				# (faster than usual b/c we know vector is normalized already)
				UpperCAmelCase	:							str						=			vector.conj().T if is_complex else vector.T
				UpperCAmelCase	:							Dict						=			np.dot(UpperCAmelCase    ,			np.dot(UpperCAmelCase    ,			UpperCAmelCase      )      )

				# Check convergence.
				UpperCAmelCase	:							Any						=			np.abs(lambda_ - lambda_previous      ) / lambda_
				iterations += 1

				if error <= error_tol or iterations >= max_iterations:
						UpperCAmelCase	:							str						=			True

				UpperCAmelCase	:							str						=			lambda_

		if is_complex:
				UpperCAmelCase	:							int						=			np.real(lambda_      )

		return lambda_, vector

def       a__					(		)  ->						None:
		UpperCAmelCase	:							Tuple						=			np.array([[41, 4, 20], [4, 26, 30], [20, 30, 50]]      )
		UpperCAmelCase	:							Union[str, Any]						=			np.array([41, 4, 20]      )
		UpperCAmelCase	:							int						=			real_input_matrix.astype(np.complexaaa      )
		UpperCAmelCase	:							Dict						=			np.triu(1j * complex_input_matrix    ,			1      )
		complex_input_matrix += imag_matrix
		complex_input_matrix += -1 * imag_matrix.T
		UpperCAmelCase	:							List[Any]						=			np.array([41, 4, 20]      ).astype(np.complexaaa      )

		for problem_type in ["real", "complex"]:
				if problem_type == "real":
						UpperCAmelCase	:							List[str]						=			real_input_matrix
						UpperCAmelCase	:							str						=			real_vector
				elif problem_type == "complex":
						UpperCAmelCase	:							Optional[Any]						=			complex_input_matrix
						UpperCAmelCase	:							List[Any]						=			complex_vector

				# Our implementation.
				UpperCAmelCase			,						UpperCAmelCase	:							Optional[Any]						=			power_iteration(UpperCAmelCase    ,			UpperCAmelCase      )

				# Numpy implementation.

				# Get eigenvalues and eigenvectors using built-in numpy
				# eigh (eigh used for symmetric or hermetian matrices).
				UpperCAmelCase			,						UpperCAmelCase	:							Any						=			np.linalg.eigh(UpperCAmelCase      )
				# Last eigenvalue is the maximum one.
				UpperCAmelCase	:							List[str]						=			eigen_values[-1]
				# Last column in this matrix is eigenvector corresponding to largest eigenvalue.
				UpperCAmelCase	:							int						=			eigen_vectors[:, -1]

				# Check our implementation and numpy gives close answers.
				assert np.abs(eigen_value - eigen_value_max      ) <= 1E-6
				# Take absolute values element wise of each eigenvector.
				# as they are only unique to a minus sign.
				assert np.linalg.norm(np.abs(UpperCAmelCase      ) - np.abs(UpperCAmelCase      )      ) <= 1E-6


if __name__ == "__main__":
					import doctest

					doctest.testmod()
					test_power_iteration()








def       a__					(		UpperCAmelCase							:      int      )  ->						bool:
  if not isinstance(UpperCAmelCase    ,			UpperCAmelCase      ):
    UpperCAmelCase	:							List[str]						=			f'''Input value of [number={number}] must be an integer'''
    raise TypeError(UpperCAmelCase      )
  if number < 0:
    return False
  UpperCAmelCase	:							List[str]						=			number * number
  while number > 0:
    if number % 10 != number_square % 10:
      return False
    number //= 10
    number_square //= 10
  return True


if __name__ == "__main__":
     import doctest

     doctest.testmod()





