2015-08-19 12 views
5

Aus dieser question frage ich mich, ob ein allgemeineres einsum möglich war. Nehmen wir an, ich hatte das Problemnumpy.einsum für Julia? (2)

using PyCall 
@pyimport numpy as np 

a = rand(10,10,10) 
b = rand(10,10) 
c = rand(10,10,10) 

Q = np.einsum("imk,ml,lkj->ij", a,b,c) 

oder etwas ähnliches, wie ich war, dieses Problem zu lösen, ohne durch die Summen Looping?

mit freundlichen Grüßen

+1

Vielleicht [dieser Tensor Operationen Bibliothek] (https: // github.com/Jutho/TensorOperations.jl#index-notation) könnte helfen. Achten Sie darauf, dass es verlassen aussieht (letzte Festschreibung März 2015 und aktuell fehlgeschlagener Build) –

+0

Sie haben das 'c' aus der Gleichung weggelassen. Die 'Python'-Implementierung hängt stark vom 'nditer'-Iterator ab. – hpaulj

+1

Nur ein Hinweis, dass 'einsum' wahrscheinlich nicht direkt auf Julia portiert wurde, weil es genauso schnell ist, die Schleifen selbst zu schreiben. Wenn ich einen Port davon schreiben würde, würde ich das wahrscheinlich als ein Makro tun, um die tiefgestellte Zeichenkette zur Parserzeit zu dekodieren und direkt zu einer Menge von for-Schleifen zu expandieren (ähnlich wie @ printf funktioniert). –

Antwort

3

Bearbeiten/Update: Dies ist nun ein registriertes Paket, so können Sie Pkg.add("Einsum") und Sie sollen (siehe Beispiel unten, um zu beginnen) gut zu gehen.

Ursprüngliche Antwort: Ich habe gerade einige sehr vorläufige Code erstellt, um dies zu tun. Es folgt genau das, was Matt B. in seinem Kommentar beschrieben hat. Hoffe es hilft, lass es mich wissen, wenn es Probleme damit gibt.

https://github.com/ahwillia/Einsum.jl

Dies ist, wie Sie Ihr Beispiel implementieren würde:

using Einsum 

a = rand(10,10,10) 
b = rand(10,10) 
c = rand(10,10,10) 
Q = zeros(10,10) 

@einsum Q[i,j] = a[i,m,k]*b[m,l]*c[l,k,j] 

Unter der Haube des Makro baut die folgende Reihe von for-Schleifen verschachtelt und fügt sie in den Code Zeit vor kompilieren. (Hinweis: Dies ist nicht der genaue Code eingefügt, es überprüft auch, um sicherzustellen, dass die Abmessungen der Eingänge übereinstimmen, macroexpand mit dem vollständigen Code zu sehen):

for j = 1:size(Q,2) 
    for i = 1:size(Q,1) 
     s = 0 
     for l = 1:size(b,2) 
      for k = 1:size(a,3) 
       for m = 1:size(a,2) 
        s += a[i,m,k] * b[m,l] * c[l,k,j] 
       end 
      end 
     end 
     Q[i,j] = s 
    end 
end 
+0

@varantir Wenn dies Ihre Frage beantwortet hat, markieren Sie sie bitte als beantwortet. Vielen Dank! –