我试图在Matlab中使用meshgrid和Chebfun来摆脱双循环。我首先定义N个函数的准矩阵,
%Define functions of type Chebfun
N = 10; %number of functions
x = chebfun('x', [0 8]); %Domain
psi = [];
for i = 1:N
psi = [psi sin(i.*pi.*x./8)];
end
样本计算将计算双和$ \ sum_ {i,j = 1} ^ 10 psi(:,i)。* psi(:,j)$。我可以在Matlab中使用两个for循环实现这一点,
h = 0;
for i = 1:N
for j = 1:N
h = h + psi(:,i).*psi(:,j);
end
end
然后我尝试使用meshgrid以下列方式进行矢量化:
[i j] = meshgrid(1:N,1:N);
h = psi(:,i).*psi(:,j);
我得到错误"列索引必须是整数向量"。我怎样才能克服这个问题,这样我就可以摆脱双循环,让我的代码更有效率?
答案 0 :(得分:2)
基本上,psi
是一个N
列矩阵,您希望在psi
中添加所有列对的组合产品。您对meshgrid
有正确的想法,但您应该做的是展开i
和j
的2D坐标矩阵,以便它们成为单个向量。然后,您可以使用它并创建两个N^2
列矩阵,其中每列对应于从i
和j
中指定的精确列数。psi
1}}。然后,您在这两个矩阵之间进行逐元素乘法,并对每行的所有列求和。顺便说一句,我将使用ii
和jj
作为meshgrid
的输出而不是i
和j
的变量。这些变量是为MATLAB中的复数保留的,我不想无意中为这些变量蒙上阴影。
这样的事情:
%// Your code
N = 10; %number of functions
x = chebfun('x', [0 8]); %Domain
psi = [];
for i = 1:N
psi = [psi sin(i.*pi.*x./8)];
end
%// New code
[ii,jj] = meshgrid(1:N, 1:N);
%// Create two matrices and sum
matrixA = psi(:, ii(:));
matrixB = psi(:, jj(:));
h = sum(matrixA.*matrixB, 2);
如果您想取消临时变量,可以在调用meshgrid
后在一个语句中执行此操作:
h = sum(psi(:, ii(:)).*psi(:, jj(:)), 2);
我没有安装Chebfun,但我们可以通过一个简单的例子验证这是否计算了我们需要的东西:
rng(123);
N = 10;
psi = randi(20, N, N);
使用上述更有效的解决方案运行此代码可以让我们:
>> h
h =
8100
17161
10816
12100
14641
9216
10000
8649
9025
11664
另外,运行上面的双for
循环代码也会给我们:
>> h
h =
8100
17161
10816
12100
14641
9216
10000
8649
9025
11664
如果你想绝对确定,我们可以将两个代码作为单独的变量运行,然后检查它们是否相等:
%// Setup
rng(123);
N = 10;
psi = randi(20, N, N);
%// Old code
h = 0;
for i = 1:N
for j = 1:N
h = h + psi(:,i).*psi(:,j);
end
end
%// New code
[ii,jj] = meshgrid(1:N, 1:N);
hnew = sum(psi(:, ii(:)).*psi(:, jj(:)), 2);
%// Check for equality
eql = isequal(h, hnew);
eql
检查两个变量是否相等,我们确实得到它们:
>> eql
eql =
1