1 #ifdef HAVE_STDLIB_H
2 #include <stdlib.h>
3 #endif
4 #include <stdio.h>
5 #include <errno.h>
6 
7 #ifdef HAVE_IEEEFP_H
8 #include <ieeefp.h>
9 #endif
10 
11 #ifdef HAVE_NAN_H
12 #include <nan.h>
13 #endif
14 
15 #include "yagi.h"
16 
17 #define granularity 8 /* 2^granularity = possible different lengths */
18 
19 #define LENGTH_MIN            0.35 /* min length of an element (in lambda) */
20 #define LENGTH_DR_MIN         0.40 /* min length of an element (in lambda) */
21 #define LENGTH_MIN_REFLECTOR  0.45 /* min length of reflector (in lambda) */
22 #define LENGTH_MAX            0.50 /* max length of an element (in lambda) */
23 #define SPACE_MIN             0.05 /* min spacing between elements(in lambda) */
24 #define SPACE_MAX             0.42 /* max spacing between elements(in lambda) */
25 #define MAX_CHANGE
26 extern int popsize;
27 extern int iterations;
28 
29 double **data_driveng, **data_parasiticg, *vg, **zg, **Ag, *bg;
30 double *ping, design_frequencyg;
31 int driveng, parasiticg, *indxg, elementsg;
32 struct FCOMPLEX *voltageg, *currentg, *input_impedanceg;
33 struct element_data *coordinatesg;
34 double lambda;
35 struct performance_data *mean_performanceg;
36 struct flags flagg;
37 char *output_filenameg, *update_filenameg;
38 double min_frequencyg, max_frequencyg, step_frequencyg, angular_stepg;
39 int k;
40 
genetic_algorithm(char * output_filename,char * update_filename,struct flags flag,double design_frequency,double min_frequency,double max_frequency,double step_frequency,double angular_step,int driven,int parasitic,double ** data_driven,double ** data_parasitic,double * v,double ** z,double * pin,struct FCOMPLEX * voltage,struct FCOMPLEX * current,struct FCOMPLEX * input_impedance,struct element_data * coordinates,double ** A,double * b,int * indx,struct performance_data * mean_performance)41 void genetic_algorithm(char *output_filename, char *update_filename, struct flags flag, double design_frequency, double min_frequency, double max_frequency, double step_frequency, double angular_step, int driven, int parasitic, double **data_driven, double **data_parasitic, double *v, double **z, double *pin, struct FCOMPLEX *voltage, struct FCOMPLEX *current, struct FCOMPLEX *input_impedance, struct element_data *coordinates, double **A, double  *b, int *indx,struct performance_data *mean_performance)
42 {
43 	int elements;
44 	elements=driven+parasitic;
45 	/* Set up global pointers; save modifiy GA code too much */
46 	data_driveng=data_driven;
47 	data_parasiticg=data_parasitic;
48 	ping=pin;
49 	mean_performanceg=mean_performance;
50 	vg=v;
51 	zg=z;
52 	Ag=A;
53 	bg=b;
54 	voltageg=voltage;
55 	currentg=current;
56 	elementsg=elements;
57 	input_impedanceg=input_impedance;
58 	coordinatesg=coordinates;
59 	indxg=indx;
60 	driveng=driven;
61 	flagg=flag;
62 	parasiticg=parasitic;
63 	design_frequencyg=design_frequency;
64 	min_frequencyg=min_frequency;
65 	max_frequencyg=max_frequency;
66 	step_frequencyg=step_frequency;
67 	angular_stepg=angular_step;
68 	output_filenameg=output_filename;
69 	update_filenameg=update_filename;
70 	if(popsize ==0) /* ie  not set by user */
71 		popsize = 40;
72 
73 	lambda = 3e8/design_frequency;
74 	/* Code with an granularity (eg 8) bit string the length in the range 0 to
75 	1, wavelength. Multiply by lambda to get true lengths.
76 
77 	Likewise code spacing between individual elements as a 8 bit
78 	string, then convert to metres by multiplying by lambda */
79 	Initialise(popsize,2*granularity*elements-granularity);
80 	SetPrint(0) ;
81 	for(k=1; k<=iterations; ++k)
82 	{
83 		if(k%1==0)
84 		    SetPrint(0) ;
85 		else
86 			SetPrint(0);
87 		end_if_stop_exists(&k,iterations,5);
88 		Selection(stdout,k) ;
89 	}
90 	GA_Free();
91 }
92 
Objective(char * gene)93 double Objective(char *gene)
94 {
95 		int i;
96 		double fitness,lmax;
97 		static double max_fitness=0;
98 		static int run_first_time=1;
99 		if(run_first_time==1)
100 		{
101 			max_fitness=get_genetic_algorithm_fitness(flagg, design_frequencyg,driveng,parasiticg,data_driveng, data_parasiticg,vg, zg, ping, voltageg, currentg, input_impedanceg, coordinatesg, Ag, bg, indxg, mean_performanceg);
102 			do_since_better(0,output_filenameg, update_filenameg, *input_impedanceg,*mean_performanceg, flagg, "Optimised with the genetic algorithm", design_frequencyg, min_frequencyg,max_frequencyg,step_frequencyg, elementsg, driveng, parasiticg,angular_stepg,data_driveng,data_parasiticg,1.0, max_fitness);
103 			run_first_time=0;
104 		}
105 		data_parasiticg[1][X]=0.0; /* Set reflector at x=0 */
106 		/* Find the length of the reflector */
107 			data_parasiticg[1][LENGTH]=(ss2r(gene,0,granularity)*(LENGTH_MAX-LENGTH_MIN_REFLECTOR)+LENGTH_MIN_REFLECTOR)*lambda;
108 		for(i=1; i<=driveng; i++) /* for every driven element */
109 		{
110 			data_driveng[i][X]=(ss2r(gene,granularity,granularity)*(SPACE_MAX-SPACE_MIN)+SPACE_MIN)*lambda;
111 			data_driveng[i][LENGTH]=(ss2r(gene,2*granularity,granularity)*(LENGTH_MAX-LENGTH_DR_MIN)+LENGTH_DR_MIN)*lambda;
112 
113 		}
114 		/* put directors in + x direction */
115 		lmax=LENGTH_MAX; /* must be longer than driven */
116 		/* printf("  dr=%f lambda = %f m\n",data_driveng[1][LENGTH],data_driveng[1][LENGTH]*lambda);  */
117 		for(i=2; i<=parasiticg; i++)
118 		{
119 			if(i==2) /* put first director ahead of the driven element */
120 			data_parasiticg[i][X]=data_driveng[1][X] +(ss2r(gene,granularity*2*i-granularity,granularity)*(SPACE_MAX-SPACE_MIN)+SPACE_MIN)*lambda;
121 			else /* These directors must be ahead of the last director */
122 		 data_parasiticg[i][X]=data_parasiticg[i-1][X] +(ss2r(gene,granularity*2*i-granularity,granularity)*(SPACE_MAX-SPACE_MIN)+SPACE_MIN)*lambda;
123 			data_parasiticg[i][LENGTH]=(ss2r(gene,granularity*2*i-granularity,granularity)*(lmax-LENGTH_MIN)+LENGTH_MIN)*lambda;
124 			/* printf("l=%f\n",data_parasiticg[i][LENGTH]/lambda);  */
125 			lmax=data_parasiticg[i][LENGTH]/lambda;
126 			if(lmax>LENGTH_MAX)
127 				lmax=LENGTH_MAX;
128 		}
129 		/* printf("\n");     */
130 		fitness=get_genetic_algorithm_fitness(flagg, design_frequencyg,driveng,parasiticg,data_driveng, data_parasiticg,vg, zg, ping, voltageg, currentg, input_impedanceg, coordinatesg, Ag, bg, indxg, mean_performanceg);
131 		if(fitness > max_fitness)
132 		{
133 			max_fitness=fitness;
134 			do_since_better(k,output_filenameg, update_filenameg, *input_impedanceg,*mean_performanceg, flagg, "Optimised with the genetic algorithm", design_frequencyg, min_frequencyg,max_frequencyg,step_frequencyg, elementsg, driveng, parasiticg,angular_stepg,data_driveng,data_parasiticg,1.0, fitness);
135 		}
136 
137 #ifdef DEBUG
138 	if(errno)
139 	{
140 	fprintf(stderr,"Errno =%d in Objective() of genetic.c\n", errno);
141 	exit(1);
142 	}
143 #endif
144 		return(fitness);
145 }
146 
ss2r(char * string,int pos,int len)147 double ss2r(char *string,int pos,int len)
148 {
149 		double result, x ;
150 		int loop;
151 
152 		result=0 ;
153 		for (loop=0 ; loop<len ; loop++) /* XXXXXXXXXXXXXXX */
154 			result=result+result+string[pos+loop]-'0' ;
155 
156 		x=(result+1)/((double)(1<<granularity));
157 		return(x);
158 }
159