K-alpha: Difference between revisions

From formulasearchengine
Jump to navigation Jump to search
en>Huntster
Fix.
fixed a typo in \alpha
Line 1: Line 1:
In the [[mathematics|mathematical]] subfield of [[numerical analysis]], '''monotone cubic interpolation''' is a variant of [[cubic interpolation]] that preserves [[Monotone function|monotonicity]] of the [[data set]] being interpolated.
Nice to satisfy you, my name is Ling and I completely dig that title. What she enjoys doing is taking part in croquet and she is attempting to make it a occupation. He currently lives in Idaho and his mothers and fathers live nearby. She is currently a cashier but quickly she'll be on her personal.<br><br>Also visit my blog: [http://forsaken-Ranger.5Cz.de/index.php?mod=users&action=view&id=1945 car warranty]
 
Monotonicity is preserved by [[linear interpolation]] but not guaranteed by [[cubic interpolation]].
 
==Monotone cubic Hermite interpolation==
[[Image:MonotCubInt.png|thumb|300px|right|Example showing non-monotone cubic interpolation (in red) and monotone cubic interpolation (in blue) of a monotone data set.]]
Monotone interpolation can be accomplished using [[cubic Hermite spline]] with the tangents <math>m_i</math> modified to ensure the monotonicity of the resulting Hermite spline.
 
===Interpolant selection===
 
There are several ways of selecting interpolating tangents for each data point. This section will outline the use of the Fritsch–Carlson method.
 
Let the data points be <math>(x_k,y_k)</math> for <math>k=1,...,n</math>
# Compute the slopes of the [[secant line]]s between successive points:<blockquote><math>\Delta_k =\frac{y_{k+1}-y_k}{x_{k+1}-x_k}</math></blockquote> for <math>k=1,\dots,n-1</math>.
# Initialize the tangents at every data point as the average of the secants, <blockquote><math>m_k = \frac{\Delta_{k-1}+\Delta_k}{2}</math></blockquote> for <math>k=2,\dots,n-1</math>; these may be updated in further steps. For the endpoints, use one-sided differences: <blockquote><math>m_1 = \Delta_1 \quad \text{and} \quad m_n = \Delta_{n-1}</math></blockquote>
# For <math>k=1,\dots,n-1</math>, if <math>\Delta_k = 0</math> (if two successive <math>y_k=y_{k+1}</math> are equal), then set <math>m_k = m_{k+1} = 0,</math> as the spline connecting these points must be flat to preserve monotonicity. Ignore step 4 and 5 for those <math>k</math>.
# Let <math>\alpha_k = m_k/\Delta_k</math> and <math>\beta_k = m_{k+1}/\Delta_k</math>. If <math>\alpha_k</math> or <math>\beta_{k-1}</math> are computed to be less than zero, then the input data points are not strictly monotone, and <math>(x_k,y_k)</math> is a local extremum. In such cases, piecewise monotone curves can still be generated by choosing <math>m_{k}=0</math>, although global strict monotonicity is not possible.
# To prevent [[overshoot]] and ensure monotonicity, at least one of the following conditions must be met:
##the function <blockquote><math>\phi(\alpha, \beta) = \alpha - \frac{(2 \alpha + \beta - 3)^2}{3(\alpha + \beta - 2)}</math></blockquote> must have a value greater than or equal to zero;
##<math>\alpha + 2\beta - 3 \le 0</math>; or
##<math>2\alpha + \beta - 3 \le 0</math>.
If monotonicity must be strict then <math>\phi(\alpha, \beta)</math> must have a value strictly greater than zero.
 
One simple way to satisfy this constraint is to restrict the magnitude of vector <math>(\alpha_k, \beta_k)</math> to a circle of radius 3. That is, if <math>\alpha_k^2 + \beta_k^2 > 9</math>, then set <math>m_k = \tau_k \alpha_k \Delta_k</math> and <math>m_{k+1} = \tau_k \beta_k \Delta_k</math> where <math>\tau_k = \frac{3}{\sqrt{\alpha_k^2 + \beta_k^2}}</math>.
 
Alternatively it is sufficient to restrict <math>\alpha_k \le 3</math> and <math>\beta_k \le 3</math>. To accomplish this if <math>\alpha_k > 3</math>, then set <math>m_k = 3\times \Delta_k</math>. Similarly for <math>\beta</math>.
 
Note that only one pass of the algorithm is required.
 
===Cubic interpolation===
 
After the preprocessing, evaluation of the interpolated spline is equivalent to [[cubic Hermite spline]], using the data <math>x_k</math>,  <math>y_k</math>, and <math>m_k</math> for <math>k=1,...,n</math>.
 
To evaluate at <math>x</math>, find the smallest value larger than <math>x</math>, <math>x_\text{upper}</math>, and the largest value smaller than <math>x</math>, <math>x_\text{lower}</math>, among <math>x_k</math> such that <math>x_\text{lower} \leq x \leq x_\text{upper}</math>. Calculate
:<math>h = x_\text{upper}-x_\text{lower}</math> and <math>t = \frac{x - x_\text{lower}}{h}</math>
then the interpolant is
:<math>f_\text{interpolated}(x) = y_\text{lower} h_{00}(t) + h m_\text{lower} h_{10}(t) + y_\text{upper} h_{01}(t) + h m_\text{upper}h_{11}(t)</math>
where <math>h_{ii}</math> are the basis functions for the [[cubic Hermite spline]].
 
==Example implementation==
The following [[JavaScript]] implementation takes a data set and produces a Fritsch-Carlson cubic spline interpolant function:
<syntaxhighlight lang="javascript">
/* Fritsch-Carlson monotone cubic spline interpolation
  Usage example:
var f = createInterpolant([0, 1, 2, 3], [0, 1, 4, 9]);
var message = '';
for (var x = 0; x <= 3; x += 0.5) {
var xSquared = f(x);
message += x + ' squared is about ' + xSquared + '\n';
}
alert(message);
*/
var createInterpolant = function(xs, ys) {
var i, length = xs.length;
// Deal with length issues
if (length != ys.length) { throw 'Need an equal count of xs and ys.'; }
if (length === 0) { return function(x) { return 0; }; }
if (length === 1) {
// Impl: Precomputing the result prevents problems if ys is mutated later and allows garbage collection of ys
// Impl: Unary plus properly converts values to numbers
var result = +ys[0];
return function(x) { return result; };
}
// Rearrange xs and ys so that xs is sorted
var indexes = [];
for (i = 0; i < length; i++) { indexes.push(i); }
indexes.sort(function(a, b) { return xs[a] < xs[b] ? -1 : 1; });
var oldXs = xs, oldYs = ys;
// Impl: Creating new arrays also prevents problems if the input arrays are mutated later
xs = []; ys = [];
// Impl: Unary plus properly converts values to numbers
for (i = 0; i < length; i++) { xs.push(+oldXs[indexes[i]]); ys.push(+oldYs[indexes[i]]); }
// Get consecutive differences and slopes
var dys = [], dxs = [], ms = [];
for (i = 0; i < length - 1; i++) {
var dx = xs[i + 1] - xs[i], dy = ys[i + 1] - ys[i];
dxs.push(dx); dys.push(dy); ms.push(dy/dx);
}
// Get degree-1 coefficients
var c1s = [ms[0]];
for (i = 0; i < dxs.length - 1; i++) {
var m = ms[i], mNext = ms[i + 1];
if (m*mNext <= 0) {
c1s.push(0);
} else {
var dx = dxs[i], dxNext = dxs[i + 1], common = dx + dxNext;
c1s.push(3*common/((common + dxNext)/m + (common + dx)/mNext));
}
}
c1s.push(ms[ms.length - 1]);
// Get degree-2 and degree-3 coefficients
var c2s = [], c3s = [];
for (i = 0; i < c1s.length - 1; i++) {
var c1 = c1s[i], m = ms[i], invDx = 1/dxs[i], common = c1 + c1s[i + 1] - m - m;
c2s.push((m - c1 - common)*invDx); c3s.push(common*invDx*invDx);
}
// Return interpolant function
return function(x) {
// The rightmost point in the dataset should give an exact result
var i = xs.length - 1;
if (x == xs[i]) { return ys[i]; }
// Search for the interval x is in, returning the corresponding y if x is one of the original xs
var low = 0, mid, high = c3s.length - 1;
while (low <= high) {
mid = Math.floor(0.5*(low + high));
var xHere = xs[mid];
if (xHere < x) { low = mid + 1; }
else if (xHere > x) { high = mid - 1; }
else { return ys[mid]; }
}
i = Math.max(0, high);
// Interpolate
var diff = x - xs[i], diffSq = diff*diff;
return ys[i] + c1s[i]*diff + c2s[i]*diffSq + c3s[i]*diff*diffSq;
};
};
</syntaxhighlight>
 
==References==
*{{cite journal
  | last = Fritsch
  | first = F. N.
  | coauthors = Carlson, R. E.
  | title = Monotone Piecewise Cubic Interpolation
  | journal = [[SIAM Journal on Numerical Analysis]]
  | volume = 17
  | issue = 2
  | pages = 238–246
  | publisher = SIAM
  | date = 1980
  | doi = 10.1137/0717021
}}
 
==External links==
* [[GPL]]v3 licensed [[C++]] implementation: [https://github.com/OPM/opm-core/blob/master/opm/core/utility/MonotCubicInterpolator.cpp MonotCubicInterpolator.cpp] [https://github.com/OPM/opm-core/blob/master/opm/core/utility/MonotCubicInterpolator.hpp MonotCubicInterpolator.hpp]
 
[[Category:Interpolation]]
[[Category:Splines]]

Revision as of 11:29, 5 February 2014

Nice to satisfy you, my name is Ling and I completely dig that title. What she enjoys doing is taking part in croquet and she is attempting to make it a occupation. He currently lives in Idaho and his mothers and fathers live nearby. She is currently a cashier but quickly she'll be on her personal.

Also visit my blog: car warranty