コード例 #1
0
void ThetaOperator::forwardEstimation(
		boost::ptr_vector<MeshContext>& contextStack ,
		                        FitobCalculator* calc ,
		                        int& stackIndex ,
		                        double& timeStamp ){

	FITOB_OUT_LEVEL3(verb(),"ThetaOperator::forwardEstimation stackIndex:" << stackIndex << "timeStamp"
			<< timeStamp << " contextStack.size():" << contextStack.size());

	MeshContext& actualContext = contextStack[stackIndex];

	if (thetaExpression_->isConstantExpression(actualContext) == false){
		FITOB_ERROR_EXIT(" ThetaOperator, theta expression is not constant ");
	}
    // evaluate the the expression (theta time) and store it
	thetaTime_ = thetaExpression_->eval(actualContext.minGlobCoord());

	// todo: these values now are not taken in consideration,
	// This might be a future feature, to split up one Theta operator in small theta operators
	// in case of too large macro time step
	// 19.09.2010 -> at todays knowledge this is not necessary, this would only make things worse
	maxThetaTime_ = 10.0; //calc->getXMLConfiguration().get()->getDoubleConfiguration("thetaconfigurations.solver.maxThetaStep.<xmlattr>.value" );
	nr_Theta_ = ceil(thetaTime_/maxThetaTime_);

	const boost::shared_ptr<ModelCollection>& factorModels = calc->getModelCollection();
	const boost::shared_ptr<ScriptModel>& scriptModel = calc->getScriptModel();
	const OperatorSequence& scriptBody = scriptModel->bodyOpSeq();
	const Domain& actDom = actualContext.getDom();
	int nrFactors = factorModels->nrFactors();

	Domain newDom(actDom);

	FITOB_OUT_LEVEL3(verb(),"ThetaOperator::forwardEstimation nrFactors:" << factorModels->nrFactors() << " thetaTime:" << thetaTime_ );
	for (int factorIndex = 0 ; factorIndex < nrFactors ; factorIndex++)
	{
		const FactorModelBase& model = factorModels->getModel(factorIndex);
		int globalIndex = model.getGlobalIndex();

		const DVector& startVal = calc->getStartDomain()->getGradedAxis(globalIndex);

		// get the points of the normal distribution
		DVector stdPoints;
		returnScaledNormalDistribution( actDom.getMaximalLevel() ,
				factorModels->stdFactor(factorIndex) , 1 ,  stdPoints );

		FITOB_OUT_LEVEL3(verb(),"ThetaOperator::forwardEstimation factorIndex:" << factorIndex << " P.size():" << stdPoints.size());
		// here we calculate the scaling
		if (startVal.size() > 1){
			for (unsigned int pointI = 0; pointI < stdPoints.size() ; pointI++ ){
				double endVal = 0.0;
				model.forwardEstimation(startVal[pointI] , timeStamp + thetaTime_ ,
						stdPoints[pointI] , actDom.getAverage() , endVal );
				if (verb()>3){
					std::cout << endVal << ",";
				}
				stdPoints[pointI] = endVal;
			}
			if (verb()>3) std::cout << std::endl;
		} else {
			for (unsigned int pointI = 0; pointI < stdPoints.size() ; pointI++ ){
				double endVal = 0.0;
				model.forwardEstimation(startVal[0] , timeStamp + thetaTime_ ,
						stdPoints[pointI] , actDom.getAverage() , endVal );
				if (verb()>3){
					std::cout << endVal << ",";
				}
				stdPoints[pointI] = endVal;
			}
			if (verb()>3) std::cout << std::endl;
		}

		//and call forwardEstimation_DiffusionEnlarement
		int stackIndex_tmp = 0;
		scriptBody.forwardEstimation_DiffusionEnlarement( contextStack ,
                calc ,stdPoints , globalIndex , stackIndex_tmp  , timeStamp );

		// sort stdPoints vector - not necessary (even in mean reversion case)
		// - this is not necessary since we estimate the values from 0 till T and not for dT
		std::sort( stdPoints.begin(),stdPoints.end() );

		// set the axis in the new domain
		newDom.setAxis(stdPoints,globalIndex);
	}

	// add new context, extend contextStack
	contextStack.push_back(new MeshContext(newDom,timeStamp));
	FITOB_OUT_LEVEL3(verb(),"ThetaOperator::forwardEstimation New Domain:" << newDom.toString() );
	timeStamp = timeStamp + thetaTime_;
	stackIndex = stackIndex + 1;

}