PathGeneratorFactory::PathGeneratorFactory(const boost::shared_ptr<StochasticProcessArray>& processes, const TimeGrid& timeGrid) : processes_(processes), grid_(timeGrid) { unsigned long myseed = static_cast<unsigned long>(1); rand_ = std::tr1::mt19937(myseed); this->numAssets_ = processes->size(); this->pathSize_ = timeGrid.size(); PseudoRandom::rsg_type gen = PseudoRandom::make_sequence_generator(numAssets_*(timeGrid.size()-1),1); gen_ = boost::shared_ptr<MultiVariate<PseudoRandom>::path_generator_type>(new MultiVariate<PseudoRandom>::path_generator_type(processes, timeGrid, gen, false)); this->next_ = MultiPath(numAssets_,this->grid_); S0_ = std::valarray<double>(numAssets_); randArrs_ = std::valarray<double>(numAssets_); //this->testRandom_ = Array(numAssets_ * pathSize_); previousRand_ = Matrix(numAssets_, pathSize_); Matrix corr = processes->correlation(); chol_=CholeskyDecomposition(corr); random_ = MultiPath(numAssets_,timeGrid); // num - 1 this->muGrid_ = Matrix(numAssets_, timeGrid.size() - 1); this->volGrid_ = Matrix(numAssets_,timeGrid.size() - 1); antitheticFlag_ = false; for (Size asset = 0 ; asset<numAssets_ ;++asset) { //초기화 수익률 or 절대값 S0_[asset] = processes->process(asset)->x0() / processes->process(asset)->basePrice(); for (Size t = 0 ; t < pathSize_ - 1 ;++t) { double mu_t = processes->process(asset)->drift(timeGrid[t],1.0); double sigma_t = processes->process(asset)->diffusion(timeGrid[t],1.0); double dt_t = timeGrid.dt(t); // exp( ( mu[t] - 0.5 * vol[t] * vol[t] ) * dt[t] ) muGrid_[asset][t] = std::exp( ( mu_t - 0.5 * sigma_t * sigma_t ) * dt_t ); // vol[t] * sqrt(dt[t]) volGrid_[asset][t] = sigma_t * std::sqrt(dt_t); } } }
/* Request a new multipath, store the result and return a handle-id to it. */ unsigned int CPathManager::RequestPath( CSolidObject* caller, const MoveDef* moveDef, float3 startPos, float3 goalPos, float goalRadius, bool synced ) { if (!IsFinalized()) return 0; // in misc since it is called from many points SCOPED_TIMER("Misc::Path::RequestPath"); startPos.ClampInBounds(); goalPos.ClampInBounds(); // Create an estimator definition. goalRadius = std::max<float>(goalRadius, PATH_NODE_SPACING * SQUARE_SIZE); //FIXME do on a per PE & PF level? assert(moveDef == moveDefHandler->GetMoveDefByPathType(moveDef->pathType)); MultiPath newPath = MultiPath(moveDef, startPos, goalPos, goalRadius); newPath.finalGoal = goalPos; newPath.caller = caller; newPath.peDef.synced = synced; if (caller != nullptr) caller->UnBlock(); const IPath::SearchResult result = ArrangePath(&newPath, moveDef, startPos, goalPos, caller); unsigned int pathID = 0; if (result != IPath::Error) { if (newPath.maxResPath.path.empty()) { if (result != IPath::CantGetCloser) { LowRes2MedRes(newPath, startPos, caller, synced); MedRes2MaxRes(newPath, startPos, caller, synced); } else { // add one dummy waypoint so that the calling MoveType // does not consider this request a failure, which can // happen when startPos is very close to goalPos // // otherwise, code relying on MoveType::progressState // (eg. BuilderCAI::MoveInBuildRange) would misbehave // (eg. reject build orders) newPath.maxResPath.path.push_back(startPos); newPath.maxResPath.squares.push_back(int2(startPos.x / SQUARE_SIZE, startPos.z / SQUARE_SIZE)); } } FinalizePath(&newPath, startPos, goalPos, result == IPath::CantGetCloser); newPath.searchResult = result; pathID = Store(newPath); } if (caller != nullptr) caller->Block(); return pathID; }
MultiPathGenerator<GSG>::MultiPathGenerator( const boost::shared_ptr<StochasticProcess>& process, const TimeGrid& times, GSG generator, bool brownianBridge) : brownianBridge_(brownianBridge), process_(process), generator_(generator), next_(MultiPath(process->size(), times), 1.0) { //std::cout << "dimension (" << generator_.dimension() // << ") is not equal to (" // << process->factors() << " * " << times.size() - 1 // << ") the number of factors " // << "times the number of time steps"; QL_REQUIRE(generator_.dimension() == process->factors()*(times.size()-1), "dimension (" << generator_.dimension() << ") is not equal to (" << process->factors() << " * " << times.size()-1 << ") the number of factors " << "times the number of time steps"); QL_REQUIRE(times.size() > 1, "no times given"); }
/* Request a new multipath, store the result and return an handle-id to it. */ unsigned int CPathManager::RequestPath(const MoveData* moveData, float3 startPos, CPathFinderDef* peDef, float3 goalPos, CSolidObject* caller) { SCOPED_TIMER("AI:PFS"); // Creates a new multipath. MultiPath* newPath = SAFE_NEW MultiPath(startPos, peDef, moveData); newPath->finalGoal = goalPos; newPath->caller = caller; if (caller) { caller->UnBlock(); } unsigned int retValue = 0; // Choose finder dependent on distance to goal. float distanceToGoal = peDef->Heuristic(int(startPos.x / SQUARE_SIZE), int(startPos.z / SQUARE_SIZE)); if (distanceToGoal < DETAILED_DISTANCE) { // Get a detailed path. IPath::SearchResult result = pf->GetPath(*moveData, startPos, *peDef, newPath->detailedPath, true); if (result == IPath::Ok || result == IPath::GoalOutOfRange) { retValue = Store(newPath); } else { delete newPath; } } else if (distanceToGoal < ESTIMATE_DISTANCE) { // Get an estimate path. IPath::SearchResult result = pe->GetPath(*moveData, startPos, *peDef, newPath->estimatedPath); if (result == IPath::Ok || result == IPath::GoalOutOfRange) { // Turn a part of it into detailed path. EstimateToDetailed(*newPath, startPos); // Store the path. retValue = Store(newPath); } else { // if we fail see if it can work find a better block to start from float3 sp = pe->FindBestBlockCenter(moveData, startPos); if (sp.x != 0 && (((int) sp.x) / (SQUARE_SIZE * 8) != ((int) startPos.x) / (SQUARE_SIZE * 8) || ((int) sp.z) / (SQUARE_SIZE * 8) != ((int) startPos.z) / (SQUARE_SIZE * 8))) { IPath::SearchResult result = pe->GetPath(*moveData, sp, *peDef, newPath->estimatedPath); if (result == IPath::Ok || result == IPath::GoalOutOfRange) { EstimateToDetailed(*newPath, startPos); retValue = Store(newPath); } else { delete newPath; } } else { delete newPath; } } } else { // Get a low-res. estimate path. IPath::SearchResult result = pe2->GetPath(*moveData, startPos, *peDef, newPath->estimatedPath2); if (result == IPath::Ok || result == IPath::GoalOutOfRange) { // Turn a part of it into hi-res. estimate path. Estimate2ToEstimate(*newPath, startPos); // And estimate into detailed. EstimateToDetailed(*newPath, startPos); // Store the path. retValue = Store(newPath); } else { // sometimes the 32*32 squares can be wrong so if it fails to get a path also try with 8*8 squares IPath::SearchResult result = pe->GetPath(*moveData, startPos, *peDef, newPath->estimatedPath); if (result == IPath::Ok || result == IPath::GoalOutOfRange) { EstimateToDetailed(*newPath, startPos); retValue = Store(newPath); } else { // 8*8 can also fail rarely, so see if we can find a better 8*8 to start from float3 sp = pe->FindBestBlockCenter(moveData, startPos); if (sp.x != 0 && (((int) sp.x) / (SQUARE_SIZE * 8) != ((int) startPos.x) / (SQUARE_SIZE * 8) || ((int) sp.z) / (SQUARE_SIZE * 8) != ((int) startPos.z) / (SQUARE_SIZE * 8))) { IPath::SearchResult result = pe->GetPath(*moveData, sp, *peDef, newPath->estimatedPath); if (result == IPath::Ok || result == IPath::GoalOutOfRange) { EstimateToDetailed(*newPath, startPos); retValue = Store(newPath); } else { delete newPath; } } else { delete newPath; } } } } if (caller) { caller->Block(); } return retValue; }