Backend Modules

Backend Shim

Shim module for non-operators. This is moer utility-like functionality, outside the scope of the array API standard.

condor.backend.symbol_class

class for expressions

Operators Shim

Shim module for operators, extending the array API standard with several calculus operators

condor.backend.operators.pi = 3.141592653589793

constant pi

condor.backend.operators.inf = inf

constant inf

condor.backend.operators.nan = nan

constant nan

condor.backend.operators.jacobian(of, wrt)

create dense jacobian expression

condor.backend.operators.if_else(*conditions_actions)

function for creating

condor.backend.operators.wrap(f)

wrap function f to allow elements, symbolic, and numeric values to be usable

condor.backend.operators.min(*args, **kwargs)

array API standard for min

condor.backend.operators.max(*args, **kwargs)
condor.backend.operators.mod(*args, **kwargs)
condor.backend.operators.tan(*args, **kwargs)
condor.backend.operators.atan(*args, **kwargs)
condor.backend.operators.atan2(*args, **kwargs)
condor.backend.operators.sin(*args, **kwargs)
condor.backend.operators.cos(*args, **kwargs)
condor.backend.operators.asin(*args, **kwargs)
condor.backend.operators.acos(*args, **kwargs)
condor.backend.operators.exp(*args, **kwargs)
condor.backend.operators.log(*args, **kwargs)
condor.backend.operators.log10(*args, **kwargs)
condor.backend.operators.sqrt(*args, **kwargs)
condor.backend.operators.vector_norm(*args, **kwargs)
condor.backend.operators.solve(*args, **kwargs)

CasADi Realization

Backend Module

condor.backends.casadi.symbols_in(expression)

return the leaf symbols in the expression

condor.backends.casadi.is_constant(symbol)

evaluate whether the symbol is a constant (e.g., numeric)

condor.backends.casadi.process_relational_element(elem)

modify an element if the backend_repr is relational

if backend_repr is lhs == rhs,

replace with lhs - rhs set upper_bound = lower_bound = 0 (if element has bounds)

if backend_repr is inequality, e.g., lhs < mhs < rhs

attach lhs to lower bound, mhs to backend_repr, and rhs to upper_bound

class condor.backends.casadi.BackendSymbolData(shape: tuple, symmetric: bool, diagonal: bool)

Dataclass for handling backend expressions

flatten_value(value)

flatten a value to the appropriate representation for the backend

wrap_value(value)

wrap a flattened value to the appropriate shape

condor.backends.casadi.symmetric_to_unique(value, symbolic=True)

helper function for flattening a symmetric symbol

condor.backends.casadi.unique_to_symmetric(unique, symbolic=True)

helper function for wrapping a symmetric symbol

condor.backends.casadi.symbol_generator(name, shape=(1, 1), symmetric=False, diagonal=False)

create a symbol

Parameters:
  • name (str)

  • shape (tuple of ints)

  • symmetric (bool) – flag to indicate this should be a symmetric (2-D) matrix; only store the unique elements

  • diagonal (bool) – flag to indicate this should be a (2-D) matrix with only elements on the diagonal

condor.backends.casadi.get_symbol_data(symbol, symmetric=None)

extract shape metadata from an expression

condor.backends.casadi.symbol_is(a, b)

evaluate whether two symbols are the same with idiosyncrasies for symbol class

class condor.backends.casadi.SymbolCompatibleDict(*args, **kwargs)

A dict subclass that works with the backend symbol class

keys() a set-like object providing a view on D's keys
items() a set-like object providing a view on D's items
condor.backends.casadi.evalf(expr, backend_repr2value)

evaluate expr with dictionary of {symbol: value}

class condor.backends.casadi.CasadiFunctionCallback(wrapper_funcs, implementation=None, model_name='', jacobian_of=None, input_symbol=None, output_symbol=None, opts=None)

Base class for wrapping a Function with a Callback

construct()

[INTERNAL]

construct(self, str name, dict opts)

Construct internal object.

This is the step that actually construct the internal object, as the class constructor only creates a null pointer. It should be called from the user constructor.

Extra doc: https://github.com/casadi/casadi/wiki/L_o5

Doc source: https://github.com/casadi/casadi/blob/main/casadi/core/callback.hpp#L78

Implementation: https://github.com/casadi/casadi/blob/main/casadi/core/callback.cpp#L36-L42

init()

[INTERNAL]

init(self)

Initialize the object.

This function is called after the object construction (for the whole class hierarchy) is complete, but before the finalization step. It is called recursively for the whole class hierarchy, starting with the lowest level.

Extra doc: https://github.com/casadi/casadi/wiki/L_o6

Doc source: https://github.com/casadi/casadi/blob/main/casadi/core/callback.hpp#L88

Implementation: https://github.com/casadi/casadi/blob/main/casadi/core/callback.hpp#L88-L88

finalize()

[INTERNAL]

finalize(self)

Finalize the object.

This function is called after the construction and init steps are

completed, but before user functions are called. It is called recursively for the whole class hierarchy, starting with the highest level.

Extra doc: https://github.com/casadi/casadi/wiki/L_o7

Doc source: https://github.com/casadi/casadi/blob/main/casadi/core/callback.hpp#L98

Implementation: https://github.com/casadi/casadi/blob/main/casadi/core/callback.hpp#L98-L98

get_n_in()

[INTERNAL]

get_n_in(self) -> int

Get the number of inputs.

This function is called during construction.

Extra doc: https://github.com/casadi/casadi/wiki/L_oa

Doc source: https://github.com/casadi/casadi/blob/main/casadi/core/callback.hpp#L129

Implementation: https://github.com/casadi/casadi/blob/main/casadi/core/callback.cpp#L64-L66

get_n_out()

[INTERNAL]

get_n_out(self) -> int

Get the number of outputs.

This function is called during construction.

Extra doc: https://github.com/casadi/casadi/wiki/L_ob

Doc source: https://github.com/casadi/casadi/blob/main/casadi/core/callback.hpp#L136

Implementation: https://github.com/casadi/casadi/blob/main/casadi/core/callback.cpp#L68-L70

eval(args)

[INTERNAL]

eval(self, [DM] arg) -> [DM]

Evaluate numerically, using temporary matrices and work vectors.

This signature is not thread-safe. For guaranteed thread-safety, use eval_buffer

Extra doc: https://github.com/casadi/casadi/wiki/L_o8

Doc source: https://github.com/casadi/casadi/blob/main/casadi/core/callback.hpp#L106

Implementation: https://github.com/casadi/casadi/blob/main/casadi/core/callback.cpp#L60-L62

get_sparsity_in(i)

[INTERNAL]

get_sparsity_in(self, int i) -> Sparsity

Get the sparsity of an input.

This function is called during construction.

Extra doc: https://github.com/casadi/casadi/wiki/L_oc

Doc source: https://github.com/casadi/casadi/blob/main/casadi/core/callback.hpp#L143

Implementation: https://github.com/casadi/casadi/blob/main/casadi/core/callback.cpp#L72-L74

get_sparsity_out(i)

[INTERNAL]

get_sparsity_out(self, int i) -> Sparsity

Get the sparsity of an output.

This function is called during construction.

Extra doc: https://github.com/casadi/casadi/wiki/L_od

Doc source: https://github.com/casadi/casadi/blob/main/casadi/core/callback.hpp#L150

Implementation: https://github.com/casadi/casadi/blob/main/casadi/core/callback.cpp#L76-L78

has_forward(nfwd)

[INTERNAL]

has_forward(self, int nfwd) -> bool

Return function that calculates forward derivatives.

forward(nfwd) returns a cached instance if available, and calls Function get_forward(casadi_int nfwd) if no cached version is available.

Extra doc: https://github.com/casadi/casadi/wiki/L_oi

Doc source: https://github.com/casadi/casadi/blob/main/casadi/core/callback.hpp#L190

Implementation: https://github.com/casadi/casadi/blob/main/casadi/core/callback.cpp#L112-L114

has_reverse(nrev)

[INTERNAL]

has_reverse(self, int nadj) -> bool

Return function that calculates adjoint derivatives.

reverse(nadj) returns a cached instance if available, and calls Function get_reverse(casadi_int nadj) if no cached version is available.

Extra doc: https://github.com/casadi/casadi/wiki/L_oj

Doc source: https://github.com/casadi/casadi/blob/main/casadi/core/callback.hpp#L205

Implementation: https://github.com/casadi/casadi/blob/main/casadi/core/callback.cpp#L124-L126

get_forward(nin, name, inames, onames, opts)

[INTERNAL]

get_forward(self, int nfwd, str name, [str] inames, [str] onames, dict opts) -> Function

Return function that calculates forward derivatives.

forward(nfwd) returns a cached instance if available, and calls Function get_forward(casadi_int nfwd) if no cached version is available.

Extra doc: https://github.com/casadi/casadi/wiki/L_oi

Doc source: https://github.com/casadi/casadi/blob/main/casadi/core/callback.hpp#L191

Implementation: https://github.com/casadi/casadi/blob/main/casadi/core/callback.cpp#L105-L110

get_reverse(nout, name, inames, onames, opts)

[INTERNAL]

get_reverse(self, int nadj, str name, [str] inames, [str] onames, dict opts) -> Function

Return function that calculates adjoint derivatives.

reverse(nadj) returns a cached instance if available, and calls Function get_reverse(casadi_int nadj) if no cached version is available.

Extra doc: https://github.com/casadi/casadi/wiki/L_oj

Doc source: https://github.com/casadi/casadi/blob/main/casadi/core/callback.hpp#L206

Implementation: https://github.com/casadi/casadi/blob/main/casadi/core/callback.cpp#L117-L122

has_jacobian()

[INTERNAL]

has_jacobian(self) -> bool

Return Jacobian of all input elements with respect to all output

elements.

Extra doc: https://github.com/casadi/casadi/wiki/L_oh

Doc source: https://github.com/casadi/casadi/blob/main/casadi/core/callback.hpp#L175

Implementation: https://github.com/casadi/casadi/blob/main/casadi/core/callback.cpp#L92-L94

get_jacobian(name, inames, onames, opts)

[INTERNAL]

get_jacobian(self, str name, [str] inames, [str] onames, dict opts) -> Function

Return Jacobian of all input elements with respect to all output

elements.

Extra doc: https://github.com/casadi/casadi/wiki/L_oh

Doc source: https://github.com/casadi/casadi/blob/main/casadi/core/callback.hpp#L176

Implementation: https://github.com/casadi/casadi/blob/main/casadi/core/callback.cpp#L97-L102

condor.backends.casadi.callables_to_operator(wrapper_funcs, *args, **kwargs)

check if this is actually something that needs to get wrapped or if it’s a native op… if latter, return directly; if former, create callback.

this function ultimately contains the generic API, CasadiFunctionCallback can be casadi specific interface

to think about: default casadi jacobian operator introduces additional inputs (and therefore, after second derivative also introduces additional output) for anti-derivative output. This is required for most “solver” type outputs. However, probably don’t want to use casadi machinery for retaining that solver – would be done externally. Is there ever a time we would want to use casadi machinery for passing in previous solution? if so, what would the API be for specifying?

y = fun(x) jac = jac_fun(x,y) d_jac_x, d_jac_y = hess_fun(x, y, jac)

if we don’t use casadi’s mechanisms, we are technically not functional but maybe when it gets wrapped by the callbacks, it effectively becomes functional because new instances are always created when needed to prevent race conditions, etc?

similarly, how to specify alternate types/details of derivative, like forward/reverse mode, matrix-vector product form, etc.

by definition, since we are consuming functions and cannot arbitrarily take derivatives (could look at how casadi does trajectory but even if useful for our trajectory, may not generalize to other external solvers) so need to implement and declare manually. Assuming this take is right, seems somewhat reasonable to assume we get functions, list of callables (at least 1) that evaluates 0th+ functions (dense jacobians, hessians, etc). Then a totally different spec track for jacobian-vector or vector-jacobian products. Could cap out at 2nd derivative, not sure what the semantics for hessian-vector vs vector-hessian products, tensor etc.

condor.backends.casadi.expression_to_operator(input_symbols, output_expressions, name='', **kwargs)

take a symbolic expression and create an operator – callable that can be used with jacobian, etc. operators

assume “MISO” – but slightly misleading since output can be arbitrary size

Operators Module

condor.backends.casadi.operators.concat(arrs, axis=0)

implement concat from array API for casadi

condor.backends.casadi.operators.jacobian(of, wrt)

jacobian of expression of with respect to symbols wrt

condor.backends.casadi.operators.jac_prod(of, wrt, rev=True)

create directional derivative

condor.backends.casadi.operators.if_else(*conditions_actions)

symbolic representation of a if/else control flow

Parameters:

*conditions_actions (list of (condition, value) pairs, ending with else_value)

Example

The expression:

value = if_else(
    (condition0, value0),
    (codnition1, value1),
    ...
    else_value
)

is equivalent to the numerical code:

if condition0:
    value = value0
elif condition1:
    value = value1
...
else:
    value = else_value