## 4.7 Advanced Looping Constructs

Combinations of the modules described above enable you to create advanced looping constructs. These constructs are equivalent to C-language constructs such as "do while" or "for" loops containing "break" and "continue" statements. In the following figures the Sum and Increment macros, as described above, are used as well as a macro named Equals that consists of a Compute where the expression is "a==b?1:0" (if the inputs are equal output 1 otherwise output 0).

Illustrated in Figure 25 is a macro that computes the sum of numbers from 1 to N. If a number in the sequence from 1 to N is equal to an external input, x, the loop terminates and returns the sum from 1 to x. Done, in combination with Equals, is used to cause early termination of the loop. Done causes the loop to terminate after all the modules in the macro have executed if the input to Done is nonzero. The macro illustrated in Figure 25 is equivalent to the C-language statements:

      sum = 0;
      i = 0;
      do
      {
         i++;
         sum = sum+i;
      } while (i<=n && i!=x);

Now consider a macro in which the sum of numbers from 1 to N is computed, but if a number is equal to an external input value, x, it is excluded from the sum. To achieve this result using C-language statements, you would use a conditional with a "continue" statement:

        sum = 0;
        for (i=1; i<=n; i++)
        {
           if (i==x) continue;
           sum = sum+i;
        }

Figure 25. Example 8

As illustrated in Figure 26, you would use Route to create this macro using Data Explorer. The `selector` input of Route is being controlled by the output of Compute. The Compute has its expression set to "a==b?0:1" (if a and b are equal output 0, otherwise output 1). (This is similar to the Equal macro used earlier, but the expression differs slightly.) Therefore, if the iteration variable is equal to x, Compute outputs a 0, causing Route to disable the execution of all the modules downstream from it. This implies that Sum and SetLocal will not run; therefore, during the next iteration, GetLocal will retrieve the same value as the current iteration.

Unfortunately, the visual program illustrated in Figure 26 has a minor problem. If x equals N, the Route will cause the Sum and SetLocal not to execute during the last iteration; therefore the output of the macro will be a NULL.

Figure 26. Example 9

Illustrated in Figure 27 is the fix to the problem. A Switch is included to choose the correct input for the output of the macro. If x equals N, the output of the GetLocal is chosen; otherwise the output of Sum is chosen.

Figure 27. Example 10

If you want to create a loop containing an early exit in the middle of the loop (a "break"), you need to use a Route in combination with Done. Illustrated in Figure 28 is a macro that performs the equivalent function as the C-language statements:

        sum = 0;
        for (i=1; i<=n; i++)
        {
           if (i==x) break;
           sum = sum+i;
        }

Data Explorer allows you to have multiple Done tools in a single loop enabling you to have more than one break or continue or combinations of the two.

Figure 28. Example 11

ForEachN or ForEachMember simplify the use of loops but they are not necessary for creating them. In fact, Done itself is sufficient, if it is included inside a macro. The macro will execute repeatedly as long as the `done` parameter is equal to 0 (zero). Note that the top-level visual program is itself a macro, so the same behavior will occur if Done is placed in the top-level visual program.

Illustrated in Figure 29 is a macro that computes the Fibonacci Series (defined by setting Y1= 1, Y2 = 1 and by the recursion formula Yk = Yk-2 + Yk-1, for k = 3,4,5...). In this example a two vector, [Yk-1, Yk], is used to store the elements of the series. The GetLocal module has its initial value set to [1,1]. The first Compute in the macro creates a new two vector consisting of [Yk-1, Yk] using the expression "[a.1, a.0 + a.1]." The second Compute in the macro extracts Yk from the two vector using the expression "a.1." To terminate the loop, the Yk element of the series is checked against an external input, x. If Yk is greater than x, the loop terminates. GreaterThan is a simple macro consisting of a Compute with its expression set to "a>b?1:0." An equivalent set of C-language statements is:

      a=1;
      b=1;
      do {
         c = b;
         b = b + a;
         a = c;
      } while (b <= x);

Figure 29. Example 12

[ OpenDX Home at IBM | OpenDX.org ]