0

PDLマトリックスを作成しました。各行をペアごとに比較する必要があります。現在、「where」および「cov」コマンドを使用して、2つのスライス(perlループで生成された)のペアワイズ比較を返しています。

私の質問:「範囲」と「スライス」を使用して、ペアごとに行をループするにはどうすればよいですか?インデックス位置を返すにはどうすればよいですか?perlを使用してマトリックスをループしました。私はperlでループすることは本当にPDLの力を損なうことを読みました。

必要な出力:

indexA indexB Value
pos1   pos5   1
pos1   pos6   5
pos1   pos0   7 

明確にするために、私はPDL機能のみを使用したいと思います。

これが私のポイントをよりよく説明する(願わくば)いくつかの擬似コードです。

p $b

[
 [1 0 3 0]
 [0 1 0 1]
 [1 3 1 3]   <- example piddle y
 [0 1 0 1]   <- example piddle z
]

my concept function{


slice $b (grab row z) - works fine
slice $b (grab row y) - works fine


($a, $b) = where($a,$b, $a < 3 && $b < 3 ) - works fine

p $a [1 1] 
p $b [0  0] 

cov($a $b) - works just fine.

}

すべての行でペアワイズで実行する方法が必要です。階乗(n行)の比較を行う必要があります。

4

2 に答える 2

1

PDL スレッド化は、ここで探している概念です。次元に沿ってループするための一般的な手法は、適切な場所にダミーの次元を追加して、計算によって必要な暗黙的なスレッドループが生成されるようにすることです。多次元の問題の場合、dim を追加してスレッドループを作成するには、さまざまな方法があります。

ペア単位の行計算では、スライス インデックスに対して 2 つのネストされたループを選択できます。これは、2 つのインデックス カウントに対して perl ループを持ち、行に沿って PDL スレッドを生成します。インデックスに対して perl ループを 1 つだけ使用することもできますが、暗黙的なスレッドループを利用してすべての行を一度に計算することができます。

完全な PDL-threadloop 計算では、各引数の行に対してループのダミー次元を追加して、N**2 行の計算全体を一度に計算するようにします。計算が == 演算子である形状 [4,3] 配列の例を次に示します。

pdl> $b = floor(random(4,3)*5)

pdl> p $b

[
 [0 4 3 3]
 [3 3 4 2]
 [4 0 1 4]
]

pdl> p $b(,*3)==$b(,,*3)

[
 [
  [1 1 1 1]
  [0 0 0 0]
  [0 0 0 0]
 ]
 [
  [0 0 0 0]
  [1 1 1 1]
  [0 0 0 0]
 ]
 [
  [0 0 0 0]
  [0 0 0 0]
  [1 1 1 1]
 ]
]

結果は形状 [4,3,3] ピドルで、0 次元はペアワイズ計算の結果の行に対応し、1 番目と 2 番目の次元は == 演算に含まれる行インデックスに対応します。

これらのスレッド ループ計算の 1 つからのインデックス値が必要な場合は、xvalsyvalszvals、またはaxisvalsを使用して、その配列軸に対応するインデックス値で piddle を生成します。

pdl> p $b->xvals

[
 [0 1 2 3]
 [0 1 2 3]
 [0 1 2 3]
]


pdl> p $b->yvals

[
 [0 0 0 0]
 [1 1 1 1]
 [2 2 2 2]
]

PDL スレッド (perl スレッドまたは posix スレッドとは異なります) の実装に関連する多くの詳細があります。perldl メーリング リストを参考にして、他の PDL ユーザーや開発者と議論することをお勧めします。また、 PDL の計算とスレッド化をより包括的にカバーしているPDL Bookの最初のオンライン ドラフトも参照してください。

于 2012-04-21T19:00:12.437 に答える
0

あなたが探しているのは、配列内のすべての異なる行のペアを見つけて、次を使用して各ペアを処理する方法だと思いますcovか? それが正しければ、聞いたことがないのでcov、ドキュメントをすばやく検索しても役に立ちません。ただし、役立つ可能性のあるいくつかのことを言うことができます。

あなたは Perl コードから脱落することに過度に慎重になっていると思います。PDLすべての行のペアのインデックスをループし、slice. これは、以下のサンプル コードに示されています。

また、などはそれ自体がピドルであり、ブール演算子はそれらに対して必要なことを実行しないため、whereそのように呼び出すことはできません。$a < 3代わりに演算子を使用し、&括弧をいくつか追加して、式が正しい順序で実行されるようにします。

それを超えて、あなたの質問に対する私の理解を修正するか、covサブルーチンのドキュメントに私を案内しない限り、私は助けることができません.

use strict;
use warnings;

use PDL;

my $dat = pdl <<END;
[
 [1 0 3 0]
 [0 1 0 1]
 [1 3 1 3]
 [0 1 0 1]
]
END

my $max2 = $dat->dim(1) - 1;

for my $i (0 .. $max2 - 1) {
  for my $j ($i + 1 .. $max2) {

    my $row1 = $dat->slice(",($i)");
    my $row2 = $dat->slice(",($j)");

    ($row1, $row2) = where($row1, $row2, ($row1 < 3) & ($row2 < 3));

    cov($row1, $row2);
  }
}
于 2012-03-02T07:59:17.907 に答える