


from typing import Dict, List, Optional, Union

import numpy as np

from ...image_processing_utils import BaseImageProcessor, BatchFeature, get_size_dict
from ...image_transforms import (
    center_crop,
    get_resize_output_image_size,
    normalize,
    rescale,
    resize,
    to_channel_dimension_format,
)
from ...image_utils import (
    IMAGENET_STANDARD_MEAN,
    IMAGENET_STANDARD_STD,
    ChannelDimension,
    ImageInput,
    PILImageResampling,
    make_list_of_images,
    to_numpy_array,
    valid_images,
)
from ...utils import TensorType, logging


UpperCAmelCase      =   logging.get_logger(__name__)







class lowerCAmelCase_						(			lowerCamelCase__	):

 '''simple docstring'''

 __snake_case												=  ["pixel_values"]



 def __init__(     self		,				_UpperCAmelCase = True		,				_UpperCAmelCase = None		,				_UpperCAmelCase = PILImageResampling.BILINEAR		,				_UpperCAmelCase = True		,				_UpperCAmelCase = None		,				_UpperCAmelCase = True		,				_UpperCAmelCase = 1 / 2_55		,				_UpperCAmelCase = True		,				_UpperCAmelCase = None		,				_UpperCAmelCase = None		,				**_UpperCAmelCase		,				):
       super().__init__(**_UpperCAmelCase )
       snake_case_	=				size if size is not None else {'''shortest_edge''': 2_56}
       snake_case_	=				get_size_dict(_UpperCAmelCase		,				default_to_square=_UpperCAmelCase )
       snake_case_	=				crop_size if crop_size is not None else {'''height''': 2_24, '''width''': 2_24}
       snake_case_	=				get_size_dict(_UpperCAmelCase )
       snake_case_	=				do_resize
       snake_case_	=				size
       snake_case_	=				resample
       snake_case_	=				do_center_crop
       snake_case_	=				crop_size
       snake_case_	=				do_rescale
       snake_case_	=				rescale_factor
       snake_case_	=				do_normalize
       snake_case_	=				image_mean if image_mean is not None else IMAGENET_STANDARD_MEAN
       snake_case_	=				image_std if image_std is not None else IMAGENET_STANDARD_STD



 def 						UpperCamelCase__					(     self		,				_UpperCAmelCase		,				_UpperCAmelCase		,				_UpperCAmelCase = PILImageResampling.BICUBIC		,				_UpperCAmelCase = None		,				**_UpperCAmelCase		,				):
       snake_case_	=				get_size_dict(_UpperCAmelCase		,				default_to_square=_UpperCAmelCase )
       if "shortest_edge" not in size:
             raise ValueError(F'''The `size` parameter must contain the key `shortest_edge`. Got {size.keys()}''' )
       snake_case_	=				get_resize_output_image_size(_UpperCAmelCase		,				size=size['''shortest_edge''']		,				default_to_square=_UpperCAmelCase )
       return resize(_UpperCAmelCase		,				size=_UpperCAmelCase		,				resample=_UpperCAmelCase		,				data_format=_UpperCAmelCase		,				**_UpperCAmelCase )



 def 						UpperCamelCase__					(     self		,				_UpperCAmelCase		,				_UpperCAmelCase		,				_UpperCAmelCase = None		,				**_UpperCAmelCase		,				):
       snake_case_	=				get_size_dict(_UpperCAmelCase )
       return center_crop(_UpperCAmelCase		,				size=(size['''height'''], size['''width'''])		,				data_format=_UpperCAmelCase		,				**_UpperCAmelCase )



 def 						UpperCamelCase__					(     self		,				_UpperCAmelCase		,				_UpperCAmelCase		,				_UpperCAmelCase = None		,				**_UpperCAmelCase ):
       return rescale(_UpperCAmelCase		,				scale=_UpperCAmelCase		,				data_format=_UpperCAmelCase		,				**_UpperCAmelCase )



 def 						UpperCamelCase__					(     self		,				_UpperCAmelCase		,				_UpperCAmelCase		,				_UpperCAmelCase		,				_UpperCAmelCase = None		,				**_UpperCAmelCase		,				):
       return normalize(_UpperCAmelCase		,				mean=_UpperCAmelCase		,				std=_UpperCAmelCase		,				data_format=_UpperCAmelCase		,				**_UpperCAmelCase )





 def 						UpperCamelCase__					(     self		,				_UpperCAmelCase		,				_UpperCAmelCase = None		,				_UpperCAmelCase = None		,				_UpperCAmelCase = None		,				_UpperCAmelCase = None		,				_UpperCAmelCase = None		,				_UpperCAmelCase = None		,				_UpperCAmelCase = None		,				_UpperCAmelCase = None		,				_UpperCAmelCase = None		,				_UpperCAmelCase = None		,				_UpperCAmelCase = None		,				_UpperCAmelCase = ChannelDimension.FIRST		,				**_UpperCAmelCase		,				):
       snake_case_	=				do_resize if do_resize is not None else self.do_resize
       snake_case_	=				size if size is not None else self.size
       snake_case_	=				get_size_dict(_UpperCAmelCase		,				default_to_square=_UpperCAmelCase )
       snake_case_	=				resample if resample is not None else self.resample
       snake_case_	=				do_center_crop if do_center_crop is not None else self.do_center_crop
       snake_case_	=				crop_size if crop_size is not None else self.crop_size
       snake_case_	=				get_size_dict(_UpperCAmelCase )
       snake_case_	=				do_rescale if do_rescale is not None else self.do_rescale
       snake_case_	=				rescale_factor if rescale_factor is not None else self.rescale_factor
       snake_case_	=				do_normalize if do_normalize is not None else self.do_normalize
       snake_case_	=				image_mean if image_mean is not None else self.image_mean
       snake_case_	=				image_std if image_std is not None else self.image_std

       snake_case_	=				make_list_of_images(_UpperCAmelCase )

       if not valid_images(_UpperCAmelCase ):
             raise ValueError(
                 '''Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, '''
                 '''torch.Tensor, tf.Tensor or jax.ndarray.''' )

       if do_resize and size is None:
             raise ValueError('''Size must be specified if do_resize is True.''' )

       if do_center_crop and crop_size is None:
             raise ValueError('''Crop size must be specified if do_center_crop is True.''' )

       if do_rescale and rescale_factor is None:
             raise ValueError('''Rescale factor must be specified if do_rescale is True.''' )

       if do_normalize and (image_mean is None or image_std is None):
             raise ValueError('''Image mean and std must be specified if do_normalize is True.''' )

       # All transformations expect numpy arrays.
       snake_case_	=				[to_numpy_array(_UpperCAmelCase ) for image in images]

       if do_resize:
             snake_case_	=				[self.resize(image=_UpperCAmelCase		,				size=_UpperCAmelCase		,				resample=_UpperCAmelCase ) for image in images]

       if do_center_crop:
             snake_case_	=				[self.center_crop(image=_UpperCAmelCase		,				size=_UpperCAmelCase ) for image in images]

       if do_rescale:
             snake_case_	=				[self.rescale(image=_UpperCAmelCase		,				scale=_UpperCAmelCase ) for image in images]

       if do_normalize:
             snake_case_	=				[self.normalize(image=_UpperCAmelCase		,				mean=_UpperCAmelCase		,				std=_UpperCAmelCase ) for image in images]

       snake_case_	=				[to_channel_dimension_format(_UpperCAmelCase		,				_UpperCAmelCase ) for image in images]

       snake_case_	=				{'''pixel_values''': images}
       return BatchFeature(data=_UpperCAmelCase		,				tensor_type=_UpperCAmelCase )



import numpy as np

import datasets


UpperCAmelCase      =   """
Compute the Mahalanobis Distance

Mahalonobis distance is the distance between a point and a distribution.
And not between two distinct points. It is effectively a multivariate equivalent of the Euclidean distance.
It was introduced by Prof. P. C. Mahalanobis in 1936
and has been used in various statistical applications ever since
[source: https://www.machinelearningplus.com/statistics/mahalanobis-distance/]
"""

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

UpperCAmelCase      =   """
Args:
    X: List of datapoints to be compared with the `reference_distribution`.
    reference_distribution: List of datapoints from the reference distribution we want to compare to.
Returns:
    mahalanobis: The Mahalonobis distance for each datapoint in `X`.
Examples:

    >>> mahalanobis_metric = datasets.load_metric(\"mahalanobis\")
    >>> results = mahalanobis_metric.compute(reference_distribution=[[0, 1], [1, 0]], X=[[0, 1]])
    >>> print(results)
    {'mahalanobis': array([0.5])}
"""







@datasets.utils.file_utils.add_start_docstrings(_DESCRIPTION ,						_KWARGS_DESCRIPTION	)
class lowerCAmelCase_						(			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		,				_UpperCAmelCase		,				_UpperCAmelCase ):
       # convert to numpy arrays
       snake_case_	=				np.array(_UpperCAmelCase )
       snake_case_	=				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
       snake_case_	=				X - np.mean(_UpperCAmelCase )
       snake_case_	=				np.cov(reference_distribution.T )
       try:
             snake_case_	=				np.linalg.inv(_UpperCAmelCase )
       except np.linalg.LinAlgError:
             snake_case_	=				np.linalg.pinv(_UpperCAmelCase )
       snake_case_	=				np.dot(_UpperCAmelCase		,				_UpperCAmelCase )
       snake_case_	=				np.dot(_UpperCAmelCase		,				X_minus_mu.T ).diagonal()

       return {"mahalanobis": mahal_dist}