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