Skip to content

Instantly share code, notes, and snippets.

@jgillis
Last active September 6, 2021 13:37
Show Gist options
  • Save jgillis/6c8d3a4b9567e39ba30e to your computer and use it in GitHub Desktop.
Save jgillis/6c8d3a4b9567e39ba30e to your computer and use it in GitHub Desktop.
using vertcat(MX,MX) as inputs to Function
from casadi import *
def HackyFunction(name,ins,outs):
# Obtain all symbolic primitives present in the inputs
Vs = symvar(veccat(*ins))
# Construct a helper function with these symbols as inputs
h = Function("helper",Vs, ins)
# Assert dense inputs
for i in ins:
assert i.is_dense(), "input must be dense"
# Obtain sparsity pattern of the helper function Jacobian
# It should be a permutation of the unit matrix
H = blockcat([[Sparsity(h.sparsity_jac(i,j)) for i in range(h.n_in())] for j in range(h.n_out())])
assert H.size1()==H.size2(), "input must be one-to-one"
assert H.colind()==range(H.size1()+1), "input must be one-to-one"
assert H.T.colind()==range(H.size1()+1), "input must be one-to-one"
# Missing assertion: check that only transpose, reshape, vertcat, slice, .. are used
# Construct new MX symbols on which the original inputs will depend
Vns = [MX.sym("V",i.size()) for i in ins]
res = reverse(ins, Vs, [Vns],{"always_inline":True,"never_inline":False})
# Substitute the original inputs
return Function("f",Vns,substitute(outs,Vs,res[0]))
# Some more tests
for M, MF in [(MX,HackyFunction), (SX,Function)]:
x = M.sym("x")
y = M.sym("y",1,12)
z = M.sym("z",3,3)
V = vertcat(y.T,x,vec(z))
w = M.sym("w",2)
v = M.sym("v",5)
W = vertcat(w,v)
f = MF("f",[V,W],[z,w,x*w])
print "numerical test"
print f(range(22),range(7))
@Filippo-Tamagnini
Copy link

Is there a possibility that this enters the main API?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment