Skip to content

Copying SecondQuantizedMolecule #361

@alexfleury-sb

Description

@alexfleury-sb

Feature Request: Deepcopy of SecondQuantizedMolecule

At this time, the SecondQuantizedMolecule can't be deepcopied:

from copy import deepcopy
from tangelo import SecondQuantizedMolecule

xyz_H2 = """
    H 0. 0. 0.00
    H 0. 0. 0.75
"""
mol = SecondQuantizedMolecule(xyz_H2)
deepcopy(mol)

outputs

Traceback (most recent call last):
  File "/home/alex/Scratch/mo_coeff_bug.py", line 14, in <module>
    deepcopy(mol)
  File "/home/alex/.pyenv/versions/3.10.13/lib/python3.10/copy.py", line 172, in deepcopy
    y = _reconstruct(x, memo, *rv)
  File "/home/alex/.pyenv/versions/3.10.13/lib/python3.10/copy.py", line 271, in _reconstruct
    state = deepcopy(state, memo)
  File "/home/alex/.pyenv/versions/3.10.13/lib/python3.10/copy.py", line 146, in deepcopy
    y = copier(x, memo)
  File "/home/alex/.pyenv/versions/3.10.13/lib/python3.10/copy.py", line 231, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "/home/alex/.pyenv/versions/3.10.13/lib/python3.10/copy.py", line 172, in deepcopy
    y = _reconstruct(x, memo, *rv)
  File "/home/alex/.pyenv/versions/3.10.13/lib/python3.10/copy.py", line 271, in _reconstruct
    state = deepcopy(state, memo)
  File "/home/alex/.pyenv/versions/3.10.13/lib/python3.10/copy.py", line 146, in deepcopy
    y = copier(x, memo)
  File "/home/alex/.pyenv/versions/3.10.13/lib/python3.10/copy.py", line 231, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "/home/alex/.pyenv/versions/3.10.13/lib/python3.10/copy.py", line 161, in deepcopy
    rv = reductor(4)
TypeError: cannot pickle 'module' object

This is not a critical bug at this moment, but it would be useful to be able to create a copy and update its attributes. For e.g.,

from copy import copy
from openfermion.linalg import eigenspectrum

def doing_something_with_molecule(sqmol):
    sqmol_copy = copy(sqmol)
    # Doing awesome stuff with mo_coeff and creating new_mo_coeff.
    sqmol_copy.mo_coeff = new_coeff
    return sqmol_copy

eigenvalues_original = eigenspectrum(mol.fermionic_hamiltonian)
updated_mol = doing_something_with_molecule(mol)
eigenvalues_verif = eigenspectrum(mol.fermionic_hamiltonian) # Should be the same as eigenvalues_original, but it is not.

# Doing other stuff with updated_mol...

The function doing_something_with_molecule is changing the MO coefficients of the sqmol_copy, but as the copy is shallow, it is also changing the MO coefficients of the mol object. This can introduce unexpected behaviour, as I experienced when working with FNO -> the MO coefficients were bound to the active space selection, so the fermionic Hamiltonian computed after the doing_something_with_molecule call wasn't trowing an error, but was physically wrong.

Metadata

Metadata

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions