Issue with Quantum Fisher Information Matrix Calculation When Specifying argnum

Hello PennyLane Community,

I am currently working on calculating the Quantum Fisher Information Matrix (QFIM) for specific parameters. of the quantum circuit using the qml.gradients.quantum_fisher function. However, I am encountering an issue when I specify the argnum argument to indicate which variables I want the QFIM to be calculated for.

Despite following the documentation, I receive an error message that seems related to the way I am specifying the parameters. I would greatly appreciate your guidance on this matter.

Here is the code I am using, along with the error message I receive:

import numpy as np
import pennylane as qml
from pennylane import numpy as pnp

pnp.random.seed(42)

N_qubits=3 # No. qubits
dev = qml.device('default.qubit', wires=N_qubits)


# Fixed values for each term in the Hamiltonian
coeffs = [0.1, 0.2, -0.3]  # This is a_i for each term
thetas = pnp.array([1., 2., 3.])  # This is theta_i for each term
params = pnp.array([0.5, 0.2, 0.1])  # This is parameters for circuit

# Define the corresponding Pauli operators (observables)
observables = [qml.Z(0), qml.Z(1), qml.Z(2)]

# Construct the Hamiltonian
hamiltonian = qml.Hamiltonian(coeffs, observables)

# Define the quantum circuit with the Hamiltonian evolution
@qml.qnode(dev)
def encoding_circuit(theta, param):
    # Apply the unitary evolution U = exp(-i * H)
    qml.Hadamard(0)
    qml.CNOT(wires=(0,1))
    qml.CNOT(wires=(0,2))
    qml.RZ(theta[0], wires=0)
    qml.RZ(theta[1], wires=1)
    qml.RZ(theta[2], wires=2)
    qml.RX(param[0], wires=0)
    qml.RX(param[1], wires=1)
    qml.RX(param[2], wires=2)
  
    return qml.expval(hamiltonian)

# Run the circuit and print the resulting state
qfim = qml.gradients.quantum_fisher(encoding_circuit, argnum=[0])(thetas, params)
qfim

The full error message is

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-3-8a8e52bb0910> in <cell line: 43>()
     41 
     42 # Run the circuit and print the resulting state
---> 43 qfim = qml.gradients.quantum_fisher(encoding_circuit, argnum=[0])(thetas, params)
     44 qfim

6 frames
/usr/local/lib/python3.10/dist-packages/pennylane/transforms/core/transform_dispatcher.py in __call__(self, *targs, **tkwargs)
     93         if isinstance(obj, qml.tape.QuantumScript):
     94             if self._expand_transform:
---> 95                 expanded_tapes, expand_processing = self._expand_transform(obj, *targs, **tkwargs)
     96                 transformed_tapes = []
     97                 processing_and_sclices = []

TypeError: _expand_trainable_multipar() got an unexpected keyword argument 'argnum'

Here it is the version that I use:

Name: PennyLane
Version: 0.38.0
Summary: 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.
Home-page: https://github.com/PennyLaneAI/pennylane
Author: 
Author-email: 
License: Apache License 2.0
Location: /usr/local/lib/python3.10/dist-packages
Requires: appdirs, autograd, autoray, cachetools, networkx, numpy, packaging, pennylane-lightning, requests, rustworkx, scipy, toml, typing-extensions
Required-by: PennyLane_Lightning

Platform info:           Linux-6.1.85+-x86_64-with-glibc2.35
Python version:          3.10.12
Numpy version:           1.26.4
Scipy version:           1.13.1
Installed devices:
- default.clifford (PennyLane-0.38.0)
- default.gaussian (PennyLane-0.38.0)
- default.mixed (PennyLane-0.38.0)
- default.qubit (PennyLane-0.38.0)
- default.qubit.autograd (PennyLane-0.38.0)
- default.qubit.jax (PennyLane-0.38.0)
- default.qubit.legacy (PennyLane-0.38.0)
- default.qubit.tf (PennyLane-0.38.0)
- default.qubit.torch (PennyLane-0.38.0)
- default.qutrit (PennyLane-0.38.0)
- default.qutrit.mixed (PennyLane-0.38.0)
- default.tensor (PennyLane-0.38.0)
- null.qubit (PennyLane-0.38.0)
- lightning.qubit (PennyLane_Lightning-0.38.0)

Hi @a.rozgonyi96, welcome to the Forum!

If you remove argnum=[0] you will get the output for both thetas and params, where qfim[0] corresponds to the Quantum Fisher Information Matrix for thetas.

So if you only wanted this output you could do: print(qfim[0])

Would this be what you were looking for?

An alternative would be to use param as a global variable instead of an argument but this may not work for a more general program.

@qml.qnode(dev)
def encoding_circuit(theta):
    param = params
    # Apply the unitary evolution U = exp(-i * H)
    qml.Hadamard(0)
    qml.CNOT(wires=(0,1))
    qml.CNOT(wires=(0,2))
    qml.RZ(theta[0], wires=0)
    qml.RZ(theta[1], wires=1)
    qml.RZ(theta[2], wires=2)
    qml.RX(param[0], wires=0)
    qml.RX(param[1], wires=1)
    qml.RX(param[2], wires=2)
  
    return qml.expval(hamiltonian)

# Run the circuit and print the resulting state
qfim = qml.gradients.quantum_fisher(encoding_circuit)(thetas)
qfim

Let me know if this helps!

1 Like

Thank you @CatalinaAlbornoz , it solved my problem perfectly.

Iā€™m glad to hear @a.rozgonyi96 !

Enjoy using PennyLane!