updated all code in LAMMPS to use the open-source "math_eigen.h" instead of "math_extra.h". Code in "lib" now uses its own abbreviated local version of the "math_eigen.h" file (which is named "jacobi_pd.h"), since it is not clear how code from "lib/" can access the code in "src/"
This commit is contained in:
140
src/math_eigen.cpp
Normal file
140
src/math_eigen.cpp
Normal file
@ -0,0 +1,140 @@
|
||||
#include "math_eigen.h"
|
||||
#include<array>
|
||||
|
||||
using std::vector;
|
||||
using std::array;
|
||||
|
||||
|
||||
using namespace MathEigen;
|
||||
|
||||
// --- Instantiate template class instances ---
|
||||
// --- to reduce bloat in the compiled binary ---
|
||||
|
||||
// When using one of these versions of Jacobi, you can reduce code bloat by
|
||||
// using an "extern template class" declaration in your cpp file. For example:
|
||||
//
|
||||
// #include"math_eigen.h"
|
||||
// extern template class MathEigen::Jacobi<double, double*, double**, double const*const*>;
|
||||
//
|
||||
// ...This should (hopefully) use the version of Jacobi defined in this file
|
||||
// instead of compiling a new version.
|
||||
|
||||
|
||||
// template instantiations of Jacobi for pointer->pointer arrays
|
||||
template class MathEigen::Jacobi<double, double*, double**, double const*const*>;
|
||||
|
||||
// template instantiations of Jacbi for fixed-size (3x3) arrays
|
||||
template class MathEigen::Jacobi<double, double*, double (*)[3], double const (*)[3]>;
|
||||
|
||||
// template instantiations of Jacobi for vector-of-vectors:
|
||||
template class MathEigen::Jacobi<double,
|
||||
vector<double>&,
|
||||
vector<vector<double> >&,
|
||||
const vector<vector<double> >& >;
|
||||
|
||||
// template instantiations of Jacobi for array-of-arrays:
|
||||
template class MathEigen::Jacobi<double,
|
||||
array<double, 3>&,
|
||||
array<array<double, 3>, 3 >&,
|
||||
const array<array<double, 3>, 3 >& >;
|
||||
// template instantiations of LambdaLanczos
|
||||
template class MathEigen::LambdaLanczos<double>;
|
||||
|
||||
// template instantiations of PEidenDense for pointer->pointer arrays
|
||||
template class MathEigen::PEigenDense<double, double*, double const*const*>;
|
||||
|
||||
// template instantiations of PEidenDense for vector<vector<>>
|
||||
template class MathEigen::PEigenDense<double,
|
||||
vector<double>&,
|
||||
const vector<vector<double> >&>;
|
||||
|
||||
// ----------------- now create instances for floats ----------------
|
||||
|
||||
template class MathEigen::Jacobi<float, float*, float**, float const*const*>;
|
||||
template class MathEigen::Jacobi<float, float*, float (*)[3], float const (*)[3]>;
|
||||
template class MathEigen::Jacobi<float,
|
||||
vector<float>&,
|
||||
vector<vector<float> >&,
|
||||
const vector<vector<float> >& >;
|
||||
template class MathEigen::Jacobi<float,
|
||||
array<float, 3>&,
|
||||
array<array<float, 3>, 3 >&,
|
||||
const array<array<float, 3>, 3 >& >;
|
||||
template class MathEigen::LambdaLanczos<float>;
|
||||
template class MathEigen::PEigenDense<float, float*, float const*const*>;
|
||||
template class MathEigen::PEigenDense<float,
|
||||
vector<float>&,
|
||||
const vector<vector<float> >&>;
|
||||
|
||||
// If you plan to use other numeric types, add them below...
|
||||
|
||||
|
||||
|
||||
// Special case: 3x3 matrices
|
||||
|
||||
int MathEigen::
|
||||
jacobi3(double const mat[3][3], // the 3x3 matrix you wish to diagonalize
|
||||
double *eval, // store the eigenvalues here
|
||||
double evec[3][3], // store the eigenvectors here...
|
||||
bool evec_as_columns, // ...as rows or columns?
|
||||
Jacobi<double,double*,double(*)[3],double const(*)[3]>::SortCriteria
|
||||
sort_criteria)
|
||||
{
|
||||
// Create "ecalc3", an instance of the MathEigen::Jacobi class to calculate
|
||||
// the eigenvalues oand eigenvectors of matrix "mat". It requires memory
|
||||
// to be allocated to store a copy of the matrix. To avoid allocating
|
||||
// this memory on the heap, we create a fixed size 3x3 array on the stack
|
||||
// (and convert it to type double**).
|
||||
double mat_cpy[3][3] = { {mat[0][0], mat[0][1], mat[0][2]},
|
||||
{mat[1][0], mat[1][1], mat[1][2]},
|
||||
{mat[2][0], mat[2][1], mat[2][2]} };
|
||||
double *M[3] = { &(mat_cpy[0][0]), &(mat_cpy[1][0]), &(mat_cpy[2][0]) };
|
||||
|
||||
// variable "ecalc3" does all the work:
|
||||
Jacobi<double,double*,double(*)[3],double const(*)[3]> ecalc3(3,M);
|
||||
int ierror = ecalc3.Diagonalize(mat, eval, evec, sort_criteria);
|
||||
|
||||
// This will store the eigenvectors in the rows of "evec".
|
||||
// Do we want to return the eigenvectors in columns instead of rows?
|
||||
if (evec_as_columns)
|
||||
for (int i=0; i<3; i++)
|
||||
for (int j=0; j<3; j++)
|
||||
std::swap(evec[i][j], evec[j][i]);
|
||||
|
||||
return ierror;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int MathEigen::
|
||||
jacobi3(double const **mat, // the 3x3 matrix you wish to diagonalize
|
||||
double *eval, // store the eigenvalues here
|
||||
double **evec, // store the eigenvectors here...
|
||||
bool evec_as_columns, // ...as rows or columns?
|
||||
Jacobi<double,double*,double**,double const*const*>::SortCriteria
|
||||
sort_criteria)
|
||||
{
|
||||
// Create "ecalc3", an instance of the MathEigen::Jacobi class to calculate
|
||||
// the eigenvalues oand eigenvectors of matrix "mat". It requires memory
|
||||
// to be allocated to store a copy of the matrix. To avoid allocating
|
||||
// this memory on the heap, we create a fixed size 3x3 array on the stack
|
||||
// (and convert it to type double**).
|
||||
double mat_cpy[3][3] = { {mat[0][0], mat[0][1], mat[0][2]},
|
||||
{mat[1][0], mat[1][1], mat[1][2]},
|
||||
{mat[2][0], mat[2][1], mat[2][2]} };
|
||||
double *M[3] = { &(mat_cpy[0][0]), &(mat_cpy[1][0]), &(mat_cpy[2][0]) };
|
||||
|
||||
// variable "ecalc3" does all the work:
|
||||
Jacobi<double,double*,double**,double const*const*> ecalc3(3,M);
|
||||
int ierror = ecalc3.Diagonalize(mat, eval, evec, sort_criteria);
|
||||
|
||||
// This will store the eigenvectors in the rows of "evec".
|
||||
// Do we want to return the eigenvectors in columns instead of rows?
|
||||
if (evec_as_columns)
|
||||
for (int i=0; i<3; i++)
|
||||
for (int j=0; j<3; j++)
|
||||
std::swap(evec[i][j], evec[j][i]);
|
||||
|
||||
return ierror;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user