scipy.stats.qmc.

Sobol#

class scipy.stats.qmc.Sobol(d, *, scramble=True, bits=None, rng=None, optimization=None)[Quelle]#

Engine zur Erzeugung von (gescrambelten) Sobol’-Sequenzen.

Sobol’-Sequenzen sind Quasizufallszahlen mit geringer Diskrepanz. Punkte können mit zwei Methoden gezogen werden

  • random_base2: Sichereres Ziehen von \(n=2^m\) Punkten. Diese Methode garantiert die Balance-Eigenschaften der Sequenz.

  • random: Ziehen einer beliebigen Anzahl von Punkten aus der Sequenz. Siehe Warnung unten.

Parameter:
dint

Dimensionalität der Sequenz. Maximale Dimensionalität ist 21201.

scramblebool, optional

Wenn True, wird LMS+Shift-Scrambling verwendet. Andernfalls findet kein Scrambling statt. Standard ist True.

bitsint, optional

Anzahl der Bits des Generators. Steuert die maximale Anzahl von Punkten, die erzeugt werden können, was 2**bits ist. Maximaler Wert ist 64. Dies entspricht nicht dem Rückgabetyp, der immer np.float64 ist, um die Wiederholung von Punkten zu verhindern. Standard ist None, was aus Gründen der Abwärtskompatibilität 30 entspricht.

Hinzugefügt in Version 1.9.0.

optimization{None, “random-cd”, “lloyd”}, optional

Ob ein Optimierungsschema zur Verbesserung der Qualität nach dem Sampling verwendet werden soll. Beachten Sie, dass dies ein Nachbearbeitungsschritt ist, der nicht garantiert, dass alle Eigenschaften der Stichprobe erhalten bleiben. Standard ist None.

  • random-cd: zufällige Permutationen von Koordinaten zur Verringerung der zentrierten Diskrepanz. Die beste Stichprobe basierend auf der zentrierten Diskrepanz wird ständig aktualisiert. Das zentrierte dispunktbasierte Sampling zeigt eine bessere Raumfüllungsrobustheit gegenüber 2D- und 3D-Unterprojektionen im Vergleich zur Verwendung anderer Dispunktmaße.

  • lloyd: Stört Stichproben mithilfe eines modifizierten Lloyd-Max-Algorithmus. Der Prozess konvergiert zu gleichmäßig verteilten Stichproben.

Hinzugefügt in Version 1.10.0.

rngnumpy.random.Generator, optional

Zustand des Pseudozufallszahlengenerators. Wenn rng None ist, wird ein neuer numpy.random.Generator unter Verwendung der Entropie des Betriebssystems erstellt. Typen, die keine numpy.random.Generator sind, werden an numpy.random.default_rng übergeben, um einen Generator zu instanziieren.

Geändert in Version 1.15.0: Als Teil des SPEC-007-Übergangs von der Verwendung von numpy.random.RandomState zu numpy.random.Generator wurde dieses Schlüsselwort von seed zu rng geändert. Für einen Übergangszeitraum werden beide Schlüsselwörter weiterhin funktionieren, obwohl nur eines gleichzeitig angegeben werden darf. Nach dem Übergangszeitraum geben Funktionsaufrufe mit dem Schlüsselwort seed Warnungen aus. Nach einer Deputationsperiode wird das Schlüsselwort seed entfernt.

Methoden

fast_forward(n)

Führt die Sequenz um n Positionen vorwärts.

integers(l_bounds, *[, u_bounds, n, ...])

Zieht n ganze Zahlen von l_bounds (inklusive) bis u_bounds (exklusive), oder wenn endpoint=True, von l_bounds (inklusive) bis u_bounds (inklusive).

random([n, workers])

Zieht n im halboffenen Intervall [0, 1).

random_base2(m)

Punkt(e) aus der Sobol’-Sequenz ziehen.

reset()

Setzt die Engine auf den Grundzustand zurück.

Hinweise

Sobol’-Sequenzen [1] liefern \(n=2^m\) Punkte mit geringer Diskrepanz in \([0,1)^{d}\). Das Scrambling [3] macht sie für singuläre Integranden geeignet, bietet eine Möglichkeit zur Fehlerabschätzung und kann ihre Konvergenzrate verbessern. Die implementierte Scrambling-Strategie ist ein (linker) linearer Matrix-Scramble (LMS) gefolgt von einer digitalen Zufallsschiebung (LMS+Shift) [2].

Es gibt viele Versionen von Sobol’-Sequenzen, abhängig von ihren „Richtungszahlen“. Dieser Code verwendet Richtungszahlen von [4]. Daher ist die maximale Anzahl von Dimensionen 21201. Die Richtungszahlen wurden mit dem Suchkriterium 6 vorab berechnet und können unter https://web.maths.unsw.edu.au/~fkuo/sobol/ abgerufen werden.

Warnung

Sobol’-Sequenzen sind eine Quadraturregel und verlieren ihre Balance-Eigenschaften, wenn eine Stichprobengröße verwendet wird, die keine Zweierpotenz ist, oder der erste Punkt übersprungen wird, oder die Sequenz ausgedünnt wird [5].

Wenn \(n=2^m\) Punkte nicht ausreichen, sollte man \(2^M\) Punkte für \(M>m\) nehmen. Beim Scrambling muss die Anzahl R der unabhängigen Replikate keine Zweierpotenz sein.

Sobol’-Sequenzen werden bis zu einer bestimmten Anzahl von \(B\) Bits generiert. Nach der Erzeugung von \(2^B\) Punkten würde sich die Sequenz wiederholen. Daher wird ein Fehler ausgelöst. Die Anzahl der Bits kann mit dem Parameter bits gesteuert werden.

Referenzen

[1]

I. M. Sobol’, „Die Verteilung von Punkten in einem Würfel und die genaue Auswertung von Integralen.“ Zh. Vychisl. Mat. i Mat. Phys., 7:784-802, 1967.

[2]

J. Matousek, „On the L2-discrepancy for anchored boxes.“ J. of Complexity 14, 527-556, 1998.

[3]

Art B. Owen, „Scrambling Sobol and Niederreiter-Xing points.“ Journal of Complexity, 14(4):466-489, Dezember 1998.

[4]

S. Joe und F. Y. Kuo, „Constructing sobol sequences with better two-dimensional projections.“ SIAM Journal on Scientific Computing, 30(5):2635-2654, 2008.

[5]

Art B. Owen, „On dropping the first Sobol’ point.“ arXiv:2008.08051, 2020.

Beispiele

Erzeuge Stichproben aus einer Sobol’-Sequenz mit geringer Diskrepanz.

>>> from scipy.stats import qmc
>>> sampler = qmc.Sobol(d=2, scramble=False)
>>> sample = sampler.random_base2(m=3)
>>> sample
array([[0.   , 0.   ],
       [0.5  , 0.5  ],
       [0.75 , 0.25 ],
       [0.25 , 0.75 ],
       [0.375, 0.375],
       [0.875, 0.875],
       [0.625, 0.125],
       [0.125, 0.625]])

Berechnet die Qualität der Stichprobe anhand des Diskrepanzkriteriums.

>>> qmc.discrepancy(sample)
0.013882107204860938

Um ein bestehendes Design fortzusetzen, können zusätzliche Punkte durch erneuten Aufruf von random_base2 erhalten werden. Alternativ können Punkte übersprungen werden, z.B.

>>> _ = sampler.reset()
>>> _ = sampler.fast_forward(4)
>>> sample_continued = sampler.random_base2(m=2)
>>> sample_continued
array([[0.375, 0.375],
       [0.875, 0.875],
       [0.625, 0.125],
       [0.125, 0.625]])

Schließlich können Stichproben auf Grenzen skaliert werden.

>>> l_bounds = [0, 2]
>>> u_bounds = [10, 5]
>>> qmc.scale(sample_continued, l_bounds, u_bounds)
array([[3.75 , 3.125],
       [8.75 , 4.625],
       [6.25 , 2.375],
       [1.25 , 3.875]])