Forums
New posts
Search forums
Members
Current visitors
Log in
Register
What's new
Search
Search
Search titles only
By:
New posts
Search forums
Menu
Log in
Register
Install the app
Install
Forums
Archive
Archive
C Programming
Request for source code review of simple Ising model
JavaScript is disabled. For a better experience, please enable JavaScript in your browser before proceeding.
Reply to thread
Message
[QUOTE="Udyant Wig, post: 5154940"] I thought it best to provide the latest source code for perusal. It incorporates most of the observations and commentary offered thus far. This should provide an updated point of reference. /* common.h begins */ #ifndef COMMON_H #define COMMON_H #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <math.h> #include <stdbool.h> #include <time.h> #include <ctype.h> #endif /* common.h ends */ /* utilities.h begins */ #ifndef UTILITIES_H #define UTILITIES_H #include "common.h" bool is_all_zeroes (char *string); bool is_positive_integer (char *string); int how_many (const char *s, int c); char *copy_substring (char *substring, const char *string, size_t start, size_t end); #endif /* utilities.h ends */ /* utilities.c begins */ #include "utilities.h" bool is_all_zeroes (char *string) { return string [strspn (string, "0")] == '\0'; } bool is_positive_integer (char *string) { char *sp; for (sp = string; *sp != '\0'; sp++) { if (!isdigit (*sp)) { return false; } } return !is_all_zeroes (string); } /* From /C: A Reference Manual/, 5th ed., by Harbison and Steele * page 352 */ int how_many (const char *s, int c) { int n = 0; if (c == 0) return 0; while (s) { s = strchr (s, c); if (s) n++, s++; } return n; } char *copy_substring (char *substring, const char *string, size_t start, size_t end) { size_t length = end - start + 1; errno = 0; substring = malloc (1 + length); if (substring == NULL) { fprintf (stderr, "copy_substring: %s\n", strerror (errno)); exit (1); } memset (substring, 0, 1 + length); strncpy (substring, string + start, length - 1); substring [length] = '\0'; return substring; } /* utilities.c ends */ /* bitsing.h begins */ #ifndef BITSING_H #define BITSING_H typedef unsigned char byte; /* Lattice */ byte *allocate_lattice (size_t size); void initialize_lattice (byte *lattice); void print_lattice (byte *lattice); /* Core */ int check_and_add_neighbor (byte *lattice, byte cell, int col, int row); void next_state (byte *lattice); void iterate (byte *lattice); /* Miscellaneous */ int count_ones (byte *lattice); void print_iteration (byte *lattice, const char *format_string, int count); /* Error checking */ void minority_error (void); void beta_error (void); void dimension_error (void); #endif /* bitsing.h ends */ /* bitsing.c begins */ #include "common.h" #include "bitsing.h" #include "utilities.h" #define ENERGY_MASK 0x1c static int dimension = 3; static double beta = 0.5; static int minority_size = 1; /* Lattice */ byte *allocate_lattice (size_t size) { byte *lattice; errno = 0; lattice = malloc (size); if (lattice == NULL) { fprintf (stderr, "allocate_lattice: %s\n", strerror (errno)); exit (1); } return lattice; } void initialize_lattice (byte *lattice) { byte *bp = lattice, *end = bp + dimension * dimension; while (bp < end) { *bp = ((byte) (rand () % 2)) << 1; bp++; } } void print_lattice (byte *lattice) { int row, col; for (col = 0; col < dimension; col++) { for (row = 0; row < dimension; row++) { printf ("%d", lattice [col * dimension + row] & 0x01); } putchar ('\n'); } } /* Core */ int check_and_add_neighbor (byte *lattice, byte cell, int col, int row) { byte neighbor; if (0 <= col && 0 <= row && col < dimension && row < dimension) { neighbor = lattice [col * dimension + row]; return ((cell & 0x02) ^ (neighbor & 0x02)); } return 0; } void next_state (byte *lattice) { byte *bp = lattice, *end = bp + dimension * dimension; while (bp < end) { *bp |= (0x01 & ((*bp & 0x02) >> 1)); bp++; } } void iterate (byte *lattice) { int rrow, rcol; byte rcell, ccell; int old_energy; int new_energy; int delta; rrow = rand () % dimension; rcol = rand () % dimension; rcell = lattice [rcol * dimension + rrow]; ccell = (rcell ^ 0x02) & 0x02; /* comlemented cell */ old_energy = (rcell & ENERGY_MASK) >> 2; new_energy = check_and_add_neighbor (lattice, ccell, rrow - 1, rcol); new_energy = check_and_add_neighbor (lattice, ccell, rrow + 1, rcol); new_energy = check_and_add_neighbor (lattice, ccell, rrow, rcol - 1); new_energy = check_and_add_neighbor (lattice, ccell, rrow, rcol + 1); delta = new_energy - old_energy; if (delta < 0) { lattice [rcol * dimension + rrow] = ccell; /* clear energy */ ccell &= ~ENERGY_MASK; /* set energy */ ccell |= (ENERGY_MASK & ((byte) new_energy << 2)); } else { double ising_window = exp (-(beta * delta)); double random_value = (double) (rand () % 100) / 100.0; if (random_value < ising_window) { lattice [rcol * dimension + rrow] = ccell; /* clear energy */ ccell &= ~ENERGY_MASK; /* set energy */ ccell |= (ENERGY_MASK & ((byte) new_energy << 2)); } } } /* Miscellaneous */ int count_ones (byte *lattice) { int count = 0; byte *bp = lattice, *end = bp + dimension * dimension; while (bp < end) { if ((*bp & 0x01) == (byte) 1) { count++; } bp++; } return count; } static const char initial_format [] = \ "Initial configuration %6d\n----------------------------\n"; static const char iteration_format [] = \ "Iteration %6d\n----------------\n"; static const char final_format [] = \ "Final configuration %6d\n--------------------------\n"; void print_iteration (byte *lattice, const char *format_string, int count) { putchar ('\n'); printf (format_string, count); print_lattice (lattice); } /* Error checking */ void minority_error (void) { fputs ("minority_size <argv [3]> is not a nonnegative integer\n", stderr); exit (2); } void beta_error (void) { fputs ("beta <argv [2]> is not positive floating-point number.\n", stderr); exit (2); } void dimension_error (void) { fputs ("dimension <argv [1]> is not a nonnegative integer.\n", stderr); exit (2); } /* Return codes: * 0 -- success * 1 -- memory allocation failure * 2 -- invalid command line argument */ int main (int argc, char *argv []) { if (argc > 3) { if (is_positive_integer (argv [3]) || is_all_zeroes (argv [3])) { minority_size = atoi (argv [3]); } else { minority_error (); } if (minority_size < 0) { minority_size = 0; } else if (minority_size > dimension * dimension) { minority_size = dimension * dimension; } else if (minority_size > (dimension * dimension) / 2) { minority_size = (dimension * dimension) - minority_size; } } if (argc > 2) { char *beta_string = argv [2]; size_t length = strlen (beta_string); if (how_many (beta_string, '.') == 1) { size_t position_decimal = strcspn (beta_string, "."); char *integral_part = NULL; char *fractional_part = NULL; if (position_decimal == 0) { beta_error (); } if (position_decimal == strlen (beta_string) - 1) { beta_error (); } integral_part = copy_substring (integral_part, \ beta_string, \ 0, \ position_decimal - 1); if (is_positive_integer (integral_part) || \ is_all_zeroes (integral_part)) { fractional_part = copy_substring (fractional_part, \ beta_string, \ position_decimal + 1, \ length - 1); if (is_positive_integer (fractional_part) || \ is_all_zeroes (fractional_part)) { beta = atof (argv [2]); } else { beta_error (); } free (fractional_part); } else { beta_error (); } free (integral_part); } else { beta_error (); } } if (argc > 1) { if (is_positive_integer (argv [1])) dimension = atoi (argv [1]); else { dimension_error (); } } srand (time (0)); byte *lattice; lattice = allocate_lattice (dimension * dimension * sizeof *lattice); initialize_lattice (lattice); next_state (lattice); print_iteration (lattice, initial_format, 0); long count = 1; while (true) { iterate (lattice); int ones_count = count_ones (lattice); if ((ones_count == minority_size) || \ ((dimension * dimension - ones_count) == minority_size)) { break; } print_iteration (lattice, iteration_format, count++); next_state (lattice); } print_iteration (lattice, final_format, count); free (lattice); exit (0); } /* bitsing.c ends */ [/QUOTE]
Verification
Post reply
Forums
Archive
Archive
C Programming
Request for source code review of simple Ising model
Top