#include #include #include #include #include #include "header.h" #include "sysdep.h" #include "matheh.h" char *ram; int *perm,*col,signdet,luflag=0; double **lumat,*c,det; complex **c_lumat,*c_c,c_det; int rank; #define outofram() { output("Out of Memory!\n"); error=120; return; } #define wrong_arg() { output("Wrong arguments!\n"); error=1000; return; } /***************** real linear systems *******************/ void lu (double *a, int n, int m) /***** lu lu decomposition of a *****/ { int i,j,k,mm,j0,kh; double *d,piv,temp,*temp1,zmax,help; if (!luflag) { /* get place for result c and move a to c */ c=(double *)ram; ram+=(LONG)n*m*sizeof(double); if (ram>ramend) outofram(); memmove((char *)c,(char *)a,(LONG)n*m*sizeof(double)); } else c=a; /* inititalize lumat */ lumat=(double **)ram; ram+=(LONG)n*sizeof(double *); if (ram>ramend) outofram(); d=c; for (i=0; iramend) outofram(); /* get place for col */ col=(int *)ram; ram+=(LONG)m*sizeof(int); if (ram>ramend) outofram(); /* d is a vector needed by the algorithm */ d=(double *)ram; ram+=(LONG)n*sizeof(double); if (ram>ramend) outofram(); /* gauss algorithm */ if (!luflag) for (k=0; kzmax) zmax=help; if (zmax==0.0) { error=130; return; } d[k]=zmax; } else { for (k=0; k=n) { kh++; break; } } if (kramend) outofram(); h=res; for (i=0; iramend) outofram(); h=rs; for (i=0; i=0; k--) { for (sum=0.0, j=k+1; jramend) outofram(); h=res; for (i=0; iramend) outofram(); h=rs; for (i=0; iramend) outofram(); d=a; for (i=0; i=0; k--) { for (sum=0.0, j=k+1; jramend) outofram(); memmove((char *)c_c,(char *)a,(LONG)n*m*sizeof(complex)); } else c_c=(complex *)a; /* inititalize c_lumat */ c_lumat=(complex **)ram; ram+=(LONG)n*sizeof(complex *); if (ram>ramend) outofram(); h=c_c; for (i=0; iramend) outofram(); /* get place for col */ col=(int *)ram; ram+=(LONG)m*sizeof(int); if (ram>ramend) outofram(); /* d is a vector needed by the algorithm */ d=(double *)ram; ram+=(LONG)n*sizeof(double); if (ram>ramend) outofram(); /* gauss algorithm */ if (!luflag) for (k=0; kzmax) zmax=help; if (zmax==0.0) { error=130; return; } d[k]=zmax; } else { for (k=0; k=n) { kh++; break; } } if (kramend) outofram(); h=(complex *)res; for (i=0; iramend) outofram(); h=(complex *)rs; for (i=0; i=0; k--) { sum[0]=0; sum[1]=0.0; for (j=k+1; jramend) outofram(); h=(complex *)res; for (i=0; iramend) outofram(); h=(complex *)rs; for (i=0; iramend) outofram(); h=(complex *)a; for (i=0; i=0; k--) { sum[0]=0; sum[1]=0.0; for (j=k+1; j1) for (m=0; m=nn) mh-=nn; } for (l=0; l=nn) mh-=nn; } } void fft (double *a, int n, int signum) { complex z; double h; int i; if (n==0) return; nn=n; ram=newram; ff=(complex *)a; zz=(complex *)ram; ram+=n*sizeof(complex); fh=(complex *)ram; ram+=n*sizeof(complex); if (ram>ramend) outofram(); /* compute zz[k]=e^{-2*pi*i*k/n}, k=0,...,n-1 */ h=2*M_PI/n; z[0]=cos(h); z[1]=signum*sin(h); zz[0][0]=1; zz[0][1]=0; for (i=1; i0.0) { qr=-qr; qi=-qi; } pr=qr-br; pi=qi-bi; h=pr*pr+pi*pi; *treal=2*(cr*pr+ci*pi)/h; *timag=2*(ci*pr-cr*pi)/h; } int cxdiv (double ar, double ai, double br, double bi, double *cr, double *ci) { double temp; if (br==0.0 && bi==0.0) return 1; if (fabs(br)>fabs(bi)) { temp=bi/br; br=temp*bi+br; *cr=(ar+temp*ai)/br; *ci=(ai-temp*ar)/br; } else { temp=br/bi; bi=temp*br+bi; *cr=(temp*ar+ai)/bi; *ci=(temp*ai-ar)/bi; } return 0; } double cxxabs (double ar, double ai) { if (ar==0.0) return fabs(ai); if (ai==0.0) return fabs(ar); return sqrt(ai*ai+ar*ar); } void chorner (int n, int iu, double *ar, double *ai, double xr, double xi, double *pr, double *pi, double *p1r, double *p1i, double *p2r, double *p2i, double *rf1) { register int i,j; int i1; double temp,hh,tempr=0.0,tempi=0.0; *pr=ar[n]; *pi=ai[n]; *p1r=*p2r=0.0; *p1i=*p2i=0.0; *rf1=cxxabs(*pr,*pi); i1=n-iu; for (j=n-iu,i=n-1; i>=iu; i--,j--) { if (itemp) temp=hh; if (temp>*rf1) { *rf1=temp; i1=j-1; } if (i*scal) *scal=h; } ar[n]/=p; ai[n]/=p; if (*scal==0.0) *scal=1.0; for (p=1.0,i=n-1; i>=0; i--) { p*= *scal; ar[i]/=p; ai[i]/=p; } } void bauroot (int n, int iu, double *ar, double *ai, double *x0r, double *x0i) { int iter=0,i=0,aborted=0; double xoldr,xoldi,xnewr,xnewi,h,h1,h2,h3,h4,dzmax,dzmin, dxr=1,dxi=0,tempr,tempi,abs_pold,abs_pnew,abs_p1new, temp,ss,u,v, pr,pi,p1r,p1i,p2r,p2i,abs_pnoted=-1; dxr=dxi=xoldr=xoldi=0.0; if (n-iu==1) { quadloes(0.0,0.0,ar[n],ai[n], ar[n-1],ai[n-1],x0r,x0i); goto stop; } if (n-iu==2) { quadloes(ar[n],ai[n],ar[n-1],ai[n-1], ar[n-2],ai[n-2],x0r,x0i); goto stop; } xnewr=*x0r; xnewi=*x0i; chorner(n,iu,ar,ai,xnewr,xnewi,&pr,&pi,&p1r,&p1i,&p2r,&p2i,&ss); iter++; abs_pnew=cxxabs(pr,pi); if (abs_pnew==0) goto stop; abs_pold=abs_pnew; dzmin=BETA*(1+cxxabs(xnewr,xnewi)); while (!aborted) { abs_p1new=cxxabs(p1r,p1i); iter++; if (abs_pnew>abs_pold) /* Spiraling */ { i=0; temp=dxr; dxr=QR*dxr-QI*dxi; dxi=QR*dxi+QI*temp; } else /* Newton step */ { dzmax=1.0+cxxabs(xnewr,xnewi); h1=p1r*p1r-p1i*p1i-pr*p2r+pi*p2i; h2=2*p1r*p1i-pr*p2i-pi*p2r; if (abs_p1new>10*ss && cxxabs(h1,h2)>100*ss*ss) /* do a Newton step */ { i++; if (i>2) i=2; tempr=pr*p1r-pi*p1i; tempi=pr*p1i+pi*p1r; cxdiv(-tempr,-tempi,h1,h2,&dxr,&dxi); if (cxxabs(dxr,dxi)>dzmax) { temp=dzmax/cxxabs(dxr,dxi); dxr*=temp; dxi*=temp; i=0; } if (i==2 && cxxabs(dxr,dxi)0) { i=0; cxdiv(xnewr-xoldr,xnewi-xoldi,dxr,dxi,&h3,&h4); h3+=1; h1=h3*h3-h4*h4; h2=2*h3*h4; cxdiv(dxr,dxi,h1,h2,&h3,&h4); if (cxxabs(h3,h4)<50*dzmin) { dxr+=h3; dxi+=h4; } } xoldr=xnewr; xoldi=xnewi; abs_pold=abs_pnew; } else /* saddle point, minimize into direction pr+i*pi */ { i=0; h=dzmax/abs_pnew; dxr=h*pr; dxi=h*pi; xoldr=xnewr; xoldi=xnewi; abs_pold=abs_pnew; do { chorner(n,iu,ar,ai,xnewr+dxr,xnewi+dxi,&u,&v, &h,&h1,&h2,&h3,&h4); dxr*=2; dxi*=2; } while (fabs(cxxabs(u,v)/abs_pnew-1)5) break; if (iter>ITERMAX) { iter=0; if (abs_pnew<=abs_pnoted) break; abs_pnoted=abs_pnew; if (test_key()==escape) { error=700; return; } } } *x0r=xnewr; *x0i=xnewi; stop: ; /* chorner(n,iu,ar,ai,*x0r,*x0i,&pr,&pi,&p1r,&p1i,&p2r,&p2i,&ss); abs_pnew=cxxabs(pr,pi); printf("%20.5e +i* %20.5e, %20.5e\n", *x0r,*x0i,abs_pnew); */ } static void polydiv (int n, int iu, double *ar, double *ai, double x0r, double x0i) { int i; for (i=n-1; i>iu; i--) { ar[i]+=ar[i+1]*x0r-ai[i+1]*x0i; ai[i]+=ai[i+1]*x0r+ar[i+1]*x0i; } } void bauhuber (double *p, int n, double *result, int all, double startr, double starti) { double *ar,*ai,scalefak=1.0; int i; double x0r,x0i; ram=newram; if (ram+2*(n+1)*sizeof(double)>ramend) outofram(); ar=(double *)ram; ai=ar+n+1; for (i=0; i<=n; i++) { ar[i]=p[2*i]; ai[i]=p[2*i+1]; } /* scpoly(n,ar,ai,&scalefak); */ /* scalefak=1; */ x0r=startr; x0i=starti; for (i=0; i<(all?n:1); i++) { bauroot(n,i,ar,ai,&x0r,&x0i); ar[i]=scalefak*x0r; ai[i]=scalefak*x0i; if (error) { output("Bauhuber-Iteration failed!\n"); error=311; return; } polydiv(n,i,ar,ai,x0r,x0i); x0i=-x0i; } for (i=0; iramend) outofram(); for (i=0; iramend) outofram(); for (i=0; imaxi) { maxi=h; ipiv=i; } } if (maxiramend) outofram(); for (i=0; iramend) outofram(); for (i=0; imaxi) { maxi=h; ipiv=i; } } if (maxitype!=s_matrix) wrong_arg(); getmatrix(hd,&r,&c,&m); if (r!=c) wrong_arg(); if (r<2) { moveresult(st,hd); return; } hd1=new_matrix(r,r,""); if (error) return; m=matrixof(hd1); memmove(m,matrixof(hd),(long)r*r*sizeof(double)); while(1) { max=0.0; for (i=0; imax) max=neumax; if (max