/* atlc - arbitrary transmission line calculator, for the analysis of transmission lines are directional couplers. Copyright (C) 2002. Dr. David Kirkby, PhD (G8WRB). This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either package_version 2 of the License, or (at your option) any later package_version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Dr. David Kirkby, e-mail drkirkby at ntlworld.com */ /* The following calculates the odd and even mode impedances between two zero thickness strips of width w, spaced a distance s between two groundplanes of spacing h. */ #include "config.h" #include "definitions.h" #ifdef HAVE_STDLIB_H #include #endif double calculate_integer_values(struct transmission_line_properties *optimise,int nmax,int accuracy_level) { double grid_size, error, error_max=1e6; int i, min_pixels, max_pixels, n, min_critical_pixels, max_critical_pixels; int most_critical=0, step=1; double min_pixel_size, max_pixel_size; double W, H; for(i=0;i<9;++i) optimise->best[i]=-1; /* A silly value, indicating it is not acceptable */ /* Let the number of pixel in the image be between 2^n and 2^(n+2) */ min_pixels=(int) pow(2.0,(double)(accuracy_level-1)); max_pixels=(int) pow(2.0,(double)(accuracy_level+1)); /* Although the stucture W by H has an exact area of W*H, we will allocate some pixels to this, which will be much smaller than the W*H. Each pixel will have a variable area, which we don't know yet, but can put upper and lower limits on it. */ W=optimise->float_values[0]; /* The calculated W and H */ H=optimise->float_values[1]; min_pixel_size=sqrt(W*H/max_pixels); max_pixel_size=sqrt(W*H/min_pixels); /* find the most critical dimension */ for(n=0;nimportance[n]==MOST_IMPORTANT) most_critical=n; } /* we will allocate a number of pixels to this most critical dimension, set by */ min_critical_pixels = optimise->float_values[most_critical]/max_pixel_size; max_critical_pixels = optimise->float_values[most_critical]/min_pixel_size; /* Normally we would try every combination of i, but it may be necessary to keep it even or odd */ if(optimise->odd_or_even[most_critical] == ODD && min_critical_pixels%2==0) min_critical_pixels--; else if(optimise->odd_or_even[most_critical] == EVEN && min_critical_pixels%2==1) min_critical_pixels--; if(optimise->odd_or_even[most_critical] != DONT_CARE) step=2; for(i=min_critical_pixels; iint_values[most_critical]=i; grid_size=optimise->float_values[most_critical]/i; /* Now set all the others to the optimal, assuming i would be used for the most critical dimension */ error=0.0; for(n=0; nint_values[n]=(int) (0.5+optimise->float_values[n]/grid_size); if (optimise->importance[n] != NOT_IMPORTANT) { error+=fabs((double)optimise->int_values[n]*grid_size-optimise->float_values[n]); } } /* Since the numbers generated for the integers seeme to differ on different computers, I've suspected the problem might be that an error is very similar at two different sets of integer values. Hence I will only consider the error lower its lower by 1e-9. That should avoid silly rounding problems. */ if(error<(error_max-TINY)) /* The 1e-9 avoids different results on different*/ { /* machines due to rounding errors */ error_max=error; for(n=0; nbest[n]=optimise->int_values[n]; } } return(error_max); /* return the error */ }