# How to perform N-loops with N as an input parameter?

**URL:** <https://discourse.julialang.org/t/how-to-perform-n-loops-with-n-as-an-input-parameter/1150>\
**Category:** New to Julia\
**Tags:** question\
**Created:** [December 25, 2016, 10:59pm UTC](https://discourse.julialang.org/t/how-to-perform-n-loops-with-n-as-an-input-parameter/1150 "2016-12-25T22:59:44Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Aleksandr\_Mikheev](https://avatars.discourse-cdn.com/v4/letter/a/b4bc9f/32.png) [@Aleksandr\_Mikheev](https://discourse.julialang.org/u/Aleksandr_Mikheev)\
**Post date:** [December 25, 2016, 10:59pm UTC](https://discourse.julialang.org/t/how-to-perform-n-loops-with-n-as-an-input-parameter/1150/1 "2016-12-25T22:59:44Z")

</div>

Hello,

Context: I would like to do a d-dimensional midlepoint integration with d as an input parameter. This leads to the problem that I need to make a d-loop

```julia
for i_1 in eachindex(x_1)
   for i_2 in eachindex(x_2)
      ...
      for i_d in eachindex(x_3)
      ...
      end
   end
...
end

```

which I have no idea how to perform.

The other possibility is to make an array of the d-length vectors. However, I do not know how to obtain such structure from x\_1, …, x\_d, either. What should be the best way to go through all n\_1\*…\*n\_d points?

Thank you in advance!

P.S. Also, I need to make it as straightforward as possible since one part of exercise is to compare the performance with MC integration for different d. Hence, no tricks to avoid loops are needed I think.

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [December 25, 2016, 11:33pm UTC](https://discourse.julialang.org/t/how-to-perform-n-loops-with-n-as-an-input-parameter/1150/2 "2016-12-25T23:33:56Z")

</div>

This might be what you are looking for:

> **[Multidimensional algorithms and iteration](https://julialang.org/blog/2016/02/iteration/)**
>
> Multidimensional algorithms and iteration | Julia makes it easy to write elegant and...

---

<div class="post-metadata">

**Author:** ![Aleksandr\_Mikheev](https://avatars.discourse-cdn.com/v4/letter/a/b4bc9f/32.png) [@Aleksandr\_Mikheev](https://discourse.julialang.org/u/Aleksandr_Mikheev)\
**Post date:** [December 26, 2016, 1:15am UTC](https://discourse.julialang.org/t/how-to-perform-n-loops-with-n-as-an-input-parameter/1150/3 "2016-12-26T01:15:25Z")

</div>

Thank you! With this, I found **Iterators.jl** package. There, one can find such function

```julia
product(xs...)

```

which returns all combinations in the cartesian product of the inputs. For instance,

```julia
x = [1,2,3]
y = [1,2,3]

for i in product(x,y)
  @show i
end

i = (1,1)
i = (2,1)
i = (3,1)
i = (1,2)
i = (2,2)
i = (3,2)
i = (1,3)
i = (2,3)
i = (3,3)

```

This is exactly what I need. The only problem now is that I do not know the number of input arrays in advance. Hence, I would like to add them in product one by one, and once again I am stuck. Maybe you know the solution?

Thank you in advance!

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [December 26, 2016, 1:23am UTC](https://discourse.julialang.org/t/how-to-perform-n-loops-with-n-as-an-input-parameter/1150/4 "2016-12-26T01:23:52Z")

</div>

Isn’t `CartesianRange` from the linked post exactly what you need for this?

---

<div class="post-metadata">

**Author:** ![Aleksandr\_Mikheev](https://avatars.discourse-cdn.com/v4/letter/a/b4bc9f/32.png) [@Aleksandr\_Mikheev](https://discourse.julialang.org/u/Aleksandr_Mikheev)\
**Post date:** [December 26, 2016, 12:20pm UTC](https://discourse.julialang.org/t/how-to-perform-n-loops-with-n-as-an-input-parameter/1150/5 "2016-12-26T12:20:51Z")

</div>

Not exactly I believe, or at least I do not understand how to use it the way I need. Honestly, I am a bit confused now. So, I have d-dimensional unit cube which I need to slice to cubes with edge length `1/n`. Then, I need to sum over all of this cubes.

Therefore, if I want to use `CartesianRange`, I need to initialize d-dimensional square array A or initialize a tuple `t = (n, n,..., n)` of length `d`, but I don’t know how to do this if `d` is a parameter. Suppose I did this step. Now I can do something like

```julia
for i in CartesianRange(size(A))
...
end

```

Now, all I need is to map my indices to coordinates. Something like `(k1,k2) => 1/(2*n)*(2*k1-1, 2*k2-1)`. If `i` was a tuple, it would be easy to do with `collect`. However, in this case `i` would be of `CartesianIndex` type, and I am once again confused.

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [December 26, 2016, 2:50pm UTC](https://discourse.julialang.org/t/how-to-perform-n-loops-with-n-as-an-input-parameter/1150/6 "2016-12-26T14:50:12Z")

</div>

To make a tuple of a given length you can use the `ntuple` function, e.g.

```julia
julia> ntuple(i -> [i, i+1], 10)
([1,2],[2,3],[3,4],[4,5],[5,6],[6,7],[7,8],[8,9],[9,10],[10,11])

```

You can use this something like the following:

```julia
julia> d = 3
3

julia> myrange = CartesianRange(ntuple(x->2, d))
CartesianRange{CartesianIndex{3}}(CartesianIndex{3}((1,1,1)),CartesianIndex{3}((2,2,2)))

julia> for i in myrange
          println(i)
       end
CartesianIndex{3}((1,1,1))
CartesianIndex{3}((2,1,1))
CartesianIndex{3}((1,2,1))
CartesianIndex{3}((2,2,1))
CartesianIndex{3}((1,1,2))
CartesianIndex{3}((2,1,2))
CartesianIndex{3}((1,2,2))
CartesianIndex{3}((2,2,2))

```

---

<div class="post-metadata">

**Author:** ![Aleksandr\_Mikheev](https://avatars.discourse-cdn.com/v4/letter/a/b4bc9f/32.png) [@Aleksandr\_Mikheev](https://discourse.julialang.org/u/Aleksandr_Mikheev)\
**Post date:** [December 26, 2016, 4:24pm UTC](https://discourse.julialang.org/t/how-to-perform-n-loops-with-n-as-an-input-parameter/1150/7 "2016-12-26T16:24:21Z")

</div>

Thank you very much! One last question if you don’t mind. As I mentioned, I need to make some transformation from Cartesian indices to some actual coordinates. Right now I run such routine

```julia
# d and n are input parameters

t = ntuple(i -> n, d)
myrange = CartesianRange(t)

for i in myrange
i = collect(i.I)
x = i/n - 1/(2*n)
y = f(x)
...
end

```

Here, `f(x)` is just some function of coordinates.

Is there anything one can significantly change here? I mean, it looks a bit sloppy, in my opinion.

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [December 26, 2016, 5:30pm UTC](https://discourse.julialang.org/t/how-to-perform-n-loops-with-n-as-an-input-parameter/1150/8 "2016-12-26T17:30:00Z")

</div>

You can make it a bit cleaner by not doing the `collect` step:

```julia
x = [(ii - 1/2) / n for ii in i.I]

```

Ccing @timholy in case there’s a better solution, since this would seem to be a common pattern.

---

<div class="post-metadata">

**Author:** ![Aleksandr\_Mikheev](https://avatars.discourse-cdn.com/v4/letter/a/b4bc9f/32.png) [@Aleksandr\_Mikheev](https://discourse.julialang.org/u/Aleksandr_Mikheev)\
**Post date:** [December 26, 2016, 6:16pm UTC](https://discourse.julialang.org/t/how-to-perform-n-loops-with-n-as-an-input-parameter/1150/9 "2016-12-26T18:16:34Z")

</div>

I believe this approach is significantly slower though? I did integration routine twice: first with collect step and then without. Hence, the only difference is in the part we discussed. Here is the benchmark result for n = 6, d = 5:

```julia
BenchmarkTools.Trial: 
  memory estimate: 7.00 mb
  allocs estimate: 209955
  --------------
  minimum time: 5.754 ms (0.00% GC)
  median time: 7.358 ms (0.00% GC)
  mean time: 7.760 ms (9.68% GC)
  maximum time: 13.954 ms (22.68% GC)
  --------------
  samples: 644
  evals/sample: 1
  time tolerance: 5.00%
  memory tolerance: 1.00%

```

and

```julia
BenchmarkTools.Trial: 
  memory estimate: 5.46 mb
  allocs estimate: 194403
  --------------
  minimum time: 81.565 ms (0.00% GC)
  median time: 84.981 ms (0.00% GC)
  mean time: 85.887 ms (0.69% GC)
  maximum time: 100.674 ms (0.00% GC)
  --------------
  samples: 59
  evals/sample: 1
  time tolerance: 5.00%
  memory tolerance: 1.00%

```

---

<div class="post-metadata">

**Author:** ![robertdj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robertdj/32/103_2.png) [@robertdj](https://discourse.julialang.org/u/robertdj)\
**Post date:** [December 26, 2016, 7:20pm UTC](https://discourse.julialang.org/t/how-to-perform-n-loops-with-n-as-an-input-parameter/1150/10 "2016-12-26T19:20:15Z")

</div>

If your primary concern is to perform the integration, then check out my package [SparseGrids](https://github.com/robertdj/SparseGrids.jl).  
It uses the Iterators package for generating the D dimensional quadrature point from the 1D points.
