#include /* Package contains following functions in addition to function hichol */ int hi_prep(double vd[],unsigned long iv[],unsigned short jv[],double rd[], unsigned short ni[],unsigned short ns,unsigned short nm, float v[],float t[],float r[],float s[]); int hi_chol(float v[],unsigned long iv[],unsigned short jv[], unsigned short ir,unsigned short nr,unsigned short mb, float t[],unsigned short nm,unsigned short nb); int cholesky(float t[],unsigned short n); int hi_solve(float v[],unsigned long iv[],unsigned short jv[], unsigned short ni[],unsigned short ns,unsigned short nm, float t[],float r[],float s[]); int hi_res(double vd[],unsigned long iv[],unsigned short jv[],double rd[], double rn[],float s[],float r[],unsigned short nm); int hichol(float v[],unsigned long iv[],unsigned short jv[], unsigned short ni[],unsigned short ns,unsigned short nm, float t[]) { unsigned short i; unsigned short nb,ib,nr,mb,np; /* Performs Cholesky-decomposition of sparse matrices. Matrix must be positive definite, symmetric doubly-bordered block diagonal. Diagonal blocks can have different sizes. Border band may be sparse too, but must consist of blocks with vertical extent matching the corresponding diagonal block. The upper triangle of the matrix is stored in row-wise format in v[], except for the upper triangle of the lower right block formed by the overlap of both borders, which is stored row-wise in t[]. The storage of the former must account for zeros in lower right part; the latter must be filled, i.e. non-sparse. The transpose of v[] is vt[]. iv[] indicates position in v[], where row i begins, jv[] gives column number of element v[i]. Dimension of the matrix is nm. There are ns diagonal blocks, each with dimension ni[i]. (All arrays [0..N-1].) */ /* Calculate number of columns in border band of matrix. This is the dimension of matrix t[] at the same time. */ nb=0; for(i=1;i<=ns;i++){nb+=ni[i];} nb=nm-nb; /* Calculate decomposition down to lower right triangle.*/ ib=1; /* We start with first block */ nr=ni[ib]; /* Number of rows in block to operate on */ mb=iv[2]-iv[1]-nr; /* Number of non-zero columns in border block */ np=nm-nb; for(i=1;i<=np;i++){ hi_chol(v,iv,jv,i,nr,mb,t,nm,nb); nr-=1; if(nr==0){ ib+=1; nr=ni[ib]; mb=iv[i+2]-iv[i+1]-nr; } } /* Calculate decomposition of lower right triangle */ cholesky(t,nb); return 0; } int hi_prep(double vd[],unsigned long iv[],unsigned short jv[],double rd[], unsigned short ni[],unsigned short ns,unsigned short nm, float v[],float t[],float r[],float s[]) { unsigned short nb,np; unsigned long i,j,ii,jj; unsigned long nv; /* Preparation for HICHOL. Copy vd into v except for lower right triangle, which is expanded and copied into t. Set r and initialize s. */ nb=0; for(i=1;i<=ns;i++){nb+=ni[i];} nb=nm-nb; /* Number of border columns */ np=nm-nb; /* Number of columns in block diagonal part */ /* Fill in v */ for(i=1;i0;i--){ t[ii]=sqrt(t[ii]); t1=1.0/t[ii]; for(j=ii+1;jnp;i--){ sum=r[i]; k=i-np; for(j=i+1;j<=nm;j++){ l=j-np; sum-=t[(k-1)*nb-(k-1)*(k-2)/2+1+l-k]*r[j]; } r[i]=sum/t[(k-1)*nb-(k-1)*(k-2)/2+1]; } /* ...and in triangle */ for(i=np;i>0;i--){ sum=r[i]; for(j=iv[i]+1;j<=iv[i+1]-1;j++){ sum-=v[j]*r[jv[j]]; } r[i]=sum/v[iv[i]]; } for(i=1;i<=nm;i++){s[i]-=r[i];} return 0; } int hi_res(double vd[],unsigned long iv[],unsigned short jv[], double rd[],double rn[],float s[],float r[],unsigned short nm) { double sum; unsigned short i; unsigned long j; /* Calculate residual of vd*s from right hand side rd and prepare new right hand side r for calculation of improved solution with hi_solve. */ for(i=1;i<=nm;i++){ sum=-rd[i]; for(j=iv[i];jtiny); ev=sum; printf("\nLargest eigenvalue = %lf",ev); sum=0.0; for(i=1;i<=nm;i++){sum+=w[i];} /* components of u assumed = 1! */ for(i=1;i<=nm;i++){u[i]-=sum*w[i];} return 0; }