Data Types
21 RETURN-NIL FOO
; I
The performance advantage of array registers over the simplest types of array (for example, no leader or no displacement) is fairly small, since the normal aref and
August 1986 Data Types
for one peculiar case: an indirect byte array with an index offset that is not a multiple of the number of array elements per word; in other words, an array whose first element is not aligned on a word boundary. An example of this case is:
(setq a (make-array 1ee :element-type 'string-char»
(setq b (make-array 99 :element-type 'string-char :displaced-to a
:displaced-index-offset 1»
If the :displaced-index-offset had been a multiple of 4, array registers would enhance performance.
9.10.2 Hints for Using Array Registers
The expansion of the loop macro's array-elements path copies the array into a temporary variable. In order to get the benefits of array registers, you must write code in the following way:
Right:
(defun tst1 (array incr)
(declare (sys:array-register a»
(loop for elt being the array-elements of array using (sequence a)
sum (* elt incr») Wrong:
(de fun tst (array incr)
(let «a array» (declare (sys:array-register a»
(loop for elt being the array-elements of a sum (* elt incr»»
loop generates a temporary variable; the "using" clause forces the temporary variable to be named a. Since the user gets to control the name of the variable, it is possible to assign a declaration to the variable.
The other way to do it is to avoid the array-elements path, and instead use:
(defun tst (array incr)
(let «a array» (declare (sys:array-register a»
(loop for i from e below (array-total-size a) sum (* (aref a i) incr»»
This is a bit more efficient because it does not have the overhead of setting up the variable elt.
Symbolics Common Lisp: Language Concepts August 1986
9.10.3 Array Register Restrictions
It is not valid to declare a variable simultaneously to be special and to be sys:array-register. You cannot declare a parameter (a variable that appears in the argument-list of a defun or a lambda) to be an array register; you must bind another variable (perhaps with the same name) to it with let and declare that variable. For example:
(defun tst (x y) (let «x x) (y y»
(declare (sys:array-register X y»
... »)
An array-register variable cannot be a free lexical variable; it must be bound in the same function that uses it.
Note that the array-register declaration is in the system package (also known as sys) , and therefore the declaratibn is sys:array-register or sys:array-register-ld.
Be sure to type sys:array-register and not just array-register to gain compile-time advantages such as checking for misspelled declarations. Also, if you type array-register, the code generated by the compiler runs slower. Note that if you type sys:array-registar instead of the correct spelling, the package system catches the misspelling because the system package is locked.
If the array decoded into an array register is altered (for example, with
adjust-array) after the array register is created, the next reference through the array register re-decodes the array.
9.11 Matrices and Systems of Linear Equations
Matrices are represented as two-dimensional Lisp arrays. These functions that operate on matrices are part of the mathematics package rather than the kernel array system, hence the "math:" in the names.
math:decompose and math:solve are used to solve sets of simultaneous linear equations. math:decompose takes a matrix holding the coefficients of the equations and produces the LU decomposition; this decomposition can then be passed to mafh:solve along with a vector of right-hand sides to get the values of the variables. If you want to solve the same equations for many different sets of right-hand side values, you only need to call math:decompose once. In terms of their argument names, these two functions exist to solve the vector equation A x
=
b for x. A is a matrix. b and x are vectors.
August 1986
9.11.1 Operations on Matrices
The following functions perform some useful matrix operations:
math:decompose Computes the LU decomposition of a matrix.
math: determinant
Returns the determinant of a matrix.
math:fill-2d-array
Stores values into elements into an array.
math:invert-matrix
Computes the inverse of a matrix.
math:1ist-2d-array
Returns a list of lists contains the values in an array.
math:multiply-matrices
Multiplies one matrix by another matrix.
math:solve Solves a set of simultaneous equations.
math:transpose-matrix
Transposes a matrix.
9.11.2 Common Operations on Arrays
Several summary tables of array operations appear elsewhere in the documentation. These include:
See the section "Basic Array Functions", page 158.
See the section "Operations on Array Leaders", page 165.
See the section "Operations on Planes", page 172.
See the section "Operations on Rasters", page 171.
See the section "Operations on Vectors", page 170.
See the section "Operations on Matrices", page 177.
9.11.2.1 Getting Information About an Array
Data Types
The following functions can be used to get information about arrays:
array-dimension Returns the length of the specified dimension of an array.
array-dimensions Returns a list whose elements are the dimensions of the array.
array-has-Ieader-p
Returns t if the given array has a leader; otherwise it returns nil.
Symbolics Common Lisp: Language Concepts August 1986
array-in-bounds-p
Tests whether a subscript is valid for the array.
array-leader-length
Returns the length of an array's leader.
length Returns the number of elements in a vector (or list). For vectors with a fill pointer, the active length as specified by the fill pointer is returned.
array-rank Returns the number of dimensions of an array.
array-row-major-index
Returns an integer that identifies the accessed element.
array-total-size Returns the number of elements in an array.
array-element-type
Returns the type of the elements of an array.
adjustable-array-p
Returns t if the array is adjustable.
sys:array-row-span
Returns the number of array elements spanned by one of its rows.
zl:array-active-Iength
Returns the active number of elements in an array; length provides the same functionality.
zl:array-dimension-n
Returns the size for the specified dimension of the array.
sys:array-displaced-p
Tests whether the array is a displaced array.
array-has-Ieader-p
Tests whether the array has a leader.
sys:array-indexed-p
Tests whether an array is an indirect array with an index-offset.
sys:array-indirect-p
Tests whether an array is indirect.
zl:array-Iength Returns the number of elements in an array.
zl:array-#-dims Returns the dimensionality of an array; array-rank provides the same functionality.
179
August 1986 Data Types
9.11.2.2 Changing the Size of an Array
The following functions can be used to modify the size of an existing array:
Performs logical and operations on the specified arrays.
Performs logical inclusive or operations on the specified arrays.
Performs logical exclusive or operations on the specified arrays.
Performs logical exclusive nor operations on the specifIed elements.
Performs logical not and operations on the specified elements.
Performs logical not or operations on the specified elements.
Takes an array as an argument and returns a copy of the array with all the bits inverted.
Performs logical and operations on the complement of argumentl with argument2.
Performs logical and operations on argumentl with the complement of argument2.
Performs logical or operations on the complement of argumentl
with argument2. ~
Performs logical or operations on the complement o( argument2 with argumentl.
Tests whether the given object is a one-dimensional array of bits.
SymboJics Common Lisp: Language Concepts August 1986
9.11.2.4 Adding to the End of an Array
The following functions can be used to add to the end of an array:
vector-pop vector-push
Decreases the fill pointer by one and. returns the vector element designated by the new value of the fill pointer.
Stores a new element in the element designated by the fill pointer and increments the fill pointer by one.
vector-push-extend
Like vector-push, but expands the vector if it is not large enough, and if the vector is adjustable.
vector-push-portion-extend zl:array-pop
zl:array-push
Copies a portion of one array to the end of another.
Decreases the fill pointer by one.
Store an object in a specified element of an array and increases the fill pointer by one.
zl:array-push-extend
Stores an object in a specified element of an array, growing the array if necessary.
zl:array-push-portion-extend
Copies a portion of one array to the end of another.
9.11.2.5 Copying an Array
The following functions can be used to copy the contents of arrays:
2d-array-blt bitblt
Copies a rectangular portion of one array into a portion of another array; intended for two dimensional arrays.
Copies a rectangular portion of one raster into a rectangular portion of another raster.
copy-array-contents-and-Ieader
Copies the contents and leader of one array into the contents of another array.
copy-array-contents
Copies the contents of one array into the contents of another array.
copy-array-portion
Copies a portion of the contents of one array into the contents of another array.
August 1986 Data Types
list-array-Ieader Creates and returns a list whose elements are those of the leader of the specified array.
replace zl:fillarray zl:listarray
Copies contents of one vector (or list) into another.
Fills up an array with the elements of a list.
Creates and returns a list of the elements of the specified array.
9.11.2.6 Accessing Multidimensional Arrays as One-dimensional
The sys:array-register-ld declaration is used together with the following functions to access multidimensional arrays as if they were one-dimensional. See the section
"Function-body Declarations" in Symbolics Common Lisp: Language Dictionary.
This declaration allows loop optimization of multidimensional array subscript calculations. The user must do the reduction from multiple subscripts to a single subscript.
For an example: See the function sys:%ld-aref in Symbolics Common Lisp:
Language Dictionary.
sys:%ld-aref sys:%ld-aset sys:%ld-aloc
Returns the specified array element; like aref except that it acts as if the array were one-dimensional.
Stores a value into the specified array element; like zl:aset except that it acts as if the array were one-dimensional.
Returns a locative pointer to the array element-cell selected by the index; like zl:aloc except that it acts as if the array were one-dimensional.
sys:array-row-span
Returns the number of array elements spanned by one of its rows.
9.11.2.7 Array Representation Tools
The following functions and variables are primitives.
sys:*array-type-codes·
A variable that is a list of all the array type symbols.
sys:array-bits-per-element
An association list that associates array type symbols with size.
sys:array-bits-per-element
A function that returns the number of bits per cell for unsigned numeric arrays.
Symbolics Common Lisp: Language Concepts August 1986
sys:array-element-size
A function that returns the number of bits that fit into an element of the specified array.
sys:array-elements-per-q
An association list that associates each array type symbol with the number of array elements stored in one word.
sys:array-elements-per-q
A function that returns the number of array elements stored in one word.
sys:array-types A function that returns the symbolic name of the array type.
9.11.2.8 Other Array Functions
sys:return-array Attempts to return an array to free storage. This is a subtle and dangerous feature.
9.11.3 Row-major Storage of Arrays
This section describes how arrays are stored in memory. This is an
implementation detail that does not concern most programmers. However, if you use some of the advanced array practices, such as displaced arrays or adjusting the array size dynamically, you need to understand how arrays are stored in memory.
Genera stores multi-dimensional arrays in row-major order. The following 2 by 3
two-dimensional array illustrates row-major order. Two-dimensional arrays have rows and columns. The number of rows is the span of the first dimension and the number of columns is the span of the second dimension. When accessing a two-dimensional array, the row is the rIrst subscript and the column is the second subscript.
Column
0 1 2
Row
0 0,0 0,1 0,2
1 1,0 1,1 1,2
In row-major order, the array elements are arranged in memory in the following order:
August 1986 Data Types
(0 J0) (0 J 1) (0 J2) (1 J0) (1 J 1) (1 J2)
In other words, the sequence is determined by going across the row from column to column. Thus, the first, or row, index remains constant while the second, or column, index changes as you follow the linear sequence in memory.
9.11.4 Performance and Arrays
In Genera 7.0, arrays are stored in row-major order rather than column-major order, which was used in Release 6.1 and all previous releases. The change from column-major to row-major order affects paging performance when large arrays are used. To reference every element in a multidimensional array and move linearly through memory to improve locality of reference in Genera 7.0, you must vary the last subscript fastest. In 6.1 and earlier releases, vary the first sUbscript fastest.
Certain programs might run faster or slower due to the interaction of
multidimensional array storage and paging. For example, a Release 6 database might be organized as 4 by n. The 4 items associated with the ith object are at consecutive array locations and are therefore likely on the same page. This is because of Release 6's column-major order. In Genera 7.0, the elements (O,i), (l,i), (2,i) and (3,i) are not consecutive and can be on different pages. It might be desirable to change all aspects of the database to be n by 4 so that (i,O), (i,l), (i,2), and (i,3) are consecutive. A useful technique for hiding some of this is to define substs that take care of the 0,1,2,3 values.
For example, in a column-major system you might have the following:
(defsubst item-name (table index) (aref table 0 index»
(defsubst item-color (table index) (aref table 1 index»
In a row-major system you can have the same names and contracts with different implementations:
(defsubst item-name (table index) (aref table index 0»
(defsubst item-color (table index) (aref table index 1»
9.11.5 Compatibility Operations for Arrays 9.11.5.1 Zetallsp Array Types
This section describes the Zetalisp array types. Zetalisp array types are known by a set of symbols whose names begin with "art-" (for ARray Type). For example, a general array is called a Zetalisp sys:art-q array. Zetalisp has many -types of specialized arrays, such as sys:art-ilXllum and sys:art-boolean. This terminology is being phased out in favor of Common Lisp terminology.