Commit 4c7fe97b authored by Philipp Schäfer's avatar Philipp Schäfer
Browse files

Math: PiecewisePolynomial and Spline

- moved to math namespace as was intended
parent 5694250a
......@@ -24,65 +24,68 @@
namespace ITABase
{
//! This class represents a piecewise polynomial of order M
/**
* A piecewise polynomial persists of a series of N break points which from N-1 intervals. For each interval, there is a polynom of order M represented by M+1 coefficients.
* See "Piecewise Polynomials and Splines" by University of Lundt for more information:
* https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&cad=rja&uact=8&ved=2ahUKEwjcofWO_IrqAhUux4sKHT52AigQFjABegQIBRAB&url=http%3A%2F%2Fwww.maths.lth.se%2Fna%2Fcourses%2FFMN050%2Fmedia%2Fmaterial%2Fpart8.pdf&usg=AOvVaw068JsSpsLz4z2yUAK9Vkd0
*
* This class is inspired by the piecewise polynomials of MATLAB:
* The coefficients are arranged in groups for each interval (piece) starting the coefficient of highest order. Example:
* Coefficients [a0, b0, c0, d0, a1, b1, c1, d1] belong to interval 0 [x0, x1] and interval 1 [x1, x2] respectively.
* The coefficients for interval 1 represent the following polynomial of order 3:
* f(x) = a1(x−x1)^3 + b1(x−x1)^2 + c1(x−x1) + d1
*/
class ITA_BASE_API CPiecewisePolynomial
namespace Math
{
public:
CPiecewisePolynomial(const std::vector<float>& vdBreakPoints, const std::vector<float>& vdCoeffs, const int iOrder);
//! This class represents a piecewise polynomial of order M
/**
* A piecewise polynomial persists of a series of N break points which from N-1 intervals. For each interval, there is a polynom of order M represented by M+1 coefficients.
* See "Piecewise Polynomials and Splines" by University of Lundt for more information:
* https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&cad=rja&uact=8&ved=2ahUKEwjcofWO_IrqAhUux4sKHT52AigQFjABegQIBRAB&url=http%3A%2F%2Fwww.maths.lth.se%2Fna%2Fcourses%2FFMN050%2Fmedia%2Fmaterial%2Fpart8.pdf&usg=AOvVaw068JsSpsLz4z2yUAK9Vkd0
*
* This class is inspired by the piecewise polynomials of MATLAB:
* The coefficients are arranged in groups for each interval (piece) starting the coefficient of highest order. Example:
* Coefficients [a0, b0, c0, d0, a1, b1, c1, d1] belong to interval 0 [x0, x1] and interval 1 [x1, x2] respectively.
* The coefficients for interval 1 represent the following polynomial of order 3:
* f(x) = a1(x−x1)^3 + b1(x−x1)^2 + c1(x−x1) + d1
*/
class ITA_BASE_API CPiecewisePolynomial
{
public:
CPiecewisePolynomial(const std::vector<float>& vdBreakPoints, const std::vector<float>& vdCoeffs, const int iOrder);
//! Returns the polynomial order
inline int Order() const { return iOrder; };
//! Returns the number of intervals (pieces) between break points
inline int NumIntervals() const { return vdBreakPoints.size() - 1; };
//! Returns the number of coefficients for a single polynomial
inline int NumCoefficients() const { return Order() + 1; };
//! Returns the break points defining the intervals for the polynomials
inline const std::vector<float>& BreakPoints() const { return vdBreakPoints; };
//! Returns the Coefficients of that Polynom. Sorted according to ascending intervals [a0, b0, c0, d0, a1, b1, c1, d1]
inline const std::vector<float>& Coefficients() const { return vdCoefficients; };
//! Returns the polynomial order
inline int Order() const { return iOrder; };
//! Returns the number of intervals (pieces) between break points
inline int NumIntervals() const { return vdBreakPoints.size() - 1; };
//! Returns the number of coefficients for a single polynomial
inline int NumCoefficients() const { return Order() + 1; };
//! Returns the break points defining the intervals for the polynomials
inline const std::vector<float>& BreakPoints() const { return vdBreakPoints; };
//! Returns the Coefficients of that Polynom. Sorted according to ascending intervals [a0, b0, c0, d0, a1, b1, c1, d1]
inline const std::vector<float>& Coefficients() const { return vdCoefficients; };
//! Evaluate the piecewise polynomial at a given x value.
float Value(const float & xValue) const;
//! Evaluates the piecewise polynomial at all given x values.
std::vector<float> Value(const std::vector<float>& vdXValues) const;
//! Finds the index of Interval at a given x value
int IntervalIndex(const float xValue) const;
//! Return a piecewise polynomial containing the derivations of the polynomials of this one
CPiecewisePolynomial Derivation() const;
//! Evaluate the piecewise polynomial at a given x value.
float Value(const float& xValue) const;
//! Evaluates the piecewise polynomial at all given x values.
std::vector<float> Value(const std::vector<float>& vdXValues) const;
//! Finds the index of Interval at a given x value
int IntervalIndex(const float xValue) const;
//! Return a piecewise polynomial containing the derivations of the polynomials of this one
CPiecewisePolynomial Derivation() const;
private:
//! Returns the iterator to the first coefficient of the interval with given index
/**
* The iterator ending this set of coefficients is then:
* std::vector<float>::const_iterator itEnd = itStart + NumCoefficients();
*/
std::vector<float>::const_iterator CoefficientsOfInterval(const int idxInterval) const;
private:
//! Returns the iterator to the first coefficient of the interval with given index
/**
* The iterator ending this set of coefficients is then:
* std::vector<float>::const_iterator itEnd = itStart + NumCoefficients();
*/
std::vector<float>::const_iterator CoefficientsOfInterval(const int idxInterval) const;
private:
//! Order of polynomials
int iOrder;
//! Vector with break points. Defines the interval for each polynomial.
std::vector<float> vdBreakPoints;
//! Vector with all coefficients. Represents a 2D matrix: First dimension = number of intervals (pieces), second dimension = number of coefficients (order+1).
/**
* The Coefficients are arranged in groups for each interval (piece) starting the coefficient of highest order. Example:
* coefficients [a1, b1, c1, d1, a2, b2, c2, d2] belong to interval 1 [x1, x2] and interval2 [x2, x3] respectively.
* The coefficients for interval 1 represent the following polynomial:
* f(x) = a1(x−x1)^3 + b1(x−x1)^2 + c1(x−x1) + d1
*/
std::vector<float> vdCoefficients;
};
private:
//! Order of polynomials
int iOrder;
//! Vector with break points. Defines the interval for each polynomial.
std::vector<float> vdBreakPoints;
//! Vector with all coefficients. Represents a 2D matrix: First dimension = number of intervals (pieces), second dimension = number of coefficients (order+1).
/**
* The Coefficients are arranged in groups for each interval (piece) starting the coefficient of highest order. Example:
* coefficients [a1, b1, c1, d1, a2, b2, c2, d2] belong to interval 1 [x1, x2] and interval2 [x2, x3] respectively.
* The coefficients for interval 1 represent the following polynomial:
* f(x) = a1(x−x1)^3 + b1(x−x1)^2 + c1(x−x1) + d1
*/
std::vector<float> vdCoefficients;
};
}
}
#endif // IW_ITA_BASE_PIECEWISEPOLYNOMIAL
......@@ -25,10 +25,13 @@
namespace ITABase
{
//! Uses cubic splines to create a piecewise polynomial (order 3) for the given data pairs vdSupportingPoints and vdDataPoints. vdSupportingPoints need to be sorted in ascending order
ITA_BASE_API CPiecewisePolynomial CubicSpline(const std::vector<float>& vdSupportingPoints, const std::vector<float>& vdDataPoints);
//! Uses cubic splines to create a piecewise polynomial (order 3) for the given data pairs vdSupportingPoints and vdDataPoints. Evaluates that Polynom at vdCostumPoints. vdSupportingPoints need to be sorted in ascending order.
ITA_BASE_API std::vector<float> CubicSpline(const std::vector<float>& vdSupportingPoints, const std::vector<float>& vdDataPoints, const std::vector<float>& vdCostumPoints);
namespace Math
{
//! Uses cubic splines to create a piecewise polynomial (order 3) for the given data pairs vdSupportingPoints and vdDataPoints. vdSupportingPoints need to be sorted in ascending order
ITA_BASE_API CPiecewisePolynomial CubicSpline(const std::vector<float>& vdSupportingPoints, const std::vector<float>& vdDataPoints);
//! Uses cubic splines to create a piecewise polynomial (order 3) for the given data pairs vdSupportingPoints and vdDataPoints. Evaluates that Polynom at vdCostumPoints. vdSupportingPoints need to be sorted in ascending order.
ITA_BASE_API std::vector<float> CubicSpline(const std::vector<float>& vdSupportingPoints, const std::vector<float>& vdDataPoints, const std::vector<float>& vdCostumPoints);
}
}
#endif // IW_ITA_BASE_SPLINE
......@@ -7,6 +7,7 @@
#include <ITABase/Math/LinearAlgebra.h>
using namespace ITABase;
using namespace ITABase::Math;
CPiecewisePolynomial::CPiecewisePolynomial(const std::vector<float>& vdBreakPoints, const std::vector<float>& vdCoeffs, const int iOrder)
: iOrder(iOrder)
......@@ -40,7 +41,7 @@ float CPiecewisePolynomial::Value(const float & xValue) const
return fResult;
}
std::vector<float> ITABase::CPiecewisePolynomial::Value(const std::vector<float>& vdXValues) const
std::vector<float> CPiecewisePolynomial::Value(const std::vector<float>& vdXValues) const
{
std::vector<float> result(vdXValues.size());
for (int i = 0; i < vdXValues.size(); i++)
......@@ -48,7 +49,7 @@ std::vector<float> ITABase::CPiecewisePolynomial::Value(const std::vector<float>
return result;
}
int ITABase::CPiecewisePolynomial::IntervalIndex(const float xValue) const
int CPiecewisePolynomial::IntervalIndex(const float xValue) const
{
if (xValue < vdBreakPoints[0] || xValue > vdBreakPoints[NumIntervals()])
ITA_EXCEPT_INVALID_PARAMETER("xValue is out of bounds");
......@@ -79,7 +80,7 @@ CPiecewisePolynomial CPiecewisePolynomial::Derivation() const
return CPiecewisePolynomial(vdBreakPoints, vdNewCoeffs, iNewOrder);
}
std::vector<float>::const_iterator ITABase::CPiecewisePolynomial::CoefficientsOfInterval(const int idxInterval) const
std::vector<float>::const_iterator CPiecewisePolynomial::CoefficientsOfInterval(const int idxInterval) const
{
if (idxInterval < 0 || idxInterval >= NumIntervals())
ITA_EXCEPT_INVALID_PARAMETER("Index for interval is out of bounds.");
......
......@@ -5,8 +5,9 @@
#include <ITABase/Math/LinearAlgebra.h>
using namespace ITABase;
using namespace ITABase::Math;
ITA_BASE_API CPiecewisePolynomial ITABase::CubicSpline(const std::vector<float>& vdSupportingPoints, const std::vector<float>& vdDataPoints)
CPiecewisePolynomial Math::CubicSpline(const std::vector<float>& vdSupportingPoints, const std::vector<float>& vdDataPoints)
{
/*setUp the bandmatrix M with the the h values. The vector with the coefficent b is called b.
The vector with the linear approximations on the right hand side is called r.
......@@ -51,7 +52,7 @@ ITA_BASE_API CPiecewisePolynomial ITABase::CubicSpline(const std::vector<float>&
vdR[i] = 3 * ((vdDataPoints[i + 2] - vdDataPoints[i + 1]) / vdH[i + 1] - (vdDataPoints[i + 1] - vdDataPoints[i]) / vdH[i]);
//solve bandmatrix and get the other coefficients
std::vector<float> vdB = Math::BandmatrixSolver(vdLower, vdMiddle, vdUpper, vdR);
std::vector<float> vdB = BandmatrixSolver(vdLower, vdMiddle, vdUpper, vdR);
vdB.insert(vdB.begin(), 0.0);
std::vector<float> vdA(iPoints - 1);
......@@ -81,7 +82,7 @@ ITA_BASE_API CPiecewisePolynomial ITABase::CubicSpline(const std::vector<float>&
return CPiecewisePolynomial(vdSupportingPoints, vdCoefficients, iPolynomialOrder);
}
ITA_BASE_API std::vector<float> ITABase::CubicSpline(const std::vector<float>& vdSupportingPoints, const std::vector<float>& vdDataPoints, const std::vector<float>& vdCostumPoints)
std::vector<float> Math::CubicSpline(const std::vector<float>& vdSupportingPoints, const std::vector<float>& vdDataPoints, const std::vector<float>& vdCostumPoints)
{
CPiecewisePolynomial myPoly = CubicSpline(vdSupportingPoints, vdDataPoints);
return myPoly.Value(vdCostumPoints);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment