source: CGBLisp/trunk/src/makelist.lisp@ 87

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

* empty log message *

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