Arrays not filling in as expected in C++ [closed] - c++

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I just started trying to learn C++ yesterday, and one of my goals for the near future is to make a matrix multiplication function.
Before trying that, I wanted to get a feel of how arrays work, so I made a simple program that is supposed to make two arrays that represent (mathematical) vectors in 3D space and take their dot product. Below is the code that I wrote.
/*Initializing two vectors, v1 and v2*/
int v1[3] = { 0 };
int v2[3] = { 0 };
int sum = 0; //This will become the sum for the dot product
int i=0; //counter for the following loop
for(; i<3; ++i)
v1[i] = v2[i] = i+1; //This should make both vectors equal {1,2,3} at the end of the loop
sum += v1[i]*v2[i]; //Component-wise, performing the dot product operation
std::cout<< sum <<std::endl;
return 0;
When the code is done running, the output is supposed to come out to be 1*1 +2*2 +3*3 = 14
However, the output is actually coming out as 647194768, which doesn't seem to make any sense. I heard from some friends that in C++, if you aren't careful about initializing the arrays, then some crazy stuff happens, but I'm completely dumbfounded how something this simple could mess up so badly.
Could you provide some deeper insight into why this is happening, and what about C++'s logic causes this?

You are accidentally putting the sum += line outside the for loop. This is because you have no braces on the loop. So only the first line v1[i]... is included in the for loop. Change it like this:
/*Initializing two vectors, v1 and v2*/
int v1[3] = { 0 };
int v2[3] = { 0 };
int sum = 0; //This will become the sum for the dot product
for(int i=0; i<3; ++i)
{
v1[i] = v2[i] = i+1; //This should make both vectors equal {1,2,3} at the end of the loop
sum += v1[i]*v2[i]; //Component-wise, performing the dot product operation
}
std::cout<< sum <<std::endl;
return 0;
Note the use of braces { .. } around the for loop statements. Now this gives the correct answer: 14.

As you ask deeper insight here i am writing some explanation of your code
int v1[3] = { 0 };
int v2[3] = { 0 };
Initializing v1 and v2 with 0,
int sum = 0; //This will become the sum for the dot product
Here you Initializing sum with 0 (GOOD)
int i=0; //counter for the following loop
for(; i<3; ++i)
v1[i] = v2[i] = i+1; //This should make both vectors equal {1,2,3} at the end of the loop
sum += v1[i]*v2[i]; //Component-wise, performing the dot product operation
Here you make mistake as you did not provide {..} compiler will consider first list in loop statement. like below
v1[0] = v2[0] = 0+1
v1[1] = v2[1] = 1+1
v1[2] = v2[2] = 2+1
Now second line will come in picture,
Note that now i is become 3.
sum += v1[i]*v2[i];
Here, you try to access invalid location of an array (4th one)
that's the reason why you got 647194768
You got junk value nothing else
Correct code is already given by metacubed, so I am not writing here,
best of luck for you further study.

Related

Vector particles with nested for loops - collisions not detected

So I have some particles (ellipses) bouncing around the screen. I'm trying to get them to collide rather than pass over each other. In order to do this I must cycle through every particle and compare it's distance to every other particle with a for loop nested within another for loop, then tell their velocity to change when their points are a certain distance from each other like so:
//p.size() returns the size of the particle system (yes it works)
//ofDist() is an open frameworks function that calculates the dist between 2 points
for( int i = 0; i < p.size(); i++){
// cout << i << endl;
for(int j = 0; j < p.size(); j++){
// cout << j << endl;
pDist[i] = ofDist(p[i].pos.x, p[i].pos.y, p[j].pos.x, p[j].pos.y);
// cout << pDist[i] << endl;
if(pDist[i] <= 300){
p[i].vel.x *= -1;
p[i].vel.y *= -1;
p[j].vel.x *= -1;
p[j].vel.y *= -1;
}
}
}
But for some mysterious reason they still pass right over each other like they don't even exist. It does work if I apply this to just 2 particles without the for loops:
pDist[0] = ofDist(p[0].pos.x, p[0].pos.y, p[1].pos.x, p[1].pos.y);
if(pDist[0] <= 300){
cout << "It's colliding" << endl;
p[0].vel.x *= -1;
p[0].vel.y *= -1;
p[1].vel.x *= -1;
p[1].vel.y *= -1;
}
The particles are stored in a vector by the way.
Any ideas how I can get this to work with the for loops?
update
The size of my vector is 3, so p.size() = 3 ( or 2, doesn't really make a difference right now). I substituted p.size() for 2 and 3 in my code and it didn't change anything, so that's not the source of the issue.
update 2
If someone could let me know what I need to do to not get downvoted that would be helpful. :/
A pretty large issue is that by saying:
for( int i = 0; i < p.size(); i++){
for(int j = 0; j < p.size(); j++){
You are actually checking each particle against themselves. You are also checking particles collisions twice. By detecting a single collision twice, and inverting the velocity each time, you are essentially doing nothing( a * -1 * -1 = a ).
A better way to do this would be to use a loop where particles collisions are only checked once, and a particle is not checked against itself. You can do this by starting the nested loop after the current particle (essentially offsetting the index by the indexes that have already been checked), like so:
for( int i = 0; i < p.size()-1; i++){
for(int j = i+1; j < p.size(); j++){
This also has the benefit of being significantly faster for a larger number of particles.
There is also no reason to store the calculated distance in an array (unless your code makes use of this somewhere else). Simply using a double would work fine here.
Edit:
Just to be a bit clearer, I have logged the output of the two arrays to demonstrate. I have used 3 particles in the array.
Original loop
1 compared to 1 (This is a problem. Checking a particle against itself)
1 compared to 2
1 compared to 3
2 compared to 1 (This is a problem. This has already been checked for)
2 compared to 2 (This is a problem. Checking a particle against itself)
2 compared to 3
3 compared to 1 (This is a problem. This has already been checked for)
3 compared to 2 (This is a problem. This has already been checked for)
3 compared to 3 (This is a problem. Checking a particle against itself)
Modified loop
1 compared to 2
1 compared to 3
2 compared to 3
As you can see, there are only three collisions checked for in the modified loop, and there are no double ups.

How to make this code faster (learning best practices)? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I have this little loop here, and I was wondering if I do some big mistake, perf wise.
For example, is there a way to rewrite parts of it differently, to make vectorization possible (assuming GCC4.8.1 and all vecotrization friendly flags enabled)?
Is this the best way to pass a list a number (const float name_of_var[])?
The idea of the code is to take a vector (in the mathematical sense, not necesserly a std::vector) of (unsorted numbers) y and two bound values (ox[0]<=ox[1]) and to store in a vector of integers rdx the index i of the entry of y satisfying ox[0]<=y[i]<=ox[1].
rdx can contain m elements and y has capacity n and n>m. If there are more than m
values of y[i] satisfying ox[0]<=y[i]<=ox[1] then the code should return the first m
Thanks in advance,
void foo(const int n,const int m,const float y[],const float ox[],int rdx[]){
int d0,j=0,i=0;
for(;;){
i++;
d0=((y[i]>=ox[0])+(y[i]<=ox[1]))/2;
if(d0==1){
rdx[j]=i;
j++;
}
if(j==m) break;
if(i==n-1) break;
}
}
d0=((y[i]>=ox[0])+(y[i]<=ox[1]))/2;
if(d0==1)
I believe the use of an intermediary variable is useless, and take a few more cycles
This is the most optimized version I could think of, but it's totally unreadable...
void foo(int n, int m, float y[],const float ox[],int rdx[])
{
for(int i = 0; i < n && m != 0; i++)
{
if(*y >= *ox && *y <= ox[1])
{
*rdx=i;
rdx++;
m--;
}
y++;
}
}
I think the following version with a decent optimisation flag should do the job
void foo(int n, int m,const float y[],const float ox[],int rdx[])
{
for(int j = 0, i = 0; j < m && i < n; i++) //Reorder to put the condition with the highest probability to fail first
{
if(y[i] >= ox[0] && y[i] <= ox[1])
{
rdx[j++] = i;
}
}
}
Just to make sure I'm correct: you're trying to find the first m+1 (if it's actually m, do j == m-1) values that are in the range of [ ox[0], ox[1] ]?
If so, wouldn't it be better to do:
for (int i=0, j=0;;++i) {
if (y[i] < ox[0]) continue;
if (y[i] > ox[1]) continue;
rdx[j] = i;
j++;
if (j == m || i == n-1) break;
}
If y[i] is indeed in the range you must perform both comparisons as we both do.
If y[i] is under ox[0], no need to perform the second comparison.
I avoid the use of division.
A. Yes, passing the float array as float[] is not only efficient, it is the only way (and is identical to a float * argument).
A1. But in C++ you can use better types without performance loss. Accessing a vector or array (the standard library container) should not be slower than accessing a plain C style array. I would strongly advise you to use those. In modern C++ there is also the possibility to use iterators and functors; I am no expert there but if you can express the independence of operations on different elements by being more abstract you may give the compiler the chance to generate code that is more suitable for vectorization.
B. You should replace the division by a logical AND, operator&&. The first advantage is that the second condition is not evaluated at all if the first one is false -- this could be your most important performance gain here. The second advantage is expressiveness and thus readability.
C. The intermediate variable d0 will probably disappear when you compile with -O3, but it's unnecessary nonetheless.
The rest is ok performancewise. Idiomatically there is room for improvement as has been shown already.
D. I am not sure about a chance for vectorization with the code as presented here. The compiler will probably do some loop unrolling at -O3; try to let it emit SSE code (cf. http://gcc.gnu.org/onlinedocs/, specifically http://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/i386-and-x86-64-Options.html#i386-and-x86-64-Options). Who knows.
Oh, I just realized that your original code passes the constant interval boundaries as an array with 2 elements, ox[]. Since array access is an unnecessary indirection and as such may carry an overhead, using two normal float parameters would be preferred here. Keep them const like your array. You could also name them nicely.

Understanding a C++ Shell sort [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Hi I am trying to learn the shell sort .I understand the basic principles of splitting into segments and using the insertion method to sort.
However I only understand this example of code I found up to a point. If anyone could give me a clear explanation of what each of the for loops do etc. would be great.
int const size = 5;
int i, j, increment, temp;
int array[size]={4,5,2,3,6},i1=0;
//split the array into segments unil we reach beginning of array
for(increment = size/2;increment > 0; increment /= 2)
{
for(i = increment; i<size; i++)
{
temp = array[i];
for(j = i; j >= increment ;j-=increment)
{
//perform the insertion sort for this section
if(temp < array[j-increment])
{
array[j] = array[j-increment];
}
else
{
break;
}
}
array[j] = temp;
}
}
for(increment = size/2;increment > 0; increment /= 2)
This for loop initializes the gap between the elements in the array you are comparing against. So increment is set to 2 initially.
for(i = increment; i<size; i++)
{
temp = array[i];
This says, start at element 3 and go forwards until you reach element 5, we will see why soon.
for(j = i; j >= increment ;j-=increment)
{
//perform the insertion sort for this section
if(temp < array[j-increment])
{
array[j] = array[j-increment];
}
else
{
break;
}
}
array[j] = temp;
Says ok, we are starting at the element specified above (in this case, the 2nd index), and we are going to compare it against the element that is the "gap" length behind it. So it would take the 3rd element, and compare it against the 1st element. If the 3rd element is smaller than the 1st element, swap them, otherwise break out of the loop. We then decrement our index by the size of the gap (from 2 to 0) and keep going if our new index is at least as large as the size of the gap (so we don't have array out of bounds issues).
Now we go back to the middle for loop and increment the element position we start at; so we compare the
4th element against the 2nd element. Stop
5th element against the 3rd, then 3rd against the 1st. Stop
Once we have compared all elements within their "gap" length, we go back and change the gap length to half of what it was before, rinse and repeat, until it reaches 0.
Typically, you don't want to just divide the gap in half - there are pre-defined functions for gap length recommendation (usually primes). See wikipedia for more info.

How to check if two n-sized vectors are linearly dependant on C++? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
A program should be made which finds if the two vectors a = (a0, a1, ..., an-1) and b = (b0, b1, ..., bn-1) (1 ≤ n ≤ 20) are linearly dependant. The input should be n, and the coordinates of the two vectors and the output should be 1 if the vectors are linearly dependant, else - 0.
I've been struggling for hours over this now and I've got absolutely nothing. I know only basic C++ stuff and my geometry sucks way too much. I'd be really thankful if someone would write me a solution or at least give me some hint. Thanks in advance !
#include <iostream>
using namespace std;
int main()
{
int n;
double a[20], b[20];
cin >> n;
int counter = n;
bool flag = false;
for (int i = 0; i < n; i++)
{
cin >> a[i];
cin >> b[i];
}
double k;
for (int i = 0; i < n; i++)
{
for (k = 0; k < 1000; k = k + 0.01)
{
if (a[i] == b[i])
{
counter--;
}
}
}
if (counter == 0 && k != 0)
flag = true;
cout << flag;
return 0;
}
Apparently that was all I could possibly come up with. The "for" cycle is wrong on so many levels but I don't know how to fix it. I'm open to suggestions.
There are 4 parts to the problem:
1. Math and algorithms
Vectors a and b are linearly depndent if ∃k. a = k b. That is expanded to ∃k. ∑i=1..n ai = k ai and that is a set of equations any of which can be solved for k.
So you calculate k as b0 / a0 and check that the same k works for the other dimensions.
Don't forget to handle a0 = 0 (or small, see below). I'd probably swap the vectors so the larger absolute value is denominator.
2. Limited precision numeric calculations
Since the precision is limited, calculations involve rounding error. You need to check for approximate equality, not exact, because most likely you won't get exact results even when you expect them.
Approximate equality comes in two forms, absolute (|x - y| < ε) and relative (1 - ε < |x / y| < 1 + ε). Obviously the relative makes more sense here (you want to ignore the last significant digit only), but again you have to handle the case where the values are too small.
3. C++
Don't use plain arrays, use std::vector. That way you won't have arbitrary limits.
Iterate with iterator, not indices. Iterators work for all container types, indices only work for the few with continuous integral indices and random access. Which is basically just vector and plain array. And note that iterators are designed so that pointer is iterator, so you can iterate with iterator over plain arrays too.
4. Plain old bugs
You have the loop over k, but you don't use the value inside the loop.
The logic with counter does not seem to make any sense. I don't even see what you wanted to achieve with that.
You're right, that code bears no reationship to the problem at all.
It's easier than you think (at least conceptually). Divide each element in the vector by the corressponding element in the other vector. If all those division result in the same number then the vectors are linearly dependendent. So { 1, 2, 4 } and { 3, 6, 12 } are linear because 1/3 == 2/6 == 4/12.
However there are two technical problems. First you have to consider what happens when your elements are zero, you don't want to divide by zero.
Secondly because you are dealing with floating point numbers it's not sufficient to test if two numbers are equal. Because of rounding errors they often won't be. So you have to come up with some test to see if two numbers are nearly equal.
I'll leave you to think about both those problems.

C++ sieve of Eratosthenes with array [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I'd like to code the famous Sieve of Eratosthenes in C++ using just array as it would be a set where I can delete some elements on the way to find out primes numbers.
I don't want to use STL (vector, set)... Just array! How can I realize it?
I try to explain why I don't want to use STL set operator: I'm learning C++ from the very beginning and I think STL is of course useful for programmers but built on standard library, so I'd like to use former operators and commands. I know that everything could be easier with STL.
The key to the sieve of Eratosthenes's efficiency is that it does not, repeat not, delete ⁄ remove ⁄ throw away ⁄ etc. the composites as it enumerates them, but instead just marks them as such.
Keeping all the numbers preserves our ability to use a number's value as its address in this array and thus directly address it: array[n]. This is what makes the sieve's enumeration and marking off of each prime's multiples efficient, when implemented on modern random-access memory computers (just as with the integer sorting algorithms).
To make that array simulate a set, we give each entry two possible values, flags: on and off, prime or composite, 1 or 0. Yes, we actually only need one bit, not byte, to represent each number in the sieve array, provided we do not remove any of them while working on it.
And btw, vector<bool> is automatically packed, representing bools by bits. Very convenient.
From Algorithms and Data Structures
#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
void runEratosthenesSieve(int upperBound) {
int upperBoundSquareRoot = (int)sqrt((double)upperBound);
bool *isComposite = new bool[upperBound + 1];
memset(isComposite, 0, sizeof(bool) * (upperBound + 1));
for (int m = 2; m <= upperBoundSquareRoot; m++) {
if (!isComposite[m]) {
cout << m << " ";
for (int k = m * m; k <= upperBound; k += m)
isComposite[k] = true;
}
}
for (int m = upperBoundSquareRoot; m <= upperBound; m++)
if (!isComposite[m])
cout << m << " ";
delete [] isComposite;
}
int main()
{
runEratosthenesSieve(1000);
}
You don't want to use STL, but that's not a good idea
STL makes life much simpler.
Still consider this implementation using std::map
int max = 100;
S sieve;
for(int it=2;it < max;++it)
sieve.insert(it);
for(S::iterator it = sieve.begin();it != sieve.end();++it)
{
int prime = *it;
S::iterator x = it;
++x;
while(x != sieve.end())
if (((*x) % prime) == 0)
sieve.erase(x++);
else
++x;
}
for(S::iterator it = sieve.begin();it != sieve.end();++it)
std::cout<<*it<<std::endl;