Logo Search packages:      
Sourcecode: yagiuda version File versions  Download package

perform.c

#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <errno.h>
#include "yagi.h"

/* The function performance gives a performance rating for the antenna
between 0 and 1, for use in a genetic algorithm to get performance. All
parameters are roughly linear */ 

extern int errno;
extern double Zo;

double performance(struct flags flag, struct performance_data data, struct performance_data max, struct performance_data weight, struct performance_data start)
{
      double a, x_err, fb,swr,product_of_weights;
      struct performance_data perform;
      double max_fb;
      int items=0;
      memset((char*) &perform,1,sizeof(perform));
      /* perform.gain=1.0; perform.fb=1.0; perform.swr=1.0;
      perform.fb=1.0; perform.r=1.0; perform.x=1.0;
      perform.sidelobe=1.0; */
      product_of_weights=1.0;
      weight.sidelobe/=100.0;
      /* To normalise the fitness, we must divide by the products of the
      weights, so this must be found. */
      if(weight.gain!=0.0)
            product_of_weights=weight.gain;
      if(weight.fb!=0.0)
            product_of_weights*=weight.fb;
      if(weight.r!=0.0)
            product_of_weights*=weight.r;
      if(weight.x!=0.0)
            product_of_weights*=weight.x;
      if(weight.swr!=0.0)
            product_of_weights*=weight.swr;
      if(weight.sidelobe!=0.0)
            product_of_weights*=weight.sidelobe;
      if(  ((flag.Wflg&GAIN)==GAIN) ||  ((flag.gflg&GAIN)==GAIN) )
      {
            /* gain=pow(10.0,data.gain/10.0);       
            start_gain=pow(10.0,(start.gain-1.0)/10.0);       
            max_gain=pow(10.0,max.gain/10.0);
            if(gain>1.2*max_gain)
                  gain=max_gain;
            perform.gain=weight.gain*(gain-start_gain)/(max_gain-start_gain); */
            perform.gain=weight.gain*(data.gain-5)/(max.gain-5);
            /* printf("perform.g= %f g=%f\n", perform.gain, data.gain);  */
            if(perform.gain < 0)
                  perform.gain=0.0;
            items++;
      }
      if(  ((flag.Wflg&FB)==FB) ||  ((flag.gflg&FB)==FB) )
      {
            fb=pow(10.0,data.fb/10.0);       
            max_fb=pow(10.0,max.fb/10.0);
            if((fb>max_fb) &(!flag.Oflg))
                  fb=max_fb; 
            perform.fb=weight.fb*fb/max_fb; 
            items++;
      }
      if(  ((flag.Wflg&RESISTANCE)==RESISTANCE) || ((flag.gflg&RESISTANCE)==RESISTANCE))
      {
            perform.r=(1-pow(fabs(Zo-data.r)/Zo,0.25));  
            if(data.r<0.7*Zo || data.r > 1.4*Zo)
                  perform.r/=10.0;
            items++;
      }
      if(  ((flag.Wflg&REACTANCE)==REACTANCE) || ((flag.gflg&REACTANCE)==REACTANCE))
      {
            x_err=fabs(data.x)/Zo;  
            if(x_err > 1.0)
                  x_err=1.0;
            perform.x=1-pow(x_err,0.28);
            items++;
      }
      if(  ((flag.Wflg&VSWR)==VSWR) ||  ((flag.gflg&VSWR)==VSWR) )
      {
            swr=data.swr;
            /* The follwing, fitness=(1-((swr-1)/(swr+1))^2), gives a fitness
            proportional to the fraction of power radiated, assuming all 
            reflected power is absorbed. Unfortunately, it gives too high a#
            fitness to a poor VSWR, so was abandoned */
            /* perform.swr=weight.swr*(1-pow((swr-1.0)/(swr+1.0),2.0) ) ;    */


            /* The folloing is an imperical relationship developed by me, by writing
            a number of VSWR's down (1.0, 1.1, 1.5, 2.0, 3.0 and infinity and 
            writing down what I donsidered their fitness (1.0, 0.9, 0.8, 0.5 and 0.1)
            then fitting a polynomial thru em. The fitness dont work out exactly
            as above, but they seem reasonable. This has a maximum value of 
            0.98220 at VSWR=1.0, but I wont bother addeding the scale factor
            1/.98220 = 1.0181, since this will not improve things - only slow the 
            program a bit! */
            /* perform.swr=2.86298/(swr*swr) - 1.88078/(swr*swr*swr); */
            /* Another imperical one */
            /* if(swr > 7.2925)
                  perform.swr=1.0/(swr);
            else */
                  perform.swr=1.0-log10(swr); 
            /* if(swr>7.76124)
                  perform.swr=1.0/(swr*swr);
            else
                  perform.swr=1.0-log10(swr); */
                  
            /* printf("swr=%f fit = %f\n", swr, perform.swr);  */
            items++;
      }
      if(  ((flag.Wflg&SIDE_LOBE_LEVEL)==SIDE_LOBE_LEVEL) ||  ((flag.gflg&SIDE_LOBE_LEVEL)==SIDE_LOBE_LEVEL) )
      {
            /* sidelobe_level=pow(10.0,data.sidelobe/10.0);       
            max_sidelobe=pow(10.0,max.sidelobe/10.0);
            if((sidelobe_level>max_sidelobe) & !flag.Oflg)
                  sidelobe_level=max_sidelobe;  
            perform.sidelobe=weight.sidelobe*sidelobe_level/max_sidelobe; */
            perform.sidelobe=weight.sidelobe*data.sidelobe/max.sidelobe; 
            items++;
      }
      /* a=(perform.gain*perform.fb*perform.r*perform.x*perform.swr*perform.sidelobe)/product_of_weights; */
      a=(perform.gain+perform.fb+perform.r+perform.x+perform.swr+perform.sidelobe)/(double) items;
#ifdef DEBUG
      if(errno)
      {
            fprintf(stderr,"Errno =%d in perform.c\n", errno);
            exit(1);
      }
#endif
      return(a);
}





Generated by  Doxygen 1.6.0   Back to index