Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get column-view and row-view from std::vector using range-v3 library?

Tags:

c++

range-v3

Having a 7x5 matrix flattened to a std::vector, I want to get a view on columns and rows using Eric Niebler's range-v3 library. So far, I managed (room for improvement) to get a view on a single row, a single column and to connected rows.

See: https://wandbox.org/permlink/8o4RgSucF3zSNuPN

std::vector<int> numbers = {
    00, 01, 02, 03, 04,
    10, 11, 12, 13, 14,
    20, 21, 22, 23, 24,
    30, 31, 32, 33, 34,
    40, 41, 42, 43, 44,
    50, 51, 52, 53, 54,
    60, 61, 62, 63, 64,
};
const size_t n = 5;//number of columns

//Row_3 = {30, 31, 32, 33, 34}
auto Row_3 = numbers | GetRow(3, n);
std::cout << Row_3 << std::endl;

//Col_2 = {02, 12, 22, 32, 42, 52, 62}
auto Col_2 = numbers | GetColumn(2, n);
std::cout << Col_2 << std::endl;

//Row_2_3_4 =  {{20, 21, 22, 23, 24},
//              {30, 31, 32, 33, 34},
//              {40, 41, 42, 43, 44}}
auto Rows_2_3_4 = numbers | GetConnectedRows(2, 4, n);
std::cout << Rows_2_3_4 << std::endl;

But how can I get a fast view on:

  1. list of rows:

    auto a = numbers | GetRows({2,3,5}, n);

  2. connected columns:

    auto b = numbers | GetCols(2, 4, n);

  3. list of columns:

    auto c = numbers | GetCols({1,2,4}, n);

  4. list of rows ("unsorted"):

    auto d = numbers | GetRows({5,2,3}, n);

  5. list of columns ("unsorted"):

    auto e = numbers | GetCols({4,1,2}, n);

?

like image 553
Porsche9II Avatar asked Dec 20 '18 15:12

Porsche9II


1 Answers

You can just pipe the indexes to an appropriate ranges::view::transform.

Wrapped up in a class:

class Matrix
{
    std::vector<int> data;
    size_t col_count;

    auto to_row(){ return [this](size_t i){ return data | ranges::view::drop(i * col_count) | ranges::view::take(col_count); }; };
    auto to_col(){ return [this](size_t i){ return data | ranges::view::drop(i) | ranges::view::stride(col_count); }; };

public:
    auto get_rows(size_t start, size_t end)
    { return ranges::view::ints(start, end) | ranges::view::transform(to_row()); }

    auto get_rows(std::initialiser_list<size_t> indexes)
    { return indexes | ranges::view::transform(to_row()); }

    auto get_cols(size_t start, size_t end)
    { return ranges::view::ints(start, end) | ranges::view::transform(to_col()); }

    auto get_cols(std::initialiser_list<size_t> indexes)
    { return indexes | ranges::view::transform(to_col()); }
};

Or as pipeable views

auto GetColumns(std::initialiser_list<size_t> indexes, size_t n)
{
    return ranges::make_pipeable([=](auto &&rng) {
        auto to_col = [&rng, n](size_t i){ return rng | GetCol(i, n); };
        return indexes | ranges::view::transform(to_col);
    });
}

auto GetRows(std::initialiser_list<size_t> indexes, size_t n)
{
    return ranges::make_pipeable([=](auto &&rng) {
        auto to_row = [&rng, n](size_t i){ return rng | GetRow(i, n); };
        return indexes | ranges::view::transform(to_col);
    });
}
like image 117
Caleth Avatar answered Sep 29 '22 09:09

Caleth