3

ループ内に行列があります。

m=


 -132.5901    -137.2695   -114.1264   -131.4986   -134.5733       Inf
       Inf       Inf       Inf        -135.2631   -121.7322       -119.7471
 -132.7978    -123.8068   -135.9385       Inf      -134.1602     -117.6997
 -130.1930    -134.0093   -137.4125   -128.7641       Inf        -116.0473

ループで使用できるコマンドを使用して、次のように答えを取得したいと思います。

 -132.5901 -137.2695 -114.1264 -131.4986 -134.5733  -119.7471  
 -132.7978 -123.8068 -135.9385 -135.2631 -121.7322  -117.6997
 -130.1930 -134.0093 -137.4125 -128.7641 -134.1602  -116.0473

isfiniteコマンドを使用して単一のベクトルは必要ありません。マトリックスサイズは、Matlabを使用して自動的に保持する必要があります。

4

2 に答える 2

5

元の行列のサイズを維持するために、解の行列の下部に。を埋めたいと仮定しますNaNInfまた、特定の列に複数ある可能性があると想定します。その場合、次のループベースのソリューションが機能します。

%# Set up an example matrix
M = [Inf 2 Inf 4; 5 Inf 6 7; Inf Inf 8 Inf];
[T, N] = size(M);

%# Get an index of finite elements
I1 = isfinite(M);

%# Solution 1
Soln1 = NaN(T, N);
for n = 1:N
    CurCol = M(:, n);
    Soln1(1:sum(I1(:, n)), n) = CurCol(I1(:, n));
end

一般的なケースでは、この問題に対しておそらく完全にベクトル化された解決策があります(確かにあります-以下の私の更新を参照してください)。ただし、ループベースのソリューションよりも大幅に高速化されているとしたら、私は驚きます。Matlabでは、問題を設定して(行ではなく)行列の列を操作できるようにすると、単一ループが非常に高速になります。これは、これらの要素がメモリ内で順番に割り当てられるためです。

ここで、列ごとに1つしかないと仮定しInfます。この場合、問題ははるかに簡単に解決でき、次のワンライナーで実行できます。

%# Solution 2
Soln2 = [reshape(M(isfinite(M)), T-1, N); NaN(1, N)];

6つの要素をT-1xN(つまり、2 x 4)の行列に再配置できないため、私が設定した例の行列では、ソリューション2は明らかに失敗します。

更新:わかりました、それで、正当な理由もなく、ループなしでそれを行うことができないことは私を苛立たせました。したがって、ループのないソリューションは次のとおりです。

%# Solution 3
Soln3 = NaN(T, N);
I2 = bsxfun(@plus, cumsum(isfinite(M)), (0:T:T*(N-1)));
I2 = I2(:);
I2(I1 == 0) = [];
Soln3(I2) = M(isfinite(M));

ループソリューションと非ループソリューションの迅速な(非常に)非厳密な速度テスト:

Elapsed time is 0.203997 seconds.
Elapsed time is 0.251969 seconds.

非ループソリューションは、Mより大きな場合でも、おそらく(比較的言えば)改善されます。

今、私は仕事に戻る必要があります:-)

于 2012-11-26T06:55:06.453 に答える
2

コリンの答えに基づいて:

>> M = [Inf 2 Inf 6; 5 Inf 8 4; Inf Inf 7 Inf];
>> [N,I] = sort(M)
N =
     5     2     7     4
   Inf   Inf     8     6
   Inf   Inf   Inf   Inf
I =
     2     1     3     2
     1     2     2     1
     3     3     1     3

つまり、それNはすでに可能な最終製品です。

のデータN並べ替えられているため、必要ない場合は、並べ替えを解除する必要があります。

>> for ii = 1:size(M,2)        
>>     N(~isinf(N(:,ii)),ii) = M(~isinf(M(:,ii)),ii);
>> end
N =
     5     2     8     6
   Inf   Inf     7     4
   Inf   Inf   Inf   Inf

そして、本当に取り除く必要がある場合はinf、を発行するだけです

N(isinf(N)) = NaN;

線に沿ったどこか(および/または必要な場所に置き換えisinfますisnan)。

于 2012-11-26T07:36:17.940 に答える