| [1200] | 1 | ;;; -*-  Mode: Lisp -*- 
 | 
|---|
| [82] | 2 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
|---|
 | 3 | ;;;                                                                              
 | 
|---|
 | 4 | ;;;  Copyright (C) 1999, 2002, 2009, 2015 Marek Rychlik <rychlik@u.arizona.edu>          
 | 
|---|
 | 5 | ;;;                                                                              
 | 
|---|
 | 6 | ;;;  This program is free software; you can redistribute it and/or modify        
 | 
|---|
 | 7 | ;;;  it under the terms of the GNU General Public License as published by        
 | 
|---|
 | 8 | ;;;  the Free Software Foundation; either version 2 of the License, or           
 | 
|---|
 | 9 | ;;;  (at your option) any later version.                                         
 | 
|---|
 | 10 | ;;;                                                                              
 | 
|---|
 | 11 | ;;;  This program is distributed in the hope that it will be useful,             
 | 
|---|
 | 12 | ;;;  but WITHOUT ANY WARRANTY; without even the implied warranty of              
 | 
|---|
 | 13 | ;;;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               
 | 
|---|
 | 14 | ;;;  GNU General Public License for more details.                                
 | 
|---|
 | 15 | ;;;                                                                              
 | 
|---|
 | 16 | ;;;  You should have received a copy of the GNU General Public License           
 | 
|---|
 | 17 | ;;;  along with this program; if not, write to the Free Software                 
 | 
|---|
 | 18 | ;;;  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
 | 
|---|
 | 19 | ;;;                                                                              
 | 
|---|
 | 20 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
|---|
 | 21 | 
 | 
|---|
| [453] | 22 | (defpackage "UTILS"
 | 
|---|
 | 23 |   (:use :cl)
 | 
|---|
| [1230] | 24 |   (:export "MAKELIST-1" "MAKELIST" "SUMMATION" "INNER-PRODUCT"))
 | 
|---|
| [82] | 25 | 
 | 
|---|
| [455] | 26 | (in-package :utils)
 | 
|---|
| [137] | 27 | 
 | 
|---|
| [92] | 28 | ;; Macros for making lists with iterators
 | 
|---|
 | 29 | ;;
 | 
|---|
| [82] | 30 | ;; MAKELIST-1 makes a list with one iterator, while MAKELIST accepts an
 | 
|---|
 | 31 | ;; arbitrary number of iterators
 | 
|---|
 | 32 | 
 | 
|---|
 | 33 | ;; Sample usage:
 | 
|---|
 | 34 | ;; Without a step:
 | 
|---|
 | 35 | ;; >(makelist-1 (* 2 i) i 0 10)
 | 
|---|
 | 36 | ;; (0 2 4 6 8 10 12 14 16 18 20)
 | 
|---|
 | 37 | ;; With a step of 3:
 | 
|---|
 | 38 | ;; >(makelist-1 (* 2 i) i 0 10 3)
 | 
|---|
 | 39 | ;; (0 6 12 18)
 | 
|---|
 | 40 | 
 | 
|---|
 | 41 | ;; Generate sums of squares of numbers between 1 and 4:
 | 
|---|
 | 42 | ;; >(makelist (+ (* i i) (* j j)) (i 1 4) (j 1 i))
 | 
|---|
 | 43 | ;; (2 5 8 10 13 18 17 20 25 32)
 | 
|---|
 | 44 | ;; >(makelist (list i j '---> (+ (* i i) (* j j))) (i 1 4) (j 1 i))
 | 
|---|
 | 45 | ;; ((1 1 ---> 2) (2 1 ---> 5) (2 2 ---> 8) (3 1 ---> 10) (3 2 ---> 13)
 | 
|---|
 | 46 | ;; (3 3 ---> 18) (4 1 ---> 17) (4 2 ---> 20) (4 3 ---> 25) (4 4 ---> 32))
 | 
|---|
 | 47 | 
 | 
|---|
 | 48 | ;; Evaluate expression expr with variable set to lo, lo+1,... ,hi
 | 
|---|
 | 49 | ;; and put the results in a list.
 | 
|---|
 | 50 | (defmacro makelist-1 (expr var lo hi &optional (step 1))
 | 
|---|
 | 51 |   (let ((l (gensym)))
 | 
|---|
 | 52 |     `(do ((,var ,lo (+ ,var ,step))
 | 
|---|
 | 53 |           (,l nil (cons ,expr ,l)))
 | 
|---|
 | 54 |          ((> ,var ,hi) (reverse ,l))
 | 
|---|
 | 55 |        (declare (fixnum ,var)))))
 | 
|---|
 | 56 | 
 | 
|---|
 | 57 | (defmacro makelist (expr (var lo hi &optional (step 1)) &rest more)
 | 
|---|
 | 58 |   (if (endp more)
 | 
|---|
 | 59 |       `(makelist-1 ,expr ,var ,lo ,hi ,step)
 | 
|---|
 | 60 |     (let* ((l (gensym)))
 | 
|---|
 | 61 |       `(do ((,var ,lo (+ ,var ,step))
 | 
|---|
 | 62 |             (,l nil (nconc ,l `,(makelist ,expr ,@more))))
 | 
|---|
 | 63 |            ((> ,var ,hi) ,l)
 | 
|---|
 | 64 |          (declare (fixnum ,var))))))
 | 
|---|
| [1228] | 65 | 
 | 
|---|
| [1230] | 66 | (defmacro summation (expr (var lo hi &optional (step 1)) &optional (add '+) (init-val 0))
 | 
|---|
| [1229] | 67 |   (let ((r (gensym)))
 | 
|---|
| [1230] | 68 |     `(do ((,r ,init-val)
 | 
|---|
| [1229] | 69 |           (,var ,lo (+ ,var ,step)))
 | 
|---|
 | 70 |          ((> ,var ,hi) ,r)
 | 
|---|
| [1230] | 71 |        (setf ,r (,add ,r ,expr)))))
 | 
|---|
 | 72 | 
 | 
|---|
| [1233] | 73 | (defmacro inner-product (x y &optional (add '+) (mult '*) (init-val 0))
 | 
|---|
| [1232] | 74 |   (let ((i (gensym))
 | 
|---|
 | 75 |         (xx (gensym))
 | 
|---|
 | 76 |         (yy (gensym)))
 | 
|---|
 | 77 |     `(let ((,xx ,x)
 | 
|---|
 | 78 |            (,yy ,y))
 | 
|---|
| [1249] | 79 |        (summation (,mult (elt ,xx ,i) (elt ,yy ,i))
 | 
|---|
 | 80 |                   (,i 0 (1- (length ,xx)))
 | 
|---|
 | 81 |                   ,add 
 | 
|---|
 | 82 |                   ,init-val))))
 | 
|---|