6.17. Řešiče a náhodná čísla¶
Když je studovaná funkce definována Python kódem spíše než bufferem vzorků, je správnou volbou jiná skupina nástrojů: kde je kořen funkce, její minimum, její integrál přes daný interval? Submoduly scipy.integrate a scipy.optimize pokrývají tuto práci. Každý algoritmus volá zpět uživatelem dodanou Python funkci, takže náklady na jednu iteraci jsou vyšší než u redukce bufferu; pohodlí spočívá v tom, že nemusíte psát řešič.
Submodul scipy.special pokrývá statistické speciální funkce (chybová funkce, gama), které se objevují při výpočtu kumulativní distribuční funkce (CDF, pravděpodobnost, že vzorek je nejvýše rovný dané hodnotě) nebo hustoty pravděpodobnosti (PDF, relativní pravděpodobnost při dané hodnotě) rozdělení pravděpodobnosti. numpy.random pokrývá pseudonáhodný generátor pro dithering, simulaci a syntetická testovací data.
6.17.1. Numerická integrace volatelné funkce¶
Když je integrand Python funkcí spíše než bufferem vzorků, scipy.integrate poskytuje čtyři kvadraturní algoritmy:
quad()– adaptivní Gauss-Kronrod. Správná výchozí volba pro hladké integrandy. Vrací(value, error).romberg()– klasická Rombergova / Newton-Cotesova metoda. Vrací jediný float. Upstream zastaralá; zahrnuta kvůli kompatibilitě.simpson()– adaptivní Simpsonovo pravidlo. Vrací jediný float.tanhsinh()– dvojitě exponenciální kvadratura. Použijte ji, když má integrand singularity v krajních bodech nebo nekonečnou mez. Vrací(value, error).
Gaussův integrál vyhodnocený dvojitě exponenciálním pravidlem (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))
Výstup:
approx: 1.7724538... exact: 1.7724538...
6.17.2. Hledání kořenů a minimalizace¶
scipy.optimize pokrývá tři klasické řešiče jedné proměnné. Každá iterace volá zpět uživatelem dodanou Python funkci, takže zrychlení oproti čistě Python řešiči je mírné (přibližně 2x); pohodlí spočívá v tom, že nemusíte psát řešič.
bisect()– najde kořenfna intervalu[a, b]půlením intervalu.f(a)af(b)musí mít opačná znaménka:def f(x): return x * x - 1 sp.optimize.bisect(f, 0, 4) # ~1.0
newton()– najde kořen pomocí sečnové / Newton-Raphsonovy iterace:def f(x): return x * x * x - 2.0 sp.optimize.newton(f, 3., tol=0.001, rtol=0.01) # ~1.260
fmin()– najde lokální minimum pomocí metody sestupného simplexu (Nelder-Mead):def f(x): return (x - 1) ** 2 - 1 sp.optimize.fmin(f, 3.0) # ~1.0
Rozsah pro jednu proměnnou postačuje pro většinu optimalizací na straně kamery – kalibrační konstanta senzoru, zisk, který maximalizuje měření kontrastu, práh, kde je bimodalita histogramu nejostřejší. U problémů s více proměnnými je správnou odpovědí obvykle přeformulovat problém jako malou úlohu lineární algebry, spíše než sáhnout po obecném nelineárním optimalizátoru.
6.17.3. Speciální funkce¶
scipy.special poskytuje hrstku statistických a pravděpodobnostních funkcí, které se chovají jako univerzální funkce – přijímají skalár, iterovatelný objekt nebo ndarray a vracejí ndarray typu float:
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
Chybová funkce a její doplněk se objevují v CDF Gaussova rozdělení – preferovaná aplikace pro převod mezi naměřeným z-skóre a pravděpodobností nebo pro výpočet ocasního integrálu normálního rozdělení. Funkce gama a log-gama se objevují ve výpočtech beta / chí-kvadrát / studentova-t; gammaln je numericky stabilní forma pro velké argumenty, kde by samotná gamma přetekla.
6.17.4. Náhodná čísla¶
numpy.random poskytuje třídu Generator, která vybírá vzorky z běžných rozdělení. Generátor je stavový: každé volání posune jeho vnitřní stav, takže po sobě jdoucí volání vracejí nezávislé vzorky:
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))
Výstupní dtype je vždy float. size= přijímá celé číslo (jednorozměrný výstup) nebo n-tici (n-rozměrný výstup); když je vynechán, vrátí se jediný Python float.
Generátor je vhodný pro simulaci, dithering, syntetická testovací data a jakoukoli jinou aplikaci, kde není vyžadována kryptografická síla. Není vhodný pro klíče nebo tokeny; pro ty použijte systémový zdroj náhodnosti prostřednictvím os.
6.17.5. Dostupnost v době sestavení¶
Zda je každý submodul skutečně přítomen, závisí na tom, jak byla kamera sestavena. scipy.optimize a scipy.special nejsou povoleny na každé kameře; volání funkce, kterou kamera neobsahuje, vyvolá AttributeError. dir(sp), dir(sp.optimize), dir(np.random) a podobné hlásí, co je dostupné na cílové kameře.