Vectorizing a function handle with some constant inputs
2 views (last 30 days)
Show older comments
Hello friends!
I have an annoying problem and need your kind help!
Suppose that I have a symbolic vector like f = [x+y;0;x.*y;2.*x;0] where both x and y are vectors of the same size. As you see, some of the elements of f are 0. Imagine that we do not know, beforehand, which one is zero. Now, I want to ake a function handle out of it which is simple as bellow
g = matlabFunction(f);g
g =
function_handle with value:
@(x,y)[x+y;0.0;x.*y;x.*2.0;0.0]
Now, if I want to rund the command g([1 2],[3 4]) then clearly I get erros (dimension mismatch). Here, I have 2 problems. First, I do not know, beforehand, which element is 0 to fix the problem. Second, even if I know which is 0 it would not be easy to fix it through 'matlabFunction' (though it is possible through @() operation). I explain more. One way to fix the problem (assuming I know that second and last components are 0) is as bellow:
g = @(x,y)[x+y;0*x;x.*y;x.*2.0;0.*x];
but, if I only have access to the symbolic expression f = [x+y;0;x.*y;2.*x;0] and if I write f = [x+y;0.*x;x.*y;2.*x;0.*x] then the command g = matlabFunction(f) first simplifies f and then I am in trouble again. I did find a nice solution as bellow:
>> tmp = arrayfun(g, [1 2],[3 4], 'uni', 0);
tmp = cat(2, tmp{:})
tmp =
4 6
0 0
3 8
2 4
0 0
but this has the problem that increases the computational time, unfortunately. Please note that my actual problem is not this simple and my f function is a super big multi-component function (and x and y have rather big dimensions like 1-by-1000 not 1-by-2) which must be calculated in a for-loop thousands of time. So, I need a solution which fixes the root of the problem, that is a solution which corrects g by notifying the zero components and replaces them by 0.*x. To give you a feeling about how the computational time between the 2 approaches differ run the following
syms x y
f = [x+y;0;x.*y;2.*x;0];
g = matlabFunction(f);
g1= @(x,y)[x+y;0.*x;x.*y;2.*x;0.*x];
N=100000;
x=[1 2];y=[3 4];
tic;
for n=1:N
g1(x,y);
end
h1=toc;
tic;
for n=1:N
tmp = arrayfun(g, 1:5,1:5, 'uni', 0);
tmp = cat(2, tmp{:});
end
h2=toc;
[h1/N h2/N]
ans =
9.8002e-07 1.6842e-05
Any idea for this extremely annoying problem? If there is no good answer to my question then I hope that in the next version of matlab they fix this (they can easily fix it but perhaps they did not predict this).
Thank you in advance!
Babak
0 Comments
Answers (0)
See Also
Categories
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!