我有矩阵:
a= 0.8147 0.1270 0.6324
0.9058 0.9134 0.0975
b= 0.2785 0.9649 0.9572
0.5469 0.1576 0.4854
0.9575 0.9706 0.8003
c = 0.1419 0.7922
0.4218 0.9595
0.9157 0.6557
我还有另一个矩阵
I= 1 3 1 1
2 1 3 2
我希望得到d
矩阵
d= a(1,3) b(3,1) c(1,1)
a(2,1) b(1,3) c(3,2)
其中索引是I
矩阵的两个连续条目
这是我得到的一个例子。但是,我为a,b,c,..
和I
获得了不同的大小矩阵。
已添加:I
为m x (n+3)
,其中包含索引,其他(n+2)
矩阵的相应条目为X,A1,A2,...,An,Y
。提供n
后,会生成A1,A2,...,An
个矩阵。
有人可以帮我写一下这个任务的Matlab代码吗?
答案 0 :(得分:1)
通常,矩阵不会被解释为索引列表,但如果使用sub2ind,则可以使用此矩阵。要使用它,您需要要处理的矩阵的大小。让我们以一个例子开头:
a(sub2ind(size(a), I(:,1), I(:,2)))
如果您首先将新生成的矩阵分配给变量名,则代码不会更改。
将使用列I(:,1)
作为行,I(:,2)
作为列。
为了使代码更具可读性,您可以定义执行此操作的匿名函数,让我们将其称为idx:
idx = @(m,I,i)(sub2ind(size(m), I(:,i), I(:,i+1)))
所以最后代码将是
d = [a(idx(a,I,1)), b(idx(b,I,2)), c(idx(c,I,3))]
如果您首先将新生成的矩阵分配给变量名,则代码不会更改。
其他详情
让我们以2个中心矩阵为例:
a = rand(3,1) % 3 rows, 1 column
b = rand(3,3) % 3 rows, 3 columns
c = rand(3,3) % another squared matrix
d = rand(3,1) % 3 rows, 1 column
匿名函数的定义是相同的,您只需更改输出向量的定义:
output = [a(idx(a,I,1)), b(idx(b,I,2)), c(idx(c,I,3)), d(idx(d,I,3))]
请注意,遵循该模式,您始终需要一个I
矩阵,其中包含(n_matrices + 1)
列。
概括
让我们将这个代码推广到n个大小为rxr的中心矩阵和#34; side matrices"大小为rxc。我将在这个例子中使用这些参数的一些值,但你可以使用你想要的。
让我生成一个使用示例:
r = 3;
c = 4;
n = 3;
a = rand(r,c); % 2D array
b = rand(r,r,n); % 3D array, along z = 1:n you have 2D matrices of size rxr
c = rand(r,c);
I = [1 3 1 2 1 3; 2 1 3 1 1 1];
我编写的代码很容易使用cat
扩展来追加矩阵(注意函数中的2告诉MATLAB追加列的方向)和for循环:
idx = @(m,I,i)(sub2ind(size(m), I(:,i), I(:,i+1)))
d = a(idx(a,I,1));
for i = 1:n
temp = b(:,:,i);
d = cat(2,d,temp(idx(tmp,I,i+1)));
end
d = cat(2,d,c(idx(c,I,n+1)));
如果你真的不想解决任何问题"手动",你可以使用单元格数组将所有矩阵放在一起,然后循环地将匿名函数应用于单元格数组中的每个矩阵。
答案 1 :(得分:1)
您可以使用varargin
执行此操作。假设你的矩阵是按照你想要的方式构建你想要的输出(根据Carmine's answer更新):
function out = IDcombiner(I, varargin)
out = zeros(size(I, 1), nargin-1);
idx = @(m, I, ii) (sub2ind(size(m), I(:, ii), I(:, ii+1)));
for ii = 1:1:nargin-1
out(:, ii) = varargin{ii}(idx(varargin{ii}, I, ii));
end
现在使用此功能,您可以在灵活的输入数量上进行选择:
out = IDcombiner(I, a, b, c)
out =
0.6324 0.9575 0.1419
0.9058 0.9572 0.6557
还有一个单行解决方案,我不推荐,因为它大大降低了代码的可读性,并没有帮助你获得更多收益:
IDcombiner = @(I,varargin) ...
cell2mat(arrayfun(@(x) varargin{x}(sub2ind(size(varargin{x}), ...
I(:,x), I(:,x+1))), 1:nargin-1, 'UniformOutput', false));