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

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