Exemple #1
0
void evalTest(const std::size_t p_size, const std::size_t p_samples) {
    Polynomial<T,Dim> P;
    Index<Dim> polyIdx;
    { 
        typename Shape<Dim>::type polyShape;
        polyShape.fill(p_size);
        P.reshape(polyShape).applyToCoefficients([](T& ak, const Index<Dim>& idx){ 
                ak = T(idx())/T(idx.maxId());
        });
    }

    std::array<T,Dim> X;
    T dX;
    {
        const T a = T(0);
        const T b = T(1);
        dX = (b-a)/(p_samples-1);   
    }
    
    typename Shape<Dim>::type sampleShape;
    sampleShape.fill(p_samples);
    Index<Dim> sampleIdx(sampleShape);
    while(!sampleIdx.atMaxId()) {
        for (std::size_t d=0; d < Dim; d++)
            X[d] = sampleIdx[d]*dX;
        T lhs, rhs;
        lhs = P(X); 
        rhs = T(0);
        polyIdx.reset(P.shape());
        while(!polyIdx.atMaxId()) {
            T val = T(1);
            for (std::size_t d=0; d<Dim; d++)
                val *= std::pow(X[d],polyIdx[d]);
            rhs += T(polyIdx())/T(polyIdx.maxId())*val;
            ++polyIdx;
        }
        ASSERT_LE(std::abs(rhs-lhs),std::pow(10,Dim)*std::numeric_limits<T>::epsilon());
        ++sampleIdx;
    }
}
Exemple #2
0
void test(std::size_t p_maxOrder, bool includePeriodicBds=false) {
    typename Shape<Dim>::type shape;
    typename Domain<T,Dim>::DomainSize domainSize;
    Domain<T,Dim> ref, inBuffer, outBuffer;

    Domain<T,Dim>& in  = inBuffer;
    Domain<T,Dim>& out = outBuffer;

    std::array<int,Dim> order;

    shape.fill(8);
    domainSize.fill(2*hysop::constants::pi);

    T eps = std::numeric_limits<T>::epsilon();
    const std::size_t N = std::accumulate(shape.begin(), shape.end(), 1, std::multiplies<std::size_t>());
    
    ref.resize(domainSize).reshape(shape);
    in  = ref;
    out = ref;
   
    typename Shape<Dim>::type maxOrder, testCases;
    maxOrder.fill(p_maxOrder+1);
    testCases.fill(nExtensionsPair);
    Index<Dim> orderId(maxOrder);
    Index<Dim> testCaseId;
    std::size_t testCaseCount;
    while(!(++orderId).atMaxId()) {
        std::cout << "  ::Order::" << orderId.ids() << (verbose ? "\n" : "");
    
        std::array<T,3> meanDists;
        meanDists.fill(0);
        testCaseId.reset(testCases);
        testCaseCount = testCaseId.maxId();
        while(!testCaseId.atMaxId()) { 
            std::copy(orderId.ids().begin(),orderId.ids().end(), order.begin());

            /* generate transform configuration */
            std::array<std::pair<fft::Extension,fft::Extension>, Dim> extConfig;
            for (std::size_t k=0; k<Dim; k++) {
                std::size_t id = testCaseId[k];
                extConfig[k] = pext[id];
                if(pext[id].first==fft::Extension::NONE)
                    order[k] = 0;
            }
            fft::FftDomainConfiguration<Dim> domainConfig(extConfig, includePeriodicBds);
            
            const std::size_t orderSum = std::accumulate(order.begin(), order.end(), 0);
            if(orderSum == 0) {
                testCaseCount--;
                ++testCaseId;
                continue;
            }
            T orderPow = std::pow(T(10),T(orderSum));
            if(std::is_same<T,long double>::value) /* just in case long doubles are not hardware supported... */
                orderPow *= 1e3;
            const auto criteria = std::make_tuple(orderPow*eps*N,orderPow*eps*sqrt(N),2*orderPow*eps);

            const auto f = [&](const typename Domain<T,Dim>::SpaceVariable &x) { 
                T val = func<T>(testCaseId[0])(x[0]);
                for (std::size_t d=1; d < Dim; d++)
                    val *= func<T>(testCaseId[d])(x[d]);
                return val;
            };
            const auto d = [&](const typename Domain<T,Dim>::SpaceVariable &x) { 
                T val = derivative<T>(testCaseId[0],order[0])(x[0]);
                for (std::size_t d=1; d < Dim; d++)
                    val *= derivative<T>(testCaseId[d],order[d])(x[d]);
                return val;
            };
            {
                ref.resetDomainConfiguration(domainConfig.boundariesConfiguration());
                in  = ref;
                out = ref;

                in.apply(f);
                ref.apply(d);
                out.data().apply([](T& v){ v=T(0);});
            }

            solver::FftDiffSolver<T,Dim> solver(domainSize, domainConfig, FFTW_MEASURE, includePeriodicBds, includePeriodicBds);
            solver.apply(in.data(), out.data(), order);

            std::stringstream ss;
            ss << "[";
            for (std::size_t k=0; k<Dim-1; k++) 
                ss << extConfig[k].first << "/" << extConfig[k].second << ",";
            ss << extConfig[Dim-1].first << "/" << extConfig[Dim-1].second;
            ss << "]";

            const auto dist = out.distance(ref);
            const bool pass =      (std::get<0>(dist) < std::get<0>(criteria)) 
                && (std::get<1>(dist) < std::get<1>(criteria))
                && (std::get<2>(dist) < std::get<2>(criteria));

            if((pass && verbose) || !pass) {
                std::cout << (pass ? GREEN : RED);
                std::cout << "\t" << std::setw(Dim*15) << ss.str() << " => " << (pass ? "OK" : "KO") 
                    << "  " << RESET << std::scientific << std::setprecision(2) << dist << std::endl;
            }
            if(!pass) {
                //in.print("IN");
                //ref.print("REF");
                //out.print("OUT");
                std::cout << "Test failed => Criteria was: " << criteria << std::endl;
            }

            meanDists[0] += std::get<0>(dist);
            meanDists[1] += std::get<1>(dist);
            meanDists[2] += std::get<2>(dist);
            
            EXPECT_TRUE(pass);

            ++testCaseId;
        }
        for (std::size_t k = 0; k < 3; k++)
            meanDists[k] /= T(testCaseCount);
        std::cout << "=> mean distances over " << std::scientific << std::setprecision(1) << std::setw(4)
            << testCaseCount << " testcases: " << meanDists;
        for (std::size_t k = 0; k < 3; k++)
            meanDists[k] = std::round(meanDists[k]/eps);
        std::cout << " ~= " <<  std::fixed << std::setprecision(0) << meanDists << " eps" << std::endl; 
    }
}