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; }