-
Notifications
You must be signed in to change notification settings - Fork 141
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Evaluate parameter derivatives for NLPP #4402
Changes from 9 commits
6163899
02e73bf
c1968ed
fb2e6a8
a5737cb
5b24452
edb11bc
e24eb3a
6cf307a
f8930df
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -306,6 +306,131 @@ void RotatedSPOs::log_antisym_matrix(ValueMatrix& mat) | |
} | ||
} | ||
|
||
void RotatedSPOs::evaluateDerivRatios(const VirtualParticleSet& VP, | ||
const opt_variables_type& optvars, | ||
ValueVector& psi, | ||
const ValueVector& psiinv, | ||
std::vector<ValueType>& ratios, | ||
Matrix<ValueType>& dratios, | ||
int FirstIndex, | ||
int LastIndex) | ||
{ | ||
Phi->evaluateDetRatios(VP, psi, psiinv, ratios); | ||
|
||
const size_t nel = LastIndex - FirstIndex; | ||
const size_t nmo = Phi->getOrbitalSetSize(); | ||
|
||
psiM_inv.resize(nel, nel); | ||
psiM_all.resize(nel, nmo); | ||
dpsiM_all.resize(nel, nmo); | ||
d2psiM_all.resize(nel, nmo); | ||
|
||
psiM_inv = 0; | ||
psiM_all = 0; | ||
dpsiM_all = 0; | ||
d2psiM_all = 0; | ||
|
||
const ParticleSet& P = VP.getRefPS(); | ||
int iel = VP.refPtcl; | ||
|
||
Phi->evaluate_notranspose(P, FirstIndex, LastIndex, psiM_all, dpsiM_all, d2psiM_all); | ||
|
||
for (int i = 0; i < nel; i++) | ||
for (int j = 0; j < nel; j++) | ||
psiM_inv(i, j) = psiM_all(i, j); | ||
|
||
Invert(psiM_inv.data(), nel, nel); | ||
|
||
const ValueType* const A(psiM_all.data()); | ||
const ValueType* const Ainv(psiM_inv.data()); | ||
SPOSet::ValueMatrix T_orig; | ||
T_orig.resize(nel, nmo); | ||
|
||
BLAS::gemm('N', 'N', nmo, nel, nel, ValueType(1.0), A, nmo, Ainv, nel, ValueType(0.0), T_orig.data(), nmo); | ||
|
||
SPOSet::ValueMatrix T; | ||
T.resize(nel, nmo); | ||
|
||
ValueVector tmp_psi; | ||
tmp_psi.resize(nmo); | ||
|
||
for (int iat = 0; iat < VP.getTotalNum(); iat++) | ||
{ | ||
Phi->evaluateValue(VP, iat, tmp_psi); | ||
|
||
for (int j = 0; j < nmo; j++) | ||
psiM_all(iel - FirstIndex, j) = tmp_psi[j]; | ||
|
||
for (int i = 0; i < nel; i++) | ||
for (int j = 0; j < nel; j++) | ||
psiM_inv(i, j) = psiM_all(i, j); | ||
|
||
Invert(psiM_inv.data(), nel, nel); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the inverse that is likely to get expensive, as it gets call nknot times. Maybe combining a Sherman-Morrison update with the matrix multiply below will lead to some simplifications. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe the math can be formulated without any update. |
||
|
||
const ValueType* const A(psiM_all.data()); | ||
const ValueType* const Ainv(psiM_inv.data()); | ||
|
||
// The matrix A is rectangular. Ainv is the inverse of the square part of the matrix. | ||
// The multiply of Ainv and the square part of A is just the identity. | ||
// This multiply could be reduced to Ainv and the non-square part of A. | ||
BLAS::gemm('N', 'N', nmo, nel, nel, ValueType(1.0), A, nmo, Ainv, nel, ValueType(0.0), T.data(), nmo); | ||
|
||
for (int i = 0; i < m_act_rot_inds.size(); i++) | ||
{ | ||
int kk = myVars.where(i); | ||
const int p = m_act_rot_inds.at(i).first; | ||
const int q = m_act_rot_inds.at(i).second; | ||
dratios(iat, kk) = T(p, q) - T_orig(p, q); // dratio size is (nknot, num_vars) | ||
} | ||
} | ||
} | ||
|
||
void RotatedSPOs::evaluateDerivativesWF(ParticleSet& P, | ||
const opt_variables_type& optvars, | ||
Vector<ValueType>& dlogpsi, | ||
int FirstIndex, | ||
int LastIndex) | ||
{ | ||
const size_t nel = LastIndex - FirstIndex; | ||
const size_t nmo = Phi->getOrbitalSetSize(); | ||
|
||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~PART1 | ||
|
||
psiM_inv.resize(nel, nel); | ||
psiM_all.resize(nel, nmo); | ||
dpsiM_all.resize(nel, nmo); | ||
d2psiM_all.resize(nel, nmo); | ||
|
||
psiM_inv = 0; | ||
psiM_all = 0; | ||
dpsiM_all = 0; | ||
d2psiM_all = 0; | ||
|
||
Phi->evaluate_notranspose(P, FirstIndex, LastIndex, psiM_all, dpsiM_all, d2psiM_all); | ||
|
||
for (int i = 0; i < nel; i++) | ||
for (int j = 0; j < nel; j++) | ||
psiM_inv(i, j) = psiM_all(i, j); | ||
|
||
Invert(psiM_inv.data(), nel, nel); | ||
|
||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~PART2 | ||
const ValueType* const A(psiM_all.data()); | ||
const ValueType* const Ainv(psiM_inv.data()); | ||
SPOSet::ValueMatrix T; | ||
T.resize(nel, nmo); | ||
|
||
BLAS::gemm('N', 'N', nmo, nel, nel, ValueType(1.0), A, nmo, Ainv, nel, ValueType(0.0), T.data(), nmo); | ||
|
||
for (int i = 0; i < m_act_rot_inds.size(); i++) | ||
{ | ||
int kk = myVars.where(i); | ||
const int p = m_act_rot_inds.at(i).first; | ||
const int q = m_act_rot_inds.at(i).second; | ||
dlogpsi[kk] = T(p, q); | ||
} | ||
} | ||
|
||
void RotatedSPOs::evaluateDerivatives(ParticleSet& P, | ||
const opt_variables_type& optvars, | ||
Vector<ValueType>& dlogpsi, | ||
|
@@ -401,9 +526,9 @@ void RotatedSPOs::evaluateDerivatives(ParticleSet& P, | |
|
||
for (int i = 0; i < m_act_rot_inds.size(); i++) | ||
{ | ||
int kk = myVars.where(i); | ||
const int p = m_act_rot_inds.at(i).first; | ||
const int q = m_act_rot_inds.at(i).second; | ||
int kk = myVars.where(i); | ||
const int p = m_act_rot_inds.at(i).first; | ||
const int q = m_act_rot_inds.at(i).second; | ||
dlogpsi[kk] = T(p, q); | ||
dhpsioverpsi[kk] = ValueType(-0.5) * Y4(p, q); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Noting the full cubic cost of matrix inversion here. However, getting something working first takes precedence over possible alternatives. Plus considering that the initial electron counts will be smallish, this might not be so bad.