Linai
Linai

Reputation: 21

C++ Arrays manipulations (python-like operations)

I'm trying to figure out the best C++ library/package for array manipulations in a manner of python. Basically I need a simplicity like this:

values  = numpy.array(inp.data)
idx1    = numpy.where(values > -2.14)
idx2    = numpy.where(values < 2.0)

res1 = (values[idx1] - diff1)/1000
res2 = (values[idx2] - diff2)*1000

In python it's just 5 lines, but the simplest way in C++ i can think of is quite a number of nested loops. Pls advise..

Basically my question is concerning the array/vector operations like array multiplications, operations on indexs, etc.. In the example above, res1 is an array, containing a set of elements filtered out of values array and some arithmetics applied afterward (subtraction, multiplication for all selected elements). In this python example I'm not copying elements of values array as it could be big enough in terms of memory, i'm keeping only the indexes and want to be able to run arithmetic operations on a selected set of elements of the original array.

Upvotes: 2

Views: 940

Answers (5)

D.Shawley
D.Shawley

Reputation: 59563

If you combine std::vector and boost::lambda, you can come really close to your example:

#include <algorithm>
#include <iostream>
#include <vector>
#include <boost/lambda/lambda.hpp>

using boost::lambda::_1;

int main() {
    float ary[10] = { -4, -3, -2, -1, 0, 1, 2, 3, 4, 5 };
    std::vector<float> v(&ary[0], &ary[10]);
    std::vector<float>::iterator iter1, iter2;

    iter1 = std::find_if(v.begin(), v.end(), (_1 > -2.14));
    iter2 = std::find_if(v.begin(), v.end(), (_1 < 2.0));

    // output:
    //     iter1 = -2.000
    //     iter2 = 1.000
    std::cout
        << "iter1 = " << *iter1 << "\n"
        << "iter2 = " << *iter2 << "\n"
        << std::endl;
    return 0;
}

Upvotes: 1

Timo Geusch
Timo Geusch

Reputation: 24351

You can achieve something similar in C++ but you shouldn't use plain C arrays for it.

The easiest way I can see this work would be using a std::set of floats (your code looks like it assumes that the data is sorted in ascending order). You could also use a std::vector of float but you'll have to sort that yourself, probably by using std::sort.

In that case, your example code could look like this - the set assumes the values are unique, if they aren't, you could use a std::multiset instead;

std::set<float> values(inp.data.begin(), inp.data.end());
std::set<float>::iterator idx1 = values.lower_bound(-2.14);
std::set<float>::iterator idx2 = values.upper_bound(2.0);

float res1 = (*idx1 - diff1) / 1000.0;
float res2 = (*idx2 - diff2) / 1000.0;

Please note that the above code sample is not a 100% conversion of your original code - lower_boundgives you the first element that's equal or larger than -2.14. I also didn't put any checking code in for failures - if lower_bound or upper_bound can't find matching elements, they would return values.end(), for example.

Using vector, the example would look very similar, just one line more to pre-sort the vector:

std::vector<float> values(inp.data.begin(), inp.data.end());
std::sort(values.begin(), values.end();
std::vector<float>::iterator idx1 = std::lower_bound(values.begin(), values.end(), -2.14);
std::vector<float>::iterator idx2 = std::upper_bound(values.begin(), values.end(), 2.0);

float res1 = (*idx1 - diff1) / 1000.0;
float res2 = (*idx2 - diff2) / 1000.0;

Upvotes: 5

anon
anon

Reputation:

You should not be using arrays at all. Please sit down and learn about the std::vector class and about iterators and Standard Library algorithms. I strongly suggest reading the book The C++ Standard Library.

Upvotes: 5

the_drow
the_drow

Reputation: 19181

I suggest you to check the algorithm header. Also don't work with arrays, you have std::vector or boost(soon to be std)::array.

wikipedia article

Reference for all algorithms

Upvotes: 4

fortran
fortran

Reputation: 76067

If I'm not mistaken, numpy is written mostly in C (with a Python wrapper), so you could be able to use it directly from C++ without much effort.

Upvotes: 1

Related Questions