Skip to content

FAQ: casadi.DM is to store numerical values. Why is this type needed and what is it good for?

András Retzler edited this page Oct 30, 2022 · 8 revisions

When you convert a matrix to casadi.DM, from then on it will be stored in CasADi's memory space, in a structure that is suitable for CasADi to do calculations with, quickly and efficiently. (This concept is similar to numpy.array or torch.tensor: to work with these libraries for fast computations, we need to move the numerical values from Python to NumPy's or PyTorch's memory space.)

DM is mainly used for storing matrices in CasADi and as inputs and outputs of functions.

E.g. you construct a casadi.Function that calculates the jacobian of your symbolic expression. This calculation will be done very fast inside CasADi, because of the AD techniques implemented. To do that, CasADi stores and handles your numbers internally. You should convert the numbers to MATLAB/Python/NumPy once the calculations are done.

from casadi import *
x = MX.sym('x',2)
y = MX.sym('y')
f = Function('f',[x,y], [x,sin(y)*x]) #This is an example function. CasADi is particularly suitable if it involves calculating the derivatives. Here we just calculate some very simple expression.
r0, q0 = f(1.1,3.3) #at this point 1.1 and 3.3 are automatically converted to DM. This would also work:
r0, q0 = f(DM(1.1),DM(3.3))
print(type(r0), r0)  #you get: <class 'casadi.casadi.DM'> [1.1, 1.1]
print(type(q0), q0)  #you get: <class 'casadi.casadi.DM'> [-0.17352, -0.17352]
print(type(q0.full()), q0.full()) #you get: <class 'numpy.ndarray'> [[-0.17352026]\n[-0.17352026]] #now we have just converted our DM to numpy so that we can continue working with this matrix

How do you know that you are dealing with a DM or a Python/MATLAB number? You can check the type() (Python) or the class() (MATLAB):

>>> A=[[1,2],[3,4]]
>>> A_DM = casadi.DM(A)
>>> type(A)
<class 'list'>
>>> type(A_DM)
<class 'casadi.casadi.DM'>

While your numbers are stored in a DM, it's not Python/MATLAB, but CasADi who will take care of all the operations on them:

>>> A_DM*2 #CasADi does this internally
DM(
[[2, 4], 
 [6, 8]])

... including printing them:

>>> A=[[1,2],[3,4]]
>>> A #Python prints the content of the List below:
[[1, 2], [3, 4]]
>>> A_DM = casadi.DM(A)
>>> A_DM #CasADi (called by Python) prints the contents of the DM below:
DM(
[[1, 2], 
 [3, 4]])

Note that here I just typed the name of the variable in the terminal, and I got a more detailed output about what they are. If you just use the built-in print() or str() of Python, you cannot easily differentiate between a DM or a Python list:

>>> print(r0) #this is a DM
[1.1, 1.1]
>>> print([1.1, 1.1]) #this is a Python list
[1.1, 1.1]

As the documentation says, if you want to continue working with the numbers and do other computationally heavy things, you should just convert them to MATLAB matrices or move them to Python libraries that are better at this, because the main purpose of DM is to let CasADi do the optimization and AD related operations fast on them:

It is not intended to be used for computationally intensive calculations. For this purpose, use the builtin dense or sparse data types in MATLAB, NumPy or SciPy matrices in Python or an expression template based library such as eigen, ublas or MTL in C++.

From the docs, this is the example code to do the conversion to NumPy/MATLAB using full() or sparse():

image

Clone this wiki locally