【问题标题】:Vectorize with Matlab Meshgrid in Chebfun在 Chebfun 中使用 Matlab Meshgrid 进行矢量化
【发布时间】:2015-09-21 01:35:46
【问题描述】:

我正在尝试在 Matlab 中使用 meshgrid 和 Chebfun 来摆脱双重 for 循环。我先定义一个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);

我收到错误“列索引必须是整数向量”。我怎样才能克服这个问题,以便我可以摆脱我的双重 for 循环并使我的代码更有效率?

【问题讨论】:

    标签: matlab


    【解决方案1】:

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

    基本上,psi 是一个N 列矩阵,您希望将psi 中所有列对组合的乘积相加。您对meshgrid 有正确的想法,但您应该做的是展开ij 的二维坐标矩阵,以便它们是单个向量。然后,您将使用它并创建两个N^2 列矩阵,每个列对应于从ij 指定的从psi 采样的确切列号。然后,您将在这两个矩阵之间进行逐元素乘法,并对每一行的所有列求和。顺便说一句,我将使用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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-25
      • 1970-01-01
      • 2015-04-07
      相关资源
      最近更新 更多