1 #ifdef HAVE_STDLIB_H
2 #include <stdlib.h>
3 #endif
4 #include <stdio.h>
5 #include <math.h>
6 #include <string.h>
7 #include <errno.h>
8 #include "yagi.h"
9 
10 /* The function performance gives a performance rating for the antenna
11 between 0 and 1, for use in a genetic algorithm to get performance. All
12 parameters are roughly linear */
13 
14 #include <errno.h>
15 extern double Zo;
16 
performance(struct flags flag,struct performance_data data,struct performance_data max,struct performance_data weight,struct performance_data start)17 double performance(struct flags flag, struct performance_data data, struct performance_data max, struct performance_data weight, struct performance_data start)
18 {
19 	double a, x_err, fb,swr,product_of_weights;
20 	struct performance_data perform;
21 	double max_fb;
22 	int items=0;
23 	memset((char*) &perform,1,sizeof(perform));
24 	/* perform.gain=1.0; perform.fb=1.0; perform.swr=1.0;
25 	perform.fb=1.0; perform.r=1.0; perform.x=1.0;
26 	perform.sidelobe=1.0; */
27 	product_of_weights=1.0;
28 	weight.sidelobe/=100.0;
29 	/* To normalise the fitness, we must divide by the products of the
30 	weights, so this must be found. */
31 	if(weight.gain!=0.0)
32 		product_of_weights=weight.gain;
33 	if(weight.fb!=0.0)
34 		product_of_weights*=weight.fb;
35 	if(weight.r!=0.0)
36 		product_of_weights*=weight.r;
37 	if(weight.x!=0.0)
38 		product_of_weights*=weight.x;
39 	if(weight.swr!=0.0)
40 		product_of_weights*=weight.swr;
41 	if(weight.sidelobe!=0.0)
42 		product_of_weights*=weight.sidelobe;
43 	if(  ((flag.Wflg&GAIN)==GAIN) ||  ((flag.gflg&GAIN)==GAIN) )
44 	{
45 		/* gain=pow(10.0,data.gain/10.0);
46 		start_gain=pow(10.0,(start.gain-1.0)/10.0);
47 		max_gain=pow(10.0,max.gain/10.0);
48 		if(gain>1.2*max_gain)
49 			gain=max_gain;
50 		perform.gain=weight.gain*(gain-start_gain)/(max_gain-start_gain); */
51 		perform.gain=weight.gain*(data.gain-5)/(max.gain-5);
52 		/* printf("perform.g= %f g=%f\n", perform.gain, data.gain);  */
53 		if(perform.gain < 0)
54 			perform.gain=0.0;
55 		items++;
56 	}
57 	if(  ((flag.Wflg&FB)==FB) ||  ((flag.gflg&FB)==FB) )
58 	{
59 		fb=pow(10.0,data.fb/10.0);
60 		max_fb=pow(10.0,max.fb/10.0);
61 		if((fb>max_fb) &(!flag.Oflg))
62 			fb=max_fb;
63 		perform.fb=weight.fb*fb/max_fb;
64 		items++;
65 	}
66 	if(  ((flag.Wflg&RESISTANCE)==RESISTANCE) || ((flag.gflg&RESISTANCE)==RESISTANCE))
67 	{
68 		perform.r=(1-pow(fabs(Zo-data.r)/Zo,0.25));
69 		if(data.r<0.7*Zo || data.r > 1.4*Zo)
70 			perform.r/=10.0;
71 		items++;
72 	}
73 	if(  ((flag.Wflg&REACTANCE)==REACTANCE) || ((flag.gflg&REACTANCE)==REACTANCE))
74 	{
75 		x_err=fabs(data.x)/Zo;
76 		if(x_err > 1.0)
77 			x_err=1.0;
78 		perform.x=1-pow(x_err,0.28);
79 		items++;
80 	}
81 	if(  ((flag.Wflg&VSWR)==VSWR) ||  ((flag.gflg&VSWR)==VSWR) )
82 	{
83 		swr=data.swr;
84 		/* The follwing, fitness=(1-((swr-1)/(swr+1))^2), gives a fitness
85 		proportional to the fraction of power radiated, assuming all
86 		reflected power is absorbed. Unfortunately, it gives too high a#
87 		fitness to a poor VSWR, so was abandoned */
88 		/* perform.swr=weight.swr*(1-pow((swr-1.0)/(swr+1.0),2.0) ) ;    */
89 
90 
91 		/* The folloing is an imperical relationship developed by me, by writing
92 		a number of VSWR's down (1.0, 1.1, 1.5, 2.0, 3.0 and infinity and
93 		writing down what I donsidered their fitness (1.0, 0.9, 0.8, 0.5 and 0.1)
94 		then fitting a polynomial thru em. The fitness dont work out exactly
95 		as above, but they seem reasonable. This has a maximum value of
96 		0.98220 at VSWR=1.0, but I wont bother addeding the scale factor
97 		1/.98220 = 1.0181, since this will not improve things - only slow the
98 		program a bit! */
99 		/* perform.swr=2.86298/(swr*swr) - 1.88078/(swr*swr*swr); */
100 		/* Another imperical one */
101 		/* if(swr > 7.2925)
102 			perform.swr=1.0/(swr);
103 		else */
104 			perform.swr=1.0-log10(swr);
105 		/* if(swr>7.76124)
106 			perform.swr=1.0/(swr*swr);
107 		else
108 			perform.swr=1.0-log10(swr); */
109 
110 		/* printf("swr=%f fit = %f\n", swr, perform.swr);  */
111 		items++;
112 	}
113 	if(  ((flag.Wflg&SIDE_LOBE_LEVEL)==SIDE_LOBE_LEVEL) ||  ((flag.gflg&SIDE_LOBE_LEVEL)==SIDE_LOBE_LEVEL) )
114 	{
115 		/* sidelobe_level=pow(10.0,data.sidelobe/10.0);
116 		max_sidelobe=pow(10.0,max.sidelobe/10.0);
117 		if((sidelobe_level>max_sidelobe) & !flag.Oflg)
118 			sidelobe_level=max_sidelobe;
119 		perform.sidelobe=weight.sidelobe*sidelobe_level/max_sidelobe; */
120 		perform.sidelobe=weight.sidelobe*data.sidelobe/max.sidelobe;
121 		items++;
122 	}
123 	/* a=(perform.gain*perform.fb*perform.r*perform.x*perform.swr*perform.sidelobe)/product_of_weights; */
124 	a=(perform.gain+perform.fb+perform.r+perform.x+perform.swr+perform.sidelobe)/(double) items;
125 #ifdef DEBUG
126 	if(errno)
127 	{
128 		fprintf(stderr,"Errno =%d in perform.c\n", errno);
129 		exit(1);
130 	}
131 #endif
132 	return(a);
133 }
134 
135 
136 
137 
138