How to vectorise the code below
古いコメントを表示
I have asked about fsurf two or three times on this platform, and received two replies, neither of which extracted me from my difficulties. I have, however, made slow progress. I think I have found one bug in both execution and documentation of fsurf, and whether or not this is really a bug is still under consideration by Mathworks. I have finally succeeded in writing some code that actually outputs an image that seems to be related to what I am aiming at. The code is given the "green light" by the editor, but, when run produces many warnings. These all relate to the complaint that my code does not vectorize. Since the functions concerned are functions of two variables, I am not sure how fsurf would like me to change the code. Here is my code (called SE3):
close all; clear all; %#ok
R = 5; % centre of square is at r=R, z=0, where r is radial coord in (x,y)
%vertices of square in (x,z) plane.
A = [1,1,-1,-1,1;1,-1,-1,1,1];
figure; hold;
for x = 1:4
funx = @(ang,s) cos(ang)*(R + [cos(ang),sin(ang)]*(s*A(:,x)...
+ (1-s)*A(:,x+1)));
funy = @(ang,s) sin(ang)*(R + [cos(ang),sin(ang)]*(s*A(:,x)...
+ (1-s)*A(:,x+1)));
funz = @(ang,s)[-sin(ang),cos(ang)]*(s*A(:,x)+(1-s)*A(:,x+1));
fsurf(funx,funy,funz,[0,2*pi,0,1]);
end
hold off;
Here is the warning (only the first few lines of many warnings)
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.ParameterizedFunctionSurface>checkVectorization
In matlab.graphics.function.ParameterizedFunctionSurface/set.XFunction
In matlab.graphics.function.ParameterizedFunctionSurface
In fsurf>singleFsurf (line 263)
In fsurf>@(f1,f2,f3)singleFsurf(cax,{f1,f2,f3},extraOpts,args) (line 236)
In fsurf>vectorizeFsurf (line 236)
In fsurf (line 200)
In SE3 (line 12)
8 件のコメント
Rik
2018 年 12 月 21 日
You supressed an m-lint warning, but you shouldn't have: you are clearing a lot of things with clear all, not just variables.
Outside of debugging you should use functions to keep workspaces clean, and while debugging you should use clear variables instead.
As for the other warnings: your functions don't support vectors as inputs, which would probably speed up the process, but not fundamentally change anything in your output. I have no real suggestions for you how you could edit your functions to make them support vector (or array) inputs.
"Since the functions concerned are functions of two variables,..."
Vectorization has nothing to do with how many input arguments a function has.
"...I am not sure how fsurf would like me to change the code."
Vectorization is explained in the MATLAB documentation:
But unfortunately matrix multiplication cannot be easily vectorized, so I don't see any trivial way to vectorize that code. The warning refers to performance, so if that is not your main concern than you can ignore it or suppress it:
David Epstein
2018 年 12 月 21 日
David Epstein
2018 年 12 月 21 日
"Note that this is really an example of a single variable vectorization, namely the variable n."
Not at all, n is just an index. That example has two variables, D and H.
"It's unpleasant of fsurf to complain about lack of vectorization in my code, while omitting any mention of vectorization in the documentation"
Actually the fsurf documentation clearly states: "The function must accept two matrix input arguments and return a matrix output argument of the same size." You ignored this requirement (your functions assume scalar inputs). That requirement could be met in various ways: loops, vectorized code, arrayfun, interpolation, etc. etc.: it is not possible for the fsurf help to know what every user is doing and what is the best way to code their algorithm.
"...one would have to use meshgrid on my variables ang and s, and this would entail using something like linspace first."
Using that approach you might as well just call surf.
Rik
2018 年 12 月 21 日
I suspect that fsurf uses something like ndgrid internally if it can, so it can have a large speed increase compared to when it has to use loops internally to generate the output.
So, yes, what fsurf is asking for is a function that supports array inputs. As long as your function does not, it doesn't matter if it is an anonymous function, or a regular function.
David Epstein
2018 年 12 月 21 日
@David Epstein: personally I have never found a use for fsurf and fplot and all those other magical plotting functions. I like to know what my data is doing, which means using meshgrid or ndgrid and generating the values myself. Don't feel demoralized, just chalk it up to experience.
" It's still a puzzle to me how I would use regular functions.... In my code there are implicitly 12 distinct functions. A factor 4 for x=1:4 ..."
One way would be to note that x (and possibly others) are also variables: you don't just have a function of two variables, but a function of three (or four or five) variables, so you can write a function that with those input arguments:
function out = funX(ang,S,x,...)
out = ...
end
and then within the code you can specify those values explicitly or use define a parametrized function, e.g. within your loop:
fx = @(a,s)funX(a,s,x);
...
fsurf(fx, ...)
Thus it would be easy to bring it down to two functions by specifying the X/Y functions and inputting a function handle to distinguish:
function out = funXY(ang,S,x,fun)
out = fun(ang) .* ...;
end
So then you can specify the first factor when the function is parameterized:
fx = @(a,s)funXY(a,s,x,@cos);
fy = @(a,s)funXY(a,s,x,@sin);
...
fsurf(fx, fy, ...)
採用された回答
その他の回答 (0 件)
カテゴリ
ヘルプ センター および File Exchange で Lighting, Transparency, and Shading についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!