115 lines
4.2 KiB
C#
115 lines
4.2 KiB
C#
using System;
|
|
using System.Collections;
|
|
|
|
namespace MarketData.Numerical
|
|
{
|
|
// The column is the key, the row is the value.
|
|
// For Time series elements put the date in the column and the value in the row
|
|
public class Element
|
|
{
|
|
private double row;
|
|
private double column;
|
|
|
|
public Element()
|
|
{
|
|
}
|
|
public Element(double column, double row)
|
|
{
|
|
this.column = column;
|
|
this.row = row;
|
|
}
|
|
public double Row
|
|
{
|
|
get { return row; }
|
|
set { row = value; }
|
|
}
|
|
public double Column
|
|
{
|
|
get { return column; }
|
|
set { column = value; }
|
|
}
|
|
}
|
|
public class CatmullRom
|
|
{
|
|
private CatmullRom()
|
|
{
|
|
}
|
|
public static bool PerformSpline(Element[] sourcePairs, Element[] destPairs)
|
|
{
|
|
double a0, a1, a2, a3;
|
|
double dx, dx1, dx2;
|
|
double dy, dy1, dy2;
|
|
double endPointOne;
|
|
double endPointTwo;
|
|
double resamplingPos;
|
|
double xPoint;
|
|
int clampOne, clampTwo;
|
|
int direction;
|
|
int destSize = destPairs.Length;
|
|
int sourceSize = sourcePairs.Length;
|
|
int inputIndex, index;
|
|
|
|
a0 = a1 = a2 = a3 = endPointOne = 0;
|
|
if (sourceSize < 2 || destSize < 1) return false;
|
|
if (((Element)sourcePairs[0]).Column < ((Element)sourcePairs[1]).Column)
|
|
{
|
|
if (((Element)destPairs[0]).Column < ((Element)sourcePairs[0]).Column ||
|
|
((Element)destPairs[destSize - 1]).Column > ((Element)sourcePairs[sourceSize - 1]).Column)
|
|
direction = 0;
|
|
else direction = 1;
|
|
}
|
|
else
|
|
{
|
|
if (((Element)destPairs[0]).Column > ((Element)sourcePairs[0]).Column ||
|
|
((Element)destPairs[destSize - 1]).Column < ((Element)sourcePairs[sourceSize - 1]).Column)
|
|
direction = 0;
|
|
else direction = -1;
|
|
}
|
|
if (0 == direction) return false;
|
|
if (1 == direction) endPointTwo = ((Element)destPairs[0]).Column - 1;
|
|
else endPointTwo = ((Element)destPairs[0]).Column + 1;
|
|
for (index = 0; index < destSize; index++)
|
|
{
|
|
resamplingPos = ((Element)destPairs[index]).Column;
|
|
if ((1 == direction && resamplingPos > endPointTwo) ||
|
|
(-1 == direction && resamplingPos < endPointTwo))
|
|
{
|
|
for (inputIndex = 0; inputIndex < sourceSize && resamplingPos > ((Element)sourcePairs[inputIndex]).Column; inputIndex++) ;
|
|
if (resamplingPos < ((Element)sourcePairs[inputIndex]).Column) inputIndex--;
|
|
if (inputIndex < 0) inputIndex = 0;
|
|
else if (inputIndex == sourceSize-1) inputIndex--;
|
|
endPointOne = ((Element)sourcePairs[inputIndex]).Column;
|
|
endPointTwo = ((Element)sourcePairs[inputIndex + 1]).Column;
|
|
clampOne = Math.Max(inputIndex - 1, 0);
|
|
clampTwo = Math.Min(inputIndex + 2, sourceSize - 1);
|
|
double clampOneValue = ((Element)sourcePairs[clampOne]).Column;
|
|
double clampTwoValue = ((Element)sourcePairs[clampTwo]).Column;
|
|
dx = 1.0 / ((endPointTwo - endPointOne)==0?1:(endPointTwo-endPointOne));
|
|
dx1 = 1.0 / ((endPointTwo - clampOneValue) == 0 ? 1 : (endPointTwo - clampOneValue));
|
|
dx2 = 1.0 / (clampTwoValue-endPointOne == 0 ? 1 : (clampTwoValue - endPointOne));
|
|
dy = (((Element)sourcePairs[inputIndex + 1]).Row - ((Element)sourcePairs[inputIndex]).Row) * dx;
|
|
dy1 = (((Element)sourcePairs[inputIndex + 1]).Row - ((Element)sourcePairs[clampOne]).Row) * dx1;
|
|
dy2 = (((Element)sourcePairs[clampTwo]).Row - ((Element)sourcePairs[inputIndex]).Row) * dx2;
|
|
a0 = ((Element)sourcePairs[inputIndex]).Row;
|
|
a1 = dy1;
|
|
a2 = dx * (3 * dy - 2 * dy1 - dy2);
|
|
a3 = dx * dx * (-2 * dy + dy1 + dy2);
|
|
}
|
|
xPoint = resamplingPos - endPointOne;
|
|
((Element)destPairs[index]).Row = ((a3 * xPoint + a2) * xPoint + a1) * xPoint + a0;
|
|
}
|
|
return true;
|
|
}
|
|
public static Element[] CreateSplineSourceElements(double[] columns, double[] rows)
|
|
{
|
|
Element[] elements = new Element[columns.Length];
|
|
if (columns.Length != rows.Length) return null;
|
|
for (int index = 0; index < columns.Length; index++)
|
|
{
|
|
elements[index] = new Element(columns[index], rows[index]);
|
|
}
|
|
return elements;
|
|
}
|
|
}
|
|
} // namespace
|