






import numpy as np

import datasets


UpperCamelCase    :      List[Any]  			=		'\nCompute the Mahalanobis Distance\n\nMahalonobis distance is the distance between a point and a distribution.\nAnd not between two distinct points. It is effectively a multivariate equivalent of the Euclidean distance.\nIt was introduced by Prof. P. C. Mahalanobis in 1936\nand has been used in various statistical applications ever since\n[source: https://www.machinelearningplus.com/statistics/mahalanobis-distance/]\n'

UpperCamelCase    :      Dict  			=		'\\n@article{de2000mahalanobis,\n  title={The mahalanobis distance},\n  author={De Maesschalck, Roy and Jouan-Rimbaud, Delphine and Massart, D{\'e}sir{\'e} L},\n  journal={Chemometrics and intelligent laboratory systems},\n  volume={50},\n  number={1},\n  pages={1--18},\n  year={2000},\n  publisher={Elsevier}\n}\n'

UpperCamelCase    :      Any  			=		'\nArgs:\n    X: List of datapoints to be compared with the `reference_distribution`.\n    reference_distribution: List of datapoints from the reference distribution we want to compare to.\nReturns:\n    mahalanobis: The Mahalonobis distance for each datapoint in `X`.\nExamples:\n\n    >>> mahalanobis_metric = datasets.load_metric("mahalanobis")\n    >>> results = mahalanobis_metric.compute(reference_distribution=[[0, 1], [1, 0]], X=[[0, 1]])\n    >>> print(results)\n    {\'mahalanobis\': array([0.5])}\n'




@datasets.utils.file_utils.add_start_docstrings(_DESCRIPTION   ,_KWARGS_DESCRIPTION			)
class 		UpperCamelCase__    (datasets.Metric			):




		'''simple docstring'''





		def 			UpperCamelCase_					(      self       ):
								return datasets.MetricInfo(
								    description=_DESCRIPTION   ,citation=_CITATION   ,inputs_description=_KWARGS_DESCRIPTION   ,features=datasets.Features(
								        {
								            """X""": datasets.Sequence(datasets.Value("""float"""   ,id="""sequence"""       )   ,id="""X"""       ),
								        }       )   ,)






		def 			UpperCamelCase_					(      self   ,_lowerCAmelCase   ,_lowerCAmelCase       ):
								# convert to numpy arrays
								lowerCamelCase__         =  np.array(_lowerCAmelCase       )
								lowerCamelCase__         =  np.array(_lowerCAmelCase       )

								# Assert that arrays are 2D
								if len(X.shape       ) != 2:
														raise ValueError("""Expected `X` to be a 2D vector"""       )
								if len(reference_distribution.shape       ) != 2:
														raise ValueError("""Expected `reference_distribution` to be a 2D vector"""       )
								if reference_distribution.shape[0] < 2:
														raise ValueError(
														    """Expected `reference_distribution` to be a 2D vector with more than one element in the first dimension"""       )

								# Get mahalanobis distance for each prediction
								lowerCamelCase__         =  X - np.mean(_lowerCAmelCase       )
								lowerCamelCase__         =  np.cov(reference_distribution.T       )
								try:
														lowerCamelCase__         =  np.linalg.inv(_lowerCAmelCase       )
								except np.linalg.LinAlgError:
														lowerCamelCase__         =  np.linalg.pinv(_lowerCAmelCase       )
								lowerCamelCase__         =  np.dot(_lowerCAmelCase   ,_lowerCAmelCase       )
								lowerCamelCase__         =  np.dot(_lowerCAmelCase   ,X_minus_mu.T       ).diagonal()

								return {"mahalanobis": mahal_dist}









'''simple docstring'''







import numpy

# List of input, output pairs
UpperCamelCase    :      List[Any]  			=		(
    ((5, 2, 3), 15),
    ((6, 5, 9), 25),
    ((11, 12, 13), 41),
    ((1, 1, 1), 8),
    ((11, 12, 13), 41),
)
UpperCamelCase    :      Optional[int]  			=		(((5_15, 22, 13), 5_55), ((61, 35, 49), 1_50))
UpperCamelCase    :      int  			=		[2, 4, 1, 5]
UpperCamelCase    :      int  			=		len(train_data)
UpperCamelCase    :      Dict  			=		0.009
def 						A__			(				__lowerCAmelCase		:			int   ,    __lowerCAmelCase		:			str="train"						):
						return calculate_hypothesis_value(__lowerCAmelCase   ,    __lowerCAmelCase						) - output(
						    __lowerCAmelCase   ,    __lowerCAmelCase						)
def 						A__			(				__lowerCAmelCase		:			Any						):
						lowerCamelCase__         =  0
						for i in range(len(__lowerCAmelCase						) - 1						):
												hyp_val += data_input_tuple[i] * parameter_vector[i + 1]
						hyp_val += parameter_vector[0]
						return hyp_val
def 						A__			(				__lowerCAmelCase		:			Optional[Any]   ,    __lowerCAmelCase		:			Tuple						):
						if data_set == "train":
												return train_data[example_no][1]
						elif data_set == "test":
												return test_data[example_no][1]
						return None
def 						A__			(				__lowerCAmelCase		:			int   ,    __lowerCAmelCase		:			Dict						):
						if data_set == "train":
												return _hypothesis_value(train_data[example_no][0]						)
						elif data_set == "test":
												return _hypothesis_value(test_data[example_no][0]						)
						return None
def 						A__			(				__lowerCAmelCase		:			List[Any]   ,    __lowerCAmelCase		:			Optional[Any]=m						):
						lowerCamelCase__         =  0
						for i in range(__lowerCAmelCase						):
												if index == -1:
																		summation_value += _error(__lowerCAmelCase						)
												else:
																		summation_value += _error(__lowerCAmelCase						) * train_data[i][0][index]
						return summation_value
def 						A__			(				__lowerCAmelCase		:			List[Any]						):
						lowerCamelCase__         =  summation_of_cost_derivative(__lowerCAmelCase   ,    __lowerCAmelCase						) / m
						return cost_derivative_value
def 						A__			(				):
						global parameter_vector
						# Tune these values to set a tolerance value for predicted output
						lowerCamelCase__         =  0.00_0002
						lowerCamelCase__         =  0
						lowerCamelCase__         =  0
						while True:
												j += 1
												lowerCamelCase__         =  [0, 0, 0, 0]
												for i in range(0   ,    len(__lowerCAmelCase						)						):
																		lowerCamelCase__         =  get_cost_derivative(i - 1						)
																		lowerCamelCase__         =  (
																		    parameter_vector[i] - LEARNING_RATE * cost_derivative
																		)
												if numpy.allclose(
												    __lowerCAmelCase   ,    __lowerCAmelCase   ,    atol=__lowerCAmelCase   ,    rtol=__lowerCAmelCase   ,    ):
																		break
												lowerCamelCase__         =  temp_parameter_vector
						print(("""Number of iterations:""", j)						)
def 						A__			(				):
						for i in range(len(__lowerCAmelCase						)						):
												print(("""Actual output value:""", output(__lowerCAmelCase   ,    """test"""						))						)
												print(("""Hypothesis output:""", calculate_hypothesis_value(__lowerCAmelCase   ,    """test"""						))						)


if __name__ == "__main__":
							run_gradient_descent()
							print('\nTesting gradient descent for a linear hypothesis function.\n')
							test_gradient_descent()

