next() missing 1 required positional argument: 'self'

next() missing 1 required positional argument: 'self'
maciej brasewicz
  • Rejestracja:prawie 6 lat
  • Ostatnio:ponad 5 lat
  • Postów:5
0

Mam problem z generatorem liczb pseudolosowych. jest to LCG - wykorzystujący pomijanie logarytmiczne do przodu (i do tyłu).
Gdy próbuję wygenerować 10k liczb dostaję następujący błąd:

Kopiuj
 next() missing 1 required positional argument: 'self'
Kopiuj
import numpy as np

class LCG(object):

    UZERO: np.uint32 = np.uint32(0)
    UONE : np.uint32 = np.uint32(1)

    def __init__(self, seed: np.uint32, a: np.uint32, c: np.uint32) -> None:
        self._seed: np.uint32 = np.uint32(seed)
        self._a   : np.uint32 = np.uint32(a)
        self._c   : np.uint32 = np.uint32(c)

    def next(self) -> np.uint32:
        self._seed = self._a * self._seed + self._c
        return self._seed

    def seed(self) -> np.uint32:
        return self._seed

    def set_seed(self, seed: np.uint32) -> np.uint32:
        self._seed = seed

    def skip(self, ns: np.int32) -> None:
        """
        Signed argument - skip forward as well as backward

        The algorithm here to determine the parameters used to skip ahead is
        described in the paper F. Brown, "Random Number Generation with Arbitrary Stride,"
        Trans. Am. Nucl. Soc. (Nov. 1994). This algorithm is able to skip ahead in
        O(log2(N)) operations instead of O(N). It computes parameters
        A and C which can then be used to find x_N = A*x_0 + C mod 2^M.
        """

        nskip: np.uint32 = np.uint32(ns)

        a: np.uint32 = self._a
        c: np.uint32 = self._c

        a_next: np.uint32 = LCG.UONE
        c_next: np.uint32 = LCG.UZERO

        while nskip > LCG.UZERO:
            if (nskip & LCG.UONE) != LCG.UZERO:
                a_next = a_next * a
                c_next = c_next * a + c

            c = (a + LCG.UONE) * c
            a = a * a

            nskip = nskip >> LCG.UONE

        self._seed = a_next * self._seed + c_next


#%%
np.seterr(over='ignore')

a = np.uint32(1664525)
c = np.uint32(1013904223)
seed = np.uint32(1)

rng = LCG(seed, a, c)
q = [LCG.next() for _ in range(0, 10000)]
Shalom
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
2

A nie chciałeś zamiast LCG.next() napisać rng.next()? ;) W końcu chcesz tą metodę wywołać na obiekcie


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 1x, ostatnio: Shalom
lion137
Zdecydowanie, tak nawet działa i zwraca wektor 10 - ciu tysięcy np.uint32:-D
maciej brasewicz
  • Rejestracja:prawie 6 lat
  • Ostatnio:ponad 5 lat
  • Postów:5
0

Dzięki za odpowiedź! Niestety z rng.next() nie działa tak jak trzeba. Myślę, że muszę utworzyć instancję obiektu klasy LCG i jawnie wywołać metodę .next () dla tego obiektu. (rzuca błędami jak na razie - coś robię nie tak)

lion137
To czemu mi z jedną zmianą: rng.next() na dole działa i zwraca wektor wyglądający "dobrze"?
Guaz
  • Rejestracja:około 8 lat
  • Ostatnio:ponad 4 lata
  • Lokalizacja:Częstochowa
  • Postów:221
1

Tak nawiasem mówiąc używasz słowa kluczowego dla pythona, tak się nie robi :).

Kopiuj
import numpy as np

class LCG(object):

    UZERO: np.uint32 = np.uint32(0)
    UONE : np.uint32 = np.uint32(1)

    def __init__(self, seed: np.uint32, a: np.uint32, c: np.uint32) -> None:
        self._seed: np.uint32 = np.uint32(seed)
        self._a   : np.uint32 = np.uint32(a)
        self._c   : np.uint32 = np.uint32(c)

    def next_(self) -> np.uint32:
        self._seed = self._a * self._seed + self._c
        return self._seed

    def seed(self) -> np.uint32:
        return self._seed

    def set_seed(self, seed: np.uint32) -> np.uint32:
        self._seed = seed

    def skip(self, ns: np.int32) -> None:
        """
        Signed argument - skip forward as well as backward

        The algorithm here to determine the parameters used to skip ahead is
        described in the paper F. Brown, "Random Number Generation with Arbitrary Stride,"
        Trans. Am. Nucl. Soc. (Nov. 1994). This algorithm is able to skip ahead in
        O(log2(N)) operations instead of O(N). It computes parameters
        A and C which can then be used to find x_N = A*x_0 + C mod 2^M.
        """

        nskip: np.uint32 = np.uint32(ns)

        a: np.uint32 = self._a
        c: np.uint32 = self._c

        a_next: np.uint32 = LCG.UONE
        c_next: np.uint32 = LCG.UZERO

        while nskip > LCG.UZERO:
            if (nskip & LCG.UONE) != LCG.UZERO:
                a_next = a_next * a
                c_next = c_next * a + c

            c = (a + LCG.UONE) * c
            a = a * a

            nskip = nskip >> LCG.UONE

        self._seed = a_next * self._seed + c_next

#%%
np.seterr(over='ignore')

a = np.uint32(1664525)
c = np.uint32(1013904223)
seed = np.uint32(1)

rng = LCG(seed, a, c)
q = [rng.next_() for _ in range(0, 10000)]

Tu pozostaje ci naprawić 'deklaracje typów', bo syntaxa wypierdzielają.


Linux Mint
Arduino / Python 3.5.2
maciej brasewicz
"Tak nawiasem mówiąc używasz słowa kluczowego dla pythona, tak się nie robi :)" Co masz na myśli?
maciej brasewicz
Na pythonie 3.7 kod działa OK
Guaz
next to wbudowana metoda w pythonie, spróbuj ten kod: iterator = (i for i in range(2, 22, 3)); for i in range(5): print(next(iterator)); będzie z iteracji brał kolejne elementy :). Co więcej, by to było pythonowe, lepiej by było gdyby twój generator również tak działał, implementując magic method __next__ :D. Fakt, działa poprawnie z tymi deklaracjami, nie wiem dlaczego u mnie na stacjonarce pod windowsem miał bóle co do tego syntaxu :s
maciej brasewicz
  • Rejestracja:prawie 6 lat
  • Ostatnio:ponad 5 lat
  • Postów:5
0
maciej brasewicz napisał(a):

Dzięki za odpowiedź! Niestety z rng.next() nie działa tak jak trzeba. Myślę, że muszę utworzyć instancję obiektu klasy LCG i jawnie wywołać metodę .next () dla tego obiektu. (rzuca błędami jak na razie - coś robię nie tak)

Chyba za długo przy kompie dzisiaj ... Zgodnie z tym co napisałem wyżej rng.next () jest właściwym rozwiązaniem.

Guaz
Ah, przeoczyłem
maciej brasewicz
Miałem na myśli, że ja dzisiaj za długo przy kompie i wydawało mi się, że rng.next() nie będzie działać tak jak trzeba

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.