Possibly misunderstanding exit(0) statement.

I have written my code to run a simulation of evenly distributing n points on a sphere. I have put a failsafe in place to end the code if there are any issues. My code is as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
#include <stdio.h> 
#include <string.h>
#include <math.h>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <time.h>
#include <stdlib.h>

using namespace std;

int main()
{

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

  clock_t t1,t2;
  t1=clock();

  /*  Set the number of points */
  n=25;

  /* 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;
  }

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

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

  while(Forcemagnitude>0.00001){

    /* 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 */
    E[a]=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));
        E[a]=E[a]+1.0/Distance;
      }
    }

    energy=E[a];

    cout << fixed << setprecision (10) << "Energy=" << Energy << "\n";
    cout << fixed << setprecision (10) << "energy=" << energy << "\n";

    /* Choose best energy and therefore best points */
    if (energy<Energy)
      Energy=energy,s=s+1;
    else
      energy=Energy,f=f+1;
  
    if(f=1){
      cout << fixed << setprecision (10) << "E=" << energy << "\n";
      cout << "Successes=" << s << " Failures=" << f <<"\n";
      cout << "Terminated \n";
      exit(0);
    }  
  
    cout << "Successes=" << s << " Failures=" << f <<"\n";
  
    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];

    cout << "Forcemagnitude=" << fixed << setprecision(10) << Forcemagnitude << "\n";

    a=a+1;
    
  }

  /* Output new energy */
  cout << "Successes=" << s << " Failures=" << f <<"\n";
  cout << fixed << setprecision (10) << "Energy=" << Energy << "\n";
  cout << "Iterations=" << a-1 << "\n";

  ofstream mypoints ("mypoints");
  for(i=1;i<=n;i++){
    mypoints << x[i][1] << " " <<   x[i][2] << " " << x[i][3] << "\n";
  }
  mypoints.close(); 

  t2=clock();
    float diff ((float)t2-(float)t1);
    float seconds = diff / CLOCKS_PER_SEC;
    cout << setprecision(2) << "Run time: " << seconds << "(s)" << "\n";
    return 0;

}


My failsafe is at line 213 and I want it to basically exit the code if energy I am calculating stops decreasing. It does this without fail, but my issue is that my outputs are confusing me.

A standard output gives me something like:

Energy=269.7821451992
energy=266.7549548756
E=266.7549548756
Successes=1 Failures=1
Terminated

As you can see, the Energy is higher than the energy and so this is a success, hence 1 success. However where has the failure come from?

The code states (I think) that on lines 204/205 I should get an output of my Energy and energy and then increment f if there is a failure. Since I only have one set of Energy and energy outputs, surely my successes and failures should add up to one. The clearly add to two and so therefore the while loop has run twice. Why is it only giving my one set of outputs?

Thanks for any assistance you can offer een if it is just links or extra reading. The only reason I can think of is either I have misunderstood exit(0) and so the code is exiting before I think it is, or I have misunderstood the order in which my code is being read and therefore expect more outputs than there should be.

Note: My code does get it right sometimes, but only if there is a fail on the first go. Then I get this output:

Energy=275.8325665982
energy=313.1149926643
E=275.8325665982
Successes=0 Failures=1
Terminated

(Obviously the Energy and energy values differ every time you run the code, but that is an example).

Thanks,

A.
My failsafe is at line 213


You might want to use the comparison operator (==) as opposed to the assignment operator in that if condition.
Excellent, such a stupid mistake. Thanks for that!
Topic archived. No new replies allowed.