




"""simple docstring"""

import warnings
from collections.abc import Callable
from typing import Any

import numpy
from matplotlib import pyplot

UpperCamelCase__ :    str 					=							0.25 + 0.0J
UpperCamelCase__ :    Any 					=							-0.4 + 0.6J
UpperCamelCase__ :    List[str] 					=							-0.1 + 0.651J
UpperCamelCase__ :    Any 					=							-2.0
UpperCamelCase__ :    int 					=							56
UpperCamelCase__ :    Dict 					=							2.0
UpperCamelCase__ :    Union[str, Any] 					=							6_66




def       snake_case__	(       lowerCAmelCase   :		complex				,					lowerCAmelCase   :		numpy.ndarray		):
					return numpy.exp(lowerCAmelCase		) + c_parameter




def       snake_case__	(       lowerCAmelCase   :		complex				,					lowerCAmelCase   :		numpy.ndarray		):
					return z_values * z_values + c_parameter




def       snake_case__	(       lowerCAmelCase   :		float				,					lowerCAmelCase   :		int		):
					__snake_case          =	numpy.linspace(-window_size				,					lowerCAmelCase				,					lowerCAmelCase		)
					__snake_case          =	x.reshape((nb_pixels, 1)		)
					__snake_case          =	numpy.linspace(-window_size				,					lowerCAmelCase				,					lowerCAmelCase		)
					__snake_case          =	y.reshape((1, nb_pixels)		)
					return x + 1.0J * y




def       snake_case__	(       lowerCAmelCase   :		Callable[[Any, numpy.ndarray], numpy.ndarray]				,					lowerCAmelCase   :		Any				,					lowerCAmelCase   :		int				,					lowerCAmelCase   :		numpy.ndarray				,					lowerCAmelCase   :		float | None = None				,					):
					__snake_case          =	z_a.astype("""complex64"""		)
					for _ in range(lowerCAmelCase		):
										__snake_case          =	eval_function(lowerCAmelCase				,					lowerCAmelCase		)
										if infinity is not None:
															numpy.nan_to_num(lowerCAmelCase				,					copy=lowerCAmelCase				,					nan=lowerCAmelCase		)
															__snake_case          =	infinity
					return z_n




def       snake_case__	(       lowerCAmelCase   :		str				,					lowerCAmelCase   :		Any				,					lowerCAmelCase   :		float				,					lowerCAmelCase   :		numpy.ndarray				,					):
					__snake_case          =	(abs(lowerCAmelCase		)).transpose()
					__snake_case          =	abs_z_final[::-1, :]
					pyplot.matshow(abs_z_final < escape_radius		)
					pyplot.title(F'''Julia set of ${function_label}$, $c={function_params}$'''		)
					pyplot.show()




def       snake_case__	(       ):
					warnings.filterwarnings(
					    """ignore"""				,					category=lowerCAmelCase				,					message="""overflow encountered in multiply"""		)
					warnings.filterwarnings(
					    """ignore"""				,					category=lowerCAmelCase				,					message="""invalid value encountered in multiply"""				,					)
					warnings.filterwarnings(
					    """ignore"""				,					category=lowerCAmelCase				,					message="""overflow encountered in absolute"""		)
					warnings.filterwarnings(
					    """ignore"""				,					category=lowerCAmelCase				,					message="""overflow encountered in exp"""		)


if __name__ == "__main__":
		UpperCamelCase__ :    Tuple 					=							prepare_grid(window_size, nb_pixels)

		ignore_overflow_warnings()  # See file header for explanations

		UpperCamelCase__ :    Union[str, Any] 					=							24
		UpperCamelCase__ :    List[str] 					=							2 * abs(c_cauliflower) + 1
		UpperCamelCase__ :    Union[str, Any] 					=							iterate_function(
		    eval_quadratic_polynomial,
		    c_cauliflower,
		    nb_iterations,
		    z_a,
		    infinity=1.1 * escape_radius,
		)
		show_results("z^2+c", c_cauliflower, escape_radius, z_final)

		UpperCamelCase__ :    str 					=							64
		UpperCamelCase__ :    List[Any] 					=							2 * abs(c_polynomial_a) + 1
		UpperCamelCase__ :    Union[str, Any] 					=							iterate_function(
		    eval_quadratic_polynomial,
		    c_polynomial_a,
		    nb_iterations,
		    z_a,
		    infinity=1.1 * escape_radius,
		)
		show_results("z^2+c", c_polynomial_a, escape_radius, z_final)

		UpperCamelCase__ :    Dict 					=							1_61
		UpperCamelCase__ :    Union[str, Any] 					=							2 * abs(c_polynomial_a) + 1
		UpperCamelCase__ :    Optional[Any] 					=							iterate_function(
		    eval_quadratic_polynomial,
		    c_polynomial_a,
		    nb_iterations,
		    z_a,
		    infinity=1.1 * escape_radius,
		)
		show_results("z^2+c", c_polynomial_a, escape_radius, z_final)

		UpperCamelCase__ :    str 					=							12
		UpperCamelCase__ :    str 					=							10000.0
		UpperCamelCase__ :    Tuple 					=							iterate_function(
		    eval_exponential,
		    c_exponential,
		    nb_iterations,
		    z_a + 2,
		    infinity=1.0e10,
		)
		show_results("e^z+c", c_exponential, escape_radius, z_final)








"""simple docstring"""

import functools
from math import sqrt
from time import time




def       snake_case__	(       lowerCAmelCase   :		int				,					*lowerCAmelCase   :		str				,					**lowerCAmelCase   :		List[Any]		):
					__snake_case          =	time()
					__snake_case          =	func(*lowerCAmelCase				,					**lowerCAmelCase		)
					__snake_case          =	time()
					if int(end - start		) > 0:
										print(F'''{func.__name__} runtime: {(end - start):0.4f} s'''		)
					else:
										print(F'''{func.__name__} runtime: {(end - start) * 1_000:0.4f} ms'''		)
					return output




def       snake_case__	(       lowerCAmelCase   :		int		):
					if n < 0:
										raise Exception("""n is negative"""		)
					if n == 0:
										return [0]
					__snake_case          =	[0, 1]
					for _ in range(n - 1		):
										fib.append(fib[-1] + fib[-2]		)
					return fib




def       snake_case__	(       lowerCAmelCase   :		int		):

					def fib_recursive_term(lowerCAmelCase   :		int		) -> int:
										if i < 0:
															raise Exception("""n is negative"""		)
										if i < 2:
															return i
										return fib_recursive_term(i - 1		) + fib_recursive_term(i - 2		)

					if n < 0:
										raise Exception("""n is negative"""		)
					return [fib_recursive_term(lowerCAmelCase		) for i in range(n + 1		)]




def       snake_case__	(       lowerCAmelCase   :		int		):

					@functools.cache
					def fib_recursive_term(lowerCAmelCase   :		int		) -> int:
										if i < 0:
															raise Exception("""n is negative"""		)
										if i < 2:
															return i
										return fib_recursive_term(i - 1		) + fib_recursive_term(i - 2		)

					if n < 0:
										raise Exception("""n is negative"""		)
					return [fib_recursive_term(lowerCAmelCase		) for i in range(n + 1		)]




def       snake_case__	(       lowerCAmelCase   :		int		):
					if n < 0:
										raise Exception("""n is negative"""		)
					# Cache must be outside recursuive function
					# other it will reset every time it calls itself.
					__snake_case          =	{0: 0, 1: 1, 2: 1}  # Prefilled cache

					def rec_fn_memoized(lowerCAmelCase   :		int		) -> int:
										if num in cache:
															return cache[num]

										__snake_case          =	rec_fn_memoized(num - 1		) + rec_fn_memoized(num - 2		)
										__snake_case          =	value
										return value

					return [rec_fn_memoized(lowerCAmelCase		) for i in range(n + 1		)]




def       snake_case__	(       lowerCAmelCase   :		int		):
					if n < 0:
										raise Exception("""n is negative"""		)
					if n >= 1_475:
										raise Exception("""n is too large"""		)
					__snake_case          =	sqrt(5		)
					__snake_case          =	(1 + sqrt_a) / 2
					return [round(phi**i / sqrt_a		) for i in range(n + 1		)]


if __name__ == "__main__":
		UpperCamelCase__ :    Optional[Any] 					=							30
		time_func(fib_iterative, num)
		time_func(fib_recursive, num)  # Around 3s runtime
		time_func(fib_recursive_cached, num)  # Around 0ms runtime
		time_func(fib_memoization, num)
		time_func(fib_binet, num)


