~ubuntu-branches/ubuntu/precise/yagiuda/precise

« back to all changes in this revision

Viewing changes to src/optimise.c

  • Committer: Bazaar Package Importer
  • Author(s): Joop Stakenborg
  • Date: 2005-08-22 20:20:13 UTC
  • Revision ID: james.westby@ubuntu.com-20050822202013-mhhxp4xirdxrdfx1
Tags: upstream-1.19
ImportĀ upstreamĀ versionĀ 1.19

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifdef HAVE_STDLIB_H
 
2
#include <stdlib.h>
 
3
#endif
 
4
#include <stdio.h>
 
5
#include <math.h>
 
6
#include <sys/types.h>
 
7
#include <memory.h>
 
8
#include <string.h>
 
9
#include <errno.h>
 
10
#include <ctype.h>
 
11
#include "nrutil.h"
 
12
#include "yagi.h"
 
13
#include "globals.h"
 
14
 
 
15
int main(int argc, char **argv)
 
16
{
 
17
 
 
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;
 
22
        int  ii;
 
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;
 
30
        struct flags flag;
 
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);
 
40
        opterr=0;
 
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)
 
50
                optimising_for(flag);
 
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]);
 
55
        if(flag.Aflg)
 
56
                iterations=2;
 
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);
 
62
        seedRNG(); 
 
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 */
 
68
        fclose(update_fp);
 
69
        strcpy(input_filename,argv[optind]);
 
70
        fp=fopen(input_filename,"rt");
 
71
        if(fp == NULL)
 
72
        {
 
73
                fprintf(stderr,"Cant open %s\n", input_filename);
 
74
                exit(10);
 
75
        }
 
76
        else
 
77
                fclose(fp);
 
78
        strcpy(output_filename,input_filename);
 
79
        strcat(output_filename,".bes");
 
80
        fp_out=fopen(output_filename,"wb");  /* Remove filname.bes */
 
81
        fclose(fp_out);
 
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, &parasitic);
 
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);
 
98
 
 
99
        current=FCOMPLEXvector(1L,(long) elements); 
 
100
        voltage=FCOMPLEXvector(1L,(long) elements);
 
101
 
 
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);
 
105
 
 
106
        read_yagi_data(line, input_filename, &design_frequency, &min_frequency,                &max_frequency, &step_frequency, driven, driven_data, parasitic,                parasitic_data,&angular_step);
 
107
 
 
108
        /* make a copy of the element data, as we will randomise it 
 
109
        Copy from 'parasitic_data' to 'parasitic_data_tmp' etc */
 
110
        errno=0;
 
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);
 
119
        if(flag.Kflg==0)
 
120
                K_times_max=1;
 
121
        /* If a genetic algorithm is used, call the genetic algorithm
 
122
        and exit */
 
123
        if(flag.gflg) /* Do this if using the genetic algorithm */
 
124
        {
 
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, \
 
129
                 &mean); 
 
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);
 
133
                exit (0);
 
134
        }
 
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 */
 
140
        {
 
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)
 
146
                {
 
147
                        if(ii==-1)
 
148
                        {
 
149
                                frequency=design_frequency;
 
150
                                /* Zero mean structure */
 
151
                                memset((char *) &mean,0,sizeof(mean));
 
152
                        }
 
153
                        if(ii==0)
 
154
                                frequency=min_frequency;
 
155
                        if(ii==1)
 
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);
 
158
                        if(ii==-1)
 
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);
 
168
                        if(i==1)
 
169
                                start=mean;
 
170
                }
 
171
                if(flag.wflg)
 
172
                {
 
173
                        mean.gain/=3.0; mean.fb/=3.0; mean.swr/=3.0; 
 
174
                }
 
175
                if(flag.Wflg || flag.gflg)
 
176
                {
 
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)
 
180
                                better=TRUE;
 
181
                        else
 
182
                                better=FALSE;
 
183
                        if((better==TRUE) && flag.Cflg)
 
184
                                better=linear_current_optimisation_test(current, &old_SD_of_currents, elements, parasitic, flag);
 
185
                }
 
186
                else if(flag.Aflg)
 
187
                        better=TRUE;
 
188
                else
 
189
                {
 
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);
 
193
                }
 
194
                if(better==TRUE && !flag.Tflg)
 
195
                {
 
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 */  
 
200
 
 
201
                        /* We write the input impedance at the centre of the band - not
 
202
                        averaging, but the swr is averaged */
 
203
 
 
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*/
 
209
 
 
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);
 
216
                        K_times=0;
 
217
                }
 
218
                else if (better == FALSE || flag.Tflg) /* no improvement */
 
219
                {
 
220
                        /* Restored original data, without any randomisation */
 
221
                        K_times++;
 
222
                        if(K_times<K_times_max) /* usual case */
 
223
                        {
 
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);
 
227
                        }
 
228
                        else
 
229
                        {
 
230
                                /* Retrieve data from _global_best to data, then put
 
231
                                data in tmp */
 
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);
 
236
                                K_times=0;
 
237
                        }
 
238
                        if(flag.Tflg) /* Want to find the sensitivity to constuction errors */
 
239
                        {
 
240
                                if(mean.gain<worst.gain)
 
241
                                        worst.gain=mean.gain;
 
242
                                if(mean.fb<worst.fb)
 
243
                                        worst.fb=mean.fb;
 
244
                                if(mean.swr > worst.swr)
 
245
                                        worst.swr=mean.swr;
 
246
                                if(mean.sidelobe < worst.sidelobe)
 
247
                                        worst.sidelobe=mean.sidelobe;
 
248
                        }
 
249
                }
 
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); 
 
259
                else if(flag.Aflg)
 
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); 
 
263
 
 
264
        } /* End of main loop, now finished trying to better the design */
 
265
        if(!flag.Tflg)
 
266
        {
 
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); 
 
274
        }
 
275
        else if (flag.Tflg) /* find worst design */
 
276
        {
 
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);
 
283
        } 
 
284
 
 
285
        /* free strings */
 
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);
 
291
        /* free vectors */
 
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);
 
296
        /* free matrices */
 
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);
 
309
        exit(0);
 
310
}