NPL
Neurological Programs and Libraries
basic_functions.h
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright 2014 Micah C Chambers (micahc.vt@gmail.com)
3  *
4  * NPL is free software: you can redistribute it and/or modify it under the
5  * terms of the BSD 2-Clause License available in LICENSE or at
6  * http://opensource.org/licenses/BSD-2-Clause
7  *
8  * @file basic_functions.h These are simple in-lineable functions for various
9  * purposes, including bounding indexes, and window functions
10  *
11  *****************************************************************************/
12 
13 #ifndef BASIC_FUNCTIONS_H
14 #define BASIC_FUNCTIONS_H
15 
16 #include <cstdlib>
17 #include <cmath>
18 #include <cassert>
19 #include <list>
20 
21 #include "macros.h"
22 
23 namespace npl {
24 
25 /**********************************************************
26  * Functions for dealing with boundaries (wrap and clamp)
27  **********************************************************/
28 
40 template <typename T>
41 inline T clamp(T inf, T sup, T v)
42 {
43  return std::min(sup, std::max(inf, v));
44 }
45 
58 template <typename T>
59 inline T wrap(T inf, T sup, T v)
60 {
61  T len = sup-inf+1;
62  T vtmp = v-inf;
63  T out = vtmp < 0 ? sup-((-vtmp-1)%len) : inf+(vtmp%len);
64  return out;
65 }
66 
67 /**********************************************************
68  * Windows/Kernels
69  **********************************************************/
70 
79 inline
80 double rectWindow(double x, double a)
81 {
82  if(fabs(x) < a)
83  return 1;
84  else
85  return 0;
86 }
87 
96 inline
97 double sincWindow(double x, double a)
98 {
99  if(x == 0)
100  return 1;
101  else if(fabs(x) < a)
102  return sin(M_PI*x/a)/(M_PI*x/a);
103  else
104  return 0;
105 }
106 
116 inline
117 double freqGaussian(double x, double sd)
118 {
119  return exp(-x*x*2*M_PI*M_PI*sd*sd);
120 }
121 
122 /*
123  * @brief Sinc function centered at 0, with radius a, range should be = 2a.
124  * Zero < -a, > a
125  *
126  * @param x distance from center
127  * @param a radius
128  *
129  * @return weight
130  */
131 inline
132 double hammingWindow(double x, double a)
133 {
134  const double alpha = .54;
135  const double beta = 1-alpha;
136  if(fabs(x) < a)
137  return alpha-beta*cos(M_PI*x/a+M_PI);
138  else
139  return 0;
140 }
141 
142 /*
143  * @brief Sinc function centered at 0, with radius a, range should be = 2a.
144  * Zero < -a, > a
145  *
146  * @param x distance from center
147  * @param a radius
148  *
149  * @return weight
150  */
151 inline
152 double welchWindow(double x, double a)
153 {
154  if(fabs(x) < a) {
155  return 1-x*x/(a*a);
156  } else
157  return 0;
158 }
159 
160 /*
161  * @brief Sinc function centered at 0, with radius a, range should be = 2a.
162  * Zero < -a, > a
163  *
164  * @param x distance from center
165  * @param a radius
166  *
167  * @return weight
168  */
169 inline
170 double hannWindow(double x, double a)
171 {
172  const double alpha = .50;
173  const double beta = 1-alpha;
174  if(fabs(x) < a)
175  return alpha-beta*cos(M_PI*x/a+M_PI);
176  else
177  return 0;
178 }
179 
188 inline
189 double lanczosKern(double x, double a)
190 {
191  if(x == 0)
192  return 1;
193  // a*Sin[Pi*x]*Sin[Pi*x/a]/(Pi*Pi*x*x)
194  double v = a*sin(M_PI*x)*sin(M_PI*x/a)/(M_PI*M_PI*x*x);
195  assert(v <= 1.001 && v >= -1.0001);
196  return v;
197 }
198 
207 inline
208 double dLanczosKern(double x, double a)
209 {
210  if(x == 0)
211  return 0;
212  double v = (M_PI*x*((cos((M_PI*x)/a)*sin(M_PI*x)) +
213  (a*sin((M_PI*x)/a)*cos(M_PI*x))) -
214  (2*a*sin((M_PI*x)/a)*sin(M_PI*x)))/(M_PI*M_PI*x*x*x);
215  assert(v >= -2 && v <= 10);
216  return v;
217 
218 }
219 
220 /* Linear Kernel Sampling */
221 inline
222 double linKern(double x, double a)
223 {
224  return fabs(1-fmin(1,fabs(x/a)))/a;
225 }
226 
227 /* Linear Kernel Sampling */
228 inline
229 double dLinKern(double x, double a)
230 {
231  if(x < -a || x > a)
232  return 0;
233  if(x < 0)
234  return 1/a;
235  else
236  return -1/a;
237 }
238 
239 /******************************************************
240  * Third Order BSpline kernel. X is distance from 0
241  ****************************************************/
242 
250 inline
251 double B3kern(double x)
252 {
253  switch((int)floor(x)) {
254  case -2:
255  return 4./3. + 2.*x + x*x + x*x*x/6.;
256  break;
257  case -1:
258  return 2./3. - x*x - x*x*x/2.;
259  break;
260  case 0:
261  return 2./3. - x*x + x*x*x/2.;
262  break;
263  case 1:
264  return 4./3. - 2*x + x*x - x*x*x/6.;
265  break;
266  default:
267  return 0;
268  break;
269  }
270 }
271 
280 inline
281 double B3kern(double x, double r)
282 {
283  return B3kern(x*2/r)*2/r;
284 }
285 
293 inline
294 double dB3kern(double x)
295 {
296  switch((int)floor(x)) {
297  case -2:
298  return (4+4*x+x*x)/2.;
299  case -1:
300  return -(4*x + 3*x*x)/2.;
301  case 0:
302  return (-4*x + 3*x*x)/2.;
303  case 1:
304  return -(x*x - 4*x + 4)/2.;
305  default:
306  return 0;
307  }
308  return 0;
309 }
310 
319 inline
320 double dB3kern(double x, double r)
321 {
322  return dB3kern(x*2/r)*4/(r*r);
323 }
324 
332 inline
333 double ddB3kern(double x)
334 {
335  switch((int)floor(x)) {
336  case -2:
337  return 2 + x;
338  case -1:
339  return -2 - 3*x;
340  case 0:
341  return -2 + 3*x;
342  case 1:
343  return 2 - x;
344  default:
345  return 0;
346  }
347  return 0;
348 }
349 
358 inline
359 double ddB3kern(double x, double r)
360 {
361  return ddB3kern(x*2/r)*8/(r*r*r);
362 }
363 
371 inline
372 double cot(double v)
373 {
374  return 1./tan(v);
375 }
376 
384 inline
385 double csc(double v)
386 {
387  return 1./sin(v);
388 }
389 
397 inline
398 double sec(double v)
399 {
400  return 1./cos(v);
401 }
402 
403 
404 inline
405 double degToRad(double rad)
406 {
407  return rad*M_PI/180.;
408 }
409 
410 inline
411 double radToDeg(double rad)
412 {
413  return rad*180./M_PI;
414 }
415 
423 inline
424 int hob(int num)
425 {
426  if (!num)
427  return 0;
428 
429  int ret = 1;
430 
431  while(num >>= 1)
432  ret <<= 1;
433 
434  return ret;
435 }
436 
437 
445 inline
446 int64_t round2(int64_t in)
447 {
448  int64_t just_hob = hob(in);
449  if(just_hob == in)
450  return in;
451  else
452  return (just_hob<<1);
453 }
454 
462 inline
463 std::list<int64_t> factor(int64_t f)
464 {
465  std::list<int64_t> factors;
466  for(int64_t ii = 2; ii<=f; ii++) {
467  while(f % ii == 0) {
468  f = f/ii;
469  factors.push_back(ii);
470  }
471  }
472 
473  return factors;
474 }
475 
484 inline
485 int64_t round357(int64_t in)
486 {
487  // make it odd
488  if(in %2 == 0)
489  in++;
490 
491  bool acceptable = false;
492  while(!acceptable) {
493  acceptable = true;
494  in += 2;
495 
496  // check the factors
497  auto factors = factor(in);
498  for(auto f : factors) {
499  if(f != 3 && f != 5 && f != 7) {
500  acceptable = false;
501  break;
502  }
503  }
504  }
505 
506  return in;
507 }
508 
531 template <typename T = int, int MAXDIM=10>
532 struct Counter
533 {
534  T sz[MAXDIM];
536  size_t ndim;
537 
544  Counter(size_t dim)
545  {
546  if(dim > MAXDIM)
547  throw INVALID_ARGUMENT("Dimension "+std::to_string(dim)+">="+
548  std::to_string(MAXDIM));
549  ndim = dim;
550  for(size_t dd=0; dd<ndim; dd++)
551  pos[dd] = 0;
552  };
553 
560  Counter(size_t dim, const T* stop)
561  {
562  if(dim > MAXDIM)
563  throw INVALID_ARGUMENT("Dimension "+std::to_string(dim)+">="+
564  std::to_string(MAXDIM));
565 
566  for(size_t dd=0; dd<dim; dd++) {
567  sz[dd] = stop[dd];
568  pos[dd] = 0;
569  }
570  ndim = dim;
571  };
572 
581  bool advance(bool rorder = false) {
582  if(rorder) {
583  for(int dd=0; dd<(int)ndim; dd++) {
584  pos[dd]++;
585  if(pos[dd] == sz[dd])
586  pos[dd] = 0;
587  else
588  return true;
589  }
590  } else {
591  for(int dd=ndim-1; dd>= 0; dd--) {
592  pos[dd]++;
593  if(pos[dd] == sz[dd])
594  pos[dd] = 0;
595  else
596  return true;
597  }
598  }
599 
600  return false;
601  };
602 };
603 
604 } // npl
605 
606 #endif //BASIC_FUNCTIONS_H
#define INVALID_ARGUMENT(EXP)
Definition: macros.h:18
Definition: accessors.h:29
Counter(size_t dim, const T *stop)
Initialize counter with the specified dimension and stop point.
bool advance(bool rorder=false)
Advance through ND-counter. 0,0,0 to 0,0,1 and so on. If roder is true then this will start at 0...
Very basic counter that iterates over an ND region.
double freqGaussian(double x, double sd)
Gaussian function in the frequency domain. Note that the standard deviation is in the time domain...
double hammingWindow(double x, double a)
double welchWindow(double x, double a)
double dLanczosKern(double x, double a)
Derivative of lanczos kernel with respect to x.
T clamp(T inf, T sup, T v)
Clamps value to range of [inf, sup]. Values outside will be pulled to either sup or inf...
int64_t round2(int64_t in)
Round up to the nearest power of 2.
std::list< int64_t > factor(int64_t f)
Provides a list of the prime-fractors of the input number.
double dB3kern(double x)
3rd order B-Spline derivative, radius 2 [-2,2]
double sincWindow(double x, double a)
Sinc function centered at 0, with radius a, range should be = 2a.
double hannWindow(double x, double a)
double radToDeg(double rad)
int64_t round357(int64_t in)
Rounds a number up to the nearest number that can be broken down into 3,5,7.
double degToRad(double rad)
double linKern(double x)
Definition: accessors.h:867
double lanczosKern(double x, double a)
Derivative of lanczos kernel with respect to x.
double ddB3kern(double x)
3rd order B-Spline, 2nd derivative, radius 2 [-2,2]
double rectWindow(double x, double a)
Rectangle function centered at 0, with radius a, range should be = 2a.
double dLinKern(double x, double a)
const size_t MAXDIM
Defines the maximum supported dimension by image, used for stack-allocations.
Definition: ndarray.h:46
double B3kern(double x)
3rd order B-Spline, radius 2 [-2,2]
int hob(int num)
Highest order bit.
double sec(double v)
Secand function.
Counter(size_t dim)
Default constructor. Just sizes pos to 0. dim is the number of dimensions to use/iterate over...
double cot(double v)
Cotangent function.
T wrap(T inf, T sup, T v)
Wraps and index based on the range [inf, sup] (when v is outside that) range. Thus inf = 1...
double csc(double v)
Cosecant function.