For my matrix class I want to do some sort of operator overloading (probably using expression templates) on range-v3 views for + - / * %
.
For example if I want to get a view of the sum of two columns, I want to write
col_1 + col_2
instead of
rv::zip_with([](auto c1, auto c2) {return c1 + c2;}, col_1, col_2);
Probably some ideas from this paper can be used to avoid constructing too many temporaries. Here is the code that I want to write:
//simple example
//what I want to write
auto rangeview = col_1 + col_2;
//what I can write
auto rangeview = rv::zip_with([](auto c1, auto c2) {
return c1 + c2;
}, col_1, col_2);
//itermediate
//what I want to write
auto rangeview = col_1 + col_2 + col_3;
//what I can write
auto rangeview = rv::zip_with([](auto c1, auto c2, auto c3) {
return c1 + c2 + c3;
}, col_1, col_2, col_3);
//advanced
//what I want to write
auto rangeview = 10*col_1 + 20*col_2 - 30*col_3;
//what I can write
auto rangeview = rv::zip_with([](auto c1, auto c2, auto c3) {
return 10.0*c1 + 20.0*c2 - 30.0*c3;
}, col_1, col_2, col_3);
//more advanced with elementwise multiplication
//what I want to write
auto rangeview = 10*col_1 + 20*col_2 - col_2 % col_3;
//what I can write
auto rangeview = rv::zip_with([](auto c1, auto c2, auto c3) {
return 10.0*c1 + 20.0*c2 - c2*c3;
}, col_1, col_2, col_3);
Range views are supposedly lazy; Is it not why they are called views in the first place? So why not to return the resulting view in a user defined operand of your own? They'll ideally get evaluated, once the final range is iterated in a for loop or an algorithm.
IMHO not everything can be provided by the std or any other general purpose library. Some little tweaks are necessary using any tool:
decltype(auto) operator+(column const& col_1, column const& col_2){
return rv::zip_transform( [] (auto c1, auto c2)
{return c1 + c2;},
rv::all(col_1),
rv::all(col_2) );
};
A scalar * vector multiplication operator can be separately defined in a similar manor too. Then the linear combination of columns is written just as it is mathematically written. The actual calculations will wait till a for
loop or an algorithm like std::fold
or std::foreach
traverses the range.
Lazy scalar * vector product becomes:
decltype(auto) operator*(range_value_t<column> const coef, column& col) {
return rv::transform(rv::all(col),[=,coef](auto x){return coef*x});
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With