Erase C++ 2d vector row while doing calculations with the matrix - c++

I'm trying to simulate the mean behaviour of an ensemble of neurons. This means I need to do calculations with a matrix of a couple of billions of elements (steps~106, neurons~104).
To avoid eating my whole RAM (and dying trying) I decided to delete rows from the matrix as soon as I'm done doing calculations with it. I don't have too much experience with C++, but my understanding is that v.erase( v.begin()-i+1); should allow me to do so.
// Membrane potential matrix using st::vector
vector<vector<double>> v;
v.resize(steps + 1, vector<double>(neurons));
// Initialise v
for (size_t n = 0; n < neurons; n++) {
v[0][n] = v0;
}
double v_avg[steps + 1] = {v0};
// Loop
for (size_t i = 1; i < steps + 1; i++) {
for (size_t n = 0; n < neurons; n++) {
if(v[i-1][n] >= vp) {
v[i][n] = -vp;
}
else {
v[i][n] = v[i-1][n] + h * ( pow(v[i-1][n], 2) + I[i] + eta[n] );
}
v_avg[i] += v[i][n]; // Sum of membrane potentials
}
cout << "step " << i << "/" << steps << " done\n";
v.erase( v.begin()-i+1); // Erase row v[i-1]
v_avg[i] = v_avg[i]/neurons; // Mean membrane potential
}
v.erase( v.begin()+steps+1 ); // Erase last row
I'm not sure why I'm getting segmentation fault after the steps/2 step (I'm doing tests with a small steps value):
...
step 10/20 done
[1] 1791 segmentation fault (core dumped) ./qif_solve_vect
Update:
Thanks to #1201ProgramAlarm I see what's my problem. My question would be:
How can I work with the matrix in a way it isn't allocated from the very beginning.
How can I deallocate/free rows whilst keeping the indices (unlike v.erase( v.begin())). This is essential, as I will later implement different refractory times for each neuron when they produce a spike (v[i][n] = -vp;).

In your erase statement, you're subtracting from v.begin(), which will result in an invalid iterator since it will point before the start of the vector. You probably meant v.erase( v.begin() + i - 1);.
However, erasing like this isn't saving you any space since you already have the full matrix allocated. The erase will move all the remaining elements down one element, and your indexing for the next loop will be wrong (since you'd want to use v[0] all the time).

Related

SFML removing elements from vector

Hello I have a problem with vectors I have double loop where I erase elements from both vectors and I have a problem when I remove element from first loop's vector it is showing the error "vector too long". I had similar problem in my last project but this time I can't to solve it the same way I did last time. The error is showing after last bullet hit the wall.
collision func
void Game::BulletHit(int j, std::vector <Bullet>& team, std::vector <Squares>& square,
std::vector <Squares>& square2)
{
for (size_t i = 0; i < bulletTeam1.size(); i++)
{
if(team[i].bullet.getGlobalBounds().intersects(square[j].square.getGlobalBounds()))
{
int x = square[j].square.getPosition().x;
int y = square[j].square.getPosition().y;
//sf::Color color = square[j].square.getFillColor();
square.erase(square.begin() + j);
Squares1.square.setFillColor(sf::Color::White);
Squares1.square.setPosition(sf::Vector2f(x, y));
square2.push_back(Squares1);
team.erase(team.begin() + i);
std::cout << "collison " << team.size() << std::endl;
}
}
}
code where i use it
for (size_t i = 0; i < team1.size(); i++)
{
BulletHit(i, bulletTeam2, team1, team2);
//BulletHit(i, bulletTeam3, team1, team3);
//BulletHit(i, bulletTeam4, team1, team4);
}
I don't think we have enough information to fully understand your problem.
One thing that I can point out and you maybe didn't catch is, that calling square.erase(square.begin() + j); will remove the j-th element from the square vector. But then you continue to run the inner loop, thus in the next iteration, you'll again remove the j-th element. This will run until there are fewer than j elements in the vector and then crash or the inner loop exits early. Either way, I believe this may not be the intended goal here and you may want to remove the j-th element outside the inner loop, so that the j-th element is only removed once.

c++: vector of vector issue

I wrote a c++ code where i'm testing the running time of vector push_back. I have a vector of vector. I called my main vector, mainVec, and embedded vector, subVec. So, I push backed 2^20 elements into subVec and then push backed subVec 2^20 times into mainVec. However, in the loop of subVec-push_back I have a cout command which doesn't get executed. I was hoping you can point out my mistake.
Here is the code (There is no error in the code, though):
vector<int> subVec;
vector< vector<int> > mainVec;
//Fills the subvector with 2^20 elements
for( size_t i = 0; i < (pow(2,20)+1); ++i) subVec.push_back(i);
//Filling of the maiVec with 2^20 subVec
for( size_t j = 10; j < 21; ++j) {
cout << pow(2,j) << endl;
clock_t t1 = clock();
//2^j times subVec is push_backed for j < 21
for( size_t k = 0; k < pow(2,j); ++k ) mainVec.push_back( subVec );
t1 = clock()-t1;
//Outputting to file
cout << "\t" << (float(t1) / CLOCKS_PER_SEC) << endl;
//ofs << pow(2,j) << "\t\t" << (float(t1) / CLOCKS_PER_SEC) << endl;
}
There are several issues with your code.
First, you don't need the +1 in the first loop, i.e,. pow(2,20)+1. Since you're starting with 0 and you want 2^20 times, you need to do until i<2^20.
Second, it's better to calculate the pows before the loop, otherwise it will calculate them each time and that could take forever.
Third, you can do 1<<j instead of pow(2,j). Just FYI.
Forth, and most important, we are talking about a tremenduous amount of memory here. Even your smallest loop is doing 2^30 ints which is 4GB of memory. My guess is that your program is just killing your computer and the reason it never prints the second cout is that it doesn't get there (because it's trying to use swap file for the memory). Try using smaller numbers, say 2^10 for the first loop, and see if you get the outputs.

Optimized way to find M largest elements in an NxN array using C++

I need a blazing fast way to find the 2D positions and values of the M largest elements in an NxN array.
right now I'm doing this:
struct SourcePoint {
Point point;
float value;
}
SourcePoint* maxValues = new SourcePoint[ M ];
maxCoefficients = new SourcePoint*[
for (int j = 0; j < rows; j++) {
for (int i = 0; i < cols; i++) {
float sample = arr[i][j];
if (sample > maxValues[0].value) {
int q = 1;
while ( sample > maxValues[q].value && q < M ) {
maxValues[q-1] = maxValues[q]; // shuffle the values back
q++;
}
maxValues[q-1].value = sample;
maxValues[q-1].point = Point(i,j);
}
}
}
A Point struct is just two ints - x and y.
This code basically does an insertion sort of the values coming in. maxValues[0] always contains the SourcePoint with the lowest value that still keeps it within the top M values encoutered so far. This gives us a quick and easy bailout if sample <= maxValues, we don't do anything. The issue I'm having is the shuffling every time a new better value is found. It works its way all the way down maxValues until it finds it's spot, shuffling all the elements in maxValues to make room for itself.
I'm getting to the point where I'm ready to look into SIMD solutions, or cache optimisations, since it looks like there's a fair bit of cache thrashing happening. Cutting the cost of this operation down will dramatically affect the performance of my overall algorithm since this is called many many times and accounts for 60-80% of my overall cost.
I've tried using a std::vector and make_heap, but I think the overhead for creating the heap outweighed the savings of the heap operations. This is likely because M and N generally aren't large. M is typically 10-20 and N 10-30 (NxN 100 - 900). The issue is this operation is called repeatedly, and it can't be precomputed.
I just had a thought to pre-load the first M elements of maxValues which may provide some small savings. In the current algorithm, the first M elements are guaranteed to shuffle themselves all the way down just to initially fill maxValues.
Any help from optimization gurus would be much appreciated :)
A few ideas you can try. In some quick tests with N=100 and M=15 I was able to get it around 25% faster in VC++ 2010 but test it yourself to see whether any of them help in your case. Some of these changes may have no or even a negative effect depending on the actual usage/data and compiler optimizations.
Don't allocate a new maxValues array each time unless you need to. Using a stack variable instead of dynamic allocation gets me +5%.
Changing g_Source[i][j] to g_Source[j][i] gains you a very little bit (not as much as I'd thought there would be).
Using the structure SourcePoint1 listed at the bottom gets me another few percent.
The biggest gain of around +15% was to replace the local variable sample with g_Source[j][i]. The compiler is likely smart enough to optimize out the multiple reads to the array which it can't do if you use a local variable.
Trying a simple binary search netted me a small loss of a few percent. For larger M/Ns you'd likely see a benefit.
If possible try to keep the source data in arr[][] sorted, even if only partially. Ideally you'd want to generate maxValues[] at the same time the source data is created.
Look at how the data is created/stored/organized may give you patterns or information to reduce the amount of time to generate your maxValues[] array. For example, in the best case you could come up with a formula that gives you the top M coordinates without needing to iterate and sort.
Code for above:
struct SourcePoint1 {
int x;
int y;
float value;
int test; //Play with manual/compiler padding if needed
};
If you want to go into micro-optimizations at this point, the a simple first step should be to get rid of the Points and just stuff both dimensions into a single int. That reduces the amount of data you need to shift around, and gets SourcePoint down to being a power of two long, which simplifies indexing into it.
Also, are you sure that keeping the list sorted is better than simply recomputing which element is the new lowest after each time you shift the old lowest out?
(Updated 22:37 UTC 2011-08-20)
I propose a binary min-heap of fixed size holding the M largest elements (but still in min-heap order!). It probably won't be faster in practice, as I think OPs insertion sort probably has decent real world performance (at least when the recommendations of the other posteres in this thread are taken into account).
Look-up in the case of failure should be constant time: If the current element is less than the minimum element of the heap (containing the max M elements) we can reject it outright.
If it turns out that we have an element bigger than the current minimum of the heap (the Mth biggest element) we extract (discard) the previous min and insert the new element.
If the elements are needed in sorted order the heap can be sorted afterwards.
First attempt at a minimal C++ implementation:
template<unsigned size, typename T>
class m_heap {
private:
T nodes[size];
static const unsigned last = size - 1;
static unsigned parent(unsigned i) { return (i - 1) / 2; }
static unsigned left(unsigned i) { return i * 2; }
static unsigned right(unsigned i) { return i * 2 + 1; }
void bubble_down(unsigned int i) {
for (;;) {
unsigned j = i;
if (left(i) < size && nodes[left(i)] < nodes[i])
j = left(i);
if (right(i) < size && nodes[right(i)] < nodes[j])
j = right(i);
if (i != j) {
swap(nodes[i], nodes[j]);
i = j;
} else {
break;
}
}
}
void bubble_up(unsigned i) {
while (i > 0 && nodes[i] < nodes[parent(i)]) {
swap(nodes[parent(i)], nodes[i]);
i = parent(i);
}
}
public:
m_heap() {
for (unsigned i = 0; i < size; i++) {
nodes[i] = numeric_limits<T>::min();
}
}
void add(const T& x) {
if (x < nodes[0]) {
// reject outright
return;
}
nodes[0] = x;
swap(nodes[0], nodes[last]);
bubble_down(0);
}
};
Small test/usage case:
#include <iostream>
#include <limits>
#include <algorithm>
#include <vector>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
using namespace std;
// INCLUDE TEMPLATED CLASS FROM ABOVE
typedef vector<float> vf;
bool compare(float a, float b) { return a > b; }
int main()
{
int N = 2000;
vf v;
for (int i = 0; i < N; i++) v.push_back( rand()*1e6 / RAND_MAX);
static const int M = 50;
m_heap<M, float> h;
for (int i = 0; i < N; i++) h.add( v[i] );
sort(v.begin(), v.end(), compare);
vf heap(h.get(), h.get() + M); // assume public in m_heap: T* get() { return nodes; }
sort(heap.begin(), heap.end(), compare);
cout << "Real\tFake" << endl;
for (int i = 0; i < M; i++) {
cout << v[i] << "\t" << heap[i] << endl;
if (fabs(v[i] - heap[i]) > 1e-5) abort();
}
}
You're looking for a priority queue:
template < class T, class Container = vector<T>,
class Compare = less<typename Container::value_type> >
class priority_queue;
You'll need to figure out the best underlying container to use, and probably define a Compare function to deal with your Point type.
If you want to optimize it, you could run a queue on each row of your matrix in its own worker thread, then run an algorithm to pick the largest item of the queue fronts until you have your M elements.
A quick optimization would be to add a sentinel value to yourmaxValues array. If you have maxValues[M].value equal to std::numeric_limits<float>::max() then you can eliminate the q < M test in your while loop condition.
One idea would be to use the std::partial_sort algorithm on a plain one-dimensional sequence of references into your NxN array. You could probably also cache this sequence of references for subsequent calls. I don't know how well it performs, but it's worth a try - if it works good enough, you don't have as much "magic". In particular, you don't resort to micro optimizations.
Consider this showcase:
#include <algorithm>
#include <iostream>
#include <vector>
#include <stddef.h>
static const int M = 15;
static const int N = 20;
// Represents a reference to a sample of some two-dimensional array
class Sample
{
public:
Sample( float *arr, size_t row, size_t col )
: m_arr( arr ),
m_row( row ),
m_col( col )
{
}
inline operator float() const {
return m_arr[m_row * N + m_col];
}
bool operator<( const Sample &rhs ) const {
return (float)other < (float)*this;
}
int row() const {
return m_row;
}
int col() const {
return m_col;
}
private:
float *m_arr;
size_t m_row;
size_t m_col;
};
int main()
{
// Setup a demo array
float arr[N][N];
memset( arr, 0, sizeof( arr ) );
// Put in some sample values
arr[2][1] = 5.0;
arr[9][11] = 2.0;
arr[5][4] = 4.0;
arr[15][7] = 3.0;
arr[12][19] = 1.0;
// Setup the sequence of references into this array; you could keep
// a copy of this sequence around to reuse it later, I think.
std::vector<Sample> samples;
samples.reserve( N * N );
for ( size_t row = 0; row < N; ++row ) {
for ( size_t col = 0; col < N; ++col ) {
samples.push_back( Sample( (float *)arr, row, col ) );
}
}
// Let partial_sort find the M largest entry
std::partial_sort( samples.begin(), samples.begin() + M, samples.end() );
// Print out the row/column of the M largest entries.
for ( std::vector<Sample>::size_type i = 0; i < M; ++i ) {
std::cout << "#" << (i + 1) << " is " << (float)samples[i] << " at " << samples[i].row() << "/" << samples[i].col() << std::endl;
}
}
First of all, you are marching through the array in the wrong order!
You always, always, always want to scan through memory linearly. That means the last index of your array needs to be changing fastest. So instead of this:
for (int j = 0; j < rows; j++) {
for (int i = 0; i < cols; i++) {
float sample = arr[i][j];
Try this:
for (int i = 0; i < cols; i++) {
for (int j = 0; j < rows; j++) {
float sample = arr[i][j];
I predict this will make a bigger difference than any other single change.
Next, I would use a heap instead of a sorted array. The standard <algorithm> header already has push_heap and pop_heap functions to use a vector as a heap. (This will probably not help all that much, though, unless M is fairly large. For small M and a randomized array, you do not wind up doing all that many insertions on average... Something like O(log N) I believe.)
Next after that is to use SSE2. But that is peanuts compared to marching through memory in the right order.
You should be able to get nearly linear speedup with parallel processing.
With N CPUs, you can process a band of rows/N rows (and all columns) with each CPU, finding the top M entries in each band. And then do a selection sort to find the overall top M.
You could probably do that with SIMD as well (but here you'd divide up the task by interleaving columns instead of banding the rows). Don't try to make SIMD do your insertion sort faster, make it do more insertion sorts at once, which you combine at the end using a single very fast step.
Naturally you could do both multi-threading and SIMD, but on a problem which is only 30x30, that's not likely to be worthwhile.
I tried replacing float by double, and interestingly that gave me a speed improvement of about 20% (using VC++ 2008). That's a bit counterintuitive, but it seems modern processors or compilers are optimized for double value processing.
Use a linked list to store the best yet M values. You'll still have to iterate over it to find the right spot, but the insertion is O(1). It would probably even be better than binary search and insertion O(N)+O(1) vs O(lg(n))+O(N).
Interchange the fors, so you're not accessing every N element in memory and trashing the cache.
LE: Throwing another idea that might work for uniformly distributed values.
Find the min, max in 3/2*O(N^2) comparisons.
Create anywhere from N to N^2 uniformly distributed buckets, preferably closer to N^2 than N.
For every element in the NxN matrix place it in bucket[(int)(value-min)/range], range=max-min.
Finally create a set starting from the highest bucket to the lowest, add elements from other buckets to it while |current set| + |next bucket| <=M.
If you get M elements you're done.
You'll likely get less elements than M, let's say P.
Apply your algorithm for the remaining bucket and get biggest M-P elements out of it.
If elements are uniform and you use N^2 buckets it's complexity is about 3.5*(N^2) vs your current solution which is about O(N^2)*ln(M).

Find the biggest 3 numbers in a vector

I'm trying to make a function to get the 3 biggest numbers in a vector. For example:
Numbers: 1 6 2 5 3 7 4
Result: 5 6 7
I figured I could sort them DESC, get the 3 numbers at the beggining, and after that resort them ASC, but that would be a waste of memory allocation and execution time. I know there is a simpler solution, but I can't figure it out. And another problem is, what if I have only two numbers...
BTW: I use as compiler BorlandC++ 3.1 (I know, very old, but that's what I'll use at the exam..)
Thanks guys.
LE: If anyone wants to know more about what I'm trying to accomplish, you can check the code:
#include<fstream.h>
#include<conio.h>
int v[1000], n;
ifstream f("bac.in");
void citire();
void afisare_a();
int ultima_cifra(int nr);
void sortare(int asc);
void main() {
clrscr();
citire();
sortare(2);
afisare_a();
getch();
}
void citire() {
f>>n;
for(int i = 0; i < n; i++)
f>>v[i];
f.close();
}
void afisare_a() {
for(int i = 0;i < n; i++)
if(ultima_cifra(v[i]) == 5)
cout<<v[i]<<" ";
}
int ultima_cifra(int nr) {
return nr - 10 * ( nr / 10 );
}
void sortare(int asc) {
int aux, s;
if(asc == 1)
do {
s = 0;
for(int i = 0; i < n-1; i++)
if(v[i] > v[i+1]) {
aux = v[i];
v[i] = v[i+1];
v[i+1] = aux;
s = 1;
}
} while( s == 1);
else
do {
s = 0;
for(int i = 0; i < n-1; i++)
if(v[i] < v[i+1]) {
aux = v[i];
v[i] = v[i+1];
v[i+1] = v[i];
s = 1;
}
} while(s == 1);
}
Citire = Read
Afisare = Display
Ultima Cifra = Last digit of number
Sortare = Bubble Sort
If you were using a modern compiler, you could use std::nth_element to find the top three. As is, you'll have to scan through the array keeping track of the three largest elements seen so far at any given time, and when you get to the end, those will be your answer.
For three elements that's a trivial thing to manage. If you had to do the N largest (or smallest) elements when N might be considerably larger, then you'd almost certainly want to use Hoare's select algorithm, just like std::nth_element does.
You could do this without needing to sort at all, it's doable in O(n) time with linear search and 3 variables keeping your 3 largest numbers (or indexes of your largest numbers if this vector won't change).
Why not just step through it once and keep track of the 3 highest digits encountered?
EDIT: The range for the input is important in how you want to keep track of the 3 highest digits.
Use std::partial_sort to descending sort the first c elements that you care about. It will run in linear time for a given number of desired elements (n log c) time.
If you can't use std::nth_element write your own selection function.
You can read about them here: http://en.wikipedia.org/wiki/Selection_algorithm#Selecting_k_smallest_or_largest_elements
Sort them normally and then iterate from the back using rbegin(), for as many as you wish to extract (no further than rend() of course).
sort will happen in place whether ASC or DESC by the way, so memory is not an issue since your container element is an int, thus has no encapsulated memory of its own to manage.
Yes sorting is good. A especially for long or variable length lists.
Why are you sorting it twice, though? The second sort might actually be very inefficient (depends on the algorithm in use). A reverse would be quicker, but why even do that? If you want them in ascending order at the end, then sort them into ascending order first ( and fetch the numbers from the end)
I think you have the choice between scanning the vector for the three largest elements or sorting it (either using sort in a vector or by copying it into an implicitly sorted container like a set).
If you can control the array filling maybe you could add the numbers ordered and then choose the first 3 (ie), otherwise you can use a binary tree to perform the search or just use a linear search as birryree says...
Thank #nevets1219 for pointing out that the code below only deals with positive numbers.
I haven't tested this code enough, but it's a start:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> nums;
nums.push_back(1);
nums.push_back(6);
nums.push_back(2);
nums.push_back(5);
nums.push_back(3);
nums.push_back(7);
nums.push_back(4);
int first = 0;
int second = 0;
int third = 0;
for (int i = 0; i < nums.size(); i++)
{
if (nums.at(i) > first)
{
third = second;
second = first;
first = nums.at(i);
}
else if (nums.at(i) > second)
{
third = second;
second = nums.at(i);
}
else if (nums.at(i) > third)
{
third = nums.at(i);
}
std::cout << "1st: " << first << " 2nd: " << second << " 3rd: " << third << std::endl;
}
return 0;
}
The following solution finds the three largest numbers in O(n) and preserves their relative order:
std::vector<int>::iterator p = std::max_element(vec.begin(), vec.end());
int x = *p;
*p = std::numeric_limits<int>::min();
std::vector<int>::iterator q = std::max_element(vec.begin(), vec.end());
int y = *q;
*q = std::numeric_limits<int>::min();
int z = *std::max_element(vec.begin(), vec.end());
*q = y; // restore original value
*p = x; // restore original value
A general solution for the top N elements of a vector:
Create an array or vector topElements of length N for your top N elements.
Initialise each element of topElements to the value of your first element in your vector.
Select the next element in the vector, or finish if no elements are left.
If the selected element is greater than topElements[0], replace topElements[0] with the value of the element. Otherwise, go to 3.
Starting with i = 0, swap topElements[i] with topElements[i + 1] if topElements[i] is greater than topElements[i + 1].
While i is less than N, increment i and go to 5.
Go to 3.
This should result in topElements containing your top N elements in reverse order of value - that is, the largest value is in topElements[N - 1].

How to sum up elements of a C++ vector?

What are the good ways of finding the sum of all the elements in a std::vector?
Suppose I have a vector std::vector<int> vector with a few elements in it. Now I want to find the sum of all the elements. What are the different ways for the same?
Actually there are quite a few methods.
int sum_of_elems = 0;
C++03
Classic for loop:
for(std::vector<int>::iterator it = vector.begin(); it != vector.end(); ++it)
sum_of_elems += *it;
Using a standard algorithm:
#include <numeric>
sum_of_elems = std::accumulate(vector.begin(), vector.end(), 0);
Important Note: The last argument's type is used not just for the initial value, but for the type of the result as well. If you put an int there, it will accumulate ints even if the vector has float. If you are summing floating-point numbers, change 0 to 0.0 or 0.0f (thanks to nneonneo). See also the C++11 solution below.
C++11 and higher
b. Automatically keeping track of the vector type even in case of future changes:
#include <numeric>
sum_of_elems = std::accumulate(vector.begin(), vector.end(),
decltype(vector)::value_type(0));
Using std::for_each:
std::for_each(vector.begin(), vector.end(), [&] (int n) {
sum_of_elems += n;
});
Using a range-based for loop (thanks to Roger Pate):
for (auto& n : vector)
sum_of_elems += n;
C++17 and above
Using std::reduce which also takes care of the result type, e.g if you have std::vector<int>, you get int as result. If you have std::vector<float>, you get float. Or if you have std::vector<std::string>, you get std::string (all strings concatenated). Interesting, isn't it?
auto result = std::reduce(v.begin(), v.end());
There are other overloads of this function which you can run even parallelly, in case if you have a large collection and you want to get the result quickly.
The easiest way is to use std:accumulate of a vector<int> A:
#include <numeric>
cout << accumulate(A.begin(), A.end(), 0);
Prasoon has already offered up a host of different (and good) ways to do this, none of which need repeating here. I'd like to suggest an alternative approach for speed however.
If you're going to be doing this quite a bit, you may want to consider "sub-classing" your vector so that a sum of elements is maintained separately (not actually sub-classing vector which is iffy due to the lack of a virtual destructor - I'm talking more of a class that contains the sum and a vector within it, has-a rather than is-a, and provides the vector-like methods).
For an empty vector, the sum is set to zero. On every insertion to the vector, add the element being inserted to the sum. On every deletion, subtract it. Basically, anything that can change the underlying vector is intercepted to ensure the sum is kept consistent.
That way, you have a very efficient O(1) method for "calculating" the sum at any point in time (just return the sum currently calculated). Insertion and deletion will take slightly longer as you adjust the total and you should take this performance hit into consideration.
Vectors where the sum is needed more often than the vector is changed are the ones likely to benefit from this scheme, since the cost of calculating the sum is amortised over all accesses. Obviously, if you only need the sum every hour and the vector is changing three thousand times a second, it won't be suitable.
Something like this would suffice:
class UberVector:
private Vector<int> vec
private int sum
public UberVector():
vec = new Vector<int>()
sum = 0
public getSum():
return sum
public add (int val):
rc = vec.add (val)
if rc == OK:
sum = sum + val
return rc
public delindex (int idx):
val = 0
if idx >= 0 and idx < vec.size:
val = vec[idx]
rc = vec.delindex (idx)
if rc == OK:
sum = sum - val
return rc
Obviously, that's pseudo-code and you may want to have a little more functionality, but it shows the basic concept.
Why perform the summation forwards when you can do it backwards? Given:
std::vector<int> v; // vector to be summed
int sum_of_elements(0); // result of the summation
We can use subscripting, counting backwards:
for (int i(v.size()); i > 0; --i)
sum_of_elements += v[i-1];
We can use range-checked "subscripting," counting backwards (just in case):
for (int i(v.size()); i > 0; --i)
sum_of_elements += v.at(i-1);
We can use reverse iterators in a for loop:
for(std::vector<int>::const_reverse_iterator i(v.rbegin()); i != v.rend(); ++i)
sum_of_elements += *i;
We can use forward iterators, iterating backwards, in a for loop (oooh, tricky!):
for(std::vector<int>::const_iterator i(v.end()); i != v.begin(); --i)
sum_of_elements += *(i - 1);
We can use accumulate with reverse iterators:
sum_of_elems = std::accumulate(v.rbegin(), v.rend(), 0);
We can use for_each with a lambda expression using reverse iterators:
std::for_each(v.rbegin(), v.rend(), [&](int n) { sum_of_elements += n; });
So, as you can see, there are just as many ways to sum the vector backwards as there are to sum the vector forwards, and some of these are much more exciting and offer far greater opportunity for off-by-one errors.
#include<boost/range/numeric.hpp>
int sum = boost::accumulate(vector, 0);
One can also use std::valarray<T> like this
#include<iostream>
#include<vector>
#include<valarray>
int main()
{
std::vector<int> seq{ 1,2,3,4,5,6,7,8,9,10 };
std::valarray<int> seq_add{ seq.data(), seq.size() };
std::cout << "sum = " << seq_add.sum() << "\n";
return 0;
}
Some may not find this way efficient since the size of valarray needs to be as big as the size of the vector and initializing valarray will also take time.
In that case, don't use it and take it as yet another way of summing up the sequence.
C++0x only:
vector<int> v; // and fill with data
int sum {}; // or = 0 ... :)
for (int n : v) sum += n;
This is similar to the BOOST_FOREACH mentioned elsewhere and has the same benefit of clarity in more complex situations, compared to stateful functors used with accumulate or for_each.
I'm a Perl user, an a game we have is to find every different ways to increment a variable... that's not really different here. The answer to how many ways to find the sum of the elements of a vector in C++ is probably an infinity...
My 2 cents:
Using BOOST_FOREACH, to get free of the ugly iterator syntax:
sum = 0;
BOOST_FOREACH(int & x, myvector){
sum += x;
}
iterating on indices (really easy to read).
int i, sum = 0;
for (i=0; i<myvector.size(); i++){
sum += myvector[i];
}
This other one is destructive, accessing vector like a stack:
while (!myvector.empty()){
sum+=myvector.back();
myvector.pop_back();
}
#include<iostream>
#include<vector>
#include<numeric>
using namespace std;
int main() {
vector<int> v = {2,7,6,10};
cout<<"Sum of all the elements are:"<<endl;
cout<<accumulate(v.begin(),v.end(),0);
}
Using inclusive_scan (C++17 and above):
The advantage is you can get sums of first "N" elements in a vector. Below is the code. Explanation in comments.
To use inclusive_scan , need to include "numeric" header.
//INPUT VECTOR
std::vector<int> data{ 3, 1, 4, 1, 5, 9, 2, 6 };
//OUTPUT VECTOR WITH SUMS
//FIRST ELEMENT - 3
//SECOND ELEMENT - 3 + 1
//THIRD ELEMENT - 3 + 1 + 4
//FOURTH ELEMENT - 3 + 1 + 4 + 1
// ..
// ..
//LAST ELEMENT - 3 + 1 + 4 + 1 + 5 + 9 + 2 + 6
std::vector<int> sums(data.size());
//SUM ALL NUMBERS IN A GIVEN VECTOR.
inclusive_scan(data.begin(), data.end(),
sums.begin());
//SUM OF FIRST 5 ELEMENTS.
std::cout << "Sum of first 5 elements :: " << sums[4] << std::endl;
//SUM OF ALL ELEMENTS
std::cout << "Sum of all elements :: " << sums[data.size() - 1] << std::endl;
Also there is an overload where the execution policy can be specified. Sequential execution or Parallel execution. Need to include "execution" header.
//SUM ALL NUMBERS IN A GIVEN VECTOR.
inclusive_scan(std::execution::par,data.begin(), data.end(),
sums.begin());
Using reduce :
One more option which I did not notice in the answers is using std::reduce which is introduced in c++17.
But you may notice many compilers not supporting it (Above GCC 10 may be good). But eventually the support will come.
With std::reduce, the advantage comes when using the execution policies. Specifying execution policy is optional. When the execution policy specified is std::execution::par, the algorithm may use hardware parallel processing capabilities. The gain may be more clear when using big size vectors.
Example:
//SAMPLE
std::vector<int> vec = {2,4,6,8,10,12,14,16,18};
//WITHOUT EXECUTION POLICY
int sum = std::reduce(vec.begin(),vec.end());
//TAKING THE ADVANTAGE OF EXECUTION POLICIES
int sum2 = std::reduce(std::execution::par,vec.begin(),vec.end());
std::cout << "Without execution policy " << sum << std::endl;
std::cout << "With execution policy " << sum2 << std::endl;
You need <numeric> header for std::reduce.
And '<execution>' for execution policies.
std::accumulate could have overflow issues so the best approach could be to do range based accumulation on bigger data type variable to avoid overflow issues.
long long sum = 0;
for (const auto &n : vector)
sum += n;
And then downcast to appropriate data type further using static_cast<>.
Nobody seems to address the case of summing elements of a vector that can have NaN values in it, e.g. numerical_limits<double>::quite_NaN()
I usually loop through the elements and bluntly check.
vector<double> x;
//...
size_t n = x.size();
double sum = 0;
for (size_t i = 0; i < n; i++){
sum += (x[i] == x[i] ? x[i] : 0);
}
It's not fancy at all, i.e. no iterators or any other tricks but I this is how I do it. Some times if there are other things to do inside the loop and I want the code to be more readable I write
double val = x[i];
sum += (val == val ? val : 0);
//...
inside the loop and re-use val if needed.
It is easy. C++11 provides an easy way to sum up elements of a vector.
sum = 0;
vector<int> vec = {1,2,3,4,5,....}
for(auto i:vec)
sum+=i;
cout<<" The sum is :: "<<sum<<endl;