source: CGBLisp/src/makelist.lisp@ 1

Last change on this file since 1 was 1, checked in by Marek Rychlik, 15 years ago

First import of a version circa 1997.

File size: 4.6 KB
Line 
1#|
2 $Id: makelist.lisp,v 1.4 2009/01/23 10:45:43 marek Exp $
3 *--------------------------------------------------------------------------*
4 | Copyright (C) 1994, Marek Rychlik (e-mail: rychlik@math.arizona.edu) |
5 | Department of Mathematics, University of Arizona, Tucson, AZ 85721 |
6 | |
7 | Everyone is permitted to copy, distribute and modify the code in this |
8 | directory, as long as this copyright note is preserved verbatim. |
9 *--------------------------------------------------------------------------*
10|#
11
12(defpackage "MAKELIST"
13 (:use "COMMON-LISP")
14 (:export makelist-1 makelist list-of set-of union-of select sum summation difference standard-vector))
15
16(in-package "MAKELIST")
17
18#+debug(proclaim '(optimize (speed 0) (debug 3)))
19#-debug(proclaim '(optimize (speed 3) (debug 0)))
20
21
22;; Macros for making lists with iterators - an exammple of GENSYM
23;; MAKELIST-1 makes a list with one iterator, while MAKELIST accepts an
24;; arbitrary number of iterators
25
26;; Sample usage:
27;; Without a step:
28;; >(makelist-1 (* 2 i) i 0 10)
29;; (0 2 4 6 8 10 12 14 16 18 20)
30;; With a step of 3:
31;; >(makelist-1 (* 2 i) i 0 10 3)
32;; (0 6 12 18)
33
34;; Generate sums of squares of numbers between 1 and 4:
35;; >(makelist (+ (* i i) (* j j)) (i 1 4) (j 1 i))
36;; (2 5 8 10 13 18 17 20 25 32)
37;; >(makelist (list i j '---> (+ (* i i) (* j j))) (i 1 4) (j 1 i))
38;; ((1 1 ---> 2) (2 1 ---> 5) (2 2 ---> 8) (3 1 ---> 10) (3 2 ---> 13)
39;; (3 3 ---> 18) (4 1 ---> 17) (4 2 ---> 20) (4 3 ---> 25) (4 4 ---> 32))
40
41;; Summation with SUM:
42;; Sum of squares of integers from 1 to 10:
43;; >(sum (expt i 2) (i 1 10))
44;; 385
45;; Sum of inverses of integers from 1 to 50:
46;; >(sum (/ n) (n 1 50))
47;; 13943237577224054960759/3099044504245996706400
48;; Sum of 1/(m^2+n^2) where m,n vary from 1 to 10:
49;; >(sum (/ (+ (expt m 2) (expt n 2))) (n 1 10) (m 1 10))
50;; 125085870045079516933345908893314157/42204464874461454985621846571472000
51;; Sum of 1/(m^2+n^2) where m,n vary from 1 to 10 and m>n:
52;; >(sum (/ (+ (expt m 2) (expt n 2))) (n 1 10) (m 1 (1- n)))
53;; 13092731173226115661182811487147/11962716801151206061684196874000
54
55;; Evaluate expression expr with variable set to lo, lo+1,... ,hi
56;; and put the results in a list.
57(defmacro makelist-1 (expr var lo hi &optional (step 1))
58 (let ((l (gensym)))
59 `(do ((,var ,lo (+ ,var ,step))
60 (,l nil (cons ,expr ,l)))
61 ((> ,var ,hi) (reverse ,l))
62 (declare (fixnum ,var)))))
63
64(defmacro makelist (expr (var lo hi &optional (step 1)) &rest more)
65 (if (endp more)
66 `(makelist-1 ,expr ,var ,lo ,hi ,step)
67 (let* ((l (gensym)))
68 `(do ((,var ,lo (+ ,var ,step))
69 (,l nil (nconc ,l `,(makelist ,expr ,@more))))
70 ((> ,var ,hi) ,l)
71 (declare (fixnum ,var))))))
72
73(defmacro sum (&body body)
74 `(reduce #'+ (makelist ,@body)))
75
76(defmacro summation (&body body)
77 ``(+ ,@(makelist ,@body)))
78
79(defmacro difference (&body body)
80 ``(- ,@(makelist ,@body)))
81
82;; List of all EXPR where VAR varies over the list LST
83(defmacro list-of (expr (var lst) &rest more)
84 (if (endp more)
85 `(list-of-1 ,expr ,var ,lst)
86 (let ((l (gensym)))
87 `(let ((,l))
88 (dolist (,var ,lst ,l)
89 (setf ,l (nconc ,l ,`(list-of ,expr ,@more))))))))
90
91(defmacro list-of-1 (expr var lst)
92 (let ((l (gensym)))
93 `(let ((,l))
94 (dolist (,var ,lst (reverse ,l))
95 (setf ,l ,`(cons ,expr ,l))))))
96
97;; Union of all EXPR where VAR varies over the list LST
98(defmacro union-of (expr (var lst) &rest more)
99 (if (endp more)
100 `(union-of-1 ,expr ,var ,lst)
101 (let ((l (gensym)))
102 `(let ((,l))
103 (dolist (,var ,lst ,l)
104 (setf ,l (union ,l ,`(union-of ,expr ,@more) :test #'equalp)))))))
105
106(defmacro union-of-1 (expr var lst)
107 (let ((l (gensym)))
108 `(let ((,l))
109 (dolist (,var ,lst (reverse ,l))
110 (setf ,l ,`(union ,expr ,l :test #'equalp))))))
111
112
113;; Set of all EXPR where VAR varies over the list LST
114(defmacro set-of (expr (var lst) &rest more)
115 (if (endp more)
116 `(set-of-1 ,expr ,var ,lst)
117 (let ((l (gensym)))
118 `(let ((,l))
119 (dolist (,var ,lst ,l)
120 (setf ,l (union ,l ,`(set-of ,expr ,@more) :test #'equalp)))))))
121
122(defmacro set-of-1 (expr var lst)
123 (let ((l (gensym)))
124 `(let ((,l))
125 (dolist (,var ,lst (reverse ,l))
126 (pushnew ,expr ,l :test #'equalp)))))
127
128;; sublist of LST consisting of elements with indecies in IND
129(defun select (ind lst)
130 (cond
131 ((endp ind) nil)
132 (t (cons (elt lst (car ind)) (select (cdr ind) lst)))))
133
134(defun standard-vector (n k &optional (coeff 1)
135 &aux (v (make-list n :initial-element 0)))
136 "Returns vector (0 0 ... 1 ... 0 0) of length N, where 1 appears on K-th place."
137 (setf (elt v k) coeff)
138 v)
Note: See TracBrowser for help on using the repository browser.