| |||||||||||
|
Make_VariablesBelow is a rather nice variable generator program. We may wish to generate say, 20 variables of the form x01, x02, ... , x20. Note, here, the importance of the leading 'zeros' for the first 9 variables. The same principle applies for 100 variables: x001, x002, ..., x100 and so on. In Derive, and in the easier make_variables function described elsewhere, Derive automatically removes any leading zeros. We want to keep them! Such variables are particularly useful, for example in Neural Networks, where it is common to have, say, 60 or more such variables. Consider the following function make_variables:
The list of arguments is self-explanatory, except for: vars - variables: p_of_10 - power of 10: var_list - variable list: v_ - some vector v: and p10 - another counter. The first prog line, vars := string(vars), tells Derive we want the variables vars to be of data type string. This is the nitty-gritty, as we are saying: the first variable is a string x001, etc; NOT a normal variable x1. p_of_10 := floor(log(n, 10)). As we count in denary, and the leading zeros need to be padded out in units of 10, so we need to calculate logs to base 10. p_of_10 simply calculates the exponent necessary to find out how many leading zeros are required. prefix := iterate(insert(0, v_, 0), v_, vars, p_of_10) inserts a '0' in vector v_, at position '0'. This is repeated 'power_of_10' times. prefix, as the name suggests, represents the leading zeros. We start off with the empty vector, var_list := []. 'counter' and 'p10' are both counters, initialised to 1. The loop is perhaps more easily understood by reading 'bottom to top'. var_list
:= APPEND(var_list, [INSERT(counter, prefix, 0)]) effectively creates the list of
variables, appending an extra variable each time the loop is passed through,
subject to counter > n. So: MAKE_VARIABLES(x,20) [x01,x02,x03,x04,x05,x06,x07,x08,x09,x10,x11,x12,x13,x14,x15,x16,x17,x18,x19,x20]
An alternative to the above, which may or may not be faster in practice [see Debugging], although perhaps not as easy to read (particularly the var_list:= line, within the loop):
This is typed in the Entry line as: MAKE_VARIABLES(vars, n, p_of_10, var_list, counter, v_) := PROG(vars := STRING(vars), p_of_10 := FLOOR(LOG(n, 10)), var_list := [], counter := 1, LOOP(IF(counter > n, RETURN REVERSE(var_list)), var_list := ADJOIN(INSERT(counter, ITERATE(INSERT(0, v_, 0), v_, vars, p_of_10 - FLOOR(LOG(counter, 10))), 0), var_list), counter :+ 1)) Sometimes however one can use a sledgehammer to crack a nut and a little lateral thinking with some insight, all the lines of code above can be condensed into a single line. This 'improvement' comes from the 'mighty' Johann Wiesenbauer . make_variables(x, n) := MAP_LIST(REPLACE(STRING(x), STRING(k + 10^DIM(n))), k, n) REPLACE(x,v,n)
replaces the contents of the nth element
of v with
x,
were the default for n is 1.
| ||||||||||||||||