Blame view

rts/sbessel.h 2.62 KB
f1402849   dmayerich   renewed commit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
  #ifndef RTS_SBESSEL_H
  #define RTS_SBESSEL_H
  #include <math.h>
  
  
  namespace rts{
  
  #define RTS_BESSEL_CONVERGENCE_FLOAT	0.00045
  
  template <typename T>
  CUDA_CALLABLE void sbesselj(int n, rtcomplex<T> x, rtcomplex<T>* j)
  {
      //compute the first bessel function
      if(n >= 0)
          j[0] = sin(x) / x;
  
      //compute the second bessel function
      if(n >= 1)
          j[1] = j[0] / x - cos(x) / x;
  
      //use the recurrence relation to compute the rest
      for(int i = 2; i <= n; i++)
      {
          j[i] = ( (2 * i - 1) / x ) * j[i-1] - j[i-2];
      }
  
      //if x = 0, deal with the degenerate case
      /*if( isnan(j[0].r) )
      {
          j[0] = (T)1.0;
          for(int i = 1; i<=n; i++)
              j[i] = (T)0.0;
      }*/
  }
  
  template <typename T>
  CUDA_CALLABLE void sbessely(int n, rtcomplex<T> x, rtcomplex<T>* y)
  {
      //compute the first bessel function
      if(n >= 0)
          y[0] = -cos(x) / x;
  
      //compute the second bessel function
      if(n >= 1)
          y[1] = y[0] / x - sin(x) / x;
  
      //use the recurrence relation to compute the rest
      for(int i = 2; i <= n; i++)
      {
          y[i] = ( (2 * i - 1) / x ) * y[i-1] - y[i-2];
      }
  
  }
  
  //spherical Hankel functions of the first kind
  template <typename T>
  CUDA_CALLABLE void sbesselh1(int n, rtcomplex<T> x, rtcomplex<T>* h)
  {
      //compute j_0 and j_1
      rtcomplex<T> j[2];
      sbesselj(1, x, j);
  
      //compute y_0 and y_1
      rtcomplex<T> y[2];
      sbessely(1, x, y);
  
      //compute the first-order Hhankel function
      if(n >= 0)
          h[0] = j[0] + y[0].imul();
  
      //compute the second bessel function
      if(n >= 1)
          h[1] = j[1] + y[1].imul();
  
      //use the recurrence relation to compute the rest
      for(int i = 2; i <= n; i++)
      {
          h[i] = ( (2 * i - 1) / x ) * h[i-1] - h[i-2];
      }
  }
  
  template <typename T>
  CUDA_CALLABLE void init_sbesselj(T x, T* j)
  {
  	/*if(x < EPSILON_FLOAT)
  	{
  		j[0] = (T)1;
  		j[1] = (T)0;
  		return;
  	}*/
  	
  	//compute the first 2 bessel functions
  	j[0] = std::sin(x) / x;
  
  	j[1] = j[0] / x - std::cos(x) / x;
  
  	//deal with the degenerate case of x = 0
  	/*if(isnan(j[0]))
  	{
  		j[0] = (T)1;
  		j[1] = (T)0;
  	}*/
  	
  }
  
  template <typename T>
  CUDA_CALLABLE void shift_sbesselj(int n, T x, T* j)//, T stability = 1.4)
  {
  
  	/*if(x < EPSILON_FLOAT)
  	{
  		j[0] = j[1];
  		j[1] = (T)0;
  		return;
  	}*/
  
  	T jnew;
  
  	//compute the next (order n) Bessel function
  	jnew = ((2 * n - 1) * j[1])/x - j[0];
  
  	//if(n > stability*x)
  	if(n > x)
  		if(jnew < RTS_BESSEL_CONVERGENCE_FLOAT)
  			jnew = (T)0;
  
  	//deal with the degenerate case of x = 0
  	//if(isnan(jnew))
  	//	jnew = (T)0;
  
  	//shift and add the new value to the array
  	j[0] = j[1];
  	j[1] = jnew;
  }
  
  
  
  }   //end namespace rts
  
  
  
  #endif