6.17. Rezolvitoare și numere aleatoare¶
Când funcția studiată este definită de cod Python mai degrabă decât de un tampon (buffer) de eșantioane, este potrivită o altă familie de instrumente: unde se află rădăcina funcției, minimul ei, integrala ei pe un interval dat? Submodulele scipy.integrate și scipy.optimize acoperă această muncă. Fiecare algoritm apelează înapoi în funcția Python furnizată de utilizator, astfel încât costul per iterație este mai mare decât o reducere de tampon (buffer); avantajul constă în a nu fi nevoit să scrii rezolvitorul.
Submodulul scipy.special acoperă funcțiile statistice speciale (funcția de eroare, gamma) care apar la calcularea funcției de distribuție cumulativă (CDF, probabilitatea ca un eșantion să fie cel mult o valoare dată) sau a funcției densității de probabilitate (PDF, probabilitatea relativă la o valoare dată) a unei distribuții de probabilitate. numpy.random acoperă generatorul pseudoaleator pentru dithering, simulare și date de test sintetice.
6.17.1. Integrare numerică a unei funcții apelabile¶
Când integrandul este o funcție Python mai degrabă decât un tampon (buffer) de eșantioane, scipy.integrate expune patru algoritmi de cuadratură:
quad()– Gauss-Kronrod adaptiv. Alegerea implicită potrivită pentru integranzi netezi. Returnează(value, error).romberg()– Romberg / Newton-Cotes clasic. Returnează un singur număr în virgulă mobilă. Depreciat în amonte; inclus pentru compatibilitate.simpson()– regula lui Simpson adaptivă. Returnează un singur număr în virgulă mobilă.tanhsinh()– cuadratură dublu-exponențială. Folosește-o când integrandul are singularități la capete sau o limită infinită. Returnează(value, error).
Integrala gaussiană evaluată cu regula dublu-exponențială (tanhsinh):
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))
Ieșire:
approx: 1.7724538... exact: 1.7724538...
6.17.2. Găsirea rădăcinilor și minimizare¶
scipy.optimize acoperă trei rezolvitoare clasice cu o singură variabilă. Fiecare iterație apelează înapoi în funcția Python furnizată de utilizator, astfel încât accelerarea față de un rezolvitor pur Python este modestă (aproximativ 2x); avantajul constă în a nu fi nevoit să scrii rezolvitorul.
bisect()– găsește o rădăcină a luifpe[a, b]prin înjumătățirea intervalului.f(a)șif(b)trebuie să aibă semne opuse:def f(x): return x * x - 1 sp.optimize.bisect(f, 0, 4) # ~1.0
newton()– găsește o rădăcină folosind iterația secantei / Newton-Raphson:def f(x): return x * x * x - 2.0 sp.optimize.newton(f, 3., tol=0.001, rtol=0.01) # ~1.260
fmin()– găsește un minim local folosind metoda simplexului descendent (Nelder-Mead):def f(x): return (x - 1) ** 2 - 1 sp.optimize.fmin(f, 3.0) # ~1.0
Domeniul cu o singură variabilă este suficient pentru majoritatea optimizărilor de pe partea camerei – o constantă de calibrare a unui senzor, amplificarea (gain) care maximizează o măsurătoare de contrast, pragul la care bimodalitatea unei histograme este cea mai accentuată. Pentru problemele cu mai multe variabile, răspunsul corect este de obicei reformularea problemei ca o mică rezolvare de algebră liniară, în loc de a recurge la un optimizator neliniar general.
6.17.3. Funcții speciale¶
scipy.special expune câteva funcții statistice și de probabilitate care se comportă ca funcții universale – acceptă un scalar, un iterabil sau un ndarray și returnează un ndarray de numere în virgulă mobilă:
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
Funcția de eroare și complementul ei apar în CDF-ul unei gaussiene – aplicația de elecție pentru conversia între un scor z măsurat și o probabilitate sau pentru calcularea integralei de coadă a unei distribuții normale. Funcțiile gamma și log-gamma apar în calculele beta / chi-pătrat / student-t; gammaln este forma stabilă numeric pentru argumente mari, unde gamma însuși ar produce depășire.
6.17.4. Numere aleatoare¶
numpy.random oferă o clasă Generator care extrage eșantioane din distribuții comune. Generatorul are stare: fiecare apel își avansează starea internă, astfel încât apelurile consecutive returnează eșantioane independente:
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))
Dtype-ul de ieșire este întotdeauna float. size= acceptă un număr întreg (ieșire 1-D) sau un tuplu (ieșire n-D); când este omis, se returnează un singur număr Python în virgulă mobilă.
Generatorul este potrivit pentru simulare, dithering, date de test sintetice și orice altă aplicație în care nu este necesară robustețe criptografică. Nu este potrivit pentru chei sau token-uri; pentru acestea folosește sursa aleatoare a sistemului prin os.
6.17.5. Disponibilitate la momentul construirii¶
Dacă fiecare submodul este de fapt prezent depinde de modul în care a fost construită camera. scipy.optimize și scipy.special nu sunt activate pe fiecare cameră; apelarea unei funcții pe care camera nu o include generează AttributeError. dir(sp), dir(sp.optimize), dir(np.random) și altele asemenea raportează ce este disponibil pe camera vizată.