在Chebfun中使用Matlab Meshgrid进行矢量化

时间:2015-09-21 01:35:47

标签: matlab

我试图在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);

我得到错误"列索引必须是整数向量"。我怎样才能克服这个问题,这样我就可以摆脱双循环,让我的代码更有效率?

1 个答案:

答案 0 :(得分:2)

BTW,Chebfun不是原生MATLAB的一部分,你必须下载它才能运行你的代码:http://www.chebfun.org/。但是,这不应该影响我回答你问题的方式。

基本上,psi是一个N列矩阵,您希望在psi中添加所有列对的组合产品。您对meshgrid有正确的想法,但您应该做的是展开ij的2D坐标矩阵,以便它们成为单个向量。然后,您可以使用它并创建两个N^2列矩阵,其中每列对应于从ij中指定的精确列数。psi 1}}。然后,您在这两个矩阵之间进行逐元素乘法,并对每行的所有列求和。顺便说一句,我将使用iijj作为meshgrid的输出而不是ij的变量。这些变量是为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