From a765b25c5fa48f05c5fda9cfa61ce4a5f2edba7a Mon Sep 17 00:00:00 2001 From: AJ Rossini Date: Sat, 27 Oct 2007 23:07:22 +0200 Subject: [PATCH] remove sequence and combine into compound completely. --- compound.lsp | 378 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- data.lisp | 3 +- ladata.lsp | 1 - linalg.lsp | 1 - lispstat.asd | 24 ++-- lsbasics.lsp | 103 ---------------- matrices.lsp | 3 +- nonlin.lsp | 1 - optimize.lisp | 1 - regression.lsp | 1 - sequence.lsp | 270 ----------------------------------------- statistics.lsp | 1 - 12 files changed, 379 insertions(+), 408 deletions(-) delete mode 100644 sequence.lsp diff --git a/compound.lsp b/compound.lsp index 34afc98..512e398 100644 --- a/compound.lsp +++ b/compound.lsp @@ -18,12 +18,12 @@ (defpackage :lisp-stat-compound-data (:use :common-lisp :lisp-stat-object-system - :lisp-stat-sequence) + :lisp-stat-types) (:import-from :lisp-stat-fastmap fastmap) (:shadowing-import-from :lisp-stat-object-system slot-value call-next-method call-method) - (:export compound-data-p compound-data-proto + (:export compound-data-p *compound-data-proto* compound-object-p compound-data-seq compound-data-length @@ -35,6 +35,18 @@ repeat ;; export matrix-related functionality (not sure??) + + check-sequence + get-next-element make-next-element set-next-element + sequencep iseq + + ;; maybe? + ordered-nneg-seq + select + + which + ;; vector differences + difference rseq )) (in-package :lisp-stat-compound-data) @@ -217,14 +229,14 @@ Returns sequence of the elements of compound item X." ;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defproto compound-data-proto) +(defproto *compound-data-proto*) -(defmeth compound-data-proto :data-length (&rest args) nil) -(defmeth compound-data-proto :data-seq (&rest args) nil) -(defmeth compound-data-proto :make-data (&rest args) nil) -(defmeth compound-data-proto :select-data (&rest args) nil) +(defmeth *compound-data-proto* :data-length (&rest args) nil) +(defmeth *compound-data-proto* :data-seq (&rest args) nil) +(defmeth *compound-data-proto* :make-data (&rest args) nil) +(defmeth *compound-data-proto* :select-data (&rest args) nil) -(defun compound-object-p (x) (kind-of-p x compound-data-proto)) +(defun compound-object-p (x) (kind-of-p x *compound-data-proto*)) @@ -268,9 +280,9 @@ strings X replaced by their ranks." -;;;; -;;;; REPEAT function -;;;; +;;; +;;; REPEAT function +;;; (defun repeat (a b) "Args: (vals times) @@ -300,3 +312,347 @@ Examples: (repeat 2 5) returns (2 2 2 2 2) (let ((next (copy-list a))) (if result (setf (rest (last next)) result)) (setf result next))))))) +;;; +;;; WHICH function +;;; + +(defun which (x) +"Args: (x) +Returns a list of the indices where elements of sequence X are not NIL." + (let ((x (list (compound-data-seq x))) + (result nil) + (tail nil)) + (flet ((add-result (x) + (if result (setf (rest tail) (list x)) (setf result (list x))) + (setf tail (if tail (rest tail) result))) + (get-next-element (seq-list i) + (cond ((consp (first seq-list)) + (let ((elem (first (first seq-list)))) + (setf (first seq-list) (rest (first seq-list))) + elem)) + (t (aref (first seq-list) i))))) + (let ((n (length (first x)))) + (dotimes (i n result) + (if (get-next-element x i) (add-result i))))))) + + +;;; Sequences are part of ANSI CL, being a supertype of vector and +;;; list (ordered set of things). +;;; +;;; Need to use the interenal structure when possible -- silly to be +;;; redundant! However, this means we need to understand what +;;; sequences were intending to do, which I'm not clear on yet. + +;;; The original ordering, object-wise, was to have compound +;;; functionality passed into sequences, into other data sources. +;;; However, at this point, we will see about inverting this and +;;; having basic data types pushed through compound, to simplify +;;; packaging. + +;;; Type Checking Functions + +(defun check-sequence (a) + ;; FIXME:AJR: does this handle consp as well? (Luke had an "or" + ;; with consp). + (if (not (typep a 'sequence)) + (error "not a sequence - ~s" a))) + +;;; Sequence Element Access + + +;;; (elt x i) -- NOT. This is more like "pop". +(defun get-next-element (x i) + "Get element i from seq x. FIXME: not really??" + (let ((myseq (first x))) + (if (consp myseq) + (let ((elem (first myseq))) + (setf (first x) (rest myseq)) + elem) + (aref myseq i)))) + +;;; (setf (elt x i) v) +(defun set-next-element (x i v) + (let ((seq (first x))) + (cond ((consp seq) + (setf (first seq) v) + (setf (first x) (rest seq))) + (t (setf (aref seq i) v))))) + +(defun make-next-element (x) (list x)) + + +;;; Sequence Functions + + +;; to prevent breakage. +(defmacro sequencep (x) + (typep x 'sequence)) + +(defun iseq (a &optional b) +"Args: (n &optional m) +Generate a sequence of consecutive integers from a to b. +With one argumant returns a list of consecutive integers from 0 to N - 1. +With two returns a list of consecutive integers from N to M. +Examples: (iseq 4) returns (0 1 2 3) + (iseq 3 7) returns (3 4 5 6 7) + (iseq 3 -3) returns (3 2 1 0 -1 -2 -3)" + (if b + (let ((n (+ 1 (abs (- b a)))) + (x nil)) + (dotimes (i n x) + (setq x (cons (if (< a b) (- b i) (+ b i)) x)))) + (cond + ((= 0 a) nil) + ((< a 0) (iseq (+ a 1) 0)) + ((< 0 a) (iseq 0 (- a 1)))))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; +;;;; Subset Selection and Mutation Functions +;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +(defun old-rowmajor-index (index indices dim olddim) + "translate row major index in resulting subarray to row major index +in the original array." + (declare (fixnum index)) + (let ((rank (length dim)) + (face 1) + (oldface 1) + (oldindex 0)) + (declare (fixnum rank face oldface)) + + (dotimes (i rank) + (declare (fixnum i)) + (setf face (* face (aref dim i))) + (setf oldface (* oldface (aref olddim i)))) + + (dotimes (i rank) + (declare (fixnum i)) + (setf face (/ face (aref dim i))) + (setf oldface (/ oldface (aref olddim i))) + (incf oldindex + (* oldface (aref (aref indices i) (floor (/ index face))))) ;;*** is this floor really needed??? + (setf index (rem index face))) + oldindex)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; +;;;; Subset Selection and Mutation Functions +;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun subarray-select (a indexlist &optional (values nil set_values)) + "extract or set subarray for the indices from a displaced array." + (let ((indices nil) + (index) + (dim) + (vdim) + (data) + (result_data) + (olddim) + (result) + (rank 0) + (n 0) + (k 0)) + (declare (fixnum rank n)) + + (if (or (sequencep a) (not (arrayp a))) (error "not an array - ~a" a)) + (if (not (listp indexlist)) (error "bad index list - ~a" indices)) + (if (/= (length indexlist) (array-rank a)) + (error "wrong number of indices")) + + (setf indices (coerce indexlist 'vector)) + + (setf olddim (coerce (array-dimensions a) 'vector)) + + ;; compute the result dimension vector and fix up the indices + (setf rank (array-rank a)) + (setf dim (make-array rank)) + (dotimes (i rank) + (declare (fixnum i)) + (setf index (aref indices i)) + (setf n (aref olddim i)) + (setf index (if (fixnump index) (vector index) (coerce index 'vector))) + (setf k (length index)) + (dotimes (j k) + (declare (fixnum j)) + (if (<= n (check-nonneg-fixnum (aref index j))) + (error "index out of bounds - ~a" (aref index j))) + (setf (aref indices i) index)) + (setf (aref dim i) (length index))) + + ;; set up the result or check the values + (let ((dim-list (coerce dim 'list))) + (cond + (set_values + (cond + ((compound-data-p values) + (if (or (not (arrayp values)) (/= rank (array-rank values))) + (error "bad values array - ~a" values)) + (setf vdim (coerce (array-dimensions values) 'vector)) + (dotimes (i rank) + (declare (fixnum i)) + (if (/= (aref vdim i) (aref dim i)) + (error "bad value array dimensions - ~a" values))) + (setf result values)) + (t (setf result (make-array dim-list :initial-element values))))) + (t (setf result (make-array dim-list))))) + + ;; compute the result or set the values + (setf data (compound-data-seq a)) + (setf result_data (compound-data-seq result)) + (setf n (length result_data)) + (dotimes (i n) + (declare (fixnum i)) + (setf k (old-rowmajor-index i indices dim olddim)) + (if (or (> 0 k) (>= k (length data))) (error "index out of range")) + (if set_values + (setf (aref data k) (aref result_data i)) + (setf (aref result_data i) (aref data k)))) + + result)) + + +;;;; is x an ordered sequence of nonnegative positive integers? +(defun ordered-nneg-seq(x) + ;; FIXME -- sbcl warning about unreachable code, might be a logic error here. + (if (sequencep x) + (let ((n (length x)) + (cx (make-next-element x)) + (m 0)) + (dotimes (i n t) + (let ((elem (check-nonneg-fixnum (get-next-element cx i)))) + (if (> m elem) (return nil) (setf m elem))))))) + +;;;; select or set the subsequence corresponding to the specified indices +(defun sequence-select(x indices &optional (values nil set-values)) + ;; FIXME -- sbcl warning about unreachable code, might be a logic error here. + (let ((rlen 0) + (dlen 0) + (vlen 0) + (data nil) + (result nil)) + (declare (fixnum rlen dlen vlen)) + + ;; Check the input data + (check-sequence x) + (check-sequence indices) + (if set-values (check-sequence values)) + + ;; Find the data sizes + (setf data (if (ordered-nneg-seq indices) x (coerce x 'vector))) + (setf dlen (length data)) + (setf rlen (length indices)) + (when set-values + (setf vlen (length values)) + (if (/= vlen rlen) (error "value and index sequences do not match"))) + + ;; set up the result/value sequence + (setf result + (if set-values + values + (make-sequence (if (listp x) 'list 'vector) rlen))) + + ;; get or set the sequence elements + (if set-values + (do ((nextx x) + (cr (make-next-element result)) + (ci (make-next-element indices)) + (i 0 (+ i 1)) + (j 0) + (index 0)) + ((>= i rlen)) + (declare (fixnum i j index)) + (setf index (get-next-element ci i)) + (if (<= dlen index) (error "index out of range - ~a" index)) + (let ((elem (get-next-element cr i))) + (cond + ((listp x) + (when (> j index) + (setf j 0) + (setf nextx x)) + (do () + ((not (and (< j index) (consp nextx)))) + (incf j 1) + (setf nextx (rest nextx))) + (setf (first nextx) elem)) + (t (setf (aref x index) elem))))) + (do ((nextx data) + (cr (make-next-element result)) + (ci (make-next-element indices)) + (i 0 (+ i 1)) + (j 0) + (index 0) + (elem nil)) + ((>= i rlen)) + (declare (fixnum i j index)) + (setf index (get-next-element ci i)) + (if (<= dlen index) (error "index out of range - ~a" index)) + (cond + ((listp data) ;; indices must be ordered + (do () + ((not (and (< j index) (consp nextx)))) + (incf j 1) + (setf nextx (rest nextx))) + (setf elem (first nextx))) + (t (setf elem (aref data index)))) + (set-next-element cr i elem))) + + result)) + +;;; +;;; SELECT function +;;; + +(defun select (x &rest args) +"Args: (a &rest indices) +A can be a list or an array. If A is a list and INDICES is a single number +then the appropriate element of A is returned. If is a list and INDICES is +a list of numbers then the sublist of the corresponding elements is returned. +If A in an array then the number of INDICES must match the ARRAY-RANK of A. +If each index is a number then the appropriate array element is returned. +Otherwise the INDICES must all be lists of numbers and the corresponding +submatrix of A is returned. SELECT can be used in setf." + (cond + ((every #'fixnump args) + (if (listp x) (nth (first args) x) (apply #'aref x args))) + ((sequencep x) (sequence-select x (first args))) + (t (subarray-select x args)))) + + +;; Built in SET-SELECT (SETF method for SELECT) +(defun set-select (x &rest args) + (let ((indices (butlast args)) + (values (first (last args)))) + (cond + ((sequencep x) + (if (not (consp indices)) (error "bad indices - ~a" indices)) + (let* ((indices (first indices)) + (i-list (if (fixnump indices) (list indices) indices)) + (v-list (if (fixnump indices) (list values) values))) + (sequence-select x i-list v-list))) + ((arrayp x) + (subarray-select x indices values)) + (t (error "bad argument type - ~a" x))) + values)) + +(defsetf select set-select) + +;;;; +;;;; Basic Sequence Operations +;;;; + +(defun difference (x) +"Args: (x) +Returns differences for a sequence X." + (let ((n (length x))) + (- (select x (iseq 1 (1- n))) (select x (iseq 0 (- n 2)))))) + +(defun rseq (a b num) +"Args: (a b num) +Returns a list of NUM equally spaced points starting at A and ending at B." + (+ a (* (values-list (iseq 0 (1- num))) (/ (float (- b a)) (1- num))))) + + diff --git a/data.lisp b/data.lisp index ed7f9df..7962d53 100644 --- a/data.lisp +++ b/data.lisp @@ -36,8 +36,7 @@ :lisp-stat-types :lisp-stat-compound-data :lisp-stat-matrix - :lisp-stat-linalg - :lisp-stat-sequence) + :lisp-stat-linalg) (:shadowing-import-from :lisp-stat-object-system slot-value call-method call-next-method) (:export diff --git a/ladata.lsp b/ladata.lsp index 4975417..418c6f5 100644 --- a/ladata.lsp +++ b/ladata.lsp @@ -20,7 +20,6 @@ :cffi :lisp-stat-ffi-int :lisp-stat-types - :lisp-stat-sequence :lisp-stat-compound-data :lisp-stat-matrix) (:export ;; more to add diff --git a/linalg.lsp b/linalg.lsp index 26fff9f..c8e1080 100644 --- a/linalg.lsp +++ b/linalg.lsp @@ -32,7 +32,6 @@ :lisp-stat-math :lisp-stat-types :lisp-stat-float - :lisp-stat-sequence :lisp-stat-compound-data :lisp-stat-data :lisp-stat-basics diff --git a/lispstat.asd b/lispstat.asd index 3cda769..4aa3630 100644 --- a/lispstat.asd +++ b/lispstat.asd @@ -17,7 +17,9 @@ (defparameter *fasl-directory* (make-pathname :directory '(:relative #+sbcl "sbcl-fasl" #+openmcl "openmcl-fasl" - #-(or sbcl openmcl) "fasl"))) + #+cmucl "cmucl-fasl" + #+clisp "clisp-fasl" + #-(or sbcl openmcl clisp cmucl) "fasl"))) (defmethod source-file-type ((c lispstat-lsp-source-file) (s module)) "lsp") (defmethod asdf::output-files :around ((operation compile-op) @@ -42,29 +44,24 @@ Last touched 1991, then in 2005--2007." (:lispstat-lsp-source-file "lsobjects") (:lispstat-lsp-source-file "cffiglue") (:lispstat-lsp-source-file "defsys") - - (:lispstat-lsp-source-file "fastmap") (:lispstat-lsp-source-file "lstypes") (:lispstat-lsp-source-file "lsfloat") - (:lispstat-lsp-source-file "sequence" - :depends-on ("lstypes")) - (:lispstat-lsp-source-file "matrices" - :depends-on ("cffiglue" - "sequence")) (:lispstat-lsp-source-file "compound" :depends-on ("lsobjects" - "fastmap" - "sequence")) + "fastmap")) + + (:lispstat-lsp-source-file "matrices" + :depends-on ("cffiglue" + "compound")) + (:lispstat-lsp-source-file "ladata" :depends-on ("cffiglue" "defsys" "lstypes" - "sequence" "compound" - "matrices" - )) + "matrices")) (:lispstat-lsp-source-file "lsmacros" :depends-on ("compound")) @@ -101,7 +98,6 @@ Last touched 1991, then in 2005--2007." :depends-on ("lsobjects" "lstypes" "lsmacros" - "sequence" "lsfloat" "matrices" "linalg" diff --git a/lsbasics.lsp b/lsbasics.lsp index a0cad4a..3cb0f3c 100644 --- a/lsbasics.lsp +++ b/lsbasics.lsp @@ -18,14 +18,11 @@ :lisp-stat-float :lisp-stat-macros :lisp-stat-compound-data - :lisp-stat-sequence ;;:lisp-stat-matrix ;;:lisp-stat-linalg :lisp-stat-probability) (:shadowing-import-from :lisp-stat-object-system slot-value call-method call-next-method) - (:shadowing-import-from :lisp-stat-sequence - check-sequence) (:export permute-array sum prod count-elements mean if-else sample @@ -59,107 +56,7 @@ (in-package #:lisp-stat-basics) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;; -;;;; Subset Selection and Mutation Functions -;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(defun old-rowmajor-index (index indices dim olddim) - "translate row major index in resulting subarray to row major index -in the original array." - (declare (fixnum index)) - (let ((rank (length dim)) - (face 1) - (oldface 1) - (oldindex 0)) - (declare (fixnum rank face oldface)) - - (dotimes (i rank) - (declare (fixnum i)) - (setf face (* face (aref dim i))) - (setf oldface (* oldface (aref olddim i)))) - - (dotimes (i rank) - (declare (fixnum i)) - (setf face (/ face (aref dim i))) - (setf oldface (/ oldface (aref olddim i))) - (incf oldindex - (* oldface (aref (aref indices i) (floor (/ index face))))) ;;*** is this floor really needed??? - (setf index (rem index face))) - oldindex)) - -(defun subarray-select (a indexlist &optional (values nil set_values)) - "extract or set subarray for the indices from a displaced array." - (let ((indices nil) - (index) - (dim) - (vdim) - (data) - (result_data) - (olddim) - (result) - (rank 0) - (n 0) - (k 0)) - (declare (fixnum rank n)) - - (if (or (sequencep a) (not (arrayp a))) (error "not an array - ~a" a)) - (if (not (listp indexlist)) (error "bad index list - ~a" indices)) - (if (/= (length indexlist) (array-rank a)) - (error "wrong number of indices")) - - (setf indices (coerce indexlist 'vector)) - - (setf olddim (coerce (array-dimensions a) 'vector)) - - ;; compute the result dimension vector and fix up the indices - (setf rank (array-rank a)) - (setf dim (make-array rank)) - (dotimes (i rank) - (declare (fixnum i)) - (setf index (aref indices i)) - (setf n (aref olddim i)) - (setf index (if (fixnump index) (vector index) (coerce index 'vector))) - (setf k (length index)) - (dotimes (j k) - (declare (fixnum j)) - (if (<= n (check-nonneg-fixnum (aref index j))) - (error "index out of bounds - ~a" (aref index j))) - (setf (aref indices i) index)) - (setf (aref dim i) (length index))) - - ;; set up the result or check the values - (let ((dim-list (coerce dim 'list))) - (cond - (set_values - (cond - ((compound-data-p values) - (if (or (not (arrayp values)) (/= rank (array-rank values))) - (error "bad values array - ~a" values)) - (setf vdim (coerce (array-dimensions values) 'vector)) - (dotimes (i rank) - (declare (fixnum i)) - (if (/= (aref vdim i) (aref dim i)) - (error "bad value array dimensions - ~a" values))) - (setf result values)) - (t (setf result (make-array dim-list :initial-element values))))) - (t (setf result (make-array dim-list))))) - - ;; compute the result or set the values - (setf data (compound-data-seq a)) - (setf result_data (compound-data-seq result)) - (setf n (length result_data)) - (dotimes (i n) - (declare (fixnum i)) - (setf k (old-rowmajor-index i indices dim olddim)) - (if (or (> 0 k) (>= k (length data))) (error "index out of range")) - (if set_values - (setf (aref data k) (aref result_data i)) - (setf (aref result_data i) (aref data k)))) - - result)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/matrices.lsp b/matrices.lsp index 82de6f6..fa9aef2 100644 --- a/matrices.lsp +++ b/matrices.lsp @@ -21,8 +21,7 @@ (defpackage :lisp-stat-matrix (:use :common-lisp - :lisp-stat-compound-data - :lisp-stat-sequence) + :lisp-stat-compound-data) (:export matrixp num-rows num-cols matmult identity-matrix diagonal row-list column-list inner-product outer-product cross-product transpose bind-columns bind-rows diff --git a/nonlin.lsp b/nonlin.lsp index 0449616..de75fdd 100644 --- a/nonlin.lsp +++ b/nonlin.lsp @@ -16,7 +16,6 @@ :lisp-stat-math :lisp-stat-basics :lisp-stat-compound-data - :lisp-stat-sequence :lisp-stat-matrix :lisp-stat-linalg :lisp-stat-regression-linear) diff --git a/optimize.lisp b/optimize.lisp index 0ecb8bf..98f21b2 100644 --- a/optimize.lisp +++ b/optimize.lisp @@ -10,7 +10,6 @@ :lisp-stat-ffi-int :lisp-stat-object-system :lisp-stat-types - :lisp-stat-sequence :lisp-stat-compound-data :lisp-stat-math :lisp-stat-basics diff --git a/regression.lsp b/regression.lsp index 1767d5b..18b9f5a 100644 --- a/regression.lsp +++ b/regression.lsp @@ -23,7 +23,6 @@ :lisp-stat-object-system :lisp-stat-basics :lisp-stat-compound-data - :lisp-stat-sequence :lisp-stat-matrix) (:shadowing-import-from :lisp-stat-object-system slot-value call-method call-next-method) diff --git a/sequence.lsp b/sequence.lsp deleted file mode 100644 index 27ea5c2..0000000 --- a/sequence.lsp +++ /dev/null @@ -1,270 +0,0 @@ -;;; -*- mode: lisp -*- -;;; Copyright (c) 2005--2007, by A.J. Rossini -;;; See COPYRIGHT file for any additional restrictions (BSD license). -;;; Since 1991, ANSI was finally finished. Edited for ANSI Common Lisp. - -;;;; Copyright (c) 1991, by Luke Tierney. Permission is granted for -;;;; unrestricted use. (though Luke never had this file). - -;;;; -;;;; Package Setup -;;;; - -(in-package :cl-user) - -(defpackage :lisp-stat-sequence - (:use :common-lisp - :lisp-stat-types) - (:export check-sequence - get-next-element make-next-element set-next-element - sequencep iseq - - ;; maybe? - ordered-nneg-seq - select - - which - ;; vector differences - difference rseq)) - -(in-package :lisp-stat-sequence) - -;;; Sequences are part of ANSI CL, being a supertype of vector and -;;; list (ordered set of things). -;;; -;;; Need to use the interenal structure when possible -- silly to be -;;; redundant! However, this means we need to understand what -;;; sequences were intending to do, which I'm not clear on yet. - -;;; The original ordering, object-wise, was to have compound -;;; functionality passed into sequences, into other data sources. -;;; However, at this point, we will see about inverting this and -;;; having basic data types pushed through compound, to simplify -;;; packaging. - -;;; Type Checking Functions - -(defun check-sequence (a) - ;; FIXME:AJR: does this handle consp as well? (Luke had an "or" - ;; with consp). - (if (not (typep a 'sequence)) - (error "not a sequence - ~s" a))) - -;;; Sequence Element Access - - -;;; (elt x i) -- NOT. This is more like "pop". -(defun get-next-element (x i) - "Get element i from seq x. FIXME: not really??" - (let ((myseq (first x))) - (if (consp myseq) - (let ((elem (first myseq))) - (setf (first x) (rest myseq)) - elem) - (aref myseq i)))) - -;;; (setf (elt x i) v) -(defun set-next-element (x i v) - (let ((seq (first x))) - (cond ((consp seq) - (setf (first seq) v) - (setf (first x) (rest seq))) - (t (setf (aref seq i) v))))) - -(defun make-next-element (x) (list x)) - - -;;; Sequence Functions - - -;; to prevent breakage. -(defmacro sequencep (x) - (typep x 'sequence)) - -(defun iseq (a &optional b) -"Args: (n &optional m) -Generate a sequence of consecutive integers from a to b. -With one argumant returns a list of consecutive integers from 0 to N - 1. -With two returns a list of consecutive integers from N to M. -Examples: (iseq 4) returns (0 1 2 3) - (iseq 3 7) returns (3 4 5 6 7) - (iseq 3 -3) returns (3 2 1 0 -1 -2 -3)" - (if b - (let ((n (+ 1 (abs (- b a)))) - (x nil)) - (dotimes (i n x) - (setq x (cons (if (< a b) (- b i) (+ b i)) x)))) - (cond - ((= 0 a) nil) - ((< a 0) (iseq (+ a 1) 0)) - ((< 0 a) (iseq 0 (- a 1)))))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;; -;;;; Subset Selection and Mutation Functions -;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;;;; is x an ordered sequence of nonnegative positive integers? -(defun ordered-nneg-seq(x) - ;; FIXME -- sbcl warning about unreachable code, might be a logic error here. - (if (sequencep x) - (let ((n (length x)) - (cx (make-next-element x)) - (m 0)) - (dotimes (i n t) - (let ((elem (check-nonneg-fixnum (get-next-element cx i)))) - (if (> m elem) (return nil) (setf m elem))))))) - -;;;; select or set the subsequence corresponding to the specified indices -(defun sequence-select(x indices &optional (values nil set-values)) - ;; FIXME -- sbcl warning about unreachable code, might be a logic error here. - (let ((rlen 0) - (dlen 0) - (vlen 0) - (data nil) - (result nil)) - (declare (fixnum rlen dlen vlen)) - - ;; Check the input data - (check-sequence x) - (check-sequence indices) - (if set-values (check-sequence values)) - - ;; Find the data sizes - (setf data (if (ordered-nneg-seq indices) x (coerce x 'vector))) - (setf dlen (length data)) - (setf rlen (length indices)) - (when set-values - (setf vlen (length values)) - (if (/= vlen rlen) (error "value and index sequences do not match"))) - - ;; set up the result/value sequence - (setf result - (if set-values - values - (make-sequence (if (listp x) 'list 'vector) rlen))) - - ;; get or set the sequence elements - (if set-values - (do ((nextx x) - (cr (make-next-element result)) - (ci (make-next-element indices)) - (i 0 (+ i 1)) - (j 0) - (index 0)) - ((>= i rlen)) - (declare (fixnum i j index)) - (setf index (get-next-element ci i)) - (if (<= dlen index) (error "index out of range - ~a" index)) - (let ((elem (get-next-element cr i))) - (cond - ((listp x) - (when (> j index) - (setf j 0) - (setf nextx x)) - (do () - ((not (and (< j index) (consp nextx)))) - (incf j 1) - (setf nextx (rest nextx))) - (setf (first nextx) elem)) - (t (setf (aref x index) elem))))) - (do ((nextx data) - (cr (make-next-element result)) - (ci (make-next-element indices)) - (i 0 (+ i 1)) - (j 0) - (index 0) - (elem nil)) - ((>= i rlen)) - (declare (fixnum i j index)) - (setf index (get-next-element ci i)) - (if (<= dlen index) (error "index out of range - ~a" index)) - (cond - ((listp data) ;; indices must be ordered - (do () - ((not (and (< j index) (consp nextx)))) - (incf j 1) - (setf nextx (rest nextx))) - (setf elem (first nextx))) - (t (setf elem (aref data index)))) - (set-next-element cr i elem))) - - result)) - -;;; -;;; SELECT function -;;; - -(defun select (x &rest args) -"Args: (a &rest indices) -A can be a list or an array. If A is a list and INDICES is a single number -then the appropriate element of A is returned. If is a list and INDICES is -a list of numbers then the sublist of the corresponding elements is returned. -If A in an array then the number of INDICES must match the ARRAY-RANK of A. -If each index is a number then the appropriate array element is returned. -Otherwise the INDICES must all be lists of numbers and the corresponding -submatrix of A is returned. SELECT can be used in setf." - (cond - ((every #'fixnump args) - (if (listp x) (nth (first args) x) (apply #'aref x args))) - ((sequencep x) (sequence-select x (first args))) - (t (subarray-select x args)))) - - -;; Built in SET-SELECT (SETF method for SELECT) -(defun set-select (x &rest args) - (let ((indices (butlast args)) - (values (first (last args)))) - (cond - ((sequencep x) - (if (not (consp indices)) (error "bad indices - ~a" indices)) - (let* ((indices (first indices)) - (i-list (if (fixnump indices) (list indices) indices)) - (v-list (if (fixnump indices) (list values) values))) - (sequence-select x i-list v-list))) - ((arrayp x) - (subarray-select x indices values)) - (t (error "bad argument type - ~a" x))) - values)) - -(defsetf select set-select) - -;;;; -;;;; Basic Sequence Operations -;;;; - -(defun difference (x) -"Args: (x) -Returns differences for a sequence X." - (let ((n (length x))) - (- (select x (iseq 1 (1- n))) (select x (iseq 0 (- n 2)))))) - -(defun rseq (a b num) -"Args: (a b num) -Returns a list of NUM equally spaced points starting at A and ending at B." - (+ a (* (values-list (iseq 0 (1- num))) (/ (float (- b a)) (1- num))))) - - -;;;; -;;;; WHICH function -;;;; - -(defun which (x) -"Args: (x) -Returns a list of the indices where elements of sequence X are not NIL." - (let ((x (list (compound-data-seq x))) - (result nil) - (tail nil)) - (flet ((add-result (x) - (if result (setf (rest tail) (list x)) (setf result (list x))) - (setf tail (if tail (rest tail) result))) - (get-next-element (seq-list i) - (cond ((consp (first seq-list)) - (let ((elem (first (first seq-list)))) - (setf (first seq-list) (rest (first seq-list))) - elem)) - (t (aref (first seq-list) i))))) - (let ((n (length (first x)))) - (dotimes (i n result) - (if (get-next-element x i) (add-result i))))))) diff --git a/statistics.lsp b/statistics.lsp index 5479719..eb4ae74 100644 --- a/statistics.lsp +++ b/statistics.lsp @@ -17,7 +17,6 @@ :lisp-stat-data :lisp-stat-math :lisp-stat-compound-data - :lisp-stat-sequence :lisp-stat-matrix :lisp-stat-linalg-data :lisp-stat-linalg -- 2.11.4.GIT