#include #include #include #include "numrecp.h" #define ROTATE(a,i,j,k,l) g=a[i*n+j];h=a[k*n+l];a[i*n+j]=g-s*(h+g*tau);\ a[k*n+l]=h+s*(g-h*tau); float **init_matrix(int m, int n) //build matrix of a[1..m][1..n] { float **ip; int i; ip=malloc((m+1)*sizeof(float *)); for (i=0;i<=m;i++) { ip[i]=malloc((n+1)*sizeof (float)); } return ip; } double **init_matrix_d(int m, int n) //build matrix of a[1..m][1..n] { double **ip; int i; ip=malloc((m+1)*sizeof(double *)); for (i=0;i<=m;i++) { ip[i]=malloc((n+1)*sizeof (double)); } return ip; } void free_matrix (float **ip, int m ) //free a[1..m][1..n] { int i; for (i=0;i<=m; i++) { free(ip[i]); } free(ip); } void free_matrix_d (double **ip, int m ) //free a[1..m][1..n] { int i; for (i=0;i<=m; i++) { free(ip[i]); } free(ip); } void jacobi( float *a, int n, float *d,float *v, int *nrot) //matrix is for [0..n-1][0..n-1] { int j,iq,ip,i; float tresh,theta,tau,t,sm,s,h,g,c,*b,*z; float zero=1e-8; b=malloc(sizeof(float)*n); z=malloc(sizeof(float)*n); for (ip=0;ip 4 && fabs(d[ip])+g == fabs(d[ip]) && fabs(d[iq])+g == fabs(d[iq])) a[ip*n+iq]=0.0; else if (fabs(a[ip*n+iq]) > tresh) { h=d[iq]-d[ip]; if (fabs(h)+g == fabs(h)) t=(a[ip*n+iq])/h; else { theta=0.5*h/(a[ip*n+iq]); t=1.0/(fabs(theta)+sqrt(1.0+theta*theta)); if (theta < 0.0) t = -t; } c=1.0/sqrt(1+t*t); s=t*c; tau=s/(1.0+c); h=t*a[ip*n+iq]; z[ip] -= h; z[iq] += h; d[ip] -= h; d[iq] += h; a[ip*n+iq]=0.0; for (j=0;j<=ip-1;j++) { ROTATE(a,j,ip,j,iq) } for (j=ip+1;j<=iq-1;j++) { ROTATE(a,ip,j,j,iq) } for (j=iq+1;j<=n-1;j++) { ROTATE(a,ip,j,iq,j) } for (j=0;j<=n-1;j++) { ROTATE(v,j,ip,j,iq) } ++(*nrot); } } } for (ip=0;ip<=n-1;ip++) { b[ip] += z[ip]; d[ip]=b[ip]; z[ip]=0.0; } } free(z); free(b); printf("Too many iterations in routine JACOBI\n"); } #undef ROTATE void eigsrt(float *d,float *v,int n) { int k,j,i; float p; for (i=0;i= p) p=d[k=j]; if (k != i) { d[k]=d[i]; d[i]=p; for (j=0;j<=n-1;j++) { p=v[j*n+i]; v[j*n+i]=v[j*n+k]; v[j*n+k]=p; } } } } void rotvec (int n,float *v, float *t) { float *s; s=malloc(n*sizeof(float)); int i,j; for (i=0;iabsb) return absa*sqrt( 1.0+(absb/absa)*(absb/absa)); else return (absb==0.0 ? 0.0 : absb* sqrt ( 1.0 + (absa/absb)*(absa/absb))); } float max (float a, float b) { if (a>=b) return a; else return b; } #define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a)) void svdcmp(float **a, int m,int n,float *w,float **v) { int flag,i,its,j,jj,k,l,nm; float c,f,h,s,x,y,z; float anorm=0.0,g=0.0,scale=0.0; float *rv1; if (m < n) {printf("SVDCMP: You must augment A with extra zero rows");exit(1);} rv1=malloc((n+1)*sizeof(float)); for (i=1;i<=n;i++) { l=i+1; rv1[i]=scale*g; g=s=scale=0.0; if (i <= m) { for (k=i;k<=m;k++) scale += fabs(a[k][i]); if (scale) { for (k=i;k<=m;k++) { a[k][i]= a[k][i]/scale; s = s+a[k][i]*a[k][i]; } f=a[i][i]; g = -SIGN(sqrt(s),f); h=f*g-s; a[i][i]=f-g; if (i != n) { for (j=l;j<=n;j++) { for (s=0.0,k=i;k<=m;k++) s =s+ a[k][i]*a[k][j]; f=s/h; for (k=i;k<=m;k++) a[k][j] = a[k][j]+ f*a[k][i]; } } for (k=i;k<=m;k++) a[k][i] = a[k][i] *scale; } } w[i]=scale*g; g=s=scale=0.0; if (i <= m && i != n) { for (k=l;k<=n;k++) scale = scale + fabs(a[i][k]); if (scale) { for (k=l;k<=n;k++) { a[i][k] = a[i][k] / scale; s = s+ a[i][k]*a[i][k]; } f=a[i][l]; g = -SIGN(sqrt(s),f); h=f*g-s; a[i][l]=f-g; for (k=l;k<=n;k++) rv1[k]=a[i][k]/h; if (i != m) { for (j=l;j<=m;j++) { for (s=0.0,k=l;k<=n;k++) s = s + a[j][k]*a[i][k]; for (k=l;k<=n;k++) a[j][k] = a[j][k] + s*rv1[k]; } } for (k=l;k<=n;k++) a[i][k] = a[i][k] * scale; } } anorm=max(anorm,(fabs(w[i])+fabs(rv1[i]))); } for (i=n;i>=1;i--) { if (i < n) { if (g) { for (j=l;j<=n;j++) v[j][i]=(a[i][j]/a[i][l])/g; for (j=l;j<=n;j++) { for (s=0.0,k=l;k<=n;k++) s = s + a[i][k]*v[k][j]; for (k=l;k<=n;k++) v[k][j] = v[k][j] + s*v[k][i]; } } for (j=l;j<=n;j++) v[i][j]=v[j][i]=0.0; } v[i][i]=1.0; g=rv1[i]; l=i; } for (i=n;i>=1;i--) { l=i+1; g=w[i]; if (i < n) for (j=l;j<=n;j++) a[i][j]=0.0; if (g) { g=1.0/g; if (i != n) { for (j=l;j<=n;j++) { for (s=0.0,k=l;k<=m;k++) s = s+ a[k][i]*a[k][j]; f=(s/a[i][i])*g; for (k=i;k<=m;k++) a[k][j] =a[k][j] + f*a[k][i]; } } for (j=i;j<=m;j++) a[j][i] = a[j][i] *g; } else { for (j=i;j<=m;j++) a[j][i]=0.0; } ++(a[i][i]); } for (k=n;k>=1;k--) { for (its=1;its<=30;its++) { flag=1; for (l=k;l>=1;l--) { nm=l-1; if (fabs(rv1[l])+anorm == anorm) { flag=0; break; } if (fabs(w[nm])+anorm == anorm) break; } if (flag) { c=0.0; s=1.0; for (i=l;i<=k;i++) { f=s*rv1[i]; if (fabs(f)+anorm != anorm) { g=w[i]; h=pythag(f,g); w[i]=h; h=1.0/h; c=g*h; s=(-f*h); for (j=1;j<=m;j++) { y=a[j][nm]; z=a[j][i]; a[j][nm]=y*c+z*s; a[j][i]=z*c-y*s; } } } } z=w[k]; if (l == k) { if (z < 0.0) { w[k] = -z; for (j=1;j<=n;j++) v[j][k]=(-v[j][k]); } break; } if (its == 30) {printf("No convergence in 30 SVDCMP iterations");exit(1);} x=w[l]; nm=k-1; y=w[nm]; g=rv1[nm]; h=rv1[k]; f=((y-z)*(y+z)+(g-h)*(g+h))/(2.0*h*y); g=pythag(f,1.0); f=((x-z)*(x+z)+h*((y/(f+SIGN(g,f)))-h))/x; c=s=1.0; for (j=l;j<=nm;j++) { i=j+1; g=rv1[i]; y=w[i]; h=s*g; g=c*g; z=pythag(f,h); rv1[j]=z; c=f/z; s=h/z; f=x*c+g*s; g=g*c-x*s; h=y*s; y=y*c; for (jj=1;jj<=n;jj++) { x=v[jj][j]; z=v[jj][i]; v[jj][j]=x*c+z*s; v[jj][i]=z*c-x*s; } z=pythag(f,h); w[j]=z; if (z) { z=1.0/z; c=f*z; s=h*z; } f=(c*g)+(s*y); x=(c*y)-(s*g); for (jj=1;jj<=m;jj++) { y=a[jj][j]; z=a[jj][i]; a[jj][j]=y*c+z*s; a[jj][i]=z*c-y*s; } } rv1[l]=0.0; rv1[k]=f; w[k]=x; } } free_vector(rv1); } #undef SIGN void matrix_mulp(float **a, int ma, int na, float **b, int mb, int nb, float **ip) //[1..m][1..n] { if (na!=mb) {printf("2nd Dim of A is not equal to 1st Dim of B\n");exit(1);} int i,j,k; float summ; for (i=1;i<=ma;i++) { for (k=1;k<=nb;k++) { summ=0; for (j=1;j<=na;j++) { summ+=a[i][j]*b[j][k]; } ip[i][k]=summ; } } } void matrix_transp(float **a, int m, int n, float **ip) //[1..m][1..n] { int i,j; for (i=1;i<=m;i++) for (j=1;j<=n;j++) ip[j][i]=a[i][j]; } void matrix_copy (float **a, int m , int n, float **ip) //[1..m][1..n] { int i,j; for (i=1;i<=m;i++) for (j=1;j<=n;j++) ip[i][j]=a[i][j]; } void agaus( double **a, double *b, int n, double *x) //solve linear eq by Gaussian Elimination // program will terminate if singular value happens { int *js; js=malloc((n+1)*sizeof(int)); int l; int i,j,k,is; double d,t; for(k=1;k<=n-1;k++) { d=0.0; for (i=k;i<=n;i++) for (j=k;j<=n;j++) if (fabs(a[i][j])>d) { d=fabs(a[i][j]); js[k]=j; is=i; } if ((d+1.0)==1.0) {printf("Singular Problem!\n");exit(1);} else { if (js[k]!=k) { for (i=1;i<=n;i++) { t=a[i][k]; a[i][k]=a[i][js[k]]; a[i][js[k]]=t; } } if (is!=k) { for (j=k;j<=n;j++) { t=a[k][j]; a[k][j]=a[is][j]; a[is][j]=t; } t=b[k]; b[k]=b[is]; b[is]=t; } } for(j=k+1;j<=n;j++) a[k][j]=a[k][j]/a[k][k]; b[k]=b[k]/a[k][k]; for (i=k+1;i<=n;i++) { for (j=k+1;j<=n;j++) a[i][j]=a[i][j]-a[i][k]*a[k][j]; b[i]=b[i]-a[i][k]*b[k]; } } if ((fabs(a[n][n])+1.0)==1.0) {printf("Singular Problem!\n");exit(1);} //backsubstitution x[n]=b[n]/a[n][n]; for (i=n-1;i>=1;i--) { // if ((fabs(a[i][i])+1.0)==1.0) // {printf("Singular Problem!\n");exit(1);} t=0.0; for (j=i+1;j<=n;j++) t+=a[i][j]*x[j]; x[i]=(b[i]-t); } for (k=n-1;k>=1;k--) if (js[k]!=k) { t=x[k]; x[k]=x[js[k]]; x[js[k]]=t; } free(js); } void fit_plane (float *x, int numx,double *nx, double *ny, double *nz, double *p ) //[0..n-1] { double sxx, syx, szx, sx; double sxy, syy, szy, sy; double sxz, syz, szz, sz; int i; sxx=0; for (i=0;i25.0) { if (numvec==0) { sl=sqrt(sl); for (k=0;k0) { sl=sqrt(sl); for (k=0;ksl) { sl=fabs(b[i]); fl=i; } if (sl+1.0==1.0) {printf("Singular Problem!\n");exit(1);} sl=b[fl]; for (i=0;isl) { sl=fabs(b[i]); fl=i; } if (sl+1.0==1.0) {printf("Singular Problem!\n");exit(1);} sl=b[fl]; for (i=0;i