Reputation: 21
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
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
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_bound
gives 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
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
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.
Upvotes: 4
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