按变量分组重新排序矩阵列

时间:2015-04-17 16:24:06

标签: matlab matrix vector

我正在编写一个旋转矩阵函数,我希望使用矢量输入。目标是为矢量"角度"中的每个角度返回旋转矩阵的单元阵列。但是,当给定向量输入时,余弦和正弦函数返回行数组,因此进入mat2cell调用的最终矩阵需要根据" angle"的大小重新排列其列,即具有正确的每个输入角度3列。以下是输入,函数调用,函数和结果的示例。

angle = [0 90];
RotZ(angle);

致电RotZ

function [ rot ] = RotZ(angle)
%RotX Rotation matrix about Z axis
%   Generates a rotation matrix about Z axis for the  given angle in
%   degrees
angle = deg2rad(angle);

rot =   [cos(angle)           -sin(angle)         zeros(size(angle));...
         sin(angle)           cos(angle)          zeros(size(angle));...
         zeros(size(angle))   zeros(size(angle))  ones(size(angle))];
break
  if size(angle,2)>1
    rot = mat2cell(rot,3,3*ones(size(rot,2)/3,1));
  end
end

返回矩阵rot :(在mat2cell调用之前)

rot =

    1.0000    0.0000         0   -1.0000         0         0
         0    1.0000    1.0000    0.0000         0         0
         0         0         0         0    1.0000    1.0000

我需要一种通用的方法来对每个第1 + n列进行分组,其中n是" angle"中元素的数量。双元素向量的正确矩阵"角度"应该列有[1 3 5]和[2 4 6]的列。对于两个角度输入,这是微不足道的,但我不知道如何推广更大尺寸的矢量"角度"即角度= [0 45 90等...]

1 个答案:

答案 0 :(得分:0)

尝试使用arrayfun并迭代angle中的每个值,而不是尝试对每列中的哪些索引进行分组或确定以构建旋转矩阵。通过此,您可以指定uni=0标志以输出单元阵列。我宁愿这样做,因为mat2cell本质上使用了for循环。如果您要这样做,您也可以使用arrayfun,并且使用循环更为明智。

尝试做这样的事情:

function [ rot ] = RotZ(angle)
%RotX Rotation matrix about Z axis
%   Generates a rotation matrix about Z axis for the  given angle in
%   degrees
angle = deg2rad(angle);

f = @(x)[cos(x) -sin(x) 0;...
         sin(x) cos(x) 0;...
         0 0 1];

rot = arrayfun(f, angle, 'uni', 0);

end

rot将包含一个3 x 3旋转矩阵的单元格数组,用于存储在angle中的每个角度。 BTW,angle是MATLAB中的一个实际函数,因此以这种方式调用变量会无意中影响命令本身,所以如果你想稍后使用它,你将无法实现。


这是一个给出一堆角度的示例运行:

ang = [0 30 60 90 120];
rot = RotZ(ang);

我们得到:

>> celldisp(rot)

rot{1} =

     1     0     0
     0     1     0
     0     0     1



rot{2} =

    0.8660   -0.5000         0
    0.5000    0.8660         0
         0         0    1.0000



rot{3} =

    0.5000   -0.8660         0
    0.8660    0.5000         0
         0         0    1.0000



rot{4} =

    0.0000   -1.0000         0
    1.0000    0.0000         0
         0         0    1.0000



rot{5} =

   -0.5000   -0.8660         0
    0.8660   -0.5000         0
         0         0    1.0000

但是,如果您希望按照自己的方式进行操作,我们可以生成索引矩阵,其中每列对应于您需要从矩阵中采样的列的顺序。您可以通过指定13M的向量轻松实现这一目标,其中Mangle中元素的总数。之后,使用reshape。例如,假设我们有两个矩阵,你可以这样做:

>> M = 2;
>> ind = reshape(1:3*M, M, []).'

ind =

     1    2   
     3    4 
     5    6

同样在M = 3

>> M = 3;
>> ind = reshape(1:3*M, M, []).'

ind =

     1     2     3
     4     5     6
     7     8     9

如您所见,每列有三个值,因为我们需要三列来构建旋转矩阵,每个值彼此相距M。这些值用于构造要从较大矩阵rot采样的旋转矩阵。此外,维护每个矩阵所需的确切顺序。接下来,我们可以执行矩阵rot重新排序,以便三列的每个连续块对应于特定的旋转矩阵。然后,您可以在此重新排序的矩阵上调用mat2cell

rot = rot(:, ind(:));
rot = mat2cell(rot, 3, 3*ones(M,1));

第一行有点棘手,但我们无法处理。我们正在访问rot的所有行,但我们想要从rot中选择我们想要的列,并且我们希望将它们按特定顺序放置。通过执行ind(:),我们将矩阵ind展开到一个向量中,其中ind的列从左列堆叠到彼此之上右栏,直到我们得到一个单一的向量。一旦我们这样做,ind中每个不同值的三元组对应于我们需要从中创建重新排序矩阵的rot的右列。结果将是您的大rot矩阵,但是不同列的连续三元组会产生您希望angle的每个值所需的特定旋转矩阵。最后一个电话很简单。只需使用mat2cell并将矩阵拆分为三个块,并将每个块放入一个单元阵列中。

通过运行此功能,您还可以获得我们上面所做的操作。为了完成图片,这里有你的功能:

function [ rot ] = RotZ(angle)
%RotX Rotation matrix about Z axis
%   Generates a rotation matrix about Z axis for the  given angle in
%   degrees
angle = deg2rad(angle);

rot =   [cos(angle)           -sin(angle)         zeros(size(angle));...
         sin(angle)           cos(angle)          zeros(size(angle));...
         zeros(size(angle))   zeros(size(angle))  ones(size(angle))];

M = numel(angle);
ind = reshape(1:3*M, M, []).';
rot = rot(:, ind(:));
rot = mat2cell(rot, 3, 3*ones(M,1));

end