【问题标题】:Matlab: arithmetic operation on columns inside a for loop (simple yet devious!)Matlab:for循环内列的算术运算(简单而狡猾!)
【发布时间】:2015-03-31 05:52:21
【问题描述】:

我试图表示一个简单的矩阵 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
这是第三次迭代后的 v :

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
现在考虑到我在 Matlab 中完全是个菜鸟,我真的低估了这样一个看似简单的任务的难度,这花了我将近一天的时间调试和上网寻找任何线索。这是我想出的:
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 或更少时才有效。

当 rows = 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

我怎样才能让它在任意数量的行和列上运行?

谢谢

【问题讨论】:

  • 我会试试这个bsxfun,如果成功了会回复你。
  • 实际上......您的定义与您公布的结果之间存在差异!在具有 3 列的 v 中,每一列似乎是列索引的第一个 v(所以第 3 列是 v.^3)。但是在定义中,第三列应该是((v.^2).^3),也就是v.^6。哪一个是正确的?
  • 是的,你是正确的@Hoki 将 v 提高到 n 列的幂是我想要的。我会更新帖子。
  • @AbdulelahAl-Jeffery - 好的。所以你不想引用最后一列?您只想使用原始向量并将其提高到nth 次方?如果是这样,那我原来的想法是对的。
  • 实际上format longG 正是我浪费时间的原因。非常感谢@rayryeng,上帝保佑你,上帝保佑你。

标签: matlab for-loop matrix vector dimensions


【解决方案1】:

我发现您的代码有一些问题:

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

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

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

    Ncol = k.^c;
    

    Ncol 替换为上面的行后,代码现在应该可以工作了。我还注意到您裁剪了结果的第一列。您获得重复列的原因是因为您的for 循环从c = 1 开始。因为你已经计算了v.^1 = v,你可以在c = 2开始你的循环。把你的循环起点改成c = 2,就可以去掉第一列了。


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

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

因此,给定您第三次“迭代”中的示例,第一列代表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 的列数相同,并将A 的行数与B 的行数相同,我们实际上得到:

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,我必须更改数字的显示方式,以便您可以清楚地看到数字。不这样做会使它变成指数形式,并且有效数字后面有很多零。


祝你好运!

【讨论】:

  • 伙计,你打字的速度太快了……我正在准备完全相同的答案(甚至解释更少),当我完成时,我看到你的答案从很久以前就在那里了! !无论如何都做得很好。
  • 是的,你是对的,我应该解释什么是v = x(1:rows,1);,但无论如何,v 的值在我之前给出的示例中。另外,您对d = 3; 的看法是正确的,这只是一个错字,因为我实际上只是将我的原始代码简化为这个正好捕捉到我的问题的示例代码。这是一个漫长而漫长的一天!
  • 那么显然bsxfun 函数具有相同的原始问题,如果行数超过 6 或列数超过 3,它就会中断!!!您对我的代码的修订似乎也有完全相同的问题。除了 6×3 矩阵之外没有什么!!!
【解决方案2】:

在计算累积幂时,您可以重复使用以前的结果:对于标量 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);

【讨论】:

  • 这是一个方便的做法,我以后会尝试使用。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-12
  • 1970-01-01
  • 2014-06-06
  • 1970-01-01
  • 1970-01-01
  • 2019-06-02
相关资源
最近更新 更多