2017-08-21 1 views
1

Follow-up auf this question. Ich habe eine Matrix (ja, ich tue), die groß und dünn sein wird.Benutzerdefinierte rowSums einer Matrix in Kapelle

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

Und ich möchte einen Vektor v erstellen, die die Summe v[j] = v[j,] * log(v[j,]) für jede Zeile hat in A

Ich glaube, es ist ein Iterator wie [x * log(x) for x in row] do... aber ich habe eine harte Zeit, um die Syntax zu finden. Eine besondere Bugaboo ist es, zu vermeiden, , also vielleicht eine if Anweisung im Iterator nehmen?

Antwort

1

Ich glaube, es gibt einen Iterator wie [x * log (x) für x in Zeile] do ... aber ich habe es schwer, die Syntax zu finden.

Statt einen Iterator zu schaffen, können wir eine Funktion berechnen x * log(x) erstellen und nur ein Array (oder Array-Slice) passieren, um es, promotion wodurch der Rest kümmern.

Statt eine + reduce über die Array-Scheiben zu tun, wie wir vorher,

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

Wir können auf den Array-Scheiben, wie dies ein + reduce über einen geförderten Betrieb tun:

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

wo logProduct(x) kann eine if-Anweisung enthalten, die den Sonderfall 0 behandelt, wie Sie oben erwähnt haben.

Putting dies sieht alles zusammen so etwas wie dieses:

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

Können Sie ein wenig erklären, wie die Förderung hilft hier? –

+1

Kurz gesagt, wenn Sie ein iterables Objekt vom Elementtyp "t" an eine Funktion übergeben, die den Typ "t" erwartet, wird die Funktion für jedes Element (parallel!) Aufgerufen. Ich habe einen Link zu der Dokumentation (http://chapel.cray.com/docs/master/users-guide/datapar/promotion.html) in einer Bearbeitung für weitere Erklärungen hinzugefügt. – bencray

Verwandte Themen