Functions and Relations#

Functions#

class sigmaepsilon.math.function.Function(f0: FunctionLike | None = None, f1: Callable | None = None, f2: Callable | None = None, *args, variables: Iterable | None = None, **kwargs)[source]#

Base class for all kinds of functions. It can be used to represent symbolic and numerical functions. The class is designed to be as flexible as possible, so it can be used in a wide range of applications.

As you can see from the examples, the class can be used in a variety of ways. You can initialize a function object with a string expression, a SymPy expression, or with numerical functions. If you initialize the object with a string or a SymPy expression, first and second derivatives can be calculated automatically.

Parameters:
  • f0 (FunctionLike or None, Optional) – Positional parameter. A callable object that returns function evaluations.

  • f1 (Callable or None, Optional) – Positional parameter. A callable object that returns evaluations of the gradient of the function. If the first positional argument is a string or a SymPy expression, this parameter can be ignored and derivative functions are calculated automatically.

  • f2 (Callable or None, Optional) – Positional parameter. A callable object that returns evaluations of the Hessian of the function. If the first positional argument is a string or a SymPy expression, this parameter can be ignored and derivative functions are calculated automatically.

  • variables (List, Optional) – Symbolic variables. Only required if the function is defined by a string or SymPy expression.

  • value (Callable, Optional) – Keyword only parameter. Same as f0.

  • gradient (Callable, Optional) – Keyword only parameter.Same as f1.

  • Hessian (Callable, Optional) – Keyword only parameter.Same as f2.

  • d (dimension or dim or) – Keyword only parameter. The number of dimensions of the domain of the function. This property is only required if the function is defined by numerical functions.

Examples

>>> from sigmaepsilon.math.function import Function
>>> import sympy as sy
>>> import numpy as np

Define a symbolic function with positive variables. Note here that if it was not relevant from the aspect of the application to indicate that the variables are positive, it wouldn’t be necessary to explicity specify them using the parameter variables.

>>> variables = ['x1', 'x2', 'x3', 'x4']
>>> x1, x2, x3, x4 = syms = sy.symbols(variables, positive=True)
>>> f = Function(3*x1 + 9*x3 + x2 + x4, variables=syms)
>>> f([0, 6, 0, 4])
10

An equivalent definition can be given without using SymPy explicitly:

>>> f = Function("3*x1 + 9*x3 + x2 + x4", variables=['x1', 'x2', 'x3', 'x4'])
>>> f([0, 6, 0, 4])
10

In both cases, providing the argument ‘variables’ is optional, but it determines the order of the arguments. If the function is defined without the variables being provided, it is derived from the input, but the order of the arguments may differ from what you would expect. Also defining the variables with SymPy might be important if you want to indicate something about their nature, eg. that they are positive, as in the example above. For instance if you execute the following code, the result my change from execution to execution.

>>> f = Function("3*x1 + 9*x3 + x2 + x4")
>>> f.variables  
(x3, x1, x4, x2)

Define a numerical function. In this case the dimension of the input must be specified explicitly.

>>> def f0(x, y): return x**2 + y
>>> def f1(x, y): return np.array([2*x, 1])
>>> def f2(x, y): return np.array([[0, 0], [0, 0]])
>>> f = Function(f0, f1, f2, d=2)
>>> f.is_linear
False

To call the function, call it like you would call the function f0:

>>> f(1, 1)
2
>>> f.g(1, 1)
array([2, 1])

You can mix different kinds of input signatures:

>>> def f0(x): return x[0]**2 + x[1]
>>> def f1(x, y): return np.array([2*x, 1])
>>> def f2(x, y): return np.array([[0, 0], [0, 0]])
>>> f = Function(f0, f1, f2, d=2)

The point is that you always call the resulting Function object according to your definition. Now your f0 expects an iterable, therefore you can call it like

>>> f([1, 1])
2

but the gradient function expects the same values as two scalars, so you call it like this

>>> f.g(1, 1)
array([2, 1])

Explicity defining the variables for a symbolic function is important if not all variables appear in the string expression you feed the object with:

>>> g = Function('3*x + 4*y - 2', variables=['x', 'y', 'z'])
>>> g.is_linear
True

If you do not specify ‘z’ as a variable here, the resulting object expects two values

>>> h = Function('3*x + 4*y - 2')
>>> h([1, 1])
5

The variables can be SymPy variables as well:

>>> m = Function('3*x + 4*y - 2', variables=sy.symbols('x y z'))
>>> m.is_linear
True
>>> m([1, 2, -30])
9
coefficients(normalize: bool = False) dict | None[source]#

Returns the coefficients if the function is symbolic.

Parameters:

normalize (bool, Optional) – If True, the coefficients are normalized. Default is False.

Examples

>>> from sigmaepsilon.math.function import Function
>>> from sigmaepsilon.math.approx.lagrange import gen_Lagrange_1d
>>> f = gen_Lagrange_1d(N=2)
>>> f1 = Function(f[1][0], f[1][1], f[1][2])
>>> coefficients = f1.coefficients()
property is_linear: bool#

Returns True if the function is at most linear in all of its variables.

property is_symbolic: bool#

Returns True if the function is a fit subject of symbolic manipulation. This is probably only true if the object was created from a string or SymPy expression.

property linear: bool#

Returns True if the function is at most linear in all of its variables.

linear_coefficients(normalize: bool = False) dict | None[source]#

Returns the linear coeffiecients, if the function is symbolic and linear.

Parameters:

normalize (bool, Optional) – If True, the coefficients are normalized. Default is False.

Examples

>>> from sigmaepsilon.math.function import Function
>>> from sigmaepsilon.math.approx.lagrange import gen_Lagrange_1d
>>> f = gen_Lagrange_1d(N=2)
>>> f1 = Function(f[1][0], f[1][1], f[1][2])
>>> linear_coefficients = f1.linear_coefficients()
simplify() None[source]#

Simplifies the symbolic expression of the instance.

subs(values: Iterable, variables: Iterable | None = None, inplace: bool = False) Function[source]#

Substitites values for variables. Only for symbolic functions.

Examples

>>> from sigmaepsilon.math.function import Function
>>> g = Function("3*x + 4*y - 2", variables=["x", "y", "z"])
>>> g = g.subs([0, 0, 0], ["x", "y", "z"], inplace=True)
property symbolic: bool#

Returns True if the function is a fit subject of symbolic manipulation. This is probably only true if the object was created from a string or sympy expression.

to_latex() str[source]#

Returns the LaTeX code of the symbolic expression of the instance. Only for symbolic functions.

Examples

>>> from sigmaepsilon.math.function import Function
>>> from sigmaepsilon.math.approx.lagrange import gen_Lagrange_1d
>>> f = gen_Lagrange_1d(N=2)
>>> f1 = Function(f[1][0], f[1][1], f[1][2])
>>> latex_string = f1.to_latex()

Relations#

class sigmaepsilon.math.function.Relation(*args, op_str: str | None = None, **kwargs)[source]#

Class to express relations. You can use this class to express equalities and inequalities. The class is a subclass of Function and can be instantiated similatly, with an additional parameter op to specify the operator.

Parameters:
  • operator (op or) – The operator to be used in the relation. If a string is provided, it should be one of =, >, >=, <, <=. If a callable is provided, it should implement a binary operator.

  • op_str ({'=', '>', '>=', '<', '<='}, Optional) – If the operator is defined with a callable, you can define the symbol for the operator as a string. This is optional and only used in some cases, for instance when generating the LaTeX representation of the relation. Also, providing this parameter will help the constructor to tetermine the class of the instance when calling the __new__ method.

property operator: Callable#

Returns the associated operator.

relate(*args, **kwargs)[source]#

Relates an input and returns True if it is feasible.

to_latex() str[source]#

Returns the LaTeX code of the symbolic expression of the instance. Only for symbolic relations.

class sigmaepsilon.math.function.Equality(*args, op_str: str | None = None, **kwargs)[source]#

Class for equalities, mostly used for expressing constraints in optimization problems.

Examples

>>> from sigmaepsilon.math.function import Equality
>>> import sympy as sy
>>> variables = ['x1', 'x2', 'x3', 'x4']
>>> x1, x2, x3, x4 = syms = sy.symbols(variables, positive=True)
>>> eq1 = Equality(x1 + 2*x3 + x4 - 4, variables=syms)
>>> eq2 = Equality(x2 + x3 - x4 - 2, variables=syms)
class sigmaepsilon.math.function.InEquality(*args, op_str: str | None = None, **kwargs)[source]#

Class for inequalities, mostly used for expressing constraints in optimization problems.

Examples

>>> from sigmaepsilon.math.function import InEquality
>>> gt = InEquality('x + y', op='>')
>>> ge = InEquality('x + y', op='>=')
>>> le = InEquality('x + y', op=lambda x, y: x <= y)
>>> lt = InEquality('x + y', op=lambda x, y: x < y)

Test Functions for Optimization#

sigmaepsilon.math.function.functions.Beale() TestMinFunction2D[source]#

Creates the Beale function object.

\begin{equation} f(x, y) = (1.5 - x + x y)^2 + (2.25 - x + x y^2)^2 + (2.625 - x + x y^3)^2 \end{equation}

One global minimum : f(3,0.5) = 0.

sigmaepsilon.math.function.functions.GoldsteinPrice() TestMinFunction2D[source]#

Creates the Goldstein-Price function object.

\begin{equation} f(x, y) = (1 + (x + y + 1)^2 (19-14x + 3x^2 - 14y + 6xy + 3y^2)) (30 + (2x - 3y)^2 (18 - 32x + 12x^2 + 48y - 36xy + 27y^2)) \end{equation}

One global minimum : f(0,-1) = 3.

sigmaepsilon.math.function.functions.Himmelblau() TestMinFunction2D[source]#

Creates the Himmelblau’s function object.

\(f(x,y) = (x^2 + y - 11)^2 + (x + y^2 - 7)^2\)

Four identical local minima with values 0.0 at (3.0,2.0), (-2.805,3.131), (-3.779,-3.283), (3.584,-1.848).

sigmaepsilon.math.function.functions.Matyas() TestMinFunction2D[source]#

Creates the Matyas function object.

\(f(x, y) = 0.26 (x^2 + y^2) - 0.48 x y\)

One global minimum : f(0., 0.) = 0.

sigmaepsilon.math.function.functions.Rosenbrock(a: float = 1, b: float = 100) TestMinFunction2D[source]#

Implements the Rosenbrock function, aka. Banana function.

\(f(x, y) = (a - x)^2 + b (y - x^2)^2\)

a,b are constants, tipically a is set to 1 and b is set to 100.

One global minimum : f(1, 1) = 0.