### Clone and Install Project Dependencies Source: https://github.com/patrick-kidger/optimistix/blob/main/CONTRIBUTING.md Clone the repository, navigate to the project directory, and install dependencies including pre-commit hooks using uv. ```bash git clone https://github.com/your-username-here/optimistix.git cd optimistix uv run prek install ``` -------------------------------- ### Install Optimistix Source: https://github.com/patrick-kidger/optimistix/blob/main/README.md Install the Optimistix library using pip. Requires Python 3.11+. ```bash pip install optimistix ``` -------------------------------- ### Basic Root Finding Example Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/examples/root_find.ipynb Demonstrates the fundamental API for root finding. Requires importing JAX and Optimistix, defining the function to solve, selecting a solver, and calling the root_find function. ```python import jax import jax.numpy as jnp import optimistix as optx # Often import when doing scientific work jax.config.update("jax_enable_x64", True) def fn(y, args): a, b = y c = jnp.tanh(jnp.sum(b)) - a d = a**2 - jnp.sinh(b + 1) return c, d solver = optx.Newton(rtol=1e-8, atol=1e-8) y0 = (jnp.array(0.0), jnp.zeros((2, 2))) sol = optx.root_find(fn, solver, y0) ``` -------------------------------- ### Import necessary libraries Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/examples/van_der_pol.ipynb Imports required libraries for the example, including Diffrax for ODE solving, Equinox for module definition, JAX for numerical operations, and Matplotlib for plotting. ```python import diffrax as dfx import equinox as eqx import jax.numpy as jnp import jax.random as jr import matplotlib.pyplot as plt import optimistix as optx ``` -------------------------------- ### Define a Custom Hybrid Solver in Python Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/api/searches/introduction.md This example demonstrates how to create a custom solver by subclassing `AbstractQuasiNewton` and composing different search, descent, and Hessian update strategies. It defines a solver that uses BFGS for Hessian updates, DoglegDescent for the descent path, and a fixed LearningRate for the step size. ```python from collections.abc import Callable import optimistix as optx class HybridSolver(optx.AbstractQuasiNewton): rtol: float atol: float norm: Callable descent: optx.AbstractDescent = optx.DoglegDescent() hessian_update: optx.AbstractQuasiNewtonUpdate = optx.BFGSUpdate(use_inverse=True) search: optx.AbstractSearch = optx.LearningRate(0.1) ``` -------------------------------- ### Build Custom Quasi-Newton Minimiser with HybridSolver Source: https://context7.com/patrick-kidger/optimistix/llms.txt Configure a custom quasi-Newton minimiser by combining a BFGS inverse-Hessian model with a Dogleg path and a fixed learning rate. This example demonstrates how to define a custom solver class inheriting from AbstractQuasiNewton. ```python class HybridSolver(optx.AbstractQuasiNewton): rtol: float atol: float norm: Callable = optx.max_norm descent: optx.AbstractDescent = optx.DoglegDescent() search: optx.AbstractSearch = optx.LearningRate(0.1) import jax.numpy as jnp def fn(x, args): return jnp.sum((x - 2.0) ** 2) y0 = jnp.zeros(3) solver = HybridSolver(rtol=1e-6, atol=1e-6) sol = optx.minimise(fn, solver, y0) print(sol.value) # Array near [2., 2., 2.] ``` -------------------------------- ### Solve ODE Fixed Point with Newton Solver Source: https://github.com/patrick-kidger/optimistix/blob/main/README.md Example of solving an ODE fixed point problem using the Newton solver from Optimistix. This snippet demonstrates setting up the problem and calling the `fixed_point` function. ```python import jax.numpy as jnp import optimistix as optx # Let's solve the ODE dy/dt=tanh(y(t)) with the implicit Euler method. # We need to find y1 s.t. y1 = y0 + tanh(y1)dt. y0 = jnp.array(1.) dt = jnp.array(0.1) def fn(y, args): return y0 + jnp.tanh(y) * dt solver = optx.Newton(rtol=1e-5, atol=1e-5) sol = optx.fixed_point(fn, solver, y0) y1 = sol.value # satisfies y1 == fn(y1) ``` -------------------------------- ### Handling Root Finding Errors Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/examples/root_find.ipynb Illustrates how Optimistix handles cases where a root cannot be found, such as when the function does not have a root or the solver fails. This example shows a function guaranteed not to have a root, leading to an error. ```python def does_not_have_root(y, _): # there is no value of y for which this equals zero. return 1 + y**2 y0 = jnp.array(1.0) optx.root_find(does_not_have_root, solver, y0) ``` -------------------------------- ### Newton Descent Implementation Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/examples/custom_solver.ipynb Implement a custom Newton descent by subclassing `AbstractDescent`. This example handles different function information structures to compute the Newton step, falling back to linear solves if the inverse Hessian is not directly available. ```python import equinox as eqx # https://github.com/patrick-kidger/equinox import jax.tree_util as jtu import lineax as lx # https://github.com/google/lineax from jaxtyping import Array, PyTree # https://github.com/google/jaxtyping class NewtonDescentState(eqx.Module): newton: PyTree[Array] result: optx.RESULTS class NewtonDescent(optx.AbstractDescent): def init(self, y, f_info_struct): del f_info_struct # Dummy values of the right shape; unused. return NewtonDescentState(y, optx.RESULTS.successful) def query(self, y, f_info, state): del state if isinstance(f_info, optx.FunctionInfo.EvalGradHessianInv): newton = f_info.hessian_inv.mv(f_info.grad) result = optx.RESULTS.successful else: if isinstance(f_info, optx.FunctionInfo.EvalGradHessian): operator = f_info.hessian vector = f_info.grad elif isinstance(f_info, optx.FunctionInfo.ResidualJac): operator = f_info.jac vector = f_info.residual else: raise ValueError( "Cannot use a Newton descent with a solver that only evaluates the " "gradient, or only the function itself." ) out = lx.linear_solve(operator, vector) newton = out.value result = optx.RESULTS.promote(out.result) return NewtonDescentState(newton, result) def step(self, step_size, state): return jtu.tree_map(lambda x: -step_size * x, state.newton), state.result ``` -------------------------------- ### Custom Minimiser with BFGS Update Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/examples/custom_solver.ipynb Define a custom minimiser by subclassing `AbstractQuasiNewton` and specifying a BFGS update for the Hessian approximation. This example uses a dogleg-shaped descent path within a trust region algorithm. ```python from collections.abc import Callable import optimistix as optx class MyNewMinimiser(optx.AbstractQuasiNewton): rtol: float atol: float norm: Callable = optx.max_norm descent: optx.AbstractDescent = optx.DoglegDescent() search: optx.AbstractSearch = optx.ClassicalTrustRegion hessian_update: optx.AbstractQuasiNewtonUpdate = optx.BFGSUpdate(use_inverse=False) solver = MyNewMinimiser(rtol=1e-4, atol=1e-4) ``` -------------------------------- ### Serve Documentation Locally Source: https://github.com/patrick-kidger/optimistix/blob/main/CONTRIBUTING.md Build and serve the project's documentation locally using uv run mkdocs serve. Access it at localhost:8000. ```bash uv run mkdocs serve ``` -------------------------------- ### optimistix.FunctionInfo.Eval.__init__ Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/api/searches/function_info.md Initializes the Eval component of FunctionInfo. ```APIDOC ## optimistix.FunctionInfo.Eval.__init__ ### Description Initializes the Eval component of FunctionInfo, likely for function evaluation. ### Method (Method details not provided in source) ### Endpoint (Endpoint details not provided in source) ### Parameters (Parameter details not provided in source) ### Request Example (Request example not provided in source) ### Response #### Success Response (200) (Response details not provided in source) #### Response Example (Response example not provided in source) ``` -------------------------------- ### Custom solver composition Source: https://context7.com/patrick-kidger/optimistix/llms.txt Demonstrates building custom optimisers by mixing AbstractSearch and AbstractDescent components. ```python from collections.abc import Callable import optimistix as optx ``` -------------------------------- ### Interactive Bisection Solve with Optimistix Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/examples/interactive.ipynb Demonstrates an interactive solve using `optimistix.Bisection`. It shows how to manually step through the solver, evaluate intermediate points, and handle the final result. This is useful for debugging or when intermediate results are needed. ```python import equinox as eqx import jax import jax.numpy as jnp import optimistix as optx # Seek `y` such that `y - tanh(y + 1) = 0`. @eqx.filter_jit def fn(y, args): out = y - jnp.tanh(y + 1) aux = None return out, aux solver = optx.Bisection(rtol=1e-3, atol=1e-3) # The initial guess for the solution y = jnp.array(0.0) # Any auxiliary information to pass to `fn`. args = None # The interval to search over. Required for `optx.Bisection`. options = dict(lower=-1, upper=1) # The shape+dtype of the output of `fn` f_struct = jax.ShapeDtypeStruct((), jnp.float32) aux_struct = None # Any Lineax tags describing the structure of the Jacobian matrix d(fn)/dy. # (In this case it's just a 1x1 matrix, so these don't matter.) tags = frozenset() def solve(y, solver): # These arguments are always fixed throughout interactive solves. step = eqx.filter_jit( eqx.Partial(solver.step, fn=fn, args=args, options=options, tags=tags) ) terminate = eqx.filter_jit( eqx.Partial(solver.terminate, fn=fn, args=args, options=options, tags=tags) ) # Initial state before we start solving. state = solver.init(fn, y, args, options, f_struct, aux_struct, tags) done, result = terminate(y=y, state=state) # Alright, enough setup. Let's do the solve! while not done: print(f"Evaluating point {y} with value {fn(y, args)[0]}.") y, state, aux = step(y=y, state=state) done, result = terminate(y=y, state=state) if result != optx.RESULTS.successful: print(f"Oh no! Got error {result}.") y, _, _ = solver.postprocess(fn, y, aux, args, options, state, tags, result) print(f"Found solution {y} with value {fn(y, args)[0]}.") solve(y, solver) ``` -------------------------------- ### Interactive Solve with BestSoFarRootFinder Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/examples/interactive.ipynb Uses `optimistix.BestSoFarRootFinder` to wrap a standard solver, ensuring that the best solution found so far is always retained. This is useful when the solver might overshoot the optimal point and you need to guarantee the best intermediate result. ```python best_so_far_solver = optx.BestSoFarRootFinder(solver) solve(y, best_so_far_solver) ``` -------------------------------- ### Import Libraries for ODE Optimisation Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/examples/optimise_diffeq.ipynb Imports necessary libraries including Diffrax for ODE solving, Equinox for JAX operations, and Optimistix for optimisation. ```python import diffrax as dfx # https://github.com/patrick-kidger/diffrax import equinox as eqx # https://github.com/patrick-kidger/equinox import jax.numpy as jnp import matplotlib.pyplot as plt import optimistix as optx from jaxtyping import Array, Float # https://github.com/google/jaxtyping ``` -------------------------------- ### Compat.minimize for jax.scipy.optimize.minimize Replacement Source: https://context7.com/patrick-kidger/optimistix/llms.txt Provides a drop-in replacement for the deprecated `jax.scipy.optimize.minimize` using `optimistix.compat.minimize`. Currently, only the `method="bfgs"` is supported, matching the original API. ```python import jax.numpy as jnp from optimistix import compat as optx_compat def rosenbrock(x, a, b): return (a - x[0]) ** 2 + b * (x[1] - x[0] ** 2) ** 2 x0 = jnp.array([0.0, 0.0]) result = optx_compat.minimize(rosenbrock, x0, args=(1.0, 100.0), method="bfgs", tol=1e-6) print(result.x) # Array near [1., 1.] print(result.success) # True print(result.fun) # Value near 0.0 print(result.nit) # Number of accepted steps ``` -------------------------------- ### Explore Available Searches and Descents in Optimistix Source: https://context7.com/patrick-kidger/optimistix/llms.txt Lists and demonstrates the instantiation of various search strategies (LearningRate, BacktrackingArmijo, ClassicalTrustRegion, LinearTrustRegion) and descent methods (SteepestDescent, NewtonDescent, DampedNewtonDescent, DoglegDescent, NonlinearCGDescent) available in Optimistix. ```python # Available searches lr = optx.LearningRate(0.01) armijo = optx.BacktrackingArmijo(decrease_factor=0.5, slope=0.1, backtrack_slope=0.5) ctr = optx.ClassicalTrustRegion() ltr = optx.LinearTrustRegion() # Available descents sd = optx.SteepestDescent() nd = optx.NewtonDescent() dnd = optx.DampedNewtonDescent() dd = optx.DoglegDescent() cgd = optx.NonlinearCGDescent() ``` -------------------------------- ### optimistix.FunctionInfo.EvalGrad.__init__ Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/api/searches/function_info.md Initializes the EvalGrad component of FunctionInfo for evaluating function and gradient. ```APIDOC ## optimistix.FunctionInfo.EvalGrad.__init__ ### Description Initializes the EvalGrad component of FunctionInfo, used for evaluating both the function and its gradient. ### Method (Method details not provided in source) ### Endpoint (Endpoint details not provided in source) ### Parameters (Parameter details not provided in source) ### Request Example (Request example not provided in source) ### Response #### Success Response (200) (Response details not provided in source) #### Response Example (Response example not provided in source) ``` -------------------------------- ### Verifying the Solution Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/examples/root_find.ipynb Prints the found solution's value and verifies that it is indeed a root of the defined function by evaluating the function at the solution. ```python print(sol.value) ``` ```python print(fn(sol.value, args=None)) ``` -------------------------------- ### Simulate Training Data Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/examples/optimise_diffeq.ipynb Generates simulated training data for the Lotka-Volterra equations. It uses multiple initial conditions and a batch solve to create the data. ```python def get_data() -> tuple[Float[Array, "3 2"], Float[Array, "3 50"]]: """Simulate some training data.""" # We consider three possible initial conditions. y0_a = jnp.array([9.0, 9.0]) y0_b = jnp.array([10.0, 10.0]) y0_c = jnp.array([11.0, 11.0]) y0s = jnp.stack([y0_a, y0_b, y0_c]) true_parameters = jnp.array([0.1, 0.02, 0.4, 0.02]) saveat = dfx.SaveAt(ts=jnp.linspace(0, 30, 20)) batch_solve = eqx.filter_jit(eqx.filter_vmap(solve, in_axes=(None, 0, None))) values = batch_solve(true_parameters, y0s, saveat) return y0s, values ``` -------------------------------- ### optimistix.FunctionInfo.EvalGradHessianInv.__init__ Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/api/searches/function_info.md Initializes the EvalGradHessianInv component of FunctionInfo for evaluating function, gradient, Hessian, and its inverse. ```APIDOC ## optimistix.FunctionInfo.EvalGradHessianInv.__init__ ### Description Initializes the EvalGradHessianInv component of FunctionInfo, allowing for the evaluation of the function, its gradient, its Hessian, and the inverse of the Hessian. ### Method (Method details not provided in source) ### Endpoint (Endpoint details not provided in source) ### Parameters (Parameter details not provided in source) ### Request Example (Request example not provided in source) ### Response #### Success Response (200) (Response details not provided in source) #### Response Example (Response example not provided in source) ``` -------------------------------- ### Perform Least Squares Optimisation Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/examples/optimise_diffeq.ipynb Initialises the Levenberg-Marquardt solver and performs a least squares optimisation to fit the Lotka-Volterra parameters to the simulated data. The `verbose=True` option shows the optimisation progress. ```python (y0s, values) = get_data() solver = optx.LevenbergMarquardt(rtol=1e-8, atol=1e-8, verbose=True) init_parameters = jnp.zeros(4) sol = optx.least_squares(residuals, solver, init_parameters, args=(y0s, values)) ``` -------------------------------- ### ImplicitAdjoint for Differentiating Through Solvers Source: https://context7.com/patrick-kidger/optimistix/llms.txt Illustrates how to use `optimistix.ImplicitAdjoint` to backpropagate through a nonlinear solve using the implicit function theorem. This is the default adjoint method and is recommended for most use cases. It bypasses solver iterations entirely. ```python import jax import jax.numpy as jnp import optimistix as optx def fn(y, args): a = args return y ** 3 - a # root is y = a^(1/3) def cube_root(a): solver = optx.Newton(rtol=1e-8, atol=1e-8, adjoint=optx.ImplicitAdjoint()) sol = optx.root_find(fn, solver, jnp.array(1.0), args=a) return sol.value # Differentiate through the solver a = jnp.array(8.0) val, grad = jax.value_and_grad(cube_root)(a) print(val) # 2.0 (cube root of 8) print(grad) # 1/3 * a^(-2/3) = 1/(3*4) ≈ 0.0833 ``` -------------------------------- ### Initialize Controlled Van der Pol Oscillator Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/examples/van_der_pol.ipynb Sets up the parameters for the Van der Pol oscillator and initializes the controlled system. This is used to define the objective function for optimization. ```python t0 = 0.0 t1 = 10.0 dt0 = 0.01 num_control_inputs = 30 controlled = ControlledVanDerPol(t0, t1, dt0, num_control_inputs, 0.1) timepoints = jnp.linspace(t0, t1, 100) u0 = 0.25 * jr.normal(jr.key(0), (num_control_inputs,)) initial_condition = 20 * jnp.array([0.1, 0.1]) args = (timepoints, initial_condition) value, initial_aux = controlled(u0, args) print("Initial value of the objective function:", value) ``` -------------------------------- ### DFP Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/api/minimise.md Implements the DFP quasi-Newton minimisation method. ```APIDOC ## optimistix.DFP ### Description Implements the DFP quasi-Newton minimisation method. ### Methods - __init__ ``` -------------------------------- ### optimistix.FixedPointIteration Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/api/fixed_point.md A simple fixed point iteration solver. ```APIDOC ## optimistix.FixedPointIteration ### Description A simple fixed point iteration solver. ### Method - `__init__(rtol=None, atol=None, max_iterations=1000)`: Initializes the FixedPointIteration solver with relative tolerance (rtol), absolute tolerance (atol), and maximum number of iterations. ``` -------------------------------- ### optimistix.FunctionInfo.Residual.__init__ Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/api/searches/function_info.md Initializes the Residual component of FunctionInfo for evaluating residuals. ```APIDOC ## optimistix.FunctionInfo.Residual.__init__ ### Description Initializes the Residual component of FunctionInfo, which is used for evaluating the residuals of a function. ### Method (Method details not provided in source) ### Endpoint (Endpoint details not provided in source) ### Parameters (Parameter details not provided in source) ### Request Example (Request example not provided in source) ### Response #### Success Response (200) (Response details not provided in source) #### Response Example (Response example not provided in source) ``` -------------------------------- ### Find root of sin(x) - 0.5 using Chord method Source: https://context7.com/patrick-kidger/optimistix/llms.txt Solves a 1D root-finding problem using the Chord method, which re-uses the initial Jacobian. Suitable when the Jacobian is approximately constant. ```python import jax.numpy as jnp import optimistix as optx def fn(x, args): return jnp.sin(x) - 0.5 y0 = jnp.array(0.5) solver = optx.Chord(rtol=1e-7, atol=1e-7) sol = optx.root_find(fn, solver, y0) print(sol.value) # Array near 0.5236 (pi/6) ``` -------------------------------- ### Optimistix Solution Object Interface Source: https://context7.com/patrick-kidger/optimistix/llms.txt Demonstrates the uniform interface of the `optimistix.Solution` object, which is returned by all four solve functions (`minimise`, `least_squares`, `root_find`, `fixed_point`). Shows how to access the solution value, result status, auxiliary data, and solver statistics. ```python import jax.numpy as jnp import optimistix as optx def fn(x, args): return jnp.sum((x - 1.0) ** 2), {"norm": jnp.linalg.norm(x)} y0 = jnp.zeros(3) solver = optx.BFGS(rtol=1e-7, atol=1e-7) sol = optx.minimise(fn, solver, y0, has_aux=True) print(sol.value) # Array near [1., 1., 1.] print(sol.result) # RESULTS.successful print(sol.aux) # {"norm": 1.732...} print(sol.stats["num_steps"]) # Number of solver steps taken ``` -------------------------------- ### optimistix.compat.minimize Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/api/compat.md A drop-in replacement for `jax.scipy.optimize.minimize`. ```APIDOC ## optimistix.compat.minimize ### Description Provides a drop-in replacement for the deprecated `jax.scipy.optimize.minimize` function. ### Method (Not specified in source) ### Endpoint (Not specified in source) ### Parameters (Not specified in source) ### Request Example (Not specified in source) ### Response (Not specified in source) ``` -------------------------------- ### Run Unit Tests Source: https://github.com/patrick-kidger/optimistix/blob/main/CONTRIBUTING.md Execute the project's unit tests using pytest via the uv run command. ```bash uv run pytest ``` -------------------------------- ### optimistix.FunctionInfo.EvalGradHessian.__init__ Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/api/searches/function_info.md Initializes the EvalGradHessian component of FunctionInfo for evaluating function, gradient, and Hessian. ```APIDOC ## optimistix.FunctionInfo.EvalGradHessian.__init__ ### Description Initializes the EvalGradHessian component of FunctionInfo, enabling the evaluation of the function, its gradient, and its Hessian. ### Method (Method details not provided in source) ### Endpoint (Endpoint details not provided in source) ### Parameters (Parameter details not provided in source) ### Request Example (Request example not provided in source) ### Response #### Success Response (200) (Response details not provided in source) #### Response Example (Response example not provided in source) ``` -------------------------------- ### Use OptaxMinimiser for messy minimisation problems Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/how-to-choose.md For 'messier' minimisation problems where the function surface is not well-behaved, first-order gradient algorithms often perform well. OptaxMinimiser is recommended for such cases, taking many small steps and avoiding large deviations from the current best solution. ```python optimistix.OptaxMinimiser(optax.adabelief(learning_rate=1e-3), rtol=1e-8, atol=1e-8) ``` -------------------------------- ### Analyze Benchmark Results Source: https://github.com/patrick-kidger/optimistix/blob/main/CONTRIBUTING.md Analyze benchmark results using the profile.py script. Specify platform, Python version, precision, run ID, benchmark kind, and solver names. ```bash python benchmarks/profile.py *solver_names ``` ```bash python benchmarks/profile.py Darwin 3.13 64bit 0001 runtime optx.BFGS optx.LBFGS ``` -------------------------------- ### AbstractGaussNewton Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/api/least_squares.md Abstract base class for Gauss-Newton solvers. ```APIDOC ## Class: optimistix.AbstractGaussNewton ### Description Abstract base class for Gauss-Newton solvers. This class does not expose any public methods beyond those inherited from `AbstractLeastSquaresSolver`. ``` -------------------------------- ### AbstractRootFinder Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/api/root_find.md Abstract base class for root finding algorithms in Optimistix. ```APIDOC ## AbstractRootFinder ### Description Abstract base class defining the interface for root finders. ### Methods - `init`: Initializes the root finder. - `step`: Performs one step of the root-finding algorithm. - `terminate`: Checks if the termination criteria have been met. - `postprocess`: Processes the results after termination. ``` -------------------------------- ### Find fixed points with Optimistix Source: https://context7.com/patrick-kidger/optimistix/llms.txt Use `optimistix.fixed_point` to find `z` such that `fn(z, args) = z`. It accepts various solver types, including `AbstractFixedPointSolver`, `AbstractRootFinder`, `AbstractLeastSquaresSolver`, or `AbstractMinimiser`, and is JIT-compiled. ```python import jax.numpy as jnp import optimistix as optx ``` -------------------------------- ### optimistix.FunctionInfo.as_min Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/api/searches/function_info.md Converts the FunctionInfo object into a format suitable for minimization problems. ```APIDOC ## optimistix.FunctionInfo.as_min ### Description Converts the FunctionInfo object into a format suitable for minimization problems. ### Method (Method details not provided in source) ### Endpoint (Endpoint details not provided in source) ### Parameters (Parameter details not provided in source) ### Request Example (Request example not provided in source) ### Response #### Success Response (200) (Response details not provided in source) #### Response Example (Response example not provided in source) ``` -------------------------------- ### Find root of x^3 - x - 2 using Bisection Source: https://context7.com/patrick-kidger/optimistix/llms.txt Solves a 1D root-finding problem using the Bisection method. Requires bracket options (lower and upper bounds) and does not require differentiability. ```python import jax.numpy as jnp import optimistix as optx def fn(x, args): return x ** 3 - x - 2.0 # root near 1.5214 y0 = jnp.array(1.5) solver = optx.Bisection(rtol=1e-10, atol=1e-10) sol = optx.root_find( fn, solver, y0, options={"lower": jnp.array(1.0), "upper": jnp.array(2.0)} ) print(sol.value) # Array near 1.5214 ``` -------------------------------- ### PyTree Norms for Convergence Testing Source: https://context7.com/patrick-kidger/optimistix/llms.txt Demonstrates the usage of `optimistix.max_norm`, `rms_norm`, and `two_norm` for PyTree norms, which are used in convergence criteria. `max_norm` is the default and is invariant to problem size. Shows how to pass a custom norm to a solver. ```python import jax.numpy as jnp import optimistix as optx x = {"a": jnp.array([1.0, -2.0]), "b": jnp.array(3.0)} print(optx.max_norm(x)) # 3.0 (max absolute value) print(optx.rms_norm(x)) # sqrt(mean([1, 4, 9])) = sqrt(14/3) print(optx.two_norm(x)) # sqrt(1 + 4 + 9) = sqrt(14) # Pass a custom norm to a solver solver = optx.Newton(rtol=1e-6, atol=1e-6, norm=optx.rms_norm) ``` -------------------------------- ### Solve root-finding problems with Optimistix Source: https://context7.com/patrick-kidger/optimistix/llms.txt Use `optimistix.root_find` to find `z` such that `fn(z, args) = 0`. It accepts various solver types and is JIT-compiled. Supports 1D Bisection with bounds and multidimensional solvers like Chord. ```python import jax.numpy as jnp import optimistix as optx # Find the root of f(x) = x^3 - x - 2 (root near x=1.5214) def fn(x, args): return x ** 3 - x - 2.0 y0 = jnp.array(1.0) solver = optx.Newton(rtol=1e-8, atol=1e-8) sol = optx.root_find(fn, solver, y0) print(sol.value) # Array near 1.5214 # 1D: use Bisection with explicit lower/upper bounds solver_bisect = optx.Bisection(rtol=1e-6, atol=1e-6) sol = optx.root_find( fn, solver_bisect, y0, options={"lower": jnp.array(1.0), "upper": jnp.array(2.0)} ) print(sol.value) # Array near 1.5214 # Multidimensional root-finding with Chord solver def system(xy, args): x, y = xy return jnp.array([x ** 2 + y ** 2 - 1.0, x - y]) # unit circle + diagonal y0_2d = jnp.array([0.5, 0.5]) solver_chord = optx.Chord(rtol=1e-6, atol=1e-6) sol = optx.root_find(system, solver_chord, y0_2d) print(sol.value) # Array near [0.707, 0.707] ``` -------------------------------- ### NewtonDescent Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/api/searches/descents.md Implements Newton's method for optimization. ```APIDOC ## Class: NewtonDescent ### Description Represents Newton's descent method for optimization. This method uses second-order derivative information (Hessian) for faster convergence near the optimum. ### Methods - `__init__(...)`: Constructor for the NewtonDescent class. Initializes the Newton descent optimizer. ``` -------------------------------- ### optimistix.root_find Source: https://context7.com/patrick-kidger/optimistix/llms.txt Finds `z` such that `fn(z, args) = 0`. Accepts `AbstractRootFinder`, `AbstractLeastSquaresSolver`, or `AbstractMinimiser` as the solver. JIT-compiled automatically. ```APIDOC ## optimistix.root_find — Solve a root-finding problem ### Description Finds `z` such that `fn(z, args) = 0`. Accepts `AbstractRootFinder`, `AbstractLeastSquaresSolver`, or `AbstractMinimiser` as the solver. JIT-compiled automatically. ### Usage ```python import jax.numpy as jnp import optimistix as optx # Find the root of f(x) = x^3 - x - 2 (root near x=1.5214) def fn(x, args): return x ** 3 - x - 2.0 y0 = jnp.array(1.0) solver = optx.Newton(rtol=1e-8, atol=1e-8) sol = optx.root_find(fn, solver, y0) print(sol.value) # Array near 1.5214 # 1D: use Bisection with explicit lower/upper bounds solver_bisect = optx.Bisection(rtol=1e-6, atol=1e-6) sol = optx.root_find( fn, solver_bisect, y0, options={"lower": jnp.array(1.0), "upper": jnp.array(2.0)} ) print(sol.value) # Array near 1.5214 # Multidimensional root-finding with Chord solver def system(xy, args): x, y = xy return jnp.array([x ** 2 + y ** 2 - 1.0, x - y]) # unit circle + diagonal y0_2d = jnp.array([0.5, 0.5]) solver_chord = optx.Chord(rtol=1e-6, atol=1e-6) sol = optx.root_find(system, solver_chord, y0_2d) print(sol.value) # Array near [0.707, 0.707] ``` ``` -------------------------------- ### GaussNewton Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/api/least_squares.md Implementation of the Gauss-Newton least squares solver. ```APIDOC ## Class: optimistix.GaussNewton ### Description Gauss-Newton algorithm for solving least squares problems. ### Methods - `__init__`: Initializes the Gauss-Newton solver. ``` -------------------------------- ### optimistix.Solution Source: https://context7.com/patrick-kidger/optimistix/llms.txt The `Solution` object is a container for the output of Optimistix solver functions, providing a uniform interface for results across `minimise`, `least_squares`, `root_find`, and `fixed_point`. ```APIDOC ### `optimistix.Solution` — Container for solver output All four solve functions (`minimise`, `least_squares`, `root_find`, `fixed_point`) return a `Solution` object with a uniform interface. ```python import jax.numpy as jnp import optimistix as optx def fn(x, args): return jnp.sum((x - 1.0) ** 2), {"norm": jnp.linalg.norm(x)} y0 = jnp.zeros(3) solver = optx.BFGS(rtol=1e-7, atol=1e-7) sol = optx.minimise(fn, solver, y0, has_aux=True) print(sol.value) # Array near [1., 1., 1.] print(sol.result) # RESULTS.successful print(sol.aux) # {"norm": 1.732...} print(sol.stats["num_steps"]) # Number of solver steps taken ``` ``` -------------------------------- ### optimistix.BestSoFarMinimiser / BestSoFarLeastSquares / BestSoFarRootFinder / BestSoFarFixedPoint Source: https://context7.com/patrick-kidger/optimistix/llms.txt Wrappers that track and return the best iterate seen during a solve, instead of the final iterate. Useful when solvers might oscillate or diverge after initially finding a good solution. ```APIDOC ## BestSoFar Wrappers ### Description Wraps any solver and tracks the best iterate seen so far during the solve, returning it instead of the final iterate. Useful when solvers may oscillate or diverge after initially finding a good solution. ### Usage Example (BestSoFarMinimiser) ```python import jax.numpy as jnp import optimistix as optx def fn(x, args): return jnp.sum((x - 1.0) ** 2) + 0.1 * jnp.sum(jnp.sin(10 * x)) y0 = jnp.array([0.0, 0.0]) inner_solver = optx.BFGS(rtol=1e-5, atol=1e-5) solver = optx.BestSoFarMinimiser(inner_solver) sol = optx.minimise(fn, solver, y0, max_steps=200) print(sol.value) # Best value encountered during the solve ``` ``` -------------------------------- ### Wrapping Optax Optimizers for Minimization Source: https://context7.com/patrick-kidger/optimistix/llms.txt Wraps any Optax first-order optimizer (e.g., Adam, SGD) for use with the Optimistix API. Requires `optimistix`, `jax.numpy`, and `optax`. ```python import jax.numpy as jnp import optax import optimistix as optx def fn(x, args): return jnp.sum((x - 1.0) ** 4) y0 = jnp.zeros(3) # Pass an Optax optimizer instance, not the class itself solver = optx.OptaxMinimiser(optax.adam(learning_rate=1e-2), rtol=1e-6, atol=1e-6) sol = optx.minimise(fn, solver, y0, max_steps=5000) print(sol.value) # Array near [1., 1., 1.] ``` -------------------------------- ### BFGS Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/api/minimise.md Implements the BFGS quasi-Newton minimisation method. ```APIDOC ## optimistix.BFGS ### Description Implements the BFGS quasi-Newton minimisation method. ### Methods - __init__ ``` -------------------------------- ### OptaxMinimiser Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/api/minimise.md Wrapper for Optax minimisers. ```APIDOC ## optimistix.OptaxMinimiser ### Description Wrapper for Optax minimisers, allowing the use of Optax's extensive collection of first-order gradient methods within the Optimistix API. ### Usage `optim` in `optimistix.OptaxMinimiser` should be an instance of an Optax minimiser, e.g., `optimistix.OptaxMinimiser(optax.adam(...), ...)`. ### Methods - __init__ ``` -------------------------------- ### Run Benchmark Tests Source: https://github.com/patrick-kidger/optimistix/blob/main/CONTRIBUTING.md Execute benchmark tests specifically for the benchmarks directory using uv run pytest with the --benchmark-only flag. ```bash uv run pytest benchmarks/ --benchmark-only ``` -------------------------------- ### Find roots of a 2D system using Newton's method Source: https://context7.com/patrick-kidger/optimistix/llms.txt Solves a system of non-linear equations for their roots using Newton's method. Requires a function that returns a vector of residuals and an initial guess. ```python import jax.numpy as jnp import optimistix as optx # Find all roots of a 2D system def fn(xy, args): x, y = xy return jnp.array([ x ** 2 - y - 1.0, y ** 2 - x - 1.0 ]) y0 = jnp.array([1.5, 1.5]) solver = optx.Newton(rtol=1e-9, atol=1e-9) sol = optx.root_find(fn, solver, y0) print(sol.value) # Array near [1.618, 1.618] (golden ratio) ``` -------------------------------- ### optimistix.AbstractFixedPointSolver Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/api/fixed_point.md Abstract base class for fixed point solvers. Users can implement custom solvers by inheriting from this class and implementing the `init`, `step`, `terminate`, and `postprocess` methods. ```APIDOC ## optimistix.AbstractFixedPointSolver ### Description Abstract base class for fixed point solvers. ### Methods - `init(f, y, args, options)`: Initializes the solver state. - `step(f, y, args, options, state, persistent_state)`: Performs one step of the fixed point iteration. - `terminate(f, y, args, options, state, persistent_state)`: Checks if the termination criteria have been met. - `postprocess(f, y, args, options, state, persistent_state)`: Postprocesses the result before returning. ``` -------------------------------- ### SteepestDescent Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/api/searches/descents.md Implements the steepest descent optimization algorithm. ```APIDOC ## Class: SteepestDescent ### Description Represents the steepest descent optimization algorithm. This class typically initializes with parameters specific to the steepest descent method. ### Methods - `__init__(...)`: Constructor for the SteepestDescent class. Initializes the steepest descent optimizer. ``` -------------------------------- ### RecursiveCheckpointAdjoint for Backprop Through Solver Iterates Source: https://context7.com/patrick-kidger/optimistix/llms.txt Demonstrates the use of `optimistix.RecursiveCheckpointAdjoint` for differentiating through the actual solver loop using binomial checkpointing. This method keeps memory usage at O(n log n) and should be used when `ImplicitAdjoint` is not applicable. ```python import jax import jax.numpy as jnp import optimistix as optx def fn(y, args): return jnp.cos(y) - args def solve_with_checkpoint(a): adjoint = optx.RecursiveCheckpointAdjoint(checkpoints=16) solver = optx.Newton(rtol=1e-8, atol=1e-8) sol = optx.fixed_point(fn, solver, jnp.array(1.0), args=a, adjoint=adjoint) return sol.value grad_fn = jax.grad(solve_with_checkpoint) print(grad_fn(jnp.array(0.5))) ``` -------------------------------- ### Dogleg Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/api/least_squares.md Implementation of the Dogleg least squares solver. ```APIDOC ## Class: optimistix.Dogleg ### Description Dogleg algorithm for solving least squares problems. ### Methods - `__init__`: Initializes the Dogleg solver. ``` -------------------------------- ### optimistix.compat.OptimizeResults Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/api/compat.md Represents the results returned by the compatibility minimize function. ```APIDOC ## optimistix.compat.OptimizeResults ### Description Represents the results object returned by `optimistix.compat.minimize`. ### Parameters (Not specified in source) ### Response (Not specified in source) ``` -------------------------------- ### BestSoFarRootFinder Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/api/root_find.md A wrapper that keeps track of the best root found so far across multiple steps or iterations. ```APIDOC ## BestSoFarRootFinder ### Description Keeps track of the best root found so far during the root-finding process. ### Method `optimistix.BestSoFarRootFinder` ### Parameters This class has an `__init__` method. Specific parameters for `__init__` are not detailed in the source. ``` -------------------------------- ### Solve ODE and Plot Results Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/examples/optimise_diffeq.ipynb Solves the ODE over a specified time span with the optimised parameters and plots the resulting trajectories for different variables. Ensure 'solve' and 'dfx.SaveAt' are imported. ```python ts = jnp.linspace(0, 140, 1000) ys = solve(sol.value, jnp.array([10.0, 10.0]), dfx.SaveAt(ts=ts)) plt.plot(ts, ys[:, 0], label="Prey") plt.plot(ts, ys[:, 1], label="Predator") plt.legend() plt.show() ``` -------------------------------- ### optimistix.FunctionInfo.ResidualJac.__init__ Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/api/searches/function_info.md Initializes the ResidualJac component of FunctionInfo for evaluating residuals and their Jacobians. ```APIDOC ## optimistix.FunctionInfo.ResidualJac.__init__ ### Description Initializes the ResidualJac component of FunctionInfo, enabling the evaluation of both residuals and their corresponding Jacobians. ### Method (Method details not provided in source) ### Endpoint (Endpoint details not provided in source) ### Parameters (Parameter details not provided in source) ### Request Example (Request example not provided in source) ### Response #### Success Response (200) (Response details not provided in source) #### Response Example (Response example not provided in source) ``` -------------------------------- ### AbstractLeastSquaresSolver Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/api/least_squares.md The base class for all least squares solvers in Optimistix. ```APIDOC ## Class: optimistix.AbstractLeastSquaresSolver ### Description This is the abstract base class for all least squares solvers. ### Methods - `init`: Initializes the solver. - `step`: Performs one step of the optimization. - `terminate`: Checks if the optimization has terminated. - `postprocess`: Post-processes the results. ``` -------------------------------- ### Optimistix.ImplicitAdjoint Source: https://context7.com/patrick-kidger/optimistix/llms.txt The `ImplicitAdjoint` class implements backpropagation through a nonlinear solve using the implicit function theorem. It bypasses solver iterations and is the default, recommended for most use cases. ```APIDOC ### `optimistix.ImplicitAdjoint` — Implicit function theorem (default) Backpropagates through a nonlinear solve via the implicit function theorem, bypassing the solver iterations entirely. This is the default and is recommended for almost all use cases. ```python import jax import jax.numpy as jnp import optimistix as optx def fn(y, args): a = args return y ** 3 - a # root is y = a^(1/3) def cube_root(a): solver = optx.Newton(rtol=1e-8, atol=1e-8, adjoint=optx.ImplicitAdjoint()) sol = optx.root_find(fn, solver, jnp.array(1.0), args=a) return sol.value # Differentiate through the solver a = jnp.array(8.0) val, grad = jax.value_and_grad(cube_root)(a) print(val) # 2.0 (cube root of 8) print(grad) # 1/3 * a^(-2/3) = 1/(3*4) ≈ 0.0833 ``` ``` -------------------------------- ### Dai-Yuan Method for NonlinearCG Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/api/minimise.md Specifies the Dai-Yuan method for computing the \(\\beta\) parameter in NonlinearCG. ```APIDOC ## optimistix.dai_yuan ### Description Specifies the Dai-Yuan method for computing the \(\\beta\) parameter in NonlinearCG. ``` -------------------------------- ### Plotting Initial and Final States Source: https://github.com/patrick-kidger/optimistix/blob/main/docs/examples/van_der_pol.ipynb Prepares for plotting the initial and final states of the Van der Pol oscillator. This snippet is typically followed by plotting commands to visualize the results. ```python fig, [ax, ax2] = plt.subplots(1, 2, figsize=(9, 4)) initial_state, initial_u = initial_aux final_state, final_control = solution.aux ```