Formalizing equations and equation systems#

Algebraic equations#

class skhippr.equations.AbstractEquation.AbstractEquation(stability_method=None)#

Abstract base class for algebraic equations in the SKHiPPR framework.

Must provide a residual. The residual may depend on arbitrarily many attributes of the object and must return a numpy array. The NewtonSolver attempts to modify the object’s attributes such that the residual becomes zero.

Subclasses may provide closed-form expressions for the derivatives of the residual with respect to the attributes. Otherwise, finite differences are used.

The class also offers functionality for stability analysis if a AbstractStabilityMethod object is passed.

abstractmethod residual_function()#

Compute the residual function based on attributes of the object. This method must be implemented in subclasses.

derivative(variable: str, update=False, h_fd=0.0001) ndarray#

Compute the derivative of the residual with respect to a given variable. This method should be called whenever a derivative is desired.

If update is False, a previously computed derivative is returned if available. Otherwise, the derivative is computed anew and is cached for future use.

If closed-form derivatives are available, they are used. Otherwise, if closed_form_derivative() raises a NotImplementedError, finite_difference_derivative() is used to compute the derivative.

Parameters:
  • variable (str) – The name of the variable (attribute) with respect to which the derivative is computed.

  • update (bool, optional) – If True, updates the cached derivative with the newly computed value. Default is False.

  • h_fd (float, optional) – Step size for finite difference approximation. Default is 1e-4.

Returns:

The partial derivative of the residual with respect to the specified variable.

Return type:

np.ndarray

closed_form_derivative(variable: str) ndarray#

Compute the closed-form derivative of the residual with respect to a given variable. To be implemented in subclasses. Must raise a NotImplementedError if closed-form derivative is nonzero and not available analytically.

Returns:

The closed-form derivative of the residual with respect to the specified variable as a2-D numpy array. Must be 2-D even if the variable or the residual is a scalar.

Return type:

np.ndarray

Raises:

NotImplementedError – If the derivative is not available in closed form and should be determined using finite differences.

finite_difference_derivative(variable, h_step=0.0001) ndarray#

Compute the finite difference derivative of the residual with respect to a given variable.

Parameters:
  • variable (str) – The name of the variable (attribute) with respect to which the derivative is computed.

  • h_step (float, optional) – Step size for finite difference approximation. Default is 1e-4.

Returns:

The finite difference derivative of the residual with respect to the specified variable as a 2-D numpy array.

Return type:

np.ndarray

determine_stability(update=False)#

Determine the stability of the equation using the stability method.

If the stability method is not set, an AttributeError is raised. If update is True, the eigenvalues are computed using the stability method. Otherwise, the cached values is used. The stability is determined based on stability_criterion().

Parameters:

update (bool, optional) – If True, updates the eigenvalues and stability status. Default is False.

stability_criterion(eigenvalues)#

Determine stability based on stability-defining eigenvalues computed by the stability method.

Equation systems#

Equation systems collect a set of AbstractEquation objects, together with their unknowns. Notable subclasses of EquationSystem are documented elsewhere:

class skhippr.equations.EquationSystem.EquationSystem(equations: Iterable[AbstractEquation], unknowns: Iterable[str], equation_determining_stability: AbstractEquation = None)#

Encodes (one or multiple) AbstractEquation objects, together with a matching set of unknowns (names of attributes of one or more equations), to be solved by the NewtonSolver.

All unknowns are attributes of the EquationSystem and of all its collected AbstractEquation objects. If the unknown is updated in the EquationSystem, it is also updated in all equations.

One of the equations can be chosen to determine the stability of the system. This is done by passing an equation as equation_determining_stability to the constructor. If no such equation is given, no stability analysis is performed.

property well_posed#

Checks if the system of equations is well-posed, i.e., if the total number of equations matches the total number of unknowns.

property vector_of_unknowns: ndarray#

All individual unknowns, stacked into a single 1-D numpy array in the order given by self.unknowns. This property can also be set to update all unknowns in the system.

property stable: bool#

Stability of the equation system, determined by the equation given in self.equation_determining_stability.

property eigenvalues: ndarray#

Eigenvalues governing the stability of the equation system, determined by the equation given in self.equation_determining_stability.

residual_function(update=False) ndarray#

Assembles one overall residual (1-D numpy array) by stacking the residuals of self.equations.

jacobian(update=False, h_fd=0.0001) ndarray#

Assemble the derivative of the overall residual w.r.t all the unknowns (2-D numpy array), with the ordering given by the ordering of self.equations and self.unknowns, respectively.

duplicate() EquationSystem#

Creates a copy of the EquationSystem, with all equations and the equation determining stability shallow-copied to avoid accidental changes to the original equations.

Concrete subclasses of AbstractEquation#

The following subclasses of AbstractEquation are documented elsewhere:

Two concrete subclass for demonstration purposes encode radius and angle conditions on a circle.

class skhippr.equations.Circle.CircleEquation(y: ndarray, radius=1)#

Has attributes y and radius. The residual function:

self.y[0] ** 2 + self.y[1] ** 2 - self.radius**2

is zero when the point y lies on the circle with radius radius.

class skhippr.equations.Circle.AngleEquation(y: ndarray, theta=1)#

Has attributes y and theta. If y encloses the angle theta with the positive x axis, then . the residual function:

self.y[1] * np.cos(self.theta) - self.y[0] * np.sin(self.theta)

vanishes.