void BackwardEulerIvpOdeSolver::ComputeNumericalJacobian(AbstractOdeSystem* pAbstractOdeSystem, double timeStep, double time, std::vector<double>& rCurrentYValues, std::vector<double>& rCurrentGuess) { std::vector<double> residual(mSizeOfOdeSystem); std::vector<double> residual_perturbed(mSizeOfOdeSystem); std::vector<double> guess_perturbed(mSizeOfOdeSystem); double epsilon = mNumericalJacobianEpsilon; ComputeResidual(pAbstractOdeSystem, timeStep, time, rCurrentYValues, rCurrentGuess); for (unsigned i=0; i<mSizeOfOdeSystem; i++) { residual[i] = mResidual[i]; } for (unsigned global_column=0; global_column<mSizeOfOdeSystem; global_column++) { for (unsigned i=0; i<mSizeOfOdeSystem; i++) { guess_perturbed[i] = rCurrentGuess[i]; } guess_perturbed[global_column] += epsilon; ComputeResidual(pAbstractOdeSystem, timeStep, time, rCurrentYValues, guess_perturbed); for (unsigned i=0; i<mSizeOfOdeSystem; i++) { residual_perturbed[i] = mResidual[i]; } // Compute residual_perturbed - residual double one_over_eps = 1.0/epsilon; for (unsigned i=0; i<mSizeOfOdeSystem; i++) { mJacobian[i][global_column] = one_over_eps*(residual_perturbed[i] - residual[i]); } } }
/** Decode a I_BL marcoblock using SNR prediction. */ void MbISnr (const PPS *Pps, const NAL* Nal, const W_TABLES *Quantif, const STRUCT_PF *BaselineVectors, RESIDU *CurrResidu, RESIDU *BaseResidu, const short PicWidthInPix, unsigned char *Y, unsigned char *U, unsigned char *V, unsigned char *BaseY, unsigned char *BaseU, unsigned char *BaseV) { //Construction process for one macroblock if (IS_I(CurrResidu -> MbType)){ //I type macroblock decoding process decode_MB_I(Y, U, V, Pps, CurrResidu, PicWidthInPix, Quantif, BaselineVectors); }else if (Nal -> TCoeffPrediction){ //Decoding proces of the macroblock, as an INTRA_BL DecodeITCoeff(CurrResidu, BaseResidu, Pps, PicWidthInPix, Quantif, BaselineVectors, Y, U, V); }else if (Nal -> SCoeffPrediction){ if ((CurrResidu -> Cbp & 0x0f) == 0){ //===== modify QP values (as specified in G.8.1.5.1.2) ===== //cbp == 0 && (Scoeff || Tcoeff) && (I_BL || ResidualPredictionFlag) CurrResidu -> Transform8x8 = BaseResidu -> Transform8x8; if (!CurrResidu -> Cbp){ CurrResidu -> Qp = BaseResidu -> Qp; } } //Bring back base layeer sample into current layer GetBaseSample(Y, U, V, BaseY, BaseU, BaseV, PicWidthInPix); if ( IS_BL (BaseResidu -> MbType)){ //In case of two SNR enchancement //We have to get the zero quality prediction //And to add to this all Scoeff SCoeffResidualAddPic(Nal, CurrResidu, BaseResidu, Pps, PicWidthInPix, Quantif, Y, U, V); }else if (Nal -> PicToDecode){ //We have only one layer prediction, so we can just add the residual to it. ComputeResidual(Pps, CurrResidu, PicWidthInPix, Y, U, V, Quantif); }else{ if( CurrResidu -> Cbp){ // In case of new SNR enhancement based on this one RescaleCurrentCoeff(CurrResidu, BaseResidu, Pps, Quantif, Nal -> SpatialScalability); } } } }
void BackwardEulerIvpOdeSolver::CalculateNextYValue(AbstractOdeSystem* pAbstractOdeSystem, double timeStep, double time, std::vector<double>& rCurrentYValues, std::vector<double>& rNextYValues) { // Check the size of the ODE system matches the solvers expected assert(mSizeOfOdeSystem == pAbstractOdeSystem->GetNumberOfStateVariables()); unsigned counter = 0; // const double eps = 1e-6 * rCurrentGuess[0]; // Our tolerance (should use min(guess) perhaps?) const double eps = 1e-6; // JonW tolerance double norm = 2*eps; std::vector<double> current_guess(mSizeOfOdeSystem); current_guess.assign(rCurrentYValues.begin(), rCurrentYValues.end()); while (norm > eps) { // Calculate Jacobian and mResidual for current guess ComputeResidual(pAbstractOdeSystem, timeStep, time, rCurrentYValues, current_guess); ComputeJacobian(pAbstractOdeSystem, timeStep, time, rCurrentYValues, current_guess); // // Update norm (our style) // norm = ComputeNorm(mResidual); // Solve Newton linear system SolveLinearSystem(); // Update norm (JonW style) norm = ComputeNorm(mUpdate); // Update current guess for (unsigned i=0; i<mSizeOfOdeSystem; i++) { current_guess[i] -= mUpdate[i]; } counter++; assert(counter < 20); // avoid infinite loops } rNextYValues.assign(current_guess.begin(), current_guess.end()); }
int TestSymmetry(SparseMatrix & A, Vector & b, Vector & xexact, TestSymmetryData & testsymmetry_data) { local_int_t nrow = A.localNumberOfRows; local_int_t ncol = A.localNumberOfColumns; Vector x_ncol, y_ncol, z_ncol; InitializeVector(x_ncol, ncol); InitializeVector(y_ncol, ncol); InitializeVector(z_ncol, ncol); double t4 = 0.0; // Needed for dot-product call, otherwise unused testsymmetry_data.count_fail = 0; // Test symmetry of matrix // First load vectors with random values FillRandomVector(x_ncol); FillRandomVector(y_ncol); double xNorm2, yNorm2; double ANorm = 2 * 26.0; // Next, compute x'*A*y ComputeDotProduct(nrow, y_ncol, y_ncol, yNorm2, t4, A.isDotProductOptimized); int ierr = ComputeSPMV(A, y_ncol, z_ncol); // z_nrow = A*y_overlap if (ierr) HPCG_fout << "Error in call to SpMV: " << ierr << ".\n" << endl; double xtAy = 0.0; ierr = ComputeDotProduct(nrow, x_ncol, z_ncol, xtAy, t4, A.isDotProductOptimized); // x'*A*y if (ierr) HPCG_fout << "Error in call to dot: " << ierr << ".\n" << endl; // Next, compute y'*A*x ComputeDotProduct(nrow, x_ncol, x_ncol, xNorm2, t4, A.isDotProductOptimized); ierr = ComputeSPMV(A, x_ncol, z_ncol); // b_computed = A*x_overlap if (ierr) HPCG_fout << "Error in call to SpMV: " << ierr << ".\n" << endl; double ytAx = 0.0; ierr = ComputeDotProduct(nrow, y_ncol, z_ncol, ytAx, t4, A.isDotProductOptimized); // y'*A*x if (ierr) HPCG_fout << "Error in call to dot: " << ierr << ".\n" << endl; testsymmetry_data.depsym_spmv = std::fabs((long double) (xtAy - ytAx))/((xNorm2*ANorm*yNorm2 + yNorm2*ANorm*xNorm2) * (DBL_EPSILON)); if (testsymmetry_data.depsym_spmv > 1.0) ++testsymmetry_data.count_fail; // If the difference is > 1, count it wrong if (A.geom->rank==0) HPCG_fout << "Departure from symmetry (scaled) for SpMV abs(x'*A*y - y'*A*x) = " << testsymmetry_data.depsym_spmv << endl; // Test symmetry of symmetric Gauss-Seidel // Compute x'*Minv*y ierr = ComputeMG(A, y_ncol, z_ncol); // z_ncol = Minv*y_ncol if (ierr) HPCG_fout << "Error in call to MG: " << ierr << ".\n" << endl; double xtMinvy = 0.0; ierr = ComputeDotProduct(nrow, x_ncol, z_ncol, xtMinvy, t4, A.isDotProductOptimized); // x'*Minv*y if (ierr) HPCG_fout << "Error in call to dot: " << ierr << ".\n" << endl; // Next, compute z'*Minv*x ierr = ComputeMG(A, x_ncol, z_ncol); // z_ncol = Minv*x_ncol if (ierr) HPCG_fout << "Error in call to MG: " << ierr << ".\n" << endl; double ytMinvx = 0.0; ierr = ComputeDotProduct(nrow, y_ncol, z_ncol, ytMinvx, t4, A.isDotProductOptimized); // y'*Minv*x if (ierr) HPCG_fout << "Error in call to dot: " << ierr << ".\n" << endl; testsymmetry_data.depsym_mg = std::fabs((long double) (xtMinvy - ytMinvx))/((xNorm2*ANorm*yNorm2 + yNorm2*ANorm*xNorm2) * (DBL_EPSILON)); if (testsymmetry_data.depsym_mg > 1.0) ++testsymmetry_data.count_fail; // If the difference is > 1, count it wrong if (A.geom->rank==0) HPCG_fout << "Departure from symmetry (scaled) for MG abs(x'*Minv*y - y'*Minv*x) = " << testsymmetry_data.depsym_mg << endl; CopyVector(xexact, x_ncol); // Copy exact answer into overlap vector int numberOfCalls = 2; double residual = 0.0; for (int i=0; i< numberOfCalls; ++i) { ierr = ComputeSPMV(A, x_ncol, z_ncol); // b_computed = A*x_overlap if (ierr) HPCG_fout << "Error in call to SpMV: " << ierr << ".\n" << endl; if ((ierr = ComputeResidual(A.localNumberOfRows, b, z_ncol, residual))) HPCG_fout << "Error in call to compute_residual: " << ierr << ".\n" << endl; if (A.geom->rank==0) HPCG_fout << "SpMV call [" << i << "] Residual [" << residual << "]" << endl; } DeleteVector(x_ncol); DeleteVector(y_ncol); DeleteVector(z_ncol); return 0; }