PolynomialFit3<Real>::PolynomialFit3 (int numXSamples, int numYSamples, const Real* xSamples, const Real* ySamples, const Real* wSamples, int numPowers, const Tuple<2,int>* powers) { InitializePowers(numPowers, powers); // Repackage the input into samples of the form (x[i],y[i],w[i]). int numSamples = numXSamples*numYSamples; Real* xRepackage = new1<Real>(numSamples); Real* yRepackage = new1<Real>(numSamples); for (int y = 0, i = 0; y < numYSamples; ++y) { Real yInput = ySamples[y]; for (int x = 0; x < numXSamples; ++x, ++i) { xRepackage[i] = xSamples[x]; yRepackage[i] = yInput; } } const Real* srcSamples[3] = { xRepackage, yRepackage, wSamples }; Real* trgSamples[3] = { 0, 0, 0 }; TransformToUnit(numSamples, srcSamples, trgSamples); DoLeastSquaresFit(numSamples, trgSamples); delete1(trgSamples[0]); delete1(trgSamples[1]); delete1(trgSamples[2]); delete1(xRepackage); delete1(yRepackage); }
PolynomialFit3<Real>::PolynomialFit3 (int numSamples, const Real* xSamples, const Real* ySamples, const Real* wSamples, int numPowers, const Tuple<2,int>* powers) { InitializePowers(numPowers, powers); const Real* srcSamples[3] = { xSamples, ySamples, wSamples }; Real* trgSamples[3] = { 0, 0, 0 }; TransformToUnit(numSamples, srcSamples, trgSamples); DoLeastSquaresFit(numSamples, trgSamples); delete1(trgSamples[0]); delete1(trgSamples[1]); delete1(trgSamples[2]); }
PolynomialFit2<Real>::PolynomialFit2 ( int numSamples, const Real* xSamples, const Real* wSamples, int numPowers, const int* powers ) : mNumPowers( numPowers ) { InitializePowers( numPowers, powers ); mPowers = new1<int>( mNumPowers ); memcpy( mPowers, powers, mNumPowers * sizeof( int ) ); mCoefficients = new1<Real>( mNumPowers ); GMatrix<Real> mat( mNumPowers, mNumPowers ); // initially zero GVector<Real> rhs( mNumPowers ); // initially zero GVector<Real> xPower( mNumPowers ); int i, row, col; for ( i = 0; i < numSamples; ++i ) { // Compute relevant powers of x. TODO: Build minimum tree for // powers of x? Real x = xSamples[i]; Real w = wSamples[i]; for ( int j = 0; j < mNumPowers; ++j ) { xPower[j] = Math<Real>::Pow( x, ( Real )mPowers[j] ); } for ( row = 0; row < mNumPowers; ++row ) { // Update the upper-triangular portion of the symmetric matrix. for ( col = row; col < mNumPowers; ++col ) { mat[row][col] += xPower[mPowers[row] + mPowers[col]]; } // Update the right-hand side of the system. rhs[row] += w * xPower[mPowers[row]]; } } // Copy the upper-triangular portion of the symmetric matrix to the // lower-triangular portion. for ( row = 0; row < mNumPowers; ++row ) { for ( col = 0; col < row; ++col ) { mat[row][col] = mat[col][row]; } } // Precondition by normalizing the sums. Real invNumSamples = ( ( Real )1 ) / ( Real )numSamples; for ( row = 0; row < mNumPowers; ++row ) { for ( col = 0; col < mNumPowers; ++col ) { mat[row][col] *= invNumSamples; } rhs[row] *= invNumSamples; } if ( LinearSystem<Real>().Solve( mat, rhs, mCoefficients ) ) { mSolved = true; } else { memset( mCoefficients, 0, mNumPowers * sizeof( Real ) ); mSolved = false; } }