1
$\begingroup$

How do I get Mathematica to run an arbitrary number of Do-loops, where the i-th loop it upper bound given by some function $f(i)$? I badly need help with this.

Let's denote the desired code by Magic[k]. Nested inside all the Do-loops will be some block of code depending on the loops variables, denoted by Max.

Here's an example of what I would like it to do. Magic[1] would do the same thing as

Do[Max[k1], {k1, 1, f[1]}]

Magic[2] would do the same thing as

Do[Do[ Max[k1, k2] ,{k1, 1, f[1]],  {k2, 1, f[2]}]

Magic[3] would do the same thing as

Do[Do[Do[Max[k1, k2, k3], {k1, 1, f[1]]}], {k2, 1, f[2]}], {k3, 1, f[3]}]

and so on.

It would be nice to have an actual working example. let's assume my Max is actually the Max function of Mathematica and that $f(i)=i^2$.

This might be bad coding practice but I find myself in dire need of it.

$\endgroup$
2
  • $\begingroup$ Related: this question, in particular Leonid's answer. $\endgroup$ Aug 16, 2020 at 16:00
  • $\begingroup$ @Marius - Any chance you understand Leonid's answer and are willing to elaborate here as an answer? I am having a hard time understanding his answer since his examples do not even use the code he suggested, and he manually types in the iterator variables and their bounds. $\endgroup$
    – Camilo
    Aug 17, 2020 at 19:29

1 Answer 1

1
$\begingroup$

One can use MixedRadix representation of a number for that matter. As an example consider a list l of length 3 containing f[1], f[2], f[3]. We can automatically build 3 respective loops each running from 0 to f[i]-1 as follows

l = {2, 3, 5};
Do[Print[PadLeft[IntegerDigits[i, MixedRadix[l]], Length[l]]], {i, 0, Times @@ l - 1}]

(*
{0,0,0}
{0,0,1}    
{0,0,2}
{0,0,3}    
{0,0,4}    
{0,1,0}    
{0,1,1}    
{0,1,2}    
{0,1,3}    
{0,1,4}    
{0,2,0}    
{0,2,1}    
{0,2,2}    
{0,2,3}    
{0,2,4}    
{1,0,0}    
{1,0,1}    
{1,0,2}    
{1,0,3}    
{1,0,4}    
{1,1,0}    
{1,1,1}    
{1,1,2}    
{1,1,3}    
{1,1,4}    
{1,2,0}    
{1,2,1}    
{1,2,2}    
{1,2,3}    
{1,2,4}*)
$\endgroup$
5
  • $\begingroup$ Personally, I prefer Tuples[] for this: Do[Print[v], {v, Tuples[Range[l] - 1]}]. $\endgroup$ Aug 16, 2020 at 7:04
  • 1
    $\begingroup$ @J.M. Yes, it is a shorter code, but it requires storage of all Tuples. I wanted to compute everything on fly. $\endgroup$
    – yarchik
    Aug 16, 2020 at 7:22
  • $\begingroup$ @yarchik I'm not sure how to use your code. Would your code be able to do something like Do[ Do[ function(k1,k2), {k1,1,10-k2^2}], {k2,1,10}]? $\endgroup$
    – Camilo
    Aug 17, 2020 at 19:35
  • 1
    $\begingroup$ @Camilo With this example you completely deviate from your original question. In the original post, your summation limits are static, i.e., known in advance. In particular, you suggested to call the upper limits as f[i]. Notice, f[i] depends only on the loop number i. I give a comprehensive solution to this problem. But now in your comment here you request that the upper limit also depends on the outer loop indices. Completely different story. Should be asked as a different question. $\endgroup$
    – yarchik
    Aug 17, 2020 at 20:26
  • 1
    $\begingroup$ @Camilo, I second what yarchik writes here. Please make a new question instead of editing this if you need the generalization that you request in the comments, and think carefully about the full scope of what you need the code to do. $\endgroup$ Aug 17, 2020 at 20:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.