Yury
Yury

Reputation: 53

How to replace some columns of a matrix using std::valarray and std::gslice

I have a set of consecutive numbers from 1 to 24. I interpret this set as a 4 by 6 matrix using std::valarray:

std::valarray va{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24};

/*
 1  2  3  4  5  6
 7  8  9 10 11 12
13 14 15 16 17 18
19 20 21 22 23 24
*/

I can replace the values ​​of the first and third columns with -1 using std::gslice:

va[std::gslice{ 0, {2, 4}, {2, 6} }] = -1;

/*
-1   2  -3  4  5  6
-7   8  -9 10 11 12
-13 14 -15 16 17 18
-19 20 -21 22 23 24
*/

But I don't know how to replace the values ​​of the first, third and sixth columns with -1. Maybe someone can help me?

Upvotes: 0

Views: 56

Answers (2)

Jerry Coffin
Jerry Coffin

Reputation: 490108

I don't see any reason you'd want to use std::gslice here. You normally use agslice to create something like 3D or 4D addressing. For 2D, you normally just use std::slice (which seems perfectly adequate to this task).

#include <valarray>
#include <iostream>
#include <iomanip>

int main() { 

    std::valarray va{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 
             13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24};

    std::vector<std::size_t> columns { 0, 2, 5 };

    for (auto column : columns) { 
        std::slice s{column, 4, 6};
        va[s] = -1;
    }

    int c=0;
    for (std::size_t i=0; i<va.size(); i++) {
        std::cout << std::setw(4) << va[i] << " ";
        if (++c == 6) {
            std::cout << "\n";
            c = 0;
        }
    }
}

Result:

  -1    2   -1    4    5   -1 
  -1    8   -1   10   11   -1 
  -1   14   -1   16   17   -1 
  -1   20   -1   22   23   -1 

Upvotes: 1

Thomas Matthews
Thomas Matthews

Reputation: 57678

Let's try the brute-force method:

constexpr unsigned int MAX_ROWS = 4U;
constexpr int value = -1;
constexpr unsigned int MAX_COLUMNS = 6U;
for (unsigned int row = 0U; row < MAX_ROWS; ++row)
{
    const unsigned int row_index = row * MAX_COLUMNS;
    va[row_index + 0] = value;
    va[row_index + 2] = value;
    va[row_index + 5] = value;
};  

The above code treats a 1d array as a 2d array.

Upvotes: 1

Related Questions