Matlab:for 循环内对列的算术运算(简单但曲折!)
Matlab: arithmetic operation on columns inside a for loop (simple yet devious!)
我试图表示一个简单的矩阵 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 时才有效。
当行数 = 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
个长期存储在 m x 1
向量中的元素,您想要的是一个大小为 m x n
的矩阵,其中 n
是所需的列数,对于从左到右开始的每一列,您希望将 v
乘以 n
th 次方。
因此,根据第三个 "iteration" 中的示例,第一列表示 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
中一样多的列,并复制 A
与 [=] 中一样多的行41=],我们实际上得到:
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,我们得到了在您的 post 中看到的内容。为了将列数增加到 7,我不得不更改数字的显示方式,以便您可以清楚地看到数字。不这样做会使它变成指数形式,并且有效数字后面有很多零。
祝你好运!
计算累积幂时,您可以重用以前的结果:对于标量 x
和 n
,x.^n
等于 x * x.^(n-1)
,这里已经得到了x.^(n-1)
。这可能比单独计算每个幂更有效,因为乘法比幂快。
令 N
为所需的最大指数。要使用所描述的方法,列向量 v
水平重复 N
次 (repmat
), and then a cumulative product is applied along each row (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);
我试图表示一个简单的矩阵 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 时才有效。
当行数 = 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
个长期存储在 m x 1
向量中的元素,您想要的是一个大小为 m x n
的矩阵,其中 n
是所需的列数,对于从左到右开始的每一列,您希望将 v
乘以 n
th 次方。
因此,根据第三个 "iteration" 中的示例,第一列表示 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
中一样多的列,并复制 A
与 [=] 中一样多的行41=],我们实际上得到:
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,我们得到了在您的 post 中看到的内容。为了将列数增加到 7,我不得不更改数字的显示方式,以便您可以清楚地看到数字。不这样做会使它变成指数形式,并且有效数字后面有很多零。
祝你好运!
计算累积幂时,您可以重用以前的结果:对于标量 x
和 n
,x.^n
等于 x * x.^(n-1)
,这里已经得到了x.^(n-1)
。这可能比单独计算每个幂更有效,因为乘法比幂快。
令 N
为所需的最大指数。要使用所描述的方法,列向量 v
水平重复 N
次 (repmat
), and then a cumulative product is applied along each row (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);