patterncsharpMinor
Monotone cubic interpolation
Viewed 0 times
interpolationmonotonecubic
Problem
http://en.wikipedia.org/wiki/Monotone_cubic_interpolation
We have implemented it using the formula from Wikipedia :
```
public class MonotoneCubicSplineInterpolation
{
public static double[] Calc(double[] xs, double[] ys, double[] x_interp)
{
var length = xs.Length;
// Deal with length issues
if (length != ys.Length)
{
IPDevLoggerWrapper.Error("Need an equal count of xs and ys");
throw new Exception("Need an equal count of xs and ys");
}
if (length == 0)
{
return null;
}
if (length == 1)
{
return new double[] {ys[0]};
}
// Get consecutive differences and slopes
var delta = new double[length - 1];
var m = new double[length];
for (int i = 0; i 0)
{
m[i] = (delta[i - 1] + delta[i]) / 2;
}
}
var toFix = new List();
for (int i = 1; i 0 && delta[i - 1] 0))
{
toFix.Add(i);
}
}
foreach (var val in toFix)
{
m[val] = 0;
}
m[0] = delta[0];
m[length - 1] = delta[length - 2];
toFix.Clear();
for (int i = 0; i 9)
{
toFix.Add(i);
}
}
foreach (var val in toFix)
{
m[val] = tau[val] alpha[val] delta[val];
m[val + 1] = tau[val] beta[val] delta[val];
}
var y_interp = new double[x_interp.Length];
int ind = 0;
foreach (var x in x_interp)
{
int i;
for (i = xs.Length - 2; i >= 0; --i)
{
if (xs[i] <= x)
We have implemented it using the formula from Wikipedia :
```
public class MonotoneCubicSplineInterpolation
{
public static double[] Calc(double[] xs, double[] ys, double[] x_interp)
{
var length = xs.Length;
// Deal with length issues
if (length != ys.Length)
{
IPDevLoggerWrapper.Error("Need an equal count of xs and ys");
throw new Exception("Need an equal count of xs and ys");
}
if (length == 0)
{
return null;
}
if (length == 1)
{
return new double[] {ys[0]};
}
// Get consecutive differences and slopes
var delta = new double[length - 1];
var m = new double[length];
for (int i = 0; i 0)
{
m[i] = (delta[i - 1] + delta[i]) / 2;
}
}
var toFix = new List();
for (int i = 1; i 0 && delta[i - 1] 0))
{
toFix.Add(i);
}
}
foreach (var val in toFix)
{
m[val] = 0;
}
m[0] = delta[0];
m[length - 1] = delta[length - 2];
toFix.Clear();
for (int i = 0; i 9)
{
toFix.Add(i);
}
}
foreach (var val in toFix)
{
m[val] = tau[val] alpha[val] delta[val];
m[val + 1] = tau[val] beta[val] delta[val];
}
var y_interp = new double[x_interp.Length];
int ind = 0;
foreach (var x in x_interp)
{
int i;
for (i = xs.Length - 2; i >= 0; --i)
{
if (xs[i] <= x)
Solution
Don't throw
It forces client code to catch any subclass of
The
Here you're using
From MSDN
The
equivalent values can be unequal due to the differing precision of the
two values.
That link covers two techniques for dealing with this.
As far as I can tell,
Can be rewritten as
Exceptionthrow new Exception("Need an equal count of xs and ys");It forces client code to catch any subclass of
Exception. In this case I would throw an ArgumentException.The
continue at the end of the last loop is redundant.Here you're using
double.Equalsif (delta[i] == 0)From MSDN
The
Equals method should be used with caution, because two apparentlyequivalent values can be unequal due to the differing precision of the
two values.
That link covers two techniques for dealing with this.
As far as I can tell,
toFix can be removed. For example,var toFix = new List();
for (int i = 1; i 0 && delta[i - 1] 0))
{
toFix.Add(i);
}
}
foreach (var val in toFix)
{
m[val] = 0;
}Can be rewritten as
for (int i = 1; i 0 && delta[i - 1] 0))
{
m[i] = 0;
}
}Code Snippets
throw new Exception("Need an equal count of xs and ys");if (delta[i] == 0)var toFix = new List<int>();
for (int i = 1; i < length - 1; i++)
{
if ((delta[i] > 0 && delta[i - 1] < 0) || (delta[i] < 0 && delta[i - 1] > 0))
{
toFix.Add(i);
}
}
foreach (var val in toFix)
{
m[val] = 0;
}for (int i = 1; i < length - 1; i++)
{
if ((delta[i] > 0 && delta[i - 1] < 0) || (delta[i] < 0 && delta[i - 1] > 0))
{
m[i] = 0;
}
}Context
StackExchange Code Review Q#73622, answer score: 4
Revisions (0)
No revisions yet.