Source code for csnlp.nlps.variables
from math import prod
from typing import Literal, TypeVar
import casadi as cs
import numpy as np
from numpy.typing import NDArray
from .parameters import HasParameters
SymType = TypeVar("SymType", cs.SX, cs.MX)
[docs]
class HasVariables(HasParameters[SymType]):
"""Class for the creation and storage of symbolic variables in an NLP problem. It
builds on top of :class:`HasParameters`, which handles parameters.
Parameters
----------
sym_type : {"SX", "MX"}, optional
The CasADi symbolic variable type to use in the NLP, by default ``"SX"``.
"""
def __init__(self, sym_type: Literal["SX", "MX"] = "SX") -> None:
super().__init__(sym_type)
self._vars: dict[str, SymType] = {}
self._x = self._sym_type()
self._discrete = np.empty(0, dtype=bool)
@property
def x(self) -> SymType:
"""Gets the primary variables of the NLP scheme in vector form."""
return self._x
@property
def nx(self) -> int:
"""Number of variables in the NLP scheme."""
return self._x.shape[0]
@property
def variables(self) -> dict[str, SymType]:
"""Gets the primal variables of the NLP scheme."""
return self._vars
@property
def discrete(self) -> NDArray[np.bool_]:
"""Gets the boolean array indicating which variables are discrete."""
return self._discrete
[docs]
def variable(
self,
name: str,
shape: tuple[int, int] = (1, 1),
discrete: bool = False,
) -> SymType:
"""Adds a variable to the NLP problem.
Parameters
----------
name : str
Name of the new variable. Must not be already in use.
shape : tuple[int, int], optional
Shape of the new parameter. By default a scalar, i.e., ``(1, 1)``.
discrete : bool, optional
Flag indicating if the variable is discrete. Defaults to ``False``.
Returns
-------
var : casadi.SX
The symbol of the new variable.
Raises
------
ValueError
Raises if there is already another variable with the same name ``name``.
"""
if name in self._vars:
raise ValueError(f"Variable name '{name}' already exists.")
var = self._sym_type.sym(name, *shape)
self._vars[name] = var
self._x = cs.veccat(self._x, var)
self._discrete = np.concatenate(
(self._discrete, np.full(prod(shape), discrete, dtype=bool))
)
return var