我试图表示一个简单的矩阵 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
如何让它在任意数量的行和列上运行?
谢谢!
我发现你的代码有几个问题:
- 我不确定你为什么要定义
d = 3;
. 这只是吹毛求疵,但您可以安全地将其从代码中删除。 -
您没有正确执行电源操作。 具体来说,请看以下语句:
您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
会看到A
和B
都具有单例维度,其中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,我不得不更改数字的呈现方式,以便您可以清楚地看到数字。 不这样做会将其变成指数形式,并且有效数字后面有很多零。
祝你好运!
在计算累积幂时,你可以重用以前的结果:对于标量x
和n
,x.^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);