secantfunction.c

containment radii to king psf function in C. used in secantbug*log' on lines that begin with 'secant' - Kelley-Hoskins Nathan, 03/10/2015 02:42 PM

Download (2.96 KB)

 
1
// from 68 and 80 % containment radii (in degrees), calculate the sigma and gamma
2
// parameters for a normalized king function (WITH THE SECANT METHOD, fails if r80 < r68*1.1)
3
int calcKingParametersViaSecant( double rad68, double rad80, double & sigma, double & gamma )
4
{
5
  // copied almost verbatim from
6
  // $CTOOLS/scripts/cta_root2caldb.py's root2psf_king() function
7

    
8
  // no point in continuing if only 0's
9
  if ( rad68 <= 0.0 || rad80 <= 0.0 )
10
  {
11
    printf("                                           calcKingParameters(%.2f %.2f %.2f %.2f): Warning, a containment radius is 0, setting g/s to 0s...\n", rad68, rad80, sigma, gamma ) ;
12
    gamma = 0.0 ;
13
    sigma = 0.0 ;
14
    return 1 ;
15
  }
16

    
17
  // initial ratios
18
  double a = 1.0 - 0.68 ;
19
  double b = 1.0 - 0.80 ;
20
  double c = (rad68*rad68) / (rad80*rad80) ;
21

    
22
  // solve equation (a^x-1)/(b^x-1)=c for x using secant
23
  // method.  Stop when we are better than 1e-6;
24
  double x,f ;
25
  double x1 = -0.5 ;
26
  double x2 = -10000.0 ; // if too close to x1=-0.5, fit will fail on some combinations of rad68 and rad80 (if rad68 and rad80 are within 5% of each other)
27
  double f1 = ( ( pow(a,x1)-1.0 ) / ( pow(b,x1) -1.0 ) ) - c ;
28
  double f2 = ( ( pow(a,x2)-1.0 ) / ( pow(b,x2) -1.0 ) ) - c ;
29
  int iter  = 0 ;
30
  while ( true )
31
  {
32
    x = x1 - f1 * (x1-x2)/(f1-f2) ;
33
    f = ( pow(a,x)-1.0 ) / ( pow(b,x)-1.0 ) - c ;
34
    iter += 1 ;
35
    if ( iter == 1 ) printf("\n");
36

    
37
    char xwarn[100]="" ;
38
    if ( x > 0.0 ) sprintf(xwarn,"%sx:%.8f%s", KRED, x, KNRM ) ;
39
    else           sprintf(xwarn,"x:%.8f"    , x             ) ;
40
    printf("              calcKingParameters(%7.3f %7.3f %7.3f %7.3f): iter:%d  diff:%.8f  %s  f1=%f  f2=%f...\n", rad68, rad80, sigma, gamma, iter, fabs(f), xwarn, f1, f2 ) ;
41

    
42
    if ( fabs(f) < 1.0e-6 )
43
    {
44
      //printf("              calcKingParameters(%7.3f %7.3f %7.3f %7.3f): Warning, breaking!...\n", rad68, rad80, sigma, gamma ) ;
45
      break ;
46
    }
47
    else
48
    {
49
      f2 = f1 ;
50
      x2 = x1 ;
51
      f1 = f  ;
52
      x1 = x  ;
53
    }
54

    
55
    // compute gamma
56
    if ( x < 0.0 )
57
    {
58
      gamma = 1.0 - (1.0/x) ;
59
    }
60
    else
61
    {
62
      gamma = 1.0 ;
63
      //printf("              calcKingParameters(%7.3f %7.3f %7.3f %7.3f): Warning, x(%7.4f) >= 0, setting gamma to 1...\n", rad68, rad80, sigma, gamma, x ) ;
64
    }
65

    
66
    // compute sigma
67
    double denom = 2.0 * gamma * ( pow(b,x)-1.0 ) ;
68
    if ( denom > 0.0 )
69
    {
70
      sigma = rad68 * sqrt(1.0/denom) ;
71
    }
72
    else
73
    {
74
      //printf("              calcKingParameters(%7.3f %7.3f %7.3f %7.3f): Warning, first denom is 0, attempting 2nd method...\n", rad68, rad80, sigma, gamma ) ;
75
      denom = 2.0 * gamma * (pow(b,x)-1.0) ;
76
      if ( denom > 0.0 )
77
      {
78
        sigma = rad80 * sqrt(1.0/denom) ;
79
      }
80
      else
81
      {
82
        //printf("              calcKingParameters(%7.3f %7.3f %7.3f %7.3f): Warning, denom is still 0.0, setting g/s to 0s...\n", rad68, rad80, sigma, gamma ) ;
83
        gamma = 0.0 ;
84
        sigma = 0.0 ;
85
        return 0 ;
86
      }
87
    }
88
  }
89

    
90
  return 0 ;
91
}
92