通过乘以向量将2D矩阵扩展为3D矩阵

时间:2016-02-22 13:23:59

标签: arrays matlab matrix multidimensional-array

这就是我想要实现的目标:

我有一个矩阵C

C=[1 2 3; 4 5 6; 7 8 9];

一个向量a

a=[1 2];

我想做一个这样的操作,a向量的每个元素乘以C(标量乘法),然后出现一个三维数组D:< / p>

(:,:,1) =

     1     2     3
     4     5     6
     7     8     9


(:,:,2) =

     2     4     6
     8    10    12
    14    16    18

它肯定会在循环中起作用,但是,由于我需要多次使用此操作,因此oneliner将是一个很好的保护程序。

5 个答案:

答案 0 :(得分:10)

这是使用bsxfunreshape的一个很好的例子。虽然@thewaywewalks建议先调用bsxfun并重新调整结果,但我建议相反。这使得bsxfun的一个关键概念 - 单身维度扩展 - 更加明确:

out = bsxfun(@times,C,reshape(a,1,1,[]))

ans(:,:,1) =

     1     2     3
     4     5     6
     7     8     9


ans(:,:,2) =

     2     4     6
     8    10    12
    14    16    18

使用reshape(a,1,1,[]),您可以将a置于第三维度。如果您现在应用bsxfun,则会将矩阵Ca的每个元素相乘。

答案 1 :(得分:6)

一些reshape'和一些bsxfun会:

 useParameterConverters(new ParameterConverters().addConverters(new ParameterConverters.ExamplesTableConverter(new ExamplesTableFactory(new LoadFromClasspath(this.getClass())))))

正如hbaderts answer中所建议的那样,人们也可以使用var balance = localStorage.getItem('balance'); if (balance === null) { // Not found, set value from database or wherever you get the value balance = 50; // Or whatever value } else { balance = +balance; // Convert the retrieved value to a number, since localStorage stores everything as string. } // After manipulating the balance, etc... newBalance = balance - 20; // Assuming the user just used up 30 credits localStorage.setItem('balance', newBalance); 维度扩展的能力,并提供一系列因素的置换:

out = reshape(bsxfun(@mtimes, C(:), a(:).'), [size(C),numel(a)] )
bsxfun

答案 2 :(得分:6)

我有基准比较的另一种方法...... IMO这是最好的方式,至少在语法/可读性方面是这样的:

out = reshape(kron(a,C),[size(C),numel(a)]);

out(:,:,1) =

     1     2     3
     4     5     6
     7     8     9


out(:,:,2) =

     2     4     6
     8    10    12
    14    16    18

答案 3 :(得分:4)

编辑(基准测试):由于已经提出了几种解决方案(包括我的下面),这里有一些粗略的基准测试来比较不同的解决方案,使用更大的阵列:

a=1:10;
N=1000; timers=zeros(N,6);
for ii=1:N; C=rand(400);
  tic; out = repmat(C,[1,1,numel(a)]).*reshape(repelem(a,size(C,1),size(C,2)),[size(C),numel(a)]); timers(ii,1)=toc;
  tic; out = bsxfun(@times,C,reshape(a,1,1,[])); timers(ii,2)=toc;
  tic; out = reshape(C(:)*a, size(C,1), size(C,2), numel(a)); timers(ii,3)=toc;
  tic; out = bsxfun(@mtimes,C,permute(a,[3,1,2])); timers(ii,4)=toc;
  tic; out = reshape(bsxfun(@mtimes, C(:), a(:).'), [size(C),numel(a)] ); timers(ii,5)=toc; 
  tic; out = reshape(kron(a,C),[size(C),numel(a)]); timers(ii,6)=toc;
end;

mean(timers)

ans =

    0.0080863    0.0032406    0.0041718     0.015166    0.0074462    0.0033051

......暗示@hbaderts解决方案最快,然后是@Adiel's,然后是@Luis Mendo's,然后是@thewaywewalk(1),然后是我的,然后是@thewaywewalk(2)。

我的解决方案:

另一种选择,使用repmatreshape(无bsxfun):

out = repmat(C,[1,1,numel(a)]).*reshape(repelem(a,size(C,1),size(C,2)),[size(C),numel(a)])

out(:,:,1) =

 1     2     3
 4     5     6
 7     8     9

out(:,:,2) =

 2     4     6
 8    10    12
14    16    18

这是两个数组的逐元素乘法。第一个是你的原始矩阵C在第三维中重复numel(a)次:

repmat(C,[1,1,numel(a)])

ans(:,:,1) =

 1     2     3
 4     5     6
 7     8     9

ans(:,:,2) =

 1     2     3
 4     5     6
 7     8     9

第二个与第一个相同,每个切片包含a的相应元素:

reshape(repelem(a,size(C,1),size(C,2)),[size(C),numel(a)])

ans(:,:,1) =

 1     1     1
 1     1     1
 1     1     1

ans(:,:,2) =

 2     2     2
 2     2     2
 2     2     2

答案 4 :(得分:4)

另一种可能性是使用C a作为列向量时间out = reshape(C(:)*a, size(C,1), size(C,2), numel(a)); 作为行向量(这给出了所有按元素的产品),然后matrix multiplication结果:

object[]