我有一个名为[U,V,W] = my_function(x,y,z)
的函数,它将网格向量作为输入,并计算在这些网格点上评估的一些输出。总共有N
个网格点。
问题是我希望我的函数能够容忍不同大小的输入。比如说,
THIS:
[Y,Z] = meshgrid(0:10,-10:20); X = 6.3;
OR THIS:
[X,Y,Z] = meshgrid(0:10,-10:20,-2:2);
OR THIS:
Z = linspace(-1,1,10); X = 4.2; Y = 1;
etc
但在函数内部,我需要将x y z变量转换为一个3 x N
数组,如下所示:
r = [X(:) Y(:) Z(:)]
(this因为我需要应用一些旋转矩阵,然后在旋转坐标上做一些进一步的操作)。如果X、Y和Z的大小不同,则此操作不起作用。
我试着做了一个辅助函数来预处理坐标,如下面的MWE所示,但它相当混乱。我想知道是否有一个更简洁/更干净/更标准的方法来实现这一点?
x = linspace(-10,10,100);
Y = 3;
z = linspace(-12,12,80);
[X,Z] = meshgrid(x,z);
[U,V,W] = my_function(X,Y,Z);
%%% MAIN FUNCTION %%%
function [U,V,W] = my_function(X,Y,Z)
[X,Y,Z] = preprocess_gridvectors(X,Y,Z); % Make sure grid vectors are all same size
N1 = size(X,1); N2 = size(X,2); N3 = size(X,3);
X = X(:); Y = Y(:); Z = Z(:);
%%% Do some transformation and processing here (rotate coordinates and use them)
R = [cos(pi) -sin(pi) 0;sin(pi) cos(pi) 0;0 0 1]; rotXYZ = R*[X Y Z].';
U = rotXYZ(1,:); V = rotXYZ(2,:); W = rotXYZ(3,:);
%%%
% Put the outputs back into the same shape as the original inputs
U = reshape(U, N1,N2,N3);
V = reshape(V, N1,N2,N3);
W = reshape(W, N1,N2,N3);
end
%%% HELPER FUNCTION %%%
function [X,Y,Z] = preprocess_gridvectors(X,Y,Z)
unique_array_sizes = unique([size(X) size(Y) size(Z)]); % Determine dimensions to use
unique_array_sizes(unique_array_sizes==1) = []; % Disregard scalar dimension
N_expected = prod(unique_array_sizes); % Total number of unique grid points expected
sizes = zeros(3,3);
if numel(X)==N_expected % X already has the right dimensions
sizes(1,1) = size(X,1); % Get the dimensions of X
sizes(1,2) = size(X,2);
sizes(1,3) = size(X,3);
end
if numel(Y)==N_expected % Y already has the right dimensions
sizes(2,1) = size(Y,1);
sizes(2,2) = size(Y,2);
sizes(2,3) = size(Y,3);
end
if numel(Z)==N_expected % Z already has the right dimensions
sizes(3,1) = size(Z,1);
sizes(3,2) = size(Z,2);
sizes(3,3) = size(Z,3);
end
inds = sizes~=0; % Anything which is non-zero has correct dimensions already
ind_dir = find(inds(:,1),1); % Choose the first axis that has good dimensions
% These should be the correct final dimensions now
N1 = sizes(ind_dir,1);
N2 = sizes(ind_dir,2);
N3 = sizes(ind_dir,3);
if ~any(sizes(1,:)) % X direction needs replicating
X = repmat(X,[N1 N2 N3]);
end
if ~any(sizes(2,:)) % Y direction needs replicating
Y = repmat(Y,[N1 N2 N3]);
end
if ~any(sizes(3,:)) % Z direction needs replicating
Z = repmat(Z,[N1 N2 N3]);
end
end
1条答案
按热度按时间8qgya5xd1#
你可以让implicit expansion为你做这些工作:
这使用了一些不必要的算术运算(即,乘以0,然后相加),但所需的计算时间可能可以忽略不计。