Asked by William Sharpless
on 17 Nov 2019 at 23:01

Hi,

I made a Jacobian with jacobian() and then turned it into a function with the matlabFunction(), but matlab rearranges the variables (in alpha numeric order). For example, it took a matrix of variables and put the tenth and eleventh row before the first row because a10_1,...a10_11 goes before a1_1 AND then within those variables it put the a10_10 and a10_11 after a11_1 ... a11_9. This is annoying because I now have to disect the matricies of data I will throw into the function and creates room for a subtle error. Is there a way to turn off the sort capability in matlabFunction()? docs lead me to sympref() and a couple name-value pairs of matlabFunction() but neither looked like they could rearrange the variables. This is in R2019a.

syms x [N 1]

syms u [N 1]

syms a [N N]

dX(:,1) = x.*(u+a*x);

J = matlabFunction(jacobian(dX(:,1),x))

outputs:

J =

function_handle with value:

@(a10_1,a10_2,a10_3,a10_4,a10_5,a10_6,a10_7,a10_8,a10_9,a11_1,a11_2,a11_3,a11_4,a11_5,a11_6,a11_7,a11_8,a11_9,a10_10,a10_11,a11_10,a11_11,a1_1,a1_2,a1_3,a1_4,a1_5,a1_6,a1_7,a1_8,a1_9,a2_1,a2_2,a2_3,a2_4,a2_5,a2_6,a2_7,a2_8,a2_9,a3_1,a3_2,a3_3,a3_4,a3_5,a3_6,a3_7,a3_8,a3_9,a4_1,a4_2,a4_3,a4_4,a4_5,a4_6,a4_7,a4_8,a4_9,a5_1,a5_2,a5_3,a5_4,a5_5,a5_6,a5_7,a5_8,a5_9,a6_1,a6_2,a6_3,a6_4,a6_5,a6_6,a6_7,a6_8,a6_9,a7_1,a7_2,a7_3,a7_4,a7_5,a7_6,a7_7,a7_8,a7_9,a8_1,a8_2,a8_3,a8_4,a8_5,a8_6,a8_7,a8_8,a8_9,a9_1,a9_2,a9_3,a9_4,a9_5,a9_6,a9_7,a9_8,a9_9,a1_10,a1_11,a2_10,a2_11,a3_10,a3_11,a4_10,a4_11,a5_10,a5_11,a6_10,a6_11,a7_10,a7_11,a8_10,a8_11,a9_10,a9_11,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11)reshape([u1+a1_1.*x1.*2.0+a1_2.*x2+a1_3.*x3+a1_4.*x4+a1_5.*x5+a1_6.*x6+a1_7.*x7+a1_8.*x8+a1_9.*x9+a1_10.*x10+a1_11.*x11,a2_1.*x2,a3_1.*x3,a4_1.*x4,a5_1.*x5,a6_1.*x6,a7_1.*x7,a8_1.*x8,a9_1.*x9,a10_1.*x10,a11_1.*x11,a1_2.*x1,u2+a2_1.*x1+a2_2.*x2.*2.0+a2_3.*x3+a2_4.*x4+a2_5.*x5+a2_6.*x6+a2_7.*x7+a2_8.*x8+a2_9.*x9+a2_10.*x10+a2_11.*x11,a3_2.*x3,a4_2.*x4,a5_2.*x5,a6_2.*x6,a7_2.*x7,a8_2.*x8,a9_2.*x9,a10_2.*x10,a11_2.*x11,a1_3.*x1,a2_3.*x2,u3+a3_1.*x1+a3_2.*x2+a3_3.*x3.*2.0+a3_4.*x4+a3_5.*x5+a3_6.*x6+a3_7.*x7+a3_8.*x8+a3_9.*x9+a3_10.*x10+a3_11.*x11,a4_3.*x4,a5_3.*x5,a6_3.*x6,a7_3.*x7,a8_3.*x8,a9_3.*x9,a10_3.*x10,a11_3.*x11,a1_4.*x1,a2_4.*x2,a3_4.*x3,u4+a4_1.*x1+a4_2.*x2+a4_3.*x3+a4_4.*x4.*2.0+a4_5.*x5+a4_6.*x6+a4_7.*x7+a4_8.*x8+a4_9.*x9+a4_10.*x10+a4_11.*x11,a5_4.*x5,a6_4.*x6,a7_4.*x7,a8_4.*x8,a9_4.*x9,a10_4.*x10,a11_4.*x11,a1_5.*x1,a2_5.*x2,a3_5.*x3,a4_5.*x4,u5+a5_1.*x1+a5_2.*x2+a5_3.*x3+a5_4.*x4+a5_5.*x5.*2.0+a5_6.*x6+a5_7.*x7+a5_8.*x8+a5_9.*x9+a5_10.*x10+a5_11.*x11,a6_5.*x6,a7_5.*x7,a8_5.*x8,a9_5.*x9,a10_5.*x10,a11_5.*x11,a1_6.*x1,a2_6.*x2,a3_6.*x3,a4_6.*x4,a5_6.*x5,u6+a6_1.*x1+a6_2.*x2+a6_3.*x3+a6_4.*x4+a6_5.*x5+a6_6.*x6.*2.0+a6_7.*x7+a6_8.*x8+a6_9.*x9+a6_10.*x10+a6_11.*x11,a7_6.*x7,a8_6.*x8,a9_6.*x9,a10_6.*x10,a11_6.*x11,a1_7.*x1,a2_7.*x2,a3_7.*x3,a4_7.*x4,a5_7.*x5,a6_7.*x6,u7+a7_1.*x1+a7_2.*x2+a7_3.*x3+a7_4.*x4+a7_5.*x5+a7_6.*x6+a7_7.*x7.*2.0+a7_8.*x8+a7_9.*x9+a7_10.*x10+a7_11.*x11,a8_7.*x8,a9_7.*x9,a10_7.*x10,a11_7.*x11,a1_8.*x1,a2_8.*x2,a3_8.*x3,a4_8.*x4,a5_8.*x5,a6_8.*x6,a7_8.*x7,u8+a8_1.*x1+a8_2.*x2+a8_3.*x3+a8_4.*x4+a8_5.*x5+a8_6.*x6+a8_7.*x7+a8_8.*x8.*2.0+a8_9.*x9+a8_10.*x10+a8_11.*x11,a9_8.*x9,a10_8.*x10,a11_8.*x11,a1_9.*x1,a2_9.*x2,a3_9.*x3,a4_9.*x4,a5_9.*x5,a6_9.*x6,a7_9.*x7,a8_9.*x8,u9+a9_1.*x1+a9_2.*x2+a9_3.*x3+a9_4.*x4+a9_5.*x5+a9_6.*x6+a9_7.*x7+a9_8.*x8+a9_9.*x9.*2.0+a9_10.*x10+a9_11.*x11,a10_9.*x10,a11_9.*x11,a1_10.*x1,a2_10.*x2,a3_10.*x3,a4_10.*x4,a5_10.*x5,a6_10.*x6,a7_10.*x7,a8_10.*x8,a9_10.*x9,u10+a10_1.*x1+a10_2.*x2+a10_3.*x3+a10_4.*x4+a10_5.*x5+a10_6.*x6+a10_7.*x7+a10_8.*x8+a10_9.*x9+a10_10.*x10.*2.0+a10_11.*x11,a11_10.*x11,a1_11.*x1,a2_11.*x2,a3_11.*x3,a4_11.*x4,a5_11.*x5,a6_11.*x6,a7_11.*x7,a8_11.*x8,a9_11.*x9,a10_11.*x10,u11+a11_1.*x1+a11_2.*x2+a11_3.*x3+a11_4.*x4+a11_5.*x5+a11_6.*x6+a11_7.*x7+a11_8.*x8+a11_9.*x9+a11_10.*x10+a11_11.*x11.*2.0],[11,11])

% ^^^^^ ^^^^^^^^^^^^ ^^^^^^ ^^^^^^

Answer by Star Strider
on 17 Nov 2019 at 23:46

Accepted Answer

I can’t run the code you posted, since it generates significant errors about matrix size multiplication.

However, a simple example demonstrates how to order the arguments:

syms a b c d x1 x2 x3 x4

e = a*x1+b*x2+c*x3+d*x4;

E = matlabFunction(e, 'Vars',{[x1 x2 x3 x4],c a b d})

producing:

E =

function_handle with value:

@(in1,c,a,b,d)a.*in1(:,1)+b.*in1(:,2)+c.*in1(:,3)+d.*in1(:,4)

So the arguments are ordered in the sequence requested, and the parameters are grouped together as ‘in1’ in a separate parameter vector, in the event you need to do that.

Star Strider
on 18 Nov 2019 at 1:02

No worries.

My illustration holds. Experiment with this:

N = 11;

syms x [N 1]

syms u [N 1]

syms a [N N]

dX(:,1) = x.*(u+a*x);

av = reshape(a.', 1, []);

uv = reshape(u.', 1, []);

xv = reshape(x.', 1, []);

J = matlabFunction(jacobian(dX(:,1),x), 'Vars',{av,uv,xv})

The various vectors are ‘in1’ and such, however they should be in the order specified in ‘av’ and the others.

William Sharpless
on 18 Nov 2019 at 1:16

Yeah this is good stuff, thanks a bunch. The following line works well.

J = matlabFunction(jacobian(dX(:,1),x),'Vars', {x, a, u})

Star Strider
on 18 Nov 2019 at 1:18

As always, my pleasure!

Sign in to comment.

Answer by the cyclist
on 17 Nov 2019 at 23:26

I don't know the answer to your sorting question.

However, pulling back to the big picture for a moment, it seems like storing all the variables separately (rather than in single variable, with indexing) is a bad idea. See, for example, this tutorial.

Back to the small picture: A tactical solution might be to name variables with 01 or 001 instead of just 1, to keep it alphabetically ahead of 10.

William Sharpless
on 17 Nov 2019 at 23:34

mm ok, the latter seems like an alright work around, thx. Note from the code, these were the indeces matlab gave to them when I asked for a symbolic matrix, seems like matlab should do it properly or change the variable output arrangement.

I would like to know general answer still as I have run into this problem before.

In regards to the prior, how could I do this with symbolic math (it seems like what I did was what you said)? I don't intend to sort these independently, matlab just gives them to me that way after I perform the required operations.

In a perfect world, matlab might recognize that I have the full index of a matrix of input variables in my symbolic function and condense them.

Sign in to comment.

Opportunities for recent engineering grads.

Apply Today
## 0 Comments

Sign in to comment.