A MATLAB function with mixed scalar and vector as inputs fail
1 Ansicht (letzte 30 Tage)
Ältere Kommentare anzeigen
Mohammad Shojaei Arani
am 7 Sep. 2022
Kommentiert: Walter Roberson
am 8 Sep. 2022
Hello,
I have a question which I explain by a simple example first. Consider the matlab function
H=@(x,x0,par1,par2)[x+par1 x.^2+par2;1-x.^2-par2 x.^3+par1];
where here x and x0 are vectors but par1 and par2 are scalars. So, H should give us matrices as output (if x and x0 are also
scalars then such matrices are square, otherwise we get non-square matrices). Any of the combinations H([1; 2],[3; 4],1,2), H([1; 2],[3 4],1,2)
H([1 2],[3; 4],1,2) and H([1 2],[3 4],1,2) works and MATLAB does not through any error message.
Now, consider the attached matlab function H_LL(x,x0,par1,par2,par3,par4,par5) which is just longer and has 5 parameters, instead of 2. Unfortunately, this only works if x and x0 are only scalars (and I do not know why!!!)
It would be great if you have an idea what's wrong here?
Thanks
Babak
2 Kommentare
David Hill
am 7 Sep. 2022
Given an example of your inputs and what you expect for the size of the output.
dpb
am 7 Sep. 2022
function h_LL = H_LL(x,x0,par1,par2,par3,par4,par5)
%H_LL
% H_LL = H_LL(X,X0,PAR1,PAR2,PAR3,PAR4,PAR5)
% This function was generated by the Symbolic Math Toolbox version 8.6.
% 07-Sep-2022 16:46:14
t2 = par4.^2;
t3 = x.^2;
t4 = x.^3;
t6 = 1.0./par2;
t8 = 1.0./par5.^2;
t9 = 1.0./par5.^3;
t10 = -x0;
t5 = t3.^2;
t7 = t6.^2;
t11 = t6.*x;
t12 = t2+t3;
t13 = t11-1.0;
t14 = 1.0./t12;
t15 = t14.^2;
t16 = t14.^3;
t17 = (par1.*t13.*x)./1.0e+2;
t18 = (par3.*t3.*t14)./1.0e+2;
t20 = (par1.*t4.*t7.*t8.*t13)./1.0e+2;
t21 = (par1.*t5.*t7.*t8.*t14)./1.0e+2;
t24 = (t4.*t8.*t13.*t14)./1.0e+2;
t19 = (par3.*par4.*t5.*t8.*t16)./5.0e+1;
t22 = (par1.*par3.*par4.*t5.*t7.*t8.*t15)./5.0e+1;
t25 = (par3.*par4.*t4.*t8.*t13.*t15)./5.0e+1;
t26 = -t24;
t27 = t10+t17+t18+x;
t23 = -t22;
t28 = t3.*t7.*t8.*t27;
t29 = par1.*t3.*t7.*t9.*t27.*2.0;
t31 = t9.*t13.*t27.*x.*2.0;
t32 = t3.*t9.*t14.*t27.*2.0;
t33 = par4.*t3.*t8.*t15.*t27.*2.0;
t34 = par3.*par4.*t3.*t9.*t15.*t27.*4.0;
t30 = -t29;
t35 = -t34;
t36 = t20+t28;
t37 = t19+t33;
h_LL = reshape([t3.*t8.*t13.^2.*(-1.0./1.0e+2),t36,t26,t25,t31,t36,par1.^2.*t5.*t7.^2.*t8.*(-1.0./1.0e+2)-par1.*t3.*t6.^3.*t8.*t27.*2.0,t21,t23,t30,t26,t21,t5.*t8.*t15.*(-1.0./1.0e+2),t37,t32,t25,t23,t37,par3.^2.*t2.*t5.*t8.*t15.^2.*(-1.0./2.5e+1)+par3.*t3.*t8.*t15.*t27.*2.0-par3.*t2.*t3.*t8.*t16.*t27.*8.0,t35,t31,t30,t32,t35,t8-t8.^2.*t27.^2.*3.0e+2],[5,5]);
What a nightmare!
But, all kinds of things have to be so for that to work -- specifically with respect to x, at a bare minimum without looking hard we find
...
t3 = x.^2;
...
t17 = (par1.*t13.*x)./1.0e+2;
t18 = (par3.*t3.*t14)./1.0e+2;
...
which will require x be same dimensions as par1 or a scalar that can multiply anything on an element-by-element basis.
Trying to make any sense of of this without what generated it is hopeless -- and trying to generalize it to anything other than that specific case is, as well....
Akzeptierte Antwort
Walter Roberson
am 7 Sep. 2022
h_LL = reshape([t3.*t8.*t13.^2.*(-1.0./1.0e+2),t36,t26,t25,t31,t36,par1.^2.*t5.*t7.^2.*t8.*(-1.0./1.0e+2)-par1.*t3.*t6.^3.*t8.*t27.*2.0,t21,t23,t30,t26,t21,t5.*t8.*t15.*(-1.0./1.0e+2),t37,t32,t25,t23,t37,par3.^2.*t2.*t5.*t8.*t15.^2.*(-1.0./2.5e+1)+par3.*t3.*t8.*t15.*t27.*2.0-par3.*t2.*t3.*t8.*t16.*t27.*8.0,t35,t31,t30,t32,t35,t8-t8.^2.*t27.^2.*3.0e+2],[5,5]);
You have 25 components in the [], each the same size as your x input. You ask to reshape() that to a 5 x 5 matrix. If x is scalar, that works out fine, a 1 x 25 reshaped to 5 x 5 fits perfectly. But if x were (for example) length 2, you would have a 1 x (25*2) array being reshaped to 5 x 5, and you cannot reshape 50 elements into 25 spaces.
You could edit the code to reshape the input x into the third dimension,
x = reshape(x, 1, 1, []);
and then in the assignment to h_LL you could change the reshape from [5,5] to 5, 5, [] . This would give you a 5 x 5 x numel(x) result... at the expense of having to manually edit the code.
You cannot convince the Symbolic Toolbox matlabFunction() to itself properly vectorize a function that returns an array (or a function that uses piecewise() or some other functions such as int()) .
2 Kommentare
Walter Roberson
am 8 Sep. 2022
This is not going to get "fixed". This is fundamental to the design of the Symbolic Toolbox. All symbolic variable names are scalars and are calculated with as scalars. matlabFunction makes no attempt to check input sizes against output sizes
Weitere Antworten (0)
Siehe auch
Kategorien
Mehr zu Entering Commands finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!