Running anonymous function in MATLAB for sub-mesh.

2 ビュー (過去 30 日間)
maubars
maubars 2020 年 10 月 15 日
回答済み: Sulaymon Eshkabilov 2020 年 10 月 18 日
Is it possble to vectorize annonymous functions in Matlab. Suppossing I wish to place and run an annoymous repeatedly on designated positions of a big, mesh, running the function at specific chunks of the mesh. For example, if I have a 2D meshgrid of size 1000 by 1000 mesh and I wish to run a annoymous function repeatedly along the centre line skiping random steps like x = [20 30 50 100 ..... and y = [0 0 0 .. to generate multiple shapes or forms, like circles around some centerline without the use of a loop. How can i run such a function at the randow x and y coordinate points?The figure below displays a desirable output from such a scenerio. Take note that the x cordinates spacing between the circle centers are not regular.
N=200
[X,Y]= meshgrid(linspace(1,1000,N),linspace(-500,500,N));
% I skipped a step for selectin the chunks here...
% Submesh selection
x1=X(:,20:30); x2=X(:,30:50); x3=X(:,50:100); x4=X(:,100:end);
y1=Y(:,20:30); y2=Y(:,30:50); y3=Y(:,50:100); y4=Y(:,100:end);
% I select the center line positions
centers_x = x1(100,5);
centers_y = y1(100,5);
% the below functions should be mapped to the cicle based on the centers line positions
func1 = @(centers_x) (radius*cos(angles)+centers_x);
func2 = @(centers_y) (radius*sin(angles)+centers_y);
x = func1(centers_x);
y = func2(centers_y);
plot(x, y, 'b-', 'LineWidth', 2);
hold on;
  4 件のコメント
Walter Roberson
Walter Roberson 2020 年 10 月 16 日
You do not need to do symbolic work. I was especially referring you to the paragraphs starting with "When an anonymous function is built," which talks about the variables being saved along with the handle.
Other than the saved variables, anonymous functions are pretty much the same as regular functions.
Imagine taking your function
func1 = @(centers_x) (radius*cos(angles)+centers_x);
and rewriting it to
function result = func1(centers_x, varargin)
persistent radius angles
if nargin > 1
radius = varargin{1};
angles = varargin{2};
end
result = (radius*cos(angles)+centers_x);
end
and then right at the point you would have defined the anonymous function, put in a call
func1([], radius, angles);
to cause the values of radius and angles to be saved inside func1.
and after that make regular calls to func1, passing in only one argument.
Here is the important part: the anonymous function is exactly as vectorized as the full function would be, no more and no less.
There is nothing magical or restricted about vectorization in anonymous function handles: either what you pass in to the anonymous function is compatible size with the captured variables, or else it isn't and you get an error -- exactly the same as if it were a regular function that had (somehow) had access to the captured variables.
Your centers_x and centers_y are 100 x 5. You do not show the size of radius or angles. If radius and angles are scalars, then you would get out 100 x 5 results. If your radius or angles are empty, you would get out empty results. If your radius is an M x N matrix and your angles is N x P then radius*angles would be matrix multiplication giving an M x P result, and that would be compatible with addition with 100 x 5 if M = 100 and P = 5 -- e.g., radius could be 100 x 17 and angles could be 17 x 5 and the calculations would work out. If radius is a scalar and you want to angles to be non-scalar and you want one result for each entry in angles, then make angles a 1 x 1 x M vector, and then with scalar radius, radius*cos(angles) would be 1 x 1 x M and you could add the 100 x 5 centers_x to it.
It's all the same as regular functions, other than the way that values of variables are captured at the time of the definition of the anonymous function.
maubars
maubars 2020 年 10 月 17 日
Thanks on the comment and info. I think I will have to redajust the code accordingly.

サインインしてコメントする。

採用された回答

Sulaymon Eshkabilov
Sulaymon Eshkabilov 2020 年 10 月 18 日
Hi,
Here is one of the viable solutuons to your exercise using the function option:
clearvars
% Number of circles to draw
N=10;
% The center line positions along x and y axes:
C_x = linspace(0, 200, N);
C_y = zeros(size(C_x));
R=10;
angles=linspace(0, 2*pi, 360);
[X, Y] = Circle(C_x, C_y, R);
for ii=1:numel(C_x)
plot(X(ii,:), Y(ii,:), 'LineWidth', 2); axis equal
hold all;
text(C_x(ii), C_y(ii), num2str(ii))
end
grid on
% Function file within M-file:
function [X, Y] = Circle(C_x, C_y,varargin)
if nargin ==2
angles=linspace(0, 2*pi, 100);
R=10;
elseif nargin ==3
angles=linspace(0, 2*pi, 100);
R=varargin{1};
else
R=varargin{1};
angles=varargin{2};
end
X= (R*sin(angles)+C_x(:));
Y= (R*cos(angles)+C_y(:));
end

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeEarth, Ocean, and Atmospheric Sciences についてさらに検索

製品

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by