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

next() missing 1 required positional argument: 'self'
maciej brasewicz
  • Rejestracja: dni
  • Ostatnio: dni
  • 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: dni
  • Ostatnio: dni
  • 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

maciej brasewicz
  • Rejestracja: dni
  • Ostatnio: dni
  • 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)

Guaz
  • Rejestracja: dni
  • Ostatnio: dni
  • 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ą.

maciej brasewicz
  • Rejestracja: dni
  • Ostatnio: dni
  • 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.

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.