32 #include "sinfo_svd.h"
33 #include "sinfo_msg.h"
41 void sinfo_fpol(
float x,
float *p,
int np)
46 for ( j = 2 ; j <= np ; j++ )
53 sinfo_svb_kas(
float **u,
float w[],
float **v,
int m,
54 int n,
float b[],
float x[])
61 tmp=sinfo_vector(1,n);
65 for (i=1;i<=m;i++) s += u[i][j]*b[i];
72 for (jj=1;jj<=n;jj++) s += v[j][jj]*tmp[jj];
75 sinfo_free_vector(tmp,1);
78 void sinfo_svd_variance(
float **v ,
int ma ,
float w[] ,
float **cvm)
83 wti=sinfo_vector(1,ma);
86 if (w[i]) wti[i]=1.0/(w[i]*w[i]);
90 for (sum=0.0,k=1;k<=ma;k++) sum += (v[i][k]*v[j][k]*wti[k]);
91 cvm[j][i]=cvm[i][j]=sum;
94 sinfo_free_vector(wti,1);
99 void sinfo_svd_fitting (
float *x,
110 void (*funcs)(
float,
float *,
int) )
113 float wmax,tmp,thresh,sum,*b,*afunc;
116 b=sinfo_vector(1,ndata);
117 afunc=sinfo_vector(1,ma);
118 for (i=1;i<=ndata;i++) {
120 (*funcs)(x[i],afunc,ma);
122 for (j=1;j<=ma;j++) {
123 u[i][j]=afunc[j]*tmp;
127 sinfo_svd_compare(u,ndata,ma,w,v);
131 if (w[j] > wmax) wmax=w[j];
133 for (j=1;j<=ma;j++) {
139 sinfo_svb_kas(u,w,v,ndata,ma,b,a);
141 for (i=1;i<=ndata;i++) {
142 (*funcs)(x[i],afunc,ma);
143 for (sum=0.0,j=1;j<=ma;j++) sum += a[j]*afunc[j];
144 *chisq += (tmp=(y[i]-sum)/sig[i],tmp*tmp);
146 sinfo_free_vector(afunc,1);
147 sinfo_free_vector(b,1);
148 sinfo_svd_variance(v,ma,w,cvm);
156 static float at,bt,ct;
157 #define SINFO_PYTHAG(a,b) ((at=fabs(a)) > (bt=fabs(b)) ? \
158 (ct=bt/at,at*sqrt(1.0+ct*ct)) : (bt ? (ct=at/bt,bt*sqrt(1.0+ct*ct)): 0.0))
161 static float maxarg1,maxarg2;
162 #define SINFO_MAX(a,b) (maxarg1=(a),maxarg2=(b),(maxarg1) > (maxarg2) ?\
163 (maxarg1) : (maxarg2))
164 #define SINFO_SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a))
166 void sinfo_svd_compare(
float **a,
int m,
int n,
float w[],
float **v)
168 int flag,i,its,j,jj,k,l=0,nm=0;
170 float anorm=0.0,g=0.0,scale=0.0;
176 rv1=sinfo_vector(1,n);
182 for (k=i;k<=m;k++) scale += fabs(a[k][i]);
186 s += a[k][i]*a[k][i];
190 g = -SINFO_SIGN(sqrt(s),f);
195 for (s=0.0,k=i;k<=m;k++) {
196 s += a[k][i]*a[k][j];
200 a[k][j] += f*a[k][i];
204 for (k=i;k<=m;k++) a[k][i] *= scale;
209 if (i <= m && i != n) {
210 for (k=l;k<=n;k++) scale += fabs(a[i][k]);
214 s += a[i][k]*a[i][k];
218 g = -SINFO_SIGN(sqrt(s),f);
221 for (k=l;k<=n;k++) rv1[k]=a[i][k]/h;
224 for (s=0.0,k=l;k<=n;k++) s += a[j][k]*a[i][k];
225 for (k=l;k<=n;k++) a[j][k] += s*rv1[k];
228 for (k=l;k<=n;k++) a[i][k] *= scale;
231 anorm=SINFO_MAX(anorm,(fabs(w[i])+fabs(rv1[i])));
238 v[j][i]=(a[i][j]/a[i][l])/g;
240 for (s=0.0,k=l;k<=n;k++) s += a[i][k]*v[k][j];
241 for (k=l;k<=n;k++) v[k][j] += s*v[k][i];
244 for (j=l;j<=n;j++) v[i][j]=v[j][i]=0.0;
254 for (j=l;j<=n;j++) a[i][j]=0.0;
259 for (s=0.0,k=l;k<=m;k++) s += a[k][i]*a[k][j];
261 for (k=i;k<=m;k++) a[k][j] += f*a[k][i];
264 for (j=i;j<=m;j++) a[j][i] *= g;
266 for (j=i;j<=m;j++) a[j][i]=0.0;
271 for (its=1;its<=30;its++) {
275 if (fabs(rv1[l])+anorm == anorm) {
279 if (fabs(w[nm])+anorm == anorm)
break;
286 if (fabs(f)+anorm != anorm) {
307 for (j=1;j<=n;j++) v[j][k]=(-v[j][k]);
313 "SVDCMP iterations");
320 f=((y-z)*(y+z)+(g-h)*(g+h))/(2.0*h*y);
322 g=SINFO_PYTHAG(f,1.0);
323 f=((x-z)*(x+z)+h*((y/(f+SINFO_SIGN(g,f)))-h))/x;
325 for (j=l;j<=nm;j++) {
340 for (jj=1;jj<=n;jj++) {
356 for (jj=1;jj<=m;jj++) {
368 sinfo_free_vector(rv1,1);
376 #define FREE_ARG char*
378 void sinfo_nerror(
const char error_text[])
380 fprintf(stderr,
"Runtime ERROR ...\n");
381 fprintf(stderr,
"%s\n",error_text);
382 fprintf(stderr,
"exiting system \n");
386 float *sinfo_vector(
long nl,
long nh)
390 v=(
float *)cpl_malloc((
size_t) ((nh-nl+1+NR_END)*
sizeof(
float)));
398 void sinfo_free_vector(
float *v,
long nl)
401 cpl_free((FREE_ARG) (v+nl-NR_END));
404 float **sinfo_matrix(
long nrl,
long nrh,
long ncl,
long nch)
406 long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
409 m=(
float **) cpl_malloc((
size_t)((nrow+NR_END)*
sizeof(
float*)));
416 m[nrl]=(
float *)cpl_malloc((
size_t)((nrow*ncol+NR_END)*
sizeof(
float)));
423 for(i=nrl+1;i<=nrh;i++) m[i] = m[i-1]+ncol;
427 void sinfo_free_matrix(
float **m,
long nrl,
long ncl)
429 cpl_free((FREE_ARG)(m[nrl]+ncl-NR_END));
430 cpl_free((FREE_ARG)(m+nrl-NR_END));