drake
drake copied to clipboard
Conversion between SymPy and pydrake.symbolic.Polynomial
Is your feature request related to a problem? Please describe. This is a followup to #20076. It would be nice to have first class support to convert between SymPy Polynomials and pydrake.symbolic.Polynomial.
Note that currently this is not possible. Consider the following code.
x_sympy = sympy.var("x")
x_drake = drake_sym.Variable("x")
x_drake_to_sympy = {x_drake.get_id(): x_sympy}
x_sympy_to_drake = {x_sympy: x_drake.get_id()}
drake_poly = drake_sym.Polynomial(x_drake**2 - 2 * x_drake + 1)
sympy_poly = drake_sym.to_sympy(
drake_poly.ToExpression(), memo=x_drake_to_sympy
).as_poly()
The result is that sympy_poly
has generators x
and x**2
. The reason for this is that drake_sym.to_sympy(drake_poly.ToExpression(), memo=x_drake_to_sympy)
has in its expression tree:
Pow(Symbol('x'), Float('2.0', precision=53)
Since the exponent of x**2
is a Float and not an Integer, then Sympy cannot cast it to a polynomial properly.
Describe the solution you'd like Ideally we can write the above code as:
drake_poly = drake_sym.Polynomial(x_drake**2 - 2 * x_drake + 1)
sympy_poly = drake_sym.to_sympy(drake_poly, memo=x_drake_to_sympy)
and avoid all the casting back and forth between the expressions.
At the very least, drake's ExpressionKind::Pow
should be converted to sympy's Pow(x, Integer(*))
rather than Pow(x, Float(*))
whenever possible.
+@AlexandreAmice would you like this assigned to you? If not that's fine -- you can re-assign over to @hongkai-dai for safekeeping.