自动展开 matlab 矩阵的左侧
Posted
技术标签:
【中文标题】自动展开 matlab 矩阵的左侧【英文标题】:Expand left hand side of the matlab matrix automatically 【发布时间】:2014-01-07 04:46:58 【问题描述】:我希望从一个大小为零的矩阵开始,并根据方向选择在左侧或右侧继续为其分配列(行数始终是固定的)。
我正在考虑的一些选项是:
1) 向正确的方向增长矩阵,然后使用循环移位。但是如果我这样做,我需要将新矩阵与具有不同列数的现有矩阵进行 OR。
所以在这种情况下,我需要找到一种简单的方法来对我不知道的两个维度不等的矩阵进行 ORing。
2) 不知何故(我还不知道如何)我可以在 Matlab 中自动扩展矩阵的左侧,就像 Matlab 支持矩阵的右侧扩展一样,只需分配超出范围的值。
注意:我不想使用填充,因为在我的情况下它会导致很多 if-else 块。
例如
mat = [1 2 3; 4 5 6; 7 8 9]
如果方向是左并且
new_mat = [10 11; 12 13; 14 15]
appended_mat = [10 11 1 2 3; 12 13 4 5 6; 14 15 7 8 9]
请帮帮我。
谢谢。
【问题讨论】:
实际上,当我尝试编写一个简短的函数来执行一些简单的标量加法和/或乘法运算时,我发现避免使用很多if
语句很方便。不过,请务必注意代码的可读性和可维护性。如果只是要附加几次,您可能希望围绕您最终将使用的代码编写一个函数包装器。
【参考方案1】:
假设你有你现有的矩阵
mat = [1 2 3; 4 5 6; 7 8 9]
并且您想在左侧或右侧包含新行(等长),例如
new_mat = [10 11; 12 13; 14 15]
您可以使用以下方法将它们放在一起:
appended_mat = [new_mat mat]
给你
appended_mat =
10 11 1 2 3
12 13 4 5 6
14 15 7 8 9
【讨论】:
我不想使用这种方法,因为我必须写 if else 条件作为方向,然后如果它是左方向,我将使用[new_mat mat]' and if it is right direction, I will use
[mat new_mat]'。但我想避免 if-else 块。
嗯,我明白了,老实说,恐怕我不知道该怎么做。
@DEEPMALA:如果我可以问,你为什么要避免 if-else
块?你说你有选择,左或右。选择以if-else
块的形式实现。
我只是在寻找一种可以避免 if-else 的替代方法。但当然,如果我没有得到任何其他解决方案,我将只使用上述方法。【参考方案2】:
这是这个问题的一个简单的单行解决方案:
假设您有两个矩阵“旧”和“新”,direction
1 表示右边,0 表示左边。
[old new]*direction + [new old]*~direction
【讨论】:
谢谢,这真的很有帮助。我一直在寻找这样的东西。【参考方案3】:你可以这样写一个小函数:
function [ B ] = appendLR( A,newCol,direction )
Z1,2 = A;
Z1,2+direction = newCol;
B = cell2mat(Z);
end
方向是1
用于附加在右侧或-1
用于左侧。
例子:
A = reshape(1:30,5,6);
1 6 11 16 21 26
2 7 12 17 22 27
3 8 13 18 23 28
4 9 14 19 24 29
5 10 15 20 25 30
newCol = 42*ones(5,1);
42
42
42
42
42
最后:
B = appendLR(A,newCol,-1)
42 1 6 11 16 21 26
42 2 7 12 17 22 27
42 3 8 13 18 23 28
42 4 9 14 19 24 29
42 5 10 15 20 25 30
newCol
也可以是矩阵,只要行数相等,如上所述!
替代解决方案:
function [ B ] = appendLR( A,newCol,direction )
Z = [A newCol];
B = circshift(Z,[0,direction<0]);
end
同样有效。
【讨论】:
【参考方案4】:好的,我喜欢挑战 :)
%// Your matrices
mat = [1 2 3; 4 5 6; 7 8 9];
new_mat = [10 11; 12 13; 14 15];
%// You can of course re-define everything, such that your matrices are
%// defined as in this cell-array:
mats = mat new_mat;
%// Set the direction
direction = 1; %// '1' for append to-the-right
%//direction = 2; %// '2' for append to-the-left
%// Auxiliary cell array, needed to avoid 'if-else'
directions = 1:size(mats,2) size(mats,2):-1:1;
%// or, if you wrap this in a function which concatenates just 2 matrices:
%// directions = [1 2] [2 1];
%// The actual concatentation
appended_mat = horzcat(matsdirectionsdirection)
但是,老实说,我强烈建议您只使用if-else
构造。这个技巧很好(就像 thewaywewalk 的功能一样,为你 +1 先生),但它们是局促的、扭曲的、扭曲的、丑陋的、低效的、过于复杂的、难以维护的等等。等等。解决你提出的看似任意的约束的方法不使用if-else
。您想要完成的事情可以通过if-else
简单而优雅地完成。如果你不这么认为,我smell trouble;那么您当前的方法可能存在更深层次的问题。
【讨论】:
+0.5 因为我实际上也会使用 if-else 构造,所以可以将它们放在我的答案中的函数中,它不应该打扰任何人。 +0.5 用于向我透露,有类似“代码气味”的东西:D @thewaywewalk:我也更喜欢你的函数式方法,但在 MATLAB 中,我个人尽可能避免使用非内置函数。糟糕的编程实践,良好的 MATLAB 实践 :)cell2mat
和 circshift
都是 m 文件,两者的核心都是 for
-loop。这一点,再加上在循环或其他东西中调用这样的函数,可能会不必要地减慢速度。【参考方案5】:
你可以试试这样的函数句柄:
mat = [1 2 3; 4 5 6; 7 8 9]
new_mat = [10 11; 12 13; 14 15]
right = @(a,b) [a,b]
left = @(a,b) [b,a]
choice = right;
result_mat = choice(mat,new_mat)
当然,你仍然需要做出选择……
【讨论】:
以上是关于自动展开 matlab 矩阵的左侧的主要内容,如果未能解决你的问题,请参考以下文章