Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Element-wise operations in C++

Is there a preexisting library that will let me create array-like objects which have the following properties:

  1. Run time size specification (chosen at instantition, not grown or shrunk afterwards)
  2. Operators overloaded to perform element wise operations (i.e. c=a+b will result in a vector c with c[i]=a[i]+b[i] for all i, and similarly for *, -, /, etc)
  3. A good set of functions which act elementwise, for example x=sqrt(vec) will have elements x[i]=sqrt(vec[i])
  4. Provide "summarising" functions such as sum(vec), mean(vec) etc
  5. (Optional) Operations can be sent to a GPU for processing.

Basically something like the way arrays work in Fortran, with all of the implementation hidden. Currently I am using vector from the STL and manually overloading the operators, but I feel like this is probably a solved problem.

like image 493
user2664470 Avatar asked Dec 08 '13 18:12

user2664470


People also ask

What is element-wise operation?

An element-wise operation is an operation between two tensors that operates on corresponding elements within the respective tensors. An element-wise operation operates on corresponding elements between tensors. Two elements are said to be corresponding if the two elements occupy the same position within the tensor.


2 Answers

In the dusty corners of standard library, long forgotten by everyone, sits a class called valarray. Look it up and see if it suits your needs.

From manual page at cppreference.com:

std::valarray is the class for representing and manipulating arrays of values. It supports element-wise mathematical operations and various forms of generalized subscript operators, slicing and indirect access.

A code snippet for illustration:

#include <valarray>
#include <algorithm>
#include <iterator>
#include <iostream>

int main()
{
    std::valarray<int> a { 1, 2, 3, 4, 5};
    std::valarray<int> b = a;
    std::valarray<int> c = a + b;
    std::copy(begin(c), end(c),
        std::ostream_iterator<int>(std::cout, " "));
}

Output: 2 4 6 8 10

like image 170
jrok Avatar answered Sep 29 '22 17:09

jrok


You can use Cilk Plus Extentions (https://www.cilkplus.org/) that provides array notation by applying element-wise operations to arrays of the same shape for C/C++. It explores the vector parallelism from your processor as well co-processor.

Example: Standard C code:

for (i=0; i<MAX; i++)
   c[i]=a[i]+b[i];

Cilk Plus - Array notation:

c[i:MAX]=a[i:MAX]+b[i:MAX];

Stride sections like:

float d[10] = {0,1,2,3,4,5,6,7,8,9};
float x[3];
x[:] = d[0:3:2]; //x contains 0,2,4 values

You can use reductions on arrays sections:

_sec_reduce_add(a[0:n]);

Interest reading: http://software.intel.com/en-us/articles/getting-started-with-intel-cilk-plus-array-notations

like image 26
Igor Freitas Avatar answered Sep 29 '22 17:09

Igor Freitas