VF_A LsmBasisSystem::multiPathBasisSystem(Size dim, Size order, PolynomType polyType) { QL_REQUIRE(dim>0, "zero dimension"); // get single factor basis VF_R pathBasis = pathBasisSystem(order, polyType); VF_A ret; // 0-th order term VF_R term(dim, pathBasis[0]); ret.push_back(MultiDimFct(term)); // start with all 0 tuple VV tuples(1, std::vector<Size>(dim)); // add multi-factor terms for(Size i=1; i<=order; ++i) { tuples = next_order_tuples(tuples); // now we have all tuples of order i // for each tuple add the corresponding term for(Size j=0; j<tuples.size(); ++j) { for(Size k=0; k<dim; ++k) term[k] = pathBasis[tuples[j][k]]; ret.push_back(MultiDimFct(term)); } } return ret; }
std::vector<boost::function1<Real, Array> > LsmBasisSystem::multiPathBasisSystem(Size dim, Size order, PolynomType polynomType) { const std::vector<boost::function1<Real, Real> > b = pathBasisSystem(order, polynomType); std::vector<boost::function1<Real, Array> > ret; ret.push_back(bind(constant<Real, Real>(1.0), bind(f_workaround, _1, 0, dim))); for (Size i=1; i<=order; ++i) { const std::vector<boost::function1<Real, Array> > a = w(dim, i, polynomType, b); for (std::vector<boost::function1<Real, Array> >::const_iterator iter = a.begin(); iter < a.end(); ++iter) { ret.push_back(*iter); } } // remove-o-zap: now remove redundant functions. // usually we do have a lot of them due to the construction schema. // We use a more "hands on" method here. std::deque<bool> rm(ret.size(), true); Array x(dim), v(ret.size()); MersenneTwisterUniformRng rng(1234UL); for (Size i=0; i<10; ++i) { Size k; // calculate random x vector for (k=0; k<dim; ++k) { x[k] = rng.next().value; } // get return values for all basis functions for (k=0; k<ret.size(); ++k) { v[k] = ret[k](x); } // find duplicates for (k=0; k<ret.size(); ++k) { if (std::find_if(v.begin(), v.end(), bind(equal_within<Real>(10*v[k]*QL_EPSILON), v[k], _1) ) == v.begin() + k) { // don't remove this item, it's unique! rm[k] = false; } } } std::vector<boost::function1<Real, Array> >::iterator iter = ret.begin(); for (Size i=0; i < rm.size(); ++i) { if (rm[i]) { iter = ret.erase(iter); } else { ++iter; } } return ret; }