Skip to content
Snippets Groups Projects
Select Git revision
  • a8d395fb925378b00c17079770c13fe8df2297a0
  • master default protected
  • dev
  • v0.1.1
  • v0.1.0
5 results

ats.py

Blame
  • test_matrix.cpp 3.09 KiB
    #include <numeric>
    #include <vector>
    
    #include "gtest.h"
    
    #include "../src/math.hpp"
    #include "../src/matrix.hpp"
    
    TEST(matrix, construct_from_parent_only)
    {
        using matrix_type = nest::mc::matrix<double, int>;
    
        // pass parent index as a std::vector by reference
        // the input should not be moved from
        {
            std::vector<int> p = {0,0,1};
            matrix_type m{p};
            EXPECT_EQ(m.num_cells(), 1);
            EXPECT_EQ(m.size(), 3u);
            EXPECT_EQ(p.size(), 3u);
    
            auto mp = m.p();
            EXPECT_EQ(mp[0], 0);
            EXPECT_EQ(mp[1], 0);
            EXPECT_EQ(mp[2], 1);
        }
    
        // pass parent index as a std::vector by rvalue reference
        // the input should not be moved from
        {
            std::vector<int> p = {0,0,1};
            matrix_type m{std::move(p)};
            EXPECT_EQ(m.num_cells(), 1);
            EXPECT_EQ(m.size(), 3u);
            EXPECT_EQ(p.size(), 3u);
    
            auto mp = m.p();
            EXPECT_EQ(mp[0], 0);
            EXPECT_EQ(mp[1], 0);
            EXPECT_EQ(mp[2], 1);
        }
    
        // pass parent index as a HostVector by reference
        // expect that the input is not moved from
        {
            memory::HostVector<int> p(3, 0);
            std::iota(p.begin()+1, p.end(), 0);
            matrix_type m{p};
            EXPECT_EQ(m.num_cells(), 1);
            EXPECT_EQ(m.size(), 3u);
            EXPECT_EQ(p.size(), 3u);
    
            auto mp = m.p();
            EXPECT_EQ(mp[0], 0);
            EXPECT_EQ(mp[1], 0);
            EXPECT_EQ(mp[2], 1);
        }
        // pass parent index as a HostVector by rvalue reference
        // expect that the input is moved from
        {
            memory::HostVector<int> p(3, 0);
            std::iota(p.begin()+1, p.end(), 0);
            matrix_type m{std::move(p)};
            EXPECT_EQ(m.num_cells(), 1);
            EXPECT_EQ(m.size(), 3u);
            EXPECT_EQ(p.size(), 0u); // 0 implies moved from
    
            auto mp = m.p();
            EXPECT_EQ(mp[0], 0);
            EXPECT_EQ(mp[1], 0);
            EXPECT_EQ(mp[2], 1);
        }
    }
    
    TEST(matrix, solve)
    {
        using matrix_type = nest::mc::matrix<double, int>;
    
        // trivial case : 1x1 matrix
        {
            matrix_type m{std::vector<int>{0}};
    
            m.d()(memory::all) =  2;
            m.l()(memory::all) = -1;
            m.u()(memory::all) = -1;
            m.rhs()(memory::all) = 1;
    
            m.solve();
    
            EXPECT_EQ(m.rhs()[0], 0.5);
        }
        // matrices in the range of 2x2 to 1000x1000
        {
            using namespace nest::mc::math;
            for(auto n : memory::Range(2,1001)) {
                auto p = std::vector<int>(n);
                std::iota(p.begin()+1, p.end(), 0);
                matrix_type m{p};
    
                EXPECT_EQ(m.size(), n);
                EXPECT_EQ(m.num_cells(), 1);
    
                m.d()(memory::all) =  2;
                m.l()(memory::all) = -1;
                m.u()(memory::all) = -1;
                m.rhs()(memory::all) = 1;
    
                m.solve();
    
                auto x = m.rhs();
                auto err = square(std::fabs(2.*x[0] - x[1] - 1.));
                for(auto i : memory::Range(1,n-1)) {
                    err += square(std::fabs(2.*x[i] - x[i-1] - x[i+1] - 1.));
                }
                err += square(std::fabs(2.*x[n-1] - x[n-2] - 1.));
    
                EXPECT_NEAR(0., std::sqrt(err), 1e-8);
            }
        }
    }