Running anonymous function in MATLAB for sub-mesh.
2 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
maubars
le 15 Oct 2020
Réponse apportée : Sulaymon Eshkabilov
le 18 Oct 2020
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;
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/381908/image.png)
4 commentaires
Walter Roberson
le 16 Oct 2020
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.
Réponse acceptée
Sulaymon Eshkabilov
le 18 Oct 2020
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 commentaires
Plus de réponses (0)
Voir également
Catégories
En savoir plus sur Earth, Ocean, and Atmospheric Sciences dans Help Center et File Exchange
Produits
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!