Repository: pyscf/pyscf — pull request #1845 (python)
Title: Fix the edge case CAS(2,2) for Selected CI (issue #1808)


Resolved issues:
title: Selected CI gives wrong results for a CAS of (2,2)
body: Dear developers,

I was trying to use selected CI as my CASCI solver by looking at the following example: https://github.com/pyscf/pyscf.github.io/blob/master/examples/mcscf/50-casscf_with_selected_ci.py

However, the selected CI results were wrong when I choose a CAS of (2,2):
```
from pyscf import gto, scf, mcscf, fci

b = 1.2
mol = gto.M(
    atom = 'N 0 0 0; N 0 0 %f'%b,
    basis = 'cc-pvdz',
)
mf = scf.RHF(mol).run()
mc = mcscf.CASCI(mf, 2, 2).run()

#
# Use SCI (Selected CI) to replace fcisolver
#
mc = mcscf.CASCI(mf, 2, 2)
mc.fcisolver = fci.SCI(mol)
mc.kernel() 
```

Here are the results. I am using pyscf version `2.1.1`
```
converged SCF energy = -108.914051975052

CASCI E = -108.94356411985  E(CI) = -1.71486588690826  S^2 = 0.0000000

CASCI E = -108.914051975052  E(CI) = -1.68535374211038  S^2 = 0.0000000
```
The selected CI seems to have only the doubly occupied determinant and misses the other doubly excited determinant. I know this is an edge case but thought of bringing this to your attention nevertheless. Thanks!


Hints:

Fix patch:
diff --git a/pyscf/fci/selected_ci.py b/pyscf/fci/selected_ci.py
index c51b8a811a..14aae7861c 100644
--- a/pyscf/fci/selected_ci.py
+++ b/pyscf/fci/selected_ci.py
@@ -115,7 +115,7 @@ def select_strs(myci, eri, eri_pq_max, civec_max, strs, norb, nelec):
     strs = numpy.asarray(strs, dtype=numpy.int64)
     nstrs = len(strs)
     nvir = norb - nelec
-    strs_add = numpy.empty((nstrs*(nelec*nvir)**2//4), dtype=numpy.int64)
+    strs_add = numpy.empty((nstrs*((nelec+1)*(nvir+1))**2//4), dtype=numpy.int64)
     libfci.SCIselect_strs.restype = ctypes.c_int
     nadd = libfci.SCIselect_strs(strs_add.ctypes.data_as(ctypes.c_void_p),
                                  strs.ctypes.data_as(ctypes.c_void_p),


Test patch:
diff --git a/pyscf/fci/test/test_selected_ci.py b/pyscf/fci/test/test_selected_ci.py
index b138f8468d..1300ea63cf 100644
--- a/pyscf/fci/test/test_selected_ci.py
+++ b/pyscf/fci/test/test_selected_ci.py
@@ -495,6 +495,16 @@ def test_guess_wfnsym(self):
         ci0[:] = 0
         self.assertRaises(RuntimeError, cis.guess_wfnsym, norb, nelec, ci0, wfnsym=1)
 
+    # The edge case CAS(2, 2). issue #1808
+    def test_cas_2_2(self):
+        mol = gto.M(atom='H 0 0 0; H 0 0 1.')
+        mc = mol.RHF().run().CASCI(2, 2)
+        mc.fcisolver = fci.SCI(mol)
+        mc.run()
+        self.assertAlmostEqual(mc.e_tot, -1.1011503302326, 9)
+        self.assertAlmostEqual(abs(mc.ci[0,0]), .984513596, 5)
+        self.assertAlmostEqual(abs(mc.ci[1,1]), .175308242, 5)
+
 
 def gen_des_linkstr(strs, norb, nelec):
     '''Given intermediates, the link table to generate input strs
@@ -691,4 +701,3 @@ def select_strs(myci, eri, eri_pq_max, civec_max, strs, norb, nelec):
 if __name__ == "__main__":
     print("Full Tests for selected_ci")
     unittest.main()
-