MATLAB Answers

Matt J
3

Why does fplot think my function is not vectorized

Asked by Matt J
on 30 May 2019
Latest activity Edited by Matt J
on 25 Jun 2019
Executing the following as a script in R2018a
a=ones(1,10);
b=a;
b0=1;
fun=@(x) myFourier(x,a,b,b0);
fplot(fun);
function f=myFourier(x,a,b,b0)
n=numel(a);
arg=x(:).*(1:n);
f=b0+sin(arg)*a(:)+cos(arg)*b(:);
f=reshape(f,size(x));
end
results successfully in a plot, but throws warnings (EDIT: and results in non-vectorized execution!!!)
Warning: Function behaves unexpectedly on array inputs. To improve performance, properly vectorize your
function to return an output with the same size and shape as the input arguments.
> In matlab.graphics.function.FunctionLine>getFunction
In matlab.graphics.function.FunctionLine/updateFunction
In matlab.graphics.function.FunctionLine/set.Function_I
In matlab.graphics.function.FunctionLine/set.Function
In matlab.graphics.function.FunctionLine
In fplot>singleFplot (line 234)
In fplot>@(f)singleFplot(cax,{f},limits,extraOpts,args) (line 193)
In fplot>vectorizeFplot (line 193)
In fplot (line 163)
In test (line 7)
But the input function is properly vectorized as is easily verified in simple tests,
>> fun(rand(1,5))
ans =
3.4371 2.5677 14.1698 2.4490 1.0828
>> fun(rand(5,1))
ans =
14.1745
8.3619
-0.2579
1.7024
1.5748
Why the warnings, then?

  0 Comments

Sign in to comment.

Tags

4 Answers

Answer by Walter Roberson
on 31 May 2019
 Accepted Answer

f1 = fun(1);
f2 = fun([1 2]);
f1 - f2(1)
ans =
4.44089209850063e-16
Your code produces different outputs for the same input, which violates the rule that the calculations must be independent.

  3 Comments

As you can see though, it is a difference of 4.4689e-14 percent, easily attributable to floating point noise. And there's nothing either in the warning messages or fplot documentation that says that should be an issue.
fplot(@(x) x .* (1 + (length(x)>1)*eps))
generates the warning, so regardless of whether it "should", it does check for equality.
Tech support got back to me and confirmed Walter's explanation of the problem, and said they will look into remedies for future releases. I passed on to them my suggestions for fixes as well.

Sign in to comment.


Answer by dpb
on 31 May 2019

Because fplot is just looking at the source code, not the output and it doesn't recognize the reshape operation at the end--only that there are no "dot" operators in the evaluation from which it infers (usually correctly, but as you've shown not infallibly) that the function isn't "vectorized".
Whether there's any chance of being able to get this one right without way more parsing logic than would want to use for performance is, I'm guessing, pretty small. You can't just presume that if the user has a reshape call in the function that always works correctly, either.

  14 Comments

Agreed, but the warning isn't implying the functional value is wrong; only that it could be calculated more efficiently if it didn't have to loop through the expression...so if that's what they're trying to catch they don't do a good job of explaining the possible problem in the resulting error/warning message.
Worse than that, because fplot incorrectly judges the function to be nonvectorized, it forms the plot by executing the function in non-vectorized fashion forcing the user to endure slow behavior. I think they should let fplot() operate like integral() already does. Let the user specify whether execution will be vectorized or not, and take responsibility for the result.
This could well be the basis for an enhancement/quality of implemenation improvement request.

Sign in to comment.


Answer by Catalytic
on 7 Jun 2019

Here's a workaround to trick fplot into doing the right thing.
Capture.PNG

  0 Comments

Sign in to comment.


Answer by Yair Altman on 22 Jun 2019

As far as I can tell (never mind exactly how), internally a check is made whether the output of fun(1:3) is exactly equaln to the output of [fun(1),fun(2),fun(3)]. Even a tiny FP eps difference will cause the warning to be evoked. If you want to disable the error in run-time, run the following command:
warning off MATLAB:fplot:NotVectorized

  1 Comment

Thanks, Yair. But disabling the warning still leaves the bigger problem of execution efficiency. fplot will still go ahead and evaluate fun in non-vectorized (therefore slow) fashion based on the fun(1:3) test, even with the warning disabled.

Sign in to comment.