adrem7 adrem7 - 2 months ago 12
C++ Question

Illegal Instruction 4 on Mac using C++

I am running this code on my mac (10.8.2) through terminal and for certain n it terminates with "Illegal Instruction 4" does anyone know why, or how to stop it?

I am confused as the code runs fine except for n=43, 45, 47 and 57.

Also after n=60 it seems to happen for all n. Might it be a memory issue as it works fine for lower values of n.

Note: anything to do with the integer c is purely to lessen the first while loop. Preferably I want the while loop to read b<251 to give me 250 iterations, but I am instead running something like b<51 for c=1,2,3,4,5 to get 5 different files with 50 results rather than 1 with 250.

The code is as follows:

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <time.h>
#include <stdlib.h>
#include <sstream>
using namespace std;

int main()
{

int a,b,c,f,i,j,k,m,n,s;
double p,Time,Averagetime,Energy,energy,Distance,Length,DotProdForce,Forcemagnitude,
ForceMagnitude[101],Force[101][4],E[10001],En[501],x[101][4],y[101][4];

clock_t t1,t2;
t1=clock();

b=1;
c=1;
Time=0.0;

while(b<251){

clock_t t3,t4;
t3=clock();

/* set the number of points */
n=45;

/* check that there are no more than 100 points */
if(n>100){
cout << n << " is too many points for me :-( \n";
exit(0);
}

/* reset the random number generator */
srand((unsigned)time(0));

for (i=1;i<=n;i++){
x[i][1]=((rand()*1.0)/(1.0*RAND_MAX)-0.5)*2.0;
x[i][2]=((rand()*1.0)/(1.0*RAND_MAX)-0.5)*2.0;
x[i][3]=((rand()*1.0)/(1.0*RAND_MAX)-0.5)*2.0;

Length=sqrt(pow(x[i][1],2)+pow(x[i][2],2)+pow(x[i][3],2));

for (k=1;k<=3;k++){
x[i][k]=x[i][k]/Length;
}
}

/* calculate the energy */
Energy=0.0;

for(i=1;i<=n;i++){
for(j=i+1;j<=n;j++){
Distance=sqrt(pow(x[i][1]-x[j][1],2)+pow(x[i][2]-x[j][2],2)
+pow(x[i][3]-x[j][3],2));

Energy=Energy+1.0/Distance;
}
}

/* Save Original Points */
for(i=1;i<=n;i++){
y[i][1]=x[i][1];
y[i][2]=x[i][2];
y[i][3]=x[i][3];
}

/* Loop for random points m times*/
m=10;

if (m>100){
cout << "The m="<< m << " loop is inefficient...lessen m \n";
exit(0);
}

a=1;

while(a<m){

/* assign random points */
for (i=1;i<=n;i++){
x[i][1]=((rand()*1.0)/(1.0*RAND_MAX)-0.5)*2.0;
x[i][2]=((rand()*1.0)/(1.0*RAND_MAX)-0.5)*2.0;
x[i][3]=((rand()*1.0)/(1.0*RAND_MAX)-0.5)*2.0;

Length=sqrt(pow(x[i][1],2)+pow(x[i][2],2)+pow(x[i][3],2));

for (k=1;k<=3;k++){
x[i][k]=x[i][k]/Length;
}
}

/* calculate the energy */
energy=0.0;

for(i=1;i<=n;i++){
for(j=i+1;j<=n;j++){
Distance=sqrt(pow(x[i][1]-x[j][1],2)+pow(x[i][2]-x[j][2],2)
+pow(x[i][3]-x[j][3],2));

energy=energy+1.0/Distance;
}
}

if(energy<Energy)
for(i=1;i<=n;i++){
for(j=1;j<=3;j++){
Energy=energy;
y[i][j]=x[i][j];
}
}
else
for(i=1;i<=n;i++){
for(j=1;j<=3;j++){
energy=Energy;
x[i][j]=y[i][j];
}
}

a=a+1;
}

/* Create string stream 1 */
ostringstream String1;
String1 << "Bestrandonpoints_" << n; //add number

/* Output these points */
ofstream File1 (String1.str().c_str());
File1 << "Energy=" << Energy << "\n";
for(i=1;i<=n;i++){
File1 << x[i][1] << " " << x[i][2] << " " << x[i][3] << "\n";
}
File1.close();

/* For energy file later */
E[0]=Energy;

/* Start doing gradient flow approach */
a=1;
s=0;
f=0;
Forcemagnitude=1.0;

if(n>80)
p=0.005;
else if(n>60)
p=0.01;
else if(n>40)
p=0.02;
else
p=0.05;

while(Forcemagnitude>0.00005){

/* Reset initial force and energy change */

for(i=1;i<=n;i++){
Force[i][1]=0.0;
Force[i][2]=0.0;
Force[i][3]=0.0;
}
/* Calculate force on each particle */

for(i=1;i<=n;i++){
for(j=1;j<i;j++){

Distance=sqrt(pow(x[i][1]-x[j][1],2)+pow(x[i][2]-x[j][2],2)
+pow(x[i][3]-x[j][3],2));
Force[i][1]=Force[i][1]+((x[i][1]-x[j][1])/(pow((Distance),3)));
Force[i][2]=Force[i][2]+((x[i][2]-x[j][2])/(pow((Distance),3)));
Force[i][3]=Force[i][3]+((x[i][3]-x[j][3])/(pow((Distance),3)));
}

for (j=i+1;j<=n;j++){

Distance=sqrt(pow(x[i][1]-x[j][1],2)+pow(x[i][2]-x[j][2],2)
+pow(x[i][3]-x[j][3],2));
Force[i][1]=Force[i][1]+((x[i][1]-x[j][1])/(pow((Distance),3)));
Force[i][2]=Force[i][2]+((x[i][2]-x[j][2])/(pow((Distance),3)));
Force[i][3]=Force[i][3]+((x[i][3]-x[j][3])/(pow((Distance),3)));
}
}

/* Add the force to my points */
for(i=1;i<=n;i++){

DotProdForce=Force[i][1]*x[i][1]+Force[i][2]*x[i][2]+Force[i][3]*x[i][3];

y[i][1]=x[i][1];
y[i][2]=x[i][2];
y[i][3]=x[i][3];

Force[i][1]=Force[i][1]-DotProdForce*y[i][1];
Force[i][2]=Force[i][2]-DotProdForce*y[i][2];
Force[i][3]=Force[i][3]-DotProdForce*y[i][3];

x[i][1] = y[i][1]+p*(Force[i][1]);
x[i][2] = y[i][2]+p*(Force[i][2]);
x[i][3] = y[i][3]+p*(Force[i][3]);

/* Bring it back onto sphere */

Length=sqrt(pow(x[i][1],2)+pow(x[i][2],2)+pow(x[i][3],2));

for (j=1;j<=3;j++){
x[i][j]=x[i][j]/Length;
}
}

/* Calculate the new energy */

energy=0.0;

for(i=1;i<=n;i++){
for(j=i+1;j<=n;j++){

Distance=sqrt(pow(x[i][1]-x[j][1],2)+pow(x[i][2]-x[j][2],2)
+pow(x[i][3]-x[j][3],2));
energy=energy+1.0/Distance;
}
}

E[a]=energy;

/* Choose best energy and therefore best points */
if (energy<Energy)
Energy=energy,s=s+1;
else
energy=Energy,f=f+1,p=(9.5*p)/10;

for(i=1;i<=n;i++){
ForceMagnitude[i]=pow((pow(Force[i][1],2)+pow(Force[i][2],2)
+pow(Force[i][3],2)),0.5);
}

for(i=1;i<=n-1;i++){
if(ForceMagnitude[i]<ForceMagnitude[i+1])
ForceMagnitude[i]=ForceMagnitude[i+1];
else
ForceMagnitude[i+1]=ForceMagnitude[i];
}

Forcemagnitude=ForceMagnitude[n];

a=a+1;
}

En[b]=Energy;

b=b+1;

t4=clock();
float diff ((float)t4-(float)t3);
float seconds = diff / CLOCKS_PER_SEC;

Time = Time + seconds;

}

Averagetime = Time/(b-1);

cout << fixed << setprecision (4) << "Average Time: " << Averagetime << "(s) \n";
cout << fixed << setprecision(10) << "Energy=" << Energy << "\n";

t2=clock();
float diff ((float)t2-(float)t1);
float seconds = diff / CLOCKS_PER_SEC;

/* Create string stream 2 */
ostringstream String2;
String2 << "GFPoints_" << n; //add number

/* Output these points */
ofstream File2 (String2.str().c_str());
for(i=1;i<=n;i++){
File2 << x[i][1] << " " << x[i][2] << " " << x[i][3] << "\n";
}
File2.close();

/* Create string stream 3 */
ostringstream String3;
String3 << "GFEnergies_" << n; //add number

/* Output these points */
ofstream File3 (String3.str().c_str());
for(i=1;i<a;i++){
File3 << fixed << setprecision (10) << E[i] << "\n";
}
File3.close();

/* Output to help with gnuin.txt */
ofstream File4 ("mypoints");
for(i=1;i<=n;i++){
File4 << x[i][1] << " " << x[i][2] << " " << x[i][3] << "\n";
}
File4.close();

/* Create string stream 4 */
ostringstream String4;
String4 << "GFInfo_" << n; //add number

/* Output these points */
ofstream File5 (String4.str().c_str());
File5 << "Iterations=" << a-1 << "\n";
File5 << "Successes=" << s << " Failures=" << f << "\n";
File5 << fixed << setprecision(20) << "Energy=" << Energy << "\n";
File5 << fixed << setprecision(5) << "Total run time: " << seconds << "(s) \n";
File5 << fixed << setprecision(5) << "Average run time: " << Averagetime << "(s) \n";
File5.close();

/* Create string stream 5 */
ostringstream String5;
String5 << "GF%Energies_" << n << "_" << c; //add number

/* Output these points */
ofstream File6 (String5.str().c_str());
for(i=1;i<b;i++){
File6 << fixed << setprecision(20) << En[i] << "\n";
}
File6.close();

cout << fixed << setprecision(5) << "Run time: " << seconds << "(s)" << "\n";
return 0;

}


Thanks for any light you spread on the subject, A.

Answer

The obvious problems are these lines:

E[a]=energy;
En[b]=Energy;

You increment a and b on each loop iteration, but do not check them against the fixed array bounds; so if the loops iterate too many times you will write outside the arrays.

Perhaps you want to replace these with dynamic arrays (std::vector<double>), or perhaps you want to abort if a or b grows too large.

Comments