All,
1. I frequently have a need to extract a SUB-ARRAY from an ARRAY.
In Matlab parlance I would have written something like
A(:,1:4:30,:) for a RANK 3 array.
2. The code, SUB-ARRAY, works but is woefully slow.
a. My attempts at various DECLARE options resulted in no change.
b. My attempts at re-writting the SUB-ARRAY selection code only
make things worse by a factor of 5 or more.
3. If anyone has some pointers as to what I might try, I'd sure appreciate
it. The details are below.
tnx in advance
mike
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; The basic function is below. My test case is an
;; (ARRAY (COMPLEX SINGLE-FLOAT) (201 360 18))
;; (SUB-ARRAY ARRAY :ALL (ISEQ 0 10 359) :ALL) results in
;;
;; Consed | Calls | Secs | Sec/Call | Bytes/C. | Name:
;; -----------------------------------------------------------------------
;; 1,042,152 | 1 | 50.650 | 50.65000 | 1,042,152 | SUB-ARRAY
;; 5,209,984 | 130,248 | 0.810 | 0.00001 | 40 | AREF
;; 5,338,584 | 1 | 0.040 | 0.04000 | 5,338,584 | CARTESIAN-PRODUCT
;; 80 | 1 | 0.000 | 0.00000 | 80 |
TRANSLATE-INDEX-SPECS
;; 1,752 | 2 | 0.000 | 0.00000 | 876 | ISEQ
;; -------------------------------------------------------------------
;; 11,592,552 | 130,253 | 51.500 | | | Total
(defun sub-array (array &rest index-specs)
"
SYNTAX
======
(SUB-ARRAY ARRAY INDEX0-SPEC INDEX1-SPEC ... )
INPUT
-----
ARRAY An ARRAY of rank N
INDEX-SPEC There must be one INDEX-SPEC for each dimension of ARRAY
One of the following:
(ISEQ START STEP STOP)
:ALL Expands to (ISEQ 0 1 (ARRAY-DIMENSION ARRAY I))
:EVEN Expands to (ISEQ 0 2 (ARRAY-DIMENSION ARRAY I))
:ODD Expands to (ISEQ 1 2 (ARRAY-DIMENSION ARRAY I))
OUTPUT
------
ARRY A new array made up of the specified entries of ARRAY."
;; Idiot check
(unless (= (array-rank array) (length index-specs))
(error "Insufficient INDEX-SPECIFICATION for given ARRAY."))
(multiple-value-bind (array-indexes array-dims)
(apply #'translate-index-specs array index-specs)
(let* (
(new-array (make-array array-dims
:element-type (array-element-type array)))
;; and create a displaced array
(new-array-displaced (make-array (array-total-size new-array)
:element-type (array-element-type array)
:displaced-to new-array)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; now populate and return the new-array
;; I FEEL THAT THE PROBLEM HAS TO BE RIGHT HERE
;; I've tried eliminating the APPLY and using
;; ROW-MAJOR-AREF on an array displaced to ARRAY...but no help
(dotimes (n (array-total-size new-array) new-array)
(setf (aref new-array-displaced n)
(apply #'aref array (nth n array-indexes)))))))