0

我需要以下简单矩阵操作的帮助。

我的输入是:

A =

    9.8627   14.6475
   65.7510   97.6500
  -48.9131  -72.6431
   65.7510   97.6500


B =

   60.3806   39.3176   39.3176   22.1663   16.1483
         0         0         0         0         0
  123.8806   80.6665   80.6665   45.4778   33.1309
         0         0         0         0         0


C =

  279.2250  275.4000  183.6000  202.7250   84.1500
         0         0         0         0         0
  518.7707  511.6642  341.1095  376.6417  156.3418
         0         0         0         0         0

然后我的matlab代码:

x_3 = size(A);
x_4 = size(B);


  for m_1 = 1:x_3(1,2);
      for n_1 = 1:x_4(1,2);


         G = A(:,m_1)+ B(:,n_1)+C(:,n_1)

      end
  end

此代码的结果:

G =

  349.4682
   65.7510
  593.7382
   65.7510


G =

  324.5802
   65.7510
  543.4176
   65.7510


G =

  232.7803
   65.7510
  372.8629
   65.7510


G =

  234.7540
   65.7510
  373.2064
   65.7510


G =

  110.1610
   65.7510
  140.5597
   65.7510


G =

  354.2531
   97.6500
  570.0081
   97.6500


G =

  329.3651
   97.6500
  519.6875
   97.6500


G =

  237.5651
   97.6500
  349.1328
   97.6500


G =

  239.5388
   97.6500
  349.4763
   97.6500


G =

  114.9458
   97.6500
  116.8296
   97.6500

但我想要的输出只是一个矩阵 G,它包含上面显示的所有十个矩阵(作为列)。所以基本上它看起来像这样:

G =  
     349.4682   324.5802    BLAH...
     65.7510    65.7510     BLAH...
     593.7382   543.3176    BLAH...
     65.7510    65.7510     BLAH...

请有人帮忙.... :(

我将不胜感激谢谢!

4

5 回答 5

1

Staying close to your original code (which isn't very efficient, but that's not what you were asking about): you just need to make sure that every loop takes you to a new column in G:

gcol = 0;
for m_1 = 1:x_3(1,2);
  for n_1 = 1:x_4(1,2);

    gcol = gcol + 1;
    G(:, gcol) = A(:,m_1) + B(:,n_1) + C(:,n_1)

  end
end

This puts each successive result in its own column.

It would be preferable to allocate the size of G before you start - that is a good habit and gets more important as the size of matrices grows (it prevents lots of copying of data "to make space for the new size"). For this you would use

G = zeros(x_3(1), x_3(1,2) * x_4(1,2));

before the nested loops.

Note - the advantage of this formulation is that you can see quite clearly what the code is doing. In my experience, 9 times out of 10 "clear code" trumps "efficient but hard to follow" code. Six months from now you would like to remember what your code does. In cases where speed really matters I will often put the "slow but clear" code in a comment, and execute the "fast but obscure" - with a test case to make sure they do in fact produce identical answers. Seems like a hassle, but it is worth the extra time. One day you will thank me...

EDIT another somewhat elegant technique would use bsxfun - as follows:

G = reshape( bsxfun(@add, reshape(A, size(A,1),1,[]), B+C), size(A,1), []);

This works because bsxfun will automatically perform the operation (add) on every dimension where one array has a singleton dimension while the other array has a non-singleton dimension - in effect performing the for loops without needing a for loop. And because no "larger" copy of the array is made, it should be marginally faster. This is probably more noticeable when A and B,C are large arrays - for the current size most of the time will go into the function overhead.

I didn't run a timing benchmark, but usually bsxfun is faster than repmat... See for example https://stackoverflow.com/a/12955706/1967396

于 2013-08-04T18:06:58.650 回答
1

您在循环的每次迭代中覆盖 G 的值:

G = A(:,m_1)+ B(:,n_1)+C(:,n_1)

您需要将新计算的行附加到 G 的现有行:

G = [G, A(:,m_1)+ B(:,n_1)+C(:,n_1)]
于 2013-08-04T13:43:22.477 回答
1

以下应该有效(但仅适用于size(B,2)=5and size(A,2) = 2):

 G = [repmat(A(:,1),1,5) repmat(A(:,2),1,5)]+ repmat(B+C,1,2);

输出是

G =

  Columns 1 through 9 

  349.4683  324.5803  232.7803  234.7540  110.1610  354.2531  329.3651  237.5651  239.5388
   65.7510   65.7510   65.7510   65.7510   65.7510   97.6500   97.6500   97.6500   97.6500
  593.7382  543.4176  372.8629  373.2064  140.5596  570.0082  519.6876  349.1329  349.4764
   65.7510   65.7510   65.7510   65.7510   65.7510   97.6500   97.6500   97.6500   97.6500

  Column 10 

  114.9458
   97.6500
  116.8296
   97.6500

如果列的顺序不是那么重要,则可以使用简短的通用解决方案:

   nA = size(A,2);
   nB = size(B,2);
   G = repmat(A,1,nB) + repmat(B+C,1,nA);

但随后列的顺序交替(首先 A(:,1) 然后 A(:,2) ...):

G =

  Columns 1 through 9 

  349.4683  329.3651  232.7803  239.5388  110.1610  354.2531  324.5803  237.5651  234.7540
   65.7510   97.6500   65.7510   97.6500   65.7510   97.6500   65.7510   97.6500   65.7510
  593.7382  519.6876  372.8629  349.4764  140.5596  570.0082  543.4176  349.1329  373.2064
   65.7510   97.6500   65.7510   97.6500   65.7510   97.6500   65.7510   97.6500   65.7510

  Column 10 

  114.9458
   97.6500
  116.8296
   97.6500

鉴于我对他们进行了速度测试的各种答案,在我的 pokey 笔记本电脑上进行了 10000 次迭代:

@LuisMendo 经过的时间是 1.906000 秒。

@TryHard 经过的时间是 1.625000 秒。(已编辑!)

@MohsenNosratinia 经过的时间是 3.985000 秒。

于 2013-08-04T13:45:46.160 回答
1

以下代码可以满足您的需求。由于您没有指定大小,因此我将其概括为:A 和 B 可以有任意数量的列。假设 B 和 C 具有相同的大小,当然 A、B、C 需要具有相同的行数。

D = B+C;
numA = size(A,2);
numB = size(B,2);

sol = reshape(repmat(A,numB,1),size(A,1),size(A,2)*numB) + repmat(D,1,numA)
于 2013-08-04T13:51:43.193 回答
1

你可以要求kron函数为你做所有的重复

G = kron(A, ones(1,size(B,2)))+kron(ones(1,size(A,2)),B+C);
于 2013-08-04T16:09:12.310 回答