3 ;;; Time-stamp: <2009-03-21 09:30:48 tony>
4 ;;; Creation: <2008-09-08 08:06:30 tony>
5 ;;; File: listoflist.lisp
6 ;;; Author: AJ Rossini <blindglobe@gmail.com>
7 ;;; Copyright: (c) 2007-2008, AJ Rossini <blindglobe@gmail.com>. BSD.
8 ;;; Purpose: Manipulating structures which are lists of lists
9 ;;; rather than arrays or matrix-likes,
11 ;;; What is this talk of 'release'? Klingons do not make software
12 ;;; 'releases'. Our software 'escapes', leaving a bloody trail of
13 ;;; designers and quality assurance people in its wake.
16 ;; Where should this go?
17 (in-package :cls-data-listoflist
)
21 ;; Serious flaw -- need to consider that we are not really well
22 ;; working with the data structures, in that Luke created compound as
23 ;; a base class, which turns out to be slightly backward if we are to
24 ;; maintain the numerical structures as well as computational
27 ;; Currently, we assume that the list-of-list representation is in
28 ;; row-major form, i.e. that lists represent rows and not columns.
29 ;; The original lisp-stat had the other way around. We could augment
30 ;; the top-level list with a property to check orientation
31 ;; (row-major/column-major), but this hasn't been done yet.
33 ;; This file contains code for going between listoflists,
34 ;; arrays/vectors, and matrix-like/vector-like data structures.
41 (defparameter *x1
* (list 1 2 3))
42 (defparameter *x2
* (list 1 2 3))
43 (defparameter *x3
* (list 1 2 3 4))
44 (defparameter *x4
* (list 1 2 3))
45 (reduce #'(lambda (x y
)
47 (mapcar #'length
(list *x1
* *x2
* *x3
*)))
48 (reduce #'(lambda (x y
)
49 (if (= x y
) y -
1)) (list 2 3 2))
50 (lists-of-same-size *x1
* *x2
* *x4
*) ; => T
51 (lists-of-same-size *x1
* *x3
* *x4
*) ; => F
52 (lists-of-same-size *x1
* *x2
* *x3
*) ; => F
53 (lists-of-same-size *x3
* *x1
* *x3
*) ; => F
57 (defun lists-of-same-size (&rest list-of-list-names
)
58 "Check if the lengths of the lists are equal (T, otherwise NIL), to
59 justify further processing and initial conditions."
60 (if (< 0 (reduce #'(lambda (x y
) (if (= x y
) y -
1))
61 (mapcar #'length list-of-list-names
)))
65 ;; the following will be handy to help out folks adjust. It should
66 ;; provide a means to write code faster and better.
67 (defmacro make-dataframe-from-listoflist
(datasetname
68 &optional
(force-overwrite nil
)
69 &rest lists-of-data-lists
)
70 "Create a cases-by-variables data frame consisting of numeric data,
71 from a ROW-MAJOR list-of-lists representation. A COLUMN-MAJOR
72 representation should be handled using the transpose-listoflists
74 (if (or (not (boundp datasetname
))
76 (if (lists-of-same-size lists-of-data-lists
)
77 `(defparameter ,datasetname
78 (make-matrix (length iron
) 2
80 (mapcar #'(lambda (x y
)
81 (list (coerce x
'double-float
)
82 (coerce y
'double-float
)))
83 ,@lists-of-data-lists
)))
84 (error "make-data-set-from-lists: no combining different length lists"))
85 (error "make-data-set-from-lists: proposed name exists")))
88 (macroexpand '(make-data-set-from-lists
95 (defun transpose-listoflist (listoflist)
96 "This function does the moral-equivalent of a matrix transpose on a
97 list-of-lists data structure"
98 (apply #'mapcar
#'list listoflist
))
100 ;; (defparameter LOL-2by3 (list (list 1 2) (list 3 4) (list 5 6)))
101 ;; (defparameter LOL-3by2 (list (list 1 3 5) (list 2 4 6)))
102 ;; (transpose-listoflists (transpose-listoflists LOL-2by3))
103 ;; (transpose-listoflists (transpose-listoflists LOL-3by2))
105 (defun equal-listoflist (x y
)
106 "FIXME: This function, when written, should walk through 2 listoflists and
107 return T/nil based on equality."
108 (and (= (list-length x
) ;; top-level length same
110 ;; FIXME: within-level lengths same
111 ;; FIXME: flattened values same, walking through
112 ;; (loop over x and verify same tree as y)
116 (defun make-array-from-listoflist (lol) ; &key (type 'row-major)
117 "From a listoflists structure, make an array.
119 FIXME: need to verify that the listoflists is a valid structure (same
120 size rows, typing if required, etc.
123 (defparameter *mdfl-test*
124 (list (list 'a 1 2.1)
129 (length (elt *mdfl-test* 0))
131 (defparameter *mdfl-test-dt* (make-datatable-from-listoflists *mdfl-test*))
132 (array-dimensions *mdfl-test-dt*)
134 (let ((n (length lol
))
135 (p (length (elt lol
0))))
136 (let ((result (make-array (list n p
))))
139 (setf (aref result i j
) (elt (elt lol i
) j
))))
143 (defparameter *mdfl-test
*
144 (list (list 'a
1 2.1)
149 (length (elt *mdfl-test
* 0))
151 (defparameter *mdfl-test-dt
* (make-datatable-from-listoflists *mdfl-test
*))
152 (array-dimensions *mdfl-test-dt
*)