DAS  3.1.6 - 18/09/2017
Macros | Functions
SVD.C File Reference
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <math.h>
#include <io.h>
#include "mgui.h"
#include "DAS_Spatram.h"
#include "dcl.h"
#include "dil.h"
#include "bil.h"
#include "DOAS.h"
#include "nrutil.h"
#include "Marq.h"
+ Include dependency graph for SVD.C:

Go to the source code of this file.

Macros

#define SWAP(a, b)   {swap=(a);(a)=(b);(b)=swap;}
 
#define TOL   1.0e-5
 

Functions

void covsrt (float **covar, int ma, int ia[], int mfit)
 
long double pythag (long double a, long double b)
 
void svbksb (long double **u, long double w[], long double **v, int m, int n, long double b[], long double x[])
 
void svdcmp (long double **a, int m, int n, long double w[], long double **v)
 
void svdfit (float x[], float y[], float sig[], int ndata, float a[], int ma, float **u, float **v, float w[], float *chisq, void(*funcs)(float, float [], int))
 

Macro Definition Documentation

§ SWAP

#define SWAP (   a,
 
)    {swap=(a);(a)=(b);(b)=swap;}

Definition at line 19 of file SVD.C.

Referenced by covsrt().

§ TOL

#define TOL   1.0e-5

Definition at line 21 of file SVD.C.

Referenced by svdfit().

Function Documentation

§ covsrt()

void covsrt ( float **  covar,
int  ma,
int  ia[],
int  mfit 
)

Definition at line 23 of file SVD.C.

References SWAP.

26 {
27  int i,j,k;
28  float swap;
29  for (i=mfit+1;i<=ma;i++)
30  for (j=1;j<=i;j++) covar[i][j]=covar[j][i]=0.0;
31  k=mfit;
32  for (j=ma;j>=1;j--)
33  {
34  if (ia[j])
35  {
36  for (i=1;i<=ma;i++) SWAP(covar[i][k],covar[i][j])
37  for (i=1;i<=ma;i++) SWAP(covar[k][i],covar[j][i])
38  k--;
39  }
40  }
41 }
#define SWAP(a, b)
Definition: SVD.C:19

§ pythag()

long double pythag ( long double  a,
long double  b 
)

Definition at line 366 of file SVD.C.

References DSQR.

Referenced by svdcmp().

368 {
369  long double absa,absb;
370  absa=fabs(a);
371  absb=fabs(b);
372  if (absa > absb) return absa*sqrt(1.0+DSQR(absb/absa));
373  else return (absb == 0.0 ? 0.0 : absb*sqrt(1.0+DSQR(absa/absb)));
374 }
#define DSQR(a)
Definition: NRUTIL.H:8
+ Here is the caller graph for this function:

§ svbksb()

void svbksb ( long double **  u,
long double  w[],
long double **  v,
int  m,
int  n,
long double  b[],
long double  x[] 
)

Definition at line 99 of file SVD.C.

References dvector(), and free_dvector().

Referenced by svdfit().

107 {
108  int jj,j,i;
109  long double s,*tmp;
110  tmp=dvector(1,n);
111  for (j=1;j<=n;j++)
112  { //Calculate U T B
113  s=0.0;
114  if (w[j])
115  { //Nonzero result only if wj is nonzero.
116  for (i=1;i<=m;i++) s += u[i][j]*b[i];
117  s /= w[j]; //This is the divide by wj .
118  }
119  tmp[j]=s;
120  }
121  for (j=1;j<=n;j++)
122  { //Matrix multiply by V to get answer.
123  s=0.0;
124  for (jj=1;jj<=n;jj++) s += v[j][jj]*tmp[jj];
125  x[j]=s;
126  }
127  free_dvector(tmp,1,n);
128 }
void free_dvector()
double * dvector()
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

§ svdcmp()

void svdcmp ( long double **  a,
int  m,
int  n,
long double  w[],
long double **  v 
)

Definition at line 132 of file SVD.C.

References DMAX, dvector(), free_vector(), IMIN, nrerror(), pythag(), and SIGN.

Referenced by svdfit().

139 {
140  FILE *fpp;
141  long double pythag(long double a, long double b);
142  int flag,i,its,j,jj,k,l,nm;
143  long double anorm,c,f,g,h,s,scale,x,y,z,*rv1;
144  rv1=dvector(1,n);
145  g=scale=anorm=0.0; //Householder reduction to bidiagonal form.
146  for (i=1;i<=n;i++)
147  {
148  l=i+1;
149  rv1[i]=scale*g;
150  g=s=scale=0.0;
151  if (i <= m)
152  {
153  for (k=i;k<=m;k++)
154  scale += fabs(a[k][i]);
155  if (scale)
156  {
157  for (k=i;k<=m;k++)
158  {
159  a[k][i] /= scale;
160  s += a[k][i]*a[k][i];
161  }
162  f=a[i][i];
163  g = -SIGN(sqrt(s),f);
164  h=f*g-s;
165  a[i][i]=f-g;
166  for (j=l;j<=n;j++)
167  {
168  for (s=0.0,k=i;k<=m;k++) s += a[k][i]*a[k][j];
169  f=s/h;
170  for (k=i;k<=m;k++) a[k][j] += f*a[k][i];
171  }
172  for (k=i;k<=m;k++) a[k][i] *= scale;
173  }
174  }
175  w[i]=scale *g;
176  g=s=scale=0.0;
177  if (i <= m && i != n)
178  {
179  for (k=l;k<=n;k++) scale += fabs(a[i][k]);
180  if (scale)
181  {
182  for (k=l;k<=n;k++)
183  {
184  a[i][k] /= scale;
185  s += a[i][k]*a[i][k];
186  }
187  f=a[i][l];
188  g = -SIGN(sqrt(s),f);
189  h=f*g-s;
190  a[i][l]=f-g;
191  for (k=l;k<=n;k++) rv1[k]=a[i][k]/h;
192  for (j=l;j<=m;j++)
193  {
194  for (s=0.0,k=l;k<=n;k++) s += a[j][k]*a[i][k];
195  for (k=l;k<=n;k++) a[j][k] += s*rv1[k];
196  }
197  for (k=l;k<=n;k++) a[i][k] *= scale;
198  }
199  }
200  anorm=DMAX(anorm,(fabs(w[i])+fabs(rv1[i])));
201  }
202  for (i=n;i>=1;i--)
203  { //Accumulation of right-hand transformations.
204  if (i < n)
205  {
206  if (g)
207  {
208  for (j=l;j<=n;j++) //Double division to avoid possible under .o .
209  v[j][i]=(a[i][j]/a[i][l])/g;
210  for (j=l;j<=n;j++)
211  {
212  for (s=0.0,k=l;k<=n;k++) s += a[i][k]*v[k][j];
213  for (k=l;k<=n;k++) v[k][j] += s*v[k][i];
214  }
215  }
216  for (j=l;j<=n;j++) v[i][j]=v[j][i]=0.0;
217  }
218  v[i][i]=1.0;
219  g=rv1[i];
220  l=i;
221  }
222  for (i=IMIN(m,n);i>=1;i--)
223  { //Accumulation of left-hand transformations.
224  l=i+1;
225  g=w[i];
226  for (j=l;j<=n;j++) a[i][j]=0.0;
227  if (g)
228  {
229  g=1.0/g;
230  for (j=l;j<=n;j++)
231  {
232  for (s=0.0,k=l;k<=m;k++) s += a[k][i]*a[k][j];
233  f=(s/a[i][i])*g;
234  for (k=i;k<=m;k++) a[k][j] += f*a[k][i];
235  }
236  for (j=i;j<=m;j++) a[j][i] *= g;
237  }
238  else
239  for (j=i;j<=m;j++) a[j][i]=0.0;
240  ++a[i][i];
241  }
242 
243  for (k=n;k>=1;k--)
244  { //Diagonalization of the bidiagonal form:Loop over singular values,and over allo ed iterations.
245  for (its=1;its<=30;its++)
246  {
247  flag=1;
248  for (l=k;l>=1;l--)
249  { //Test for splitting.
250  nm=l-1; //Note that rv1[1] is always zero.
251  if ((float)(fabs(rv1[l])+anorm) == anorm)
252  {
253  flag=0;
254  break;
255  }
256  if ((float)(fabs(w[nm])+anorm) == anorm) break;
257  }
258  if (flag)
259  {
260  c=0.0; //Cancellation of rv1[l],if l > 1
261  s=1.0;
262  for (i=l;i<=k;i++)
263  {
264  f=s*rv1[i];
265  rv1[i]=c*rv1[i];
266  if ((float)(fabs(f)+anorm) == anorm) break;
267  g=w[i];
268  h=pythag(f,g);
269  w[i]=h;
270  h=1.0/h;
271  c=g*h;
272  s = -f*h;
273  for (j=1;j<=m;j++)
274  {
275  y=a[j][nm];
276  z=a[j][i];
277  a[j][nm]=y*c+z*s;
278  a[j][i]=z*c-y*s;
279  }
280  }
281  }
282  z=w[k];
283  if (l == k)
284  { //Convergence.
285  if (z < 0.0)
286  { //Singular value is made nonnegative.
287  w[k] = -z;
288  for (j=1;j<=n;j++) v[j][k] = -v[j][k];
289  }
290  break;
291  }
292  if (its == 30) nrerror("no convergence in 30 svdcmp iterations");
293  x=w[l]; //Shift from bottom 2-by-2 minor.
294  nm=k-1;
295  y=w[nm];
296  g=rv1[nm];
297  h=rv1[k];
298  f=((y-z)*(y+z)+(g-h)*(g+h))/(2.0*h*y);
299  g=pythag(f,1.0);
300  f=((x-z)*(x+z)+h*((y/(f+SIGN(g,f)))-h))/x;
301  c=s=1.0; //Next QR transformation:
302  for (j=l;j<=nm;j++)
303  {
304  i=j+1;
305  g=rv1[i];
306  y=w[i];
307  h=s*g;
308  g=c*g;
309  z=pythag(f,h);
310  rv1[j]=z;
311  c=f/z;
312  s=h/z;
313  f=x*c+g*s;
314  g = g*c-x*s;
315  h=y*s;
316  y *=c;
317  for (jj=1;jj<=n;jj++)
318  {
319  x=v[jj][j];
320  z=v[jj][i];
321  v[jj][j]=x*c+z*s;
322  v[jj][i]=z*c-x*s;
323  }
324  z=pythag(f,h);
325  w[j]=z; //Rotation can be arbitrary if z =0
326  if (z)
327  {
328  z=1.0/z;
329  c=f*z;
330  s=h*z;
331  }
332  f=c*g+s*y;
333  x=c*y-s*g;
334  for (jj=1;jj<=m;jj++)
335  {
336  y=a[jj][j];
337  z=a[jj][i];
338  a[jj][j]=y*c+z*s;
339  a[jj][i]=z*c-y*s;
340  }
341  }
342  rv1[l]=0.0;
343  rv1[k]=f;
344  w[k]=x;
345  }
346  }
347 
348  fpp = fopen("matUInSVD.dat", "w");
349  for(k=1;k<=m;k++)
350  {
351  for(l=1;l<=m;l++)
352  {
353  fprintf(fpp,"%7.6e ",a[k][l]) ;
354  }
355  fprintf(fpp,"\n");
356  }
357 
358  fclose(fpp);
359 
360 
361  free_vector(rv1,1,n);
362 }
#define SIGN(a, b)
Definition: NRUTIL.H:42
long double pythag(long double a, long double b)
Definition: SVD.C:366
double * dvector()
#define DMAX(a, b)
Definition: NRUTIL.H:11
#define IMIN(a, b)
Definition: NRUTIL.H:39
void free_vector()
struct flag flag
Control Flags.
void nrerror()
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

§ svdfit()

void svdfit ( float  x[],
float  y[],
float  sig[],
int  ndata,
float  a[],
int  ma,
float **  u,
float **  v,
float  w[],
float *  chisq,
void(*)(float, float [], int)  funcs 
)

Definition at line 47 of file SVD.C.

References dvector(), free_vector(), svbksb(), svdcmp(), and TOL.

61 {
62  void svbksb(long double **u, long double w[], long double **v, int m, int n, long double b[],
63  double x[]);
64  void svdcmp(long double **a, int m, int n, long double w[], long double **v);
65  int j,i;
66  long double wmax,tmp,thresh,sum,*b,*afunc;
67 
68  b=dvector(1,ndata);
69  afunc=dvector(1,ma);
70  for (i=1;i<=ndata;i++)
71  { //Accumulate coefficients of the fitting matrix.
72  (*funcs)(x[i],(float *)afunc,ma);
73  tmp=1.0/sig[i];
74  for (j=1;j<=ma;j++) u[i][j]=afunc[j]*tmp;
75  b[i]=y[i]*tmp;
76  }
77  svdcmp(u,ndata,ma,w,v); //Singular value decomposition.
78  wmax=0.0; //Edit the singular values,given TOL from the
79  //#define statement,between here ...
80  for (j=1;j<=ma;j++)
81  if (w[j] > wmax) wmax=w[j];
82  thresh=TOL*wmax;
83  for (j=1;j<=ma;j++)
84  if (w[j] < thresh) w[j]=0.0; //...and here.
85  svbksb(u,w,v,ndata,ma,b,a);
86  *chisq=0.0; //Evaluate chi-square.
87  for (i=1;i<=ndata;i++)
88  {
89  (*funcs)(x[i],afunc,ma);
90  for (sum=0.0,j=1;j<=ma;j++) sum += a[j]*afunc[j];
91  *chisq += (float)(tmp=(y[i]-sum)/sig[i],tmp*tmp);
92  }
93  free_vector(afunc,1,ma);
94  free_vector(b,1,ndata);
95 }
void svbksb(long double **u, long double w[], long double **v, int m, int n, long double b[], long double x[])
Definition: SVD.C:99
#define TOL
Definition: SVD.C:21
double * dvector()
void svdcmp(long double **a, int m, int n, long double w[], long double **v)
Definition: SVD.C:132
void free_vector()
+ Here is the call graph for this function:
______________________________________________________________________________________
Generated on Mon Sep 18 2017 11:46:57 for DAS - Rel. 3.1.6 - 18/09/2017.