




from typing import Callable, Dict, Optional, Tuple

import torch
from torch import nn
from torch.distributions import (
    AffineTransform,
    Distribution,
    Independent,
    NegativeBinomial,
    Normal,
    StudentT,
    TransformedDistribution,
)







class 						lowercase							(   UpperCamelCase__		):

     def __init__(  self		,     _a		,     _a=None		,     _a=None		,     _a=0				)						->							List[Any]:
           _A							:     int			=						1.0 if scale is None else scale
           _A							:     Dict			=						0.0 if loc is None else loc

           super().__init__(_a		,     [AffineTransform(loc=self.loc		,     scale=self.scale		,     event_dim=_a				)]				)

     @property
     def 					a__	(  self				)						->							Tuple:
           return self.base_dist.mean * self.scale + self.loc

     @property
     def 					a__	(  self				)						->							int:
           return self.base_dist.variance * self.scale**2



     @property
     def 					a__	(  self				)						->							Tuple:
           return self.variance.sqrt()







class 						lowercase							(   nn.Module		):

     def __init__(  self		,     _a		,     _a		,     _a		,     **_a				)						->							None:
           super().__init__(**_a				)
           _A							:     List[Any]			=						args_dim
           _A							:     Optional[Any]			=						nn.ModuleList([nn.Linear(_a		,     _a				) for dim in args_dim.values()]				)
           _A							:     Dict			=						domain_map



     def 					a__	(  self		,     _a				)						->							Tuple[torch.Tensor]:
           _A							:     Optional[Any]			=						[proj(_a				) for proj in self.proj]

           return self.domain_map(*_a				)







class 						lowercase							(   nn.Module		):

     def __init__(  self		,     _a				)						->							List[Any]:
           super().__init__()
           _A							:     Any			=						function



     def 					a__	(  self		,     _a		,     *_a				)						->							Optional[int]:
           return self.function(_a		,     *_a				)







class 						lowercase							:
     _a							 =						42
     _a							 =						42
     _a							 =						42

     def __init__(  self		,     _a = 1				)						->							None:
           _A							:     Tuple			=						dim
           _A							:     Tuple			=						{k: dim * self.args_dim[k] for k in self.args_dim}

     def 					a__	(  self		,     _a				)						->							Optional[int]:
           if self.dim == 1:
                 return self.distribution_class(*_a				)
           else:
                 return Independent(self.distribution_class(*_a				)		,     1				)

     def 					a__	(  self		,     _a		,     _a = None		,     _a = None		,     )						->							Distribution:
           _A							:     Union[str, Any]			=						self._base_distribution(_a				)
           if loc is None and scale is None:
                 return distr
           else:
                 return AffineTransformed(_a		,     loc=_a		,     scale=_a		,     event_dim=self.event_dim				)

     @property
     def 					a__	(  self				)						->							Tuple:
           return () if self.dim == 1 else (self.dim,)

     @property
     def 					a__	(  self				)						->							int:
           return len(self.event_shape				)

     @property
     def 					a__	(  self				)						->							float:
           return 0.0

     def 					a__	(  self		,     _a				)						->							nn.Module:
           return ParameterProjection(
               in_features=_a		,     args_dim=self.args_dim		,     domain_map=LambdaLayer(self.domain_map				)		,     )

     def 					a__	(  self		,     *_a				)						->							Dict:
           raise NotImplementedError()



     @staticmethod
     def 					a__	(  _a				)						->							torch.Tensor:
           return (x + torch.sqrt(torch.square(_a				) + 4.0				)) / 2.0







class 						lowercase							(   UpperCamelCase__		):
     _a							 =						{"df": 1, "loc": 1, "scale": 1}
     _a							 =						StudentT

     @classmethod
     def 					a__	(  cls		,     _a		,     _a		,     _a				)						->							int:
           _A							:     int			=						cls.squareplus(_a				).clamp_min(torch.finfo(scale.dtype				).eps				)
           _A							:     Any			=						2.0 + cls.squareplus(_a				)
           return df.squeeze(-1				), loc.squeeze(-1				), scale.squeeze(-1				)







class 						lowercase							(   UpperCamelCase__		):
     _a							 =						{"loc": 1, "scale": 1}
     _a							 =						Normal

     @classmethod
     def 					a__	(  cls		,     _a		,     _a				)						->							List[Any]:
           _A							:     List[str]			=						cls.squareplus(_a				).clamp_min(torch.finfo(scale.dtype				).eps				)
           return loc.squeeze(-1				), scale.squeeze(-1				)







class 						lowercase							(   UpperCamelCase__		):
     _a							 =						{"total_count": 1, "logits": 1}
     _a							 =						NegativeBinomial

     @classmethod
     def 					a__	(  cls		,     _a		,     _a				)						->							Union[str, Any]:
           _A							:     List[str]			=						cls.squareplus(_a				)
           return total_count.squeeze(-1				), logits.squeeze(-1				)

     def 					a__	(  self		,     _a				)						->							Distribution:
           _A			,   _A							:     Tuple			=						distr_args
           if self.dim == 1:
                 return self.distribution_class(total_count=_a		,     logits=_a				)
           else:
                 return Independent(self.distribution_class(total_count=_a		,     logits=_a				)		,     1				)



     def 					a__	(  self		,     _a		,     _a = None		,     _a = None				)						->							Distribution:
           _A			,   _A							:     List[Any]			=						distr_args

           if scale is not None:
                 # See scaling property of Gamma.
                 logits += scale.log()

           return self._base_distribution((total_count, logits)				)







from math import asin, atan, cos, radians, sin, sqrt, tan

_snake_case										=       6_3_7_8_1_3_7.0
_snake_case										=       6_3_5_6_7_5_2.3_1_4_2_4_5
_snake_case										=       6378137







def 				lowerCAmelCase_	(     snake_case_,snake_case_,snake_case_,snake_case_     ):
      _A							:     Any			=						(AXIS_A - AXIS_B) / AXIS_A
      _A							:     Optional[int]			=						atan((1 - flattening) * tan(radians(snake_case_     )     )     )
      _A							:     List[str]			=						atan((1 - flattening) * tan(radians(snake_case_     )     )     )
      _A							:     Optional[Any]			=						radians(snake_case_     )
      _A							:     str			=						radians(snake_case_     )
      # Equation
      _A							:     Dict			=						sin((phi_a - phi_a) / 2     )
      _A							:     List[str]			=						sin((lambda_a - lambda_a) / 2     )
      # Square both values
      sin_sq_phi *= sin_sq_phi
      sin_sq_lambda *= sin_sq_lambda
      _A							:     Optional[int]			=						sqrt(sin_sq_phi + (cos(snake_case_     ) * cos(snake_case_     ) * sin_sq_lambda)     )
      return 2 * RADIUS * asin(snake_case_     )


if __name__ == "__main__":
  import doctest

  doctest.testmod()

