Hi,
I ran into an issue with the sparse FEAST implementation of "dfeast_scsrev"& "dfeast_scsrgv".
The actual matrix I need eigen-decomposed is of size 4096 x 4096. Here is a test case that
presents the same problem:
A = [ 1 1 0
1 0 0
0 0 0]
In CSR format A is:
vals=(1, 1, 1)
rows=(1, 3, 4)
cols=(1, 2, 1).
Now this does not take in to accoun the third row and column of all zeros. In fact, in CSR format
it is no different than:
A'= [ 1 1
1 0].
However, for my problem, I can't simply truncate the Hilbert space, it is imperative that I return
an eigenvalue of 0. The dense version of FEAST( dfeast_syev) can eigen-decompose both these matrices,
however, the sparse version can only do the latter, not the former. It just hangs. Please let me know
of any suggestions! Thank you!
Here is the source code for the general version of Sparse:
Version: icc version 13.1.0 (gcc version 4.4.7 compatibility)
///////////Trial for Sparse General///////////
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <mkl.h>
#include <vector>
#include <vector>
using namespace std;
void convertDense2CSR( double *A, int N, vector<double> &Values, vector<int> &Rows, vector<int> &Cols) {
// Convert matrix A (dense format) to CSR
Values.clear();
Rows.clear();
Cols.clear();
int nnz = 0;
int lastRow = -1;
for (int i=0; i<N; i++) {
for (int j=0; j<N; j++) {
if (A[i*N+j] != 0) {
Values.push_back( A[i*N+j] );
Cols.push_back( j+1 );
if (i != lastRow) {
Rows.push_back( nnz+1 );
}
nnz++;
lastRow = i;
}
}
}
Rows.push_back( nnz+1 );
}
int main()
{
int N = 3;
int i, j;
double A[9] = {1, 1, 0, 1, 0, 0, 0, 0, 0};
double B[9] = {1, 0, 0, 0, 1, 0, 0, 0, 1};
printf ("'A: \n\n");
for (i=0; i<3; i++) {
for (j=0; j<3; j++) {
printf ("%12.4f", A[i*N+j]);
}
printf ("\n");
}
printf (" B: \n\n");
for (i=0; i<3; i++) {
for (j=0; j<3; j++) {
printf ("%12.4f", B[i*N+j]);
}
printf ("\n");
}
////////////////////////////////
/////////////FEAST//////////////
////////////////////////////////
/* EIGEN-VALUE SYSTEM*/
int LDA = N;
char UPLO = 'F';
double Emin = -10.0, Emax = 10.0;
int M0 = N;
/* INPUT PARAMETERS FOR FEAST*/
int feastparam[128];
/* OUTPUT VARIABLES FOR FEAST*/
double *E, *res, *X;
double epsout, trace;
int loop, info, M;
/*Allocate memory for eigenvaluues. eigenvectors/residuals*/
/* Note: I'm doing this differently than the example*/
E = (double *)calloc( M0*sizeof( double ), 64 ); //eigenvalues
res = (double *)calloc( M0*sizeof( double ), 64 ); //residuals
X = (double *)calloc( M0*M0*sizeof( double ), 64 ); //eigenvectors
/* !!!!!!!!!!!!! FEAST !!!!!!!!!!!!!!!!! */
FEASTINIT(feastparam);
feastparam[0] = 0; // change default value
//feastparam[5] = 0; // change default value
dfeast_syev( &UPLO, &N, A, &LDA, feastparam, &epsout, &loop, &Emin, &Emax, &M0, E, X, &M, res, &info );
///*
printf("\nReport using Dense version:\n");
printf(" Eigenvalues\n\n");
for (i=0; i<N; i++) {
printf ("%12.5f \n", E[i]);
}
printf("\n");//*/
///*
printf ("'X' Eigenvectors \n\n");
for (i=0; i<N; i++) {
for (j=0; j<N; j++) {
printf ("%12.4f", X[i*N+j]);
}
printf ("\n");
}
//*/
printf("\nReport using General Sparse version:\n");
//char UPLO = 'F';
//double Emin = -10.0, Emax = 10.0;
int M01 = N;
/* INPUT PARAMETERS FOR FEAST*/
//int feastparam[128];
/* OUTPUT VARIABLES FOR FEAST*/
double *E1, *res1, *X1;
double epsout1, trace1;
int loop1, info1, M1;
/*Allocate memory for eigenvaluues. eigenvectors/residuals*/
vector<double> Values;
vector<int> Cols, Rows;
vector<double> ValuesB;
vector<int> ColsB, RowsB;
convertDense2CSR( A, N, Values, Rows, Cols );
convertDense2CSR( B, N, ValuesB, RowsB, ColsB );
/*
cout << "Set CSR version of A. We have, values: "<< endl;
for (int i=0; i< Values.size(); i++) {
cout << Values.at(i) << " ";
} cout << endl;
cout << "We have, cols: "<< endl;
for (int i=0; i< Cols.size(); i++) {
cout << Cols.at(i) << " ";
} cout << endl;
cout << "We have, rows: "<< endl;
for (int i=0; i< Rows.size(); i++) {
cout << Rows.at(i) << " ";
} cout << endl;
*/
E1 = (double *)calloc( M01*sizeof( double ), 64 ); //eigenvalues
res1 = (double *)calloc( M01*sizeof( double ), 64 ); //residuals
X1 = (double *)calloc( M01*M01*sizeof( double ), 64 ); //eigenvectors
/* !!!!!!!!!!!!! FEAST !!!!!!!!!!!!!!!!! */
FEASTINIT(feastparam);
feastparam[0] = 0; // change default value
printf("FEAST OUTPUT INFO %d \n",info);
dfeast_scsrgv(&UPLO,&N,(&Values[0]),(&Rows[0]),(&Cols[0]),(&ValuesB[0]),(&RowsB[0]),(&ColsB[0]) ,feastparam,&epsout1,&loop1,&Emin,&Emax,&M01,E1,X1,&M1,res1,&info1);
if ( info1 != 0 ){ return 1;
}
printf(" EigenValues2: \n");
for (i=0; i<N; i++) {
printf ("%12.5f", E1[i]);
}
printf("\n Eigenvector matrix X2: \n");
for (i=0; i<N; i++) {
for (j=0; j<N; j++) {
printf ("%12.4f", X1[j+i*N]);
}
printf("\n");
}
}