How can I vectorize a function?
現在この質問をフォロー中です
- フォローしているコンテンツ フィードに更新が表示されます。
- コミュニケーション基本設定に応じて電子メールを受け取ることができます。
エラーが発生しました
ページに変更が加えられたため、アクションを完了できません。ページを再度読み込み、更新された状態を確認してください。
古いコメントを表示
The function I want to vectorize is Cross-in-Tray Function (2-D):
f(X,Y) = -0.0001*(abs(sin(X)*sin(Y)*exp(abs(100-sqrt(X^2+Y^2)/pi)))+1)^0.1;
I want to use the command (to plot the function):
fsurf(@(x,y) crossintrayfcn([x,y]))
I have this two function codes:
function z = crossintrayfcn(xx)
x = xx(:,1);
y = xx(:,2);
expcomponent = abs(100-(sqrt(x.^2 + y.^2)/pi));
z = -0.0001*((abs(sin(x).*sin(y).*exp(expcomponent))+1).^0.1);
end
And:
function [y] = crossintrayfcn(xx)
x1 = xx(1);
x2 = xx(2);
fact1 = sin(x1)*sin(x2);
fact2 = exp(abs(100 - sqrt(x1^2 + x2^2)/pi));
y = -0.0001 * (abs(fact1*fact2) + 1)^0.1;
end
But they plot nothing!
Thanks!
採用された回答
Star Strider
2018 年 3 月 1 日
Vectorising it simply requires using element-wise operations:
f = @(X,Y) -0.0001*(abs(sin(X).*sin(Y).*exp(abs(100-sqrt(X.^2+Y.^2)/pi)))+1).^0.1;
[x,y] = meshgrid(linspace(-10, 10, 49));
figure
surfc(x, y, f(x,y))
grid on
9 件のコメント
David Franco
2018 年 3 月 1 日
Thanks for the reply Star Strider. But when I use your code inside a function:
fsurf(@(x,y) crossintrayfcn([x,y]))
Where:
function Z = crossintrayfcn(xx)
X = xx(:,1);
Y = xx(:,2);
Z = -0.0001*(abs(sin(X).*sin(Y).*exp(abs(100-sqrt(X.^2+Y.^2)/pi)))+1).^0.1;
end
I got the warning:
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.
And the plot shows nothing, like the codes I posted before...
I want to plot without using pre-defined X and Y. Just like:
fsurf(@(x,y) sin(x)+cos(y))
Directly, without using meshgrid...
Star Strider
2018 年 3 月 1 日
My pleasure.
I have no idea what you are doing.
For whatever reason, fsurf (that will throw the error you quoted, although it did not throw the error when I used it) will not plot your function, although fcontour and ezsurf have no problem with it:
f = @(X,Y) -0.0001*(abs(sin(X).*sin(Y).*exp(abs(100-sqrt(X.^2+Y.^2)/pi)))+1).^0.1;
figure(2)
fcontour(f, [-6 6 -6 6])
figure(3)
ezsurf(f, [-6 6 -6 6])
Use these instead. You might want to report the inability of fsurf (and fmesh) to plot your function, while fcontour and ezsurf will, as a bug. Use the Contact Us link in the upper right corner of this page to do it.
The meshgrid function (that the plotting functions likely use internally anyway) is the preferred approach, since it gives you more control over the mesh size.
David Franco
2018 年 3 月 2 日
Indeed I have a problem with fsurf command:
When I use
fsurf(@(x,y) ackleyfcn([x,y]),[-32 32 -32 32])
I got this warning:
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.
And this picture (after a long time, about 20 sec):

When I use
ezsurf(@(x,y) ackleyfcn([x,y]),[-32 32 -32 32])
I got no warning and the correct (and fast) picture:

Where:
function z = ackleyfcn(xx)
% Ackley's function
% Search domain: [-32,32]
% Global minimum: f(x) = 0 | x = (0,...,0)
d = size(xx, 2);
xx = max(-32,min(32,xx));
z = -20*exp(-0.2*sqrt(1/d*sum(xx.^2,2))) - exp(1/d*sum(cos(2*pi*xx),2)) + 20 + exp(1);
end
I think this Ackley's function is correctly vectorized. Am I right?
I don't know what is the error with fsurf.
Ps.: I am using R2017b version.
Star Strider
2018 年 3 月 2 日
It seems to be.
You’ve written it as a function of one variable, and to create the variable you’re horizontally concatenating two arrays to create the single variable. This may be confusing fsurf.
I’ve not examined the code for either fsurf or ezsurf, so I don’t know for sure how they work. Both apparently use meshgrid to create the matrix function arguments they send to the argument function.
I understand that ezsurf will be deprecated and replaced by fsurf, so it would probably be best for you to bring this behavior to the attention of MathWorks. It would seem that fsurf needs to be improved somewhat before ezsurf disappears. Your approach (that appears to be valid) may not be designed into fsurf.
Include the URL to this thread in your message to MathWorks, so you don’t have to repeat everything.
David Franco
2018 年 3 月 5 日
I got a MathWorks' Support Response:
I have been able to reproduce the slow down that you were experiencing. The fsurf function tries to determine what density of points to use in order to give an accurate depiction of the function you pass it. Since the ackleyfcn has many small oscillations, fsurf decides to use a very dense mesh in order to display it. This feature is not available in ezsurf which is why the plots look so different.
The time fsurf takes is also much longer because if it displaying many more points. If you would like to use fsurf to produce the plot similar to ezplot, you can turn off the AdaptiveMeshDenstity feature by using the following line of code:
set(fsurf(@(x,y) ackleyfcn([x,y]),[-32 32 -32 32]),'AdaptiveMeshDensity',0,'MeshDensity',60)
Note that this will increase the speed of fsurf and will produce a plot similar to that of ezsurf. However, this new surface uses fewer points and so does not fully represent the ackleyfcn function.
Star Strider
2018 年 3 月 5 日
Thank you for your efforts.
Interesting that in the FunctionSurface Properties (link) 'MeshDensity' is listed, though 'AdaptiveMeshDensity' is not.
I just finished reading your other post about this. Since you reproduced that text in its entirety here, I have not linked to it.
This is useful information. I am tagging your other post with ‘yair altman’ (who has the ‘Undocumented MATLAB’ site) so he will see it.
David Franco
2018 年 3 月 5 日
Yes, this stuff is priceless and my suspicion has been confirmed:
That most beautiful figure produced by ezsurf is not as accurate as the figure produced by fsurf.
We were being deceived :)
Yair Altman
2018 年 3 月 24 日
@StarStrider - thanks, duly noted
Star Strider
2018 年 3 月 24 日
@Yair — My pleasure.
その他の回答 (1 件)
David Franco
2018 年 3 月 5 日
Because of the above problems I'm using my own function with surfc to replace fsurf:
function z = plotfcn(fcn,range,grid,shad)
% PLOTFCN evaluate and plot a 3D function
% INPUT:
% FCN - @myFunction (function handle)
% RANGE - [x1min x1 max x2min x2max] (default = [-10 10 -10 10])
% GRID - grid size for the function evaluation (default = 101)
% SHAD - set color shading properties (default = 0)
% 0 = faceted (continued colormap with black mesh lines)
% 1 = interp (interpolated colormap)
% 2 = flat (continued colormap)
% OUTPUT:
% Z - function eval (GRID x GRID)
% EXAMPLE:
% z = plotfcn2(@ackleyfcn, [-32 32; -32 32], 200, 1);
switch nargin
case 4
case 3
shad = 0;
case 2
shad = 0;
grid = 101;
case 1
shad = 0;
grid = 101;
range = [-10 10 -10 10];
otherwise
disp('Not enough input arguments. Function required.')
return
end
x1 = meshgrid(linspace(range(1,1), range(1,2), grid));
x2 = meshgrid(linspace(range(1,3), range(1,4), grid))';
xx = [x1(:),x2(:)];
f = fcn(xx);
f = reshape(f,size(x1));
if nargout == 1
z = f;
end
figure
surfc(x1,x2,f)
title([func2str(fcn), ' [x,y]'])
colormap jet
if shad == 1
shading interp
elseif shad == 2
shading flat
end
end
カテゴリ
ヘルプ センター および File Exchange で Surface and Mesh Plots についてさらに検索
参考
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!Web サイトの選択
Web サイトを選択すると、翻訳されたコンテンツにアクセスし、地域のイベントやサービスを確認できます。現在の位置情報に基づき、次のサイトの選択を推奨します:
また、以下のリストから Web サイトを選択することもできます。
最適なサイトパフォーマンスの取得方法
中国のサイト (中国語または英語) を選択することで、最適なサイトパフォーマンスが得られます。その他の国の MathWorks のサイトは、お客様の地域からのアクセスが最適化されていません。
南北アメリカ
- América Latina (Español)
- Canada (English)
- United States (English)
ヨーロッパ
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
