0

Why does this line:

    prog.AddQuadraticErrorCost(np.identity(len(q)), q0, q)

works.

But this:

  prog.AddCost(np.linalg.norm(q_variables - q_nominal)**2)

RuntimeError: Expression pow(sqrt((pow(q(0), 2) + pow(q(2), 2) + pow(q(4), 2) + pow(q(6), 2) + pow(q(7), 2) + pow(q(8), 2) + pow((-1 + q(5)), 2) + pow((-0.59999999999999998 + q(1)), 2) + pow((1.75 + q(3)), 2))), 2) is not a polynomial. ParseCost does not support non-polynomial expression.

does not?

Are the expressions not mathematically identical?

user3180
  • 1,369
  • 1
  • 21
  • 38

1 Answers1

1

They are mathematically identical, but our symbolic engine is not yet powerful enough to recognize that sqrt(x)**2 should be simplified as x.

You can also write the expression using the symbolic form

prog.AddQuadraticCost((q-q0).dot(q-q0))

if you prefer readable code.

Hongkai Dai
  • 2,546
  • 11
  • 12
  • Note that _"sqrt(x)**2 should be simplified as x"_ is only true for x >= 0. In this case x is a sum of squares so we can reason that it's non-negative, and we could teach the symbolic simplification that same rule, but it's not such a trivial pattern-match as it might first seem. – jwnimmer-tri Nov 09 '21 at 00:57
  • @jwnimmer-tri I think by writing sqrt(x), we already suppose that x >= 0, unless we want to explicitly support imaginary numbers? – Hongkai Dai Nov 09 '21 at 02:12
  • If you have `sqrt(x)**2` and substitute `x = -1`, you get an exception. If you have `x` and substitute `x = -1`, you get -1. They are not equivalent. In other words, the expressions are only valid over some domain. As we change how they are written, we change that domain. For some applications, that change is unwanted or incorrect. – jwnimmer-tri Nov 09 '21 at 13:50