Next: Casts, Previous: Functions, Up: Programming
Appending []
to a built-in or user-defined type yields an array.
The array element i
of an array A
can be accessed as A[i]
.
By default, attempts to access or assign to an array element using a negative
index generates an error. Reading an array element with an index
beyond the length of the array also generates an error; however,
assignment to an element beyond the length of the array causes the
array to be resized to accommodate the new element.
One can also index an array A
with an integer array B
:
the array A[B]
is formed by indexing array A
with
successive elements of array B
.
The declaration
real[] A;
initializes A
to be an empty (zero-length) array. Empty arrays should be
distinguished from null arrays. If we say
real[] A=null;
then A
cannot be dereferenced at all (null arrays have no length
and cannot be read from or assigned to).
Arrays can be explicitly initialized like this:
real[] A={0,1,2};
Array assignment in Asymptote
does a shallow copy: only
the pointer is copied (if one copy if modified, the other will be too).
The copy
function listed below provides a deep copy of an array.
Every array A
of type T[]
has the virtual members
int length
, void cyclic(bool b)
, bool cyclicflag
,
T push(T x)
, void append(T[] a)
, and T pop()
.
The member A.length
evaluates to the length of the array.
Setting A.cyclic(true)
signifies that array indices should be reduced
modulo the current array length. Reading from or writing to a nonempty
cyclic array never leads to out-of-bounds errors or array resizing. The member
A.cyclicflag
returns the current setting of the cyclic
flag.
The functions A.push
and A.append
append their
arguments onto the end of the array (for convenience A.push
also returns its argument), while A.pop()
pops and
returns the last element. Like all Asymptote
functions,
cyclic
, push
, pop
, and append
can be
"pulled off" of the array and used on their own. For example,
int[] A={1}; A.push(2); // A now contains {1,2}. A.append(A); // A now contains {1,2,1,2}. int f(int)=A.push; f(3); // A now contains {1,2,1,2,3}. int g()=A.pop; write(g()); // Outputs 3.
The []
suffix can also appear after the variable name; this
is sometimes convenient for declaring a list of variables and arrays
of the same type:
real a,A[];This declares
a
to be real
and implicitly declares A
to
be of type real[]
. But beware that this alternative syntax
currently does not construct certain internal type-dependent functions
that take real[]
as an argument: alias
, copy
,
concat
, sequence
, map
, and transpose
for
type real[]
won't be defined until the type real[]
is
explicitly used.
In the following list of built-in array functions, T
represents a
generic type.
new T[]
T[]
;
new T[] {list}
T[]
initialized with list
(a comma
delimited list of elements).
new T[n]
n
elements of type T[]
.
Unless they are arrays themselves, these n
array elements are
not initialized.
int[] sequence(int n)
n >= 1
returns the array {0,1,...,n-1}
(otherwise returns
a null array);
int[] sequence(int n, int m)
m >= n
returns an array {n,n+1,...,m}
(otherwise
returns a null array);
T[] sequence(T f(int),n)
n >= 1
returns the sequence {f_i :i=0,1,...n-1}
given a
function T f(int)
and integer int n
(otherwise returns a
null array);
int[] reverse(int n)
n >= 1
returns the array {n-1,n-2,...,0}
(otherwise
returns a null array);
int[] complement(int[] a, int n)
a
in
{1,2,...,n}
, so that b[complement(a,b.length)]
yields the
complement of b[a]
.
int find(bool[], int n=1)
n
th true
value or -1 if not found.
If n
is negative, search backwards from the end of the array for the
-n
th value;
int search(T[] a, T key)
T
, searches a sorted ordered array
a
of n
elements to find an interval containing
key
, returning -1
if key
is less than the first
element, n-1
if key
is greater than or equal to the last
element, and otherwise the index corresponding to the left-hand
(smaller) endpoint.
T[] copy(T[] a)
a
;
T[] concat(T[] a, T[] b)
a
and b
;
bool alias(T[] a, T[] b)
true
if the arrays a
and b
are identical;
T[] sort(T[] a)
T
, returns a copy of a
sorted in
ascending order;
T[][] sort(T[][] a)
T
, returns a copy of a
with the rows
sorted by the first column, breaking ties with successively higher
columns. For example:
string[][] a={{"bob","9"},{"alice","5"},{"pete","7"}, {"alice","4"}}; // Row sort (by column 0, using column 1 to break ties): write(stdout,sort(a));
produces
alice 4 alice 5 bob 9 pete 7
T[][] transpose(T[][] a)
a
.
T sum(T[] a)
T
, returns the sum of a
.
T min(T[] a)
T min(T[][] a)
T min(T[][][] a)
T
, returns the minimum element of a
.
T max(T[] a)
T max(T[][] a)
T max(T[][][] a)
T
, returns the maximum element of a
.
map(f(T), T[] a)
f
to each
element of the array a
.
T[] min(T[] a, T[] b)
T
, and arrays a
and b
of the same length, returns an array composed of the minimum of the
corresponding elements of a
and b
.
T[] max(T[] a, T[] b)
T
, and arrays a
and b
of the same length, returns an array composed of the maximum of the
corresponding elements of a
and b
.
pair[] fft(pair[] a, int sign=1)
a
(if the optional
FFTW
package is installed), using the given sign
. Here
is a simple example:
int n=4; pair[] f=sequence(n); write(f); pair[] g=fft(f,-1); write(); write(g); f=fft(g,1); write(); write(f/n);
real[] tridiagonal(real[] a, real[] b, real[] c, real[] f);
f
, where f
is an n vector and L is the n \times n matrix
[ b[0] c[0] a[0] ] [ a[1] b[1] c[1] ] [ a[2] b[2] c[2] ] [ ... ] [ c[n-1] a[n-1] b[n-1] ]For Dirichlet boundary conditions (denoted here by
u[-1]
and
u[n]
), replace f[0]
by f[0]-a[0]u[-1]
and
f[n-1]-c[n-1]u[n]
; then set a[0]=c[n-1]=0
.
real[] quadraticroots(real a, real b, real c);
ax^2+bx+c=0
.
real[] cubicroots(real a, real b, real c, real d);
ax^3+bx^2+cx+d=0
.
Asymptote
includes a full set of vectorized array instructions for
arithmetic (including self) and logical operations. These
element-by-element instructions are implemented in C++ code for speed. Given
real[] a={1,2}; real[] b={3,2};then
a == b
and a >= 2
both evaluate to the vector
{false, true}
.
To test whether all components of a
and b
agree,
use the boolean function all(a == b)
. One can also use conditionals like
(a >= 2) ? a : b
, which returns the array {3,2}
, or
write((a >= 2) ? a : null
, which returns the array {2}
.
All of the standard built-in libm
functions of signature
real(real)
also take a real array as an argument, effectively like an
implicit call to map
.
As with other built-in types, arrays of the basic data types can be read in by assignment. In this example, the code
file fin=input("test.txt"); real[] A=fin;
reads real values into A
until the end of file is reached (or an
I/O error occurs). If line mode is set with line(file)
, then
reading will stop once the end of the line is reached instead
(line mode may be cleared with line(file,false)
):
file fin=input("test.txt"); real[] A=line(fin);
Another useful mode is comma-separated-value mode, set with csv(file)
and cleared with csv(file,false)
, which skips over any comma delimiters:
file fin=input("test.txt"); real[] A=csv(fin);
To restrict the number of values read, use the dimension(file,int)
function:
file fin=input("test.txt"); real[] A=dimension(fin,10);
This reads 10 values into A, unless end-of-file (or end-of-line in line mode) occurs first. Attempting to read beyond the end of the file will produce a runtime error message. Specifying a value of 0 for the integer limit is equivalent to the previous example of reading until end-of-file (or end-of-line in line mode) is encountered.
Two- and three-dimensional arrays of the basic data types can be read in like this:
file fin=input("test.txt"); real[][] A=dimension(fin,2,3); real[][][] B=dimension(fin,2,3,4);Again, an integer limit of zero means no restriction.
Sometimes the array dimensions are stored with the data as integer
fields at the beginning of an array. Such arrays can be read in with the
functions read1
, read2
, and read3
, respectively:
file fin=input("test.txt"); real[] A=read1(fin); real[][] B=read2(fin); real[][][] C=read3(fin);
One, two, and three-dimensional arrays of the basic data types can be
output with the functions write(file,T[])
,
write(file,T[][])
, write(file,T[][][])
, respectively.
The command scroll(int n)
is useful for pausing the output
after every n output lines (press Enter
to continue).