


import warnings
from typing import List

import numpy as np

from ...processing_utils import ProcessorMixin
from ...tokenization_utils_base import BatchEncoding
from ...utils import is_flax_available, is_tf_available, is_torch_available







class lowerCAmelCase_						(			lowerCamelCase__	):

 '''simple docstring'''

 __snake_case												=  ["image_processor", "tokenizer"]
 __snake_case												=  "OwlViTImageProcessor"
 __snake_case												=  ("CLIPTokenizer", "CLIPTokenizerFast")



 def __init__(     self		,				_UpperCAmelCase=None		,				_UpperCAmelCase=None		,				**_UpperCAmelCase ):
       snake_case_	=				None
       if "feature_extractor" in kwargs:
             warnings.warn(
                 '''The `feature_extractor` argument is deprecated and will be removed in v5, use `image_processor`'''
                 ''' instead.'''		,				_UpperCAmelCase		,				)
             snake_case_	=				kwargs.pop('''feature_extractor''' )

       snake_case_	=				image_processor if image_processor is not None else feature_extractor
       if image_processor is None:
             raise ValueError('''You need to specify an `image_processor`.''' )
       if tokenizer is None:
             raise ValueError('''You need to specify a `tokenizer`.''' )

       super().__init__(_UpperCAmelCase		,				_UpperCAmelCase )



 def __call__(     self		,				_UpperCAmelCase=None		,				_UpperCAmelCase=None		,				_UpperCAmelCase=None		,				_UpperCAmelCase="max_length"		,				_UpperCAmelCase="np"		,				**_UpperCAmelCase ):

       if text is None and query_images is None and images is None:
             raise ValueError(
                 '''You have to specify at least one text or query image or image. All three cannot be none.''' )

       if text is not None:
             if isinstance(_UpperCAmelCase		,				_UpperCAmelCase ) or (isinstance(_UpperCAmelCase		,				_UpperCAmelCase ) and not isinstance(text[0]		,				_UpperCAmelCase )):
                   snake_case_	=				[self.tokenizer(_UpperCAmelCase		,				padding=_UpperCAmelCase		,				return_tensors=_UpperCAmelCase		,				**_UpperCAmelCase )]

             elif isinstance(_UpperCAmelCase		,				_UpperCAmelCase ) and isinstance(text[0]		,				_UpperCAmelCase ):
                   snake_case_	=				[]

                   # Maximum number of queries across batch
                   snake_case_	=				max([len(_UpperCAmelCase ) for t in text] )

                   # Pad all batch samples to max number of text queries
                   for t in text:
                         if len(_UpperCAmelCase ) != max_num_queries:
                               snake_case_	=				t + [''' '''] * (max_num_queries - len(_UpperCAmelCase ))

                         snake_case_	=				self.tokenizer(_UpperCAmelCase		,				padding=_UpperCAmelCase		,				return_tensors=_UpperCAmelCase		,				**_UpperCAmelCase )
                         encodings.append(_UpperCAmelCase )
             else:
                   raise TypeError('''Input text should be a string, a list of strings or a nested list of strings''' )

             if return_tensors == "np":
                   snake_case_	=				np.concatenate([encoding['''input_ids'''] for encoding in encodings]		,				axis=0 )
                   snake_case_	=				np.concatenate([encoding['''attention_mask'''] for encoding in encodings]		,				axis=0 )

             elif return_tensors == "jax" and is_flax_available():
                   import jax.numpy as jnp

                   snake_case_	=				jnp.concatenate([encoding['''input_ids'''] for encoding in encodings]		,				axis=0 )
                   snake_case_	=				jnp.concatenate([encoding['''attention_mask'''] for encoding in encodings]		,				axis=0 )

             elif return_tensors == "pt" and is_torch_available():
                   import torch

                   snake_case_	=				torch.cat([encoding['''input_ids'''] for encoding in encodings]		,				dim=0 )
                   snake_case_	=				torch.cat([encoding['''attention_mask'''] for encoding in encodings]		,				dim=0 )

             elif return_tensors == "tf" and is_tf_available():
                   import tensorflow as tf

                   snake_case_	=				tf.stack([encoding['''input_ids'''] for encoding in encodings]		,				axis=0 )
                   snake_case_	=				tf.stack([encoding['''attention_mask'''] for encoding in encodings]		,				axis=0 )

             else:
                   raise ValueError('''Target return tensor type could not be returned''' )

             snake_case_	=				BatchEncoding()
             snake_case_	=				input_ids
             snake_case_	=				attention_mask

       if query_images is not None:
             snake_case_	=				BatchEncoding()
             snake_case_	=				self.image_processor(
                 _UpperCAmelCase		,				return_tensors=_UpperCAmelCase		,				**_UpperCAmelCase ).pixel_values
             snake_case_	=				query_pixel_values

       if images is not None:
             snake_case_	=				self.image_processor(_UpperCAmelCase		,				return_tensors=_UpperCAmelCase		,				**_UpperCAmelCase )

       if text is not None and images is not None:
             snake_case_	=				image_features.pixel_values
             return encoding
       elif query_images is not None and images is not None:
             snake_case_	=				image_features.pixel_values
             return encoding
       elif text is not None or query_images is not None:
             return encoding
       else:
             return BatchEncoding(data=dict(**_UpperCAmelCase )		,				tensor_type=_UpperCAmelCase )



 def 						UpperCamelCase__					(     self		,				*_UpperCAmelCase		,				**_UpperCAmelCase ):
       return self.image_processor.post_process(*_UpperCAmelCase		,				**_UpperCAmelCase )



 def 						UpperCamelCase__					(     self		,				*_UpperCAmelCase		,				**_UpperCAmelCase ):
       return self.image_processor.post_process_object_detection(*_UpperCAmelCase		,				**_UpperCAmelCase )



 def 						UpperCamelCase__					(     self		,				*_UpperCAmelCase		,				**_UpperCAmelCase ):
       return self.image_processor.post_process_image_guided_detection(*_UpperCAmelCase		,				**_UpperCAmelCase )



 def 						UpperCamelCase__					(     self		,				*_UpperCAmelCase		,				**_UpperCAmelCase ):
       return self.tokenizer.batch_decode(*_UpperCAmelCase		,				**_UpperCAmelCase )



 def 						UpperCamelCase__					(     self		,				*_UpperCAmelCase		,				**_UpperCAmelCase ):
       return self.tokenizer.decode(*_UpperCAmelCase		,				**_UpperCAmelCase )



 @property
 def 						UpperCamelCase__					(     self ):
       warnings.warn(
           '''`feature_extractor_class` is deprecated and will be removed in v5. Use `image_processor_class` instead.'''		,				_UpperCAmelCase		,				)
       return self.image_processor_class





 @property
 def 						UpperCamelCase__					(     self ):
       warnings.warn(
           '''`feature_extractor` is deprecated and will be removed in v5. Use `image_processor` instead.'''		,				_UpperCAmelCase		,				)
       return self.image_processor



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}