




import re

import jax.numpy as jnp
from flax.traverse_util import flatten_dict, unflatten_dict
from jax.random import PRNGKey

from ..utils import logging


UpperCAmelCase_		:				Optional[Any]									=     logging.get_logger(__name__)




def 		lowerCAmelCase_   (	lowerCamelCase   ):
				__magic_name__	:	List[str]								=R"""\w+[.]\d+"""
				__magic_name__	:	Tuple								=re.findall(lowerCamelCase	,     lowerCamelCase   )
				for pat in pats:
								__magic_name__	:	Tuple								=key.replace(lowerCamelCase	,     """_""".join(pat.split("""."""   )   )   )
				return key




def 		lowerCAmelCase_   (	lowerCamelCase	,     lowerCamelCase	,     lowerCamelCase   ):
				__magic_name__	:	Any								=pt_tuple_key[:-1] + ("""scale""",)
				if (
				    any("""norm""" in str_ for str_ in pt_tuple_key   )
				    and (pt_tuple_key[-1] == "bias")
				    and (pt_tuple_key[:-1] + ("bias",) not in random_flax_state_dict)
				    and (pt_tuple_key[:-1] + ("scale",) in random_flax_state_dict)
				):
								__magic_name__	:	List[str]								=pt_tuple_key[:-1] + ("""scale""",)
								return renamed_pt_tuple_key, pt_tensor
				elif pt_tuple_key[-1] in ["weight", "gamma"] and pt_tuple_key[:-1] + ("scale",) in random_flax_state_dict:
								__magic_name__	:	int								=pt_tuple_key[:-1] + ("""scale""",)
								return renamed_pt_tuple_key, pt_tensor

				# embedding
				if pt_tuple_key[-1] == "weight" and pt_tuple_key[:-1] + ("embedding",) in random_flax_state_dict:
								__magic_name__	:	Union[str, Any]								=pt_tuple_key[:-1] + ("""embedding""",)
								return renamed_pt_tuple_key, pt_tensor

				# conv layer
				__magic_name__	:	Any								=pt_tuple_key[:-1] + ("""kernel""",)
				if pt_tuple_key[-1] == "weight" and pt_tensor.ndim == 4:
								__magic_name__	:	Optional[int]								=pt_tensor.transpose(2	,     3	,     1	,     0   )
								return renamed_pt_tuple_key, pt_tensor

				# linear layer
				__magic_name__	:	Dict								=pt_tuple_key[:-1] + ("""kernel""",)
				if pt_tuple_key[-1] == "weight":
								__magic_name__	:	int								=pt_tensor.T
								return renamed_pt_tuple_key, pt_tensor

				# old PyTorch layer norm weight
				__magic_name__	:	Tuple								=pt_tuple_key[:-1] + ("""weight""",)
				if pt_tuple_key[-1] == "gamma":
								return renamed_pt_tuple_key, pt_tensor

				# old PyTorch layer norm bias
				__magic_name__	:	Any								=pt_tuple_key[:-1] + ("""bias""",)
				if pt_tuple_key[-1] == "beta":
								return renamed_pt_tuple_key, pt_tensor

				return pt_tuple_key, pt_tensor




def 		lowerCAmelCase_   (	lowerCamelCase	,     lowerCamelCase	,     lowerCamelCase=42   ):
				# Step 1: Convert pytorch tensor to numpy
				__magic_name__	:	Any								={k: v.numpy() for k, v in pt_state_dict.items()}

				# Step 2: Since the model is stateless, get random Flax params
				__magic_name__	:	Any								=flax_model.init_weights(PRNGKey(lowerCamelCase   )   )

				__magic_name__	:	Dict								=flatten_dict(lowerCamelCase   )
				__magic_name__	:	Dict								={}

				# Need to change some parameters name to match Flax names
				for pt_key, pt_tensor in pt_state_dict.items():
								__magic_name__	:	str								=rename_key(lowerCamelCase   )
								__magic_name__	:	Union[str, Any]								=tuple(renamed_pt_key.split("""."""   )   )

								# Correctly rename weight parameters
								__magic_name__				, __magic_name__	:	int								=rename_key_and_reshape_tensor(lowerCamelCase	,     lowerCamelCase	,     lowerCamelCase   )

								if flax_key in random_flax_state_dict:
												if flax_tensor.shape != random_flax_state_dict[flax_key].shape:
																raise ValueError(
																    F"PyTorch checkpoint seems to be incorrect. Weight {pt_key} was expected to be of shape "
																    F"{random_flax_state_dict[flax_key].shape}, but is {flax_tensor.shape}."   )

        # also add unexpected weight so that warning is thrown
								__magic_name__	:	Optional[int]								=jnp.asarray(lowerCamelCase   )

				return unflatten_dict(lowerCamelCase   )










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

from .haversine_distance import haversine_distance

UpperCAmelCase_		:				Dict									=     637_8137.0
UpperCAmelCase_		:				List[Any]									=     635_6752.31_4245
UpperCAmelCase_		:				List[str]									=     6378137




def 		lowerCAmelCase_   (	lowerCamelCase	,     lowerCamelCase	,     lowerCamelCase	,     lowerCamelCase   ):
				__magic_name__	:	str								=(AXIS_A - AXIS_B) / AXIS_A
				# Parametric latitudes
				# https://en.wikipedia.org/wiki/Latitude#Parametric_(or_reduced)_latitude
				__magic_name__	:	str								=atan((1 - flattening) * tan(radians(lowerCamelCase   )   )   )
				__magic_name__	:	List[Any]								=atan((1 - flattening) * tan(radians(lowerCamelCase   )   )   )

				# Compute central angle between two points
				# using haversine theta. sigma =  haversine_distance / equatorial radius
				__magic_name__	:	List[Any]								=haversine_distance(lowerCamelCase	,     lowerCamelCase	,     lowerCamelCase	,     lowerCamelCase   ) / EQUATORIAL_RADIUS

				# Intermediate P and Q values
				__magic_name__	:	Tuple								=(b_lata + b_lata) / 2
				__magic_name__	:	int								=(b_lata - b_lata) / 2

				# Intermediate X value
				# X = (sigma - sin(sigma)) * sin^2Pcos^2Q / cos^2(sigma/2)
				__magic_name__	:	Optional[int]								=(sin(lowerCamelCase   ) ** 2) * (cos(lowerCamelCase   ) ** 2)
				__magic_name__	:	Any								=cos(sigma / 2   ) ** 2
				__magic_name__	:	List[Any]								=(sigma - sin(lowerCamelCase   )) * (x_numerator / x_demonimator)

				# Intermediate Y value
				# Y = (sigma + sin(sigma)) * cos^2Psin^2Q / sin^2(sigma/2)
				__magic_name__	:	Any								=(cos(lowerCamelCase   ) ** 2) * (sin(lowerCamelCase   ) ** 2)
				__magic_name__	:	Optional[Any]								=sin(sigma / 2   ) ** 2
				__magic_name__	:	str								=(sigma + sin(lowerCamelCase   )) * (y_numerator / y_denominator)

				return EQUATORIAL_RADIUS * (sigma - ((flattening / 2) * (x_value + y_value)))


if __name__ == "__main__":
							import doctest

							doctest.testmod()




