2017-08-21 6 views
1

this questionのフォローアップ。私は大規模で疎な行列を持っています。チャペルの行列のカスタム行

A = [ 
    [0, 0, 0, 1.2, 0] 
    [0, 0, 0, 0, 0] 
    [3.5, 0, 0, 0, 0] 
    [0 7, 0, 0, 0] 
] 

そして私は、私はそこ[x * log(x) for x in row] do...のようなイテレータがあるが、私は、構文を見つけるのに苦労してると信じA

の行ごとの和v[j] = v[j,] * log(v[j,])を持つベクトルvを作成したいです。 1つの具体的な問題はlog(0)を避けることです。おそらくイテレータのif文ですか?

答えて

1

[x * log(x)for x]行のようなイテレータがあると思いますが、構文がわかりません。代わりにイテレータを作成する

、我々はpromotionは残りの世話をすることができ、x * log(x)を計算し、それに配列(または配列スライスを)渡しする関数を作成することができます。このような代わりに、私たちは前に行ったよう配列スライスの上に+ reduceを行う

、配列スライスに昇格操作超える

forall i in indices { 
    rowsums[i] = + reduce(A[i, ..]); 
} 
我々が行うことができます

+ reduce、:

forall i in indices { 
    rowsums[i] = + reduce(logProduct(A[i, ..])); 
} 

logProduct(x)には、上述したように、0という特別な場合を扱うif文を含めることができます。

config const n = 10; 

proc main() { 
    const indices = 1..n; 
    const Adom = {indices, indices}; 
    var A: [Adom] real; 

    populate(A); 

    var v = rowSums(A); 

    writeln('matrix:'); 
    writeln(A); 

    writeln('row sums:'); 
    writeln(v); 
} 


/* Populate A, leaving many zeros */ 
proc populate(A: [?Adom]) { 
    forall i in Adom.dim(1) by 2 do // every other row 
    forall j in Adom.dim(2) by 3 do // every third column 
     A[i, j] = i*j; 
} 

/* Compute row sums with custom function (logProduct) */ 
proc rowSums(A: [?Adom] ?t) { 
    var v: [Adom.dim(1)] t; 

    [i in v.domain] v[i] = + reduce(logProduct(A[i, ..])); 

    return v; 
} 

/* Custom function to handle log(0) case */ 
proc logProduct(x: real) { 
    if x == 0 then return 0; 
    return x * log(x); 
} 
+0

あなたは昇進がここにどのように役立つかを少し説明することができます:すべて一緒にこれを置く

は次のようになりますか? –

+1

簡単に言えば、要素型 't'の反復可能オブジェクトを型' t'を期待する関数に渡すと、関数は各要素に対して(並列に)呼び出されます。私は詳細な説明のために、ドキュメンテーション(http://chapel.cray.com/docs/master/users-guide/datapar/promotion.html)へのリンクを編集に追加しました。 – bencray

関連する問題