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]);
        }
    }
}
Exemplo n.º 2
0
/**
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());
}
Exemplo n.º 4
0
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;
}