void CubicSplineInterpolation::calCubicSplineCoeffs( 
    std::vector<double> &input_x, 
    std::vector<double> &input_y, 
    CubicSplineCoeffs *&cubicCoeffs,
    CubicSplineMode splineMode /* = CUBIC_NATURAL */,
    SplineFilterMode filterMode /*= CUBIC_MEDIAN_FILTER*/ )
{
    int sizeOfx = input_x.size();
    int sizeOfy = input_y.size();

    if ( sizeOfx != sizeOfy )
    {
        std::cout << "Data input error!" << std::endl <<
            "Location: CubicSplineInterpolation.cpp" <<
            " -> calCubicSplineCoeffs()" << std::endl;

        return;
    }

    /*
        hi*mi + 2*(hi + hi+1)*mi+1 + hi+1*mi+2
        =  6{ (yi+2 - yi+1)/hi+1 - (yi+1 - yi)/hi }

        so, ignore the both ends:
        | -     -     -        0           ...             0     |  |m0 |
        | h0 2(h0+h1) h1       0           ...             0     |  |m1 |
        | 0     h1    2(h1+h2) h2 0        ...                   |  |m2 |
        |         ...                      ...             0     |  |...|
        | 0       ...           0 h(n-2) 2(h(n-2)+h(n-1)) h(n-1) |  |   |
        | 0       ...                      ...             -     |  |mn |

    */

    std::vector<double> copy_y = input_y;

    if ( filterMode == CUBIC_MEDIAN_FILTER )
    {
        cubicMedianFilter(copy_y, 5);
    }

    const int count  = sizeOfx;
    const int count1 = sizeOfx - 1;
    const int count2 = sizeOfx - 2;
    const int count3 = sizeOfx - 3;

    cubicCoeffs = new CubicSplineCoeffs( count1 );

    std::vector<double> step_h( count1, 0.0 );

    // for m matrix
    cv::Mat_<double> m_a(1, count2, 0.0);
    cv::Mat_<double> m_b(1, count2, 0.0);
    cv::Mat_<double> m_c(1, count2, 0.0);
    cv::Mat_<double> m_d(1, count2, 0.0);
    cv::Mat_<double> m_part(1, count2, 0.0);

    cv::Mat_<double> m_all(1, count, 0.0);

    // initial step hi
    for ( int idx=0; idx < count1; idx ++ )
    {
        step_h[idx] = input_x[idx+1] - input_x[idx];
    }
    // initial coefficients
    for ( int idx=0; idx < count3; idx ++ )
    {
        m_a(idx) = step_h[idx];
        m_b(idx) = 2 * (step_h[idx] + step_h[idx+1]);
        m_c(idx) = step_h[idx+1];
    }
    // initial d
    for ( int idx =0; idx < count3; idx ++ )
    {
        m_d(idx) = 6 * ( 
            (copy_y[idx+2] - copy_y[idx+1]) / step_h[idx+1] -  
            (copy_y[idx+1] - copy_y[idx]) / step_h[idx] );
    }

     //cv::Mat_<double> matOfm( count2,  )
    bool isSucceed = caltridiagonalMatrices(m_a, m_b, m_c, m_d, m_part);
    if ( !isSucceed )
    {
        std::cout<<"Calculate tridiagonal matrices failed!"<<std::endl<<
            "Location: CubicSplineInterpolation.cpp -> " <<
            "caltridiagonalMatrices()"<<std::endl;

        return;
    }

    if ( splineMode == CUBIC_NATURAL )
    {
        m_all(0)      = 0.0;
        m_all(count1) = 0.0;

        for ( int i=1; i<count1; i++ )
        {
            m_all(i) = m_part(i-1);
        }

        for ( int i=0; i<count1; i++ )
        {
            cubicCoeffs->a[i] = copy_y[i];
            cubicCoeffs->b[i] = ( copy_y[i+1] - copy_y[i] ) / step_h[i] -
                step_h[i]*( 2*m_all(i) + m_all(i+1) ) / 6;
            cubicCoeffs->c[i] = m_all(i) / 2.0;
            cubicCoeffs->d[i] = ( m_all(i+1) - m_all(i) ) / ( 6.0 * step_h[i] );
        }
    }
    else
    {
        std::cout<<"Not define the interpolation mode!"<<std::endl;
    }
}
Beispiel #2
0
	V m_setpart(const AtomList &ret) { m_part(ret.Count(),ret.Atoms()); }