Mathematica Loop with variable nesting depth and variable count at each level

AI Thread Summary
In Mathematica, creating "M" levels of nested loops, where each loop runs from 1 to specific counts (N_1, N_2, ..., N_M), can be efficiently achieved using a single loop that calculates indices based on a single index. The formula for calculating the indices involves modular arithmetic to determine the values of i_1, i_2, ..., i_M during each iteration. An alternative method involves incrementing the first index and resetting it when it exceeds its limit, while incrementing the next index, which can streamline the process. Additionally, examples of both recursive and iterative implementations of factorial functions in Mathematica illustrate different coding approaches, emphasizing the educational value of understanding both methods. The discussion also highlights the importance of mastering recursion, especially for those who find it challenging, and provides resources for further exploration of factorial implementations across various programming languages.
Swamp Thing
Insights Author
Messages
1,028
Reaction score
768
TL;DR Summary
"M" levels of nested loops;
each loop running from 1 to Counts[[m]]
In Mathematica, how can we have "M" levels of nested loops, with each loop (level) going from 1 to Counts=##\{N_1, N_2, ... N_M\}## respectively, where the value of M and the elements of Counts are computed beforehand?
 
Physics news on Phys.org
Swamp Thing said:
TL;DR Summary: "M" levels of nested loops;
each loop running from 1 to Counts[[m]]

In Mathematica, how can we have "M" levels of nested loops, with each loop (level) going from 1 to Counts=##\{N_1, N_2, ... N_M\}## respectively, where the value of M and the elements of Counts are computed beforehand?

Do a single loop of length N_1N_2 \dots N_M and calculate the values of the separate indices (i_1, \dots, i_M) in each iteration based on the single index <br /> 1 \leq i = 1 + (i_1 - 1) + N_1(i_2 - 1) + N_1N_2(i_3 - 1) + \dots + (N_1N_2 \cdots N_{M-1})(i_M - 1) \leq (N_1 \cdots N_{M})<br /> as <br /> \begin{split}<br /> i_1 &amp;= 1 + (i \mod N_1) \\<br /> i_2 &amp;= 1 + ((i - i_1)/N_1 \mod N_2) \\<br /> i_3 &amp;= 1 + ((i - i_1 - N_1i_2)/N_2 \mod N_3)<br /> \end{split} etc.

EDIT: More efficient is to increment i_1 after each loop, and increment i_2 and reset i_1 if this makes i_1 &gt; N_1, etc.
 
Last edited:
jedishrfu said:
There is a discussion on stackexchange about using recursion
pasmith said:
Do a single loop of length N1N2…NM and calculate the values of the separate indices

Thanks, I will do both methods as an exercise to keep from getting rusty. I have always felt a bit daunted by recursive code, so this may be a good time to lay that to rest. And pasmith's method seems to have a lot of moving parts, which will be interesting to master.
 
Code:
// Initialize loop counters
for i = 1 to M:
   I[i] = 1

while true:

    // do stuff

   // Increment I[1]
   I[1] += 1

   for i = 1  to M-1:
      // If I[i] has advanced beyond Counts[i], set it to 1 and increment I[i+1].
      if I[i] > Counts[i]:
         I[i] = 1
         I[i+1] += 1

   // As soon as I[M] is out of range we are done.
   if I[M] > Counts[M]:
      break
 
  • Like
Likes Swamp Thing
Here's am example of factorial in Mathematica from the RosettaCode site:

Mathematica / Wolfram Language

Note that Mathematica already comes with a factorial function, which can be used as e.g. 5! (gives 120). So the following implementations are only of pedagogical value.

Recursive​

Code:
factorial[n_Integer] := n*factorial[n-1]
factorial[0] = 1

Iterative (direct loop)​

Code:
factorial[n_Integer] :=
  Block[{i, result = 1}, For[i = 1, i <= n, ++i, result *= i]; result]

Iterative (list)​

Code:
factorial[n_Integer] := Block[{i}, Times @@ Table[i, {i, n}]]

https://rosettacode.org/wiki/Factorial#Mathematica_/_Wolfram_Language

and more languages implementing factorial:

https://rosettacode.org/wiki/Factorial

I like this site because of its numerous examples and language comparisons.

With respect to recursion, the recursing method has a conditional that stops the recursion at the start of the method, which is best illustrated in Python:

Recursive
Python:
def factorial(n):

    if n<1:      ## stops recursion and blocks negative n values
        return 1

    return n*factorial(n-1)
 
Last edited:
  • Like
Likes Swamp Thing
Back
Top