2

マトリックス (size_out、size_in) を入力する必要があります。私は同様の問題を探していますが、それらの解決策はどれも私を助けてくれませんでした.

初めての試みでした

for k= 0:size_out-1
    for n= 0:size_in-1
        part1= sincd(2*No-2, 2*size_in, (k+1/2)/factor -n -1/2);
        part3= sincd(2*No-2, 2*size_in, (k+1/2)/factor +n +1/2);
        part2= cos( (pi/(2*size_in) ) * ( (k+1/2)/factor -n -1/2) );
        part4= cos( (pi/(2*size_in) ) * ( (k+1/2)/factor +n +1/2) );
        A(k+1,n+1)= part1*part2+part3*part4;
    end
end

内側のループを削除して、このコードをベクトル化しました。

for k= 0:size_out-1
    A(k+1,1:size_in)= ...
        sincd(2*No-2, 2*size_in, (k+1/2)/factor -(0:size_in-1) -1/2 ) .* ...
        cos( pi/(2*size_in) * ( (k+1/2)/factor -(0:size_in-1) -1/2 ) ) + ...
        sincd(2*No-2, 2*size_in, (k+1/2)/factor +(0:size_in-1) +1/2 ) .* ...
        cos( pi/(2*size_in) * ( (k+1/2)/factor +(0:size_in-1) +1/2 ) );
end

私の質問は: 外側のループをベクトル化する方法は?

reshape&permute または bsxfun の組み合わせがここで役立つかどうかはわかりません。

前もって感謝します。

4

1 に答える 1

0

いくつかのパラメーターと関数が未定義のままだったので、私はそれらを自由に定義しました。

すばらしいのは、'ベクトル化' による非常に優れた速度の向上です。ただし、その多くはおそらく MATLAB の並列化によるものです。これは kron の悪用ですが、ここにアプローチがあります。

プロットをスピードアップ

ここでの for ループは、さまざまなスケールをテストするためのものであることに注意してください

% // testing for a range of scales
t1 = [];
t2 = [];
scales = floor(logspace(1,3,20));
for scale = scales

    % // Some guessed parameters and large sizes
    size_out = scale;
    size_in = scale;
    No = 2; %?
    factor = 3;

    % // Arbitrary function for sincd
    sincd = @(x, y, z) x.*y.*z;

    tic
    % // Provided code
    A = zeros(size_out,size_in);
    for k= 0:size_out-1
        for n= 0:size_in-1
            part1= sincd(2*No-2, 2*size_in, (k+1/2)/factor -n -1/2);
            part3= sincd(2*No-2, 2*size_in, (k+1/2)/factor +n +1/2);
            part2= cos( (pi/(2*size_in) ) * ( (k+1/2)/factor -n -1/2) );
            part4= cos( (pi/(2*size_in) ) * ( (k+1/2)/factor +n +1/2) );
            A(k+1,n+1)= part1*part2+part3*part4;
        end
    end
    t1 = [t1; toc];



    tic

ここでは、クロネッカー テンソル積を使用して、行と列のインデックスとそれに続く単位行列を含む 2 つの行列を作成し、sincd に入るすべての形状が同じになるようにします。

    ns = kron([1:size_in]-1,ones(1,size_out)');
    ks = kron(ones(1,size_in),[1:size_out]'-1);
    ident = ones(size_out,size_in);

ここでは、k、n を ks と ns に単純に置き換えて、操作の要素を賢く保ち、同じサイズにするようにしました。

    B =  sincd( 2*No-2*ident, 2*size_in*ident, (ks+1/2)/factor -ns -1/2) ...
        .* cos( (pi/(2*size_in) ) * ( (ks+1/2)/factor -ns -1/2) ) ...
      +  sincd(2*No-2*ident, 2*size_in*ident, (ks+1/2)/factor +ns +1/2) ...
         .*cos( (pi/(2*size_in) ) * ( (ks+1/2)/factor +ns +1/2) );

    t2 = [t2; toc];

    % // Should be zero
    norm(A-B)


end

loglog(scales, t1./t2)
title('speed up')
于 2012-12-11T12:12:38.810 に答える