qiskit-community / qiskit-nature

Qiskit Nature is an open-source, quantum computing, framework for solving quantum mechanical natural science problems.
https://qiskit-community.github.io/qiskit-nature/
Apache License 2.0
301 stars 204 forks source link

Imcompatible size and shape in `second_q.operators.symmetric_two_body.S8Integrals` Tensor object #1353

Open ashsaki opened 6 months ago

ashsaki commented 6 months ago

Environment

What is happening?

from qiskit_nature.second_q.operators.tensor_ordering import to_chemist_ordering in 0.7.2 returns different size object compared to 0.6.2 leading to breaking behavior.

How can we reproduce the issue?

MWE

import numpy as np

from qiskit_nature.second_q.drivers import PySCFDriver
from qiskit_nature.second_q.operators.tensor_ordering import to_chemist_ordering

radius_1 = 0.958  # position for the first H atom
radius_2 = 0.958  # position for the second H atom
thetas_in_deg = 104.478  # bond angles.

H1_x = radius_1
H2_x = radius_2 * np.cos(np.pi / 180 * thetas_in_deg)
H2_y = radius_2 * np.sin(np.pi / 180 * thetas_in_deg)

# Create an ElectronicStructureProblem from the molecule using PySCFDriver
driver = PySCFDriver(
    f"O 0.0 0.0 0.0; H {H1_x} 0.0 0.0; H {H2_x} {H2_y} 0.0", basis="sto6g"
)
driver.run()
problem = driver.to_problem()

eri = to_chemist_ordering(
    problem.hamiltonian.electronic_integrals.two_body.alpha["++--"]
)
print(f'size {eri.size} | shape {eri.shape} | Type {type(eri)}')

Result 0.6.2

size 2401 | shape (7, 7, 7, 7) | Type <class 'numpy.ndarray'>

Result 0.7.2

size 406 | shape (7, 7, 7, 7) | Type <class 'qiskit_nature.second_q.operators.symmetric_two_body.S8Integrals'>

It leads to errors in previous workflows such as in circuit-knitting-toolbox (GitHub Link) as size 406 is not compatible with shape (7, 7, 7, 7).

What should happen?

The Tensor object's size and shape should be compatible.

Any suggestions?

No response

mrossinek commented 5 months ago

This is done by design. The symmetry-aware integrals used to store the 2-body terms report their shape as the correct 4-dimensional shape of the electron repulsion integrals but have a different size because of the encoded symmetries. This brings potentially massive memory savings for storing these objects.

Many numpy methods are handled automatically but reshape cannot work in the general case. All you need to do to fix your code is to unfold the S8Integrals to s1 symmetry using the method found in this module. This results in a 4d array that you can reshape as intended.

Looking at that old entanglement forging code, it expects to use a numpy array so you would probably want to make sure that you actually have one. The Tensor class (which is the base class of S8Integrals) can be either dense or sparse. So to ensure you have a numpy array you should call its .to_dense() method to get a dense Tensor and then extract its .array property to get the actual inner numpy array.

Here is the code in full:

from qiskit_nature.second_q.operators.symmetric_two_body import unfold

numpy_array = unfold(eri).to_dense().array