Arrays

Arrays are containers of FISH variables where the inserted items are assigned and retrieved via an integer index. Arrays may be multidimensional. See Array Utilities for available methods.

Arrays are less flexible and perform less well than Maps. We suggest arrays be replaced with Maps whenever possible.

The syntax to create a FISH array is

array array1 (i1 , i2 …)

This statement is unusual in FISH syntax, in that it is executed at compile time (i.e., when the c define … end statements are interpreted) rather than runtime (i.e., when the function is executed). It causes an array object to be created and assigned to the symbol name array1. The parameters i1, i2, … specify the array dimensions, and must be actual integers or FISH symbols with integer values that are available at compile time. Several array objects may be created on the same line (e.g., var2 above); the number of dimensions may be different for each array.

Note the following:

  1. The given name may be an existing single variable or function. If so, its value is converted to a pointer to an array, and its former value is lost. If the name does not already exist, it is created as a global variable.
  2. The given dimensions (i1, i2, …) must be positive integers or evaluate to positive integers (i.e., indices start at 1, not 0).
  3. There is no limit to the number and size of the array dimensions, except memory capacity.

Note that array objects can also be created and destroyed with the array.create and array.delete intrinsic functions. The array.create function has the advantage of taking arguments that can be evaluated at runtime. For example, the statement:

array abc(1,2,3)

is equivalent to:

abc = array.create(1,2,3)

except that the former is executed at compile time, and the latter is executed at runtime.

Members of an array are FISH variables (except that there is no name associated with them), and are therefore governed by the same rules as symbol values. If a FISH symbol points to an array, array elements may be accessed by specifying an index in a parenthesis-enclosed list. For example:

var1 = abc(3, nn + 3, max (5, 6))

is a valid statement if abc is currently pointing to a three-dimensional array. Arrays may appear on both sides of an assignment, and arrays may be used as indices of other arrays.

Be aware that if abc currently points to an array, the statement:

abc = 0

will cause abc to become an integer whose value is zero. If no other symbol points to the array, all access to that array is lost and the memory will not be recovered until a model new command is issued.

A FISH array symbol name may be used on the command line with index arguments:

set gravity 0 0 @abc(1,2,3)

where abc points to a three-dimensional array. This is true for assignments as well:

set @abc(1,2,3) = 4.0

The fish list symbols command gives the type as “(array pointer).” If the symbol currently points to an array, this is immediately followed by the size of the array.

In addition to printing the pointer type and size of an array, one can print array entries:

list @abc(1,2,3)

The example below details an example that creates and queries arrays.

model new
model random 10001
fish define afill          ; fill matrix with random numbers
  array var(4,3)
  loop local m (1,array.size(var,1))
    loop local n (1,array.size(var,2))
      var(m,n) = math.random.uniform
    end_loop
  end_loop
end
fish define ashow          ; display contents of matrix
  loop local m (1,array.size(var,1))
    local hed = '   '
    local msg = '  '+string(m)
    loop local n (1,array.size(var,2))
      hed = hed + '               '+string(n)
      msg = msg + '  '+string(var(m,n),8,' ',8,'e')
    end_loop
    if m = 1
      io.out(hed)
    end_if
    io.out(msg)
  end_loop
end
@afill
@ashow