23 void sse_op_callback(
const long* n,
28 assert(current_system !=
nullptr);
39 void sse_iovect_callback(
const long* n,
45 assert(current_system !=
nullptr);
54 : nvalues(0), vectors(nullptr), values(nullptr)
88 current_system =
this;
91 long nvals = (smallest)?-n:n;
95 std::vector<double> temp_vals(n*4);
96 std::vector<double> temp_vecs(n*dim);
99 long nblock = (dim<60) ? dim/6 : 10;
105 long maxj = maxop*nblock;
106 long t1 = 6*nblock+1;
107 if (maxj < t1) maxj = t1;
108 if (maxj < 40) maxj = 40;
112 int work_size = dim*nblock;
113 int t2 = maxj*(2*nblock+3) + 2*n + 6 + (2*nblock+2)*(nblock+1);
114 if (work_size < t2) work_size = t2;
115 work_size += 2*dim*nblock + maxj*(nblock + n + 2) + 2*nblock*nblock + 3*n;
116 std::vector<double> work(work_size+10);
119 for (
int i=0; i<dim*nblock; ++i)
122 std::vector<long> ind(n);
126 v3p_netlib_dnlaso_(sse_op_callback, sse_iovect_callback,
127 &dim, &nvals, &nfigures, &nperm,
128 &nmval, &temp_vals[0],
129 &nmvec, &temp_vecs[0],
139 std::cerr <<
"Error: vnl_sparse_symmetric_eigensystem: N < 6*NBLOCK\n";
141 std::cerr <<
"Error: vnl_sparse_symmetric_eigensystem: NFIG < 0\n";
143 std::cerr <<
"Error: vnl_sparse_symmetric_eigensystem: NMVEC < N\n";
145 std::cerr <<
"Error: vnl_sparse_symmetric_eigensystem: NPERM < 0\n";
147 std::cerr <<
"Error: vnl_sparse_symmetric_eigensystem: MAXJ < 6*NBLOCK\n";
149 std::cerr <<
"Error: vnl_sparse_symmetric_eigensystem: NVAL < max(1,NPERM)\n";
151 std::cerr <<
"Error: vnl_sparse_symmetric_eigensystem: NVAL > NMVAL\n";
153 std::cerr <<
"Error: vnl_sparse_symmetric_eigensystem: NVAL > MAXOP\n";
155 std::cerr <<
"Error: vnl_sparse_symmetric_eigensystem: NVAL > MAXJ/2\n";
157 std::cerr <<
"Error: vnl_sparse_symmetric_eigensystem: NBLOCK < 1\n";
162 std::cerr <<
"Error: vnl_sparse_symmetric_eigensystem:\n" 163 <<
" poor initial vectors chosen\n";
165 std::cerr <<
"Error: vnl_sparse_symmetric_eigensystem:\n" 166 <<
" reached maximum operations " << maxop
167 <<
" without finding all eigenvalues,\n" 168 <<
" found " << nperm <<
" eigenvalues\n";
170 std::cerr <<
"Error: vnl_sparse_symmetric_eigensystem:\n" 171 <<
" disastrous loss of orthogonality - internal error\n";
178 for (
int i=0; i<n; ++i) {
181 for (
int j=0; j<dim; ++j)
182 vec[j] = temp_vecs[j + dim*i];
206 double tolerance,
int numberLanczosVecs,
207 bool smallest,
bool magnitude,
221 constexpr
long whichLength = 2;
222 char which[whichLength + 1];
223 which[whichLength] =
'\0';
238 long numberLanczosVecsL = numberLanczosVecs;
241 auto *resid =
new double[matSize];
242 std::memset((
void*) resid, 0,
sizeof(
double)*matSize);
244 if (maxIterations <= 0)
245 maxIterations = nEVL * 100;
247 if (numberLanczosVecsL <= 0)
248 numberLanczosVecsL = 2 * nEVL + 1;
249 numberLanczosVecsL = (numberLanczosVecsL > matSize ? matSize : numberLanczosVecsL);
250 auto *V =
new double[matSize * numberLanczosVecsL + 1];
253 constexpr
int genEigProblemLength = 1;
254 char genEigProblem =
'G';
257 #define IPARAMSIZE 12 264 iParam[3] = maxIterations;
316 for (
long & clrIx : iPntr)
320 auto *workd =
new double[3 * matSize + 1];
323 long lworkl = numberLanczosVecsL * (numberLanczosVecsL+9);
326 auto *workl =
new double[lworkl + 1];
334 &ido, &genEigProblem, &matSize, which,
335 &nEVL, &tolerance, resid, &numberLanczosVecsL, &V[1], &matSize,
336 &iParam[1], &iPntr[1], &workd[1], &workl[1], &lworkl, &info,
337 genEigProblemLength, whichLength);
363 iPntr[3] = iPntr[2] + matSize;
382 A.
mult(x, workVector);
399 constexpr
int howMnyLength = 1;
412 auto *Z =
new double[
nvalues * matSize];
414 v3p_netlib_dseupd_(&rvec, &howMny, select.
data_block(),
values, Z, &matSize, &sigma, &genEigProblem,
415 &matSize, which, &nEVL, &tolerance, resid, &numberLanczosVecsL, &V[1], &matSize, &iParam[1],
416 &iPntr[1], &workd[1], &workl[1], &lworkl, &info,
417 howMnyLength, genEigProblemLength, whichLength);
421 for (evIx = 0; evIx <
nvalues; evIx++)
464 auto* temp =
new double[n*
m];
465 std::memcpy(temp,q,n*
m*
sizeof(
double));
467 std::cout <<
"Save vectors " << base <<
' ' << temp <<
'\n';
483 static int read_idx = 0;
488 std::memcpy(q,temp,n*
m*
sizeof(
double));
490 std::cout <<
"Restore vectors " << base <<
' ' << temp <<
'\n';
unsigned int columns() const
Get the number of columns in the matrix.
vnl_vector< double > * vectors
Find the eigenvalues of a sparse symmetric matrix.
Solution of the linear system Mx = b for sparse matrices.
vnl_vector< T > & update(vnl_vector< T > const &, size_t start=0)
Replaces elements with index beginning at start, by values of v. O(n).
void mult(vnl_vector< T > const &rhs, vnl_vector< T > &result) const
Multiply this*rhs, where rhs is a vector.
vnl_vector using user-supplied storage
vnl_vector using user-supplied storage.
T const * data_block() const
Access the contiguous block storing the elements in the vector. O(1).
int CalculateNPairs(vnl_sparse_matrix< double > &M, int n, bool smallest=true, long nfigures=10)
Here is where the fortran converted code gets called.
std::vector< double * > temp_store
double get_eigenvalue(int i) const
vnl_vector< double > get_eigenvector(int i) const
Return a calculated eigenvector.
vnl_sparse_symmetric_eigensystem()
int CalculateProduct(int n, int m, const double *p, double *q)
Callback from solver to calculate the product A p.
Declare in a central place the list of symbols from netlib.
Find the eigenvalues of a sparse symmetric matrix.
Linear system solver for Mx = b using LU decomposition of a sparse matrix.
vnl_vector< double > solve(vnl_vector< double > const &b)
Solve problem M x = b.
~vnl_sparse_symmetric_eigensystem()
int RestoreVectors(int n, int m, double *q, int base)
Callback to restore vectors for dnlaso.
int SaveVectors(int n, int m, const double *q, int base)
Callback to store vectors for dnlaso.
vnl_sparse_matrix< double > * Bmat
vnl_sparse_matrix< double > * mat