Search code examples
matlabsymbolic-matheigenvaluestate-space

Matlab place function error


Interesting problem here. On our school's Windows server, Matlab can execute the place function in the following code perfectly well and return a 1x4 matrix assigned to variable K. However, the Linux servers, and Matlab on my personal computer (Windows 8.1) all return multiple errors. The solution to the state space matrices is correct. I have also tried simply creating an A and B matrix with values of type Double rather than symbolic matrices, to no avail. The errors are as follows:

Error using symengine
Cannot prove '(0.00000000000011152837950971767051666806677642 < 5.0227916840119976230900756087285) < 2' literally. To test the statement
mathematically, use isAlways.

Error in sym/logical (line 360)
            X = mupadmex('symobj::logical',A.s,9);

Error in sym/any (line 417)
                X = any(logical(A));

Error in place (line 77)
if any(mult>m)

The relevant code I am trying to execute is this:

syms theta thetadot y ydot u s;

I2 = 0.05;
I1 = 0.2;
m2 = 2;
r = 0.11;
a = 0.1;
g = 9.81;

x0 = [20 * pi / 180 0.2 0 0];

W = [I1 + I2 + m2 * (y^2 + r^2) m2 * r + I2 / a; m2 * r + I2 / a m2 + I2 / a^2];

qdd = W^(-1) * ([u; 0] - (m2 * [2*y*thetadot*ydot; -y*thetadot^2] - m2*g*        [r*sin(theta) + y*cos(theta); sin(theta)]));
qd = [thetadot; ydot];

xdot = [qd; qdd];
eq = [0 0 0 0 0 ];

x3bytheta = subs(diff(qdd(1), theta), {theta, y, thetadot, ydot, u}, eq);
x3byy = subs(diff(qdd(1), y), {theta, y, thetadot, ydot, u}, eq);
x3bythetadot = subs(diff(qdd(1), thetadot), {theta, y, thetadot, ydot, u}, eq);
x3byydot = subs(diff(qdd(1), ydot), {theta, y, thetadot, ydot, u}, eq);

x4bytheta = subs(diff(qdd(2), theta), {theta, y, thetadot, ydot, u}, eq);
x4byy = subs(diff(qdd(2), y), {theta, y, thetadot, ydot, u}, eq);
x4bythetadot = subs(diff(qdd(2), thetadot), {theta, y, thetadot, ydot, u}, eq);
x4byydot = subs(diff(qdd(2), ydot), {theta, y, thetadot, ydot, u}, eq);

x3byu = subs(diff(qdd(1), u), {theta, y, thetadot, ydot, u}, eq);
x4byu = subs(diff(qdd(2), u), {theta, y, thetadot, ydot, u}, eq);

A = [0 0 1 0; 0 0 0 1; x3bytheta x3byy x3bythetadot x3byydot; x4bytheta x4byy x4bythetadot x4byydot];
B = [0; 0; x3byu; x4byu];

K = place(vpa(A, 3), vpa(B, 3), [-1, -2, -1+2j, -1-2j]);

Solution

  • The difference in behavior comes from an R2015a update to the Symbolic Toolbox (last entry), and quoting from the current documentation of symbolic gt:

    In previous releases, gt in some cases evaluated inequalities involving only symbolic numbers and returned logical 1 or 0. To obtain the same results as in previous releases, wrap inequalities in isAlways. For example, use isAlways(A > B).

    And the symbolic comparison persists even if both operands are constant; which is, not having been at the architecture meeting, a rather big oversight and quizzical behavior.

    Unfortunately, since place was written from a "double-use first" perspective, the function relies on the summation of logicals to produce numeric output and not symbolic expressions.

    I can see two methods to remedy this situation:

    1. Unless you really need Variable Precision Arithmetic due to systems whose ill-conditioned nature is unavoidable, simply cast A and B as doubles, which you have already noted works.
    2. If you do need Variable Precision Arithmetic, create a local copy of the place function and wrap all pertinent logical comparisons in isAlways to evaluate the comparisons. The lines of interest I've found are (if not exact, are close to) 60, 105, 117, and 123.