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 azfgyökét az[a, b]intervallumon az intervallum felezésével. Azf(a)és azf(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.