HELP ARRPACK David Young
December 2003
revised March 2004
Modified by A.Sloman 21 Dec 2004
Added some extra code to make the examples work and some instructions
to print out results for testing.
LIB * _______ARRPACK is an array processing package for Pop-11. It provides
efficient procedures to carry out arithmetic and logical operations on
elements of real and complex arrays. A whole array or a subset of its
elements may be processed in a single procedure call. _______ARRPACK is
restricted to operations in which each array element is treated
separately from other elements of the same array, such as the
element-by-element addition of two arrays. (Operations where each
element is processed along with its neighbours, such as convolution,
Fourier transforms and matrix operations, are provided by other
libraries.) A higher-level interface to these procedures may be provided
in future.
CONTENTS - (Use g to access required sections)
1 General Information
1.1 When to use this package
1.2 Loading and checking the library
1.3 Procedure names
1.4 Array storage types
1.5 Other array argument considerations
1.6 Repeated use of arrays
2 Active sets
2.1 General
2.2 Whole array
2.3 Regular grids in rectangular regions
2.4 Consistency between arguments with region/grid active sets
2.5 Mask selection
2.6 Indexed sets
2.7 Consistency between arguments with indexed active sets
2.8 Efficiency of masked and indexed sets
2.9 Switching between masked, grid and indexed representations
3 Procedures
3.1 Conventions
3.2 Copying and type conversion
3.3 Reshaping
3.4 Finding locations of non-zero values
3.5 Setting values
3.6 Arithmetic operations on single arrays
3.7 Arithmetic operations on two arrays
3.8 Mathematical functions
3.9 Relational operations
3.10 Logical operations
3.11 Scalar functions of arrays
3.12 Miscellaneous
-----------------------------------------------------------------------
1 General Information
-----------------------------------------------------------------------
1.1 When to use this package
-----------------------------
The _______ARRPACK library provides a convenient way of carrying out arithmetic
and logical operations on arrays, when the operation is applied to each
element (or set of corresponding elements in different arrays)
separately. This covers, for example, adding two arrays element by
element, or comparing each element of an array to a constant. For large
arrays the library procedures are much faster than equivalent procedures
written wholly in Pop-11 - generally by at least an order of magnitude.
For very small arrays the overhead of calling the external procedure
makes the library slightly slower than using pure Pop-11. Simple tests
on a Sun give a break-even point at about a 4x4 array for
single-precision addition, and this suggests that for all but the
smallest arrays it is worth considering using _______ARRPACK for efficiency.
All the operations can be applied to subsets of array elements,
specified in a variety of ways, giving considerable flexibility.
1.2 Loading and checking the library
-------------------------------------
The library may be loaded with
uses popvision, arrpack;
This should produce no error messages or warnings. If there is a message
to the effect that the object file cannot be found, it may be necessary
to recompile the external functions, using the Gnu C compiler, for the
system you are working on. In this case, consult the *POPVISION
documentation.
A simple check on whether the library is working correctly may then be
done by executing
uses newzfloatarray
vars a = newzfloatarray([1 10 11 20], nonop +:);
Asumof(0, a, [3 8 12 19], [2 3]) =>
which should print
** 45.0_+:135.0
A further test for whether you have the latest version of linux poplog
which fixes a bug connected with external procedures that return single
floats:
uses newsfloatarray
vars a = newsfloatarray([1 10 11 20], nonop +);
Asumof(0, a, [3 8 12 19], [2 3]) =>
** 180.0
If you get the result 0.0 instead of 180.0 then you probably do not have
the latest version of poplog with the bug fixed, built on 6 Jan 2005.
1.3 Procedure names
--------------------
_______ARRPACK procedure names start with upper-case A, AM or AI, followed by
the name of the operation they perform in lower case, for example Aplus.
This is intended to make them distinctive enough to avoid name clashes,
whilst not involving lengthy prefixes.
1.4 Array storage types
------------------------
The arrays processed must be of a "packed" type which can be accessed by
external functions. The package recognises six types, given in the
following table. The letter in the first column identifies the types in
the documentation below.
ARRPACK Pop-11 type C type Popvision Other
ID construction construction
procedure procedures
------- ----------- ------ ------------ ------------
b (byte) unsigned *newbytearray *newsarray
char
i integer int *newintarray *array_of_int
*array_of_integer
s decimal float *newsfloatarray *array_of_float
*array_of_real
*newfloatarray
d ddecimal double *newdfloatarray *array_of_double
*newfloatarray
c (complex Complex *newcfloatarray
decimal) float
z (complex Complex *newzfloatarray
ddecimal) double
(The Pop-11 "types" in brackets are not true Pop-11 primitive data
types, but arrays can be constructed that behave much as if they were.)
It is also possible to create arrays of these types using *defclass and
*newanyarray, but it is likely to be simpler to use the existing
routines. The *_________POPVISION set are the most coherent. The other routines
mentioned above may be found by reference to HELP *________EXTERNAL/Arrays.
These array types can be divided into classes in different ways:
integral: b i
single-precision floating point: s c
double-precision floating point: d z
or
real: b i s d
complex: c z
Any given procedure may accept some or all array types as arguments,
depending on the operation being carried out. Details are given in the
procedure descriptions below.
1.5 Other array argument considerations
----------------------------------------
Apart from the storage type, array arguments are not restricted. In
particular:
* they may be stored "by row" or "by column" (i.e. with
*poparray_by_row or ), and arrays stored with
different orderings may even be mixed in the same call;
* they may have any number of dimensions;
* they may be offset in their arrayvectors.
All the array arguments in a single call must be of the same type, with
the following exceptions:
* the copying procedures Acop, AMcop and AIcop will copy from any
real type to any type, and from any complex type to any complex
type;
* the real-to-complex and complex-to-real conversion procedures take
different types as appropriate;
* all mask arrays, all index arrays (see below) and the results
of a "find" operation are of type i;
* the results of relational operations (e.g. Aeq) are of type i.
Where a procedure accepts scalar arguments (i.e. real or complex
numbers) as well as arrays, the array types are restricted as follows:
* if a scalar argument's value is not equal to an integer, the
arrays must be real or complex floating point;
* if a scalar argument is complex, the arrays must be complex.
Arrays are never created by _______ARRPACK procedures, but must be supplied for
both input and output. In many cases, the same array is used for both
input and output, with the results overwriting the original data. This
is because in many programs the original data are no longer required,
and this strategy allows you to avoid creating new arrays more often
than is necessary. If the original data are to be preserved, they can
be copied first.
1.6 Repeated use of arrays
---------------------------
The same array may be used for any number of input arguments to a
procedure. If however the argument is used for output, then the same
array must not be used for another argument, unless the two active sets
(see below) have no elements in common.
If the same array is passed as more than one argument, one of which is
an output or input/output argument, and the active sets (see below) have
elements in common, the results of the computation are undefined. No
error message is given. This also applies to two arrays sharing an
arrayvector; the sets of elements processed, allowing for any offsets in
the arrayvector, must be disjoint.
A single array may be used as an index array for different arguments in
the same call.
-----------------------------------------------------------------------
2 Active sets
-----------------------------------------------------------------------
2.1 General
------------
A call to an _______ARRPACK procedure may process all the points in an array,
or a subset of them. There are different ways to specify such a subset,
which is here referred to as the ______active ___set of the array.
* A set of elements lying on a rectangular grid within a rectangular
region (or the equivalent in N dimensions) may be selected using
the Axxx procedures.
* A set of elements specified by the non-zero elements of a ____mask
_____array may be selected using the AMxxx procedures.
* The two methods above may be combined: a region and grid may be
specified together with a mask using the AMxxx procedures.
* The indices of an arbitrary set of elements may be specified using
the AIxxx procedures.
2.2 Whole array
----------------
An Axxx procedure should be used to process the whole array. Each array
argument should be followed by two further arguments, which should be []
(the empty list) and 1 (the empty list), e.g.
Acos(arr, [], 1); ;;; find the cosine of every element of arr
2.3 Regular grids in rectangular regions
-----------------------------------------
An Axxx procedure may be used to process a "rectangular" region of an
array, possibly sampled on a grid with spacing greater than unity. (A
"rectangular" region is one formed by putting separate limits on the
range of each index, and in the 2-D case it can be pictured as a
rectangle.) The two arguments following the array specify the region and
grid spacing.
The argument following the array defines the ______active ______region. If it is not
the empty list (meaning the whole array), it must be a list the same
length as the *boundslist of the array - i.e. with 2 elements for each
dimension. It specifies a subregion of the array in the same way as a
boundslist specifies the bounds of the whole array. That is, for each
dimension a pair of list elements gives the minimum and maximum indices
on that dimension.
For example, for this code:
uses newsfloatarray
vars arr = newsfloatarray([1 4 1 9]);
Acos(arr, [2 4 2 7], 1);
the active set looks like this:
- - - - - - - - -
- * * * * * * - -
- * * * * * * - -
- * * * * * * - -
vars x,y;
pr(newline);
for x from 1 to 4 do
pr(newline);
for y from 1 to 9 do prnum(arr(x,y), 3, 2) endfor
endfor;
Here the array is shown with the first index giving the row and the
second index giving the column. Dashes show indicate unprocessed
elements of the array, and asterisks show processed elements. The active
set covers rows 2 to 4 and columns 2 to 7.
This is a two-dimensional example, but the same mechanism applies to
arrays with any number of dimensions. Also, there is no need for array
indices to start from 1 - this is done here just to make the example
easier to read.
The second argument following the array is the ________sampling ________interval. This
allows the active region to be sampled on a regular grid. For example,
for the call
Acos(arr, [2 4 2 7], 2);
the active set looks like this:
- - - - - - - - -
- * - * - * - - -
- - - - - - - - -
- * - * - * - - -
with alternate rows and columns processed.
The element with the lowest indices in the active region is always
processed - in this case it's ___arr(2, 2). If the sampling interval is _s,
then every _s'th element after that on each dimension is processed.
The sampling interval may be different on different dimensions. This is
done by giving a list equal in length to the number of dimensions,
containing the sampling intervals in order. For example
Acos(arr, [2 4 2 7], [1 3]);
processes every row and every third column, giving this set:
- - - - - - - - -
- * - - * - - - -
- * - - * - - - -
- * - - * - - - -
All the elements of the active set must lie within the array. This is
not quite the same as saying that the active region must lie within the
array. For example, the following is a correct call, given that ___arr's
boundslist is [1 4 1 9]:
Acos(arr, [2 4 2 10], [1 3]);
Although the active region includes column 10, whilst the array only
goes up to column 9, the sampling interval means that no elements in
column 10 are actually processed, so there is no problem. (This
simplifies one common kind of program construction in which the active
region is computed from the number of elements to process and the
sampling interval.)
The case of the empty list for the active region (which defaults to the
boundslist), and unity for the sampling interval, is handled specially.
If the whole array is to be processed it is slightly more efficient to
give the arguments in this form rather than giving the boundslist or a
list of ones explicitly.
2.4 Consistency between arguments with region/grid active sets
---------------------------------------------------------------
When more than one array is processed by an Axxx or AMxxx procedure,
then, with the exception of Areshape, the arrays must all have the same
number of dimensions, and the active sets must be consistent with one
another.
Two active sets are consistent if they have the same number of
processable elements on each dimension. For 2-D examples shown as above,
this means that if the dashes are omitted, the remaining blocks of
asterisks must be the same for each of the arrays in question.
For example, the following code is correct
vars arr1 = newsfloatarray([1 4 1 9], 1);
vars arr2 = newsfloatarray([-10 -8 11 17]);
Aplus(arr1, [2 4 3 9], [2 3], arr2, [-9 -8 14 16], [1 1]);
because the active sets look like this for arr1:
- - - - - - - - -
- - * - - * - - *
- - - - - - - - -
- - * - - * - - *
and like this for arr2:
- - - - - - -
- - - * * * -
- - - * * * -
so they are both 2 rows and 3 columns.
vars x,y;
pr(newline);
for x from -10 to -8 do
pr(newline);
for y from 11 to 17 do prnum(arr2(x,y), 3, 2) endfor
endfor;
Elements in the active sets map onto one another in the obvious way. In
the 2-D case, one can picture the two blocks of asterisks, with the
dashes removed, superimposed. Elements that overlie one another then
correspond. To be precise, in 1-D, ____arr1(__i1) and ____arr2(__i2) will be
processed together if they are each in their active sets and
(__i1 - __r1) / __s1 = (__i2 - __r2) / __s2
where __r1 and __r2 are the lowest indices in the respective active regions,
and __s1 and __s2 are the respective sampling intervals.
This generalises to any number of dimensions: the equation above applies
on each dimension separately.
2.5 Mask selection
-------------------
Every basic Axxx procedure in _______ARRPACK has a corresponding "masked" AMxxx
procedure (except for Areshape). The masked procedures allow the
processing to be restricted further, to arbitrary sets of elements, by
giving a "mask array" and its active set as extra arguments.
A mask array is always of type i (see above). Its active set is defined
as a regular grid using the two arguments that follow it, and the
correspondence between its elements and those of other array arguments
is as described above.
If an element of a mask's active set is zero, the corresponding elements
of other arrays will not be accessed or updated. If a mask element is
non-zero, then the operation required is carried out on the
corresponding elements of the other arrays.
For example, here is a mask for restricting attention to elements on the
main diagonal of a 4x4 2-D region:
uses newintarray;
vars mask = newintarray([1 4 1 4],
procedure(i,j); if i == j then 1 else 0 endif endprocedure);
If we now process ___arr (which has boundslist [1 4 1 9]) thus:
AMcos(mask,[],1, arr,[1 4 3 6],1);
the elements processed are these:
- - * - - - - - -
- - - * - - - - -
- - - - * - - - -
- - - - - * - - -
As in this example, mask and array active sets must be consistent. Mask
elements correspond to other array elements in the normal way, so that
in this case the main diagonal of ___arr's active set gets processed.
vars x,y;
pr(newline);
for x from 1 to 4 do
pr(newline);
for y from 1 to 9 do prnum(arr(x,y), 3, 3) endfor
endfor;
2.6 Indexed sets
-----------------
An alternative way of selecting an arbitrary set of elements is to
specify their indices explicitly. Each basic Axxx procedure except
Areshape, Aindex and Afind has a corresponding AIxxx procedure.
In this case the array arguments are preceded by an integer _N giving the
number of elements to process. Each array argument is followed by an
array containing the indices of the elements of its active set. This
_____index _____array must be of type i (see above), and must be two-dimensional.
Assume that the index array is stored "by column" (the default, with the
first index varying fastest and *poparray_by_row set ). Its
boundslist must be [1 ____Ndim 1 ___Len] where ____Ndim is the number of dimensions
of the preceding array. ___Len must be greater than or equal to _N. Each
of the first _N columns of the index array holds the indices of one
element of the active set of the array to be processed.
For example
vars ind = newintarray([1 2 1 3]);
creates a suitable index array for processing three elements of a 2-D
array. We can specify three elements thus:
(2,2), (3,1), (4,9) -> explode(ind);
and then in the call
AIcos(3, arr, ind);
the active set of ___arr (assuming ___arr has boundslist [1 4 1 9]) is:
- - - - - - - - -
- * - - - - - - -
* - - - - - - - -
- - - - - - - - *
vars x,y;
pr(newline);
for x from 1 to 4 do
pr(newline);
for y from 1 to 9 do prnum(arr(x,y), 3, 3) endfor
endfor;
The order in which elements are specified in the columns of the index
array has no effect.
If the index array is stored "by row" (i.e. *poparray_by_row )
then its boundslist must be [1 ___Len 1 ____Ndim] and each set of indices must
be stored in one row.
The AIxxx procedures do not check that all indices in an indexed array
are valid, to reduce computational overhead. Out of range indices may
cause mishaps or silent errors, depending on whether or not the
resulting code actually attempts to access elements outside the array.
2.7 Consistency between arguments with indexed active sets
-----------------------------------------------------------
When indexed access is used, there is no need for different array
arguments to have the same boundslists or even the same number of
dimensions, as long as each index array is consistent with the array it
refers to.
2.8 Efficiency of masked and indexed sets
------------------------------------------
In general, masks are more efficient than index arrays when a high
proportion of the elements in the underlying grid is to be processed.
Index arrays are more efficient, conversely, when the elements to be
processed are sparse.
If efficiency is crucial, the crossover should be determined by
experiment. However, the logic of the calling program will often dictate
the choice of representation.
2.9 Switching between masked, grid and indexed representations
---------------------------------------------------------------
An index array may be obtained from a mask using Afind, e.g.
vars N;
Afind(ind, mask, [], 1) -> N;
N=>
** 4
The value of _N (the number of non-zero elements found) should then be
checked to see that it is no bigger than the length of ___ind.
A mask may be obtained from an index array using Azero followed by
AIinc, e.g.
Azero(mask, [], 1);
AIinc(N, mask, ind);
where N is the number of columns of ___ind to use, i.e. the number of
elements of ____mask to increment.
The procedures AIsetvals and AIgetvals, in conjunction with Areshape,
allow data to be moved between indexed active sets and any convenient
grid representation. There are no equivalent AMsetvals and AMgetvals
procedures because the order in which elements in a masked
representation are processed is undefined, and indeed subject to
optimisation. Afind (on the mask) and AIsetvals/AIgetvals (on the data
array) can be used in succession to handle this situation, though the
apparent need to do so may mean that the program logic should be
reconsidered.
-----------------------------------------------------------------------
3 Procedures
-----------------------------------------------------------------------
3.1 Conventions
----------------
Capital letters refer to array arguments. The corresponding lower-case
letters in procedure descriptions refer to a typical element of the
array. The arguments __ar and __as refer to the active region and sampling
interval for array _A, as described above.
A mask is always referred to as _M, and is always "input" and type i.
An index array is always referred to as __Ia, __Ib etc. and is always
"input" and type i. The number of elements to process in an indexed
procedure is always referred to as _N, an input integer.
Arrays marked as "input" are not altered (unless the same array is also
used for output). Arrays marked as "output" are updated and the original
data in their active sets are lost. Arrays marked as "input/output" are
also updated, their original data having first been used.
Each array argument has a list of acceptable types which refers to the
section on array types above. "Same type as _A" means that the type of
the array in question has to be the same as the type of _A in any given
call, not simply that the list of possible types is the same.
If the value of any scalar argument (_k etc.) is not equal to an integer,
the array arguments must be floating point (real or complex). If any of
the scalar arguments is complex, the array arguments must be complex
too.
The operation carried out on an typical element is shown as the
corresponding Pop-11 code after the argument descriptions.
3.2 Copying and type conversion
--------------------------------
Note that the routines in this section are atypical in allowing
different types for different arguments, allowing type conversion.
Acop(_A,__ar,__as, _B,__br,__bs)
AMcop(_M,__mr,__ms, _A,__ar,__as, _B,__br,__bs)
AIcop(_N, _A,__Ia, _B,__Ib)
_A: input, b,i,s,d,c,z
_B: output, b,i,s,d,c,z but if _A is complex, _B must be complex.
a -> b;
Copies each element, doing type conversion if necessary. If
converting from double precision to single precision, from float
to integer or byte, or from integer to byte, information may be
lost. Assignments from floats to integers truncate any
fractional part. Assignments to bytes are modulus 256.
Actori(_C,__cr,__cs, _A,__ar,__as, _B,__br,__bs)
AMctori(_M,__mr,__ms, _C,__cr,__cs, _A,__ar,__as, _B,__br,__bs)
AIctori(_N, _C,__Ic, _A,__Ia, _B,__Ib)
_C: input, c,z
_A: output, b,i,s,d
_B: output, same type as _A
realpart(c) -> a; imagpart(c) -> b;
Converts from complex to real, putting the real and imaginary
parts into separate arrays. Same possible loss of information as
with Acop.
Aritoc(_A,__ar,__as, _B,__br,__bs, _C,__cr,__cs)
AMritoc(_M,__mr,__ms, _A,__ar,__as, _B,__br,__bs, _C,__cr,__cs)
AIritoc(_N, _A,__Ia, _B,__Ib, _C,__Ic)
_A: input, b,i,s,d
_B: input, same type as _A
_C: output, c,z
a +: b -> c;
Combines two real arrays into the real and imaginary parts of a
complex array. Information may be lost if double precision reals
or integers are converted to single precision complex.
Areal(_C,__cr,__cs, _A,__ar,__as)
AMreal(_M,__mr,__ms, _C,__cr,__cs, _A,__ar,__as)
AIreal(_N, _C,__Ic, _A,__Ia)
_C: input, c,z
_A: output, b,i,s,d
realpart(c) -> a;
Same possible loss of information as with Acop.
Aimag(_C,__cr,__cs, _A,__ar,__as)
AMimag(_M,__mr,__ms, _C,__cr,__cs, _A,__ar,__as)
AIimag(_N, _C,__Ic, _A,__Ia)
_C: input, c,z
_A: output, b,i,s,d
imagpart(c) -> a;
Same possible loss of information as with Acop.
3.3 Reshaping
--------------
These routines are unique in that the active sets do not need to be
consistent, allowing data to be reorganised into different "shapes".
There are no masked versions. Areshape is for moving data between
different grids. AIsetvals/AIgetvals are for moving data between indexed
representations and grid representations. Reshaping from one indexed
representation to another is done with AIcop.
Areshape(_A,__ar,__as, _B,__br,__bs)
_A: input, b,i,s,d,c,z
_B: output, same type as _A
a -> b;
The active sets of _A and _B must contain the same total number of
elements as each other. Otherwise they are not restricted; _A and
_B may even have different numbers of dimensions. Values are
taken from _A in sequence, with the first index increasing
fastest, and are stored in _B in the same sequence, again with
the first index increasing fastest. This ordering is not
affected by the internal storage formats of _A and _B ("by row" or
"by column").
AIsetvals(_V, _N, _A,__Ia)
_V: input, b,i,s,d,c,z, 1-dimensional
_A: output, same type as _V, any number of dimensions
v -> a;
_V must have at least _N elements; the first _N are copied.
AIgetvals(_V, _N, _A,__Ia)
_V: output, b,i,s,d,c,z, 1-dimensional
_A: input, same type as _V, any number of dimensions
a -> v;
_V must have at least _N elements; the first _N are updated.
3.4 Finding locations of non-zero values
-----------------------------------------
Afind(_I, _A,__ar,__as) -> _N
AMfind(_I, _M,__mr,__ms, _A,__ar,__as) -> _N
_I: output, i, with bounds as for an index array
_A: input, b,i,s,d,c,z
_N: integer, the number of non-zero values in the active set
if a /= 0 then (x,y,...) -> icol endif;
In the pseudo-Pop11 example ____icol stands for an unused column of
_I and _x,_y,... stand for the Pop-11 indices of _a in _A. Thus the
indices of the non-zero elements of _A are stored in _I in the
same format as for an index array (see the section "Indexed
sets" above). _N always returns the number of non-zero elements
in the active set of _A. If _I has _P columns, then if _N < _P then
the columns from _N+1 to _P are not updated. If _N > _P then only _P
sets of indices are stored; to obtain the remainder the
procedure must be called again with an array with at least _N
columns. (In the above, _I was assumed to be stored by column;
replace "column" by "row" if _I is stored by row.)
3.5 Setting values
-------------------
Azero(_A,__ar,__as)
AMzero(_M,__mr,__ms, _A,__ar,__as)
AIzero(_N, _A,__Ia)
_A: output, b,i,s,d,c,z
0 -> a;
Ak(_k, _A,__ar,__as)
AMk(_k, _M,__mr,__ms, _A,__ar,__as)
AIk(_k, _N, _A,__Ia)
_k: number
_A: output, b,i,s,d,c,z
k -> a;
Aindex(_d, _A,__ar,__as)
AMindex(_d, _M,__mr,__ms, _A,__ar,__as)
_d: integer greater than 0 and less than or equal to the number
of dimensions of _A
_A: output, b,i,s,d,c,z
The d'th index of each element is assigned to that element. For
an N-dimensional array this may be represented as
id -> A(i1, i2, ... id, ...iN)
where id is the d'th index, and the indices run over the
elements of the active set. Note that the index is the actual
Pop-11 index of the array element, not, for example, an offset
into the active region.
Do not confuse these procedures with AIxxx procedures giving
indexed access to arrays for other operations.
3.6 Arithmetic operations on single arrays
-------------------------------------------
See also "mathematical functions" below. No strong distinction is
intended between the two terms; it is just convenient to split the list
of procedures up somehow.
Ainc(_A,__ar,__as)
AMinc(_M,__mr,__ms, _A,__ar,__as)
AIinc(_N, _A,__Ia)
_A: input/output, b,i,s,d,c,z
a+1 -> a;
Adec(_A,__ar,__as)
AMdec(_M,__mr,__ms, _A,__ar,__as)
AIdec(_N, _A,__Ia)
_A: input/output, b,i,s,d,c,z
a-1 -> a;
Aneg(_A,__ar,__as)
AMneg(_M,__mr,__ms, _A,__ar,__as)
AIneg(_N, _A,__Ia)
_A: input/output, b,i,s,d,c,z
-a -> a;
Aconj(_A,__ar,__as)
AMconj(_M,__mr,__ms, _A,__ar,__as)
AIconj(_N, _A,__Ia)
_A: input/output, c,z
conjugate(a) -> a;
Asqr(_A,__ar,__as)
AMsqr(_M,__mr,__ms, _A,__ar,__as)
AIsqr(_N, _A,__Ia)
_A: input/output, b,i,s,d,c,z
a*a -> a;
Aplusk(_k, _A,__ar,__as)
AMplusk(_k, _M,__mr,__ms, _A,__ar,__as)
AIplusk(_k, _N, _A,__Ia)
_k: number
_A: input/output, b,i,s,d,c,z
a + k -> a;
The following 15 procedures have the same details as Aplusk etc.
Aminusk, AMminusk, AIminusk
a - k -> a;
Akminus, AMkminus, AIkminus
k - a -> a;
Atimesk, AMtimesk, AItimesk
a * k -> a;
Adivk, AMdivk, AIdivk
a / k -> a;
Akdiv, AMkdiv, AIkdiv
k / a -> a;
Apowk(_k, _A,__ar,__as)
AMpowk(_k, _M,__mr,__ms, _A,__ar,__as)
AIpowk(_k, _N, _A,__Ia)
_k: number
_A: input/output, b,i,s,d
a ** k -> a;
The following 9 procedures have the same details as Apowk etc.
Amodk, AMmodk, AImodk
mod(a,k) -> a;
Amaxk, AMmaxk, AImaxk
max(a,k) -> a;
Amink, AMmink, AImink
min(a,k) -> a;
Alink(__k1, __k2, _A,__ar,__as)
AMlink(__k1, __k2, _M,__mr,__ms, _A,__ar,__as)
AIlink(__k1, __k2, _N, _A,__Ia)
__k1: number
__k2: number
_A: input/output, b,i,s,d,c,z
k1 * a + k2 -> a;
Aquadk(__k1, __k2, __k3, _A,__ar,__as)
AMquadk(__k1, __k2, __k3, _M,__mr,__ms, _A,__ar,__as)
AIquadk(__k1, __k2, __k3, _N, _A,__Ia)
__k1: number
__k2: number
__k3: number
_A: input/output, b,i,s,d,c,z
k1 * a**2 + k2 * a + k3 -> a;
3.7 Arithmetic operations on two arrays
----------------------------------------
Aplus(_A,__ar,__as, _B,__br,__bs)
AMplus(_M,__mr,__ms, _A,__ar,__as, _B,__br,__bs)
AIplus(_N, _A,__Ia, _B,__Ib)
_A: input, b,i,s,d,c,z
_B: input/output, same type as _A
a + b -> b;
The following 15 procedures have the same details as Aplus etc.
Aminus, AMminus, AIminus
a - b -> b;
Aminusrev, AMminusrev, AIminusrev
b - a -> b;
Atimes, AMtimes, AItimes
a * b -> b;
Adiv, AMdiv, AIdiv
a / b -> b;
Adivrev, AMdivrev, AIdivrev
b / a -> b;
Apow(_A,__ar,__as, _B,__br,__bs)
AMpow(_M,__mr,__ms, _A,__ar,__as, _B,__br,__bs)
AIpow(_N, _A,__Ia, _B,__Ib)
_A: input, b,i,s,d
_B: input/output, same type as _A
a ** b -> b;
The following 9 procedures have the same details as Apow etc.
Amod, AMmod, AImod
mod(a,b) -> b;
Amax, AMmax, AImax
max(a,b) -> b;
Amin, AMmin, AImin
min(a,b) -> b;
Asumsqr(_A,__ar,__as, _B,__br,__bs)
AMsumsqr(_M,__mr,__ms, _A,__ar,__as, _B,__br,__bs)
AIsumsqr(_N, _A,__Ia, _B,__Ib)
_A: input, s,d
_B: input/output, same type as _A
a**2 + b**2 -> b;
Alincomb(__k1, __k2, _A,__ar,__as, _B,__br,__bs)
AMlincomb(__k1, __k2, _M,__mr,__ms, _A,__ar,__as, _B,__br,__bs)
AIlincomb(__k1, __k2, _N, _A,__Ia, _B,__Ib)
__k1: number
__k2: number
_A: input, b,i,s,d,c,z
_B: input/output, same type as _A
k1 * a + k2 * b -> b;
3.8 Mathematical functions
---------------------------
Complex functions have mostly not yet been provided. They should be
added in due course.
Aabs(_A,__ar,__as)
AMabs(_M,__mr,__ms, _A,__ar,__as)
AIabs(_N, _A,__Ia)
_A: input/output, b,i,s,d
abs(a) -> a;
Alog(_A,__ar,__as)
AMlog(_M,__mr,__ms, _A,__ar,__as)
AIlog(_N, _A,__Ia)
_A: input/output, s,d
log(a) -> a;
The following 42 procedures have the same details as Alog etc. Where no
description is given, the functions are as indicated by the procedure
names. Trigonometric functions use radians, not degrees, regardless of
the setting of *popradians.
Aexp, AMexp, AIexp
Asin, AMsin, AIsin
Acos, AMcos, AIcos
Atan, AMtan, AItan
Aasin, AMasin, AIasin
Aacos, AMacos, AIacos
Aatan, AMatan, AIatan
Asinh, AMsinh, AIsinh
Acosh, AMcosh, AIcosh
Atanh, AMtanh, AItanh
Asqrt, AMsqrt, AIsqrt
Aceil, AMceil, AIceil
The smallest integral value not less than a.
Afloor, AMfloor, AIfloor
The largest integral value not greater than a.
Alogistic, AMlogistic, AIlogistic
1/(1 + exp(-a)) -> a;
Ahypot(_A,__ar,__as, _B,__br,__bs)
AMhypot(_M,__mr,__ms, _A,__ar,__as, _B,__br,__bs)
AIhypot(_N, _A,__Ia, _B,__Ib)
_A: input, s,d
_B: input/output, same type as _A
sqrt(a**2 + b**2) -> b;
Note that Asumsqr may often be used instead, and is much faster.
Aarctan2(_A,__ar,__as, _B,__br,__bs)
AMarctan2(_M,__mr,__ms, _A,__ar,__as, _B,__br,__bs)
AIarctan2(_N, _A,__Ia, _B,__Ib)
_A: input, s,d
_B: input/output, same type as _A
arctan2(a, b) -> b;
Note that this follows the Pop-11 convention for argument
ordering: that is, if the first argument is an x-coordinate and
the second a y-coordinate in the usual frame, then the result is
the angle of the point measured anticlockwise from the x-axis.
Acartopol(_A,__ar,__as, _B,__br,__bs)
AMcartopol(_M,__mr,__ms, _A,__ar,__as, _B,__br,__bs)
AIcartopol(_N, _A,__Ia, _B,__Ib)
_A: input/output, s,d
_B: input/output, same type as _A
sqrt(a**2 + b**2), arctan2(a, b) -> (a, b);
Cartesian to polar coordinate transform.
Apoltocar(_A,__ar,__as, _B,__br,__bs)
AMpoltocar(_M,__mr,__ms, _A,__ar,__as, _B,__br,__bs)
AIpoltocar(_N, _A,__Ia, _B,__Ib)
_A: input/output, s,d
_B: input/output, same type as _A
a * cos(b), a * sin(b) -> (a, b);
Polar to Cartesian coordinate transform.
3.9 Relational operations
--------------------------
Relational operations produce arrays of zeros and ones, which are stored
in integer arrays, for use as masks or in logical operations. For this
reason the output arrays are distinct from the input arrays for this
class of operations.
Akeq(_k, _A,__ar,__as, _C,__cr,__cs)
AMkeq(_k, _M,__mr,__ms, _A,__ar,__as, _C,__cr,__cs)
AIkeq(_k, _N, _A,__Ia, _C,__Ic)
k: number
_A: input, b,i,s,d,c,z
_C: output, i
if k = a then 1 else 0 endif -> c;
The following 15 procedures have the same details as Akeq etc.
Akne, AMkne, AIkne
if k /= a then 1 else 0 endif -> c;
Akgt, AMkgt, AIkgt
if k > a then 1 else 0 endif -> c;
Akge, AMkge, AIkge
if k >= a then 1 else 0 endif -> c;
Aklt, AMklt, AIklt
if k > a then 1 else 0 endif -> c;
Akle, AMkle, AIkle
if k <= a then 1 else 0 endif -> c;
Aeq(_A,__ar,__as, _B,__br,__bs, _C,__cr,__cs)
AMeq(_M,__mr,__ms, _A,__ar,__as, _B,__br,__bs, _C,__cr,__cs)
AIeq(_N, _A,__Ia, _B,__Ib, _C,__Ic)
_A: input, b,i,s,d,c,z
_B: input, same type as _A
_C: output, i
if a = b then 1 else 0 endif -> c;
The following 15 procedures have the same details as Aeq etc.
Ane, AMne, AIne
if a /= b then 1 else 0 endif -> c;
Agt, AMgt, AIgt
if a > b then 1 else 0 endif -> c;
Age, AMge, AIge
if a >= b then 1 else 0 endif -> c;
Alt, AMlt, AIlt
if a > b then 1 else 0 endif -> c;
Ale, AMle, AIle
if a <= b then 1 else 0 endif -> c;
3.10 Logical operations
------------------------
Logical operations use the common convention of zero for and
non-zero for . In Pop11, zero is non-, so the results of
these operations need to be tested against zero if they are to be
interpreted as logical values in Pop-11.
Anot(_A,__ar,__as)
AMnot(_M,__mr,__ms, _A,__ar,__as)
AInot(_N, _A,__Ia)
_A: input/output, i
if a = 0 then 1 else 0 endif -> a;
Aand(_A,__ar,__as, _B,__br,__bs)
AMand(_M,__mr,__ms, _A,__ar,__as, _B,__br,__bs)
AIand(N, _A,__Ia, _B,__Ib)
_A: input, i
_B: input/output, i
if a /= 0 and b /= 0 then 1 else 0 endif -> b;
Aor(_A,__ar,__as, _B,__br,__bs)
AMor(_M,__mr,__ms, _A,__ar,__as, _B,__br,__bs)
AIor(_N, _A,__Ia, _B,__Ib)
_A: input, i
_B: input/output, i
if a /= 0 or b /= 0 then 1 else 0 endif -> b;
Axor(_A,__ar,__as, _B,__br,__bs)
AMxor(_M,__mr,__ms, _A,__ar,__as, _B,__br,__bs)
AIxor(_N, _A,__Ia, _B,__Ib)
_A: input, i
_B: input/output, i
if (a = 0) /== (b = 0) then 1 else 0 endif -> b;
3.11 Scalar functions of arrays
--------------------------------
Asumof(_k, _A,__ar,__as) -> _s
AMsumof(_k, _M,__mr,__ms, _A,__ar,__as) -> _s
AIsumof(_k, _N, _A,__Ia) -> _s
_k: number
_A: input, b,i,s,d,c,z
_s: number returned
Returns the sum of _k and the values of the elements in the
active region of _A, masked in the second case.
Aminof(_k, _A,__ar,__as) -> _s
AMminof(_k, _M,__mr,__ms, _A,__ar,__as) -> _s
AIminof(_k, _N, _A,__Ia) -> _s
_k: number
_A: input, b,i,s,d
_s: number returned
Returns the minimum of _k and the minimum value of the elements
in the active region of _A, masked in the second case. To find
the minimum of the elements in the active region of _A, set _k to
the value of one of the elements. (It is a very bad idea to set
it to some arbitrary large value.)
Amaxof(_k, _A,__ar,__as) -> _s
AMmaxof(_k, _M,__mr,__ms, _A,__ar,__as) -> _s
AImaxof(_k, _N, _A,__Ia) -> _s
_k: number
_A: input, b,i,s,d
_s: number returned
Returns the maximum of _k and the maximum value of the elements
in the active region of _A, masked in the second case. To find
the maximum of the elements in the active region of _A, set _k to
the value of one of the elements. (It is a very bad idea to set
it to some arbitrary small or negative value.)
Aminmaxof(__k1, __k2, _A,__ar,__as) -> (__s1, __s2)
AMminmaxof(__k1, __k2, _M,__mr,__ms, _A,__ar,__as) -> (__s1, __s2)
AIminmaxof(__k1, __k2, _N, _A,__Ia) -> (__s1, __s2)
__k1: number
__k2: number
_A: input, b,i,s,d
__s1: number returned
__s2: number returned
Returns the minimum of __k1 and the minimum value of the elements
in the active region of _A as __s1, and the maximum of __k2 and the
maximum value of the elements in the active region of _A as __s2,
masked in the second case. To find the min and max of the
elements in the active region of _A, set _k to the value of one of
the elements. (It is a very bad idea to set it to some arbitrary
value.)
3.12 Miscellaneous
-------------------
Aspecv(_A,__ar,__as, _i,_____cdopt,______ordopt) -> _____specv
_A: input, any type including Pop-11 full vectors
_i: non-negative integer
_____cdopt: boolean
______ordopt: boolean
Returns a "specification vector" for the active set of the
array, as used internally by the external procedures. This is
for debugging and for possible use by related libraries. The
format of the vector and the meanings of _____cdopt and ______ordopt are
documented in LIB * _________ARRSCAN.C. If _i is 0 a new vector is created
and returned; otherwise _i must be a small positive integer in
which case a vector from a pool is returned and its contents may
be changed by other calls to _______ARPPACK procedures.
Aindv(_A, _i) -> ind_v
_A: input, any type including Pop-11 full vectors
_i: non-negative integer
Returns an "indexing vector" for the array, as used internally
by the external procedures. Other comments, and the meaning of
_i, are as for Aspecv.
--- _______________________$popvision/help/arrpack
--- _________Copyright __________University __of ______Sussex _____2004. ___All ______rights _________reserved.