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; } }
V m_setpart(const AtomList &ret) { m_part(ret.Count(),ret.Atoms()); }