# Using aesara.scan to "double loop" a vector over an matrix

**URL:** <https://discourse.pymc.io/t/using-aesara-scan-to-double-loop-a-vector-over-an-matrix/10305>\
**Category:** Questions\
**Tags:** aesara\
**Created:** [September 3, 2022, 11:59pm UTC](https://discourse.pymc.io/t/using-aesara-scan-to-double-loop-a-vector-over-an-matrix/10305 "2022-09-03T23:59:00Z")\
**Posts on this page:** 1\
**Showing post:** 3

<div class="post-metadata">

**Author:** ![jessegrabowski](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.pymc.io/jessegrabowski/32/5010_2.png) [@jessegrabowski](https://discourse.pymc.io/u/jessegrabowski)\
**Post date:** [September 4, 2022, 7:48am UTC](https://discourse.pymc.io/t/using-aesara-scan-to-double-loop-a-vector-over-an-matrix/10305/3 "2022-09-04T07:48:47Z")

</div>

I think you’re over-engineering the problem a bit. Sticking to your example numpy code, what you really want is a a function with inputs X, y, M, P, that loops only over the range P to M, and does a specific computation.

A nice trick when using `scan` is to use `aesara.tensor.arange` as the sequence argument, and provide the list of objects to be indexed as non-sequences. This will allow you to collapse the two scans you tried into a single scan. I wrote your numpy example in aesara like this:

```python
y_aes = at.dvector('y')
X_aes = at.dmatrix('X')
P_aes = at.iscalar('P')
M_aes = at.iscalar('M')

results, _ = aesara.scan(lambda j, y, X, P: (y * X[:, (j-P):j]).sum(axis=1),
                         sequences=at.arange(P_aes, M_aes),
                         non_sequences=[y_aes, X_aes, P])

Z_aes = at.concatenate([results], axis=0).T

```

The main scan is exactly the for-loop in your example code. The only line that I think needs a bit of contemplation is `Z_aes = at.concatenate([results], axis=0).T`. The lambda function in the scan (which I stole from your code) outputs a single column of computation. Here we are indexing `X` in such a way that we will get vectors out, so the `result` object is a list of M-P 1d vectors. When you call concatenate on them, you’ll get back a `M-P x N` matrix, so you need to transpose it back to `N x M-P`.

Alternatively, you could try to fuss with shapes in the scan code, so that the lambda function returned N x 1 column vectors.

Verify this gives the right answer:

```python
f_Z = aesara.function([y_aes, X_aes, P_aes, M_aes], [Z_aes])
np.allclose(f_Z(y, X, P, M)[0], Z)
>>> Out: True

```

Finally, if your ultimate goal is to use these computations in a PyMC model, be aware that you should _not_ compile and evaluate the function using `aesara.function`. I did that just as a check to show it’s giving the right answer.

---

_[View the full topic](https://discourse.pymc.io/t/using-aesara-scan-to-double-loop-a-vector-over-an-matrix/10305)._
