2016-04-10 4 views
4

Ich versuche Vektor von Zufall NormalenRegenerieren Vektor randoms in Python

ich in die Lage sein will, zu generieren und regenerieren den folgend durch die Erzeugung von Zufall normale Matrix der Größe 100x3 und zufälligen Normalen zu erreichen Mittelwert 0 mit und sd 1 :

seed1 = '123' 
seed2 = 'asd' 
randMatrixrows = 100 
randMatrixcols = 3 
mu = 0 
sd = 1 

normRand1 = rekina_normRandomGenerator(seed1, randMatrixrows, randMatrixcols, mu, sd) #normRand1 is of size 100x3 
normRand2 = rekina_normRandomGenerator(seed2, randMatrixrows, randMatrixcols, mu, sd) 
normRand3 = rekina_normRandomGenerator(seed1, randMatrixrows, randMatrixcols, mu, sd) 
normRand4 = rekina_normRandomGenerator(seed2, randMatrixrows, randMatrixcols, mu, sd) 

err1 = normRand1 - normRand3 
err2 = normRand2 - normRand4 

Jedes Element von ERR1 und ERR2 sollte 0 sein

ich habe auch versucht zu lesen, aber ich bin total verloren mit der Umsetzung zu Python neu ist. Ich erwartete eine einfache Implementierung, um zu zeigen, wie man das CBRNG benutzt.

+0

Ich weiß nicht viel über Reikna, aber jedes Mal, wenn Sie eine zufällige Sache generieren, wird es nicht anders sein? Warum brauchen Sie err1 und err3 als 0? –

+0

@Sagar https://en.wikipedia.org/wiki/Pseudorandom_number_generator, Seeding Kontrollen gegeben "zufällige" Zahlen, die vollständig deterministisch sind. Wiederholbare "zufällige" Zahlen zu haben, kann beim Testen usw. sehr nützlich sein. –

+0

Danke @Ilja wird durchgehen. –

Antwort

3

Ihre ursprüngliche Annahme, dass Sie reikna.cbrng.CBRNG verwenden müssen, ist richtig. Es scheint, es bietet eine Vielzahl von sources of pseudo randomness - basierend auf Counter-basierte Zufallszahlengeneratoren - und distributions, die verwirrend sein können. Es bietet auch shortcuts zum Erstellen von Zufallszahlengeneratoren mit gegebener Verteilung.

from reikna.core import Type 
from reikna.cbrng import CBRNG 
from reikna.cluda import any_api 
import numpy as np 

# Get any supported API for this system, or an exception  
_api = any_api() 
# The global CLUDA Thread, wrapping context, shared by all 
# reikna_norm_rng's 
_thr = _api.Thread.create() 


def reikna_norm_rng(seed, rows, cols, mean, std, 
        dtype=np.float32, 
        generators_dim=1): 
    """ 
    A do-all generator function for creating a new Computation 
    returning a stream of pseudorandom number arrays. 
    """ 
    # The Type of the output array 
    randoms_arr = Type(dtype, (rows, cols)) 
    # Shortcut for creating a Sampler for normally distributed 
    # random numbers 
    rng = CBRNG.normal_bm(randoms_arr=randoms_arr, 
          generators_dim=generators_dim, 
          sampler_kwds=dict(mean=mean, std=std), 
          # Reikna expects a positive integer. This is a 
          # quick and *dirty* solution. 
          seed=abs(hash(seed))) 
    compiled_comp = rng.compile(_thr) 
    # RNG "state" 
    counters = _thr.to_device(rng.create_counters()) 
    # Output array 
    randoms = _thr.empty_like(compiled_comp.parameter.randoms) 

    while True: 
     compiled_comp(counters, randoms) 
     yield randoms.get() 

Um es in Aktion Add zu sehen:

if __name__ == '__main__': 
    seed1 = '123' 
    seed2 = 'asd' 
    rows, cols = 100, 3 
    mu, sd = 0, 1 

    # This will create a new RNG, take 1 result and throw the RNG away 
    r1 = next(reikna_norm_rng(seed1, rows, cols, mu, sd)) 
    r2 = next(reikna_norm_rng(seed2, rows, cols, mu, sd)) 
    r3 = next(reikna_norm_rng(seed1, rows, cols, mu, sd)) 
    r4 = next(reikna_norm_rng(seed2, rows, cols, mu, sd)) 

    err1 = r1 - r3 
    err2 = r2 - r4 

    print("all(err1 == 0):", np.all(err1 == 0)) 
    print("all(err2 == 0):", np.all(err2 == 0)) 

Ich möchte auch sicherstellen, dass randoms die beiden unterschiedlichen Samen keine Korrelation haben generiert.

Dies hängt von der Qualität der Implementierung ab. Hier ist, wie zwei Sätze von Zahlen mit Samen und geplottet:

rng1 = reikna_norm_rng(0, 100, 10000, 0, 1) 
rng2 = reikna_norm_rng(1, 100, 10000, 0, 1) 
A = next(rng1) 
B = next(rng2) 
A_r = A.ravel() 
B_r = B.ravel() 
for i in range(0, A_r.size, 1000): 
    plot(A_r[i:i+1000], B_r[i:i+1000], 'b.') 

plot(A, B)

Haftungsausschluss

Dies ist mein erster Lauf in mit reikna. Der obige Code kann Ressourcen nicht rechtzeitig freigeben und/oder wie ein Sieb auslaufen. Es verwendet eine globale Thread, die möglicherweise nicht das ist, was Sie in einer größeren Anwendung möchten.

PS

np.random.seed(seed) 
np.random.normal(0, 1, (100, 3)) 

produziert auch Arrays von normalverteilten Zufallszahlen mit Form (100, 3), obwohl es nicht die GPU zu verwenden ist.

+0

"Der obige Code kann Ressourcen nicht rechtzeitig freigeben und/oder wie ein Sieb auslaufen. Es verwendet einen globalen Thread, der in einer größeren Anwendung möglicherweise nicht Ihren Anforderungen entspricht." Was bedeutet diese Aussage? – Zanam

+0

Im Allgemeinen vertraue ich Python-Objekten, um Ressourcen etc. freizugeben, wenn sie gc'd werden, aber dieses GPU-Zeug ist mir etwas fremd und deshalb bin ich mir nicht ganz sicher, ob du diese Puffer manuell freigeben sollst. Wahrscheinlich nicht. –

+0

In einer größeren App würden Sie wahrscheinlich 'reikna_norm_rng' umgestalten, um eine von einer App bereitgestellte Thread-Instanz anstelle eines globalen Modulbereichs zu verwenden. Erleichtert das Testen und ist generell modularer. –

Verwandte Themen