2016-03-22 17 views
4

Ich habe festgestellt, dass nach der Ausführung eigs() Funktion mehrmals, jedes Mal gibt es andere, aber näherungsweise Ergebnis.Julia: eigs() -Funktion, die nach jeder Auswertung verschiedene Werte zurückgibt

Gibt es eine Möglichkeit, es jedes Mal das gleiche Ergebnis zurückgeben? Die Ausgabe erfolgt manchmal mit dem Zeichen "+" oder "-".

Inhalt des M:

[2, 1] = 1.0 
[3, 1] = 0.5 
[1, 2] = 1.0 
[3, 2] = 2.5 
[1, 3] = 0.5 
[2, 3] = 2.5 

M = M+M' 
(d, v) = eigs(M, nev=1, which=:LR) 

habe ich versucht, gleiche Funktion auf derselben Sparse Matrix in Python ausgeführt wird, obwohl die Matrix etwas anders aussieht als ich denke, es ist gleich ist. Gerade linke Werte sind von 0 nummeriert. In Julia sind sie von 1 nummeriert. Ich weiß nicht, ob das ein großer Unterschied ist. Die Werte sind in Julia und Python ungefähr gleich, aber in Python sind sie nach jeder Auswertung immer gleich. Auch Rückgabewerte in Python sind komplexe Zahlen, in Julia real.

Python-Code:

Inhalt des M.T:

from scipy.sparse import linalg 

(1, 0) 1.0 
(2, 0) 0.5 
(0, 1) 1.0 
(2, 1) 2.5 
(0, 2) 0.5 
(1, 2) 2.5 

eigenvalue, eigenvector = linalg.eigs(M.T, k=1, which='LR') 

Jede Idee, warum dieses Verhalten auftritt?

Edit:

Dies sind Ergebnisse von vier Bewertungen von GIE

==========eigvalues============== 
[2.8921298144977587] 
===========eigvector============= 
[-0.34667468634025667 
-0.679134250677923 
-0.6469878912367839] 
================================= 

==========eigvalues============== 
[2.8921298144977596] 
===========eigvector============= 
[0.34667468634025655 
0.6791342506779232 
0.646987891236784] 
================================= 

==========eigvalues============== 
[2.8921298144977596] 
===========eigvector============= 
[0.34667468634025655 
0.6791342506779233 
0.6469878912367841] 
================================= 

==========eigvalues============== 
[2.8921298144977583] 
===========eigvector============= 
[0.3466746863402567 
0.679134250677923 
0.646987891236784] 
================================= 
+0

Ich habe versucht, die Anzahl der Iterationen zu erhöhen. Ich bin nicht so besorgt, dass die Zahl etwas anders ist. Ich bin besorgt über dieses "-" Zeichen. In Python, egal wie oft ich es ausführe, gibt es nie "-" Vorzeichen für diese Eingabedaten. –

+1

Korrektur: Nach der Bearbeitung scheint es, dass nicht die Anzahl der Iterationen das Problem ist. Der Algorithmus oszilliert wahrscheinlich zur Lösung hin und manchmal findet er ihn von oben und manchmal von unten und er stoppt, wenn die maximale Genauigkeit (Unterschied kleiner eps = nicht messbar) erreicht ist. – maraca

+0

Und gibt es einen Weg, wie man es reparieren kann? –

Antwort

5

Das Ergebnis eigs hängt von dem Anfangsvektor für die Lanczos Iterationen. Wenn nicht angegeben, ist es zufällig. Obwohl alle zurückgegebenen Vektoren korrekt sind, ist nicht garantiert, dass die Phase über verschiedene Iterationen gleich ist.

Wenn Sie möchten, dass das Ergebnis jedes Mal gleich ist, können Sie v0 in eigs, z.

eigs(M, nev=1, which=:LR, v0 = ones(3))

Solange v0 nicht ändert Sie deterministische Ergebnisse erhalten sollten.

Wenn Sie ein deterministisches Ergebnis zu Testzwecken wünschen, sollten Sie ein Testschema in Erwägung ziehen, das Phasenverschiebungen ermöglicht, da sich die Phase mit den kleinsten Störungen verschieben kann. Z.B. Wenn Sie ein anderes BLAS verknüpfen oder die Anzahl der Threads ändern, kann sich das Ergebnis wieder ändern.

+0

Ja, aber welcher ** v0 ** Vektor zu wählen. Python benutzt es auch und es ist zufällig bei jeder Iteration. Ich denke auch, dass es in Julia nicht zufällig ist, wenn es nicht spezifiziert ist, weil es gemäß der Spezifikation gleich ist mit ** v0 = Nullen ((0,)) **, wenn das Argument nicht spezifiziert ist. –

+0

Ich benutze ** Julia v0.3 **. Denkst du, dass ein Upgrade auf ** v0.4 ** mein Problem beheben kann? –

+1

Es spielt keine Rolle, welchen Sie wählen, solange Sie jedes Mal denselben auswählen. Es mag kleine Unterschiede geben, wie schnell 'Eigs' für verschiedene Startwerte konvergieren, aber man kann nicht wirklich sagen, welches schneller a priori ist. Sie können den Startwert mit 'srand' setzen und dann' rand' verwenden, um den Vektor zu initialisieren und Sie sollten in Ordnung sein. In Bezug auf die 'Nullen ((0,))' Teil dann müssen Sie ein wenig tiefer in der Quelle graben. Dann können Sie sehen, dass der Start-Residuum auf nicht initialisierten Speicher gesetzt wird, wenn der Vektor leer ist. Es ist nicht optimal und wahrscheinlich nicht beabsichtigt, aber es ist zufällig. –