Matlab:对 for 循环内列的算术运算(简单而狡猾!



我试图表示一个简单的矩阵 m*n(假设它只有一行!),使得 m1n1 = m1n1^1, m1n2 = m1n1^2, m1n3 = m1n1^3, m1n3 = m1n1^4, ...m1ni = m1n1^i.换句话说,我正在尝试遍历矩阵列 n 次以在末尾添加新的向量(列),以便每个索引具有与第一个向量相同的值,但提高到其列号 n 的幂。

这是原始向量:

v =
    1.2421
    2.3348
    0.1326
    2.3470
    6.7389
and this is v after the third iteration:

v = 
    1.2421    1.5429    1.9165
    2.3348    5.4513   12.7277
    0.1326    0.0176    0.0023
    2.3470    5.5084   12.9282
    6.7389   45.4128  306.0329
now given that I'm a total noob in Matlab, I really underestimated the difficulty of such a seemingly easy task, that took my almost a day of debugging and surfing the web to find any clue. Here's what I have come up with:

rows = 5;
columns = 3;
v = x(1:rows,1);
k = v;
Ncol = ones(rows,1);
extraK = ones(rows,1);
disp(v)
for c = 1:columns
    Ncol = k(:,length(k(1,:))).^c; % a verbose way of selecting the last column only.
    extraK = cat(2,extraK,Ncol);
end
k = cat(2,k,extraK);
disp(extraK(:,2:columns+1)) % to cut off the first column

现在,此代码(出于某种奇怪的原因)仅在行 = 6 或更少且列 = 3 或更少时才有效。

当行 = 7 时,这是输出:

v = 1.0e+03 *

0.0012    0.0015    0.0019
0.0023    0.0055    0.0127
0.0001    0.0000    0.0000
0.0023    0.0055    0.0129
0.0067    0.0454    0.3060
0.0037    0.0138    0.0510
0.0119    0.1405    1.6654

如何让它在任意数量的行和列上运行?

谢谢

我发现你的代码有几个问题:

  1. 我不确定你为什么要定义d = 3;. 这只是吹毛求疵,但您可以安全地将其从代码中删除。
  2. 您没有正确执行电源操作。 具体来说,请看以下语句:

    Ncol = k(:,length(k(1,:))).^c; % a verbose way of selecting the last column only.
    

    有选择地选择最后一列,这很好,但您没有正确应用电源操作。 如果我理解你的说法,你希望采用原始向量,并对n的幂执行幂运算,其中n是当前迭代。 因此,您实际上只需要这样做:

    Ncol = k.^c;
    

    Ncol替换为上述行后,代码现在应该可以工作了。 我还注意到您裁剪了结果的第一列。 您获得重复列的原因是因为您的for循环从 c = 1 开始。 由于您已经计算了v.^1 = v,因此您可以在 c = 2 处开始循环。 将循环起点更改为 c = 2 ,您可以摆脱删除第一列。


但是,我将在一行代码中以另一种方式执行此操作。 在我们这样做之前,让我们先来看看你想做什么的理论。

给定一个向量v,该向量是长期存储在m x 1向量中的m元素,您想要的是有一个大小为 m x n 的矩阵,其中 n 是所需的列数,对于从左到右开始的每一列,您希望将v带到 n 方。

因此,给定您在第三次"迭代"中的示例,第一列表示v,第二列表示v.^2,第三列表示v.^3


我将向您介绍bsxfun的力量。 bsxfun代表 Binary Singleton EXpansion 函数。 bsxfun的作用是,如果有两个输入,其中一个或两个输入都具有单例维度,或者如果两个输入中的任何一个只有一个维度的值为 1,则每个输入都在其单例维度中复制以匹配另一个输入的大小,然后将元素操作一起应用于这些输入以生成输出。

例如,如果我们有两个这样的向量:

A = [1 2 3]
B = [1
     2
     3]

请注意,其中一个是行向量,另一个是列向量。 bsxfun会看到AB都具有单例维度,其中A的单例维度是行数为 1,B具有单例维度,即列数为 1。 因此,我们将复制B A中尽可能多的列,并复制B中尽可能多的行的A,我们实际上得到:

A = [1 2 3
     1 2 3
     1 2 3]
B = [1 1 1
     2 2 2
     3 3 3]

一旦我们有了这两个矩阵,您就可以对这些矩阵应用任何元素明智的操作来获得您的输出。 例如,您可以加、减、取幂或进行元素明智的乘法或除法。


现在,此方案如何应用于您的问题如下。 你正在做的是你有一个向量v,你将有一个像这样的幂矩阵

M = [1 2 3 ... n
     1 2 3 ... n
     ...........
     ...........
     1 2 3 ... n]

从本质上讲,我们将有一列 1 秒,然后是一列 2 秒,最多可以n任意数量的列。 我们将bsxfun应用于向量v,这是一个列向量,另一个向量只是从 1 到 n单行值。 您将应用电源操作来实现结果。 因此,您可以通过执行以下操作方便地计算输出:

columns = 3;
out = bsxfun(@power, v, 1:columns);

让我们尝试几个给定您的向量v的例子:

>> v = [1.2421; 2.3348; 0.1326; 2.3470; 6.7389];
>> columns = 3;
>> out = bsxfun(@power, v, 1:columns)
out =
    1.2421    1.5428    1.9163
    2.3348    5.4513   12.7277
    0.1326    0.0176    0.0023
    2.3470    5.5084   12.9282
    6.7389   45.4128  306.0321
>> columns = 7;
>> format bank
>> out = bsxfun(@power, v, 1:columns)
out =
  Columns 1 through 5
          1.24          1.54          1.92          2.38          2.96
          2.33          5.45         12.73         29.72         69.38
          0.13          0.02          0.00          0.00          0.00
          2.35          5.51         12.93         30.34         71.21
          6.74         45.41        306.03       2062.32      13897.77
  Columns 6 through 7
          3.67          4.56
        161.99        378.22
          0.00          0.00
        167.14        392.28
      93655.67     631136.19

请注意,要将列设置为 3,我们会得到在您的帖子中看到的内容。 为了将列增加到 7,我不得不更改数字的呈现方式,以便您可以清楚地看到数字。 不这样做会将其变成指数形式,并且有效数字后面有很多零。


祝你好运!

在计算累积幂时,你可以重用以前的结果:对于标量xnx.^n等于x * x.^(n-1),其中已经获得了x.^(n-1)。这可能比独立计算每个幂更有效,因为乘法比幂快。

N成为所需的最大指数。为了使用所描述的方法,将列向量v水平重复N次(repmat),然后沿每行(cumprod)应用累积乘积:

v =[1.2421; 2.3348; 0.1326; 2.3470; 6.7389]; %// data. Column vector
N = 3; %// maximum exponent
result = cumprod(repmat(v, 1, N), 2);

最新更新