CasADi tutorial 2

/home/travis/build/casadi/binaries/casadi/docs/tutorials/python/src/symbolics/temp.py
June 30, 2015
CasADi tutorial 2
0
1
2
3
4
5
6
[ SX(@1= sq ( x ), ( s i n (@1)+@1)) ] < t y p e
48
49
50
#
#
#
#
#
#
#
51
Introduction
53
54
55
from c a s a d i i m p o r t *
from numpy i m p o r t *
x = SX. sym (" x ")
y = x **2
z = s i n (y) + y
print z
The printout value of z may give you the false impression that the evaluation of z will involve two multiplications
of x. This is not the case. This is what’s going on under the hood:
The expression tree of z does not contain two subexpressions x*x, rather it contains two pointers to a signle
subexpression x*x. In fact, in the C++ implementation, an S object is really not more than a collection of pointers.
It are SXNode objects which really contain the data associated with subexpressions.
CasADi generates SXnodes at a very fine-grained level. Even ’sin(y)’ is an SXNode, even though we have not
ourselves declared a variable to point to it.
When evaluating z for a particular numerical value of x, the product is computed only once.
Functions
CasADi’s SXFunction has powerful input/output behaviour. The following input/output primitives are supported: A
function that uses one primitive as input/output is said to be ’single input’/’single output’.
In general, an SXfunction can map from-and-to list/tuples of these primitives.
Functions with scalar valued input
The following code creates and evaluates a single input (scalar valued), single output (scalar valued) function.
57
print
print
f([ y ])
print
f([2])
[ D M a t r i x (3.2432) ]
We can do symbolic derivatives: f’ = dz/dx .
61
print
f . g r a d ()
(( x + x )*(1+ c o s ( sq ( x ))))
The following code creates and evaluates a multi input (scalar valued), multi output (scalar valued) function.
64
65
66
67
68
69
x = SX. sym (" x ") # 1 by 1 matrix serves as scalar
y = SX. sym (" y ") # 1 by 1 matrix serves as scalar
f = S X F u n c t i o n ( ’ f ’, [ x , y ] , [ x * y , x + y ] )
p r i n t "%d −> %d " % ( f . n I n (), f . nOut ())
2 -> 2
67
68
69
70
71
f . i n i t ()
f . s e t I n p u t (2,0)
f . s e t I n p u t (3,1)
print
[ f.getOutput( i ) for
i
i n r a n g e (2) ]
[ D M a t r i x (0), D M a t r i x (0) ]
72
print
[ [ f .grad(i , j ) for
i
i n r a n g e (2) ]
[ [ SX( y ), SX( x ) ] , [ SX(1), SX(1) ] ]
f . i n p u t E x p r (), t y p e ( f . i n p u t E x p r ())
[ SX( x ) ] < t y p e
47
f . s e t I n p u t (3)
f . e v a l u a t e ()
p r i n t f . g e t O u t p u t ()
Since numbers get cast to SXConstant object, you can also write the following non-efficient code:
59
1 -> 1
print
t y p e ( f . g e t O u t p u t ())
[ SX(@1= sq ( sq ( x )), ( s i n (@1)+@1)) ]
f = S X F u n c t i o n ( ’ f ’, [ x ] , [ z ] ) # z = f(x)
p r i n t "%d −> %d " % ( f . n I n (), f . nOut ())
print
9.41212
We can evaluate symbolically, too:
@1= sq ( x ), ( s i n (@1)+@1)
46
f . s e t I n p u t (2)
f . e v a l u a t e ()
p r i n t f . g e t O u t p u t ()
< c l a s s ’ c a s a d i . c a s a d i . DMatrix ’>
Reevaluation does not require the init call.
Let’s start with creating a simple expression tree z.
45
46
47
’ l i s t ’>
3.2432
This tutorial file explains the use of CasADi’s SXFunction in a python context. We assume you have read trough
the SX tutorial.
17
18
19
20
21
22
1
Symbolic function manipulation
’ l i s t ’>
f . o u t p u t E x p r (), t y p e ( f . o u t p u t E x p r ())
76
x =SX. sym (" x ")
for
j
i n r a n g e (2) ]
/home/travis/build/casadi/binaries/casadi/docs/tutorials/python/src/symbolics/temp.py
77
78
79
80
81
a=SX. sym (" a ")
b=SX. sym (" b ")
f = S X F u n c t i o n ( ’ f ’, [ x , v e r t c a t (( a , b )) ] , [ a * x + b ] )
82
print
83
print
84
print
print
June 30, 2015
109
110
111
2
d f . s e t I n p u t ( [ 7,6 ] ,1)
d f . e v a l u a t e ()
p r i n t d f . g e t O u t p u t (1) # v
[ 33, 13 ]
f ( [ x , v e r t c a t ( [ a ,b ] ) ] )
[ SX((( a * x )+ b )) ]
Functions with matrix valued input
f ( [ SX(1.0), v e r t c a t (( a , b )) ] )
[ SX(( a + b )) ]
f ( [ x , v e r t c a t ((SX. sym (" c "),SX. sym (" d "))) ] )
115
116
117
x = SX. sym (" x ",2,2)
y = SX. sym (" y ",2,2)
p r i n t x * y # Not a dot product
[ SX((( c * x )+ d )) ]
f ( [ SX(), v e r t c a t ( [ SX. sym (" c "),SX. sym (" d ") ] ) ] )
[ [ ( x_0 * y_0 ), ( x_2 * y_2 ) ] ,
[ ( x_1 * y_1 ), ( x_3 * y_3 ) ] ]
[ SX( d ) ]
87
88
89
90
118
119
k = SX( a )
p r i n t f ( [ x , v e r t c a t (( k [ 0 ] , b )) ] )
2 -> 1
120
[ SX((( a * x )+ b )) ]
89
print
[ SX((( c * x )+ d )) ]
The following code creates and evaluates a single input (vector valued), single output (vector valued) function.
95
96
97
98
99
x = SX. sym (" x ")
y = SX. sym (" y ")
f = S X F u n c t i o n ( ’ f ’, [ v e r t c a t (( x , y )) ] , [ v e r t c a t (( x * y , x + y )) ] )
p r i n t "%d −> %d " % ( f . n I n (), f . nOut ())
print
f ( [ x ,y ] )
[ SX(
[ [ ( x_0 * y_0 ), ( x_2 * y_2 ) ] ,
[ ( x_1 * y_1 ), ( x_3 * y_3 ) ] ] ) ]
f ( [ x , v e r t c a t ((SX. sym (" c "),SX. sym (" d "))) ] )
Functions with vector valued input
f = S X F u n c t i o n ( ’ f ’, [ x , y ] , [ x * y ] )
p r i n t "%d −> %d " % ( f . n I n (), f . nOut ())
121
122
123
124
125
f . i n i t ()
f . s e t I n p u t ( D M a t r i x ( [ [ 1,2 ] , [ 3,4 ] ] ),0)
f . s e t I n p u t ( D M a t r i x ( [ [ 4,5 ] , [ 6,7 ] ] ),1)
f . e v a l u a t e ()
p r i n t f . g e t O u t p u t ()
[ [ 4, 10 ] ,
[ 18, 28 ] ]
126
print
f . j a c (0).T
1 -> 1
99
100
101
[ 6, 5 ]
102
103
[ [ y_0 , 00, 00, 00 ] ,
[ 00, y_1 , 00, 00 ] ,
[ 00, 00, y_2 , 00 ] ,
[ 00, 00, 00, y_3 ] ]
f . s e t I n p u t ( [ 2,3 ] )
f . e v a l u a t e ()
p r i n t f . g e t O u t p u t ()
127
G= f . j a c ().T
print G
106
107
108
f . i n i t ()
d f = f . d e r i v a t i v e (1,0)
d f . s e t I n p u t ( [ 2,3 ] ,0)
f . j a c (1).T
[ [ x_0 , 00, 00, 00 ] ,
[ 00, x_1 , 00, 00 ] ,
[ 00, 00, x_2 , 00 ] ,
[ 00, 00, 00, x_3 ] ]
@1= 1,
[ [ y , @1] ,
[ x , @1] ]
The evaluation of v can be efficiently achieved by automatic differentiation as follows:
print
129
130
p r i n t 12
12
/home/travis/build/casadi/binaries/casadi/docs/tutorials/python/src/symbolics/temp.py
131
132
133
June 30, 2015
f = S X F u n c t i o n ( ’ f ’, [ x , y ] , [ x * y , x + y ] )
p r i n t t y p e (x)
< c l a s s ’ c a s a d i . c a s a d i . SX ’>
133
print
f ( [ x ,y ] )
[ SX(
[ [ ( x_0 * y_0 ),
[ ( x_1 * y_1 ),
[ [ ( x_0 + y_0 ),
[ ( x_1 + y_1 ),
134
print
( x_2 * y_2 ) ] ,
( x_3 * y_3 ) ] ] ), SX(
( x_2 + y_2 ) ] ,
( x_3 + y_3 ) ] ] ) ]
t y p e ( f ( [ x , y ] ))
< t y p e ’ l i s t ’>
135
print
t y p e ( f ( [ x ,y ] ) [ 0 ] )
< c l a s s ’ c a s a d i . c a s a d i . SX ’>
136
print
t y p e ( f ( [ x , y ] ) [ 0 ] [ 0,0 ] )
< c l a s s ’ c a s a d i . c a s a d i . SX ’>
139
140
141
142
f = S X F u n c t i o n ( ’ f ’, [ x ] , [ x + y ] )
p r i n t t y p e (x)
141
print
< c l a s s ’ c a s a d i . c a s a d i . SX ’>
f([ x ])
[ SX(
[ [ ( x_0 + y_0 ), ( x_2 + y_2 ) ] ,
[ ( x_1 + y_1 ), ( x_3 + y_3 ) ] ] ) ]
142
print
143
print
144
print
t y p e ( f ( [ x ] ))
< t y p e ’ l i s t ’>
type(f([ x ])[0])
< c l a s s ’ c a s a d i . c a s a d i . SX ’>
t y p e ( f ( [ x ] ) [ 0 ] [ 0,0 ] )
< c l a s s ’ c a s a d i . c a s a d i . SX ’>
A current limitation is that matrix valued input/ouput is handled through flattened vectors Note the peculiar form
of the gradient.
Conclusion
This tutorial showed how SXFunction allows for symbolic or numeric evaluation and differentiation.
3