, 2 min read

Loops Over Loops

Problem statement: Loop over a variable number of loops. I.e., we want to search a parameter space and therefore want to loop over multiple loops. The number of loops is variable.

The initial approach goes like this:

for (p1=1; p1<=10; ++p1)
    for (p2=1; p2<=10; ++p2)
        for (p3=1; p3<=10; ++p3)
            for (p4=1; p4<=10; ++p4)
                do_something();

It also might involve only two loops, i.e., p1 and p2, or even more loops, i.e., p1, p2, ..., p9.

Solution: ml[] corresponds to various pi. I.e., ml[0] is p1, ml[1] is p2, etc. Below program starts from start up to stop in increments of step.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define MAXLOOP	50

int main (int argc, char *argv[]) {
    int c, i, k, n=4, cnt=0, start=1, stop=3, step=1;
    int ml[MAXLOOP];

    while ((c = getopt(argc,argv,"i:n:")) != -1) {
        switch(c) {
        case 'i':	// step numbers of base formulas
            sscanf(optarg,"%d:%d:%d",&start,&stop,&step);
            break;
        case 'n':
            if ((n = atoi(optarg)) >= MAXLOOP) return 1;
            break;
        default:
            printf("%s: illegal option %c\n",argv[0],c);
            return 4;
        }
    }
    printf("start=%d, stop=%d, step=%d\n", start, stop, step);

    for (i=0; i<n; ++i) ml[i] = start;

    for (;;) {
        printf("\t");
        for (k=0; k<n; ++k) printf("%6d",ml[k]);
        printf("\t\t%d\n",++cnt);
        for (i=n-1; i>=0; --i) {
            if (ml[i] < stop) {
                ml[i] += step;
                break;
            } else {
                ml[i] = start;
                if (i == 0) return 0;
            }
        }
    }

    return 0;
}

Program running for two loops:

$ tstmultiloop -n2
start=1, stop=3, step=1
             1     1            1
             1     2            2
             1     3            3
             2     1            4
             2     2            5
             2     3            6
             3     1            7
             3     2            8
             3     3            9

Last "digits" varies the fastest.

Three "digits".

$ tstmultiloop -n3 -i-3:3:2
start=-3, stop=3, step=2
            -3    -3    -3              1
            -3    -3    -1              2
            -3    -3     1              3
            -3    -3     3              4
            -3    -1    -3              5
            -3    -1    -1              6
            -3    -1     1              7
            -3    -1     3              8
            -3     1    -3              9
            -3     1    -1              10
            -3     1     1              11
            -3     1     3              12
            -3     3    -3              13
            -3     3    -1              14
            -3     3     1              15
            -3     3     3              16
            -1    -3    -3              17
            -1    -3    -1              18
            -1    -3     1              19
            -1    -3     3              20
            -1    -1    -3              21
            -1    -1    -1              22
            -1    -1     1              23
            -1    -1     3              24
            -1     1    -3              25
            -1     1    -1              26
            -1     1     1              27
            -1     1     3              28
            -1     3    -3              29
            -1     3    -1              30
            -1     3     1              31
            -1     3     3              32
             1    -3    -3              33
             1    -3    -1              34
             1    -3     1              35
             1    -3     3              36
             1    -1    -3              37
             1    -1    -1              38
             1    -1     1              39
             1    -1     3              40
             1     1    -3              41
             1     1    -1              42
             1     1     1              43
             1     1     3              44
             1     3    -3              45
             1     3    -1              46
             1     3     1              47
             1     3     3              48
             3    -3    -3              49
             3    -3    -1              50
             3    -3     1              51
             3    -3     3              52
             3    -1    -3              53
             3    -1    -1              54
             3    -1     1              55
             3    -1     3              56
             3     1    -3              57
             3     1    -1              58
             3     1     1              59
             3     1     3              60
             3     3    -3              61
             3     3    -1              62
             3     3     1              63
             3     3     3              64

It shows 64 entries, i.e., 444.