Closed alphaville closed 4 years ago
Update: it turns out that the following is allowed in CasADi (so we may not need to use Callbacks, which work only with MX
):
x = cs.SX.sym('x', 3)
r = cs.SX.sym('x', 1)
# Some function
normx = cs.norm_2(x)
# First branch
condition1 = cs.norm_2(x) <= r
fun1 = 0
# Second branch
condition2 = r <= -cs.norm_2(x)
fun2 = normx**2 + r**2
# Thrird branch
condition3 = (-cs.norm_2(x) < r) * (cs.norm_2(x) > r)
fun3 = (1 - (1*normx + r)/2 * (1/normx))**2 * normx**2
# Function defined piecewise
y = condition1*fun1 + condition2*fun2 + condition3*fun3
print(cs.substitute(cs.substitute(y, x, [5, -10, 0]), r, 5))
print(cs.jacobian(y, x))
that is, we can define logical predicates (corresponding to the branches of a function), the construct the function and compute its Jacobian.
Related issue: https://github.com/casadi/casadi/issues/2490
Useful snippet:
x = cs.SX.sym('x', 1)
f = cs.if_else(x > 0, cs.sqrt(x), 0.0, True)
f_jac = cs.jacobian(f, x)
JF = cs.Function('JF', [x], [f_jac])
o = JF(1.0)
print(JF, "at x=1.0 is ", o)
Possible solution that may allow to use SX
in our current SOC implementation: https://github.com/casadi/casadi/issues/2115
Find a way to implement the squared distance function from a given second-order cone. The definition involves branches, which correspond to if-blocks. These cannot be handled directly by CasADi. We either need to find a mathematically elegant way to describe the squared distance function in terms of supported functions (min, max, sign, abs, etc), or implement a custom CasADi function (and define its Jacobian too). Perhaps subclassing Callback is the best way to go.