Classes | Public Types | Public Member Functions | Protected Member Functions | Protected Attributes

QwtSpline Class Reference

A class for spline interpolation. More...

#include <qwt_spline.h>

Collaboration diagram for QwtSpline:
Collaboration graph
[legend]

List of all members.

Classes

class  PrivateData

Public Types

enum  SplineType { Natural, Periodic }
 

Spline type.

More...

Public Member Functions

 QwtSpline ()
 Constructor.
 QwtSpline (const QwtSpline &)
 ~QwtSpline ()
 Destructor.
QwtSplineoperator= (const QwtSpline &)
void setSplineType (SplineType)
SplineType splineType () const
bool setPoints (const QMemArray< QwtDoublePoint > &points)
 Calculate the spline coefficients.
QMemArray< QwtDoublePointpoints () const
void reset ()
 Free allocated memory and set size to 0.
bool isValid () const
 True if valid.
double value (double x) const
const QMemArray< double > & coefficientsA () const
const QMemArray< double > & coefficientsB () const
const QMemArray< double > & coefficientsC () const

Protected Member Functions

bool buildNaturalSpline (const QMemArray< QwtDoublePoint > &)
 Determines the coefficients for a natural spline.
bool buildPeriodicSpline (const QMemArray< QwtDoublePoint > &)
 Determines the coefficients for a periodic spline.

Protected Attributes

PrivateDatad_data

Detailed Description

A class for spline interpolation.

The QwtSpline class is used for cubical spline interpolation. Two types of splines, natural and periodic, are supported.

Usage:
  1. First call setPoints() to determine the spline coefficients for a tabulated function y(x).
  2. After the coefficients have been set up, the interpolated function value for an argument x can be determined by calling QwtSpline::value().
Example:
#include <qwt_spline.h>

QPolygonF interpolate(const QPolygonF& points, int numValues)
{
    QwtSpline spline;
    if ( !spline.setPoints(points) ) 
        return points;

    QPolygonF interpolatedPoints(numValues);

    const double delta = 
        (points[numPoints - 1].x() - points[0].x()) / (points.size() - 1);
    for(i = 0; i < points.size(); i++)  / interpolate
    {
        const double x = points[0].x() + i * delta;
        interpolatedPoints[i].setX(x);
        interpolatedPoints[i].setY(spline.value(x));
    }
    return interpolatedPoints;
}

Definition at line 77 of file qwt_spline.h.


Member Enumeration Documentation

Spline type.

Enumerator:
Natural 
Periodic 

Definition at line 81 of file qwt_spline.h.


Constructor & Destructor Documentation

QwtSpline::QwtSpline (  )

Constructor.

Definition at line 73 of file qwt_spline.cpp.

References d_data.

{
    d_data = new PrivateData;
}
QwtSpline::QwtSpline ( const QwtSpline other )

Copy constructor

Parameters:
otherSpline used for initilization

Definition at line 82 of file qwt_spline.cpp.

References d_data.

{
    d_data = new PrivateData(*other.d_data);
}
QwtSpline::~QwtSpline (  )

Destructor.

Definition at line 98 of file qwt_spline.cpp.

References d_data.

{
    delete d_data;
}

Member Function Documentation

bool QwtSpline::buildNaturalSpline ( const QMemArray< QwtDoublePoint > &  points ) [protected]

Determines the coefficients for a natural spline.

Returns:
true if successful

Definition at line 241 of file qwt_spline.cpp.

{
    int i;
    
#if QT_VERSION < 0x040000
    const QwtDoublePoint *p = points.data();
#else
    const QPointF *p = points.data();
#endif
    const int size = points.size();

    double *a = d_data->a.data();
    double *b = d_data->b.data();
    double *c = d_data->c.data();

    //  set up tridiagonal equation system; use coefficient
    //  vectors as temporary buffers
    QwtArray<double> h(size-1);
    for (i = 0; i < size - 1; i++) 
    {
        h[i] = p[i+1].x() - p[i].x();
        if (h[i] <= 0)
            return false;
    }
    
    QwtArray<double> d(size-1);
    double dy1 = (p[1].y() - p[0].y()) / h[0];
    for (i = 1; i < size - 1; i++)
    {
        b[i] = c[i] = h[i];
        a[i] = 2.0 * (h[i-1] + h[i]);

        const double dy2 = (p[i+1].y() - p[i].y()) / h[i];
        d[i] = 6.0 * ( dy1 - dy2);
        dy1 = dy2;
    }

    //
    // solve it
    //
    
    // L-U Factorization
    for(i = 1; i < size - 2;i++)
    {
        c[i] /= a[i];
        a[i+1] -= b[i] * c[i]; 
    }

    // forward elimination
    QwtArray<double> s(size);
    s[1] = d[1];
    for ( i = 2; i < size - 1; i++)
       s[i] = d[i] - c[i-1] * s[i-1];
    
    // backward elimination
    s[size - 2] = - s[size - 2] / a[size - 2];
    for (i = size -3; i > 0; i--)
       s[i] = - (s[i] + b[i] * s[i+1]) / a[i];
    s[size - 1] = s[0] = 0.0;

    //
    // Finally, determine the spline coefficients
    //
    for (i = 0; i < size - 1; i++)
    {
        a[i] = ( s[i+1] - s[i] ) / ( 6.0 * h[i]);
        b[i] = 0.5 * s[i];
        c[i] = ( p[i+1].y() - p[i].y() ) / h[i] 
            - (s[i+1] + 2.0 * s[i] ) * h[i] / 6.0; 
    }

    return true;
}
bool QwtSpline::buildPeriodicSpline ( const QMemArray< QwtDoublePoint > &  points ) [protected]

Determines the coefficients for a periodic spline.

Returns:
true if successful

Definition at line 323 of file qwt_spline.cpp.

References qwtSqr(), QuadProgPP::sqrt(), and QuadProgPP::sum().

{
    int i;
    
#if QT_VERSION < 0x040000
    const QwtDoublePoint *p = points.data();
#else
    const QPointF *p = points.data();
#endif
    const int size = points.size();

    double *a = d_data->a.data();
    double *b = d_data->b.data();
    double *c = d_data->c.data();

    QwtArray<double> d(size-1);
    QwtArray<double> h(size-1);
    QwtArray<double> s(size);
    
    //
    //  setup equation system; use coefficient
    //  vectors as temporary buffers
    //
    for (i = 0; i < size - 1; i++)
    {
        h[i] = p[i+1].x() - p[i].x();
        if (h[i] <= 0.0)
            return false;
    }
    
    const int imax = size - 2;
    double htmp = h[imax];
    double dy1 = (p[0].y() - p[imax].y()) / htmp;
    for (i = 0; i <= imax; i++)
    {
        b[i] = c[i] = h[i];
        a[i] = 2.0 * (htmp + h[i]);
        const double dy2 = (p[i+1].y() - p[i].y()) / h[i];
        d[i] = 6.0 * ( dy1 - dy2);
        dy1 = dy2;
        htmp = h[i];
    }

    //
    // solve it
    //
    
    // L-U Factorization
    a[0] = sqrt(a[0]);
    c[0] = h[imax] / a[0];
    double sum = 0;

    for( i = 0; i < imax - 1; i++)
    {
        b[i] /= a[i];
        if (i > 0)
           c[i] = - c[i-1] * b[i-1] / a[i];
        a[i+1] = sqrt( a[i+1] - qwtSqr(b[i]));
        sum += qwtSqr(c[i]);
    }
    b[imax-1] = (b[imax-1] - c[imax-2] * b[imax-2]) / a[imax-1];
    a[imax] = sqrt(a[imax] - qwtSqr(b[imax-1]) - sum);
    

    // forward elimination
    s[0] = d[0] / a[0];
    sum = 0;
    for( i = 1; i < imax; i++)
    {
        s[i] = (d[i] - b[i-1] * s[i-1]) / a[i];
        sum += c[i-1] * s[i-1];
    }
    s[imax] = (d[imax] - b[imax-1] * s[imax-1] - sum) / a[imax];
    
    
    // backward elimination
    s[imax] = - s[imax] / a[imax];
    s[imax-1] = -(s[imax-1] + b[imax-1] * s[imax]) / a[imax-1];
    for (i= imax - 2; i >= 0; i--)
       s[i] = - (s[i] + b[i] * s[i+1] + c[i] * s[imax]) / a[i];

    //
    // Finally, determine the spline coefficients
    //
    s[size-1] = s[0];
    for ( i=0; i < size-1; i++)
    {
        a[i] = ( s[i+1] - s[i] ) / ( 6.0 * h[i]);
        b[i] = 0.5 * s[i];
        c[i] = ( p[i+1].y() - p[i].y() ) 
            / h[i] - (s[i+1] + 2.0 * s[i] ) * h[i] / 6.0; 
    }

    return true;
}
const QMemArray< double > & QwtSpline::coefficientsA (  ) const
Returns:
A coefficients

Definition at line 187 of file qwt_spline.cpp.

References QwtSpline::PrivateData::a, and d_data.

{
    return d_data->a;
}
const QMemArray< double > & QwtSpline::coefficientsB (  ) const
Returns:
B coefficients

Definition at line 193 of file qwt_spline.cpp.

References QwtSpline::PrivateData::b, and d_data.

{
    return d_data->b;
}
const QMemArray< double > & QwtSpline::coefficientsC (  ) const
Returns:
C coefficients

Definition at line 199 of file qwt_spline.cpp.

References QwtSpline::PrivateData::c, and d_data.

{
    return d_data->c;
}
bool QwtSpline::isValid (  ) const

True if valid.

Definition at line 215 of file qwt_spline.cpp.

References QwtSpline::PrivateData::a, and d_data.

{
    return d_data->a.size() > 0;
}
QwtSpline & QwtSpline::operator= ( const QwtSpline other )

Assignment operator

Parameters:
otherSpline used for initilization

Definition at line 91 of file qwt_spline.cpp.

References d_data.

{
    *d_data = *other.d_data;
    return *this;
}
QMemArray< QwtDoublePoint > QwtSpline::points (  ) const

Return points passed by setPoints

Definition at line 178 of file qwt_spline.cpp.

{
    return d_data->points;
}
void QwtSpline::reset (  )

Free allocated memory and set size to 0.

Definition at line 206 of file qwt_spline.cpp.

References QwtSpline::PrivateData::a, QwtSpline::PrivateData::b, QwtSpline::PrivateData::c, d_data, and QwtSpline::PrivateData::points.

Referenced by QwtSplineCurveFitter::setSpline().

{
    d_data->a.resize(0);
    d_data->b.resize(0);
    d_data->c.resize(0);
    d_data->points.resize(0);
}
bool QwtSpline::setPoints ( const QMemArray< QwtDoublePoint > &  points )

Calculate the spline coefficients.

Depending on the value of periodic, this function will determine the coefficients for a natural or a periodic spline and store them internally.

Parameters:
x
ypoints
sizenumber of points
periodicif true, calculate periodic spline
Returns:
true if successful
Warning:
The sequence of x (but not y) values has to be strictly monotone increasing, which means x[0] < x[1] < .... < x[n-1]. If this is not the case, the function will return false

Definition at line 140 of file qwt_spline.cpp.

{
    const int size = points.size();
    if (size <= 2) 
    {
        reset();
        return false;
    }

#if QT_VERSION < 0x040000
    d_data->points = points.copy(); // Qt3: deep copy
#else
    d_data->points = points;
#endif
    
    d_data->a.resize(size-1);
    d_data->b.resize(size-1);
    d_data->c.resize(size-1);

    bool ok;
    if ( d_data->splineType == Periodic )
        ok = buildPeriodicSpline(points);
    else
        ok = buildNaturalSpline(points);

    if (!ok) 
        reset();

    return ok;
}
void QwtSpline::setSplineType ( SplineType  splineType )

Select the algorithm used for calculating the spline

Parameters:
splineTypeSpline type
See also:
splineType()

Definition at line 109 of file qwt_spline.cpp.

References d_data, splineType(), and QwtSpline::PrivateData::splineType.

QwtSpline::SplineType QwtSpline::splineType (  ) const
Returns:
the spline type
See also:
setSplineType()

Definition at line 118 of file qwt_spline.cpp.

References d_data, and QwtSpline::PrivateData::splineType.

Referenced by setSplineType().

{
    return d_data->splineType;
}
double QwtSpline::value ( double  x ) const

Calculate the interpolated function value corresponding to a given argument x.

Definition at line 224 of file qwt_spline.cpp.

References QwtSpline::PrivateData::a, QwtSpline::PrivateData::b, QwtSpline::PrivateData::c, d_data, lookup(), and QwtSpline::PrivateData::points.

{
    if (d_data->a.size() == 0)
        return 0.0;

    const int i = lookup(x, d_data->points);

    const double delta = x - d_data->points[i].x();
    return( ( ( ( d_data->a[i] * delta) + d_data->b[i] ) 
        * delta + d_data->c[i] ) * delta + d_data->points[i].y() );
}

Member Data Documentation


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines