
from typing import Any

import numpy as np



def      _a     (   __UpperCamelCase       :  np.ndarray    ):
			assert np.shape(__UpperCamelCase    )[0] == np.shape(__UpperCamelCase    )[1]

			# If matrix not symmetric, exit right away.
			if np.allclose(__UpperCamelCase	,matrix.T    ) is False:
						return False

			# Get eigenvalues and eignevectors for a symmetric matrix.
			lowerCAmelCase__      ,				lowerCAmelCase__ :    Optional[Any]				      =			np.linalg.eigh(__UpperCamelCase    )

			# Check sign of all eigenvalues.
			# np.all returns a value of type np.bool_
			return bool(np.all(eigen_values > 0    )    )



def      _a     (   __UpperCamelCase       :  int    ):
			lowerCAmelCase__ :    Optional[Any]				      =			np.random.randn(__UpperCamelCase	,__UpperCamelCase    )
			lowerCAmelCase__ :    Optional[int]				      =			np.dot(__UpperCamelCase	,random_matrix.T    )
			assert _is_matrix_spd(__UpperCamelCase    )
			return spd_matrix



def      _a     (   __UpperCamelCase       :  np.ndarray	,__UpperCamelCase       :  np.ndarray	,__UpperCamelCase       :  int = 1000	,__UpperCamelCase       :  float = 1e-8	,):
			assert np.shape(__UpperCamelCase    )[0] == np.shape(__UpperCamelCase    )[1]
			assert np.shape(__UpperCamelCase    )[0] == np.shape(__UpperCamelCase    )[0]
			assert _is_matrix_spd(__UpperCamelCase    )

			# Initialize solution guess, residual, search direction.
			lowerCAmelCase__ :    Tuple				      =			np.zeros((np.shape(__UpperCamelCase    )[0], 1)    )
			lowerCAmelCase__ :    Union[str, Any]				      =			np.copy(__UpperCamelCase    )
			lowerCAmelCase__ :    int				      =			np.copy(__UpperCamelCase    )

			# Set initial errors in solution guess and residual.
			lowerCAmelCase__ :    Union[str, Any]				      =			1e9
			lowerCAmelCase__ :    Any				      =			1e9
			lowerCAmelCase__ :    List[Any]				      =			1e9

			# Set iteration counter to threshold number of iterations.
			lowerCAmelCase__ :    List[str]				      =			0

			while error > tol:
						# Save this value so we only calculate the matrix-vector product once.
						lowerCAmelCase__ :    Optional[int]				      =			np.dot(__UpperCamelCase	,__UpperCamelCase    )

						# The main algorithm.

						# Update search direction magnitude.
						lowerCAmelCase__ :    str				      =			np.dot(ra.T	,__UpperCamelCase    ) / np.dot(pa.T	,__UpperCamelCase    )
						# Update solution guess.
						lowerCAmelCase__ :    Any				      =			xa + alpha * pa
						# Calculate new residual.
						lowerCAmelCase__ :    str				      =			ra - alpha * w
						# Calculate new Krylov subspace scale.
						lowerCAmelCase__ :    Dict				      =			np.dot(r.T	,__UpperCamelCase    ) / np.dot(ra.T	,__UpperCamelCase    )
						# Calculate new A conjuage search direction.
						lowerCAmelCase__ :    Optional[Any]				      =			r + beta * pa

						# Calculate errors.
						lowerCAmelCase__ :    Tuple				      =			np.linalg.norm(r - ra    )
						lowerCAmelCase__ :    List[Any]				      =			np.linalg.norm(x - xa    )
						lowerCAmelCase__ :    Optional[Any]				      =			np.maximum(__UpperCamelCase	,__UpperCamelCase    )

						# Update variables.
						lowerCAmelCase__ :    Union[str, Any]				      =			np.copy(__UpperCamelCase    )
						lowerCAmelCase__ :    Any				      =			np.copy(__UpperCamelCase    )
						lowerCAmelCase__ :    str				      =			np.copy(__UpperCamelCase    )

						# Update number of iterations.
						iterations += 1
						if iterations > max_iterations:
									break

			return x



def      _a     (   ):
			lowerCAmelCase__ :    int				      =			3
			lowerCAmelCase__ :    Optional[int]				      =			_create_spd_matrix(__UpperCamelCase    )
			lowerCAmelCase__ :    List[Any]				      =			np.random.randn(__UpperCamelCase	,1    )
			lowerCAmelCase__ :    Any				      =			np.dot(__UpperCamelCase	,__UpperCamelCase    )

			# Numpy solution.
			lowerCAmelCase__ :    Optional[int]				      =			np.linalg.solve(__UpperCamelCase	,__UpperCamelCase    )

			# Our implementation.
			lowerCAmelCase__ :    Any				      =			conjugate_gradient(__UpperCamelCase	,__UpperCamelCase    )

			# Ensure both solutions are close to x_true (and therefore one another).
			assert np.linalg.norm(x_numpy - x_true    ) <= 1e-6
			assert np.linalg.norm(x_conjugate_gradient - x_true    ) <= 1e-6


if __name__ == "__main__":
							import doctest

							doctest.testmod()
							test_conjugate_gradient()





from math import radians as angle_to_radians
from math import sin

# Acceleration Constant on Earth (unit m/s^2)
A__       :   str   						=					9.8_0665



def      _a     (   __UpperCamelCase       :  float	,__UpperCamelCase       :  float    ):

			# Ensure valid instance
			if not isinstance(__UpperCamelCase	,(int, float)    ):
						raise TypeError('''Invalid velocity. Should be a positive number.'''    )

			if not isinstance(__UpperCamelCase	,(int, float)    ):
						raise TypeError('''Invalid angle. Range is 1-90 degrees.'''    )

			# Ensure valid angle
			if angle > 90 or angle < 1:
						raise ValueError('''Invalid angle. Range is 1-90 degrees.'''    )

			# Ensure valid velocity
			if init_velocity < 0:
						raise ValueError('''Invalid velocity. Should be a positive number.'''    )



def      _a     (   __UpperCamelCase       :  float	,__UpperCamelCase       :  float    ):
			check_args(__UpperCamelCase	,__UpperCamelCase    )
			lowerCAmelCase__ :    Union[str, Any]				      =			angle_to_radians(2 * angle    )
			return round(init_velocity**2 * sin(__UpperCamelCase    ) / g	,2    )



def      _a     (   __UpperCamelCase       :  float	,__UpperCamelCase       :  float    ):
			check_args(__UpperCamelCase	,__UpperCamelCase    )
			lowerCAmelCase__ :    List[str]				      =			angle_to_radians(__UpperCamelCase    )
			return round(init_velocity**2 * sin(__UpperCamelCase    ) ** 2 / (2 * g)	,2    )



def      _a     (   __UpperCamelCase       :  float	,__UpperCamelCase       :  float    ):
			check_args(__UpperCamelCase	,__UpperCamelCase    )
			lowerCAmelCase__ :    Dict				      =			angle_to_radians(__UpperCamelCase    )
			return round(2 * init_velocity * sin(__UpperCamelCase    ) / g	,2    )



def      _a     (   ):
			lowerCAmelCase__      ,				lowerCAmelCase__ :    List[Any]				      =			25, 20
			assert horizontal_distance(__UpperCamelCase	,__UpperCamelCase    ) == 40.97
			assert max_height(__UpperCamelCase	,__UpperCamelCase    ) == 3.73
			assert total_time(__UpperCamelCase	,__UpperCamelCase    ) == 1.74


if __name__ == "__main__":
							from doctest import testmod

							testmod()

							# Get input from user
							A__       :   List[Any]   						=					float(input("""Initial Velocity: """).strip())

							# Get input from user
							A__       :   Optional[Any]   						=					float(input("""angle: """).strip())

							# Print results
							print()
							print("""Results: """)
							print(f"""Horizontal Distance: {horizontal_distance(init_vel, angle)!s} [m]""")
							print(f"""Maximum Height: {max_height(init_vel, angle)!s} [m]""")
							print(f"""Total Time: {total_time(init_vel, angle)!s} [s]""")



