Necessary Resources
Letter Image Files
EasyBMP Resources
To Compile, Use These Commands:
g++ -o -g NeuralNet.cpp
g++ -o neuralnet EasyBMP.o NeuralNet.o
neuralnet
With Large L, Segmentation Faults Can Be Avoided Using:
limit stacksize unlimited
002 | #include <stdlib.h> // |
003 | #include <ctime> // needed for compatible sleep function |
004 | #include <sstream> // needed for incorporation of variables into file names |
005 | #include "EasyBMP.h" // needed for BMP input/output |
006 | #include <iostream> // |
009 | #include <math.h> // needed for floor() |
017 | ofstream hammergy( "hammergy.dat" , ios::app); |
018 | ofstream flips( "flips.dat" ); |
023 | int const MC_Steps = 1000; |
024 | float const RN_seed = 0.4f; |
027 | bool restrictJbool = false ; |
029 | char * initname = "A_40" ; |
031 | float J_lifetime = 0.0; |
034 | char image_directory[] = "Letter Images/" ; |
035 | char output_directory[] = "Run Output/" ; |
038 | void MonteCarloStep( int [L][L], float [L][L][L][L], float T, int [L][L]); |
039 | float CalculateEnergy( int [L][L], float [L][L][L][L]); |
040 | float CalculateEnergyChange_SN ( int [L][L], float [L][L][L][L], int , int ); |
041 | void InitializeSpins( int [L][L]); |
042 | void InitializeSpins( int [L][L], char []); |
043 | void InitializeJ( int , float [L][L][L][L]); |
044 | void TeachJ( float [L][L][L][L], float , int *); |
045 | void TeachJ( float [L][L][L][L], float , char []); |
046 | void InputImage( char *, int [L][L]); |
047 | void PrintSpins( int [L][L]); |
048 | void PrintSpins_Linux( int [L][L]); |
049 | int * loadImage( char []); |
050 | void outputBMP( int [L][L], char []); |
051 | void restrictJ( float [L][L][L][L]); |
052 | void brainDamageRec( int , int , int , int , float [L][L][L][L], int [L][L]); |
053 | void brainDamageRan( float , float [L][L][L][L]); |
054 | void createOrthogonal( int , float [L][L][L][L]); |
055 | void flipS( float spindmg, int S[L][L]); |
056 | float Hamming( int [L][L], int [L][L]); |
062 | srand (( int )(RAND_MAX * RN_seed)); |
068 | int refS[L][L] = {0}; |
070 | float J[L][L][L][L] = {0.0}; |
073 | InitializeSpins(refS, "black" ); |
074 | InitializeSpins(S, initname); |
079 | TeachJ(J, 1.0f, "A" ); |
080 | TeachJ(J, 1.0f, "B" ); |
081 | TeachJ(J, 1.0f, "C" ); |
082 | TeachJ(J, 1.0f, "D" ); |
083 | TeachJ(J, 1.0f, "E" ); |
084 | TeachJ(J, 1.0f, "F" ); |
090 | createOrthogonal(teachOrtho,J); |
099 | brainDamageRan(bdamage,J); |
106 | for (Step = 0; Step < MC_Steps; Step++) { |
108 | T = (Tstart/MC_Steps)*(MC_Steps - Step); |
109 | MonteCarloStep(S, J, T, refS); |
110 | outputBMP(S, "Trial1" ); |
119 | void MonteCarloStep( int S[L][L], float J[L][L][L][L], float T, int refS[L][L]) { |
124 | for ( int i = 0; i < L*L; i++) { |
126 | x = ( int )(L * ( rand () / (RAND_MAX + 1.0))); |
127 | y = ( int )(L * ( rand () / (RAND_MAX + 1.0))); |
130 | dE = CalculateEnergyChange_SN(S, J, x, y); |
136 | if ( exp (-dE/T) > ( rand () / (RAND_MAX + 1.0))) { |
143 | hammergy << Hamming(S, refS) << ' ' << CalculateEnergy(S, J) << endl; |
144 | flips << counter << "\n" << endl; |
152 | float CalculateEnergy( int S[L][L], float J[L][L][L][L]) { |
156 | for (i = 0; i < L*L; i++) { |
157 | for (j = i + 1; j < L*L; j++) { |
158 | if (!(i%L == j%L && ( int ) floor (1.0*i/L) == ( int ) floor (1.0*j/L))) { |
159 | E -= J[i%L][( int ) floor (1.0*i/L)][j%L][( int ) floor (1.0*j/L)] * S[i%L][( int ) floor (1.0*i/L)] * S[j%L][( int ) floor (1.0*j/L)]; |
173 | float CalculateEnergyChange_SN ( int S[L][L], float J[L][L][L][L], int x, int y) { |
177 | for (j = 0; j < L*L; j++) { |
178 | if (!(x == j%L && y == ( int ) floor (1.0*j/L))) { |
179 | dE -= ( float )J[x][y][j%L][( int ) floor (1.0*j/L)] * ( float )-S[x][y] * ( float )S[j%L][( int ) floor (1.0*j/L)]; |
188 | void InitializeSpins( int S[L][L]) { |
189 | for ( int x = 0; x < L; x++) { |
190 | for ( int y = 0; y < L; y++) { |
191 | S[x][y] = ( int ) floor ( rand () / (RAND_MAX + 1.0) + 0.5); |
192 | if (S[x][y] == 0) S[x][y] = -1; |
200 | void InitializeSpins( int S[L][L], char name[]) { |
201 | std::string filename; |
202 | std::stringstream filename_out; |
204 | filename_out << image_directory << name << ".bmp" ; |
205 | filename = filename_out.str(); |
207 | int * image = loadImage(( char *)filename.c_str()); |
209 | for ( int i = 0; i < L*L; i++) { |
210 | S[i%L][( int ) floor (1.0*i/L)] = image[i]; |
219 | void InitializeJ( int selection, float J[L][L][L][L]) { |
228 | for (ix = 0; ix < L; ix++) { |
229 | for (iy = 0; iy < L; iy++) { |
230 | for (jx = 0; jx < L; jx++) { |
231 | for (jy = 0; jy < L; jy++) { |
232 | J[ix][iy][jx][jy] = ( float )( rand () / (RAND_MAX + 1.0) * 10.0 - 5.0); |
245 | void TeachJ( float J[L][L][L][L], float exposure_time, int * image) { |
246 | for ( int ix = 0; ix < L; ix++) { |
247 | for ( int iy = 0; iy < L; iy++) { |
248 | for ( int jx = 0; jx < L; jx++) { |
249 | for ( int jy = 0; jy < L; jy++) { |
250 | J[ix][iy][jx][jy] = J_lifetime / (J_lifetime + exposure_time) * J[ix][iy][jx][jy] + |
251 | exposure_time / (J_lifetime + exposure_time) * image[ix + iy * L] * image[jx + jy * L]; |
257 | J_lifetime += exposure_time; |
264 | void TeachJ( float J[L][L][L][L], float exposure_time, char name[]) { |
265 | std::string filename; |
266 | std::stringstream filename_out; |
268 | filename_out << image_directory << name << "_" << L << ".bmp" ; |
269 | filename = filename_out.str(); |
271 | int * image = loadImage(( char *)filename.c_str()); |
273 | for ( int ix = 0; ix < L; ix++) { |
274 | for ( int iy = 0; iy < L; iy++) { |
275 | for ( int jx = 0; jx < L; jx++) { |
276 | for ( int jy = 0; jy < L; jy++) { |
277 | J[ix][iy][jx][jy] = (J_lifetime / (J_lifetime + exposure_time)) * J[ix][iy][jx][jy] + |
278 | (exposure_time / (J_lifetime + exposure_time)) * image[ix + iy * L] * image[jx + jy * L]; |
284 | J_lifetime += exposure_time; |
289 | void PrintSpins( int S[L][L]) { |
291 | for ( int x = 0; x < L; x++) { |
292 | for ( int y = 0; y < L; y++) { |
304 | void PrintSpins_Linux( int S[L][L]) { |
306 | for ( int x = 0; x < L; x++) { |
307 | for ( int y = 0; y < L; y++) { |
320 | int * loadImage( char filename[]) { |
322 | image.ReadFromFile(filename); |
324 | int * S_image = new int [L*L]; |
326 | for ( int i = 0; i < L*L; i++) { |
327 | if (image(( int ) floor (1.0*i/L),i%L)->Red + image(( int ) floor (1.0*i/L),i%L)->Blue + image(( int ) floor (1.0*i/L),i%L)->Green < 382) |
340 | void outputBMP( int S[L][L], char name[]) { |
341 | std::string filename; |
342 | std::stringstream filename_out; |
344 | filename_out << output_directory << "TEMP" << "_" << Step << ".bmp" ; |
345 | filename = filename_out.str(); |
346 | current_BMP.SetSize(L,L); |
348 | for ( int x = 0; x < L; x++) { |
349 | for ( int y = 0; y < L; y++) { |
351 | current_BMP(y,x)->Red = 255; |
352 | current_BMP(y,x)->Green = 255; |
353 | current_BMP(y,x)->Blue = 255; |
355 | current_BMP(y,x)->Red = 0; |
356 | current_BMP(y,x)->Green = 0; |
357 | current_BMP(y,x)->Blue = 0; |
362 | current_BMP.WriteToFile(( char *)filename.c_str()); |
366 | void restrictJ( float J[L][L][L][L]){ |
367 | for ( int ix = 0; ix < L; ix++) { |
368 | for ( int iy = 0; iy < L; iy++) { |
369 | for ( int jx = 0; jx < L; jx++) { |
370 | for ( int jy = 0; jy < L; jy++) { |
371 | if (J[ix][iy][jx][jy]>=0) |
374 | J[ix][iy][jx][jy]=-1; |
382 | void brainDamageRec( int sx, int sy, int dx, int dy, float J[L][L][L][L], int S[L][L]){ |
383 | for ( int x = sx; x < sx+dx; x++) { |
384 | for ( int y = sy; y < sy+dy; y++) { |
386 | for ( int ix = 0; ix < L; ix++) { |
387 | for ( int iy = 0; iy < L; iy++) { |
397 | void brainDamageRan( float rate, float J[L][L][L][L]){ |
399 | for ( int ix = 0; ix < L; ix++) { |
400 | for ( int iy = 0; iy < L; iy++) { |
401 | for ( int jx = 0; jx < L; jx++) { |
402 | for ( int jy = 0; jy < L; jy++) { |
403 | if (( rand () / (RAND_MAX + 1.0))<rate) |
413 | void createOrthogonal( int n, float J[L][L][L][L]){ |
416 | for ( int i=0; i<n; i++){ |
417 | for ( int x = 0; x < L*L; x++) { |
418 | if (( rand () / (RAND_MAX + 1.0)) < 0.5) |
429 | void flipS( float spindmg, int S[L][L]) { |
431 | for ( int x = 0; x < L; x++) { |
432 | for ( int y = 0; y < L; y++) { |
433 | if (( rand () / (RAND_MAX + 1.0))<spindmg) |
434 | S[x][y] = int ((( rand () % 2)-0.5)*2); |
441 | float Hamming( int S[L][L], int refS[L][L]) { |
442 | float hamming = 0.0f; |
444 | for ( int x = 0; x < L; x++) { |
445 | for ( int y = 0; y < L; y++) { |
446 | hamming += (1.0 / L*L) * pow (refS[x][y] - S[x][y], 2.0); |
|