/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
© Copyright 2024