Source code for pyscf.lo.cholesky
#!/usr/bin/env python
# Copyright 2014-2021 The PySCF Developers. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Author: Peter Pinski <peter.pinski@quantumsimulations.de>
#
'''
Localized molecular orbitals via Cholesky factorization.
The orbitals are usually less well localized than with Boys, Pipek-Mezey, etc.
On the other hand, the procedure is non-iterative and the result unique,
except for degeneracies.
F. Aquilante, T.B. Pedersen, J. Chem. Phys. 125, 174101 (2006)
https://doi.org/10.1063/1.2360264
'''
import numpy as np
from pyscf.lib.scipy_helper import pivoted_cholesky
[docs]
def cholesky_mos(mo_coeff):
'''
Calculates localized orbitals through a pivoted Cholesky factorization
of the density matrix.
Args:
mo_coeff: block of MO coefficients to be localized
Returns:
the localized MOs
'''
assert (mo_coeff.ndim == 2)
nao, nmo = mo_coeff.shape
# Factorization of a density matrix-like quantity.
D = np.dot(mo_coeff, mo_coeff.T)
L, piv, rank = pivoted_cholesky(D, lower=True)
if rank < nmo:
raise RuntimeError('rank of matrix lower than the number of orbitals')
# Permute L back to the original order of the AOs.
# Superfluous columns are cropped out.
P = np.zeros((nao, nao))
P[piv, np.arange(nao)] = 1
mo_loc = np.dot(P, L[:, :nmo])
return mo_loc
if __name__ == "__main__":
import numpy
from pyscf.gto import Mole
from pyscf.scf import RHF
from pyscf.tools.mo_mapping import mo_comps
mol = Mole()
mol.atom = '''
C 0.681068338 0.605116159 0.307300799
C -0.733665805 0.654940451 -0.299036438
C -1.523996730 -0.592207689 0.138683275
H 0.609941801 0.564304456 1.384183068
H 1.228991034 1.489024155 0.015946420
H -1.242251083 1.542928348 0.046243898
H -0.662968178 0.676527364 -1.376503770
H -0.838473936 -1.344174292 0.500629028
H -2.075136399 -0.983173387 -0.703807608
H -2.212637905 -0.323898759 0.926200671
O 1.368219958 -0.565620846 -0.173113101
H 2.250134219 -0.596689848 0.204857736
'''
mol.basis = 'STO-3G'
mol.build()
mf = RHF(mol)
mf.kernel()
nocc = numpy.count_nonzero(mf.mo_occ > 0)
mo_loc = cholesky_mos(mf.mo_coeff[:, :nocc])
print('LMO Largest coefficients')
numpy.set_printoptions(precision=3, suppress=True, sign=' ')
for i in range(nocc):
li = numpy.argsort(abs(mo_loc[:, i]))
print('{0:3d} {1}'. format(i, mo_loc[li[:-6:-1], i]))