Structural zero detection with MX expressions

67 views
Skip to first unread message

Jonathan Frey

unread,
Jul 9, 2018, 10:56:52 AM7/9/18
to CasADi
Hi all,

I want to process a CasADi expression to detect linear and nonlinear parts, using structural zero detection "is_zero".
For SX variables, this works fine. I do something like in the following short example:

import casadi.*

x1    
= SX.sym('x1');
x2    
= SX.sym('x2');

x
= vertcat(x1, x2);
x0
= rand(size(x));

f
= [x1 + x2; 0 ];

% generate and eval f
f_fun
= Function('f_fun', {x},{f});

f_new
= SX(f)
f_new
(1) = f_new(1) - 1 * x1
f_new
(1) = f_new(1) - x2

f1
= f_new(1);
f1
= f1.simplify()

f1
.is_zero()

This works fine and gives the final output "1"


Sadly for MX expressions this does not work.

import casadi.*

x1    
= MX.sym('x1');
x2    
= MX.sym('x2');

x
= vertcat(x1, x2);
x0
= rand(size(x));

f
= [x1 + x2; 0 ];

% generate and eval f
f_fun
= Function('f_fun', {x},{f});

f_new
= MX(f)
f_new
(1) = f_new(1) - 1 * x1
f_new
(1) = f_new(1) - x2

f1
= f_new(1);
f1
= f1.simplify()

f1
.is_zero()
here the last output is "0".

The expression I want to analyze however contains a Spline call, such that using SX variables is not possible - see https://groups.google.com/forum/#!topic/casadi-users/-b8BL6H-tqw

Am I missing something when using MX here?
If not, I am quite interested in using the splines/lookup tables within SX CasADi expressions, which I read that Joris Gillis is working on, https://groups.google.com/d/msg/casadi-users/-b8BL6H-tqw/XDJZshLEAgAJ
Please let me know if this is ready to be tested!

Best regards,
Jonathan


Joris Gillis

unread,
Jul 9, 2018, 11:14:43 AM7/9/18
to CasADi
Dear Jonathan,

Perhaps you are looking for 'which_depends'?
This function can classify expressions/variables..

Best,
  Joris

Jonathan Frey

unread,
Jul 9, 2018, 3:03:53 PM7/9/18
to CasADi
Dear Joris,

unfortunately this does not do the trick.
The plan is to successively remove the linear parts and just keep the nonlinear part. This does not work with MX:

import casadi.*

% set up functions and variables
x1    
= MX.sym('x1');

x2    
= MX.sym('x2');

x
= vertcat(x1, x2);


f
= [x1 + x2;
       
0];

% remove linear terms of f
f_new
= MX(f);
f_new
(1) = f_new(1) - x1;

f_new
(1) = f_new(1) - x2;

f1
= f_new(1)
f1
= f1.simplify()


f1
.is_zero() % should put out 1, but is 0

f1
.which_depends(x) % should put out 0 0, but is 0 1

So do you think the way is to go with your "experimental build"?

Best,
Jonathan
Reply all
Reply to author
Forward
0 new messages