EVSL  1.1.0
EigenValues Slicing Library
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
Lan_MMRLanR.c
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <sys/stat.h>
5 #include <math.h>
6 #include "io.h"
7 #include "evsl.h"
8 #include "evsl_direct.h"
9 
10 #define max(a, b) ((a) > (b) ? (a) : (b))
11 #define min(a, b) ((a) < (b) ? (a) : (b))
12 
13 /*-------------------- Protos */
14 int read_coo_MM(const char *matfile, int idxin, int idxout, cooMat *Acoo);
15 int get_matrix_info(FILE *fmat, io_t *pio);
16 /*-------------------- End Protos */
17 
18 int main() {
19  /*--------------------------------------------------------------
20  * this tests the spectrum slicing idea for a generic matrix pair
21  * read in matrix format -- using
22  * Thick-Restarted Lanczos with rational filtering.
23  *-------------------------------------------------------------*/
24  int n = 0, i, j, npts, nslices, nvec, nev, mlan, max_its, ev_int, sl, ierr,
25  totcnt;
26  /* find the eigenvalues of A in the interval [a,b] */
27  double a, b, lmax, lmin, ecount, tol, *sli;
28  double xintv[4];
29  double *alleigs;
30  int *counts; // #ev computed in each slice
31  /* initial vector: random */
32  double *vinit;
33  /* parameters for rational filter */
34  int num = 1; // number of poles used for each slice
35  int pow = 2; // multiplicity of each pole
36  double beta = 0.01; // beta in the LS approximation
37  /*-------------------- matrices A, B: coo format and csr format */
38  cooMat Acoo, Bcoo;
39  csrMat Acsr, Bcsr, Acsr0, Bcsr0;
40  double *sqrtdiag = NULL;
41  /* slicer parameters */
42  int msteps = 40;
43  nvec = 10;
44  npts = 200;
45  FILE *flog = stdout, *fmat = NULL;
46  FILE *fstats = NULL;
47  io_t io;
48  const int degB = 200; // Max degree to aproximate B with
49  const double tau = 1e-4; // Tolerance in polynomial approximation
50  int numat, mat;
51  char line[MAX_LINE];
52 #if CXSPARSE == 1
53  printf("-----------------------------------------\n");
54  printf("Note: You are using CXSparse for the direct solver. \n We recommend a more performance based direct solver for anything more than basic tests. \n SuiteSparse is supported with a makefile change. \n Using SuiteSparse can result in magnitudes faster times. \n\n");
55  printf("-----------------------------------------\n");
56 #endif
57  /*-------------------- stopping tol */
58  tol = 1e-6;
59  /*-------------------- Polynomial approximation to B and sqrtB*/
60  BSolDataPol Bsol, Bsqrtsol;
61  /*-------------------- start EVSL */
62  EVSLStart();
63  /*------------------ file "matfile" contains paths to matrices */
64  if (NULL == (fmat = fopen("matfile", "r"))) {
65  fprintf(flog, "Can't open matfile...\n");
66  exit(2);
67  }
68  /*-------------------- read number of matrices ..*/
69  memset(line, 0, MAX_LINE);
70  if (NULL == fgets(line, MAX_LINE, fmat)) {
71  fprintf(flog, "error in reading matfile...\n");
72  exit(2);
73  }
74  if ((numat = atoi(line)) <= 0) {
75  fprintf(flog, "Invalid count of matrices...\n");
76  exit(3);
77  }
78  for (mat = 1; mat <= numat; mat++) {
79  if (get_matrix_info(fmat, &io) != 0) {
80  fprintf(flog, "Invalid format in matfile ...\n");
81  exit(5);
82  }
83  /*----------------input matrix and interval information -*/
84  fprintf(flog, "MATRIX A: %s...\n", io.MatNam1);
85  fprintf(flog, "MATRIX B: %s...\n", io.MatNam2);
86  a = io.a; // left endpoint of input interval
87  b = io.b; // right endpoint of input interval
88  nslices = io.n_intv;
89 
90  struct stat st = {0}; /* Make sure OUT directory exists */
91  if (stat("OUT", &st) == -1) {
92  mkdir("OUT", 0750);
93  }
94 
95  char path[1024]; // path to write the output files
96  strcpy(path, "OUT/Lan_MMRLanR_");
97  strcat(path, io.MatNam1);
98  fstats = fopen(path, "w"); // write all the output to the file io.MatNam
99  if (!fstats) {
100  printf(" failed in opening output file in OUT/\n");
101  fstats = stdout;
102  }
103  fprintf(fstats, "MATRIX A: %s...\n", io.MatNam1);
104  fprintf(fstats, "MATRIX B: %s...\n", io.MatNam2);
105  fprintf(fstats, "Partition the interval of interest [%f,%f] into %d slices\n",
106  a, b, nslices);
107  counts = malloc(nslices * sizeof(int));
108  /*-------------------- Read matrix - case: COO/MatrixMarket formats */
109  if (io.Fmt > HB) {
110  ierr = read_coo_MM(io.Fname1, 1, 0, &Acoo);
111  if (ierr == 0) {
112  fprintf(fstats, "matrix read successfully\n");
113  n = Acoo.nrows;
114  } else {
115  fprintf(flog, "read_coo error for A = %d\n", ierr);
116  exit(6);
117  }
118  ierr = read_coo_MM(io.Fname2, 1, 0, &Bcoo);
119  if (ierr == 0) {
120  fprintf(fstats, "matrix read successfully\n");
121  if (Bcoo.nrows != n) {
122  return 1;
123  }
124  } else {
125  fprintf(flog, "read_coo error for B = %d\n", ierr);
126  exit(6);
127  }
128  /*------------------ diagonal scaling for Acoo and Bcoo */
129  sqrtdiag = (double *)calloc(n, sizeof(double));
130  /*------------------ conversion from COO to CSR format */
131  ierr = cooMat_to_csrMat(0, &Acoo, &Acsr);
132  ierr = cooMat_to_csrMat(0, &Bcoo, &Bcsr);
133  } else if (io.Fmt == HB) {
134  fprintf(flog, "HB FORMAT not supported (yet) * \n");
135  exit(7);
136  }
137 
138  /*-------------------- diagonal scaling for L-S poly. approx.
139  * of B^{-1} and B^{-1/2},
140  * which will be used in the DOS */
141  /*-------------------- sqrt of diag(B) */
142  extrDiagCsr(&Bcsr, sqrtdiag);
143  for (i=0; i<n; i++) {
144  sqrtdiag[i] = sqrt(sqrtdiag[i]);
145  }
146  /*-------------------- backup A and B */
147  csr_copy(&Acsr, &Acsr0, 1); /* 1 stands for memory alloc */
148  csr_copy(&Bcsr, &Bcsr0, 1);
149  /*-------------------- Scale A and B */
150  diagScalCsr(&Acsr, sqrtdiag);
151  diagScalCsr(&Bcsr, sqrtdiag);
152  if (sqrtdiag) {
153  free(sqrtdiag);
154  }
155 
156  /*---------------- Set EVSL to solve std eig problem to
157  *---------------- compute the range of the spectrum of B */
158  SetStdEig();
159  SetAMatrix(&Bcsr);
160  vinit = (double *)malloc(n * sizeof(double));
161  rand_double(n, vinit);
162  ierr = LanTrbounds(50, 200, 1e-10, vinit, 1, &lmin, &lmax, fstats);
163  /*-------------------- Use polynomial to solve B and sqrt(B) */
164  /*-------------------- Setup the Bsol and Bsqrtsol struct */
165  SetupPolRec (n, degB, tau, lmin, lmax, &Bsol);
166  SetupPolSqrt(n, degB, tau, lmin, lmax, &Bsqrtsol);
167  SetBSol (BSolPol, (void *)&Bsol);
168  SetLTSol(BSolPol, (void *)&Bsqrtsol);
169  printf("The degree for LS polynomial approximations to B^{-1} and B^{-1/2} "
170  "are %d and %d\n", Bsol.deg, Bsqrtsol.deg);
171  /*-------------------- set the left-hand side matrix A */
172  SetAMatrix(&Acsr);
173  /*-------------------- set the right-hand side matrix B */
174  SetBMatrix(&Bcsr);
175  /*-------------------- for generalized eigenvalue problem */
176  SetGenEig();
177  /*-------------------- step 0: get eigenvalue bounds */
178  //-------------------- initial vector
179  rand_double(n, vinit);
180  ierr = LanTrbounds(50, 200, 1e-10, vinit, 1, &lmin, &lmax, fstats);
181  fprintf(fstats, "Step 0: Eigenvalue bound s for B^{-1}*A: [%.15e, %.15e]\n",
182  lmin, lmax);
183  /*-------------------- interval and eig bounds */
184  xintv[0] = a;
185  xintv[1] = b;
186  xintv[2] = lmin;
187  xintv[3] = lmax;
188  /*-------------------- call landos to get the DOS for dividing the
189  * spectrum*/
190  /*-------------------- define landos parameters */
191  double t = evsl_timer();
192  double *xdos = (double *)malloc(npts* sizeof(double));
193  double *ydos = (double *)malloc(npts* sizeof(double));
194  ierr = LanDosG(nvec, msteps, npts, xdos, ydos, &ecount, xintv);
195  t = evsl_timer() - t;
196  if (ierr) {
197  printf("Landos error %d\n", ierr);
198  return 1;
199  }
200  fprintf(fstats, " Time to build DOS (Landos) was : %10.2f \n", t);
201  fprintf(fstats, " estimated eig count in interval: %.15e \n", ecount);
202  //-------------------- call splicer to slice the spectrum
203  sli = malloc((nslices + 1) * sizeof(double));
204  fprintf(fstats, "DOS parameters: msteps = %d, nvec = %d, npnts = %d\n",
205  msteps, nvec, npts);
206  spslicer2(xdos, ydos, nslices, npts, sli);
207  printf("==================== SLICES FOUND ====================\n");
208  for (j = 0; j < nslices; j++) {
209  printf(" %2d: [% .15e , % .15e]\n", j + 1, sli[j], sli[j + 1]);
210  }
211  /*-------------------- DONE WITH DOS */
212  FreeBSolPolData(&Bsol);
213  FreeBSolPolData(&Bsqrtsol);
214 
215  //-------------------- # eigs per slice
216  ev_int = (int)(1 + ecount / ((double)nslices));
217  totcnt = 0;
218  alleigs = malloc(n * sizeof(double));
219 
220  /* recover the original matrices A and B before scaling
221  * Note that B-sol and sqrt(B)-sol will not be needed in RatLan,
222  * so we can recover them */
223  csr_copy(&Acsr0, &Acsr, 0); /* 0 stands for no memory alloc */
224  csr_copy(&Bcsr0, &Bcsr, 0);
225 
226  //-------------------- For each slice call RatLanrNr
227  for (sl = 0; sl < nslices; sl++) {
228  printf("======================================================\n");
229  int nev2;
230  double *lam, *Y, *res;
231  int *ind;
232  //--------------------
233  a = sli[sl];
234  b = sli[sl + 1];
235  printf(" subinterval: [%.4e , %.4e]\n", a, b);
236  double intv[4];
237  intv[0] = a;
238  intv[1] = b;
239  intv[2] = lmin;
240  intv[3] = lmax;
241  // find the rational filter on this slice
242  ratparams rat;
243  // setup default parameters for rat
244  set_ratf_def(&rat);
245  // change some default parameters here:
246  rat.pw = pow;
247  rat.num = num;
248  rat.beta = beta;
249  // now determine rational filter
250  find_ratf(intv, &rat);
251  // use direct solver function
252  void **solshiftdata = (void **)malloc(num * sizeof(void *));
253  /*------------ factoring the shifted matrices and store the factors */
254  SetupASIGMABSolDirect(&Acsr, &Bcsr, num, rat.zk, solshiftdata);
255  /*------------ give the data to rat */
256  SetASigmaBSol(&rat, NULL, ASIGMABSolDirect, solshiftdata);
257  //-------------------- approximate number of eigenvalues wanted
258  nev = ev_int + 2;
259  //-------------------- Dimension of Krylov subspace and maximal iterations
260  mlan = max(4 * nev, 100);
261  mlan = min(mlan, n);
262  max_its = 3 * mlan;
263  //-------------------- RationalLanNr
264  ierr = RatLanTr(mlan, nev, intv, max_its, tol, vinit, &rat, &nev2, &lam,
265  &Y, &res, fstats);
266  if (ierr) {
267  printf("RatLanNr error %d\n", ierr);
268  return 1;
269  }
270 
271  /* sort the eigenvals: ascending order
272  * ind: keep the orginal indices */
273  ind = (int *)malloc(nev2 * sizeof(int));
274  sort_double(nev2, lam, ind);
275  printf(" number of eigenvalues found: %d\n", nev2);
276  /* print eigenvalues */
277  fprintf(fstats, " Eigenvalues in [a, b]\n");
278  fprintf(fstats, " Computed [%d] ||Res||\n", nev2);
279  for (i = 0; i < nev2; i++) {
280  fprintf(fstats, "% .15e %.1e\n", lam[i], res[ind[i]]);
281  }
282  fprintf(fstats, "- - - - - - - - - - - - - - - - - - - - - - - - - - - - "
283  "- - - - - - - - - - - - - - - - - -\n");
284  memcpy(&alleigs[totcnt], lam, nev2 * sizeof(double));
285  totcnt += nev2;
286  counts[sl] = nev2;
287  //-------------------- free allocated space withing this scope
288  if (lam)
289  free(lam);
290  if (Y)
291  free(Y);
292  if (res)
293  free(res);
294  FreeASIGMABSolDirect(rat.num, solshiftdata);
295  free(solshiftdata);
296  free_rat(&rat);
297  free(ind);
298  } // for (sl=0; sl<nslices; sl++)
299  //-------------------- free other allocated space
300  fprintf(fstats, " --> Total eigenvalues found = %d\n", totcnt);
301  sprintf(path, "OUT/EigsOut_Lan_MMRLanR_(%s_%s)", io.MatNam1, io.MatNam2);
302  FILE *fmtout = fopen(path, "w");
303  if (fmtout) {
304  for (j = 0; j < totcnt; j++)
305  fprintf(fmtout, "%.15e\n", alleigs[j]);
306  fclose(fmtout);
307  }
308  free(vinit);
309  free(sli);
310  free_coo(&Acoo);
311  free_csr(&Acsr);
312  free_coo(&Bcoo);
313  free_csr(&Bcsr);
314  free_csr(&Acsr0);
315  free_csr(&Bcsr0);
316  free(alleigs);
317  free(counts);
318  free(xdos);
319  free(ydos);
320  if (fstats != stdout) {
321  fclose(fstats);
322  }
323  /*-------------------- end matrix loop */
324  }
325  if (flog != stdout) {
326  fclose(flog);
327  }
328  fclose(fmat);
329  /*-------------------- finalize EVSL */
330  EVSLFinish();
331  return 0;
332 }
void free_coo(cooMat *coo)
memory deallocation for coo matrix
Definition: spmat.c:126
void ASIGMABSolDirect(int n, double *br, double *bi, double *xr, double *xz, void *data)
complex linear solver routine passed to evsl
double b
Definition: io.h:25
complex double * zk
Definition: struct.h:126
int get_matrix_info(FILE *fmat, io_t *pio)
Definition: io.c:22
#define MAX_LINE
Definition: io.h:5
int num
Definition: struct.h:114
void free_rat(ratparams *rat)
Definition: ratfilter.c:424
void extrDiagCsr(csrMat *B, double *d)
Definition: spmat.c:406
int SetGenEig()
Set the problem to generalized eigenvalue problem.
Definition: evsl.c:158
int SetupASIGMABSolDirect(csrMat *A, csrMat *BB, int num, complex double *zk, void **data)
setup CXsparse solver for A - SIGMA B
int SetAMatrix(csrMat *A)
Set the matrix A.
Definition: evsl.c:68
void rand_double(int n, double *v)
Definition: vect.c:11
int Fmt
Definition: io.h:20
int cooMat_to_csrMat(int cooidx, cooMat *coo, csrMat *csr)
convert coo to csr
Definition: spmat.c:135
int LanTrbounds(int lanm, int maxit, double tol, double *vinit, int bndtype, double *lammin, double *lammax, FILE *fstats)
Lanczos process for eigenvalue bounds [Thick restart version].
Definition: lanTrbounds.c:38
void FreeASIGMABSolDirect(int num, void **data)
free the data needed by CXSparse
#define min(a, b)
Definition: Lan_MMRLanR.c:11
int SetBMatrix(csrMat *B)
Set the B matrix.
Definition: evsl.c:83
char Fname1[MAX_LINE]
Definition: io.h:17
void sort_double(int n, double *v, int *ind)
Definition: vect.c:92
void spslicer2(double *xi, double *yi, int n_int, int npts, double *sli)
Definition: spslice2.c:29
int EVSLStart()
Initialize evslData.
Definition: evsl.c:27
int pw
Definition: struct.h:115
char Fname2[MAX_LINE]
Definition: io.h:19
void free_csr(csrMat *csr)
memory deallocation for csr matrix
Definition: spmat.c:91
char MatNam2[MaxNamLen]
Definition: io.h:20
#define HB
Definition: io.h:7
void diagScalCsr(csrMat *A, double *d)
Definition: spmat.c:390
void SetupPolSqrt(int n, int max_deg, double tol, double lmin, double lmax, BSolDataPol *data)
Definition: dos_utils.c:45
int LanDosG(const int nvec, const int msteps, int npts, double *xdos, double *ydos, double *neig, const double *const intv)
Definition: landosG.c:43
int SetLTSol(SolFuncR func, void *data)
Set the solve routine for LT.
Definition: evsl.c:185
int SetStdEig()
Set the problem to standard eigenvalue problem.
Definition: evsl.c:148
sparse matrix format: the compressed sparse row (CSR) format, 0-based
Definition: struct.h:31
int read_coo_MM(const char *matfile, int idxin, int idxout, cooMat *Acoo)
Definition: io.c:66
This file contains function prototypes and constant definitions for EVSL.
Definition: io.h:14
int EVSLFinish()
Finish EVSL.
Definition: evsl.c:48
int SetBSol(SolFuncR func, void *data)
Set the solve routine and the associated data for B.
Definition: evsl.c:132
double a
Definition: io.h:24
int RatLanTr(int lanm, int nev, double *intv, int maxit, double tol, double *vinit, ratparams *rat, int *nev2, double **vals, double **W, double **resW, FILE *fstats)
RatLanTR filtering Lanczos process [Thick restart version].
Definition: ratlanTr.c:61
int nrows
Definition: struct.h:17
double beta
Definition: struct.h:117
#define max(a, b)
Definition: Lan_MMRLanR.c:10
void set_ratf_def(ratparams *rat)
Sets default values for ratparams struct.
Definition: ratfilter.c:345
int main()
Definition: Lan_MMRLanR.c:18
int SetASigmaBSol(ratparams *rat, SolFuncC *func, SolFuncC allf, void **data)
Set the solve routine and the associated data for A-SIGMA*B if func == NULL, set all functions to be ...
Definition: evsl.c:168
Definitions used for direct solver interface.
void csr_copy(csrMat *A, csrMat *B, int allocB)
copy a csr matrix A into B alloB: 0: will not allocate memory for B (have been alloced outside) 1: wi...
Definition: spmat.c:106
void BSolPol(double *b, double *x, void *data)
Definition: dos_utils.c:61
int find_ratf(double *intv, ratparams *rat)
Definition: ratfilter.c:375
void SetupPolRec(int n, int max_deg, double tol, double lmin, double lmax, BSolDataPol *data)
Definition: dos_utils.c:37
void FreeBSolPolData(BSolDataPol *data)
Definition: dos_utils.c:53
sparse matrix format: the coordinate (COO) format, 0-based
Definition: struct.h:16
double evsl_timer()
evsl timer for mac
Definition: mactime.c:14
int n_intv
Definition: io.h:23
parameters for rational filter
Definition: struct.h:112
char MatNam1[MaxNamLen]
Definition: io.h:18