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

from .haversine_distance import haversine_distance

UpperCAmelCase	      = 6378137.0
UpperCAmelCase	      = 6356752.314245
UpperCAmelCase	      = 637_8137






def 							UpperCAmelCase_		(							__SCREAMING_SNAKE_CASE ,							__SCREAMING_SNAKE_CASE ,							__SCREAMING_SNAKE_CASE ,							__SCREAMING_SNAKE_CASE							):
	lowercase       =    (AXIS_A - AXIS_B) / AXIS_A
	# Parametric latitudes
	# https://en.wikipedia.org/wiki/Latitude#Parametric_(or_reduced)_latitude
	lowercase       =    atan((1 - flattening) * tan(radians(__SCREAMING_SNAKE_CASE							)							)							)
	lowercase       =    atan((1 - flattening) * tan(radians(__SCREAMING_SNAKE_CASE							)							)							)

	# Compute central angle between two points
	# using haversine theta. sigma =  haversine_distance / equatorial radius
	lowercase       =    haversine_distance(__SCREAMING_SNAKE_CASE ,							__SCREAMING_SNAKE_CASE ,							__SCREAMING_SNAKE_CASE ,							__SCREAMING_SNAKE_CASE							) / EQUATORIAL_RADIUS

	# Intermediate P and Q values
	lowercase       =    (b_lata + b_lata) / 2
	lowercase       =    (b_lata - b_lata) / 2

	# Intermediate X value
	# X = (sigma - sin(sigma)) * sin^2Pcos^2Q / cos^2(sigma/2)
	lowercase       =    (sin(__SCREAMING_SNAKE_CASE							) ** 2) * (cos(__SCREAMING_SNAKE_CASE							) ** 2)
	lowercase       =    cos(sigma / 2							) ** 2
	lowercase       =    (sigma - sin(__SCREAMING_SNAKE_CASE							)) * (x_numerator / x_demonimator)

	# Intermediate Y value
	# Y = (sigma + sin(sigma)) * cos^2Psin^2Q / sin^2(sigma/2)
	lowercase       =    (cos(__SCREAMING_SNAKE_CASE							) ** 2) * (sin(__SCREAMING_SNAKE_CASE							) ** 2)
	lowercase       =    sin(sigma / 2							) ** 2
	lowercase       =    (sigma + sin(__SCREAMING_SNAKE_CASE							)) * (y_numerator / y_denominator)

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


if __name__ == "__main__":
	import doctest

	doctest.testmod()



import importlib
import sys
from argparse import REMAINDER, ArgumentParser
from pathlib import Path

import torch_xla.distributed.xla_multiprocessing as xmp






def 							UpperCAmelCase_		(							):
	lowercase       =    ArgumentParser(
	    description=(
	        'PyTorch TPU distributed training launch '
	        'helper utility that will spawn up '
	        'multiple distributed processes'
	    )							)

	# Optional arguments for the launch helper
	parser.add_argument('--num_cores' ,							type=__SCREAMING_SNAKE_CASE ,							default=1 ,							help='Number of TPU cores to use (1 or 8).'							)

	# positional
	parser.add_argument(
	    'training_script' ,							type=__SCREAMING_SNAKE_CASE ,							help=(
	        'The full path to the single TPU training '
	        'program/script to be launched in parallel, '
	        'followed by all the arguments for the '
	        'training script'
	    ) ,							)

	# rest from the training program
	parser.add_argument('training_script_args' ,							nargs=__SCREAMING_SNAKE_CASE							)

	return parser.parse_args()






def 							UpperCAmelCase_		(							):
	lowercase       =    parse_args()

	# Import training_script as a module.
	lowercase       =    Path(args.training_script							)
	sys.path.append(str(script_fpath.parent.resolve()							)							)
	lowercase       =    script_fpath.stem
	lowercase       =    importlib.import_module(__SCREAMING_SNAKE_CASE							)

	# Patch sys.argv
	lowercase       =    [args.training_script] + args.training_script_args + ['--tpu_num_cores', str(args.num_cores							)]
	xmp.spawn(mod._mp_fn ,							args=() ,							nprocs=args.num_cores							)


if __name__ == "__main__":
	main()

