



'''simple docstring'''





import numpy as np

import datasets


SCREAMING_SNAKE_CASE__      					=     "\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"

SCREAMING_SNAKE_CASE__      					=     "\\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"

SCREAMING_SNAKE_CASE__      					=     "\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 				snake_case__ (datasets.Metric   ):



       def 							_a      (				self      )  ->							Dict:
           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 							_a      (				self     ,UpperCAmelCase_     ,UpperCAmelCase_      )  ->							str:
           lowercase__		       =						np.array(UpperCAmelCase__      )
           lowercase__		       =						np.array(UpperCAmelCase__      )

           # 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
           lowercase__		       =						X - np.mean(UpperCAmelCase__      )
           lowercase__		       =						np.cov(reference_distribution.T      )
           try:
               lowercase__		       =						np.linalg.inv(UpperCAmelCase__      )
           except np.linalg.LinAlgError:
               lowercase__		       =						np.linalg.pinv(UpperCAmelCase__      )
           lowercase__		       =						np.dot(UpperCAmelCase__     ,UpperCAmelCase__      )
           lowercase__		       =						np.dot(UpperCAmelCase__     ,X_minus_mu.T      ).diagonal()

           return {"mahalanobis": mahal_dist}









'''simple docstring'''





def        lowerCamelCase  (				_snake_case  :						List[str]       ):  # noqa: E741





    '''simple docstring'''


    lowercase__		       =						len(_snake_case       )
    lowercase__		       =						0
    lowercase__		       =						[0] * n
    lowercase__		       =						[False] * n
    lowercase__		       =						[False] * n

    def dfs(_snake_case  :						Tuple     ,_snake_case  :						int     ,_snake_case  :						List[str]     ,_snake_case  :						str       ):
        if parent == root:
            out_edge_count += 1
        lowercase__		       =						True
        lowercase__		       =						at

        for to in l[at]:
            if to == parent:
                pass
            elif not visited[to]:
                lowercase__		       =						dfs(_snake_case     ,_snake_case     ,_snake_case     ,_snake_case       )
                lowercase__		       =						min(low[at]     ,low[to]       )

                # AP found via bridge
                if at < low[to]:
                    lowercase__		       =						True
                # AP found via cycle
                if at == low[to]:
                    lowercase__		       =						True
            else:
                lowercase__		       =						min(low[at]     ,_snake_case       )
        return out_edge_count

    for i in range(_snake_case       ):
        if not visited[i]:
            lowercase__		       =						0
            lowercase__		       =						dfs(_snake_case     ,_snake_case     ,-1     ,_snake_case       )
            lowercase__		       =						out_edge_count > 1

    for x in range(len(_snake_case       )       ):
        if is_art[x] is True:
            print(_snake_case       )


# Adjacency list of graph
SCREAMING_SNAKE_CASE__      					=     {
    0: [1, 2],
    1: [0, 2],
    2: [0, 1, 3, 5],
    3: [2, 4],
    4: [3],
    5: [2, 6, 8],
    6: [5, 7],
    7: [6, 8],
    8: [5, 7],
}



compute_ap(data)




