# Computing custom obsevables in Pennylane

**URL:** https://discuss.pennylane.ai/t/computing-custom-obsevables-in-pennylane/1671
**Category:** PennyLane Help
**Created:** [February 15, 2022, 5:08pm UTC](https://discuss.pennylane.ai/t/computing-custom-obsevables-in-pennylane/1671 "2022-02-15T17:08:37Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![ofir.arzi](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/ofir.arzi/32/886_2.png) [@ofir.arzi](https://discuss.pennylane.ai/u/ofir.arzi)
#### Post date: [February 15, 2022, 5:08pm UTC](https://discuss.pennylane.ai/t/computing-custom-obsevables-in-pennylane/1671/1 "2022-02-15T17:08:37Z")

</div>

I wanted to compute the expectation value of the projector |000\>\<000|+|111\>\<111| in Pennylane. So I wrote down the representing matrix and used the `qml.Hermitian` function which worked as expected, but when I tried to measure the projector |100\>\<100|+|011\>\<011|.

I got an error message because the operator do not commute (which is weird, since the project on different spaces):

```auto
dev = qml.device("default.mixed", wires=3)

@qml.qnode(dev) def circuit():
    return qml.expval(P1(wires=[0,1,2])),qml.expval(P0(wires=[0,1,2]))

def P0(wires):
    down = np.array([1, 0])
    up = np.array([0, 1])
    m1 = np.kron(down, np.kron(down, down))
    m2 = np.kron(up, np.kron(up, up))
    p0 = np.outer(m1 + m2, np.conj(m1 + m2))

    return qml.Hermitian(p0, wires)

def P1(wires):
    p0 = P0(wires)
    X = np.array([[0, 1], [1, 0]])
    I = np.array([[1, 0], [0, 1]])
    X1 = np.kron(np.kron(X, I), I)
    p1 = np.matmul(X1, np.matmul(p0, X1))

    return qml.Hermitian(p1, wires=wires)

```

How can I fix this? And what is the proper way of measuring expectation values \<\hat{O}\>=Tr(O\rho) of a custom operator for a state \rho? Writing the matrix by hand everytime seems a bit too complicated.

---

<div class="post-metadata">

### Author: ![josh](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/josh/32/100_2.png) [@josh](https://discuss.pennylane.ai/u/josh)
#### Post date: [February 15, 2022, 5:34pm UTC](https://discuss.pennylane.ai/t/computing-custom-obsevables-in-pennylane/1671/2 "2022-02-15T17:34:49Z")

</div>

Hey @ofir.arzi! One approach could be to directly use the [`qml.Projector`](https://pennylane.readthedocs.io/en/stable/code/api/pennylane.Projector.html) observable:

```python
def H(wires):
    P100 = qml.Projector(np.array([1, 0, 0]), wires=wires)
    P011 = qml.Projector(np.array([0, 1, 1]), wires=wires)
    return qml.Hamiltonian([1.0, 1.0], [P100, P011], simplify=False)

@qml.qnode(dev)
def circuit():
    return qml.expval(H(wires=[0, 1, 2]))

```

Note that I disable Hamiltonian simplification, since it seems to not currently work with the projector observable yet (likely a bug!)

---

<div class="post-metadata">

### Author: ![ofir.arzi](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/ofir.arzi/32/886_2.png) [@ofir.arzi](https://discuss.pennylane.ai/u/ofir.arzi)
#### Post date: [February 16, 2022, 9:46am UTC](https://discuss.pennylane.ai/t/computing-custom-obsevables-in-pennylane/1671/3 "2022-02-16T09:46:30Z")

</div>

Thanks @josh! How come I can’t return with simply `qml.expval(P100+P011)` or `qml.expval(P100) + qml.expval(P011)`?

---

<div class="post-metadata">

### Author: ![ofir.arzi](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/ofir.arzi/32/886_2.png) [@ofir.arzi](https://discuss.pennylane.ai/u/ofir.arzi)
#### Post date: [February 16, 2022, 9:54am UTC](https://discuss.pennylane.ai/t/computing-custom-obsevables-in-pennylane/1671/4 "2022-02-16T09:54:53Z")

</div>

Furthermore, trying to return as follows fails:

```auto
def H1(wires):
    P100 = qml.Projector(np.array([1, 0, 0]), wires=wires)
    P011 = qml.Projector(np.array([0, 1, 1]), wires=wires)
    return qml.Hamiltonian([1.0, 1.0], [P100, P011], simplify=False)

def H2(wires):
    P100 = qml.Projector(np.array([0, 0, 1]), wires=wires)
    P011 = qml.Projector(np.array([1, 1, 0]), wires=wires)
    return qml.Hamiltonian([1.0, 1.0], [P100, P011], simplify=False)

@qml.qnode(dev)
def circuit():
    return qml.expval(H1(wires=[0, 1, 2])), qml.expval(H2(wires=[0, 1, 2]))

```

The error is `pennylane.QuantumFunctionError: Only observables that are qubit-wise commuting Pauli words can be returned on the same wire`. But as far as I understand the two observables are commuting!

---

<div class="post-metadata">

### Author: ![josh](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/josh/32/100_2.png) [@josh](https://discuss.pennylane.ai/u/josh)
#### Post date: [February 16, 2022, 1:44pm UTC](https://discuss.pennylane.ai/t/computing-custom-obsevables-in-pennylane/1671/5 "2022-02-16T13:44:19Z")

</div>

@ofir.arzi after some investigation, the two cases above appear to be two separate bugs in PennyLane:

- The first is that addition of Projectors doesn’t seem to be natively supported

- The second is that the current logic for computing commutation of Hamiltonians assumes that the Hamiltonian is composed purely of Pauli words.

Thanks for catching these, this is very useful feedback that I will take back to the development team!
