Inconvenience working with matlabFunction
Afficher commentaires plus anciens
Hello,
One of you did kindly respond my question (my question was very similar to this one) but I again ran into problem and need to bother you again. Sorry for this. Consider the following
>> syms x y p1 p2
h=[x*y+p1 y^2-1;x^3+p2^2 1-x^2+p1*p2];
H=matlabFunction(h)
H =
function_handle with value:
@(p1,p2,x,y)reshape([p1+x.*y,p2.^2+x.^3,y.^2-1.0,p1.*p2-x.^2+1.0],[2,2])
I am not happy with this. I would prefer the 'reshape' to be removed. Why? because this is never convenient in letting me to to do vector operations. For instance, if I use the command H(1,2,[3 4],[5 6]) then matlab throws an erros message. How can I tell matlab PLEASE make the following matlab function for me:
H=@(p1,p2,x,y)[x*y+p1 y^2-1;x^3+p2^2 1-x^2+p1*p2];
I know how to tackle this problem when all inputs p1,p2,x,y have the same size (I can fix it by the command HL = @(p1v,p2v,xv,yv) arrayfun(H, p1v,p2v,xv,yv, 'Unif',0);).
However, here p1 and p2 are scalar parameters while x and y are (row) vectors of the same size (like H(1,2,[3 4],[5 6]), as I mentioned above). The best way to tackle this problem for me is as follows:
I would prefer the output to be a 3D array where the first page is H(1,2,3,5) and the second page is H(1,2,4,6).
Thanks for your kind help, in advance!
Babak
2 commentaires
Steven Lord
le 8 Sep 2022
Since this question appears to be a continuation of https://www.mathworks.com/matlabcentral/answers/1800275-inconveniences-working-with-matlabfunction you should probably add comments to that question (which has already received several comments and answers) rather than posting a new question.
Mohammad Shojaei Arani
le 8 Sep 2022
Réponse acceptée
Plus de réponses (2)
If you don't need to work in symbolics, don't.
h=@(p1,p2,x,y)[x.*y+p1,y.^2-1;x.^3+p2^2, 1-x.^2+p1*p2];
h(1,2,[3 4],[5 6])
Walter Roberson
le 8 Sep 2022
0 votes
Sorry, but matlabFunction() is not going to change about this, as it involves a fundamental model of what symbolic variables are and how they are manipulated.
8 commentaires
Mohammad Shojaei Arani
le 10 Sep 2022
You are misunderstanding what is happening. Consider
syms x
f = 3*x^2 + 2*x + 1
y1 = 5*diff(f,x)
y2 = 7*diff(f,x,x)
g1 = matlabFunction(y1, 'vars', x)
g2 = matlabFunction(y2, 'vars', x)
g3 = matlabFunction(7*diff(f,x,x), 'vars', x)
You can see that g3 does not take into account the size() of x -- if you were to pass in a vector of length 5 it would only return scalar 42 not a vector that repeated 42 as many times as elements there were in x.
But if you look at y2 you can see that the 7*diff(f,x,x) has already lost the size of x and become the constant 42.
So it is not the case that matlabFunction() is examining its input and optimizing some internal repmat(42, size(x)) away to a simple scalar 42 -- matlabFunction() only receives the 42 with no information about where it came from. matlabFunction() emits based upon the information it is given.
Now consider
f1 = matlabFunction([x; 1])
if you pass in a column vector for x, then what is the desired output? Should the output of f1([3;2]) be [3;2;1] or should it be [3;2;1;1] where the constant 1 is being repeated according to the size of x ? It should be clear that you might want different behaviour for different constants. For example,
f2 = matlabFunction([x;1;0*x])
That hints that you might want just a scalar 1, but that you want 0's the same size as x. But what matlabFunction recieves is going to be [x; 1; 0] because [x;1;0*x] is going to be evaluated before it reaches matlabFunction()
Can we code this using size(), something like
syms x
f3 = matlabFunction([x; 1; zeros(size(x))])
But "syms x" creates a symbolic scalar, so size(x) would be 1 1, so matlabFunction is going to receive [x; 1; 0]
Can you work with the new symbolic matrices?
x = symmatrix('x', [3 2])
f4 = [x;1 1;zeros(size(x))]
%f4 would be vertcat(x, vertcat(symmatrix(ones(1,2)), symmatrix(zeros(3,2))))
but you cannot matlabFunction() a symmatrix so you have to convert to sym:
f5 = matlabFunction( symmatrix2sym(f4), 'vars', symmatrix2sym(x))
% f5 = @(x1_1,x2_1,x3_1,x1_2,x2_2,x3_2)reshape([x1_1,x2_1,x3_1,1.0,0.0,0.0,0.0,x1_2,x2_2,x3_2,1.0,0.0,0.0,0.0],[7,2])
and you are back to a fixed size.
There are currently no circumstances under which you can designate a particular expression as being variable size and convince matlabFunction() to generate appropriate code that takes into account the size at run-time.
Let us consider
syms y z
f6 = y - y + z - z
f5 is going to receive scalar 0. If somehow you had designated y and z as variable size, a hypothetical
varsizesym y z %hypothetical
f6 = y - y + z - z
then the expression would have to generate something like
f6 = varsizesym(0, y) + varsizesym(0, z)
What is the size of f6? Because of implicit expansion, we do not know until fairly late in the computation...
We can imagine that we might want f7 = [1; f6] -- but is that 1 intended to be scalar 1, or is it intended to be 1 with the size number of columns as f6, or is it intended to be 1 with the same number of rows as f6...
so we start needing (hypothetical) code such as
f7 = varsizesym(1, 'width', f6)
but as we extend into 3 or more dimensions, naming the dimensions becomes unworkable, so we start needing varsizesym(1, 'size', symsize(f6)) where symsize(f6) is the runtime size of f6...
You can see that this is all a lot more complicated that just adding a flag to matlabFunction: it would require adding new symbolic operations that return unresolved until subs() is used.
Speaking of subs(), what if what you subs() in is a symbolic vector that includes an unresolved symbolic variable name? If it includes a (hypothetical) varsizesym symbolic variable? How do we define the sizes properly?
Mohammad Shojaei Arani
le 11 Sep 2022
Walter Roberson
le 12 Sep 2022
Suppose you have
syms x
f = [1 2 3; 4 x 6; 7 8 9]
F = matlabFunction(f, 'loose') %hypothetical keyword
What output would you expect for F([100 200]) ? What output would you expect for F([300; 400]) ?
Now suppose you have
syms x y
g = [x; y]
G = matlabFunction(g, 'loose')
What output would you expect for G(1, [20 30]) ? What output would you expect for G([10; 11], 40) ? What output would you expect for G([10; 11], [50 60]) ?
Bruno Luong
le 12 Sep 2022
f = [1 2 3; 4 x 6; 7 8 9]
g = [x; y]
Personallly I would love to have they behaves like auto-expansion but on array construction, not only for symbolic variable but also for non-symbolic objects.
(In the first case f only x that is "vector" along dimension > 2 can be accepted).
Mohammad Shojaei Arani
le 19 Sep 2022
Walter Roberson
le 19 Sep 2022
Huh. I would have guessed that it would be the 1 that should be duplicated, not the 30.
Mohammad Shojaei Arani
le 21 Sep 2022
Catégories
En savoir plus sur Programming dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!