New syntax for calling functions in CasADi 3.0

113 views
Skip to first unread message

Joel Andersson

unread,
Mar 3, 2016, 10:59:13 AM3/3/16
to CasADi
Dear all,

During the recent course on optimal control that we organized in Freiburg, based on the feedback from users, we decided to do one more syntax change for the (upcoming) CasADi 3.0. This concerns how functions are being called. The new calling syntax was introduced in CasADi 3.0 RC3 and concerns both MATLAB and Python (but not C++).

Until now, the principle for calling a CasADi Function has been that the Python user passes ether a list or a dictionary in and gets the same type back. Or in MATLAB, the same but with cell arrays and structs:

# Old syntax, Python
[r] = F([a,b])
[s,t] = G([a,b,c])
q = G({'a':a, 'b':b, 'c':c})

% Old syntax, MATLAB
v
= F({a,b});
r = v{1};
v
= G({a,b,c});
s
= v{1};
t
= v{2};
q
= G(struct('a', a, 'b', b, 'c', c));


This syntax is has now been deprecated and replaced with a more natural calling syntax, using variable number of inputs and outputs:

# New syntax, Python
r = F(a,b)
s,t = G(a,b,c)
q = G(a=a, b=b, c=c)

% New syntax, MATLAB
r
= F(a,b);
[s,t] = G(a,b,c);
q
= G('a', a, 'b', b, 'c', c);


Since it's not always practical to work with variable number of inputs/outputs, the old calling syntax is still available, but has been renamed "call":
# New alternative syntax, Python
[r] = F.call([a,b])
[s,t] = G.call([a,b,c])
q = G.call({'a':a, 'b':b, 'c':c})

% New alternative syntax, MATLAB
v
= F.call({a,b});
r = v{1};
v
= G.call({a,b,c});
s
= v{1};
t
= v{2};
q
= G.call(struct('a', a, 'b', b, 'c', c));

The alternative syntax is also required if you e.g. wants to force a function call to be inlined.

Best regards,
Joel



Jonas Koenemann

unread,
Mar 7, 2016, 10:53:26 AM3/7/16
to CasADi
Hi,

i was thinking about an example to create the function with "named" inputs in matlab. This is what i got. 
I think its still not very intuitive. Can my example be written better?

a = SX.sym('a');
b
= SX.sym('b');
c
= SX.sym('c');
g_sym
= a+b^2-c^3;
G
= Function('G', struct('a',a,'b',b,'c',c,'g_out',g_sym), ['a';'b';'c'],'g_out')

q
= G('a', 1, 'b', 2, 'c', 3);
result
= q.g_out

I think its worth thinking about a nice, easy to understand, and intuitive way to create and call functions (before the release) because this seems to be quiet essential.

Maybe there is no way to do it nicely in one line. For me doing it multline would be more intuitive, e.g.:

G = Function('G')
G
.defineInput('a',a)
G
.defineInput('b',b)
G
.defineInput('c',c)
G
.defineOutput('g_out',g_sym)

or

= Function('G')
G
.defineInputs('a',a,'b',b,'c',c)
G
.defineOutputs('g_out',g_sym)




Jonas

Joris Gillis

unread,
Mar 7, 2016, 11:36:24 AM3/7/16
to CasADi
 Hi Jonas,

Just a quick remark; your multi-line suggestion is in fact opposing our heading with 3.0.

We went from stateful construction:
F = Function('F',...)
F
.setOption(..)
F
.init()

to an atomic construction:
F = Function('F',...,options)

How about the following? Note that's currently not valid syntax.
Gin = struct;
Gin.a = a;
Gin.b = b;
Gin.c = c;

Gout = struct;
Gout.g_out = g_sym;

Function
('G', Gin, Gout, fieldnames(Gin), fieldnames(Gout))


Best regards,
  Joris

--
Sent from CasADi's user forum at http://forum.casadi.org.
---
You received this message because you are subscribed to the Google Groups "CasADi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to casadi-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/casadi-users/1646c675-b333-4979-9e57-eef6571d9f6d%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Joel Andersson

unread,
Mar 7, 2016, 11:45:52 AM3/7/16
to CasADi
Hello Jonas,

The following is the recommended syntax:
a = SX.sym('a');
b
= SX.sym('b');
c
= SX.sym('c');
g_sym
= a+b^2-c^3;

G
= Function('G', {a,b,c},{g_sym},{'a','b','c'},{'g_out'});


q
= G('a', 1, 'b', 2, 'c', 3);
result
= q.g_out

Best regards,
Joel

Joel Andersson

unread,
Mar 7, 2016, 11:59:02 AM3/7/16
to CasADi
One more note: You can provide the names either as a cell arrays:

G = Function('G', {a,b,c},{g_sym},{'a','b','c'},{'g_out'});

or as char arrays:

G = Function('G', {a,b,c},{g_sym},char('a','b','c'),'g_out');

Although equivalent, don't won't to replace
char('a','b','c')
with
['a';'b';'c']
because the latter only works if all names have the same number of characters.
Reply all
Reply to author
Forward
0 new messages