May 2007
Beyond Ranges: Iteration Again
by Stuart Bruff

Last month's article, Range, Sequences, and Variables, discussed the differences between vectors and range variables, and touched upon sequences. This article expands on the uses of range variables and highlights some of the limitations of a range variable only approach..  simple functions can help make using range variable easier. The article introduces programming and the use of sequences by way of the for-loop.


Vectors, Ranges, and Variables


Both ranges and vectors are types of data. A vector is a single-column array that stores list of other data types, such as numbers or even other arrays. A range does not store data but specifies the first, second, and last values of a uniformly spaced set of real numbers.



The examples above show first creating a vector using the function stack to combine the values 1 through 4, then assigning the vector to the variable v. You can then create a range using the first..last notation and assign it to the variable i.


A variable that has a range for its value is called a range variable; it differs from a normal variable in that Mathcad treats it as an instruction to evaluate an expression for each value of the range.


Example of using a range variable


The Fibonacci sequence is "1,1,2,3,5,8,13,21 ...", where each number in the sequence is the sum of the preceding two elements. To start the sequence, define the first two elements to both be 1. For the nth number, the indices of the two preceding number are simply n-1 and n-2.

 


You can use a range variable to quickly and conveniently generate arrays of data where each value is dependent on only the 'current' range variable value or elements of the array that have already been calculated. The notation occurs commonly in mathematics and requires no special programming skills. With a small amount of thought, the range variable can meet many iteration requirements.


Parallel calculations using range variables


One potential problem with range variables is that the values of several iterated variables may be mutually dependent. If you calculate them individually, you lose that dependence, as the range variable applies to only one region. However, if you put related expressions inside an array, you can calculate the variables in parallel.


For example, consider an infection model with four variables. The time development of this model is given by the equations below:


i  number of individuals

s  number susceptible

d  number decreased (eliminated)

r  number recovered (immune)


     TIME

 


If you simply calculate it in isolation, you would hit problems immediately. The value of i at any time depends upon the value of s, so you need to know the values of s. However, the values of s depend upon the values of i, so you need to know the values of i.


The array method of synchronizing iteration provides an elegant way round this dilemma and, once more, looks like commonly occurring notation.


Breaking the Iteration


You can numerically estimate square roots using seeded iteration. It is a simple example but shows how you can repeatedly evaluate expressions to determine convergence. A vector is initialized with a guess value, then the range variable generates successive guess values from the convergence expression. The resulting vector lists all of the guesses and, hopefully, the desired result.


In this case, start with a positive real number X for which you want the square root and an initial guess value for the square root.



Next create a range variable; as this algorithm converges fairly quickly, choose a small range:



Then iterate over the range, updating each guess in terms of previous ones.



Convergence is very fast, but the number of iterations, N, can be increased to suit the needs of the problem.


However, if the convergence rate is unknown or unpredictable, you could end up choosing a range that is significantly large in terms of both execution time and storage. It would be convenient to be able to stop the iteration when the guess values converged to a constant value. The until function is helpful here.


The until function takes the form until(expr1, expr2), where expr1 is a test expression (usually involving a single range variable). When this expression becomes negative, the until function halts iteration. expr2 is the value returned by the until function at each iteration.


Ideally, you want to halt the square root iteration when two successive guesses are equal. However, to avoid problems with numerical round off causing values to alternate by small amounts, you can terminate the process when the square of the guess differs from X by one part in a million. Define a function, close_enough, and call it for expr1. The previous guess expression is expr2.



initialize the new guess vector



iterate until convergence is reached



count the rows and define a new range variable based on the length of newguess




show the new values



The until function has successfully reduced the number of iterations.


Some Issues with Range Variables


As you see, range variables provide Mathcad with a flexible and easy-to-use method of iterating expressions. A single range variable can apply to multiple expressions, which makes it easy to vary the number of iterations according to the particular details of a problem.


Sometimes varying the iterations can be a problem. Consider the square root solution. Every time you need to calculate a square root, you must either change X, copy and paste the guess expressions as needed, or modify the expressions. It would be more convenient if you could wrap the root algorithm up in a function and simply pass numbers to it.


Furthermore, although you can terminate expressions by use of the until function, you still have to create a large enough range to guarantee convergence - just add 6 zeros onto the end of X above to see the problem.


The examples above are deliberately simple, but many real world problems involve long and detailed expressions. The single line limitation of a single line expression makes such expressions difficult to write, interpret, and modify.


In addition, there are classes of problem where only the final value is of interest, and where each value only depends upon its predecessor, for example, the square root algorithm; a brief examination shows that guessi+1 only depends on guessi. Consequently, there is no need to store the intermediate results in a vector at all. Unfortunately, you can't use the until function here, as it only works in the context of a range variable and  otherwise generates an error:



This 'break' must occur within a loop


for loop and while loop


Mathcad's programming language can be used to resolve some of these issues, by grouping related statements together. The for-loop and while-loops offer more control than the range variable.


Note: The programming operators while, for, if, and return should only be entered using the programming toolbar or a keyboard shortcut. They won't work if you type in the word.


The while loop


The while operator starts with a condition, evaluates it, and if it's true (not equal to zero), executes the subsequent, indented expressions. The operation repeats until the expression becomes false (zero). Look at the square root algorithm solved by a while loop. The major difference between the while loop and the until function, is that the while loop iterates while the guess isn't close enough. Modify the convergence test to account for this. Guess is now a a simple scalar.



Note the use of the left arrow operator to perform assignment. Although a Mathcad program can refer to an externally defined variable, it cannot modify it. If a program tries to assign a value to a variable, Mathcad creates a new 'local' variable (if one of that name doesn't already exist). This is an important point - the variable newguess in the program above is completely independent of the previous newguess, as you can see by evaluating newguess.



The local variable newguess in the program only exists within the context of the program, that is, it is 'local' to the program.

 

An advantage of the while loop is that you don't have to worry about how many iterations the program needs to take, and it uses far less memory than multiple vectors.


The program also encapsulates the whole algorithm in one region, making it easier to copy and paste for different values. Even more usefully, you can convert the program to a function and call that as you would any other function.




Now take a look at the for loop, but first review what a sequence is.


Sequences


A sequence is a comma-separated list of values, where a value is a scalar, string, array, sequence, range, function name, or an expression that evaluates to one of these types of values (for example an evaluated function or a range variable). The argument  to the stack function is a sequence.


Note that a sequence is not a vector, and it isn't possible to pick out a single element from within it. A sequence also differs from a range in that it can't be assigned to a variable, which makes statements like the one below, flag up an error.



Sequences are often used as arguments to functions. However, sequences are at their most useful as the argument to a for loop.


For Loops


A for loop takes the form



where x is a variable, known as the iteration variable, s is a sequence and z is one or more lines that Mathcad evaluates for each iteration. The key to the for loop is that x works its way from left to right through the sequence, taking on each value in turn. 

The first example uses a simple range that makes x take on the values 1 through 5; the local variable i indexes the vector v and assigns each value of k to successive elements of v.



The second example is slightly more complex; the sequence comprises the two scalars 1 and 2, and the range 3,5..9 consequently takes on the values 1, 2, 3, 5, 7, 9.



The third example uses a matrix as the sequence. Mathcad scans the matrix element by element, working down each successive column. Note the different approach to indexing the vector v. With a zero-based array, the function rows always return a value one greater than the index of the last element of a vector. If you use rows as an index, it effectively points to the next 'free' element of the vector. To get it started, define v as a scalar. A scalar has zero rows, so writing to v0 causes the first iteration to transform v into a vector and subsequent iterations extend v.



Referring back to the Fibonacci sequence, you now have a means of encapsulating the entire algorithm in a single region, using the multiline capability of programming to initialize the sequence and the for-loop to perform the iteration:




The function Fib(n), as defined above, returns a vector containing the first n + 1 Fibonacci numbers. The function also shows some other important aspects of programming. Unlike the range variable version, you can check that the function returns a valid result for n less than or equal to 1 and for n equal 2. You can use the if operator to check the condition and the return operator to stop evaluating the result.


The if operator tests a condition. If the condition is true (not zero), it evaluates an associated clause. The if operator may look a little strange since the condition appears on the right-hand side of the operator 'if',  but the clause appears on the left-hand side.  When the clause is spread over two or more lines, Mathcad drops the clauses underneath the if operator and indents them.



A final point is that if fib were not the last line of the function Fib, Mathcad returns fibn; by default, Mathcad returns the last value calculated, which in this instance is the final value of the sequence. Adding fib ensures that you return the entire vector.


About the Author


Stuart Bruff has 25 years experience in engineering, both as a Royal Air Force communications engineer officer and subsequently as a systems engineer in the United Kingdom aerospace industry. He has used Mathcad since version 7 and is a regular contributor to the Mathcad User's Forums. He also works as a Mathcad consultant.




Right-click to
download Mathcad file (version Mathcad 13). You must have Mathcad installed on your computer before you can view this file. 


Was this article interesting? Let us know.







[PRINTER FRIENDLY VERSION]
HOME

Practical Tips for Working in Pro/ENGINEER
PTC Updates
Tips of the Month
Mathcad Methods
Knowledge Base Exclusive
Webcasts & Events
Model-Centric Makes Sense
Beyond Ranges: Iteration Again

Contact PTC | Privacy Policy | PTC Express Archive | Subscribe | Unsubscribe | Change Preferences | Edit Profile

This e-mail was sent to:   PTC, 140 Kendrick Street, Needham, MA 02494 USA
If you are unable to read this page correctly, please click here