1 /* *******************************************************************
2 FILE: recipes.c
3 DESCRIPTION: Routines for vector and matrix allocation/free.
4 Linear system solving by LU decomposition.
5 All are from "Numerical Recipes in C".
6
7 CONTAINTS:
8 double *vector(nl,nh)
9 int nl,nh;
10
11 int *ivector(nl,nh)
12 int nl,nh;
13
14 void free_vector(v,nl,nh)
15 double *v;
16 int nl,nh;
17
18 void free_ivector(v,nl,nh)
19 int *v;
20 int nl,nh;
21
22 double **matrix(nrl,nrh,ncl,nch)
23 int nrl,nrh,ncl,nch;
24
25 void free_matrix(m,nrl,nrh,ncl,nch)
26 double **m;
27 int nrl,nrh,ncl,nch;
28
29 nrerror(error_text)
30 char error_text[];
31
32 void ludcmp(a,n,indx,d)
33 int n, *indx;
34 double **a,*d;
35
36 void lubksb(a,n,indx,b)
37 double **a,b[];
38 int n,indx[];
39
40 DATE:
41 AUTHOR: From "Numerical Recipes in C"
42 REVISIONS: February 01, 1994: File created.
43 Febryary 24, 2000:
44 This file is taken out from my PhD sources, Srdjan.
45 Unnecessary functions are removed.
46 All floats are converted to doubles.
47 ********************************************************************* */
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <math.h>
51 #include "recipes.h"
52
53 #define TINY 1.0e-20
54
55 void nrerror(char * error_text);
56
57 /*****************************************************/
58 /*** Allocates a double vector with range [nl..nh]. ***/
59 /*****************************************************/
vector(nl,nh)60 double *vector(nl,nh)
61 int nl,nh;
62 {
63 double *v;
64
65 v = (double *) malloc((unsigned) (nh-nl+1)*sizeof(double));
66 if (!v) nrerror("Allocation failure in vector().\n");
67 return (v-nl);
68 }
69
70 /*****************************************************/
71 /*** Allocates an int vector with range [nl..nh]. ***/
72 /*****************************************************/
ivector(nl,nh)73 int *ivector(nl,nh)
74 int nl,nh;
75 {
76 int *v;
77
78 v = (int *) calloc((unsigned) (nh-nl+1),sizeof(int));
79 if (!v) nrerror("Allocation failure in vector().\n");
80 return (v-nl);
81 }
82
83 /****************************************************/
84 /*** Frees a double vector allocated by vector(). ***/
85 /****************************************************/
free_vector(v,nl,nh)86 void free_vector(v,nl,nh)
87 double *v;
88 int nl,nh;
89 {
90 free((char*) (v+nl));
91 }
92
93 /****************************************************/
94 /*** Frees an int vector allocated by ivector(). ***/
95 /****************************************************/
free_ivector(v,nl,nh)96 void free_ivector(v,nl,nh)
97 int *v;
98 int nl,nh;
99 {
100 free((char*) (v+nl));
101 }
102
103 /*******************************************/
104 /**** Allocates a double matrix with ****/
105 /**** range [nrl..nrh] [ncl..nch]. ****/
106 /*******************************************/
matrix(nrl,nrh,ncl,nch)107 double **matrix(nrl,nrh,ncl,nch)
108 int nrl,nrh,ncl,nch;
109 {
110 int i;
111 double **m;
112
113 /*** Allocate pointers to rows. ****/
114 m = (double**) calloc((unsigned) (nrh-nrl+1),sizeof(double*));
115 if (!m) nrerror("Allocation failure #1 in matrix().");
116 m -= nrl;
117
118
119 /*** Allocate rows and pointers to them. ***/
120 for (i=nrl; i<=nrh; i++) {
121 m[i] = (double *) malloc((unsigned) (nch-ncl+1)*sizeof(double));
122 if (!m[i]) nrerror("Allocation failure #2 in matrix().");
123 m[i] -= ncl;
124 }
125 return(m);
126 }
127
128 /******************************************/
129 /**** Frees a matrix allocated by ... ***/
130 /**** matrix(). ***/
131 /******************************************/
free_matrix(m,nrl,nrh,ncl,nch)132 void free_matrix(m,nrl,nrh,ncl,nch)
133 double **m;
134 int nrl,nrh,ncl,nch;
135 {
136 int i;
137
138 for (i=nrh; i>=nrl; i--) free((char*) (m[i]+ncl));
139 free ((char*) (m+nrl));
140 }
141
142 /*************************************************/
143 /*** Numerical Recipes standard error handler. ***/
144 /*************************************************/
nrerror(error_text)145 void nrerror(error_text)
146 char error_text[];
147 {
148 void exit();
149
150 fprintf(stderr,"Numerical Recipes run-time error...\n");
151 fprintf(stderr,"%s\n",error_text);
152 fprintf(stderr,"Forced to exit.\n");
153 exit(1);
154 }
155
156 /* ******************************************************************** */
157 /* LU Decomposition of a matrix */
158 /* a[1:n][1:n] system matrix, */
159 /* n problem dimension, */
160 /* indx[1:n] temporary storage, */
161 /* d temporary storage. */
162 /* ******************************************************************** */
ludcmp(a,n,indx,d)163 int ludcmp(a,n,indx,d)
164 int n, *indx;
165 double **a,*d;
166 {
167 int i,imax,j,k;
168 double big,dum,sum,temp;
169 double *vv,*vector();
170 void free_vector();
171
172 imax = 0;
173
174 vv=vector(1,n);
175 (*d)=1.0;
176 for (i=1;i<=n;i++) {
177 big=0.0;
178 for (j=1;j<=n;j++)
179 if ((temp=fabs(a[i][j])) > big) big=temp;
180 if (!big) nrerror("Singular matrix in routine LUDCMP");
181 vv[i]=1.0/big;
182 }
183 for (j=1;j<=n;j++) {
184 for (i=1;i<j;i++) {
185 sum=a[i][j];
186 for (k=1;k<i;k++) sum -= a[i][k]*a[k][j];
187 a[i][j]=sum;
188 }
189 big=0.0;
190 for (i=j;i<=n;i++) {
191 sum=a[i][j];
192 for (k=1;k<j;k++)
193 sum -= a[i][k]*a[k][j];
194 a[i][j]=sum;
195 if ((dum=vv[i]*fabs(sum))>=big) {
196 big=dum;
197 imax=i;
198 }
199 }
200 if (j!=imax) {
201 for (k=1;k<=n;k++) {
202 dum=a[imax][k];
203 a[imax][k]=a[j][k];
204 a[j][k]=dum;
205 }
206 (*d)= -(*d);
207 vv[imax]=vv[j];
208 }
209 indx[j]=imax;
210 if(fpclassify(a[j][j]) == FP_ZERO) {
211 a[j][j]=TINY;
212 }
213 if (j!=n) {
214 dum=1.0/(a[j][j]);
215 for (i=j+1;i<=n;i++) a[i][j] *= dum;
216 }
217 }
218 free_vector(vv,1,n);
219 return(0);
220
221 } /* end of ludcmp() */
222
223 /* ******************************************************************** */
224 /* Solve system of equation */
225 /* ******************************************************************** */
lubksb(a,n,indx,b)226 void lubksb(a,n,indx,b)
227 double **a,b[];
228 int n,indx[];
229 {
230 int i,ii=0,ip,j;
231 double sum;
232
233 for (i=1;i<=n;i++) {
234 ip=indx[i];
235 sum=b[ip];
236 b[ip]=b[i];
237 if (ii) {
238 for (j=ii;j<=i-1;j++) sum -= a[i][j]*b[j];
239 } else if (sum) {
240 ii=i;
241 }
242 b[i]=sum;
243 }
244 for (i=n;i>=1;i--) {
245 sum=b[i];
246 for (j=i+1;j<=n;j++) sum -= a[i][j]*b[j];
247 b[i]=sum/a[i][i];
248 }
249
250 } /* end of lubksb() */
251
252