






from math import pi, sqrt, tan



def  a__ (__lowercase							:float   )		-> float:
				if side_length < 0:
								raise ValueError('''surface_area_cube() only accepts non-negative values'''   )
				return 6 * side_length**2



def  a__ (__lowercase							:float					,  __lowercase							:float					,  __lowercase							:float   )		-> float:
				if length < 0 or breadth < 0 or height < 0:
								raise ValueError('''surface_area_cuboid() only accepts non-negative values'''   )
				return 2 * ((length * breadth) + (breadth * height) + (length * height))



def  a__ (__lowercase							:float   )		-> float:
				if radius < 0:
								raise ValueError('''surface_area_sphere() only accepts non-negative values'''   )
				return 4 * pi * radius**2



def  a__ (__lowercase							:float   )		-> float:
				if radius < 0:
								raise ValueError('''surface_area_hemisphere() only accepts non-negative values'''   )
				return 3 * pi * radius**2



def  a__ (__lowercase							:float					,  __lowercase							:float   )		-> float:
				if radius < 0 or height < 0:
								raise ValueError('''surface_area_cone() only accepts non-negative values'''   )
				return pi * radius * (radius + (height**2 + radius**2) ** 0.5)



def  a__ (__lowercase							:float					,  __lowercase							:float					,  __lowercase							:float   )		-> float:
				if radius_a < 0 or radius_a < 0 or height < 0:
								raise ValueError(
								    '''surface_area_conical_frustum() only accepts non-negative values'''   )
				_A	:				List[str]   =      (height**2 + (radius_a - radius_a) ** 2) ** 0.5
				return pi * ((slant_height * (radius_a + radius_a)) + radius_a**2 + radius_a**2)



def  a__ (__lowercase							:float					,  __lowercase							:float   )		-> float:
				if radius < 0 or height < 0:
								raise ValueError('''surface_area_cylinder() only accepts non-negative values'''   )
				return 2 * pi * radius * (height + radius)



def  a__ (__lowercase							:float					,  __lowercase							:float   )		-> float:
				if torus_radius < 0 or tube_radius < 0:
								raise ValueError('''surface_area_torus() only accepts non-negative values'''   )
				if torus_radius < tube_radius:
								raise ValueError(
								    '''surface_area_torus() does not support spindle or self intersecting tori'''   )
				return 4 * pow(__lowercase					,  2   ) * torus_radius * tube_radius



def  a__ (__lowercase							:float					,  __lowercase							:float   )		-> float:
				if length < 0 or width < 0:
								raise ValueError('''area_rectangle() only accepts non-negative values'''   )
				return length * width



def  a__ (__lowercase							:float   )		-> float:
				if side_length < 0:
								raise ValueError('''area_square() only accepts non-negative values'''   )
				return side_length**2



def  a__ (__lowercase							:float					,  __lowercase							:float   )		-> float:
				if base < 0 or height < 0:
								raise ValueError('''area_triangle() only accepts non-negative values'''   )
				return (base * height) / 2



def  a__ (__lowercase							:float					,  __lowercase							:float					,  __lowercase							:float   )		-> float:
				if sidea < 0 or sidea < 0 or sidea < 0:
								raise ValueError('''area_triangle_three_sides() only accepts non-negative values'''   )
				elif sidea + sidea < sidea or sidea + sidea < sidea or sidea + sidea < sidea:
								raise ValueError('''Given three sides do not form a triangle'''   )
				_A	:				int   =      (sidea + sidea + sidea) / 2
				_A	:				Tuple   =      sqrt(
				    semi_perimeter
				    * (semi_perimeter - sidea)
				    * (semi_perimeter - sidea)
				    * (semi_perimeter - sidea)   )
				return area



def  a__ (__lowercase							:float					,  __lowercase							:float   )		-> float:
				if base < 0 or height < 0:
								raise ValueError('''area_parallelogram() only accepts non-negative values'''   )
				return base * height



def  a__ (__lowercase							:float					,  __lowercase							:float					,  __lowercase							:float   )		-> float:
				if basea < 0 or basea < 0 or height < 0:
								raise ValueError('''area_trapezium() only accepts non-negative values'''   )
				return 1 / 2 * (basea + basea) * height



def  a__ (__lowercase							:float   )		-> float:
				if radius < 0:
								raise ValueError('''area_circle() only accepts non-negative values'''   )
				return pi * radius**2



def  a__ (__lowercase							:float					,  __lowercase							:float   )		-> float:
				if radius_x < 0 or radius_y < 0:
								raise ValueError('''area_ellipse() only accepts non-negative values'''   )
				return pi * radius_x * radius_y



def  a__ (__lowercase							:float					,  __lowercase							:float   )		-> float:
				if diagonal_a < 0 or diagonal_a < 0:
								raise ValueError('''area_rhombus() only accepts non-negative values'''   )
				return 1 / 2 * diagonal_a * diagonal_a



def  a__ (__lowercase							:int					,  __lowercase							:float   )		-> float:
				if not isinstance(__lowercase					,  __lowercase   ) or sides < 3:
								raise ValueError(
								    '''area_reg_polygon() only accepts integers greater than or \
equal to three as number of sides'''   )
				elif length < 0:
								raise ValueError(
								    '''area_reg_polygon() only accepts non-negative values as \
length of a side'''   )
				return (sides * length**2) / (4 * tan(pi / sides   ))
				return (sides * length**2) / (4 * tan(pi / sides   ))


if __name__ == "__main__":
	import doctest

	doctest.testmod(verbose=True)  # verbose so we can see methods missing tests

	print('[DEMO] Areas of various geometric shapes: \n')
	print(f'''Rectangle: {area_rectangle(10, 20) = }''')
	print(f'''Square: {area_square(10) = }''')
	print(f'''Triangle: {area_triangle(10, 10) = }''')
	print(f'''Triangle: {area_triangle_three_sides(5, 12, 13) = }''')
	print(f'''Parallelogram: {area_parallelogram(10, 20) = }''')
	print(f'''Rhombus: {area_rhombus(10, 20) = }''')
	print(f'''Trapezium: {area_trapezium(10, 20, 30) = }''')
	print(f'''Circle: {area_circle(20) = }''')
	print(f'''Ellipse: {area_ellipse(10, 20) = }''')
	print('\nSurface Areas of various geometric shapes: \n')
	print(f'''Cube: {surface_area_cube(20) = }''')
	print(f'''Cuboid: {surface_area_cuboid(10, 20, 30) = }''')
	print(f'''Sphere: {surface_area_sphere(20) = }''')
	print(f'''Hemisphere: {surface_area_hemisphere(20) = }''')
	print(f'''Cone: {surface_area_cone(10, 20) = }''')
	print(f'''Conical Frustum: {surface_area_conical_frustum(10, 20, 30) = }''')
	print(f'''Cylinder: {surface_area_cylinder(10, 20) = }''')
	print(f'''Torus: {surface_area_torus(20, 10) = }''')
	print(f'''Equilateral Triangle: {area_reg_polygon(3, 10) = }''')
	print(f'''Square: {area_reg_polygon(4, 10) = }''')
	print(f'''Reqular Pentagon: {area_reg_polygon(5, 10) = }''')











import flax.linen as nn
import jax.numpy as jnp

from .attention_flax import FlaxTransformeraDModel
from .resnet_flax import FlaxDownsampleaD, FlaxResnetBlockaD, FlaxUpsampleaD






class 						UpperCAmelCase__ (							nn.Module							):
		__snake_case      :       int
		__snake_case      :       int
		__snake_case      :       float     =   0.0
		__snake_case      :       int     =   1
		__snake_case      :       int     =   1
		__snake_case      :       bool     =   True
		__snake_case      :       bool     =   False
		__snake_case      :       bool     =   False
		__snake_case      :       bool     =   False
		__snake_case      :       jnp.dtype     =   jnp.floataa







		def  A__      (					self		):
						_A	:				Optional[Any]   =      []
						_A	:				str   =      []

						for i in range(self.num_layers		):
										_A	:				Union[str, Any]   =      self.in_channels if i == 0 else self.out_channels

										_A	:				str   =      FlaxResnetBlockaD(
										    in_channels=A__       ,out_channels=self.out_channels       ,dropout_prob=self.dropout       ,dtype=self.dtype       ,)
										resnets.append(A__		)

										_A	:				List[str]   =      FlaxTransformeraDModel(
										    in_channels=self.out_channels       ,n_heads=self.num_attention_heads       ,d_head=self.out_channels // self.num_attention_heads       ,depth=1       ,use_linear_projection=self.use_linear_projection       ,only_cross_attention=self.only_cross_attention       ,use_memory_efficient_attention=self.use_memory_efficient_attention       ,dtype=self.dtype       ,)
										attentions.append(A__		)

						_A	:				List[str]   =      resnets
						_A	:				Any   =      attentions

						if self.add_downsample:
										_A	:				Any   =      FlaxDownsampleaD(self.out_channels       ,dtype=self.dtype		)







		def __call__(					self       ,A__       ,A__       ,A__       ,A__=True		):
						_A	:				List[str]   =      ()

						for resnet, attn in zip(self.resnets       ,self.attentions		):
										_A	:				Optional[Any]   =      resnet(A__       ,A__       ,deterministic=A__		)
										_A	:				Tuple   =      attn(A__       ,A__       ,deterministic=A__		)
										output_states += (hidden_states,)

						if self.add_downsample:
										_A	:				Optional[int]   =      self.downsamplers_a(A__		)
										output_states += (hidden_states,)

						return hidden_states, output_states






class 						UpperCAmelCase__ (							nn.Module							):
		__snake_case      :       int
		__snake_case      :       int
		__snake_case      :       float     =   0.0
		__snake_case      :       int     =   1
		__snake_case      :       bool     =   True
		__snake_case      :       jnp.dtype     =   jnp.floataa







		def  A__      (					self		):
						_A	:				List[Any]   =      []

						for i in range(self.num_layers		):
										_A	:				int   =      self.in_channels if i == 0 else self.out_channels

										_A	:				List[Any]   =      FlaxResnetBlockaD(
										    in_channels=A__       ,out_channels=self.out_channels       ,dropout_prob=self.dropout       ,dtype=self.dtype       ,)
										resnets.append(A__		)
						_A	:				Tuple   =      resnets

						if self.add_downsample:
										_A	:				Optional[Any]   =      FlaxDownsampleaD(self.out_channels       ,dtype=self.dtype		)







		def __call__(					self       ,A__       ,A__       ,A__=True		):
						_A	:				List[Any]   =      ()

						for resnet in self.resnets:
										_A	:				Optional[int]   =      resnet(A__       ,A__       ,deterministic=A__		)
										output_states += (hidden_states,)

						if self.add_downsample:
										_A	:				List[Any]   =      self.downsamplers_a(A__		)
										output_states += (hidden_states,)

						return hidden_states, output_states






class 						UpperCAmelCase__ (							nn.Module							):
		__snake_case      :       int
		__snake_case      :       int
		__snake_case      :       int
		__snake_case      :       float     =   0.0
		__snake_case      :       int     =   1
		__snake_case      :       int     =   1
		__snake_case      :       bool     =   True
		__snake_case      :       bool     =   False
		__snake_case      :       bool     =   False
		__snake_case      :       bool     =   False
		__snake_case      :       jnp.dtype     =   jnp.floataa







		def  A__      (					self		):
						_A	:				List[str]   =      []
						_A	:				Optional[Any]   =      []

						for i in range(self.num_layers		):
										_A	:				Dict   =      self.in_channels if (i == self.num_layers - 1) else self.out_channels
										_A	:				List[str]   =      self.prev_output_channel if i == 0 else self.out_channels

										_A	:				Optional[int]   =      FlaxResnetBlockaD(
										    in_channels=resnet_in_channels + res_skip_channels       ,out_channels=self.out_channels       ,dropout_prob=self.dropout       ,dtype=self.dtype       ,)
										resnets.append(A__		)

										_A	:				Union[str, Any]   =      FlaxTransformeraDModel(
										    in_channels=self.out_channels       ,n_heads=self.num_attention_heads       ,d_head=self.out_channels // self.num_attention_heads       ,depth=1       ,use_linear_projection=self.use_linear_projection       ,only_cross_attention=self.only_cross_attention       ,use_memory_efficient_attention=self.use_memory_efficient_attention       ,dtype=self.dtype       ,)
										attentions.append(A__		)

						_A	:				Dict   =      resnets
						_A	:				int   =      attentions

						if self.add_upsample:
										_A	:				str   =      FlaxUpsampleaD(self.out_channels       ,dtype=self.dtype		)







		def __call__(					self       ,A__       ,A__       ,A__       ,A__       ,A__=True		):
						for resnet, attn in zip(self.resnets       ,self.attentions		):
										# pop res hidden states
										_A	:				List[Any]   =      res_hidden_states_tuple[-1]
										_A	:				int   =      res_hidden_states_tuple[:-1]
										_A	:				List[Any]   =      jnp.concatenate((hidden_states, res_hidden_states)       ,axis=-1		)

										_A	:				str   =      resnet(A__       ,A__       ,deterministic=A__		)
										_A	:				Optional[int]   =      attn(A__       ,A__       ,deterministic=A__		)

						if self.add_upsample:
										_A	:				Union[str, Any]   =      self.upsamplers_a(A__		)

						return hidden_states






class 						UpperCAmelCase__ (							nn.Module							):
		__snake_case      :       int
		__snake_case      :       int
		__snake_case      :       int
		__snake_case      :       float     =   0.0
		__snake_case      :       int     =   1
		__snake_case      :       bool     =   True
		__snake_case      :       jnp.dtype     =   jnp.floataa







		def  A__      (					self		):
						_A	:				Optional[Any]   =      []

						for i in range(self.num_layers		):
										_A	:				Any   =      self.in_channels if (i == self.num_layers - 1) else self.out_channels
										_A	:				Optional[Any]   =      self.prev_output_channel if i == 0 else self.out_channels

										_A	:				List[Any]   =      FlaxResnetBlockaD(
										    in_channels=resnet_in_channels + res_skip_channels       ,out_channels=self.out_channels       ,dropout_prob=self.dropout       ,dtype=self.dtype       ,)
										resnets.append(A__		)

						_A	:				int   =      resnets

						if self.add_upsample:
										_A	:				List[str]   =      FlaxUpsampleaD(self.out_channels       ,dtype=self.dtype		)







		def __call__(					self       ,A__       ,A__       ,A__       ,A__=True		):
						for resnet in self.resnets:
										# pop res hidden states
										_A	:				Tuple   =      res_hidden_states_tuple[-1]
										_A	:				Optional[int]   =      res_hidden_states_tuple[:-1]
										_A	:				Any   =      jnp.concatenate((hidden_states, res_hidden_states)       ,axis=-1		)

										_A	:				Optional[Any]   =      resnet(A__       ,A__       ,deterministic=A__		)

						if self.add_upsample:
										_A	:				Tuple   =      self.upsamplers_a(A__		)

						return hidden_states






class 						UpperCAmelCase__ (							nn.Module							):
		__snake_case      :       int
		__snake_case      :       float     =   0.0
		__snake_case      :       int     =   1
		__snake_case      :       int     =   1
		__snake_case      :       bool     =   False
		__snake_case      :       bool     =   False
		__snake_case      :       jnp.dtype     =   jnp.floataa







		def  A__      (					self		):
						# there is always at least one resnet
						_A	:				List[str]   =      [
						    FlaxResnetBlockaD(
						        in_channels=self.in_channels       ,out_channels=self.in_channels       ,dropout_prob=self.dropout       ,dtype=self.dtype       ,)
						]

						_A	:				Union[str, Any]   =      []

						for _ in range(self.num_layers		):
										_A	:				Any   =      FlaxTransformeraDModel(
										    in_channels=self.in_channels       ,n_heads=self.num_attention_heads       ,d_head=self.in_channels // self.num_attention_heads       ,depth=1       ,use_linear_projection=self.use_linear_projection       ,use_memory_efficient_attention=self.use_memory_efficient_attention       ,dtype=self.dtype       ,)
										attentions.append(A__		)

										_A	:				Any   =      FlaxResnetBlockaD(
										    in_channels=self.in_channels       ,out_channels=self.in_channels       ,dropout_prob=self.dropout       ,dtype=self.dtype       ,)
										resnets.append(A__		)

						_A	:				List[str]   =      resnets
						_A	:				str   =      attentions







		def __call__(					self       ,A__       ,A__       ,A__       ,A__=True		):
						_A	:				Optional[int]   =      self.resnets[0](A__       ,A__		)
						for attn, resnet in zip(self.attentions       ,self.resnets[1:]		):
										_A	:				Dict   =      attn(A__       ,A__       ,deterministic=A__		)
										_A	:				Any   =      resnet(A__       ,A__       ,deterministic=A__		)

						return hidden_states



