Amplitude embedding with circuit not yielding any actual measurements

Hello Pennylane Team

This is my first post on the messageboard.

The following code does not yield any actual results on measurement. I am unsure if there is something else required in code to obtain a proper measurement or if perhaps the amplitude embedding method is incompatible with this circuit Ansatz.

Any help or comments would be welcome.

Many thanks

Berend

''' 
DNA encoder using complex amplitudes to represent nucleotide bases
followed by variational quantum circuit.
Cost function not yet implemented.
'''

import pennylane as qml
from pennylane import numpy as np

seq='ATTGTCGGTT'
DNA_list=list(seq)
i=0
while True:
    if 2**i>=len(seq):
        n=i
        break
    i+=1
print(n, 2**n)

encode_DNA={'A':'-1','C':'1','G':'-1j','T':'1j'}
encoded_seq=[complex(encode_DNA[base]) for base in DNA_list]

''' variational quantum circuit

    the circuit uses alternating RQ and RX gates and entangling CNOT gates


'''

def circuit(encoded_seq, qubits,layers, phi):
    
    qml.AmplitudeEmbedding(features=encoded_seq, wires=range(qubits), normalize=True, pad_with=0.)
    
    for l in range(layers):
        
        for q in range(qubits):
            
        # alternating Ry and Rz gates
            
            if q%2!=0:    #odd gate
                qml.RZ(phi[q,l], wires=q)
            else:
                qml.RY(phi[q,l], wires=q)
                
        for q in range(qubits-1):
                
            # entangling layer - connect neighbouring wires and the last and first one
            
            qml.CNOT(wires=[q,q+1])
            
        qml.CNOT(wires=[qubits,0])
        
    # Expectation values in the Z basis
    exp_vals = [qml.expval(qml.PauliZ(q)) for q in range(qubits)]
    return exp_vals
        
        
            
qubits=4
layers=4
phi=np.random.random(size =(qubits, layers))  


results=circuit(encoded_seq,qubits,layers,phi)

print(results)


fig, ax=qml.draw_mpl(circuit)(encoded_seq,qubits,layers,phi)
fig.show()

    

It runs but does not provide any measurement results:

[expval(PauliZ(wires=[0])), expval(PauliZ(wires=[1])), expval(PauliZ(wires=[2])), expval(PauliZ(wires=[3]))]

# Put full error message here

Name: PennyLane
Version: 0.32.0
Summary: PennyLane is a Python quantum machine learning library by Xanadu Inc.
Home-page: GitHub - PennyLaneAI/pennylane: PennyLane is a cross-platform Python library for differentiable programming of quantum computers. Train a quantum computer the same way as a neural network.
Author:
Author-email:
License: Apache License 2.0
Location: /Users/brah/anaconda3/envs/Pennylane_test/lib/python3.8/site-packages
Requires: appdirs, autograd, autoray, cachetools, networkx, numpy, pennylane-lightning, requests, rustworkx, scipy, semantic-version, toml, typing-extensions
Required-by: PennyLane-Lightning

Platform info: macOS-12.6.3-arm64-arm-64bit
Python version: 3.8.18
Numpy version: 1.24.3
Scipy version: 1.10.1
Installed devices:

  • default.gaussian (PennyLane-0.32.0)
  • default.mixed (PennyLane-0.32.0)
  • default.qubit (PennyLane-0.32.0)
  • default.qubit.autograd (PennyLane-0.32.0)
  • default.qubit.jax (PennyLane-0.32.0)
  • default.qubit.tf (PennyLane-0.32.0)
  • default.qubit.torch (PennyLane-0.32.0)
  • default.qutrit (PennyLane-0.32.0)
  • null.qubit (PennyLane-0.32.0)
  • lightning.qubit (PennyLane-Lightning-0.32.0)

Hi,

You haven’t defined a device and a QNode. Like:

dev = qml.device("lightning.qubit", wires='number of qubits inside your circuit')
@qml.qnode(dev, interface="autograd")
def circuit(...): 
    ...

This demo can help you: Simple Clasifier.

Best

1 Like

Hi Christophe

Thanks for spotting the omission. Unfortunately, there is still something wrong with my code.
When I add your missing code, I get the following error message:


ValueError Traceback (most recent call last)
File ~/anaconda3/envs/Pennylane_test/lib/python3.8/site-packages/pennylane/wires.py:239, in Wires.index(self, wire)
238 try:
β†’ 239 return self._labels.index(wire)
240 except ValueError as e:

ValueError: tuple.index(x): x not in tuple

The above exception was the direct cause of the following exception:

WireError Traceback (most recent call last)
Cell In[20], line 52
44 return exp_vals
49 phi=np.random.random(size =(qubits, layers))
β€”> 52 results=circuit(encoded_seq,qubits,layers,phi)
54 print(results)
57 fig, ax=qml.draw_mpl(circuit, style=β€œpennylane”)(encoded_seq,qubits,layers,phi)

File ~/anaconda3/envs/Pennylane_test/lib/python3.8/site-packages/pennylane/qnode.py:989, in QNode.call(self, *args, **kwargs)
986 self.execute_kwargs.pop(β€œmode”)
988 # pylint: disable=unexpected-keyword-arg
β†’ 989 res = qml.execute(
990 (self._tape,),
991 device=self.device,
992 gradient_fn=self.gradient_fn,
993 interface=self.interface,
994 transform_program=self.transform_program,
995 gradient_kwargs=self.gradient_kwargs,
996 override_shots=override_shots,
997 **self.execute_kwargs,
998 )
1000 res = res[0]
1002 # convert result to the interface in case the qfunc has no parameters

File ~/anaconda3/envs/Pennylane_test/lib/python3.8/site-packages/pennylane/interfaces/execution.py:636, in execute(tapes, device, gradient_fn, interface, transform_program, grad_on_execution, gradient_kwargs, cache, cachesize, max_diff, override_shots, expand_fn, max_expansion, device_batch_transform)
634 # Exiting early if we do not need to deal with an interface boundary
635 if no_interface_boundary_required:
β†’ 636 results = inner_execute(tapes)
637 results = batch_fn(results)
638 return program_post_processing(results)

File ~/anaconda3/envs/Pennylane_test/lib/python3.8/site-packages/pennylane/interfaces/execution.py:255, in make_inner_execute..inner_execute(tapes, **)
253 if numpy_only:
254 tapes = tuple(qml.transforms.convert_to_numpy_parameters(t) for t in tapes)
β†’ 255 return cached_device_execution(tapes)

File ~/anaconda3/envs/Pennylane_test/lib/python3.8/site-packages/pennylane/interfaces/execution.py:377, in cache_execute..wrapper(tapes, **kwargs)
372 return (res, ) if return_tuple else res
374 else:
375 # execute all unique tapes that do not exist in the cache
376 # convert to list as new device interface returns a tuple
β†’ 377 res = list(fn(tuple(execution_tapes.values()), **kwargs))
379 final_res =
381 for i, tape in enumerate(tapes):

File ~/anaconda3/envs/Pennylane_test/lib/python3.8/contextlib.py:75, in ContextDecorator.call..inner(*args, **kwds)
72 @wraps(func)
73 def inner(*args, **kwds):
74 with self._recreate_cm():
β€”> 75 return func(*args, **kwds)

File ~/anaconda3/envs/Pennylane_test/lib/python3.8/site-packages/pennylane/_qubit_device.py:629, in QubitDevice.batch_execute(self, circuits)
624 for circuit in circuits:
625 # we need to reset the device here, else it will
626 # not start the next computation in the zero state
627 self.reset()
β†’ 629 res = self.execute(circuit)
630 results.append(res)
632 if self.tracker.active:

File ~/anaconda3/envs/Pennylane_test/lib/python3.8/site-packages/pennylane/_qubit_device.py:337, in QubitDevice.execute(self, circuit, **kwargs)
334 self.check_validity(circuit.operations, circuit.observables)
336 # apply all circuit operations
β†’ 337 self.apply(circuit.operations, rotations=self._get_diagonalizing_gates(circuit), **kwargs)
339 # generate computational basis samples
340 if self.shots is not None or circuit.is_sampled:

File ~/anaconda3/envs/Pennylane_test/lib/python3.8/site-packages/pennylane/devices/default_qubit.py:294, in DefaultQubit.apply(self, operations, rotations, **kwargs)
292 self._state = self._apply_parametrized_evolution(self._state, operation)
293 else:
β†’ 294 self._state = self._apply_operation(self._state, operation)
296 # store the pre-rotated state
297 self._pre_rotated_state = self._state

File ~/anaconda3/envs/Pennylane_test/lib/python3.8/site-packages/pennylane/devices/default_qubit.py:331, in DefaultQubit._apply_operation(self, state, operation)
329 if str(operation.name) in self._apply_ops: # cast to string because of Tensor
330 shift = int(self._ndim(state) > self.num_wires)
β†’ 331 axes = [ax + shift for ax in self.wires.indices(wires)]
332 return self._apply_ops[operation.name](state, axes)
334 matrix = self._asarray(self._get_unitary_matrix(operation), dtype=self.C_DTYPE)

File ~/anaconda3/envs/Pennylane_test/lib/python3.8/site-packages/pennylane/wires.py:265, in Wires.indices(self, wires)
262 if not isinstance(wires, Iterable):
263 return [self.index(wires)]
β†’ 265 return [self.index(w) for w in wires]

File ~/anaconda3/envs/Pennylane_test/lib/python3.8/site-packages/pennylane/wires.py:265, in (.0)
262 if not isinstance(wires, Iterable):
263 return [self.index(wires)]
β†’ 265 return [self.index(w) for w in wires]

File ~/anaconda3/envs/Pennylane_test/lib/python3.8/site-packages/pennylane/wires.py:241, in Wires.index(self, wire)
239 return self._labels.index(wire)
240 except ValueError as e:
β†’ 241 raise WireError(f"Wire with label {wire} not found in {self}.") from e

WireError: Wire with label 4 not found in <Wires = [0, 1, 2, 3]>.

Finally, I fixed it. I did not index the wire correctly. The final CNOT gate should be connected to qubits-1.

qml.CNOT(wires=[qubits-1,0])

Hey @Quvance! Welcome to the forum :sunglasses:

Glad you were able to solve your problem! Since you’re new to PennyLane, I highly recommend checking out some of our demos on our website. Our qubit rotation tutorial is the one you should look at if you only choose one: Basic tutorial: qubit rotation | PennyLane Demos

Let me know if that helps, and please feel free to post more questions on the forum as you start your journey into the PennyLane-iverse :grin:

Excellent, I created a notebook on my side to understand the wires=4 error. Glad you solved it!!!

1 Like