Repository: PennyLaneAI/pennylane
Pull request #5080 (2024-01-17 21:45:06)

CosineWindow expands over all circuit wires
**Context:**
When StatePrepBase operations are used at the start of a circuit on a subset of all circuit wires, we want to initialize the system state with all other wires set to the zero-state. `CosineWindow` did not implement this edge-case, and only returned a state spanning the subspace of the wires it acts on regardless of wire order given (it only used `wire_order` for transposition, not expansion)

**Description of the Change:**
Update `CosineWindow.state_vector` to expand over unused wires present in the provided `wire_order`

Master:
```pycon
>>> qml.CosineWindow(wires=[0, 1]).state_vector(wire_order=[0, 1, 2]).shape
(2, 2)
```
Branch:
```pycon
>>> qml.CosineWindow(wires=[0, 1]).state_vector(wire_order=[0, 1, 2]).shape
(2, 2, 2)
```

**Benefits:**
No more unexpected errors when `CosineWindow` is used as a state-prep operation on a subset of wires with DefaultQubit

**Possible Drawbacks:**
N/A

[sc-54223]

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/PennyLaneAI/pennylane/pull/5080?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Comparison is base [(`c01cb4b`)](https://app.codecov.io/gh/PennyLaneAI/pennylane/commit/c01cb4b96f758a9f1a0c4e422115829b80e113cb?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) 99.67% compared to head [(`8b52d34`)](https://app.codecov.io/gh/PennyLaneAI/pennylane/pull/5080?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) 99.66%.
> Report is 25 commits behind head on master.


<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##           master    #5080      +/-   ##
==========================================
- Coverage   99.67%   99.66%   -0.01%     
==========================================
  Files         394      394              
  Lines       35670    35463     -207     
==========================================
- Hits        35554    35345     -209     
- Misses        116      118       +2     
```



</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/PennyLaneAI/pennylane/pull/5080?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI).


Patch:
diff --git a/doc/releases/changelog-dev.md b/doc/releases/changelog-dev.md
index 260049a3d..393882590 100644
--- a/doc/releases/changelog-dev.md
+++ b/doc/releases/changelog-dev.md
@@ -144,6 +144,9 @@
 * The return value of `Controlled.generator` now contains a projector that projects onto the correct subspace based on the control value specified.
   [(#5068)](https://github.com/PennyLaneAI/pennylane/pull/5068)
 
+* `CosineWindow` no longer raises an unexpected error when used on a subset of wires at the beginning of a circuit.
+  [(#5080)](https://github.com/PennyLaneAI/pennylane/pull/5080)
+
 <h3>Contributors ✍️</h3>
 
 This release contains contributions from (in alphabetical order):
diff --git a/pennylane/templates/state_preparations/cosine_window.py b/pennylane/templates/state_preparations/cosine_window.py
index 179b6ece2..de6320ed7 100644
--- a/pennylane/templates/state_preparations/cosine_window.py
+++ b/pennylane/templates/state_preparations/cosine_window.py
@@ -115,9 +115,11 @@ class CosineWindow(StatePrepBase):
         if not wire_order.contains_wires(self.wires):
             raise WireError(f"Custom wire_order must contain all {self.name} wires")
 
-        indices = tuple([Ellipsis] + [slice(None)] * num_op_wires)
-
-        ket_shape = [2] * num_op_wires
+        num_total_wires = len(wire_order)
+        indices = tuple(
+            [Ellipsis] + [slice(None)] * num_op_wires + [0] * (num_total_wires - num_op_wires)
+        )
+        ket_shape = [2] * num_total_wires
         ket = np.zeros(ket_shape, dtype=np.complex128)
         ket[indices] = op_vector
 


Test patch:
diff --git a/tests/templates/test_state_preparations/test_cosine_window.py b/tests/templates/test_state_preparations/test_cosine_window.py
index 7fb713697..7d05ed327 100644
--- a/tests/templates/test_state_preparations/test_cosine_window.py
+++ b/tests/templates/test_state_preparations/test_cosine_window.py
@@ -125,3 +125,13 @@ class TestStateVector:
         res = np.reshape(op.state_vector(wire_order=[1, 0]) ** 2, (-1,))
         expected = np.array([0.0, 0.5, 0.25, 0.25])
         assert np.allclose(res, expected)
+
+    def test_CosineWindow_state_vector_subset_of_wires(self):
+        """Tests that the state vector works with not all state wires."""
+        op = qml.CosineWindow([2, 1])
+        res = op.state_vector(wire_order=[0, 1, 2])
+        assert res.shape == (2, 2, 2)
+
+        expected_10 = qml.CosineWindow([0, 1]).state_vector(wire_order=[1, 0])
+        expected = np.stack([expected_10, np.zeros_like(expected_10)])
+        assert np.allclose(res, expected)