Thread: Suggestions please.

  1. #1
    Not bad at Crack Attack!
    Join Date
    Aug 2003
    Posts
    45

    Suggestions please.

    OK. Thanks to the help of posters on this board I have managed to get to the following stage with my code. Now I appreciate that asking people you don't know to scan your code for errors is probably almost as rude as expecting them to write it for you. I am using a Pentium 4, 2.4Ghz laptop, Microsoft Visual Studio on Win XP and all the nightmares that entails. The code seems to work but when I take the size value up high I get realloc failures...

    OK the first function writes a header file of global variables:

    Code:
    headwrite.cpp
    
    #include "stdafx.h"
    #include<stdio.h>
    #include<stdlib.h>
    
    #define OUTPUT "C:\\matt\\nodes.h"
    
    /* This program writes a header file that generates the N^2 nodes used in*
     * the following program to use. It includes preprocessor shortcuts for  *
     * the names of the neighbour arrays.                                    */
    
    void write_header_file(char[], int, int);
    
    int main(int argc, char* argv[])
    {
    	char getside[20];
    	int side, size;
    	
    	printf("Please input the side of the lattice:\n(ie \"5\" for a 25 node lattice)\n");
    	fgets(getside, 20, stdin);
    	side=atoi(getside);
    	size=side*side;
    
    	write_header_file(OUTPUT, side, size);
    	return 0;
    }
    
    void write_header_file(char filename[], int side, int size)
    {
    	FILE *fptr;
    	int i;
    	fptr = fopen(filename, "w");
    	if(fptr == NULL){
    		fprintf(stderr, "Unable to open \"%s\" to write!\n", filename);
    		return;
    	}
    	fprintf(fptr, "/*Header file with node information*/\n\n");
    	fprintf(fptr, "/*General global quantities*/\n");
    	fprintf(fptr, "int side=%d;\nint size=%d;\n\n",side,size);
    	fprintf(fptr, "/*List of neighbour arrays*/\n");
    	for(i=0; i<size; i++)
    		fprintf(fptr, "int N%d[4];\n", i);
    	fprintf(fptr, "\n/*An array of neighbour arrays*/\n");
    	fprintf(fptr, "int *nbrs[]={N0,");
    	for(i=1; i<size-1; i++)
    		fprintf(fptr, " N%d,",i);
    	fprintf(fptr, " N%d};\n\n",size-1);
    	fprintf(fptr, "/*An array of flags, all initialised to zero*/\n");
    	fprintf(fptr, "int flags[]={0,");
    	for(i=1; i<size-1; i++)
    		fprintf(fptr, "0,");
    	fprintf(fptr, "0};\n\n");
    	fprintf(fptr, "/*A node degree array, where the ith element is the number *\n
     *of links emanating from the ith node, initialised to that*\n
     *of a regular square lattice*/\n\n");
    	fprintf(fptr, "int degree[]={4,");
    	for(i=1; i<size-1; i++)
    		fprintf(fptr, "4,");
    	fprintf(fptr, "4};\n");
    	return;
    }
    And here is an example of nodes.h for side=15. (Altho I have trimmed it to save a little space)
    Code:
    nodes.h
    /*Header file with node information*/
    
    /*General global quantities*/
    int side=15;
    int size=225;
    
    /*List of neighbour arrays*/
    int N0[4];
    int N1[4];
    int N2[4];
    int N3[4];
    int N4[4];
    int N5[4];
    int N6[4];
    int N7[4];
    int N8[4];
    int N9[4];
    int N10[4];
    
    ... etc ...
    
    int N215[4];
    int N216[4];
    int N217[4];
    int N218[4];
    int N219[4];
    int N220[4];
    int N221[4];
    int N222[4];
    int N223[4];
    int N224[4];
    
    /*An array of neighbour arrays*/
    int *nbrs[]={N0, N1, N2, N3, N4, N5, N6, N7, N8, N9, N10, ... ,
     N215, N216, N217, N218, N219, N220, N221, N222, N223, N224};
    
    /*An array of flags, all initialised to zero*/
    int flags[]={0,0,0, ..., 0,0,0};
    
    /*A node degree array, where the ith element is the number *
     *of links emanating from the ith node, initialised to that*
     *of a regular square lattice                              */
    
    int degree[]={4,4,4,...,4,4,4};
    And then the main program:
    Code:
    carla.cpp
    
    /************************************ 
     *              CARLA               *
     * C Adaptation: Random Links Added *
     *                                  *
     *    by Matt 13, August 2003    *
     ************************************/
    
    #include "stdafx.h"
    #include<stdio.h>
    #include<stdlib.h>
    #include<math.h>
    #include<time.h>
    #include<gsl/gsl_rng.h>
    #include"C:\matt\nodes.h"
    
    void create_lattice(int);
    void add_random_link(int);
    void initialise_flags(int);
    void save_flags(int[]);
    void restore_flags(int[]);
    void setup_infectives(int[], int);
    int get_flag_type(int);
    void do_algorithm(int[], int[], int, double);
    void update_flags(int[]);
    void dump_stats(int, int, int, int, int, int, char[]);
    
    gsl_rng * seed = gsl_rng_alloc (gsl_rng_ranlux389);
    
    #define OUTPUT "C:\\matlab6p1\\work\\carla.m"
    
    int main(int argc, char* argv[])
    {
    	/*DECLARATIONS - PRE SHELL INTERACTION*/
    	int iterate, enditerate, t, endtime;
    	int i;
    	int init_infec, infec;
    	int no_of_s, no_of_i, no_of_r;
    	double p, alpha;
    	int *infectives;
    	int *temp;
    	int *restore;
    
    	char getits[20];
    	char gettime[20];
    	char getp[20];
    	char getalpha[20];
    	char getinfec[20];
    
    	srand(time(NULL));
    	
    	/*SHELL INTERACTION*/
    	printf("There are %d nodes.\n", size);
    	printf("To change this, please run the headerwrite program.\n");
    	printf("Please enter the number of iterates required:\n");
    	fgets(getits, 20, stdin);
    	enditerate=atoi(getits);
    	printf("Please enter the number of time steps required:\n");
    	fgets(gettime, 20, stdin);
    	endtime=atoi(gettime);
    	printf("Please enter the probability p that a rewired link exists:\n");
    	printf("NB: Entering p=0 will give the original lattice.\n");
    	fgets(getp, 20, stdin);
    	p=atof(getp);
    	while(p<0 || p>1){
    		printf("Probability must be between 0 and 1!\n");
    		printf("Please enter the probability (p) that a rewired link exists:\n");
    		fgets(getp, 20, stdin);
    		p=atof(getp);
    	}
    	printf("Please enter the probability (alpha) that an infective becomes\n");
    	printf("a stifler upon contact with another infective or stifler:\n");
    	fgets(getalpha, 20, stdin);
    	alpha=atof(getalpha);
    	while(alpha<0 || alpha>1){
    		printf("Probability must be between 0 and 1!\n");
    		printf("Please enter the probability alpha:\n");
    		fgets(getalpha, 20, stdin);
    		alpha=atof(getalpha);
    	}
    	printf("Please enter a non-zero number of initially infected nodes:\n");
    	fgets(getinfec, 20, stdin);
    	init_infec=atoi(getinfec);
    	while(init_infec>size){
    		printf("Number of initial infectives cannot exceed the total number of nodes!\n");
    		printf("Please enter the number of initially infected nodes:\n");
    		fgets(getinfec, 20, stdin);
    		init_infec=atoi(getinfec);
    	}
    	
    	/*DECLARATIONS - POST SHELL INTERACTION*/
    	infectives=(int*)calloc(init_infec, sizeof(int));
    	temp=(int*)calloc(size, sizeof(int));
    	restore=(int*)calloc(size, sizeof(int));
    
    	/*MAIN PROGRAM CENTRE*/
    	create_lattice(size);
    	for(i=0;i<size;i++){
    		if(gsl_rng_uniform(seed)<p){
    				add_random_link(i);
    		}
    	}
    	initialise_flags(init_infec);
    	temp=flags;
    	save_flags(restore);
    	for(iterate=0; iterate<enditerate; iterate++){
    		for(t=0; t<endtime; t++){
    			if((t==0)&&(iterate!=0)){
    				restore_flags(restore);
    				temp=flags;
    			}
    			infec=get_flag_type(1);
    			infectives=(int*)calloc(infec, sizeof(int));
    			setup_infectives(infectives, infec);
    			do_algorithm(infectives, temp, infec, alpha);
    			update_flags(temp);
    			no_of_s=get_flag_type(0);
    			no_of_i=get_flag_type(1);
    			no_of_r=get_flag_type(2);
    			dump_stats(t, endtime-1, iterate, no_of_s, no_of_i, no_of_r, OUTPUT);
    			free(infectives);
    		}
    	}
    	free(temp);
    	free(restore);
    	return 0;
    }
    
    void create_lattice(int size)
    {
    	/*******************************************************
    	 * MODIFIES THE NEIGHBOUR ARRAYS CREATED IN THE HEADER *
    	 *FILE AND MAKES THEM CONSISTENT WITH A REGULAR LATTICE*
    	 *******************************************************/
    	int i;
    	for(i=0; i<size; i++){
    		if(i<=side-1)                       /*up*/
    			nbrs[i][0]=(side*side)-(side-i);
    		else
    			nbrs[i][0]=i-side;
    		if(i%side==side-1)                  /*right*/
    			nbrs[i][1]=i-(side-1);
    		else
    			nbrs[i][1]=i+1;
    		if(i>side*(side-1) && i<side*side)  /*down*/
    			nbrs[i][2]=i-(side*(side-1));
    		else
    			nbrs[i][2]=i+side;
    		if(i%side==0)                       /*left*/
    			nbrs[i][3]=i+side-1;
    		else
    			nbrs[i][3]=i-1;
    	}
    	printf("The regular lattice has been set up.\n");
    	return;
    }
    
    void add_random_link(int origin)
    {
    	/*(WITH PROBABILITY p) ADD A LINK TO A RANDOM NODE TO "ORIGIN"*/
    	int target=rand()%size;
    	while(target==origin)
    		target=rand()%size;
    	printf("Target is %d.\n", target);
    	int len=degree[origin];
    	int len2=degree[target];
    	int *tmp;
    	int *tmp2;
    	
    	tmp=(int*)realloc(nbrs[origin], sizeof(int)*(len+1));
    	if(tmp!=NULL){
    		nbrs[origin]=tmp;
    		nbrs[origin][len]=target;
    		degree[origin]++;
    		printf("The degree of node %d is now %d.\n", origin, degree[origin]);
    	}
    	else{
    		printf("Failure in realloc.\n");
    		return;
    	}
    	free(tmp);
    	tmp2=(int*)realloc(nbrs[target], sizeof(int)*(len2+1));
    	if(tmp2!=NULL){
    		nbrs[target]=tmp2;
    		nbrs[target][len2]=origin;
    		degree[target]++;
    		printf("The degree of node %d is now %d.\n", target, degree[target]);
    	}
    	else{
    		printf("Failure in realloc.\n");
    		return;
    	}
    	free(tmp2);
    	printf("There is a new link between %d and %d.\n",origin, target);
    	return;
    }
    
    void initialise_flags(int init_infec)
    {
    	/*SETS THE FLAGS OF init_infec NODES TO 1*/
    	int i=0;
    	int j;
    	while(i<init_infec){
    		j=rand()%size;
    		flags[j]=1;
    		i++;
    	}
    	printf("Flags have been initialised.\n");
    	return;
    }
    
    void save_flags(int restore[])
    {
    	/*SAVE FLAGS FOR RESTORE AT NEXT ITERATION*/
    	int i;
    	for(i=0; i<size; i++)
    		restore[i]=flags[i];
    	printf("Flags have been saved.\n");
    	return;
    }
    
    void restore_flags(int restore[])
    {
    	/*RESTORES FLAGS TO INITIAL VALUES*/
    	int j;
    	for(j=0; j<size; j++)
    		flags[j]=restore[j];
    	printf("Flags have been restored.\n");
    	return;
    }
    
    void setup_infectives(int infectives[], int check)
    {
    	/*SETS UP THE INFECTIVES ARRAY*/
    	int i=0;
    	int j=0;
    	while(i<size){
    		if(flags[i]==1){
    			if(j<check){
    				infectives[j]=i;
    				j++;
    			}
    		}
    		i++;
    	}
    	printf("Infectives array has been set up.\n");
    	return;
    }
    
    int get_flag_type(int flagtype)
    {
    	/*RETURNS NUMBER OF NODES WITH FLAG "flagtype"*/
    	int count=0;
    	int i;
    	for(i=0; i<size; i++){
    		if(flags[i]==flagtype){
    			count++;
    		}
    	}
    	return count;
    }
    
    void do_algorithm(int infectives[], int temp[], int infec, double alpha)
    {
    	/*PERFORMS ALGORITHM LOOPING OVER INFECTIVE NODES*/
    	int i,r;
    	for(i=0;i<infec;i++){
    		r=rand()%degree[infectives[i]];
    		if(flags[nbrs[infectives[i]][r]]==0)
    			temp[nbrs[infectives[i]][r]]=1;
    		else{
    			if(gsl_rng_uniform(seed)<alpha)
    				temp[infectives[i]]=2;
    		}
    	}
    	printf("Algorithm applied.\n");
    	return;
    }
    
    void update_flags(int temp[])
    {
    	/*UPDATES THE FLAGS ARRAY AFTER A TIME STEP*/
    	int i;
    	for(i=0;i<size;i++)
    		flags[i]=temp[i];
    	printf("Flags updated.\n");
    	return;
    }
    
    void dump_stats(int time, int endt, int it, int s, int i, int r, char filename[])
    {
    	/*WRITES DATA TO AN M-FILE FOR MATLAB PLOTS*/
    	FILE *fptr;
    	if(time==0&&it==0)
    		fptr=fopen(filename, "w");
    	else
    		fptr=fopen(filename, "a");
    	if(fptr==NULL){
    		fprintf(stderr, "Unable to open \"%s\" to append.\n", filename);
    		return;
    	}
    	if(time==0)
    		fprintf(fptr, "A%d=[%d, %d, %d;\n", it, s, i, r);
    	if(time==endt){
    		fprintf(fptr, "%d, %d, %d]\n", s, i, r);
    		printf("Iteration number: %d. Total number of nodes infected is: %d\n", it, i+r);
    	}
    	else
    		fprintf(fptr, "%d, %d, %d;\n", s, i, r);
    	fclose(fptr);
    	return;
    }
    I'm aware that I only listed one problem with the code above but there are a few more issues - some of them so basic I intend to sort them out myself. I apologise in advance for the size (particularly the width) of this post.
    Last edited by Matt13; 08-20-2003 at 05:25 AM.

  2. #2
    Not bad at Crack Attack!
    Join Date
    Aug 2003
    Posts
    45
    I don't mean to intimidate people with all this code. If anyone has MS V C++ they are welcome to run the two programs and tell me how they interpret the errors that arise...

    Or should I post some information on the errors that I am getting?

  3. #3
    Registered User Draco's Avatar
    Join Date
    Apr 2002
    Posts
    463
    yes, it would help us a great deal if you would post the exact error reports you get. That would give us a direction in which to start looking.

  4. #4
    Not bad at Crack Attack!
    Join Date
    Aug 2003
    Posts
    45
    Well, when I examine the output generated by the program - the "failure in realloc" message gets printed a lot more than I would like it to. (ie more than once!)

    Most of the errors seem to be ones that pop up in a standard windows error box and say stuff like access violation and provide an incomprehensible sequence of numbers and letters (memory addresses yes?)...

    Also FYI I am intending to run this entering "size" as 100, maybe this is too many arrays (10000) and too much memory is required at any one time - but then surely it would run slowly? Besides I have tried my hardest to free most of the arrays when I am finished with them.


  5. #5
    Not bad at Crack Attack!
    Join Date
    Aug 2003
    Posts
    45
    Why does it work some times then? From the gist of your answer it would seem that it shouldn't work at all?

  6. #6
    Not bad at Crack Attack!
    Join Date
    Aug 2003
    Posts
    45
    And of course, I will adapt the code in order to follow your advice.
    I suppose I only need to start with pointers in the header file and then malloc for the initial 4 at the start of the create_lattice function?

    (You can see why the temptation to start with arrays exits - because every array starts with four ints in it...)
    Last edited by Matt13; 08-20-2003 at 03:00 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Free Book Suggestions!
    By valaris in forum A Brief History of Cprogramming.com
    Replies: 4
    Last Post: 10-08-2008, 10:25 AM
  2. Hi, Suggestions on my program please..
    By Siggy in forum C++ Programming
    Replies: 44
    Last Post: 11-23-2004, 10:55 PM
  3. Math Book Suggestions
    By curlious in forum A Brief History of Cprogramming.com
    Replies: 4
    Last Post: 10-09-2003, 10:43 AM
  4. Need Suggestions
    By Drew in forum C++ Programming
    Replies: 3
    Last Post: 09-18-2003, 05:46 AM
  5. Learning C for OSX, tutorial suggestions please
    By Nexum in forum C Programming
    Replies: 2
    Last Post: 02-17-2003, 04:57 AM