Inconvenience working with matlabFunction
显示 更早的评论
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 个评论
Steven Lord
2022-9-8
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
2022-9-8
采纳的回答
更多回答(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
2022-9-8
0 个投票
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 个评论
Mohammad Shojaei Arani
2022-9-10
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
2022-9-11
Walter Roberson
2022-9-12
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
2022-9-12
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
2022-9-19
Walter Roberson
2022-9-19
Huh. I would have guessed that it would be the 1 that should be duplicated, not the 30.
Mohammad Shojaei Arani
2022-9-21
类别
在 帮助中心 和 File Exchange 中查找有关 Programming 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!