I have some symbolic expressions stored on disk that I want to use in a non-convex program with autodiff variables. How can I substitute symbolic variables for autodiff variables?
from pydrake.all import (
MathematicalProgram,
SnoptSolver,
Variable,
)
# Loaded from disk
x = Variable("x")
cost_expression = x**2
prog = MathematicalProgram()
x_vars = prog.NewContinuousVariables(1, "x")
def cost_func(vars):
var = vars[0]
return cost_expression.Substitute({x: var})
prog.AddCost(cost_func, vars=x_vars)
# Use Snopt with autodiff as the real problem won't be convex
solver = SnoptSolver()
result = solver.Solve(prog)
The above code gives the following error:
result: MathematicalProgramResult = solver.Solve(prog) RuntimeError: Exception while evaluating SNOPT costs and constraints: 'TypeError: Substitute(): incompatible function arguments. The following argument types are supported: 1. (self: pydrake.symbolic.Expression, var: pydrake.symbolic.Variable, e: pydrake.symbolic.Expression) -> pydrake.symbolic.Expression 2. (self: pydrake.symbolic.Expression, s: Dict[pydrake.symbolic.Variable, pydrake.symbolic.Expression]) -> pydrake.symbolic.Expression
Invoked with: <Expression "pow(x, 2)">, {Variable('x', Continuous): <AutoDiffXd 0.0 nderiv=1>}
Thank you, Jeremy, for the great answer! I'm writing this up here so that it is marked as completed.
Substitution/ evaluation of a symbolic expression with autodiff variables is possible by converting it to an ExpressionCost
.
from pydrake.all import (
ExpressionCost,
MathematicalProgram,
SnoptSolver,
Variable,
)
# Loaded from disk
x = Variable("x")
cost_expression = x**2
expression_cost = ExpressionCost(cost_expression)
prog = MathematicalProgram()
x_vars = prog.NewContinuousVariables(1, "x")
def cost_func(vars):
return expression_cost.Eval(vars)[0]
prog.AddCost(cost_func, vars=x_vars)
solver = SnoptSolver()
result = solver.Solve(prog)