# @nloops with lower triangular indices

**URL:** https://discourse.julialang.org/t/nloops-with-lower-triangular-indices/117903
**Category:** General Usage
**Tags:** question
**Created:** [August 6, 2024, 5:44pm UTC](https://discourse.julialang.org/t/nloops-with-lower-triangular-indices/117903 "2024-08-06T17:44:17Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![fastwave](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fastwave/32/14725_2.png) [@fastwave](https://discourse.julialang.org/u/fastwave)
#### Post date: [August 6, 2024, 5:44pm UTC](https://discourse.julialang.org/t/nloops-with-lower-triangular-indices/117903/1 "2024-08-06T17:44:17Z")

</div>

I am trying to create N nested loops that create indices, up to and including the previous index. I am clearly bad at `Symbol`s and macros and struggling to make up the index expression that `@nloops`. My attempt here clearly fails:

`@nloops 3 i d -> (d < 3) ? range(1,Symbol("i_",d+1)) : (1:3) begin display(@ntuple 2 i) end`

Any help is welcome. Thanks!

---

<div class="post-metadata">

### Author: ![fastwave](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fastwave/32/14725_2.png) [@fastwave](https://discourse.julialang.org/u/fastwave)
#### Post date: [August 6, 2024, 6:19pm UTC](https://discourse.julialang.org/t/nloops-with-lower-triangular-indices/117903/2 "2024-08-06T18:19:42Z")

</div>

A slight improvement:

```julia
@nloops 3 i d -> (d < 3) ? range(1,eval(Symbol("i_",d+1))) : (1:3) begin display(@ntuple 3 i) end

```

Now the problem is that the generated inner loops do not have access to the indices in the outer loops. Strange.

The error:

```julia
ERROR: UndefVarError: `i_2` not defined
Stacktrace:
 [1] top-level scope
   @ :0
 [2] eval
   @ ./boot.jl:385 [inlined]
 [3] eval
   @ ./client.jl:491 [inlined]
 [4] macro expansion
   @ ./cartesian.jl:62 [inlined]
 [5] top-level scope
   @ ./REPL[158]:1

```

---

<div class="post-metadata">

### Author: ![mikmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikmoore/32/31109_2.png) [@mikmoore](https://discourse.julialang.org/u/mikmoore)
#### Post date: [August 6, 2024, 6:22pm UTC](https://discourse.julialang.org/t/nloops-with-lower-triangular-indices/117903/3 "2024-08-06T18:22:35Z")

</div>

I’m not sure whether it’s possible to do what you want with `@nloops`. Those macros are somewhat limited in their capability. I’ve seldom found them actually useful.

I typically find `CartesianIndices` to be more powerful for nested loop ranges. For example,

```julia-repl
julia> ci = CartesianIndices(ntuple(Returns(1:3),3))
CartesianIndices((1:3, 1:3, 1:3))

julia> for c in Iterators.filter(c -> issorted(Tuple(c);rev=true), ci); display(Tuple(c)); end
(1, 1, 1)
(2, 1, 1)
(3, 1, 1)
(2, 2, 1)
(3, 2, 1)
(3, 3, 1)
(2, 2, 2)
(3, 2, 2)
(3, 3, 2)
(3, 3, 3)

```

Equivalently, you could drop the `filter` and instead check the `issorted` condition (and `continue` if it’s violated).

However, (unless the compiler is quite clever, which I’m doubting here) this will still loop over every possible index in order to throw many out (not a big deal in 2-3 dimensions but becomes worse with more).

Another option is to construct a custom iterator that more efficiently visits the lower triangle using the [iteration interface](https://docs.julialang.org/en/v1/manual/interfaces/#man-interface-iteration).

---

<div class="post-metadata">

### Author: ![fastwave](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fastwave/32/14725_2.png) [@fastwave](https://discourse.julialang.org/u/fastwave)
#### Post date: [August 6, 2024, 6:38pm UTC](https://discourse.julialang.org/t/nloops-with-lower-triangular-indices/117903/4 "2024-08-06T18:38:26Z")

</div>

Thanks, I was contemplating going through all indices with `CartesianIndices` and it might be compromise solution in the end. I’ll wait a bit more, there might be a direct solution…

---

<div class="post-metadata">

### Author: ![fastwave](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fastwave/32/14725_2.png) [@fastwave](https://discourse.julialang.org/u/fastwave)
#### Post date: [August 6, 2024, 6:54pm UTC](https://discourse.julialang.org/t/nloops-with-lower-triangular-indices/117903/5 "2024-08-06T18:54:16Z")

</div>

The solution is quite simple. The trick is to use LaTeX style syntax as in the documentation of `@nloops`:

`@nloops(3, i, d -> (d < 3) ? range(1,i_{d+1}) : (1:3), begin display(@ntuple 3 i) end)`
