Subject: SF[887639] listarray when use_fast_arrays : true
From: Dieter Kaiser
Date: Sat, 17 Jan 2009 17:38:08 +0100
There are two problems when switching fast arrays on.
First:
With use_fast_arrays:TRUE the output for an array with one dimension is wrong. I
have already suggested the following correction to the function $listarray in
marray.lisp:
((hash-table-p ary)
(let (vals (tab ary))
(declare (special vals tab))
(maphash #'(lambda (x &rest l) l
(unless (eq x 'dim1) (push (gethash x tab) vals)))
ary)
(reverse vals)))
The code skips over the element (dim1 t) which is stored in the hash-table by
the Lisp function make-equal-hash-table. Additionaly the code reorders the list
of elements so that we get the expected order of elements.
I would like to check in the changes if no one sees a problem with the code.
Second:
A Maxima list or matrix can be accessed like an array. With use_fast_arrays:TRUE
Maxima no longer checks the type or the range of the indices. Depending on the
Lisp we get Lisp Errors or the memory is damaged (GCL). This is reported in a
post of this bug report and on this mailing list.
I would like to suggest to implement a complete type and range check when the
code of use_fast_arrays access a Maxima list or matrix. This has to be added to
the function arrstore in the file mlisp.lisp:
((eq the-type 'list)
(cond ((eq (caar tem) 'mlist)
(unless (= (length index) 1)
(merror "Wrong number of indices: ~M"
(cons '(mlist) index)))
(setq index (car index))
(cond
((not (eq (ml-typep index) 'fixnum))
(merror "Index not an integer: ~M" index))
((and (> index 0) (< index (length tem)))
(setf (nth index tem) r)
r)
(t
(merror "Index out of range: ~A" index))))
((eq (caar tem) '$matrix)
(cond
((not (= (length index) 2))
(merror "Wrong number of indices: ~M"
(cons '(mlist) index)))
((or (not (eq (ml-typep (first index)) 'fixnum))
(not (eq (ml-typep (second index)) 'fixnum)))
(merror "Indices not an integer: ~M"
(cons '(mlist) index)))
((and (> (first index) 0)
(< (first index) (length (cadr tem)))
(> (second index) 0)
(< (second index) (length (caddr tem))))
(setf (nth (second index) (nth (first index) tem)) r)
r)
(t
(merror "Indices out of range: ~M"
(cons '(mlist) index)))))
With this code we no longer get Lisp Errors when accessing an element of a
Maxima list or matrix with wrong range or type and use_fast_arrays:TRUE.
Remark:
With use_fast_arrays:FALSE the check of the type and the range of the indices is
completely done by Maxima.
Because a Maxima list or a Maxima matrix is not a fast array it seems to be even
better to have no code duplication and to implement the access via the existing
code. But to do this the algorithm of arrstore has to be changed (rewritten).
I would like to check in the complete type and range checking for the case
use_fast_arrays:TRUE if no one sees a problem with the change?
The testsuite and share_testsuite have no problems.
Dieter Kaiser