/*
 Copyright (C) Andrew Wuensche
 
 This file is part of DDLab (Discrete Dynamics Lab) <www.ddlab.org>
 
 DDLab is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with DDLab.  If not, see <http://www.gnu.org/licenses/>.
 */


/************ significant calloc and free, but also done elsewhere ************/

#include "edecfunc.h"
/***************  list of functions  *************/
/*
void allocate_mem_buffers(void)
void free_mem_buffers(void)
void allocate_mem_rule0(char thisnhood)
void free_mem_rule0(void)
void allocate_mem_iso(char thisnhood)
void free_mem_iso(char thisnhood)
void allocate_mem_rule0_extra(char thisnhood)
void free_mem_rule0_extra(void)
void allocate_mem_rulemix(char thisnhoood)
void reallocate_mem_rulemix(char thisnhood,char increace)
void free_mem_rulemix(void)
void allocate_mem_tcode0(char thisnhood)
void allocate_mem_tcode0_extra(char thisnhood)
void free_mem_tcode0_extra(void)
void allocate_mem_tcodemix(char thisnhood)
void reallocate_mem_tcodemix(char thisnhood,char increace)
void free_mem_tcodemix(void)
void free_mem_tcode0(void)
void allocate_mem_diffrules(char thisnhood,signed int nodiffrules)
void free_mem_diffrules(signed int nodiffrules)
void allocate_mem_diffcodes(char thisnhood,signed int nodiffrules)
void free_mem_diffcodes(signed int nodiffrules)
void allocate_mem_all_0s_all_1s_rules(char thisnhood)
void free_mem_all_0s_all_1s_rules(void)
char allocate_mem_nhood_matrix(char thisnhood)
void free_mem_nhood_matrix(char thisnhood)
void allocate_mem_Z_parameter(void)
void free_mem_Z_parameter(void)
void allocate_code_mem(void)
void allocate_mem_CA_states(void)
void free_mem_CA_states(void)
void allocate_mem_wiring(void)
void reallocate_mem_wiring(char increace)
void free_mem_wiring(void)
*/
signed int no_textbufs=11;
/**************** allocate memory to buffers **********************/
void allocate_mem_buffers(void){
 signed int z;

  /*text buffers*/
  if ((textb=(char**)calloc(no_textbufs,sizeof(char*)))
				  ==NULL) outof_memory("textb");
  if ((textb[0]=(char *)calloc(1000,sizeof(char))) /*was 250*/
				  ==NULL) outof_memory("textb[0]");
  
  for (z=1;z<=2;z++){ /*textb[9] reserved for putimage()*/
     sprintf(textb[0],"textb[%d]",z);
     if ((textb[z]=(char *)calloc(1000,sizeof(char))) /*was 250*/
				   ==NULL) outof_memory(textb[0]);
  }
  /*textb[9] reserved for putimage()*/
  /*textb[10] reserved for measuring a string*/
  for (z=3;z<=no_textbufs-1;z++){ /*textb[9] reserved for putimage()*/
     sprintf(textb[0],"textb[%d]",z);
     if ((textb[z]=(char *)calloc(150,sizeof(char)))
				   ==NULL) outof_memory(textb[0]);
  }
# if __WATCOM__
     if ((boximage=(void**)calloc(kNumBoxImages,sizeof(void*)))
	 ==NULL) outof_memory("boximage");/* #define kNumBoxImages 30 in eglob_a.h, 21 used */
				   
     if ((boximage_prompt=(void**)calloc(kNumBoxPromptImages,sizeof(void*)))
	 ==NULL) outof_memory("boximage_prompt"); /*#define kNumBoxPromptImages 15 in eglob_a.h */
# endif
/* done in setup_images in g_setx.c
# if __UNIX__ 
     if ((boximage=calloc(kNumBoxImages,sizeof(Pixmap*)))==NULL)
     	outof_memory("boximage");
				   
     if ((boximage_prompt=calloc(kNumBoxPromptImages,sizeof(Pixmap*)))
                            ==NULL) outof_memory("boximage_prompt");
# endif
*/  
  if ((is=(char *)calloc(1024,sizeof(char)))
				   ==NULL) outof_memory("is");
  if ((bigbuf=(char *)calloc(1024,sizeof(char)))
				   ==NULL) outof_memory("bigbuf");
  /*filename*/
  if ((filename=(char *)calloc(13,sizeof(char)))
				   ==NULL) outof_memory("filename");
  /*filename for data ascii file*/
  if ((filename_data=(char *)calloc(13,sizeof(char)))
				   ==NULL) outof_memory("filename_data");
  /*filename for basin_postScript ascii file*/
  if ((filename_basin_PS=(char *)calloc(13,sizeof(char)))
				   ==NULL) outof_memory("filename_basin_PS");

  if ((path=(char *)calloc(81,sizeof(char)))
				   ==NULL) outof_memory("path");
  /*boorland <dir.h> MAXDIR+1=67, MAXPATH+1=81*/
  /*unix <sys/param.h> maxpathlen=? */


}

/**************** free memory to buffers **********************/
void free_mem_buffers(void){
 signed int z;
                
		for (z=0;z<=no_textbufs-1;z++) free(textb[z]);
		free(textb);
		/*/* done in free_images in g_setx.c
                  free(boximage);
		  free(boximage_prompt);*/
                free(bigbuf);
		free(is);
		free(filename);
		free(filename_data);
                free(filename_basin_PS);
		free(path);
}

/************** allocate memory at cell 0 ***************************/
void allocate_mem_rule0(char thisnhood){
 signed int tablemax,tablebytes;

   tablemax= (signed int)pow(value_range,(double)thisnhood)-1;
   tablebytes=(signed int)ceil(value_bits * (double)(tablemax+1)/8);
   /*one rule only*/
   if ((carule=(char**)calloc(1,sizeof(char*)))
				       ==NULL) outof_memory("carule");
   if ((carule[0]=(char *)calloc(tablebytes,sizeof(char)))
				       ==NULL) outof_memory("carule[0]");
   if ((carule_mut=(char**)calloc(1,sizeof(char*)))
				       ==NULL) outof_memory("carule");
   if ((carule_mut[0]=(char *)calloc(tablebytes,sizeof(char)))
				       ==NULL) outof_memory("carule[0]");
}

/**************** free memory rule 0  **********************/
void free_mem_rule0(void){
	free(carule[0]);
	free(carule);
        free(carule_mut[0]);
	free(carule_mut);
}

/****************** for isotropic groups Feb 2020 ***********************/
void allocate_mem_iso(char thisnhood){
  signed int tablemax,tablebytes,z,gsize_bytes;
  
    /*called in main*/
    tablemax= (signed int)pow(value_range,(double)thisnhood)-1;
    tablebytes=(signed int)ceil(value_bits * (double)(tablemax+1)/8);
    
    if ((iso_rule=(char *)calloc(tablebytes,sizeof(char)))
				       ==NULL) outof_memory("iso_rule");
   
    if ((group_list_iso=(signed int *)calloc(tablemax+1,sizeof(signed int)))
				       ==NULL) outof_memory("group_list_iso");
    
    /*list of all nhoods and iso-rule index for each*
      tablemax/2 and tablemax/4 shoud be more than enough for the list*/
    if ((glbl_iso_list=(signed int**) calloc(tablemax+1,sizeof(signed int*)))
					==NULL) outof_memory("isotropic_list");
    for (z=0;z<=tablemax;z++){
      if ((glbl_iso_list[z]=
		      (signed int*) calloc(tablemax,sizeof(signed int*)))
				==NULL) outof_memory("isotropic_list[tablemax/4]");
    }
    /*max memory for an iso-group image*/
    gsize_bytes=(signed int)ceil(value_bits * (double)(3*3*3)/8);
    if ((iso_group_image=(char *)calloc( gsize_bytes,sizeof(char)))
					==NULL) outof_memory("iso_group_image");
}    
/****************** for isotropic groups Feb 2020 ***********************/
void free_mem_iso(char thisnhood){
  signed int tablemax,z;

  //fprintf(stderr,"\nfree_mem_iso(%d)",nhood);
  
    /*called in main*/
    free(iso_rule);
    free(group_list_iso);
    
    tablemax= (signed int)pow(value_range,(double)thisnhood)-1;
    //fprintf(stderr,"\n%d:",tablemax); 
    for (z=0;z<=tablemax;z++){
      //fprintf(stderr,"\n %d",z);q
      free(glbl_iso_list[z]);
    }  
    free(glbl_iso_list);
    free(iso_group_image);
}
/********** allocate various for rule 0, not for tot_only==1  ************/
void allocate_mem_rule0_extra(char thisnhood){
 signed int tablemax,tablebytes,filter_bytes;
 
   //fprintf(stderr,"\nallocate_mem_iso(%d)",nhood);
  
   tablemax= (signed int)pow(value_range,(double)thisnhood)-1;
   tablebytes=(signed int)ceil(value_bits * (double)(tablemax+1)/8);
   filter_bytes =(signed int)ceil((double)(tablemax+1)/8);

   /*if ((carule_mut=(char *)calloc(tablebytes,sizeof(char)))
                            ==NULL) outof_memory("carule_mut");*/

   /*nominal calloc of buffer to hold statistical rule sample*/
   if ((statbuf=(unsigned char *)calloc(1,
	     sizeof(unsigned char)))==NULL) outof_memory("statbuf");
      totstatrules=0; /*stat rules not yet loaded*/
      sizeof_statbuf=2; 
   /*to filter out colors in space-time patterns*/
   if ((color_filter=(char *)calloc(filter_bytes,sizeof(char)))
				==NULL) outof_memory("color_filter");
   if ((mutation_filter=(char *)calloc(filter_bytes,sizeof(char)))
				==NULL) outof_memory("mutation_filter");
   if ((hist_order=(unsigned long *)calloc(tablemax+1,sizeof(unsigned long)))
				==NULL) outof_memory("hist_order");  
}
/**************** free various rule 0  **********************/
void free_mem_rule0_extra(void){
	
        //free(carule_mut);
  
	free(statbuf);
        totstatrules=sizeof_statbuf=0;
        free(color_filter);
        free(mutation_filter);
        free(hist_order);         
}

/*********** allocate memory rulemix except at cell 0 ******************/
void allocate_mem_rulemix(char thisnhood){
 signed int tablebytes,tablemax;
 unsigned int zu;
    /*all rules have mem allocated as for largest nhood*/
    tablemax= (signed int)pow(value_range,(double)thisnhood)-1;
    tablebytes=(signed int)ceil(value_bits * (double)(tablemax+1)/8);
 
    /*remainder of rules in rule mix*/
    if ((carule=(char**)realloc(carule,lineL*sizeof(char*)))
					 ==NULL) outof_memory("carule");
    for (zu=1;zu<=lineL-1;zu++){
       sprintf(textb[0],"carule[%d]",zu);
       if ((carule[zu]=(char *)calloc(tablebytes,sizeof(char)))
					==NULL) outof_memory(textb[0]);
    }

    if ((carule_mut=(char**)realloc(carule_mut,lineL*sizeof(char*)))
					 ==NULL) outof_memory("carule");
    for (zu=1;zu<=lineL-1;zu++){
       sprintf(textb[0],"carule_mut[%d]",zu);
       if ((carule_mut[zu]=(char *)calloc(tablebytes,sizeof(char)))
					==NULL) outof_memory(textb[0]);
    }
}

/************** re-allocate memory, rules ***************************/
void reallocate_mem_rulemix(char thisnhood,char increace){
 signed int tablemax,tablebytes,z;
   
    tablemax= (signed int)pow(value_range,(double)thisnhood)-1;
    tablebytes=(signed int)ceil(value_bits * (double)(tablemax+1)/8);
   
    /*decreace*/
    if (increace<0){
       for (z=1;z<=abs(increace);z++) free(carule[L+z]);
    }
    if ((carule=(char**)realloc(carule,lineL*sizeof(char*)))
					 ==NULL) outof_memory("carule");
    /*increace*/
    if (increace>0){
       for (z=1;z<=increace;z++){
	  sprintf(textb[0],"carule[%d]",lineL-z);
	  if ((carule[lineL-z]=(char *)calloc(tablebytes,sizeof(char)))
					 ==NULL) outof_memory(textb[0]);
       }
    }

    /*decreace*/
    if (increace<0){
       for (z=1;z<=abs(increace);z++) free(carule_mut[L+z]);
    }
    if ((carule_mut=(char**)realloc(carule_mut,lineL*sizeof(char*)))
					 ==NULL) outof_memory("carule");
    /*increace*/
    if (increace>0){
       for (z=1;z<=increace;z++){
	  sprintf(textb[0],"carule_mut[%d]",lineL-z);
	  if ((carule_mut[lineL-z]=(char *)calloc(tablebytes,sizeof(char)))
					 ==NULL) outof_memory(textb[0]);
       }
    }
}

/*********** free memory rulemix, except cell 0 *****************/
void free_mem_rulemix(void){
  unsigned int zu;

    for (zu=1;zu<=lineL-1;zu++) free(carule[zu]);
    for (zu=1;zu<=lineL-1;zu++) free(carule_mut[zu]);
}

/************** allocate memory, totalistic code, at cell0 *************/
void allocate_mem_tcode0(char thisnhood){
  unsigned int v_tablecodesize,v_codebytes;
  signed int cacode_max,cacode_bytes;

   /*t-code and k-code*/
   if ((cacode=(char**)calloc(1,sizeof(char*)))
					==NULL) outof_memory("cacode");
   cacode_max=thisnhood*(value_range-1);
   cacode_bytes=(signed int)ceil(value_bits * (double)(cacode_max+1)/8);
   if ((cacode[0]=(char *)calloc(cacode_bytes,
			  sizeof(char)))==NULL)outof_memory("cacode[0]");

   /*if ((cacode[0]=(char *)calloc((signed int)
                 ceil(value_bits*(double)(thisnhood+1)/8),
		 sizeof(char)))==NULL)outof_memory("cacode[0]"); $$$ */

   if ((v_code=(char**)calloc(1,sizeof(char*)))
					==NULL) outof_memory("v_code"); 
#  if __UNIX__  /* long long doesnt work or DOS */        
      v_tablecodesize=/*v-codetable size = (v+k-1)!/(k!(v-1)! */
         (unsigned int) 
              (longlong_fact(value_range+thisnhood-1,thisnhood+1)/ 
	      (longlong_fact(value_range-1,1)));

# elif __WATCOM__
      v_tablecodesize=/*v-codetable size*/
         (unsigned int) 
              (long_fact(value_range+thisnhood-1,thisnhood+1)/ 
	      (long_fact(value_range-1,1)));
# endif
   v_codebytes=(signed int) /*bytes for v-code, min=1*/
            ceil(value_bits * (double)(v_tablecodesize)/8);
   if ((v_code[0]=(char *)calloc(v_codebytes,
			  sizeof(char)))==NULL)outof_memory("v_code[0]");
}

/**** if (tot_only==1) allocate various for totalistic code 0  *******/
void allocate_mem_tcode0_extra(char thisnhood){
    unsigned int v_tablecodesize,tablemax,filter_bytes;

#  if __UNIX__  /* long long doesnt work for DOS */        
      v_tablecodesize=/*v-codetable size*/
         (unsigned int) 
              (longlong_fact(value_range+thisnhood-1,thisnhood+1)/ 
	      (longlong_fact(value_range-1,1)));
# elif __WATCOM__
      v_tablecodesize=/*v-codetable size*/
         (unsigned int) 
              (long_fact(value_range+thisnhood-1,thisnhood+1)/ 
	      (long_fact(value_range-1,1)));
# endif
   
      /*if (totalistic==1) tablemax=(unsigned int)thisnhood; $$$ */ 
      if (totalistic==1) tablemax=(unsigned int)thisnhood*(value_range-1);     
      else if (totalistic==2) tablemax=v_tablecodesize;

      filter_bytes=(unsigned int)ceil((double)(tablemax+1)/8);

      if ((statbuf=(unsigned char *)calloc(1,
	     sizeof(unsigned char)))==NULL) outof_memory("statbuf");
      totstatrules=0; /*stat rules not yet loaded*/
      sizeof_statbuf=2; 
      /*to filter out colors in space-time patterns*/
      if ((color_filter=(char *)calloc(filter_bytes,sizeof(char)))
				==NULL) outof_memory("color_filter");
      if ((mutation_filter=(char *)calloc(filter_bytes,sizeof(char)))
				==NULL) outof_memory("mutation_filter");
      if ((hist_order=(unsigned long *)calloc(tablemax+1,sizeof(unsigned long)))
				==NULL) outof_memory("hist_order");        
}
/***** if (tot_only==1) free memory extra buffer, for tot_only==1 only *******/
void free_mem_tcode0_extra(void){
        /*free sample rule buffer*/
	free(statbuf);
        totstatrules=sizeof_statbuf=0;
        free(color_filter);
        free(mutation_filter);
        free(hist_order);
} 
/************** allocate memory, totalistic codes *********************/
void allocate_mem_tcodemix(char thisnhood){    
 unsigned int zu;
 signed int v_tablecodesize,v_codebytes;
 signed int cacode_max,cacode_bytes;

  /*all rules have mem allocated as for largest nhood*/ 
  /*remainder of rules in rule mix*/
  if ((cacode=(char**)realloc(cacode,lineL*sizeof(char*)))
					 ==NULL) outof_memory("cacode");
  if ((v_code=(char**)realloc(v_code,lineL*sizeof(char*)))
					 ==NULL) outof_memory("v_code");
#  if __UNIX__  /* long long doesnt work or DOS */        
      v_tablecodesize=/*v-codetable size*/
         (signed int) 
              (longlong_fact(value_range+thisnhood-1,thisnhood+1)/ 
	      (longlong_fact(value_range-1,1)));
# elif __WATCOM__
      v_tablecodesize=/*v-codetable size*/
         (signed int) 
              (long_fact(value_range+thisnhood-1,thisnhood+1)/ 
	      (long_fact(value_range-1,1)));
# endif
  
  cacode_max=thisnhood*(value_range-1);
  cacode_bytes=(signed int)ceil(value_bits * (double)(cacode_max+1)/8);

  v_codebytes=(signed int) /*bytes for v-code, min=1*/
            ceil(value_bits * (double)(v_tablecodesize)/8);
  for (zu=1;zu<=lineL-1;zu++){
     sprintf(textb[0],"cacode[%d]",zu);
     if ((cacode[zu]=
	 (char *)calloc(cacode_bytes,
			 sizeof(char)))==NULL) outof_memory(textb[0]);//$$$
     sprintf(textb[0],"v_code[%d]",zu);
     if ((v_code[zu]=
	 (char *)calloc(v_codebytes,sizeof(char)))==NULL) outof_memory(textb[0]);
  }
}

/************** re-allocate memory, totalistic codes *********************/
void reallocate_mem_tcodemix(char thisnhood,char increace){
 signed int z,v_tablecodesize,v_codebytes;
 signed int cacode_max,cacode_bytes;

  if (increace<0){
       for (z=1;z<=abs(increace);z++){
          free(cacode[L+z]);
          free(v_code[L+z]);
       }
  }
  if ((cacode=(char**)realloc(cacode,lineL*sizeof(char*)))
					==NULL) outof_memory("cacode");
  if ((v_code=(char**)realloc(v_code,lineL*sizeof(char*)))
					==NULL) outof_memory("v_code");
  /*max index of tcode*/ //$$$
  cacode_max=thisnhood*(value_range-1);
  cacode_bytes=(signed int)ceil(value_bits * (double)(cacode_max+1)/8);
  /*max index of kcode*/
  v_tablecodesize=(signed int)( fact(value_range+thisnhood-1)/ 
			      (fact(thisnhood)*fact(value_range-1)) );
  v_codebytes=(signed int) /*bytes for k-code, min=1*/
            ceil(value_bits * (double)(v_tablecodesize)/8);
  /*increace*/
  if (increace>0){
       for (z=1;z<=increace;z++){
	  sprintf(textb[0],"cacode[%d]",lineL-z);
	  if ((cacode[lineL-z]=
	     (char *)calloc(cacode_bytes,
			  sizeof(char)))==NULL) outof_memory(textb[0]);
          sprintf(textb[0],"v_code[%d]",lineL-z);
	  if ((v_code[lineL-z]=
	       (char *)calloc(v_codebytes,
			  sizeof(char)))==NULL) outof_memory(textb[0]);
       }
  }
}

/**************** free memory tcodemix, except cell 0 *********************/
void free_mem_tcodemix(void){
  unsigned int zu;
    for (zu=1;zu<=lineL-1;zu++){ 
       free(cacode[zu]);
       free(v_code[zu]);
    }
}

/**************** free memory tcode 0  **********************/
void free_mem_tcode0(void){
	free(cacode[0]);
	free(cacode);
        free(v_code[0]);
	free(v_code);
}

/***** allocate memory nodiffrules, rulemix selected from this set *****/
void allocate_mem_diffrules(char thisnhood,signed int nodiffrules){
 signed int tablemax,tablebytes;
 unsigned int zu;

    tablemax= (signed int)pow(value_range,(double)thisnhood)-1;
    tablebytes=(signed int)ceil(value_bits * (double)(tablemax+1)/8);

    /*the range of different rules in rule mix*/
    if ((diffrule=(char**)calloc(nodiffrules,sizeof(char*)))
					==NULL) outof_memory("diffrule");
    for (zu=0;zu<=nodiffrules-1;zu++){
		sprintf(textb[0],"diffrule[%d]",zu);
		if ((diffrule[zu]=(char *)calloc(tablebytes,sizeof(char)))
					==NULL) outof_memory(textb[0]);
    }
}
/*********** free memory diffrule *****************/
void free_mem_diffrules(signed int nodiffrules){
  unsigned int zu;

	for (zu=0;zu<=nodiffrules-1;zu++) free(diffrule[zu]);
	free(diffrule);
}

/***** allocate memory nodiffrules, codemix selected from this set *****/
void allocate_mem_diffcodes(char thisnhood,signed int nodiffrules){
  unsigned int zu;
  signed int v_codemax, v_codebytes,t_codemax,t_codebytes;

   /*the range of different codes in code mix*/
   if ((diffcode=(char**)calloc(nodiffrules,sizeof(char*)))
					==NULL) outof_memory("diffcode");
   if ((v_diffcode=(char**)calloc(nodiffrules,sizeof(char*)))
					==NULL) outof_memory("v_diffcode");
   
   t_codemax=thisnhood*(value_range-1); /*max index of codetable*/
   t_codebytes=(signed int)ceil(value_bits * (double)(t_codemax+1)/8);
   /*fprintf(stderr,"\n >v_codemax");*/
   v_codemax=v_tablecodemax[thisnhood];
   v_codebytes=(signed int) /*bytes for k-code, min=1*/
            ceil(value_bits * (double)(v_codemax+1)/8);


   for (zu=0;zu<=nodiffrules-1;zu++){
      sprintf(textb[0],"diffcode[%d]",zu);
      if ((diffcode[zu]=
	  (char *)calloc(t_codebytes,
			  sizeof(char)))==NULL) outof_memory(textb[0]);
      sprintf(textb[0],"v_diffcode[%d]",zu);
      if ((v_diffcode[zu]=
         (char *)calloc(v_codebytes,sizeof(char)))==NULL) outof_memory(textb[0]);
   }
}

/**************** free memory tcodemix, except cell 0 **********************/
void free_mem_diffcodes(signed int nodiffrules){
  unsigned int zu;

    for (zu=0;zu<=nodiffrules-1;zu++){ 
       free(diffcode[zu]);
       free(v_diffcode[zu]);
    }
    free(diffcode);
    free(v_diffcode);
}

/****** allocate memory fo 2 rules consisting of all 0s and all 1s ********/
void allocate_mem_all_0s_all_1s_rules(char thisnhood){
  signed int tablemax,tablebytes;

   tablemax= (signed int)pow(value_range,(double)thisnhood)-1;
   tablebytes=(signed int)ceil(value_bits * (double)(tablemax+1)/8);

   /*for checking for same n-tupules in rbn pre-image algorithm*/
   if ((rule_all_0s=(char *)calloc(tablebytes,sizeof(char)))
				   ==NULL) outof_memory("rule_all_0s");
   if ((rule_all_1s=(char *)calloc(tablebytes,sizeof(char)))
				   ==NULL) outof_memory("rule_all_1s");
   memset(rule_all_1s, 255, tablebytes); /*set all bits to 1*/
}

/****** free memory fo 2 rules consisting of all 0s and all 1s ********/
void free_mem_all_0s_all_1s_rules(void){
		free(rule_all_0s);
		free(rule_all_1s);
}

/************** allocate memory nhood matrix *******************/
char allocate_mem_nhood_matrix(char thisnhood){
  signed int  z,zz,tablemax,tablebytes,nhoodbytes,
              temp,tempx,tempy;
  signed long sod;
  char *value_nhood;

   tempx=getx;
   tempy=gety;
   tablemax= (signed int)pow(value_range,(double)thisnhood)-1;
   tablebytes=(signed int)ceil(value_bits * (double)(tablemax+1)/8);

   /*allocate mem to n=Maxnhood nhood matrix*/
   if( (nm=(char**) calloc(thisnhood,sizeof(char*)))
					==NULL) outof_memory("nm");
   for (z=0;z<=thisnhood-1;z++){
      sprintf(textb[0],"nm[%d]",z);
      if ((nm[z]=(char *)calloc(tablebytes,sizeof(char)))
					==NULL) outof_memory(textb[0]);
   }
   nhoodbytes=(signed int)ceil(value_bits * (double)(thisnhood)/8);
   if ((value_nhood=(char *)calloc(nhoodbytes,sizeof(char)))
					==NULL) outof_memory("nhoodbytes");
   setfillstyle(SOLID_FILL,black);
   /*set bits or values in memory*/
   for (zz=tablemax;zz>=0;zz--){
           /*monitor for very big rule tables*/
           /*print in prompt-box after value-range, q to abort*/ 
           if (zz>0 && zz%100000==0){
              moveto(tempx,tempy);             
              bar(getx,gety,Maxx-5,gety+CHeight); 
              sprintf(textb[0]," %d%%",
		      (signed int)(100*(double)(tablemax-zz)/tablemax) );
              outtext(textb[0]);
              if (event_ready()){
		 if (is[0]=='q'){
                    for (z=0;z<=thisnhood-1;z++) free(nm[z]);
                    free(nm);
                    free(value_nhood);
                    sprintf(is,"%s","");
                    return(1);                 
                 }             
              }
           }

           if (value_range==2){
              sod=zz;
	      for (z=thisnhood-1;z>=0;z--){	      
		  temp=sod/(signed int)pow(2,(double)z);
		  if (temp==1) {
		      set_bit1(nm[z],zz);
                      //fprintf(stderr,"%d",get_bit(nm[z],zz));
		      sod=sod-(signed int)pow(2,(double)z);
		  }
              }
           }
           else{
	      dec_to_value_line(value_nhood,zz,thisnhood);
              for (z=thisnhood-1;z>=0;z--){
		  set_value(nm[z],zz,get_value(value_nhood,z));
                  //fprintf(stderr,"%d",get_value(nm[z],zz));
              }
	      //fprintf(stderr,"\n");
           }	      
   }
   free(value_nhood);   
   /*canalyzing inputs are stored as bits in 2 bytes,  max nhood=16*/
   if ((canal=(char *)calloc(4,sizeof(char)))==NULL)
		     outof_memory("canal");
   return(0);
}

/**************** free memory for nhood matrix **********************/
void free_mem_nhood_matrix(char thisnhood){
 signed int z;
  
   for (z=0;z<=thisnhood-1;z++) free(nm[z]);
   free(nm);
   free(canal);
}

/************** allocate memory nhood matrix *******************/
void allocate_mem_Z_parameter(void){

   sprintf(textb[0],"zparam");
   if ((zparam=(float*)calloc(3,sizeof(float)))
			    ==NULL) outof_memory("zparam");
}
/************** free memory nhood matrix *******************/
void free_mem_Z_parameter(void){

	free(zparam);
}

/********** allocate memory for equivalent codes, Oct 93 *****************/
void allocate_code_mem(void){
 signed int codemax,codespacebytes;

   /*needs updating $$$ */
   /*set up code tick off - to avoid plotting equiv codes in graph*/
   codemax=(signed int)pow(2,(double)nhood+1)-1;/*max code dec*/
   codespacebytes=(signed int)ceil( (double) (codemax+1)/8 );
   /*code-space index set to 0, equivalent code ticked off by bit=1*/
   if ((codetickoff=(char *)calloc(codespacebytes,sizeof(char)))
			       ==NULL) outof_memory("codetickoff");
   /*set up temp pointer for equivalent codes*/
   sprintf(textb[0],"tempcode");
   if ((tempcode=(char *)calloc((signed int)ceil((double)(nhood+1)/8),
			 sizeof(char)))==NULL) outof_memory("tempcode");
   /*freed in main, and in drpara for lambda_z_graph*/
}

/**************** allocate memory to CA state arrays **********************/
void allocate_mem_CA_states(void){

   if ((seq_order=(unsigned int*)calloc(lineL,sizeof(unsigned int)))
			    ==NULL) outof_memory("seq_order");
   if ((nhd=(unsigned int *)calloc(lineL,sizeof(unsigned int)))
					==NULL) outof_memory("nhd");
   if ((bitseed=(char *)calloc(bytesL,sizeof(char)))
					==NULL) outof_memory("bitseed");
   if ((firstseed=(char *)calloc(bytesL,sizeof(char)))
					==NULL) outof_memory("firstseed");
   if ((this_firstseed=(char *)calloc(bytesL,sizeof(char)))
				   ==NULL) outof_memory("this_firstseed");
   if ((state1=(char *)calloc(bytesL,sizeof(char)))==NULL) outof_memory("state1");
   if ((state2=(char *)calloc(bytesL,sizeof(char)))==NULL) outof_memory("state2");
   if ((all_0s=(char *)calloc(bytesL,sizeof(char)))
					==NULL) outof_memory("all_0s");
   if ((all_1s=(char *)calloc(bytesL,sizeof(char)))
					==NULL) outof_memory("all_1s");
   memset(all_1s,255,bytesL); /*set all bits to 1*/
   /*set exess bits to 0*/
   if (value_range==2){
     unsigned int z;
      if (lineL%8!=0){  /* not multistate compatible */    
         for (z=L+1;z<=bytesL*8 -1;z++){
            set_bit0(all_1s,z);
         }
      }   
   }
   else{
      if ((lineL*value_bits)%sizeof(char)!=0){
	char *p_state1;
        unsigned int z,excess_bits;
         excess_bits=(bytesL*sizeof(char)) - (lineL*value_bits);
         p_state1=&state1[bytesL-1];
         for (z=7;z>=7-excess_bits;z--) set_bit0(p_state1,z);
      }
   }
   /*for segment repeats,equivalent cycle states etc */
   if ((rot=(char *)calloc(bytesL,sizeof(char)))
					==NULL) outof_memory("rot");
   if ((tempState=(char*)calloc(bytesL,sizeof(char)))
					==NULL) outof_memory("tempState");
   if (tot_only==0){
      if ((tempState2=(char*)calloc(bytesL,sizeof(char)))
					==NULL) outof_memory("tempState2");
      /*to distinguish canalizing cells (genes)*/
      if ((iscanal=(char *)calloc(bytesL,sizeof(char)))
					==NULL) outof_memory("iscanal");
      /*for learning algorithms*/
      /*target state*/
      if ((tar=(char *)calloc(bytesL,sizeof(char)))
					==NULL) outof_memory("tar");
      /*aspiring pre-image state/s, initial alloc, will be re-alloced*/
      notolearn=1;
      if ((learn_pre=(char**)calloc(1,sizeof(char*)))
					==NULL) outof_memory("learn_pre");
      if ((learn_pre[0]=(char *)calloc(bytesL,sizeof(char)))
					==NULL) outof_memory("learn_pre[0]");      
      /*pratial pre-image histogram, rnd wiring*/
      if ((pp_hist=(unsigned long *)calloc(lineL,sizeof(unsigned long)))
					==NULL) outof_memory("pp_hist");
      /*pratial pre-image histogram total (to find average), rnd wiring*/
      if ((pp_hist_total=(unsigned long *)calloc(lineL,sizeof(unsigned long)))
					==NULL) outof_memory("pp_hist_total");
   }
}

/**************** free memory to CA state arrays **********************/
void free_mem_CA_states(void){
    signed int z;
                //fprintf(stderr,"\nseq_order"); 
                free(seq_order);
                //fprintf(stderr,"\nnhd");
		free(nhd);
                //fprintf(stderr,"\nbitseed");
		free(bitseed);
                //fprintf(stderr,"\nfirstseed"); 
		free(firstseed);
                //fprintf(stderr,"\nthis_firstseed");
                free(this_firstseed);
                //fprintf(stderr,"\nstate1");
		free(state1);
                //fprintf(stderr,"\nstate2");
		free(state2);
                //fprintf(stderr,"\nall_0s");         
		free(all_0s);
                //fprintf(stderr,"\nall_1s");
                free(all_1s);
                //fprintf(stderr,"\nrot");
                free(rot);
                //fprintf(stderr,"\ntempState");
		free(tempState);
            
                if (tot_only==0){
		   //fprintf(stderr,"\ntempState2");
		   free(tempState2);
                   //fprintf(stderr,"\niscanal");
		   free(iscanal);
                   //fprintf(stderr,"\ntar"); 
		   free(tar);

		   for (z=0;z<=notolearn-1;z++){
		       //fprintf(stderr,"\n notolearn=%d learn_pre[z]=%d",notolearn,z);
                       free(learn_pre[z]);
                   }
                   //fprintf(stderr,"\nlearn_pre");
		   free(learn_pre);

                   //fprintf(stderr,"\npp_hist"); 
		   free(pp_hist); 
                   //fprintf(stderr,"\npp_hist_total ");
		   free(pp_hist_total);
			   
                }
		//fprintf(stderr,"\n---all---");             
}

/*************** allocate memory for wiring scheme, Oct 93 **************/
void allocate_mem_wiring(void){
 unsigned int zu;

  signed int z;

  /*fprintf(stderr,"\n wiring calloc - ");*/
  if ((wiring=(unsigned int **)calloc(lineL,sizeof(unsigned int*)))
					==NULL) outof_memory("**wiring");
  for (zu=0;zu<=lineL-1;zu++){
	sprintf(textb[0],"wiring[%d]",zu);
	if ((wiring[zu]=
	    (unsigned int*)calloc(nhood,sizeof(unsigned int)))
					==NULL) outof_memory(textb[0]);
	/*set all values to Maxu=65535*/
	for (z=0;z<=nhood-1;z++) wiring[zu][z]=Maxu;
  }
  
  if ((wiring_backup=(unsigned int **)calloc(lineL,sizeof(unsigned int*)))
					==NULL) outof_memory("**wiring");
  for (zu=0;zu<=lineL-1;zu++){
	sprintf(textb[0],"wiring_backup[%d]",zu);
	if ((wiring_backup[zu]=
	    (unsigned int*)calloc(nhood,sizeof(unsigned int)))
					==NULL) outof_memory(textb[0]);
	/*set all values to Maxu=65535*/
	for (z=0;z<=nhood-1;z++) wiring_backup[zu][z]=Maxu;
  }

  if ((celloutfreq=(unsigned int*)calloc(lineL,sizeof(unsigned int)))
					==NULL) outof_memory("celloutfreq");
}
   
/*************** allocate memory for wiring scheme, Oct 93 **************/
void reallocate_mem_wiring(char increace){
 char z;

   if (increace==0) return;
 
   /*decreace*/
   if (increace<0){
      for (z=1;z<=abs(increace);z++) free(wiring[L+z]);
   }
   
   if ((wiring=
       (unsigned int**)realloc(wiring,lineL*sizeof(unsigned int*)))
					==NULL) outof_memory("**wiring");

   if (increace>0){
      for (z=1;z<=increace;z++){
	 sprintf(textb[0],"wiring[%d]",lineL-z);
	   if ((wiring[lineL-z]=
	    (unsigned int*)calloc(nhood,sizeof(unsigned int)))
					==NULL) outof_memory(textb[0]);
      }
   }

   /*decreace*/
   if (increace<0){
      for (z=1;z<=abs(increace);z++) free(wiring_backup[L+z]);
   }
   
   if ((wiring_backup=
       (unsigned int**)realloc(wiring_backup,lineL*sizeof(unsigned int*)))
					==NULL) outof_memory("**wiring");

   if (increace>0){
      for (z=1;z<=increace;z++){
	 sprintf(textb[0],"wiring_backup[%d]",lineL-z);
	   if ((wiring_backup[lineL-z]=
	    (unsigned int*)calloc(nhood,sizeof(unsigned int)))
					==NULL) outof_memory(textb[0]);
      }
   }

   if ((celloutfreq=
       (unsigned int*)realloc(celloutfreq,lineL*sizeof(unsigned int)))
					==NULL) outof_memory("celloutfreq");
}

/*************** free memory for wiring scheme, Oct 93 **************/
void free_mem_wiring(void){
 unsigned int zu;

    for (zu=0;zu<=lineL-1;zu++) free(wiring[zu]);
    free(wiring);
    for (zu=0;zu<=lineL-1;zu++) free(wiring_backup[zu]);
    free(wiring_backup);
    free(celloutfreq);
}

/************************************************************/













