Skip to content

BUG: stochastic optimizer in ProjectedSchrodingerPyCI #207

Description

@kzsigmond

Describe the problem:

Calling the optimize_stochastic method for the PojectedSchrodingerPyCI class fails.

Code that reproduces the bug:

The following test on the 108-test-interface-submodule branch fails if run in the test folder:

import numpy as np
import pyci 

from fanpy.interface.fanci.pyci import ProjectedSchrodingerPyCI
from interface_utils import FakeHamiltonian, FakeWavefunction, FakeSchrodinger

def make_test_instance(**overrides):
    """make test instance of ProjectedSchrodingerPyCI with fake fanpy objective and fake pyci hamiltonian and wavefunction
    This helps set up a class that requires a lot of parameters.
    """
    # build Fake fanpy objective
    wfn = FakeWavefunction(2, 4, np.ones(4))
    nocc = wfn.nelec // 2
    ham = FakeHamiltonian(np.ones((2, 2)), np.ones((2, 2, 2, 2)))
    obj = FakeSchrodinger(wfn, ham)

    # build fake pyci hamiltonian
    energy_nuc = 0.0
    pyci_ham = pyci.hamiltonian(energy_nuc, ham.one_int, ham.two_int)

    # build pyci wavefunction 
    # use FCI pspace wavefunction
    pyci_wfn = pyci.fullci_wfn(pyci_ham.nbasis, wfn.nelec - nocc, nocc)

    defaults = {
        "fanpy_objective" : obj,
        "ham" : pyci_ham,
        "wfn" : pyci_wfn,
        "nocc" : 2,
        "seniority": wfn.seniority,
        "nproj": 1,
        "fill": "excitation",
        "mask": np.ones(wfn.params.shape[0]+1, dtype=bool),
        "constraints": {},
        "param_selection": obj.indices_component_params,
        "norm_param": None,
        "norm_det": None,
        "max_memory": 8000,
        "step_print": False,
        "step_save": False,
        "tmpfile": ""
    }
    defaults.update(overrides)
    return ProjectedSchrodingerPyCI(**defaults)

def test_optimize_stochasitc_lstsq():
    """ Check if optimize method runs without errors and energy is one of the keys"""
    mask = np.ones(5, dtype=int)
    pyci_obj = make_test_instance(mask=mask)
    initial_guess = np.random.rand(pyci_obj.fanpy_wfn.nparams+1)
    results = pyci_obj.optimize_stochastic(nsamp=3, x0=initial_guess, mode="lstsq", fill = pyci_obj.fill)
    assert "energy" in results.keys()

Traceback error:

=================================================================================== test session starts ====================================================================================
platform linux -- Python 3.10.16, pytest-8.3.4, pluggy-1.5.0
rootdir: /home/quintana/Documents/code/Fanpy
configfile: pyproject.toml
plugins: cov-6.0.0
collected 1 item                                                                                                                                                                           

test.py F                                                                                                                                                                            [100%]

========================================================================================= FAILURES =========================================================================================
______________________________________________________________________________ test_optimize_stochasitc_lstsq ______________________________________________________________________________

    def test_optimize_stochasitc_lstsq():
        """ Check if optimize method runs without errors and energy is one of the keys"""
        mask = np.ones(5, dtype=int)
        pyci_obj = make_test_instance(mask=mask)
        initial_guess = np.random.rand(pyci_obj.fanpy_wfn.nparams+1)
>       results = pyci_obj.optimize_stochastic(nsamp=3, x0=initial_guess, mode="lstsq", fill = pyci_obj.fill)

test.py:51: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <fanpy.interface.fanci.pyci.ProjectedSchrodingerPyCI object at 0x7e0fca5b93c0>, nsamp = 3, x0 = array([0.2028639 , 0.28284929, 0.95316465, 0.30245556, 0.24879663]), mode = 'lstsq'
use_jac = False, fill = 'excitation', kwargs = {}, ham = <pyci._pyci.secondquant_op object at 0x7e0fca57e9b0>, nproj = 1, nparam = 5, nbasis = 2, nocc_up = 1, nocc_dn = 1, constraints = ()

    def optimize_stochastic(
        self,
        nsamp: int,
        x0: np.ndarray,
        mode: str = "lstsq",
        use_jac: bool = False,
        fill: str = "excitation",
        **kwargs: Any,
    ) -> List[Tuple[np.ndarray]]:
        """
        Run a stochastic optimization of a FanCI wave function.
    
        Parameters
        ----------
        nsamp: int
            Number of samples to compute.
        x0 : np.ndarray
            Initial guess for wave function parameters.
        mode : ('lstsq' | 'root' | 'cma'), default='lstsq'
            Solver mode.
        use_jac : bool, default=False
            Whether to use the Jacobian function or a finite-difference approximation.
        fill : ('excitation' | 'seniority' | None)
            Whether to fill the projection ("P") space by excitation level, by seniority, or not
            at all (in which case ``wfn`` must already be filled).
        kwargs : Any, optional
            Additional keyword arguments to pass to optimizer.
    
        Returns
        -------
        result : List[Tuple[np.ndarray]]
            List of (occs, coeffs, params) vectors for each solution.
    
        """
        # Get wave function information
        ham = self.ham
        nproj = self.nproj
        nparam = self.nparam
        nbasis = self.wfn.nbasis
        nocc_up = self.wfn.nocc_up
        nocc_dn = self.wfn.nocc_dn
        constraints = self.constraints
        mask = self.mask
        ci_cls = self.wfn.__class__
        # Start at sample 1
        isamp = 1
        result = []
        # Iterate until nsamp samples are reached
        # **kwargs: Any,
        while True:
            # Optimize this FanCI wave function and get the result
            opt = self.optimize(x0, mode=mode, use_jac=use_jac, **kwargs)
            energy = opt.x[-1]
            if opt.success:
                print("Optimization was successful")
            else:
                print("Optimization was not successful: {}".format(opt.message))
>           print("Final Electronic Energy for sample {isamp}: {}".format(energy))
E           KeyError: 'isamp'

../fanpy/interface/fanci/pyci.py:860: KeyError
----------------------------------------------------------------------------------- Captured stdout call -----------------------------------------------------------------------------------
WARNING: System is underdetermined with dimensions 1, 5. Continuing anyways
   Iteration     Total nfev        Cost      Cost reduction    Step norm     Optimality   
       0              1         3.0041e+01                                    7.75e+00    
       1              2         2.2201e+01      7.84e+00       1.09e+00       6.66e+00    
       2              3         1.0072e+01      1.21e+01       2.18e+00       4.49e+00    
       3              4         9.4402e-03      1.01e+01       4.35e+00       1.37e-01    
       4              8         1.0442e-06      9.44e-03       1.36e-01       1.45e-03    
       5             13         7.3321e-08      9.71e-07       1.06e-03       3.83e-04    
       6             15         1.0975e-08      6.23e-08       5.31e-04       1.48e-04    
       7             17         6.8904e-09      4.08e-09       2.66e-04       1.17e-04    
       8             19         1.1831e-10      6.77e-09       1.33e-04       1.54e-05    
       9             22         7.3713e-13      1.18e-10       1.66e-05       1.21e-06    
      10             25         3.7015e-13      3.67e-13       2.07e-06       8.60e-07    
      11             27         1.5646e-14      3.55e-13       1.04e-06       1.77e-07    
      12             30         1.1154e-15      1.45e-14       1.30e-07       4.72e-08    
      13             32         1.5488e-16      9.61e-16       6.48e-08       1.76e-08    
`xtol` termination condition is satisfied.
Function evaluations 32, initial cost 3.0041e+01, final cost 1.5488e-16, first-order optimality 1.76e-08.
Optimization was successful
================================================================================= short test summary info ==================================================================================
FAILED test.py::test_optimize_stochasitc_lstsq - KeyError: 'isamp'
==================================================================================== 1 failed in 0.18s =====================================================================================

Package versions:

python: 3.10
fanpy: N/A
numpy:1.26

Additonal comments

No response

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingtriageNeeds to be assigned/validated

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions