ATSuite C++  v1.0
Scientific C++ routines originally developed by Alexis Tantet
atspectrum.hpp
Go to the documentation of this file.
1 #ifndef ATSPECTRUM_HPP
2 #define ATSPECTRUM_HPP
3 
4 #include <cstdlib>
5 #include <cstdio>
6 #include <vector>
7 #include <Eigen/Sparse>
8 #include <arpack++/arlnsmat.h>
9 #include <arpack++/arlssym.h>
10 #include <ATSuite/atio.hpp>
11 
19 // Typedef declaration
21 typedef SparseMatrix<double, RowMajor> SpMatCSR;
23 typedef SparseMatrix<double, ColMajor> SpMatCSC;
24 
25 // Class declarations
31 class configAR {
32 public:
33  std::string which_;
34  int ncv_ = 0;
35  double tol_ = 0.;
36  int maxit_ = 0;
37  double *resid_ = NULL;
38  bool AutoShift_ = true;
39  configAR(const std::string&, int, double, int, double *, bool);
40 };
41 
42 // Function declarations
43 ARluNonSymMatrix<double, double> * pajek2AR(FILE *);
44 ARluNonSymMatrix<double, double> * Eigen2AR(SpMatCSC *);
45 ARluNonSymMatrix<double, double> * Eigen2AR(SpMatCSR *);
46 ARluSymMatrix<double> * Eigen2ARSym(SpMatCSC *);
47 ARluSymMatrix<double> * Eigen2ARSym(SpMatCSR *);
48 ARluNonSymMatrix<double, double> * Compressed2AR(FILE *);
49 int getSpectrum(ARluNonSymMatrix<double, double> *, int, configAR, double *, double *, double *);
50 void writeSpectrum(FILE *, FILE *, double *, double *, double *, int, size_t);
51 
52 // Definitions
58 configAR::configAR(const std::string& which="LM", int ncv=0, double tol=0.,
59  int maxit=0, double *resid=NULL, bool AutoShift=true)
60 {
61  which_ = which;
62  ncv_ = ncv;
63  tol_ = tol;
64  maxit_ = maxit;
65  resid_ = resid;
66  AutoShift_ = AutoShift;
67 }
68 
79 ARluNonSymMatrix<double, double> *pajek2AR(FILE *fp)
80 {
81  // The edge entries must be ordered by row and then by col.
82  char label[20];
83  int N, E, row, col;
84  double val;
85  int *irow, *pcol;
86  double *nzval;
87  ARluNonSymMatrix<double, double> *T = new ARluNonSymMatrix<double, double>;
88 
89  // Read vertices
90  fscanf(fp, "%s %d", label, &N);
91  pcol = new int [N+1];
92 
93  // Read first (assume monotonous)
94  for (int k = 0; k < N; k++)
95  fscanf(fp, "%d %s", &row, label);
96 
97  // Read number of edges
98  fscanf(fp, "%s %d", label, &E);
99  irow = new int [E];
100  nzval = new double [E];
101  for (int k = 0; k < N+1; k++)
102  pcol[k] = E;
103 
104  // Read edges
105  for (int k = 0; k < E; k++){
106  fscanf(fp, "%d %d %lf", &row, &col, &val);
107  irow[k] = row;
108  printf("irow[%d] = %d\n", k, row);
109  nzval[k] = val;
110  if (k < pcol[col])
111  pcol[col] = k;
112  }
113 
114  // Define matrix, order=2 for degree ordering of A.T + A (good for transition mat)
115  T->DefineMatrix(N, E, nzval, irow, pcol, 0.1, 2, true);
116 
117  return T;
118 }
119 
129 ARluNonSymMatrix<double, double> * Compressed2AR(FILE *fp)
130 {
131  int innerSize, outerSize, nnz;
132  char sparseType[4];
133  double *nzval;
134  int *irow, *pcol;
135  ARluNonSymMatrix<double, double> *T = new ARluNonSymMatrix<double, double>;
136 
137  // Read type, inner size, outer size and number of non-zeros and allocate
138  fscanf(fp, "%s %d %d %d", sparseType, &innerSize, &outerSize, &nnz);
139  nzval = new double [nnz];
140  irow = new int [nnz];
141  pcol = new int[outerSize+1];
142 
143  // Read values
144  for (int nz = 0; nz < nnz; nz++)
145  fscanf(fp, "%lf ", &nzval[nz]);
146 
147  // Read row indices
148  for (int nz = 0; nz < nnz; nz++)
149  fscanf(fp, "%d ", &irow[nz]);
150 
151  // Read first element of column pointer
152  for (int outer = 0; outer < outerSize+1; outer++)
153  fscanf(fp, "%d ", &pcol[outer]);
154 
155  // Define matrix, order=2 for degree ordering of A.T + A (good for transition mat)
156  T->DefineMatrix(outerSize, nnz, nzval, irow, pcol, 0.1, 2, true);
157 
158  return T;
159 }
160 
168 ARluNonSymMatrix<double, double>* Eigen2AR(SpMatCSC *TEigen)
169 {
170  int outerSize, nnz;
171  double *nzval;
172  int *irow, *pcol;
173  ARluNonSymMatrix<double, double> *T = new ARluNonSymMatrix<double, double>;
174 
175  outerSize = TEigen->outerSize();
176  nnz = TEigen->nonZeros();
177  nzval = new double [nnz];
178  irow = new int [nnz];
179  pcol = new int [outerSize+1];
180 
181  // Set values
182  nzval = TEigen->valuePtr();
183 
184  // Set inner indices
185  irow = TEigen->innerIndexPtr();
186 
187  // Set first element of column pointer
188  pcol = TEigen->outerIndexPtr();
189 
190  // Define matrix, order=2 for degree ordering of A.T + A (good for transition mat)
191  T->DefineMatrix(outerSize, nnz, nzval, irow, pcol, 0.1, 2, true);
192 
193  return T;
194 }
195 
203 ARluNonSymMatrix<double, double>* Eigen2AR(SpMatCSR *TEigenCSR)
204 {
205  SpMatCSC *TEigen;
206  ARluNonSymMatrix<double, double> *T;
207 
208  // Convert from Eigen CSR to CSC
209  TEigen = CSR2CSC(TEigenCSR);
210 
211  // Convert from Eigen CSC to AR
212  T = Eigen2AR(TEigen);
213 
214  return T;
215 }
216 
224 ARluSymMatrix<double>* Eigen2ARSym(SpMatCSC *TEigen)
225 {
226  int outerSize, nnz;
227  double *nzval, *nzvalSym;
228  int *irow, *pcol, *irowSym, *pcolSym;
229  ARluSymMatrix<double> *T = new ARluSymMatrix<double>;
230  int nzIdx, nzSymIdx, innerIdx;
231  bool isNewCol;
232 
233  outerSize = TEigen->outerSize();
234  nnz = TEigen->nonZeros();
235  nzval = new double [nnz];
236  irow = new int [nnz];
237  pcol = new int [outerSize+1];
238  nzvalSym = new double [(int) ((nnz-outerSize)/2)+outerSize+1];
239  irowSym = new int [(int) ((nnz-outerSize)/2)+outerSize+1];
240  pcolSym = new int [outerSize+1];
241 
242  // Set values
243  nzval = TEigen->valuePtr();
244  // Set inner indices
245  irow = TEigen->innerIndexPtr();
246  // Set first element of column pointer
247  pcol = TEigen->outerIndexPtr();
248 
249  // Discard lower triangle
250  nzIdx = 0;
251  nzSymIdx = 0;
252  for (int outerIdx = 0; outerIdx < outerSize; outerIdx++){
253  isNewCol = true;
254  while (nzIdx < pcol[outerIdx+1]){
255  innerIdx = irow[nzIdx];
256  if (outerIdx >= innerIdx){
257  nzvalSym[nzSymIdx] = nzval[nzIdx];
258  irowSym[nzSymIdx] = irow[nzIdx];
259  if (isNewCol){
260  pcolSym[outerIdx] = nzSymIdx;
261  isNewCol = false;
262  }
263  nzSymIdx++;
264  }
265  nzIdx++;
266  }
267  // Check for empty column
268  if (isNewCol)
269  pcolSym[outerIdx] = nzSymIdx;
270  }
271  pcolSym[outerSize] = nzSymIdx;
272 
273  // Define matrix, order=2 for degree ordering of A.T + A (good for transition mat)
274  T->DefineMatrix(outerSize, nzSymIdx, nzvalSym, irowSym, pcolSym,
275  'U', 0.1, 2, true);
276 
277  return T;
278 }
279 
287 ARluSymMatrix<double>* Eigen2ARSym(SpMatCSR *TEigenCSR)
288 {
289  SpMatCSC *TEigen;
290  ARluSymMatrix<double> *T;
291 
292  // Convert from Eigen CSR to CSC
293  TEigen = CSR2CSC(TEigenCSR);
294 
295  // Convert from Eigen CSC to AR
296  T = Eigen2ARSym(TEigen);
297 
298  return T;
299 }
300 
313 int
314 getSpectrum(ARluNonSymMatrix<double, double> *P, int nev, configAR cfgAR,
315  double *EigValReal, double *EigValImag, double *EigVec)
316 {
317  ARluNonSymStdEig<double> EigProb;
318  int nconv;
319 
320  // Define eigen problem
321  EigProb = ARluNonSymStdEig<double>(nev, *P, cfgAR.which_, cfgAR.ncv_, cfgAR.tol_,
322  cfgAR.maxit_, cfgAR.resid_, cfgAR.AutoShift_);
323 
324  // Find eigenvalues and left eigenvectors
325  EigProb.EigenValVectors(EigVec, EigValReal, EigValImag);
326  nconv = EigProb.ConvergedEigenvalues();
327 
328 
329  return nconv;
330 }
331 
344 void writeSpectrum(FILE *fEigVal, FILE *fEigVec,
345  double *EigValReal, double *EigValImag,
346  double *EigVec, int nev, size_t N)
347 {
348  size_t vecCount = 0;
349  int ev =0;
350  // Write real and imaginary parts of each eigenvalue on each line
351  // Write on each pair of line the real part of an eigenvector then its imaginary part
352  while (ev < nev) {
353  // Always write the eigenvalue
354  fprintf(fEigVal, "%lf %lf\n", EigValReal[ev], EigValImag[ev]);
355  // Always write the real part of the eigenvector ev
356  for (size_t i = 0; i < N; i++){
357  fprintf(fEigVec, "%lf ", EigVec[vecCount*N+i]);
358  }
359  fprintf(fEigVec, "\n");
360  vecCount++;
361 
362  // Write its imaginary part or the zero vector
363  if (EigValImag[ev] != 0.){
364  for (size_t i = 0; i < N; i++)
365  fprintf(fEigVec, "%lf ", EigVec[vecCount*N+i]);
366  vecCount++;
367  // Skip the conjugate
368  ev += 2;
369  }
370  else{
371  for (size_t i = 0; i < N; i++)
372  fprintf(fEigVec, "%lf ", 0.);
373  ev += 1;
374  }
375  fprintf(fEigVec, "\n");
376  }
377 
378  return;
379 }
380 
381 #endif
SparseMatrix< double, RowMajor > SpMatCSR
Eigen sparse CSR matrix of double type.
Definition: atspectrum.hpp:21
bool AutoShift_
Shifts for the implicit restarting of the Arnoldi method.
Definition: atspectrum.hpp:38
void writeSpectrum(FILE *, FILE *, double *, double *, double *, int, size_t)
Write complex eigenvalues and eigenvectors from ARPACK++.
Definition: atspectrum.hpp:344
SpMatCSC * CSR2CSC(const SpMatCSR *T)
Convert an Eigen CSR matrix to an Eigen CSC matrix.
Definition: atio.hpp:372
int ncv_
The number of Arnoldi vectors generated at each iteration of ARPACK.
Definition: atspectrum.hpp:34
ARluNonSymMatrix< double, double > * pajek2AR(FILE *)
Scans an ARPACK++ nonsymmetric matrix from a Pajek file.
Definition: atspectrum.hpp:79
int getSpectrum(ARluNonSymMatrix< double, double > *, int, configAR, double *, double *, double *)
Get spectrum of a nonsymmetric matrix using ARPACK++.
Definition: atspectrum.hpp:314
configAR(const std::string &, int, double, int, double *, bool)
Main constructor.
Definition: atspectrum.hpp:58
std::string which_
Which eigenvalues to look for. &#39;LM&#39; for Largest Magnitude.
Definition: atspectrum.hpp:33
SparseMatrix< double, ColMajor > SpMatCSC
Eigen sparse CSC matrix of double type.
Definition: atspectrum.hpp:23
ARluNonSymMatrix< double, double > * Compressed2AR(FILE *)
Scans an ARPACK++ nonsymmetric matrix from a file in compressed format.
Definition: atspectrum.hpp:129
double tol_
The relative accuracy to which eigenvalues are to be determined.
Definition: atspectrum.hpp:35
Utility class used to give configuration options to ARPACK++.
Definition: atspectrum.hpp:31
ARluNonSymMatrix< double, double > * Eigen2AR(SpMatCSC *)
Converts an Eigen CSC matrix to an ARPACK++ nonsymmetric CSC matrix.
Definition: atspectrum.hpp:168
int maxit_
The maximum number of iterations allowed.
Definition: atspectrum.hpp:36
double * resid_
A starting vector for the Arnoldi process.
Definition: atspectrum.hpp:37
ARluSymMatrix< double > * Eigen2ARSym(SpMatCSC *)
Converts an Eigen CSC matrix to an ARPACK++ symmetric CSC matrix.
Definition: atspectrum.hpp:224
Eigen::SparseMatrix< double, Eigen::ColMajor > SpMatCSC
Eigen sparse CSC matrix of double type.
Definition: atio.hpp:27