Monotónní kubická interpolace - Monotone cubic interpolation
V matematický pole numerická analýza, monotónní kubická interpolace je varianta kubická interpolace který zachovává monotónnost z soubor dat interpolován.
Monotónnost je zachována lineární interpolace ale není zaručeno kubická interpolace.
Monotónní kubická Hermitova interpolace
Monotónní interpolaci lze provést pomocí kubický Hermitův spline s tečnami upraveno, aby byla zajištěna monotónnost výsledného Hermitova spline.
Algoritmus je k dispozici také pro monotónní kvintický Hermitova interpolace.
Interpolantní výběr
Existuje několik způsobů výběru interpolačních tečen pro každý datový bod. V této části je popsáno použití metody Fritsch-Carlson. Všimněte si, že je vyžadován pouze jeden průchod algoritmu.
Nechť jsou datové body indexováno v seřazeném pořadí pro .
- Vypočítejte sklon svahu sekanční linie mezi po sobě následujícími body:
pro . - Tato přiřazení jsou prozatímní a ve zbývajících krocích mohou být nahrazena. Inicializujte tangenty v každém datovém bodě interiéru jako průměr secants,
pro .
Pro koncové body použijte jednostranné rozdíly:
Li a mít opačné znaky, nastavit ..
- Pro kde vůbec (kdykoli dva po sobě jdoucí jsou rovny),
soubor protože spline spojující tyto body musí být plochá, aby byla zachována monotónnost.
Pro tyto kroky 4 a 5 ignorujte . - Nechat
Pokud ano nebo je záporné, pak vstupní datové body nejsou striktně monotónní a je místní extremum. V takových případech, po částech monotónní křivky lze stále generovat výběrem -li nebo -li , ačkoli přísná monotónnost není globálně možná..
- Aby se zabránilo přestřelení a zajistit monotónnost, musí být splněna alespoň jedna z následujících tří podmínek:
- a) funkce
, nebo
- b) , nebo
- (C) .
- K zajištění přísné monotónnosti stačí pouze podmínka (a): musí být pozitivní.
- Jedním z jednoduchých způsobů, jak uspokojit toto omezení, je omezit vektor do kruhu o poloměru 3. To znamená, že pokud , pak nastavte
a změňte měřítko tečen pomocí,
.
- Jinak stačí omezit a . Toho dosáhnout, pokud , pak nastavte .
- a) funkce
Kubická interpolace
Po předzpracování výše je vyhodnocení interpolovaného splajnu ekvivalentní kubický Hermitův spline pomocí údajů , , a pro .
Vyhodnotit na , najděte index v pořadí kde , leží mezi , a , to znamená: . Vypočítat
pak je interpolovaná hodnota
kde jsou základní funkce pro kubický Hermitův spline.
Příklad implementace
Následující JavaScript implementace vezme datovou sadu a vytvoří monotónní kubickou spline interpolantovou funkci:
/ * Monotónní kubická spline interpolace Příklad použití:var f = createInterpolant ([0, 1, 2, 3, 4], [0, 1, 4, 9, 16]);var zpráva = '';pro (var x = 0; x <= 4; x + = 0,5) {var xSquared = f (x);zpráva + = x + 'na druhou je o' + xSquared + ' n'; }výstraha (zpráva);*/var createInterpolant = funkce(xs, ys) { var i, délka = xs.délka; // Řešení problémů s délkou -li (délka != ys.délka) { házet "Potřebujete stejný počet xs a ys."; } -li (délka === 0) { vrátit se funkce(X) { vrátit se 0; }; } -li (délka === 1) { // Impl: Předpočítání výsledku zabrání problémům, pokud je ys později mutován, a umožní smetí ys // Impl: Unary plus správně převádí hodnoty na čísla var výsledek = +ys[0]; vrátit se funkce(X) { vrátit se výsledek; }; } // Uspořádejte xs a ys tak, aby bylo xs tříděno var indexy = []; pro (i = 0; i < délka; i++) { indexy.tlačit(i); } indexy.třídit(funkce(A, b) { vrátit se xs[A] < xs[b] ? -1 : 1; }); var oldXs = xs, oldYs = ys; // Impl: Vytváření nových polí také zabrání problémům, pokud budou vstupní pole později mutována xs = []; ys = []; // Impl: Unary plus správně převádí hodnoty na čísla pro (i = 0; i < délka; i++) { xs.tlačit(+oldXs[indexy[i]]); ys.tlačit(+oldYs[indexy[i]]); } // Získejte po sobě jdoucí rozdíly a svahy var dys = [], dxs = [], slečna = []; pro (i = 0; i < délka - 1; i++) { var dx = xs[i + 1] - xs[i], dy = ys[i + 1] - ys[i]; dxs.tlačit(dx); dys.tlačit(dy); slečna.tlačit(dy/dx); } // Získejte koeficienty stupně 1 var c1s = [slečna[0]]; pro (i = 0; i < dxs.délka - 1; i++) { var m = slečna[i], mDalší = slečna[i + 1]; -li (m*mDalší <= 0) { c1s.tlačit(0); } jiný { var dx_ = dxs[i], dxDalší = dxs[i + 1], běžný = dx_ + dxDalší; c1s.tlačit(3*běžný/((běžný + dxDalší)/m + (běžný + dx_)/mDalší)); } } c1s.tlačit(slečna[slečna.délka - 1]); // Získejte koeficienty stupně 2 a stupně 3 var c2s = [], c3s = []; pro (i = 0; i < c1s.délka - 1; i++) { var c1 = c1s[i], m_ = slečna[i], invDx = 1/dxs[i], běžný_ = c1 + c1s[i + 1] - m_ - m_; c2s.tlačit((m_ - c1 - běžný_)*invDx); c3s.tlačit(běžný_*invDx*invDx); } // Návrat interpolantní funkce vrátit se funkce(X) { // Bod zcela vpravo v datové sadě by měl poskytnout přesný výsledek var i = xs.délka - 1; -li (X == xs[i]) { vrátit se ys[i]; } // Hledání intervalu x je in, vrací odpovídající y, pokud x je jedním z původních xs var nízký = 0, střední, vysoký = c3s.délka - 1; zatímco (nízký <= vysoký) { střední = Matematika.podlaha(0.5*(nízký + vysoký)); var x tady = xs[střední]; -li (x tady < X) { nízký = střední + 1; } jiný -li (x tady > X) { vysoký = střední - 1; } jiný { vrátit se ys[střední]; } } i = Matematika.max(0, vysoký); // Interpolovat var rozdíl = X - xs[i], diffSq = rozdíl*rozdíl; vrátit se ys[i] + c1s[i]*rozdíl + c2s[i]*diffSq + c3s[i]*rozdíl*diffSq; };};
Reference
- Fritsch, F. N .; Carlson, R. E. (1980). "Monotónní po částech kubická interpolace". Časopis SIAM o numerické analýze. SIAM. 17 (2): 238–246. doi:10.1137/0717021.
- Dougherty, R.L .; Edelman, A .; Hyman, J. M. (duben 1989). „Pozitivní, monotonická nebo konvexní kubická a kvintická Hermitova interpolace. Matematika výpočtu. 52 (186): 471–494. doi:10.2307/2008477.
externí odkazy
- GPLv 2 licencované C ++ implementace: MonotCubicInterpolator.cpp MonotCubicInterpolator.hpp