c++stlvalarray

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?


Solution

  • 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