StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
nrutil.cxx
1 /* CAUTION: This is the ANSI C (only) version of the Numerical Recipes
2  utility file nrutil.c. Do not confuse this file with the same-named
3  file nrutil.c that is supplied in the same subdirectory or archive
4  as the header file nrutil.h. *That* file contains both ANSI and
5  traditional K&R versions, along with #ifdef macros to select the
6  correct version. *This* file contains only ANSI C. */
7 
8 #include "nrutil.h"
9 
10 void numericalRecipes::nrerror(const char error_text[])
11 /* Numerical Recipes standard error handler */
12 {
13  fprintf(stderr,"Numerical Recipes run-time error...\n");
14  fprintf(stderr,"%s\n",error_text);
15  fprintf(stderr,"...now exiting to system...\n");
16  exit(1);
17 }
18 
19 float *numericalRecipes::vector(long nl, long nh)
20 /* allocate a float nrvector with subscript range v[nl..nh] */
21 {
22  float *v;
23 
24  v=(float *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(float)));
25  if (!v) nrerror("allocation failure in nrvector()");
26  return v-nl+NR_END;
27 }
28 
29 int *numericalRecipes::ivector(long nl, long nh)
30 /* allocate an int nrvector with subscript range v[nl..nh] */
31 {
32  int *v;
33 
34  v=(int *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(int)));
35  if (!v) nrerror("allocation failure in inrvector()");
36  return v-nl+NR_END;
37 }
38 
39 double *numericalRecipes::dvector(long nl, long nh)
40 /* allocate a double nrvector with subscript range v[nl..nh] */
41 {
42  double *v;
43 
44  v=(double *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(double)));
45  if (!v) nrerror("allocation failure in dnrvector()");
46  return v-nl+NR_END;
47 }
48 
49 float **numericalRecipes::matrix(long nrl, long nrh, long ncl, long nch)
50 /* allocate a float matrix with subscript range m[nrl..nrh][ncl..nch] */
51 {
52  long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
53  float **m;
54 
55  /* allocate pointers to rows */
56  m=(float **) malloc((size_t)((nrow+NR_END)*sizeof(float*)));
57  if (!m) nrerror("allocation failure 1 in matrix()");
58  m += NR_END;
59  m -= nrl;
60 
61  /* allocate rows and set pointers to them */
62  m[nrl]=(float *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(float)));
63  if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
64  m[nrl] += NR_END;
65  m[nrl] -= ncl;
66 
67  for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
68 
69  /* return pointer to array of pointers to rows */
70  return m;
71 }
72 
73 double **numericalRecipes::dmatrix(long nrl, long nrh, long ncl, long nch)
74 /* allocate a double matrix with subscript range m[nrl..nrh][ncl..nch] */
75 {
76  long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
77  double **m;
78 
79  /* allocate pointers to rows */
80  m=(double **) malloc((size_t)((nrow+NR_END)*sizeof(double*)));
81  if (!m) nrerror("allocation failure 1 in matrix()");
82  m += NR_END;
83  m -= nrl;
84 
85  /* allocate rows and set pointers to them */
86  m[nrl]=(double *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(double)));
87  if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
88  m[nrl] += NR_END;
89  m[nrl] -= ncl;
90 
91  for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
92 
93  /* return pointer to array of pointers to rows */
94  return m;
95 }
96 
97 int **numericalRecipes::imatrix(long nrl, long nrh, long ncl, long nch)
98 /* allocate a int matrix with subscript range m[nrl..nrh][ncl..nch] */
99 {
100  long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
101  int **m;
102 
103  /* allocate pointers to rows */
104  m=(int **) malloc((size_t)((nrow+NR_END)*sizeof(int*)));
105  if (!m) nrerror("allocation failure 1 in matrix()");
106  m += NR_END;
107  m -= nrl;
108 
109 
110  /* allocate rows and set pointers to them */
111  m[nrl]=(int *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(int)));
112  if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
113  m[nrl] += NR_END;
114  m[nrl] -= ncl;
115 
116  for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
117 
118  /* return pointer to array of pointers to rows */
119  return m;
120 }
121 
122 float **numericalRecipes::submatrix(float **a, long oldrl, long oldrh, long oldcl, long oldch,
123  long newrl, long newcl)
124 /* point a submatrix [newrl..][newcl..] to a[oldrl..oldrh][oldcl..oldch] */
125 {
126  long i,j,nrow=oldrh-oldrl+1,ncol=oldcl-newcl;
127  float **m;
128 
129  /* allocate array of pointers to rows */
130  m=(float **) malloc((size_t) ((nrow+NR_END)*sizeof(float*)));
131  if (!m) nrerror("allocation failure in submatrix()");
132  m += NR_END;
133  m -= newrl;
134 
135  /* set pointers to rows */
136  for(i=oldrl,j=newrl;i<=oldrh;i++,j++) m[j]=a[i]+ncol;
137 
138  /* return pointer to array of pointers to rows */
139  return m;
140 }
141 
142 float **numericalRecipes::convert_matrix(float *a, long nrl, long nrh, long ncl, long nch)
143 /* allocate a float matrix m[nrl..nrh][ncl..nch] that points to the matrix
144 declared in the standard C manner as a[nrow][ncol], where nrow=nrh-nrl+1
145 and ncol=nch-ncl+1. The routine should be called with the address
146 &a[0][0] as the first argument. */
147 {
148  long i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1;
149  float **m;
150 
151  /* allocate pointers to rows */
152  m=(float **) malloc((size_t) ((nrow+NR_END)*sizeof(float*)));
153  if (!m) nrerror("allocation failure in convert_matrix()");
154  m += NR_END;
155  m -= nrl;
156 
157  /* set pointers to rows */
158  m[nrl]=a-ncl;
159  for(i=1,j=nrl+1;i<nrow;i++,j++) m[j]=m[j-1]+ncol;
160  /* return pointer to array of pointers to rows */
161  return m;
162 }
163 
164 int numericalRecipes::ludcmp(double **a, int n, int *indx, double *d) {
165  int i,imax,j,k;
166  double big,dum,sum,temp;
167  double *vv;
168 
169  imax = 0;
170  vv= dvector( 1, n );
171  *d=1.0;
172  for (i=1;i<=n;i++) {
173  big=0.0;
174  for (j=1;j<=n;j++)
175  if ((temp=fabs(a[i][j])) > big) big=temp;
176  if (big == 0.0) {
177  printf("Singular matrix in routine ludcmp");
178  return -1;
179  }
180  vv[i]=1.0/big;
181  }
182  for (j=1;j<=n;j++) {
183  for (i=1;i<j;i++) {
184  sum=a[i][j];
185  for (k=1;k<i;k++) sum -= a[i][k]*a[k][j];
186  a[i][j]=sum;
187  }
188  big=0.0;
189  for (i=j;i<=n;i++) {
190  sum=a[i][j];
191  for (k=1;k<j;k++)
192  sum -= a[i][k]*a[k][j];
193  a[i][j]=sum;
194  if ( (dum=vv[i]*fabs(sum)) >= big) {
195  big=dum;
196  imax=i;
197  }
198  }
199  if (j != imax) {
200  for (k=1;k<=n;k++) {
201  dum=a[imax][k];
202  a[imax][k]=a[j][k];
203  a[j][k]=dum;
204  }
205  *d = -(*d);
206  vv[imax]=vv[j];
207  }
208  indx[j]=imax;
209  if (a[j][j] == 0.0) a[j][j]=TINY;
210  if (j != n) {
211  dum=1.0/(a[j][j]);
212  for (i=j+1;i<=n;i++) a[i][j] *= dum;
213  }
214  }
215  free_dvector(vv, 1, n);
216  return 1;
217 }
218 void numericalRecipes::lubksb(double **a, int n, int *indx, double b[]) {
219  int i,ii=0,ip,j;
220  double sum;
221 
222  for (i=1;i<=n;i++) {
223  ip=indx[i];
224  sum=b[ip];
225  b[ip]=b[i];
226  if (ii)
227  for (j=ii;j<=i-1;j++) sum -= a[i][j]*b[j];
228  else if (sum) ii=i;
229  b[i]=sum;
230  }
231  for (i=n;i>=1;i--) {
232  sum=b[i];
233  for (j=i+1;j<=n;j++) sum -= a[i][j]*b[j];
234  b[i]=sum/a[i][i];
235  }
236 }
237 void numericalRecipes::invertMatrix( int n, double **matrix, double **inverse ) {
238 
239  int i, j, *indx;
240  double d, **a, *col;
241 
242  indx = ivector( 1, n );
243  a = dmatrix( 1, n, 1, n );
244  col = dvector( 1, n );
245 
246  for(i=1;i<=n;i++) {
247  for (j=1;j<=n;j++) {
248  a[i][j] = matrix[i][j];
249  }
250  }
251  if (ludcmp(a,n,indx,&d) < 0) {
252  printf("Error in ludcmp. Ending inversion.");
253  }
254  for (i=1;i<=n;i++) {
255  for (j=1;j<=n;j++) {
256  col[j] = 0;
257  }
258  col[i] = 1;
259  lubksb(a,n,indx,col);
260  for (j=1;j<=n;j++) {
261  inverse[j][i] = col[j];
262  }
263  }
264  free_dvector( col, 1, n);
265  free_dmatrix( a, 1, n, 1, n);
266  free_ivector( indx, 1, n);
267 }
268 #define SWAP(a,b) {swap=(a);(a)=(b);(b)=swap;}
269 void numericalRecipes::covsrt(double **covar, int ma, int ia[], int mfit)
270 {
271  int i,j,k;
272  double swap;
273 
274  for (i=mfit+1;i<=ma;i++)
275  for (j=1;j<=i;j++) covar[i][j]=covar[j][i]=0.0;
276  k=mfit;
277  for (j=ma;j>=1;j--) {
278  if (ia[j]) {
279  for (i=1;i<=ma;i++) SWAP(covar[i][k],covar[i][j])
280  for (i=1;i<=ma;i++) SWAP(covar[k][i],covar[j][i])
281  k--;
282  }
283  }
284 }
285 #undef SWAP
286 #define SWAP(a,b) {temp=(a);(a)=(b);(b)=temp;}
287 
288 void numericalRecipes::gaussj(double **a, int n, double **b, int m)
289 {
290  int *indxc,*indxr,*ipiv;
291  int i,icol,irow,j,k,l,ll;
292  double big,dum,pivinv,temp;
293 
294  icol = 0;
295  irow = 0;
296  indxc=ivector(1,n);
297  indxr=ivector(1,n);
298  ipiv=ivector(1,n);
299  for (j=1;j<=n;j++) ipiv[j]=0;
300  for (i=1;i<=n;i++) {
301  big=0.0;
302  for (j=1;j<=n;j++)
303  if (ipiv[j] != 1)
304  for (k=1;k<=n;k++) {
305  if (ipiv[k] == 0) {
306  if (fabs(a[j][k]) >= big) {
307  big=fabs(a[j][k]);
308  irow=j;
309  icol=k;
310  }
311  } else if (ipiv[k] > 1) {
312  printf("gaussj: Singular Matrix-1\n");
313  exit(1);
314  }
315  }
316  ++(ipiv[icol]);
317  if (irow != icol) {
318  for (l=1;l<=n;l++) SWAP(a[irow][l],a[icol][l])
319  for (l=1;l<=m;l++) SWAP(b[irow][l],b[icol][l])
320  }
321  indxr[i]=irow;
322  indxc[i]=icol;
323  if (a[icol][icol] == 0.0) {
324  printf("gaussj: Singular Matrix-2\n");
325 
326  }
327  pivinv=1.0/a[icol][icol];
328  a[icol][icol]=1.0;
329  for (l=1;l<=n;l++) a[icol][l] *= pivinv;
330  for (l=1;l<=m;l++) b[icol][l] *= pivinv;
331  for (ll=1;ll<=n;ll++)
332  if (ll != icol) {
333  dum=a[ll][icol];
334  a[ll][icol]=0.0;
335  for (l=1;l<=n;l++) a[ll][l] -= a[icol][l]*dum;
336  for (l=1;l<=m;l++) b[ll][l] -= b[icol][l]*dum;
337  }
338  }
339  for (l=n;l>=1;l--) {
340  if (indxr[l] != indxc[l])
341  for (k=1;k<=n;k++)
342  SWAP(a[k][indxr[l]],a[k][indxc[l]]);
343  }
344  free_ivector(ipiv,1,n);
345  free_ivector(indxr,1,n);
346  free_ivector(indxc,1,n);
347 }
348 #undef SWAP
349 #undef NRANSI
350 
351 
352 void numericalRecipes::free_vector(float *v, long nl, long nh)
353 /* free a float nrvector allocated with nrvector() */
354 {
355  free((FREE_ARG) (v+nl-NR_END));
356 }
357 
358 void numericalRecipes::free_ivector(int *v, long nl, long nh)
359 /* free an int nrvector allocated with inrvector() */
360 {
361  free((FREE_ARG) (v+nl-NR_END));
362 }
363 
364 void numericalRecipes::free_dvector(double *v, long nl, long nh)
365 /* free a double nrvector allocated with dnrvector() */
366 {
367  free((FREE_ARG) (v+nl-NR_END));
368 }
369 
370 void numericalRecipes::free_matrix(float **m, long nrl, long nrh, long ncl, long nch)
371 /* free a float matrix allocated by matrix() */
372 {
373  free((FREE_ARG) (m[nrl]+ncl-NR_END));
374  free((FREE_ARG) (m+nrl-NR_END));
375 }
376 
377 void numericalRecipes::free_dmatrix(double **m, long nrl, long nrh, long ncl, long nch)
378 /* free a double matrix allocated by dmatrix() */
379 {
380  free((FREE_ARG) (m[nrl]+ncl-NR_END));
381  free((FREE_ARG) (m+nrl-NR_END));
382 }
383 
384 void numericalRecipes::free_imatrix(int **m, long nrl, long nrh, long ncl, long nch)
385 /* free an int matrix allocated by imatrix() */
386 {
387  free((FREE_ARG) (m[nrl]+ncl-NR_END));
388  free((FREE_ARG) (m+nrl-NR_END));
389 }
390 
391 void numericalRecipes::free_submatrix(float **b, long nrl, long nrh, long ncl, long nch)
392 /* free a submatrix allocated by submatrix() */
393 {
394  free((FREE_ARG) (b+nrl-NR_END));
395 }
396 
397 void numericalRecipes::free_convert_matrix(float **b, long nrl, long nrh, long ncl, long nch)
398 /* free a matrix allocated by convert_matrix() */
399 {
400  free((FREE_ARG) (b+nrl-NR_END));
401 }
402