Symbolic operators#

CVXlab supports a variety of built-in mathematical operators that can be used within symbolic expressions. These operators include standard arithmetic operations, matrix operations, and various mathematical functions, allowing users to construct complex expressions for optimization problems.

Symbolic operators defined as mathematical signs include:

  • == : Equality

  • >= : Greater than or equal comparison

  • <= : Less than or equal comparison

  • + : Addition (works for both scalars and matrices)

  • - : Subtraction (works for both scalars and matrices)

  • * : Multiplication (element-wise for matrices)

  • / : Division (element-wise for matrices)

  • @ : Matrix multiplication (for matrices)

Other regular symbolic operators works like functions, taking variables as inputs arguments and returning a cvxpy expression when symbolic expression is processed. These operators are defined as functions in module cvxlab.support.util_operators, and are listed below:

  • Minimize() : Create a maximization objective (minimize())

  • Maximize() : Create a maximization objective (maximize())

  • tran() : Transposition of matrix or vector (transposition())

  • diag() : Extract the diagonal of a matrix or create a diagonal matrix from a vector (diagonal())

  • sum() : Sum elements of a matrix or vector along a specified axis (sum())

  • mult() : Element-wise multiplication of two matrices or vectors (mult())

  • pow() : Element-wise power of matrix or scalar base by an exponent (power())

  • minv() : Calculate the inverse of matrix (matrix_inverse())

  • shift() : Shift values of the diagonal of an identity matrix of upwards/downwards (shift())

  • annuity() : Calculate the annuity factor based on a set of parameters (annuity())

  • weib() : Generate a Weibull probability density function based on a set of parameters (weibull_distribution())

Adding symbolic operators#

CVXlab allows new symbolic operators to be defined and used in model expressions. This is particularly useful when the model requires specific mathematical functions not available in CVXPY or when existing functions need to be adapted to the model’s specific needs. As example, it may be complex to define probability density functions of exogenous variables, or to implement piece-wise linear functions with specific breakpoints, based on simple mathematical expressions.

In such cases, a symbolic operator can be defined and then used in problem expressions as any other operator listed above. Definition of new operators should be performed in two ways:

  1. Adding a new built-in symbolic operator to the CVXPY library. To do so, it is sufficient to add a new function the module cvxlab.support. util_operators.py, following instructions provided in the module. This way, the new operator will be available to all users of the package. This approach is recommended when the operator is generally useful and can be reused in multiple models. It is recommended to properly document and test the new operator before committing it to the main package (see Contributing).

  2. Defining a new custom symbolic operator in the model directory. To accomplish this, users can define new operator/s as regular functions in the user_defined_operators.py file (template can be found in cvxlab/templates/user_defined_operators.py). New operators are loaded once Model instance is generated. This way, users can use their own custom symbolic operators in defining problems without modifying the package code (ideal for model users).

Built-in operators reference#

Module with allowed functions to be used as symbolic operators.

This module provides various built-in utility functions that are defined to support calculations in symbolic problems, ranging from simple operations like transposition and diagonal extraction to more complex operations such as generating special matrices, reshaping arrays, or any special numerical manipulation that can be hardly defined based on symbolic expressions.

Functions are registered as operators in Constants class, and can be directly used in defining symbolic problem expressions simply by writing its name followed by parentheses containing the required arguments (defined as problems variables).

cvxlab.support.util_operators.annuity(period_length, tech_lifetime, interest_rate=None)[source]#

Calculate the annuity factor.

This function calculate the annuity factor, used to calculate the present value of an annuity for a given period length, lifetime, and interest rate, which is a series of equal payments made at regular intervals.

Parameters:
  • period_length (cp.Parameter) – The length of the period for which the annuity factor is calculated.

  • lifetime (cp.Parameter) – The total number of periods over which the annuity is paid.

  • interest_rate (cp.Parameter) – The interest rate used to discount the annuity payments.

  • tech_lifetime (Parameter)

Returns:

The annuity factor calculated based on the input parameters.

Return type:

cp.Parameter

Raises:
  • TypeError – If period_length or lifetime are not cvxpy Parameters, or if interest_rate is provided and is not a cvxpy Parameter.

  • ValueError – If the values assigned to period_length, lifetime, or interest_rate are None, or if period_length or lifetime are not scalars, or if interest_rate is not a vector of size equal to period_length.

cvxlab.support.util_operators.diagonal(x)[source]#

Extract the diagonal of a matrix or create a diagonal matrix from a vector.

If x is a matrix, extracts its diagonal as a vector. If x is a vector, creates a diagonal matrix with x on the diagonal.

Parameters:

x (cp.Parameter | cp.Expression) – A matrix (to extract diagonal) or vector (to create diagonal matrix).

Returns:

A vector containing the diagonal elements

(if x is a matrix) or a diagonal matrix (if x is a vector).

Return type:

cp.Parameter | cp.Expression

cvxlab.support.util_operators.matrix_inverse(matrix)[source]#

Calculate the inverse of a matrix.

Parameters:

matrix (cp.Parameter | cp.Expression) – The matrix to calculate the inverse of.

Returns:

The inverse of the input matrix.

Return type:

cp.Parameter

Raises:
  • TypeError – If the passed item is not a cvxpy Parameter or Expression.

  • ValueError – If the passed matrix values are None, or if the passed item is not a matrix, or if the passed item is not a square matrix, or if the passed matrix is singular and cannot be inverted.

cvxlab.support.util_operators.maximize(x)[source]#

Create a maximization objective.

Parameters:

x (cp.Expression) – The scalar expression to maximize.

Returns:

A cvxpy Maximize objective function.

Return type:

cp.Maximize

cvxlab.support.util_operators.minimize(x)[source]#

Create a minimization objective.

Parameters:

x (cp.Expression) – The scalar expression to minimize.

Returns:

A cvxpy Minimize objective function.

Return type:

cp.Minimize

cvxlab.support.util_operators.multiplication(x, y)[source]#

Element-wise multiplication of two matrices or vectors.

Performs element-wise (Hadamard) multiplication between x and y.

Parameters:
  • x (cp.Parameter | cp.Expression) – The first matrix or vector.

  • y (cp.Parameter | cp.Expression) – The second matrix or vector. Must have the same shape as x.

Returns:

A matrix or vector containing the

element-wise product of x and y.

Return type:

cp.Parameter | cp.Expression

cvxlab.support.util_operators.power(base, exponent)[source]#

Calculate the element-wise power of a matrix or scalar.

This funciton calculates the element-wise power of the base, provided an exponent. Either base or exponent can be a scalar.

Parameters:
  • base (cp.Parameter | cp.Expression) – The base for the power operation. The corresponding value can be a scalar or a 1-D numpy array.

  • exponent (cp.Parameter | cp.Expression) – The exponent for the power operation. The corresponding value can be a scalar or a 1-D numpy array.

Returns:

A new parameter with the same shape as the input parameters,

containing the result of the power operation.

Return type:

cp.Parameter

Raises:
  • TypeError – If the base and exponent are not both instances of cvxpy Parameter or Expression.

  • ValueError – If the base and exponent do not have the same shape and neither is a scalar. If the base and exponent are not numpy arrays. If the base and exponent include non-numeric values.

cvxlab.support.util_operators.shift(set_length, shift_values)[source]#

Shift values of an identity matrix diagonal upwards/downwards.

This function generates a square matrix of specified dimension, with all zeros except a diagonal of ones that is shifted with respect to the main diagonal by a specified shift_value. A positive shift_value results in a downward shift, while a negative shift_value results in an upward shift. If shift_value is 0, identity matrix is returned.

Parameters:
  • set_length (cp.Constant) – The dimension of the matrix row/col.

  • shift_values (cp.Parameter) – (scalar) the number of positions to shift the diagonal.

Returns:

A square matrix with a diagonal of ones downward shifted by

the specified shift_value.

Return type:

cp.Parameter

Raises:
  • ValueError – If passed dimension is not greater than zero.

  • TypeError – If passed dimension is not an iterable containing integers.

cvxlab.support.util_operators.summation(x, axis=None, keepdims=True)[source]#

Sum elements of a matrix or vector along a specified axis.

Parameters:
  • x (cp.Parameter | cp.Expression) – The matrix or vector to sum.

  • axis (Optional[int]) – The axis along which to sum. If None, sums all elements. If 0, sums along columns. If 1, sums along rows.

  • keepdims (bool) – Whether to keep the reduced dimensions in the result. default is True.

Returns:

The sum of elements along the specified

axis, or a scalar if axis is None.

Return type:

cp.Parameter | cp.Expression

cvxlab.support.util_operators.transposition(x)[source]#

Transpose a matrix or vector.

Parameters:

x (cp.Parameter | cp.Expression) – The matrix or vector to transpose.

Returns:

The transposed matrix or vector.

Return type:

cp.Parameter | cp.Expression

cvxlab.support.util_operators.weibull_distribution(
scale_factor,
shape_factor,
range_vector,
dimensions,
rounding=2,
)[source]#

Generate a Weibull probability density function.

This function can be produced either as a one-dimensional vector or a two-dimensional matrix, based on specified dimensions. This function primarily uses parameters from ‘cvxpy’ to enable integration with optimization tasks and ‘numpy’ for handling numerical operations.

Parameters:
  • scale_factor (cp.Parameter) – A cvxpy Parameter object containing a scalar value representing the scale parameter (λ) of the Weibull distribution. This value must be positive.

  • shape_factor (cp.Parameter) – A cvxpy Parameter object containing a scalar value representing the shape parameter (k) of the Weibull distribution. Typically, this value must be positive to define the distribution correctly.

  • range_vector (cp.Constant) – A cvxpy Constant object that includes an array of values over which the Weibull PDF is computed. The range should be a one-dimensional array of non-negative values.

  • dimensions (int) – Determines the output dimension of the Weibull PDF: 1 for a vector output, 2 for a matrix output where each subsequent column is a downward rolled version of the Weibull PDF vector.

  • rounding (int, optional) – Number of decimal places to which the computed Weibull PDF values are rounded. Defaults to 2.

Returns:

A cvxpy Parameter object that contains the Weibull PDF in

the specified dimension (vector or matrix). This can be directly used in further cvxpy optimizations.

Return type:

cp.Parameter

Raises:

ValueError – If any of the input parameters (scale_factor, shape_factor, or range_vector) is None, or if their contained values do not meet the expected requirements (e.g., non-scalar for scale or shape factors, or if dimensions is not 1 or 2).