GLAMERDOC++
Gravitational Lensing Code Library
Loading...
Searching...
No Matches
utilities.h
1/*
2 * utilities.h
3 *
4 */
5
6#ifndef UTILITIES_H_
7#define UTILITIES_H_
8
9#include <vector>
10#include <math.h>
11#include <algorithm>
12#include <functional>
13#include <string>
14#include <stdexcept>
15#include <iostream>
16#include <sstream>
17
18
19#ifndef PosType_declare
20#define PosType_declare
21typedef double PosType;
22typedef unsigned long ULONG;
23#endif
24
25template <typename T> int sgn(T val) {
26 return (T(0) < val) - (val < T(0));
27}
28
29template <class T>
30inline T min(T x,T y){
31 return (x < y) ? x : y;
32};
33template <class T>
34inline T max(T x,T y){
35 return (x > y) ? x : y;
36};
37
38
39namespace Utilities{
40
41 inline void print_date(){
42 time_t now = time(0);
43 struct tm date = *localtime(&now);
44 std::cout << date.tm_hour << ":" << date.tm_min << " " << date.tm_mday << "/" << date.tm_mon << "/" << date.tm_year + 1900 << std::endl;
45 }
46
47
48 const double nXbin=64.;
49
53 template <class T>
54 void fill_linear ( std::vector<T> &v, size_t n, T min, T max ){
55 v.resize ( n );
56 for ( size_t i = 0; i < n; i++ )
57 v[i] = min + (max - min) * T (i)/T (n-1);
58 }
59
63 template <class T>
64 void fill_logarithmic ( std::vector<T> &v, size_t n, T min, T max ){
65 v.resize (n);
66 for ( size_t i = 0; i < n; i++ )
67 v[i] = exp ( log (min) + ( log (max) - log (min) ) * T (i)/T (n-1) );
68 }
69
75 template <class T>
76 long locate (const std::vector<T> &v, const T x)
77 {
78 long n = v.size ();
79 if(n==0) return -1;
80
81 if (x == v[0])
82 return 0;
83 if (x == v[n-1])
84 return n-1;
85
86 long jl = -1;
87 long ju = n;
88 bool as = (v[n-1] >= v[0]);
89 while (ju-jl > 1)
90 {
91 long jm = (ju+jl)/2;
92 if ((x >= v[jm]) == as)
93 jl=jm;
94 else
95 ju=jm;
96 }
97
98 return jl;
99 }
105 template <class T,class F>
106 long locate (const std::vector<T> &v,F x,std::function<bool (F ,const T &)> less_than)
107 {
108 long n = v.size ();
109
110 if (less_than(x,v[0]))
111 return -1;
112 if (!less_than(x,v[n-1]))
113 return n-1;
114
115 long jl = -1;
116 long ju = n;
117
118
119 while (ju-jl > 1)
120 {
121 long jm = (ju+jl)/2;
122 if ( less_than(x,v[jm]) )
123 ju=jm;
124 else
125 jl=jm;
126 }
127
128 return jl;
129 }
130
131 template <class T>
132 void locate (T *v, unsigned long n, T x, unsigned long *index)
133 {
134 if (x == v[0]){
135 *index = 0;
136 return;
137 }
138 if (x == v[n-1]){
139 *index = n-1;
140 return;
141 }
142
143 long jl = -1;
144 long ju = n;
145 bool as = (v[n-1] >= v[0]);
146 while (ju-jl > 1)
147 {
148 long jm = (ju+jl)/2;
149 if ((x >= v[jm]) == as)
150 jl=jm;
151 else
152 ju=jm;
153 }
154
155 *index = jl;
156 return;
157 }
166 template<typename T>
167 size_t locate(const std::vector<T> &v
168 ,const std::vector<size_t> &sorted_index
169 ,T value
170 ,size_t &rank
171 ){
172 size_t n = v.size();
173
174 if(n<=1) return 0;
175
176 if(n != sorted_index.size() ){
177 std::cerr << "sorted_index is the wrong size." << std::endl;
178 throw std::invalid_argument("wrong size");
179 }
180
181 long imin=0,imax=v.size()-1;
182 double fmax = v[sorted_index[imax]];
183 double fmin = v[sorted_index[imin]];
184 if(fmin > fmax){
185 std::swap(imin,imax);
186 std::swap(fmin,fmax);
187 }
188
189 if(value <= fmin) return sorted_index[imin];
190 if(value >= fmax) return sorted_index[imax];
191
192 size_t icurrent = (imax+imin)/2;
193 double fcurrent = v[sorted_index[icurrent]];
194
195 while ( abs(imax-imin) > 1 ) {
196 if(fcurrent > value){
197 fmax = fcurrent;
198 imax = icurrent;
199 }else{
200 fmin = fcurrent;
201 imin = icurrent;
202 }
203 icurrent = (imax+imin)/2;
204 fcurrent = v[sorted_index[icurrent]];
205 }
206
207 rank=imin;
208 return sorted_index[imin];
209 }
210
212 template <class T>
213 size_t closest (const std::vector<T> &v, const T x)
214 {
215
216 int index = locate(v,x);
217 if(index == -1) return 0;
218 if(index == v.size()-1) return index;
219
220 return (x - v[index]) < (v[index+1] - x) ? index : index+1;
221 }
222
223
224 PosType InterpolateYvec(std:: vector<PosType> &x, std:: vector<PosType> &y,PosType xi);
225
226 PosType arctanh(PosType x);
227
228 PosType fmini(PosType a,PosType b);
229
230 PosType fmaxi(PosType a,PosType b);
231
233 template <typename T>
234 T median(std::vector<T> vec){
235 size_t size = vec.size();
236 if (size == 0){
237 // std:: cout << "median of an empty vector" << std:: endl;
238 return 0;
239 }
240 sort(vec.begin(), vec.end());
241 size_t mid = size/2;
242 return size % 2 == 0 ? (vec[mid] + vec[mid-1]) / 2 : vec[mid];
243 }
244
246 template <typename T>
247 void range(std::vector<T> vec,T &max,T &min){
248 if(vec.size() == 0){
249 max = min = NAN;
250 return;
251 }
252 max = min = vec[0];
253 for(T a : vec){
254 if(a > max) max = a;
255 if(a < min) min = a;
256 }
257 }
258
259
261 template <typename T>
262 void polintT(T xa[], T ya[], int n, T x, T *y, T *dy)
263 {
264 int i,m,ns=1;
265 T den,dif,dift,ho,hp,w;
266 T *c,*d;
267
268 dif=fabs(x-xa[1]);
269
270 c = new T[n+1];
271 d = new T[n+1];
272
273 for (i=1;i<=n;i++) {
274 if ( (dift=fabs(x-xa[i])) < dif) {
275 ns=i;
276 dif=dift;
277 }
278 c[i]=ya[i];
279 d[i]=ya[i];
280 }
281 *y=ya[ns--];
282 for (m=1;m<n;m++) {
283 for (i=1;i<=n-m;i++) {
284 ho=xa[i]-x;
285 hp=xa[i+m]-x;
286 w=c[i+1]-d[i];
287 if ( (den=ho-hp) == 0.0) throw std::runtime_error("Error in routine polint");
288 den=w/den;
289 d[i]=hp*den;
290 c[i]=ho*den;
291 }
292 *y += (*dy=(2*ns < (n-m) ? c[ns+1] : d[ns--]));
293 }
294 delete[] d;
295 delete[] c;
296 }
297
299 template <typename FunctorType,typename T = double>
300 T trapz(FunctorType &func, T a, T b, int n, T *s2)
301 {
302 T x,tnm,del,sum;
303 int it,j;
304
305 if (n == 1) {
306 return (*s2=0.5*(b-a)*( func(a) + func(b) ));
307 } else {
308
309 for (it=1,j=1;j<n-1;j++) it <<= 1;
310 tnm=it;
311 del=(b-a)/tnm;
312 x=a+0.5*del;
313 for (sum=0.0,j=1;j<=it;j++,x+=del) sum += func(x);
314 *s2=0.5*(*s2+(b-a)*sum/tnm);
315
316 return *s2;
317 }
318 }
319
320 template <typename FunctorType,typename T = double>
322 FunctorType func
323 ,T a
324 ,T b
325 ,T tols
326 )
327 {
328 const int JMAX = 34,K=6;
329 const int JMAXP = JMAX+1;
330
331 if(a==b) return 0;
332
333 T ss,dss;
334 T s2[JMAXP],h2[JMAXP+1];
335 T ss2=0;
336
337 h2[1]=1.0;
338 for (int j=1;j<=JMAX;j++) {
339 s2[j] = Utilities::trapz<FunctorType,T>(func,a,b,j,&ss2);
340
341 if (j>=K) {
342 Utilities::polintT<T>(&h2[j-K],&s2[j-K],K,0.0,&ss,&dss);
343 if(fabs(dss) <= tols*fabs(ss)) return ss;
344 }
345 h2[j+1]=0.25*h2[j];
346 }
347 std::cout << "s2= "; for(int j=1;j<=JMAX;j++) std::cout << s2[j] << " ";
348 std::cout << std::endl << "Too many steps in routine nintegrate<>\n";
349 throw std::invalid_argument("Too many steps in routine nintegrate<>");
350 return 0.0;
351 }
352
429 template <typename FunctorType,typename T = double>
430 T nintegrate(
431 FunctorType &func
432 ,T a
433 ,T b
434 ,T tols
435 )
436 {
437 const int JMAX = 34,K=6;
438 const int JMAXP = JMAX+1;
439
440 T ss,dss;
441 T s2[JMAXP],h2[JMAXP+1];
442 T ss2=0;
443
444 h2[1]=1.0;
445 for (int j=1;j<=JMAX;j++) {
446 s2[j] = Utilities::trapz<FunctorType,T>(func,a,b,j,&ss2);
447 if (j>=K) {
448 Utilities::polintT<T>(&h2[j-K],&s2[j-K],K,0.0,&ss,&dss);
449 if(fabs(dss) <= tols*fabs(ss)) return ss;
450 }
451 h2[j+1]=0.25*h2[j];
452 }
453 std::cout << "s2= "; for(int j=1;j<=JMAX;j++) std::cout << s2[j] << " ";
454 std::cout << std::endl << "Too many steps in routine nintegrate<>\n";
455 throw std::invalid_argument("Too many steps in routine nintegrate<>");
456 return 0.0;
457 }
458
460 template <class F,typename T>
461 double bisection_search(
462 F &func
463 ,T fvalue
464 ,T x1
465 ,T x2
466 ,T xacc
467 ){
468 int Nmax = 100000000,count=0;
469
470 T f1 = func(x1) - fvalue;
471 T f2 = func(x2) - fvalue;
472 if( f1/f2 > 0 ){
473 throw std::invalid_argument("not bracketed");
474 }
475 while( fabs(x1-x2) > xacc && count < Nmax ){
476 ++count;
477 T xnew = (x1 + x2)/2;
478 T fnew = func(xnew) - fvalue;
479 if( fnew/f1 < 0 ){
480 x2 = xnew;
481 f2 = fnew;
482 }else{
483 x1 = xnew;
484 f1 = fnew;
485 }
486 }
487
488 return (x1+x2)/2;
489 }
490
492 namespace stats{
493 //**********************************************************
494 //*** some routines for statistics of vectors **************
495 //**********************************************************
497 template <typename T>
498 void vector_maxmin(const std::vector<T> &v,T &max,T &min ){
499
500 max = min = v[0];
501 for(T d : v){
502 max = (max > d) ? max : d;
503 min = (min < d) ? min : d;
504 }
505 }
506
508 template <typename T>
509 T vector_mean(const std::vector<T> &v){
510 T ans = 0;
511 for(T a : v) ans += a;
512 return ans/v.size();
513 }
514
516 template <typename T>
517 T vector_variance(const std::vector<T> &v){
518 T m = vector_mean(v);
519 T ans = 0;
520 for(T a : v) ans += (a - m)*(a - m);
521 return ans/(v.size() - 1);
522 }
523
524 // Pearson's correlation coefficient
525 template <typename T>
526 T vector_correlation(const std::vector<T> &v1,const std::vector<T> &v2){
527 size_t N = v1.size();
528 if(v2.size() != N){
529 throw std::invalid_argument("vectors are not the same size");
530 }
531
532 T m1 = vector_mean(v1);
533 T m2 = vector_mean(v2);
534 T var1 = vector_variance(v1);
535 T var2 = vector_variance(v2);
536
537 T ans = 0;
538 for(size_t i = 0 ; i < N ; ++i){
539 ans += (v1[i]-m1)*(v2[i]-m2);
540 }
541 ans /= (N-1)*sqrt(var1*var2);
542
543 return ans;
544 }
545
546 template <typename T>
547 class Accumulater{
548 public:
549 Accumulater(int size):
550 sum(0),count(0),N(size)
551 {
552 products.resize(N*N,0);
553 sums.resize(N,0);
554 }
555
557 void add(const std::vector<T> &v){
558 if(v.size() != N ) throw std::invalid_argument("wrong size vector");
559 for(T a : v) sum += a;
560
561 for(size_t i = 0 ; i < N ; ++i){
562 sums[i] += v[i];
563 for(size_t j = 0 ; j < N ; ++j){
564 products[j + i*N] += v[i]*v[j];
565 }
566 }
567 ++count;
568 }
569
571 void add(T a){
572 if(1 != N ) throw std::invalid_argument("wrong size vector");
573 sum += a;
574
575 sums[0] += a;
576 products[0] += a*a;
577 ++count;
578 }
579
581 T mean(){
582 T sum = 0;
583 for(auto d : sums) sum += d;
584 return sum/count/N;
585 }
587 T mean(size_t i){return sums[i]/count;}
588 void means(std::vector<T> &mm){
589 mm = sums;
590 for(T &m : mm) m /= count;
591 }
592
594 T covariance(size_t i,size_t j){
595 return (products[j + i*N] - sums[i]*sums[j]/count)/(count - 1);
596 }
597
598 void variances(std::vector<T> &mm){
599 mm.resize(N);
600 for(size_t i=0 ; i < N ; ++i){
601 mm[i] = covariance(i,i);
602 }
603 }
604
605 T ave_variances(){
606 T ans = 0;
607 for(size_t i=0 ; i < N ; ++i){
608 ans += covariance(i,i);
609 }
610 return ans/N;
611 }
612
614 void cov_matrix(std::vector<T> &mm){
615 mm.resize(N*N);
616 for(size_t i = 0 ; i<N ; ++i){
617 T avi = sums[i]/count;
618 for(size_t j = i ; j<N ; ++j){
619 size_t k = i + j*N;
620 mm[k] = (products[k] - avi*sums[j])/(count - 1);
621 mm[j + i*N] = mm[k];
622 }
623 }
624 }
625
626 void cov_matrix_normalized(std::vector<T> &mm){
627 std::vector<T> var;
628 variances(var);
629
630 mm.resize(N*N);
631 for(size_t i = 0 ; i<N ; ++i){
632 T avi = sums[i]/count;
633 for(size_t j = i ; j<N ; ++j){
634 size_t k = i + j*N;
635 mm[k] = (products[k] - avi*sums[j])/(count - 1)/sqrt( var[i]*var[j] );
636 mm[j + i*N] = mm[k];
637 }
638 }
639 }
640
641 private:
642 T sum;
643 std::vector<T> products;
644 std::vector<T> sums;
645 size_t count;
646 size_t N;
647 };
648
649 }
650}
651#endif /* UTILITIES_H_ */
Definition utilities.h:39
T median(std::vector< T > vec)
find median of vector
Definition utilities.h:234
void fill_linear(std::vector< T > &v, size_t n, T min, T max)
Definition utilities.h:54
void fill_logarithmic(std::vector< T > &v, size_t n, T min, T max)
Definition utilities.h:64
T trapz(FunctorType &func, T a, T b, int n, T *s2)
used in trapizoidal integral
Definition utilities.h:300
void polintT(T xa[], T ya[], int n, T x, T *y, T *dy)
interpolation
Definition utilities.h:262
long locate(const std::vector< T > &v, const T x)
Definition utilities.h:76
size_t closest(const std::vector< T > &v, const T x)
Returns the index of the element of v that is closest to x. v must be sorted.
Definition utilities.h:213
void range(std::vector< T > vec, T &max, T &min)
find the maximum and minimum of a vector
Definition utilities.h:247
PosType InterpolateYvec(std::vector< PosType > &x, std::vector< PosType > &y, PosType xi)
Definition utilities.cpp:36
T nintegrateF(FunctorType func, T a, T b, T tols)
Definition utilities.h:321