






from math import factorial





class 	snake_case__ :
	def __init__(    self      ,       lowerCAmelCase__      ,       lowerCAmelCase__			)							->				List[str]:
							__magic_name__      :       str       						= real
							if isinstance(snake_case__      ,       snake_case__			):
													__magic_name__      :       Any       						= [1] * rank
							else:
													__magic_name__      :       Optional[Any]       						= rank
	def __repr__(    self			)							->				Dict:
							return (
							    F'{self.real}+'
							    F'{"+".join(str(snake_case__			)+"E"+str(n+1			)for n,dual in enumerate(self.duals			)			)}'
							)
	def       __magic_name__    (    self			)							->				Dict:
							__magic_name__      :       Dict       						= self.duals.copy()
							while cur[-1] == 0:
													cur.pop(-1			)
							return Dual(self.real      ,       snake_case__			)
	def __add__(    self      ,       lowerCAmelCase__			)							->				int:





							if not isinstance(snake_case__      ,       snake_case__			):
													return Dual(self.real + other      ,       self.duals			)
							__magic_name__      :       Tuple       						= self.duals.copy()
							__magic_name__      :       int       						= other.duals.copy()
							if len(snake_case__			) > len(snake_case__			):
													o_dual.extend([1] * (len(snake_case__			) - len(snake_case__			))			)
							elif len(snake_case__			) < len(snake_case__			):
													s_dual.extend([1] * (len(snake_case__			) - len(snake_case__			))			)
							__magic_name__      :       List[Any]       						= []
							for i in range(len(snake_case__			)			):
													new_duals.append(s_dual[i] + o_dual[i]			)
							return Dual(self.real + other.real      ,       snake_case__			)

	lowercase__						:					Dict											=   __add__
	def __sub__(    self      ,       lowerCAmelCase__			)							->				Optional[int]:
							return self + other * -1
	def __mul__(    self      ,       lowerCAmelCase__			)							->				Dict:





							if not isinstance(snake_case__      ,       snake_case__			):
													__magic_name__      :       List[Any]       						= []
													for i in self.duals:
																			new_duals.append(i * other			)
													return Dual(self.real * other      ,       snake_case__			)
							__magic_name__      :       str       						= [0] * (len(self.duals			) + len(other.duals			) + 1)
							for i, item in enumerate(self.duals			):
													for j, jtem in enumerate(other.duals			):
																			new_duals[i + j + 1] += item * jtem
							for k in range(len(self.duals			)			):
													new_duals[k] += self.duals[k] * other.real
							for index in range(len(other.duals			)			):
													new_duals[index] += other.duals[index] * self.real
							return Dual(self.real * other.real      ,       snake_case__			)

	lowercase__						:					Any											=   __mul__
	def __truediv__(    self      ,       lowerCAmelCase__			)							->				Union[str, Any]:





							if not isinstance(snake_case__      ,       snake_case__			):
													__magic_name__      :       Tuple       						= []
													for i in self.duals:
																			new_duals.append(i / other			)
													return Dual(self.real / other      ,       snake_case__			)
							raise ValueError
	def __floordiv__(    self      ,       lowerCAmelCase__			)							->				Any:





							if not isinstance(snake_case__      ,       snake_case__			):
													__magic_name__      :       Optional[int]       						= []
													for i in self.duals:
																			new_duals.append(i // other			)
													return Dual(self.real // other      ,       snake_case__			)
							raise ValueError







	def __pow__(    self      ,       lowerCAmelCase__			)							->				Union[str, Any]:





							if n < 0 or isinstance(snake_case__      ,       snake_case__			):
													raise ValueError("""power must be a positive integer"""			)
							if n == 0:
													return 1
							if n == 1:
													return self
							__magic_name__      :       Union[str, Any]       						= self
							for _ in range(n - 1			):
													x *= self
							return x



def    UpperCamelCase						(	_A,   _A,   _A			):






						"""simple docstring"""







						if not callable(__lowerCAmelCase			):
												raise ValueError("""differentiate() requires a function as input for func"""			)
						if not isinstance(__lowerCAmelCase,   (float, int)			):
												raise ValueError("""differentiate() requires a float as input for position"""			)
						if not isinstance(__lowerCAmelCase,   __lowerCAmelCase			):
												raise ValueError("""differentiate() requires an int as input for order"""			)
						__magic_name__      :       Union[str, Any]       						= Dual(__lowerCAmelCase,   1			)
						__magic_name__      :       Optional[int]       						= func(__lowerCAmelCase			)
						if order == 0:
												return result.real
						return result.duals[order - 1] * factorial(__lowerCAmelCase			)


if __name__ == "__main__":
		import doctest

		doctest.testmod()

		def    UpperCamelCase						(	_A			):






								"""simple docstring"""







								return y**2 * y**4

		print(differentiate(f, 9, 2))








from manim import *





class 	snake_case__ (							_lowerCAmelCase				):
	def       __magic_name__    (    self			)							->				Dict:
							__magic_name__      :       int       						= Rectangle(height=0.5      ,       width=0.5			)
							__magic_name__      :       Optional[int]       						= Rectangle(height=0.2_5      ,       width=0.2_5			)
							__magic_name__      :       str       						= Rectangle(height=0.4_6      ,       width=0.4_6			).set_stroke(width=0			)

							__magic_name__      :       List[Any]       						= [mem.copy() for i in range(6			)]
							__magic_name__      :       int       						= [mem.copy() for i in range(6			)]
							__magic_name__      :       Tuple       						= VGroup(*lowerCAmelCase__			).arrange(lowerCAmelCase__      ,       buff=0			)
							__magic_name__      :       List[str]       						= VGroup(*lowerCAmelCase__			).arrange(lowerCAmelCase__      ,       buff=0			)
							__magic_name__      :       str       						= VGroup(lowerCAmelCase__      ,       lowerCAmelCase__			).arrange(lowerCAmelCase__      ,       buff=0			)
							__magic_name__      :       Union[str, Any]       						= Text("""CPU"""      ,       font_size=24			)
							__magic_name__      :       Tuple       						= Group(lowerCAmelCase__      ,       lowerCAmelCase__			).arrange(lowerCAmelCase__      ,       buff=0.5      ,       aligned_edge=lowerCAmelCase__			)
							cpu.move_to([-2.5, -0.5, 0]			)
							self.add(lowerCAmelCase__			)

							__magic_name__      :       Any       						= [mem.copy() for i in range(4			)]
							__magic_name__      :       List[Any]       						= VGroup(*lowerCAmelCase__			).arrange(lowerCAmelCase__      ,       buff=0			)
							__magic_name__      :       Tuple       						= Text("""GPU"""      ,       font_size=24			)
							__magic_name__      :       Tuple       						= Group(lowerCAmelCase__      ,       lowerCAmelCase__			).arrange(lowerCAmelCase__      ,       buff=0.5      ,       aligned_edge=lowerCAmelCase__			)
							gpu.move_to([-1, -1, 0]			)
							self.add(lowerCAmelCase__			)

							__magic_name__      :       Union[str, Any]       						= [mem.copy() for i in range(6			)]
							__magic_name__      :       Union[str, Any]       						= VGroup(*lowerCAmelCase__			).arrange(lowerCAmelCase__      ,       buff=0			)

							__magic_name__      :       str       						= Text("""Model"""      ,       font_size=24			)
							__magic_name__      :       Optional[int]       						= Group(lowerCAmelCase__      ,       lowerCAmelCase__			).arrange(lowerCAmelCase__      ,       buff=0.5      ,       aligned_edge=lowerCAmelCase__			)
							model.move_to([3, -1.0, 0]			)
							self.add(lowerCAmelCase__			)

							__magic_name__      :       str       						= []
							__magic_name__      :       Tuple       						= []
							__magic_name__      :       Union[str, Any]       						= []

							for i, rect in enumerate(lowerCAmelCase__			):
													rect.set_stroke(lowerCAmelCase__			)

													__magic_name__      :       Optional[Any]       						= Rectangle(height=0.4_6 / 4      ,       width=0.4_6 / 3			).set_stroke(width=0.0			).set_fill(lowerCAmelCase__      ,       opacity=0.7			)

													if i == 0:
																			cpu_target.next_to(cpu_left_col_base[0].get_corner(DOWN + LEFT			)      ,       buff=0.0_2      ,       direction=lowerCAmelCase__			)
																			cpu_target.set_x(cpu_target.get_x() + 0.1			)
													elif i == 3:
																			cpu_target.next_to(model_cpu_arr[0]      ,       direction=lowerCAmelCase__      ,       buff=0.0			)
													else:
																			cpu_target.next_to(model_cpu_arr[i - 1]      ,       direction=lowerCAmelCase__      ,       buff=0.0			)
													self.add(lowerCAmelCase__			)
													model_cpu_arr.append(lowerCAmelCase__			)

							self.add(*lowerCAmelCase__      ,       *lowerCAmelCase__      ,       *lowerCAmelCase__			)

							__magic_name__      :       Optional[Any]       						= [mem.copy() for i in range(6			)]
							__magic_name__      :       Optional[Any]       						= VGroup(*lowerCAmelCase__			).arrange(lowerCAmelCase__      ,       buff=0			)

							__magic_name__      :       Any       						= Text("""Loaded Checkpoint"""      ,       font_size=24			)
							__magic_name__      :       Optional[int]       						= Group(lowerCAmelCase__      ,       lowerCAmelCase__			).arrange(lowerCAmelCase__      ,       buff=0.5      ,       aligned_edge=lowerCAmelCase__			)
							checkpoint.move_to([3, 0.5, 0]			)

							self.add(lowerCAmelCase__			)

							__magic_name__      :       Optional[int]       						= []
							__magic_name__      :       Tuple       						= []

							for i, rect in enumerate(lowerCAmelCase__			):
													__magic_name__      :       Dict       						= fill.copy().set_fill(lowerCAmelCase__      ,       opacity=0.7			)
													target.move_to(lowerCAmelCase__			)
													ckpt_arr.append(lowerCAmelCase__			)

													__magic_name__      :       int       						= target.copy()
													if i < 5:
																			cpu_target.move_to(cpu_left_col_base[i + 1]			)
													else:
																			cpu_target.move_to(cpu_right_col_base[i - 5]			)
													ckpt_cpu_arr.append(lowerCAmelCase__			)
							self.add(*lowerCAmelCase__      ,       *lowerCAmelCase__			)

							__magic_name__      :       Tuple       						= Square(side_length=2.2			)
							key.move_to([-5, 2, 0]			)

							__magic_name__      :       str       						= MarkupText(
							    F'<b>Key:</b>\n\n<span fgcolor=\'{YELLOW}\'>●</span> Empty Model'      ,       font_size=18      ,       )

							key_text.move_to([-5, 2.4, 0]			)

							self.add(lowerCAmelCase__      ,       lowerCAmelCase__			)

							__magic_name__      :       Any       						= MarkupText(
							    F'<span fgcolor=\'{BLUE}\'>●</span> Checkpoint'      ,       font_size=18      ,       )

							blue_text.next_to(lowerCAmelCase__      ,       DOWN * 2.4      ,       aligned_edge=key_text.get_left()			)
							self.add(lowerCAmelCase__			)

							__magic_name__      :       Optional[Any]       						= MarkupText(
							    F'Based on the passed in configuration, weights are stored in\na variety of np.memmaps on disk or to a particular device.'      ,       font_size=24      ,       )
							step_a.move_to([2, 2, 0]			)

							__magic_name__      :       int       						= [meta_mem.copy() for i in range(6			)]
							__magic_name__      :       Union[str, Any]       						= [meta_mem.copy() for i in range(6			)]
							__magic_name__      :       Any       						= VGroup(*lowerCAmelCase__			).arrange(lowerCAmelCase__      ,       buff=0			)
							__magic_name__      :       str       						= VGroup(*lowerCAmelCase__			).arrange(lowerCAmelCase__      ,       buff=0			)
							__magic_name__      :       Tuple       						= VGroup(lowerCAmelCase__      ,       lowerCAmelCase__			).arrange(lowerCAmelCase__      ,       buff=0			)
							__magic_name__      :       int       						= Text("""Disk"""      ,       font_size=24			)
							__magic_name__      :       Union[str, Any]       						= Group(lowerCAmelCase__      ,       lowerCAmelCase__			).arrange(lowerCAmelCase__      ,       buff=0.5      ,       aligned_edge=lowerCAmelCase__			)
							disk.move_to([-4.0, -1.2_5, 0]			)
							self.play(Write(lowerCAmelCase__      ,       run_time=3			)      ,       Write(lowerCAmelCase__      ,       run_time=1			)      ,       Create(lowerCAmelCase__      ,       run_time=1			)			)

							__magic_name__      :       List[Any]       						= []
							for i, rect in enumerate(lowerCAmelCase__			):
													__magic_name__      :       Dict       						= rect.copy()
													target.generate_target()
													target.target.move_to(disk_left_col_base[i]			).scale(0.5			)
													animations.append(MoveToTarget(lowerCAmelCase__      ,       run_time=1.5			)			)
							self.play(*lowerCAmelCase__			)

							self.play(FadeOut(lowerCAmelCase__			)			)

							__magic_name__      :       str       						= MarkupText(F'Then, the checkpoint is removed from memory\nthrough garbage collection.'      ,       font_size=24			)
							step_a.move_to([2, 2, 0]			)

							self.play(Write(lowerCAmelCase__      ,       run_time=3			)			)

							self.play(
							    FadeOut(lowerCAmelCase__      ,       lowerCAmelCase__      ,       *lowerCAmelCase__      ,       *lowerCAmelCase__			)      ,       )

							self.wait()
