


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

from .haversine_distance import haversine_distance

lowerCAmelCase           =		6_3_7_8_1_3_7.0
lowerCAmelCase           =		6_3_5_6_7_5_2.3_1_4_2_4_5
lowerCAmelCase           =		6_3_7_8_1_3_7







def        _lowerCamelCase(	lowercase__   , lowercase__   , lowercase__   , lowercase__	)						->	float:

		'''simple docstring'''







		__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(lowercase__	)	)	)
		__lowercase=			atan((1 - flattening) * tan(radians(lowercase__	)	)	)

		# Compute central angle between two points
		# using haversine theta. sigma =  haversine_distance / equatorial radius
		__lowercase=			haversine_distance(lowercase__   , lowercase__   , lowercase__   , lowercase__	) / 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(lowercase__	) ** 2) * (cos(lowercase__	) ** 2)
		__lowercase=			cos(sigma / 2	) ** 2
		__lowercase=			(sigma - sin(lowercase__	)) * (x_numerator / x_demonimator)

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

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


if __name__ == "__main__":
	import doctest

	doctest.testmod()










import os

import numpy
import onnx







def        _lowerCamelCase(	lowercase__   , lowercase__	)						->	Union[str, Any]:

		'''simple docstring'''







		__lowercase=			a.name
		__lowercase=			b.name

		__lowercase=			''
		__lowercase=			''

		__lowercase=			a == b

		__lowercase=			name_a
		__lowercase=			name_b

		return res







def        _lowerCamelCase(	lowercase__   , lowercase__   , lowercase__	)						->	Union[str, Any]:

		'''simple docstring'''







		for i, input_name in enumerate(node_proto.input	):
				if input_name == name:
						node_proto.input.insert(lowercase__   , lowercase__	)
						node_proto.input.pop(i + 1	)

		if node_proto.op_type == "If":
				_graph_replace_input_with(node_proto.attribute[0].g   , lowercase__   , lowercase__	)
				_graph_replace_input_with(node_proto.attribute[1].g   , lowercase__   , lowercase__	)
		if node_proto.op_type == "Loop":
				_graph_replace_input_with(node_proto.attribute[0].g   , lowercase__   , lowercase__	)







def        _lowerCamelCase(	lowercase__   , lowercase__   , lowercase__	)						->	str:

		'''simple docstring'''







		for n in graph_proto.node:
				_node_replace_input_with(lowercase__   , lowercase__   , lowercase__	)







def        _lowerCamelCase(	lowercase__   , lowercase__   , lowercase__	)						->	Any:

		'''simple docstring'''







		__lowercase=			list(model.graph.initializer	)
		__lowercase=			list(model_without_ext.graph.initializer	)
		for i, ref_i in ind_to_replace:
				assert inits_with_data[i].name == inits[i].name
				assert inits_with_data[ref_i].name == inits[ref_i].name
				assert i > ref_i

				__lowercase=			inits[i].name
				__lowercase=			inits[ref_i].name

				model_without_ext.graph.initializer.remove(inits[i]	)

				# for n in model.graph.node:
				_graph_replace_input_with(model_without_ext.graph   , lowercase__   , lowercase__	)







def        _lowerCamelCase(	lowercase__	)						->	Dict:

		'''simple docstring'''







		__lowercase=			os.path.dirname(lowercase__	)
		__lowercase=			os.path.basename(lowercase__	)

		__lowercase=			onnx.load(os.path.join(lowercase__   , lowercase__	)	)

		__lowercase=			list(model.graph.initializer	)

		__lowercase=			set()
		__lowercase=			{}
		__lowercase=			[]

		__lowercase=			0

		for i in range(len(lowercase__	)	):
				if i in dup_set:
						continue

				for j in range(i + 1   , len(lowercase__	)	):
						if j in dup_set:
								continue
						if _is_equal_tensor_proto(inits[i]   , inits[j]	):
								dup_set.add(lowercase__	)
								dup_set.add(lowercase__	)

								__lowercase=			inits[j].data_type
								__lowercase=			numpy.prod(inits[j].dims	)
								if dtype == 1:
										mem_size *= 4
								elif dtype == 6:
										mem_size *= 4
								elif dtype == 7 or dtype == 1_1:
										mem_size *= 8
								else:
										print('unexpected data type: '   , lowercase__	)
								total_reduced_size += mem_size

								__lowercase=			inits[i].name
								__lowercase=			inits[j].name

								if name_i in dup_map:
										dup_map[name_i].append(lowercase__	)
								else:
										__lowercase=			[name_j]
								ind_to_replace.append((j, i)	)

		print('total reduced size: '   , total_reduced_size / 1_0_2_4 / 1_0_2_4 / 1_0_2_4   , 'GB'	)

		__lowercase=			sorted(lowercase__	)
		_remove_dup_initializers_from_model(lowercase__   , lowercase__   , lowercase__	)

		__lowercase=			'optimized_' + model_file_name
		__lowercase=			os.path.join(lowercase__   , lowercase__	)
		onnx.save(lowercase__   , lowercase__	)

		return new_model






