Flan
r8butil.h
Go to the documentation of this file.
1 //$ nobt
2 //$ nocpp
3 
16 #ifndef R8BUTIL_INCLUDED
17 #define R8BUTIL_INCLUDED
18 
19 #include "r8bbase.h"
20 
21 namespace r8b {
22 
30 inline double convertResponseToLog( const double re, const double im )
31 {
32  return( 4.34294481903251828 * log( re * re + im * im + 1e-100 ));
33 }
34 
49 inline void updateScanStep( double& step, const double curg,
50  double& prevg_log, const double prec, const double maxstep,
51  const double minstep = 1e-11 )
52 {
53  double curg_log = 4.34294481903251828 * log( curg + 1e-100 );
54  curg_log += ( prevg_log - curg_log ) * 0.7;
55 
56  const double slope = fabs( curg_log - prevg_log );
57  prevg_log = curg_log;
58 
59  if( slope > 0.0 )
60  {
61  step /= prec * slope;
62  step = max( min( step, maxstep ), minstep );
63  }
64 }
65 
84 inline void findFIRFilterResponseMinLtoR( const double* const flt,
85  const int fltlen, double& ming, double& minth, const double thend )
86 {
87  const double maxstep = minth * 2e-3;
88  double curth = minth;
89  double re;
90  double im;
91  calcFIRFilterResponse( flt, fltlen, M_PI * curth, re, im );
92  double prevg_log = convertResponseToLog( re, im );
93  double step = 1e-11;
94 
95  while( true )
96  {
97  curth += step;
98 
99  if( curth > thend )
100  {
101  break;
102  }
103 
104  calcFIRFilterResponse( flt, fltlen, M_PI * curth, re, im );
105  const double curg = re * re + im * im;
106 
107  if( curg > ming )
108  {
109  ming = curg;
110  minth = curth;
111  break;
112  }
113 
114  ming = curg;
115  minth = curth;
116 
117  updateScanStep( step, curg, prevg_log, 0.31, maxstep );
118  }
119 }
120 
140 inline void findFIRFilterResponseMaxLtoR( const double* const flt,
141  const int fltlen, double& maxg, double& maxth, const double thend )
142 {
143  const double maxstep = maxth * 1e-4;
144  double premaxth = maxth;
145  double premaxg = maxg;
146  double postmaxth = maxth;
147  double postmaxg = maxg;
148 
149  double prevth = maxth;
150  double prevg = maxg;
151  double curth = maxth;
152  double re;
153  double im;
154  calcFIRFilterResponse( flt, fltlen, M_PI * curth, re, im );
155  double prevg_log = convertResponseToLog( re, im );
156  double step = 1e-11;
157 
158  bool WasPeak = false;
159  int AfterPeakCount = 0;
160 
161  while( true )
162  {
163  curth += step;
164 
165  if( curth > thend )
166  {
167  break;
168  }
169 
170  calcFIRFilterResponse( flt, fltlen, M_PI * curth, re, im );
171  const double curg = re * re + im * im;
172 
173  if( curg > maxg )
174  {
175  premaxth = prevth;
176  premaxg = prevg;
177  maxg = curg;
178  maxth = curth;
179  WasPeak = true;
180  AfterPeakCount = 0;
181  }
182  else
183  if( WasPeak )
184  {
185  if( AfterPeakCount == 0 )
186  {
187  postmaxth = curth;
188  postmaxg = curg;
189  }
190 
191  if( AfterPeakCount == 5 )
192  {
193  // Perform 2 approximate binary searches.
194 
195  int k;
196 
197  for( k = 0; k < 2; k++ )
198  {
199  double l = ( k == 0 ? premaxth : maxth );
200  double curgl = ( k == 0 ? premaxg : maxg );
201  double r = ( k == 0 ? maxth : postmaxth );
202  double curgr = ( k == 0 ? maxg : postmaxg );
203 
204  while( true )
205  {
206  const double c = ( l + r ) * 0.5;
207  calcFIRFilterResponse( flt, fltlen, M_PI * c,
208  re, im );
209 
210  const double curg = re * re + im * im;
211 
212  if( curgl > curgr )
213  {
214  r = c;
215  curgr = curg;
216  }
217  else
218  {
219  l = c;
220  curgl = curg;
221  }
222 
223  if( r - l < 1e-11 )
224  {
225  if( curgl > curgr )
226  {
227  maxth = l;
228  maxg = curgl;
229  }
230  else
231  {
232  maxth = r;
233  maxg = curgr;
234  }
235 
236  break;
237  }
238  }
239  }
240 
241  break;
242  }
243 
244  AfterPeakCount++;
245  }
246 
247  prevth = curth;
248  prevg = curg;
249 
250  updateScanStep( step, curg, prevg_log, 1.0, maxstep );
251  }
252 }
253 
270 inline void findFIRFilterResponseLevelRtoL( const double* const flt,
271  const int fltlen, const double maxg, double& th, const double thend )
272 {
273  // Perform exact binary search.
274 
275  double l = thend;
276  double r = th;
277 
278  while( true )
279  {
280  const double c = ( l + r ) * 0.5;
281 
282  if( r - l < 1e-14 )
283  {
284  th = c;
285  break;
286  }
287 
288  double re;
289  double im;
290  calcFIRFilterResponse( flt, fltlen, M_PI * c, re, im );
291  const double curg = re * re + im * im;
292 
293  if( curg > maxg )
294  {
295  l = c;
296  }
297  else
298  {
299  r = c;
300  }
301  }
302 }
303 
304 } // namespace r8b
305 
306 #endif // R8BUTIL_INCLUDED
void updateScanStep(double &step, const double curg, double &prevg_log, const double prec, const double maxstep, const double minstep=1e-11)
An utility function that performs frequency response scanning step update based on the current magnit...
Definition: r8butil.h:49
void findFIRFilterResponseMinLtoR(const double *const flt, const int fltlen, double &ming, double &minth, const double thend)
Function locates normalized frequency at which the minimum filter gain is reached.
Definition: r8butil.h:84
double convertResponseToLog(const double re, const double im)
Definition: r8butil.h:30
The "base" inclusion file with basic classes and functions.
void calcFIRFilterResponse(const double *flt, int fltlen, const double th, double &re0, double &im0, const int fltlat=0)
Function calculates frequency response of the specified FIR filter at the specified circular frequenc...
Definition: r8bbase.h:824
void findFIRFilterResponseMaxLtoR(const double *const flt, const int fltlen, double &maxg, double &maxth, const double thend)
Function locates normalized frequency at which the maximal filter gain is reached.
Definition: r8butil.h:140
T max(const T &v1, const T &v2)
Definition: r8bbase.h:1134
T min(const T &v1, const T &v2)
Definition: r8bbase.h:1118
#define M_PI
The macro equals to "pi" constant, fits 53-bit floating point mantissa.
Definition: r8bbase.h:94
void findFIRFilterResponseLevelRtoL(const double *const flt, const int fltlen, const double maxg, double &th, const double thend)
Function locates normalized frequency at which the specified maximum filter gain is reached...
Definition: r8butil.h:270
The "r8brain-free-src" library namespace.
Definition: CDSPBlockConvolver.h:21