Skip to content

DMET calculation problem #414

@commco789

Description

@commco789

I successfully used DMET-VQE to calculate the energy of the H₁₀ system. However, when I tried using the same pipeline to compute the energy of the BF₄⁻, the simulation crashed with a TypeError: '<' not supported between instances of 'complex' and 'float'.
Here's the minimal code I used:


from tangelo import SecondQuantizedMolecule
from tangelo.problem_decomposition import DMETProblemDecomposition
from tangelo.algorithms import VQESolver
bf4="""
F -0.67434965686117 -0.13772650470120 -1.22197648248581
F 1.28027646840210 0.52623822634537 -0.22824137456014
F -0.71946117361893 0.86667506771115 0.83534222327770
F 0.11359664918233 -1.25541074050712 0.61497359584763
B -0.00005885050433 0.00022520685180 -0.00009728207940
"""

mol_bf4 = SecondQuantizedMolecule(bf4, q=-1, spin=0, basis="minao")

options_mol_dmet = {"molecule": mol_bf4,
"fragment_atoms": [1]*5,
"fragment_solvers": "vqe",
"fragment_frozen_orbitals": [[0] for _ in range(5)],
"virtual_orbital_threshold": 1e-10,
"verbose": False
}

dmet_mol = DMETProblemDecomposition(options_mol_dmet)
dmet_mol.build()

dmet_mol.verbose = False
energy_mol_dmet = dmet_mol.simulate()

print(f"DMET energy (hartree): \t {energy_mol_dmet}")


and the error message:


TypeError Traceback (most recent call last)
Cell In[29], line 2
1 dmet_mol.verbose = False
----> 2 energy_mol_dmet = dmet_mol.simulate()
4 print(f"DMET energy (hartree): \t {energy_mol_dmet}")

File ~/miniforge3/envs/tangelo-env/lib/python3.10/site-packages/tangelo/problem_decomposition/dmet/dmet_problem_decomposition.py:280, in DMETProblemDecomposition.simulate(self)
277 if not self.orbitals:
278 raise RuntimeError("No fragment built. Have you called DMET.build ?")
--> 280 self.chemical_potential = self.optimizer(self._oneshot_loop, self.initial_chemical_potential)
281 self.chemical_potential = self.chemical_potential.real
283 # run one more time to save results

File ~/miniforge3/envs/tangelo-env/lib/python3.10/site-packages/tangelo/problem_decomposition/dmet/dmet_problem_decomposition.py:740, in DMETProblemDecomposition._default_optimizer(self, func, var_params)
726 def _default_optimizer(self, func, var_params):
727 """Function used as a default optimizer for DMET when user does not
728 provide one.
729
(...)
737 float: The chemical potential found by the optimizer.
738 """
--> 740 result = scipy.optimize.newton(func, var_params, tol=1e-5)
742 return result.real

File ~/miniforge3/envs/tangelo-env/lib/python3.10/site-packages/scipy/optimize/_zeros_py.py:385, in newton(func, x0, fprime, args, tol, maxiter, fprime2, x1, rtol, full_output, disp)
383 p0, q0 = p1, q1
384 p1 = p
--> 385 q1 = func(p1, *args)
386 funcalls += 1
388 if disp:

File ~/miniforge3/envs/tangelo-env/lib/python3.10/site-packages/tangelo/problem_decomposition/dmet/dmet_problem_decomposition.py:520, in DMETProblemDecomposition._oneshot_loop(self, chemical_potential, save_results, resample, n_shots, purify, rdm_measurements)
518 solver_fragment = VQESolver({**system, **solver_options})
519 solver_fragment.build()
--> 520 solver_fragment.simulate()
522 if purify and solver_fragment.molecule.n_active_electrons == 2 and not self.uhf:
523 onerdm, twordm = solver_fragment.get_rdm(solver_fragment.optimal_var_params, resample=resample, sum_spin=False)

File ~/miniforge3/envs/tangelo-env/lib/python3.10/site-packages/tangelo/algorithms/variational/vqe_solver.py:259, in VQESolver.simulate(self)
256 if len(self.ansatz.circuit._variational_gates) == 0:
257 raise RuntimeError("No variational gate found in the circuit.")
--> 259 optimal_energy, optimal_var_params = self.optimizer(self.energy_estimation, self.initial_var_params)
261 self.optimal_var_params = optimal_var_params
262 self.optimal_energy = optimal_energy

File ~/miniforge3/envs/tangelo-env/lib/python3.10/site-packages/tangelo/algorithms/variational/vqe_solver.py:709, in VQESolver._default_optimizer(self, func, var_params)
706 from scipy.optimize import minimize
708 with HiddenPrints() if not self.verbose else nullcontext():
--> 709 result = minimize(func, var_params, method="SLSQP",
710 options={"disp": True, "maxiter": 2000, "eps": 1e-5, "ftol": 1e-5})
712 if self.verbose:
713 print(f"VQESolver optimization results:")

File ~/miniforge3/envs/tangelo-env/lib/python3.10/site-packages/scipy/optimize/_minimize.py:750, in minimize(fun, x0, args, method, jac, hess, hessp, bounds, constraints, tol, callback, options)
747 res = _minimize_cobyqa(fun, x0, args, bounds, constraints, callback,
748 **options)
749 elif meth == 'slsqp':
--> 750 res = _minimize_slsqp(fun, x0, args, jac, bounds,
751 constraints, callback=callback, **options)
752 elif meth == 'trust-constr':
753 res = _minimize_trustregion_constr(fun, x0, args, jac, hess, hessp,
754 bounds, constraints,
755 callback=callback, **options)

File ~/miniforge3/envs/tangelo-env/lib/python3.10/site-packages/scipy/optimize/_slsqp_py.py:381, in _minimize_slsqp(func, x0, args, jac, bounds, constraints, maxiter, ftol, iprint, disp, eps, callback, finite_diff_rel_step, **unknown_options)
378 xu[infbnd[:, 1]] = np.nan
380 # ScalarFunction provides function and gradient evaluation
--> 381 sf = _prepare_scalar_function(func, x, jac=jac, args=args, epsilon=eps,
382 finite_diff_rel_step=finite_diff_rel_step,
383 bounds=new_bounds)
384 # gh11403 SLSQP sometimes exceeds bounds by 1 or 2 ULP, make sure this
385 # doesn't get sent to the func/grad evaluator.
386 wrapped_fun = _clip_x_for_func(sf.fun, new_bounds)

File ~/miniforge3/envs/tangelo-env/lib/python3.10/site-packages/scipy/optimize/_optimize.py:291, in _prepare_scalar_function(fun, x0, jac, args, bounds, epsilon, finite_diff_rel_step, hess)
287 bounds = (-np.inf, np.inf)
289 # ScalarFunction caches. Reuse of fun(x) during grad
290 # calculation reduces overall function evaluations.
--> 291 sf = ScalarFunction(fun, x0, args, grad, hess,
292 finite_diff_rel_step, bounds, epsilon=epsilon)
294 return sf

File ~/miniforge3/envs/tangelo-env/lib/python3.10/site-packages/scipy/optimize/_differentiable_functions.py:223, in ScalarFunction.init(self, fun, x0, args, grad, hess, finite_diff_rel_step, finite_diff_bounds, epsilon)
220 finite_diff_options["as_linear_operator"] = True
222 # Initial function evaluation
--> 223 self._update_fun()
225 # Initial gradient evaluation
226 self._wrapped_grad, self._ngev = _wrapper_grad(
227 grad,
228 fun=self._wrapped_fun,
229 args=args,
230 finite_diff_options=finite_diff_options
231 )

File ~/miniforge3/envs/tangelo-env/lib/python3.10/site-packages/scipy/optimize/_differentiable_functions.py:296, in ScalarFunction._update_fun(self)
294 if not self.f_updated:
295 fx = self._wrapped_fun(self.x)
--> 296 if fx < self._lowest_f:
297 self._lowest_x = self.x
298 self._lowest_f = fx

TypeError: '<' not supported between instances of 'complex' and 'float'


I don't know how to deal with the situation. It seems to trigger a complex-valued energy or objective, which causes a failure in scipy.optimize.minimize. Any suggestions on how to fix or work around this would be greatly appreciated. Thanks for your excellent work on this project!

Run Environment:

Machine: Mac, M2

Python version: 3.10.18

Tangelo version: latest (installed via pip)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions