15
int main(int argc, char **argv)
18
FILE *fp, *update_fp, *fp_out;
19
char *input_filename, notes[1000];
20
char *output_filename, *update_filename, *line, *ofile;
21
int elements, driven, parasitic;
23
int *indx, i, better=FALSE;
24
double **A, *x,*v,*b,**z,pin,old_perf=-10000.0, new_perf=-1000.0;
25
double **driven_data, **parasitic_data, angular_step, scale_factor=1.0;
26
double **driven_data_tmp, **parasitic_data_tmp;
27
double **driven_data_global_best, **parasitic_data_global_best;
28
double design_frequency, min_frequency, max_frequency, step_frequency;
29
double E_fwd, E_back, H_fwd, H_back, frequency, old_SD_of_currents=1e100;
31
struct FCOMPLEX *voltage, *current, input_impedance, z_centre;
32
struct element_data *coordinates;
33
struct performance_data mean, best_performance,start,changes,worst;
34
/* Zero all the flags in the structure flag. Some compilers allow
35
me to zero them when I define it in the header file, but not all.
36
Hope this method is less compiler specific. */
37
memset( (char *) &flag , 0, sizeof(flag));
38
/* Set the structs to have sensible values to start with. */
39
set_performance_structures(&weight,&max,&best_performance,&worst);
41
ofile=string(0L,100L);
42
/* Since there are so many command line options to get, as of version 1.10
43
of the software, all the options are got from a sepparate file, using lots
44
of global variables! */
45
flag.eflg=31; /* set elements to move */
46
flag.oflg=32805; /* Set things to optimise for */
47
test_for_stop_file(); /* Exit if the file "stop" exists */
48
get_command_line_options(argc, argv,&flag);
49
if(!flag.Tflg && !flag.tflg)
51
/* a function check_flags() does all the checking to make sure flags
52
set (by user adding options) are reasonable. It also acts on many of them. */
53
check_flags(flag, argc, optind, argv[0]);
54
iterations=atoi(argv[optind+1]);
57
/* allocate memory for strings */
58
input_filename=string(0L,100L);
59
line=string(0L,MAX_LINE);
60
output_filename=string(0L,100L);
61
update_filename=string(0L,100L);
63
/* Create a file showing best gain, fb-ratio etc achieved to date */
64
/* This might typically have the name 'antenna.up' */
65
strcpy(update_filename,argv[optind]);
66
strcat(update_filename,".up");
67
update_fp=fopen(update_filename,"wt"); /* Remove filname.up */
69
strcpy(input_filename,argv[optind]);
70
fp=fopen(input_filename,"rt");
73
fprintf(stderr,"Cant open %s\n", input_filename);
78
strcpy(output_filename,input_filename);
79
strcat(output_filename,".bes");
80
fp_out=fopen(output_filename,"wb"); /* Remove filname.bes */
82
/* since the size of all the arrays depends on the number of elements,
83
lets first find out how many elements we have, including driven and
84
parasitic sepparately. Then try to allocate all the memory we need. If we
85
fail, then not much time is wasted. */
86
elements=get_number_of_elements(input_filename, &driven, ¶sitic);
87
/* allocate all memory */
88
driven_data=dmatrix(1L,(long)(driven),1L,6L);
89
parasitic_data=dmatrix(1L,(long) (parasitic),1L,4L);
90
driven_data_global_best=dmatrix(1L,(long)(driven),1L,6L);
91
parasitic_data_global_best=dmatrix(1L,(long) (parasitic),1L,4L);
92
driven_data_tmp=dmatrix(1L,(long)(driven),1L,6L);
93
parasitic_data_tmp=dmatrix(1L,(long) (parasitic),1L,4L);
94
z=dmatrix(1L,(long) elements, 1L, elements*2L);
95
A=dmatrix(1L, 2L*elements, 1L, 2L*elements); /* A.x=b for large matrices */
96
x=dvector(1L, 2L*elements);
97
b=dvector(1L, 2L*elements);
99
current=FCOMPLEXvector(1L,(long) elements);
100
voltage=FCOMPLEXvector(1L,(long) elements);
102
coordinates=element_data_vector(1,elements); /* x,y &l of centre of ele's */
103
v=dvector(1L,2L*elements);
104
indx=ivector(1,2L*elements);
106
read_yagi_data(line, input_filename, &design_frequency, &min_frequency, &max_frequency, &step_frequency, driven, driven_data, parasitic, parasitic_data,&angular_step);
108
/* make a copy of the element data, as we will randomise it
109
Copy from 'parasitic_data' to 'parasitic_data_tmp' etc */
111
/* cp _data to _data_global_best */
112
copy_matrix(driven,6,driven_data_global_best, driven_data);
113
copy_matrix(parasitic,4,parasitic_data_global_best,parasitic_data);
114
/* cp _data to _data_tmp */
115
copy_matrix(driven,6,driven_data_tmp, driven_data);
116
copy_matrix(parasitic,4,parasitic_data_tmp,parasitic_data);
117
/* Find the maximum likely gain, given the boom length */
118
max.gain=determine_maximum_gain2(elements);
121
/* If a genetic algorithm is used, call the genetic algorithm
123
if(flag.gflg) /* Do this if using the genetic algorithm */
125
genetic_algorithm(output_filename, update_filename, flag,\
126
design_frequency, min_frequency, max_frequency, step_frequency, \
127
angular_step, driven, parasitic, driven_data, parasitic_data, v, z, \
128
&pin, voltage, current, &input_impedance, coordinates, A, b, indx, \
130
printf("The best design is in a file \"%s\". You should check it thoroughly\n",output_filename);
131
printf("and if its better than %s, copy %s to %s\n",input_filename,\
132
output_filename, input_filename);
135
if(flag.wflg) /* Do for wide band use */
136
sprintf(notes,"This has been run through optimise and optimised for \
137
wide-band use over the frequency range %.3f MHz to %.3fMHz. \n", \
138
min_frequency/1e6, max_frequency/1e6);
139
for(i=1; i<=iterations; ++i) /* main loop */
141
percent=change_max_percentage_changes(i,iterations,original_percent);
142
/* By default flag.wflg is set to zero, hence the following loop
143
will be exectude only once. If the flag was set to +2, the loop
144
is executed 3 times and we get the average performance */
145
for(ii=-1; ii<flag.wflg;++ii)
149
frequency=design_frequency;
150
/* Zero mean structure */
151
memset((char *) &mean,0,sizeof(mean));
154
frequency=min_frequency;
156
frequency=max_frequency;
157
solve_equations(frequency, driven, parasitic, driven_data, parasitic_data, v, z, &pin, voltage, current, &input_impedance, coordinates, A, b, indx);
159
z_centre=input_impedance;
160
/* compute gain at theta=90, phi=0 (forward direction) */
161
gain(90,0,pin,frequency/design_frequency,coordinates,current,elements,&E_fwd,&H_fwd,frequency,design_frequency);
162
/* now compute gain in the reverse direction */
163
gain(270,0,pin,frequency/design_frequency,coordinates,current, \
164
elements,&E_back,&H_back,frequency,design_frequency);
165
/* put the performance in a structure performance_data */
166
set_mean_structure(input_impedance,E_fwd,E_back,flag, \
167
pin, coordinates, current, elements,frequency,design_frequency,&mean);
173
mean.gain/=3.0; mean.fb/=3.0; mean.swr/=3.0;
175
if(flag.Wflg || flag.gflg)
177
old_perf=performance(flag, best_performance, max, weight,start);
178
new_perf=performance(flag, mean, max, weight,start);
179
if(new_perf > old_perf)
183
if((better==TRUE) && flag.Cflg)
184
better=linear_current_optimisation_test(current, &old_SD_of_currents, elements, parasitic, flag);
190
better=is_it_better(flag.oflg,mean,best_performance);
191
if((better==TRUE) && flag.Cflg)
192
better=linear_current_optimisation_test(current, &old_SD_of_currents, elements, parasitic, flag);
194
if(better==TRUE && !flag.Tflg)
196
/* The function do_since_better() does most things that need to
197
be done if we have a better design. These include writing the
198
new antenna description to disk, print the new performance to disk
199
and to stdout, etc */
201
/* We write the input impedance at the centre of the band - not
202
averaging, but the swr is averaged */
204
do_since_better(i,output_filename, update_filename, z_centre, \
205
mean, flag, notes, design_frequency, min_frequency, \
206
max_frequency, step_frequency, elements, driven, parasitic, \
207
angular_step,driven_data,parasitic_data,scale_factor, new_perf);
208
/* now set the best performance to the performance of this iteration*/
210
best_performance=mean;
211
/* Copy current new design (_data) to the place we keep the best
212
design (_data_tmp) */
213
/* copy _data to _data_global_best */
214
copy_matrix(driven,6,driven_data_global_best,driven_data);
215
copy_matrix(parasitic,4,parasitic_data_global_best,parasitic_data);
218
else if (better == FALSE || flag.Tflg) /* no improvement */
220
/* Restored original data, without any randomisation */
222
if(K_times<K_times_max) /* usual case */
224
/* Retriev data from tmp into data */
225
copy_matrix(driven,6,driven_data,driven_data_tmp);
226
copy_matrix(parasitic,4,parasitic_data,parasitic_data_tmp);
230
/* Retrieve data from _global_best to data, then put
232
copy_matrix(driven,6,driven_data,driven_data_global_best);
233
copy_matrix(parasitic,4,parasitic_data,parasitic_data_global_best);
234
copy_matrix(driven,6,driven_data_tmp,driven_data);
235
copy_matrix(parasitic,4,parasitic_data_tmp,parasitic_data);
238
if(flag.Tflg) /* Want to find the sensitivity to constuction errors */
240
if(mean.gain<worst.gain)
241
worst.gain=mean.gain;
244
if(mean.swr > worst.swr)
246
if(mean.sidelobe < worst.sidelobe)
247
worst.sidelobe=mean.sidelobe;
250
/* The following line looks for a file 'stop' in the current directory
251
and stops next time if it finds it. For DOS use, calling the function
252
kbhit() - keyboard hit, might be better, so the user kits the keyboard
253
to stop the program. We pause after 100 iterations. With a much faster/
254
slower machine, you might want to change this */
255
end_if_stop_exists(&i,iterations,100);
256
dynamic_changing_of_weights(i,1,&weight);
257
if(!flag.Tflg && !flag.Aflg)/*user doesnt want to test sensitivity */
258
randomise(flag.eflg, design_frequency/1e6, percent, driven_data, parasitic_data, driven, parasitic);
260
automatic_enhancement(flag,design_frequency,driven_data,parasitic_data, driven,parasitic,voltage, current, &input_impedance, v,z,A,b,indx,coordinates);
261
else if(flag.Tflg) /* Check sensitivity to construction errors */
262
sensitivity(boom_sd, length_sd, driven_data, parasitic_data, driven, parasitic);
264
} /* End of main loop, now finished trying to better the design */
267
printf("The best design is in a file \"%s\". You should check it thoroughly\n",output_filename);
268
printf("and if its better than %s, copy %s to %s\n",input_filename,output_filename, input_filename);
269
printf("For your information, the original data on the antenna was:\n");
270
print_relavent_performance_data(stdout,"Start data:",0,flag,start,0.0,0,0);
271
print_relavent_performance_data(stdout,"Final data:",0,flag,best_performance,0.0,0,0);
272
changes=subtract_structures(best_performance,start);
273
print_relavent_performance_data(stdout,"Changes: ",0,flag,changes,0.0,0,0);
275
else if (flag.Tflg) /* find worst design */
277
printf("For your inforation, the original data on the antenna was:\n");
278
print_relavent_performance_data(stdout,"Start data:",0,flag,start,0.0,0,0);
279
print_relavent_performance_data(stdout,"Worst data:",0,flag,worst,0.0,0,0);
280
changes=subtract_structures(worst,start);
281
print_relavent_performance_data(stdout,"Changes: ",0,flag,changes,0.0,0,0);
282
printf("\nTolerance parameters were: Length_SD(t)=%.3fmm Boom_SD(T) = %.3fmm\n",length_sd,boom_sd);
286
free_string(input_filename, 0L,100L);
287
free_string(line, 0L, MAX_LINE);
288
free_string(update_filename, 0L, 100L);
289
free_string(output_filename,0L, 100L);
290
free_string(ofile,0L,100L);
292
free_dvector(x,1L, 2L*elements);
293
free_dvector(b,1L, 2L*elements);
294
free_dvector(v,1L,2L*elements);
295
free_ivector(indx, 1L, 2L*elements);
297
free_dmatrix(z,1L,(long) elements, 1L, elements*2L);
298
free_dmatrix(A,1L, 2L*elements, 1L, 2L*elements);
299
free_dmatrix(driven_data,1L,(long)(driven),1L,6L);
300
free_dmatrix(parasitic_data,1L,(long) (parasitic),1L,4L);
301
free_dmatrix(parasitic_data_global_best,1L,(long) (parasitic),1L,4L);
302
free_dmatrix(driven_data_global_best,1L,(long) (parasitic),1L,6L);
303
free_dmatrix(driven_data_tmp,1L,(long)(driven),1L,6L);
304
free_dmatrix(parasitic_data_tmp,1L,(long) (parasitic),1L,4L);
305
/* free FCOMPLEX vectors */
306
free_FCOMPLEXvector(current, 1L,(long) elements);
307
free_FCOMPLEXvector(voltage, 1L,(long) elements);
308
free_element_data_vector(coordinates,1,elements);