# Source code for pyscf.lo.cholesky

```#!/usr/bin/env python
#
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#
# Unless required by applicable law or agreed to in writing, software
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
#
# 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]))
```