6.17. Megoldók és véletlenszámok

Amikor a vizsgált függvényt Python-kód definiálja, nem pedig egy mintapuffer, egy másik eszközcsalád a helyes választás: hol van a függvény gyöke, minimuma, integrálja egy adott intervallumon? A scipy.integrate és a scipy.optimize almodulok fedik le ezt a munkát. Minden algoritmus visszahív a felhasználó által megadott Python-függvénybe, így az iterációnkénti költség magasabb, mint egy puffer-redukcióé; a kényelem abban rejlik, hogy nem kell megírni a megoldót.

A scipy.special almodul a statisztikai speciális függvényeket (hibafüggvény, gamma) fedi le, amelyek egy valószínűségi eloszlás kumulatív eloszlásfüggvényének (CDF, annak valószínűsége, hogy egy minta legfeljebb egy adott érték) vagy valószínűségi sűrűségfüggvényének (PDF, a relatív valószínűség egy adott értéknél) kiszámításakor merülnek fel. A numpy.random a pszeudovéletlen-generátort fedi le ditheringhez, szimulációhoz és szintetikus tesztadatokhoz.

6.17.1. Egy hívható objektum numerikus integrálása

Amikor az integrandus egy Python-függvény, nem pedig egy mintapuffer, a scipy.integrate négy kvadratúra-algoritmust tesz elérhetővé:

  • quad() – adaptív Gauss-Kronrod. A megfelelő alapértelmezés sima integrandusokhoz. Egy (value, error) párt ad vissza.

  • romberg() – klasszikus Romberg / Newton-Cotes. Egyetlen float-ot ad vissza. Felsőbb szinten elavult; kompatibilitás miatt szerepel.

  • simpson() – adaptív Simpson-szabály. Egyetlen float-ot ad vissza.

  • tanhsinh() – dupla-exponenciális kvadratúra. Akkor használd, ha az integrandusnak végpont-szingularitásai vagy végtelen határa van. Egy (value, error) párt ad vissza.

A Gauss-integrál a dupla-exponenciális szabállyal (tanhsinh) kiértékelve:

from math import exp
from math import pi
from math import sqrt
from ulab import numpy as np
from ulab import scipy as sp

f = lambda x: exp(-x * x)
value, err = sp.integrate.tanhsinh(f, -np.inf, np.inf)
print("approx:", value, "   exact:", sqrt(pi))

Kimenet:

approx: 1.7724538...   exact: 1.7724538...

6.17.2. Gyökkeresés és minimalizálás

A scipy.optimize három klasszikus egyváltozós megoldót fed le. Minden iteráció visszahív a felhasználó által megadott Python-függvénybe, így a tisztán Python-alapú megoldóhoz képesti gyorsulás szerény (nagyjából 2x); a kényelem abban rejlik, hogy nem kell megírni a megoldót.

  • bisect() – megtalálja az f gyökét az [a, b] intervallumon az intervallum felezésével. Az f(a) és az f(b) ellentétes előjelű kell hogy legyen:

    def f(x):
        return x * x - 1
    
    sp.optimize.bisect(f, 0, 4)        # ~1.0
    
  • newton() – gyököt keres szekáns / Newton-Raphson iterációval:

    def f(x):
        return x * x * x - 2.0
    
    sp.optimize.newton(f, 3., tol=0.001, rtol=0.01)
    # ~1.260
    
  • fmin() – lokális minimumot keres a lefelé tartó szimplex (Nelder-Mead) módszerrel:

    def f(x):
        return (x - 1) ** 2 - 1
    
    sp.optimize.fmin(f, 3.0)           # ~1.0
    

Az egyváltozós hatókör elegendő a legtöbb kameraoldali optimalizáláshoz – egy érzékelő kalibrációs állandója, a kontrasztmérést maximalizáló erősítés, a küszöbérték, ahol egy hisztogram bimodalitása a legélesebb. Többváltozós problémák esetén a helyes válasz általában az, hogy a problémát egy kis lineáris algebrai megoldásként fogalmazzuk át, ahelyett, hogy egy általános nemlineáris optimalizálóhoz nyúlnánk.

6.17.3. Speciális függvények

A scipy.special egy maroknyi statisztikai és valószínűségi függvényt tesz elérhetővé, amelyek univerzális függvényként viselkednek – elfogadnak egy skalárt, egy iterálhatót vagy egy ndarray-t, és egy float ndarray-t adnak vissza:

x = np.linspace(0, 4, num=8)

sp.special.erf(x)         # error function
sp.special.erfc(x)        # complementary error function
sp.special.gamma(x + 1)   # gamma function
sp.special.gammaln(x + 1) # log-gamma function

A hibafüggvény és komplementere megjelenik egy Gauss-eloszlás CDF-jében – ez a választott alkalmazás egy mért z-érték és egy valószínűség közötti átváltáshoz, vagy egy normális eloszlás farokintegráljának kiszámításához. A gamma és a log-gamma függvények a béta / khí-négyzet / Student-féle t számításokban bukkannak fel; a gammaln a numerikusan stabil forma nagy argumentumokhoz, ahol maga a gamma túlcsordulna.

6.17.4. Véletlenszámok

A numpy.random egy Generator osztályt biztosít, amely közönséges eloszlásokból húz mintákat. A generátor állapottal rendelkezik: minden hívás előrelépteti a belső állapotát, így az egymást követő hívások független mintákat adnak vissza:

from ulab import numpy as np

rng = np.random.Generator(seed=42)

rng.random(size=5)             # 5 uniform [0.0, 1.0) samples
rng.uniform(low=-1.0, high=1.0, size=10)
rng.normal(loc=0.0, scale=1.0, size=(2, 4))

A kimenet dtype-ja mindig float. A size= elfogad egy egész számot (1-D kimenet) vagy egy tuple-t (n-D kimenet); ha elhagyod, egyetlen Python float-ot ad vissza.

A generátor alkalmas szimulációhoz, ditheringhez, szintetikus tesztadatokhoz és minden olyan alkalmazáshoz, ahol nem szükséges kriptográfiai erősség. Nem alkalmas kulcsokhoz vagy tokenekhez; ezekhez használd a rendszer véletlenforrását az os modulon keresztül.

6.17.5. Fordítási idejű elérhetőség

Hogy az egyes almodulok ténylegesen jelen vannak-e, az attól függ, hogyan építették fel a kamerát. A scipy.optimize és a scipy.special nincs minden kamerán engedélyezve; egy olyan függvény meghívása, amelyet a kamera nem tartalmaz, AttributeError kivételt vált ki. A dir(sp), dir(sp.optimize), dir(np.random) és társaik jelentik, hogy mi érhető el a célzott kamerán.