6.16. Kurvor och integration

Matematiksidorna täckte operationer som tar en array in och producerar en array (eller skalär) ut – aritmetik, reduktioner, broadcasting. Denna sida täcker en annan klass av operationer: sådana som behandlar arrayen som en samplad funktion och ställer frågor om själva funktionen. Att interpolera mellan sampel, anpassa en kurva till dem, integrera under dem, falta dem med en annan buffert.

Alla dessa accepterar ndarray-indata och returnerar antingen en float-skalär eller en float-ndarray.

6.16.1. Interpolation

interp() gör endimensionell linjär interpolation. xp är en monotont växande 1-D-array av oberoende värden; fp är de matchande beroende värdena; x är där interpolanten ska utvärderas:

xp = np.array([0.0, 1.0, 2.0, 3.0])
fp = np.array([10.0, 20.0, 25.0, 30.0])
x  = np.array([0.5, 1.5, 2.5])

np.interp(x, xp, fp)
# array([15.0, 22.5, 27.5])

Utanför intervallet [xp[0], xp[-1]] klipps resultatet till fp[0] respektive fp[-1]; nyckelorden left= och right= åsidosätter dessa ändpunkter.

Används på kameran för att mappa om en kalibreringstabell till godtyckliga sampelpositioner – en temperatur-till-spänning-tabell från en termistor, en icke-linjär pixelresponskurva, en gammauppslagning per kanal. Ett biblioteksanrop, ett pass över indata, ingen Python-loop.

6.16.2. Polynomanpassning och utvärdering

polyfit() anpassar ett polynom av grad deg till datapunkterna (x, y) med minsta kvadratmetoden och returnerar koefficienterna (högsta graden först):

x = np.array([0.0, 1.0, 2.0, 3.0, 4.0])
y = np.array([0.0, 1.1, 3.9, 9.1, 15.8])

coeffs = np.polyfit(x, y, 2)
# array([1.0, 0.0, 0.0])  (approximately)

När x utelämnas används range(len(y)) – användbart för att snabbt anpassa ett polynom till en regelbundet samplad buffert utan tillhörande x-axel:

np.polyfit(y, 2)

polyval() utvärderar polynomet vars koefficienter är p vid x. Indata x kan vara en skalär (returnerar en float) eller en ndarray (returnerar en ndarray):

p = np.polyfit(x, y, 2)
fitted = np.polyval(p, x)

Den naturliga kombinationen är att anropa polyfit en gång vid kalibreringstillfället, lagra koefficienterna och anropa polyval för att utvärdera den resulterande kurvan varje bildruta. Polynomutvärderingssteget är en handfull float-operationer per sampel, vilket är billigt även på de minsta kamerorna.

6.16.3. Faltning

convolve() returnerar den fullängds diskreta linjära faltningen av två 1-D-arrayer. Endast full-läget är implementerat; utdatans längd är len(a) + len(v) - 1. Slica resultatet för samma effekt som same- och valid-lägena som skrivbords-numpy erbjuder:

a = np.array([1.0, 2.0, 3.0])
v = np.array([0.5, 0.5])

np.convolve(a, v)
# array([0.5, 1.5, 2.5, 1.5])

Användbart för korta FIR-filter och utjämningskärnor (box, triangel, gauss) där det är överdrivet att sätta upp en SOS-kedja. Körtiden är proportionell mot produkten av de två arraylängderna – bra för korta kärnor men blir snabbt dyrare än en FFT-faltning för långa.

6.16.4. Trapetsintegration

trapz() integrerar en samplad funktion med den sammansatta trapetsregeln:

x = np.linspace(0, np.pi, num=128)
y = np.sin(x)
np.trapz(y, x)             # ~ 2.0

Skicka dx= när sampelavståndet är jämnt och bara steget spelar roll; skicka x= när samplen inte är jämnt fördelade. Rätt anrop för att integrera redan insamlade sensordata, där den analytiska formen inte är tillgänglig.

För sampeldata som har bandbegränsats (en ljudbuffert efter ett antivikningsfilter, till exempel) konvergerar trapetsregeln som kvadraten på antalet sampel, vilket betyder att en fördubbling av buffertlängden minskar felet med en faktor fyra.

När integranden inte är en buffert med sampel utan en Python-funktion som applikationen kan utvärdera vid godtyckliga punkter, är en annan familj av lösare rätt anrop.