PennyLaneAI / pennylane

PennyLane is a cross-platform Python library for quantum computing, quantum machine learning, and quantum chemistry. Train a quantum computer the same way as a neural network.
https://pennylane.ai
Apache License 2.0
2.29k stars 590 forks source link

[BUG] Controlled time evolution with `lightning.qubit` gives incorrect results #5859

Closed obliviateandsurrender closed 3 months ago

obliviateandsurrender commented 3 months ago

Expected behavior

import pennylane as qml
import numpy as np

symbols = ["H", "H"]
coordinates = np.array([[0.0, 0.0, -0.6614], [0.0, 0.0, 0.6614]])
H, num_qubits = qml.qchem.molecular_hamiltonian(symbols, coordinates, basis="sto-3g", wires=[1, 2, 3, 4])

for dev_name in ["default.qubit", "lightning.qubit"]:
    dev = qml.device(dev_name, wires=num_qubits+1)
    @qml.qnode(dev)
    def cirucit():
        qml.BasisState([1, 1, 0, 0], wires=[1, 2, 3, 4])
        qml.Hadamard(0)
        qml.ctrl(qml.TrotterProduct, control=0, control_values=0)(H, 1)
        qml.Hadamard(0)
        return qml.probs()
    print(f"{dev_name} : {cirucit().round(4)}")

Outputs from both the devices should be equal.

Actual behavior

In reality, we get different results -

default.qubit : [0.     0.     0.     0.0079 0.     0.     0.     0.     0.     0.
 0.     0.     0.7076 0.     0.     0.     0.     0.     0.     0.0079
 0.     0.     0.     0.     0.     0.     0.     0.     0.2765 0.
 0.     0.    ]

lightning.qubit : [0.     0.     0.     0.0079 0.     0.     0.     0.     0.     0.
 0.     0.     0.726  0.     0.     0.     0.     0.     0.     0.0079
 0.     0.     0.     0.     0.     0.     0.     0.     0.2581 0.
 0.     0.    ]

Additional information

This error can probably be boiled down to the missing GlobalPhase during the decomposition of the TrotterProduct to the lightning.qubit device. Therefore, the controlled evolution of Hamiltonians with some scalar Identities that result in a controlled GlobalPhase is skipped and leads to incorrect results.

Please note, this is a high-priority bug for us!

Source code

import pennylane as qml
import numpy as np

symbols = ["H", "H"]
coordinates = np.array([[0.0, 0.0, -0.6614], [0.0, 0.0, 0.6614]])
H, num_qubits = qml.qchem.molecular_hamiltonian(symbols, coordinates, basis="sto-3g", wires=[1, 2, 3, 4])

for dev_name in ["default.qubit", "lightning.qubit"]:
    dev = qml.device(dev_name, wires=num_qubits+1)
    @qml.qnode(dev)
    def cirucit():
        qml.BasisState([1, 1, 0, 0], wires=[1, 2, 3, 4])
        qml.Hadamard(0)
        if dev_name == "lightning.qubit": # Apply the missing the Global Phase to fix the error
            qml.ctrl(qml.GlobalPhase, control=0, control_values=0)(-H.terms()[0][0], wires=[1, 2, 3, 4])
        qml.ctrl(qml.TrotterProduct, control=0, control_values=0)(H, 1)
        qml.Hadamard(0)
        return qml.probs()
    print(f"{dev_name} : {cirucit().round(4)}")

Tracebacks

No response

System information

Platform info:           macOS-13.6.7-arm64-arm-64bit
Python version:          3.10.4
Numpy version:           1.26.4
Scipy version:           1.12.0
Installed devices:
- default.clifford (PennyLane-0.37.0.dev0)
- default.gaussian (PennyLane-0.37.0.dev0)
- default.mixed (PennyLane-0.37.0.dev0)
- default.qubit (PennyLane-0.37.0.dev0)
- default.qubit.autograd (PennyLane-0.37.0.dev0)
- default.qubit.jax (PennyLane-0.37.0.dev0)
- default.qubit.legacy (PennyLane-0.37.0.dev0)
- default.qubit.tf (PennyLane-0.37.0.dev0)
- default.qubit.torch (PennyLane-0.37.0.dev0)
- default.qutrit (PennyLane-0.37.0.dev0)
- default.qutrit.mixed (PennyLane-0.37.0.dev0)
- default.tensor (PennyLane-0.37.0.dev0)
- null.qubit (PennyLane-0.37.0.dev0)
- lightning.kokkos (PennyLane_Lightning_Kokkos-0.36.0)

Existing GitHub issues