need performance tips

"Andrew K. Wolven" <[email protected]> Sat, 23 Sep 2006 15:23:18 -0500
Newsgroups gmane.lisp.allegro
Message-ID <009b01c6df4e$1beae5a0$0d00a8c0@Schmazelshmox>
Hi all,
I am preparing to do a mini-lisp primer for a group of CAD students in 
preparation for them to see a GDL presentation by David Cooper.

Here is the low down:
I have chosen to do the cubic spline as an example.  It's is going to be a 
comparison against Fortran which most of them have taken.  Therefore I will 
be pitting something like gcc against ACL.  *You know* somebody is going to 
ask which language is faster in execution.  This is going to be tough.

I will do a "get it done correctly" example first, and then show a 
pre-prepared optimized version.

What can anyone tell me (or point me in the right direction) about getting 
optimal numerical performance where I will be using arrays and iteration to 
do this.

Here is some code that worked last time I checked: It's basically a 
hand-translation of a Fortran program, so I know it might be a little ugly. 
I basically just wanted to get it done to turn in and get my grade and move 
on.  I do know somethings, like obviously I can have those arrays in 
derivative function pre-made and reused, so long as I am careful about it. 
Oh yeah, it's missing a macro vref which is something like (defmacro vref 
(array index) `(aref ,array (1- ,index)))  --> which I probably should rid 
myself of for the optimized version and perhaps use svref?
What about declarations?  If anyone happens to want to share a better 
algorithm, I would also be very grateful.

Thanks in advance all,
(I hope this is correct code!)
AKW

(in-package :me428)

(defun V-example-6.4 ()
  (make-array
   15
   :initial-contents
   (list 0.397 0.798 1.203 1.611 2.022 2.436 2.85 3.266 3.681 4.095 4.508 
4.919 5.327 5.733 6.137)))

(defun Temp-example-6.4 ()
  (make-array
   15
   :initial-contents
   (list 10 20 30 40 50 60 70 80 90 100 110 120 130 140 150)))

(defun derivative (m V Temp)
  (let ((T2 (make-array m))
 (A (make-array m))
 (B (make-array m))
 (C (make-array m))
 (D (make-array m)))
    (setf (vref C 1) (- (vref V 2) (vref V 1)))
    (loop for i from 2 to (1- m)
 do (setf (vref A i) (- (vref V i) (vref V (1- i)))
   (vref B i) (* 2.0 (- (vref V (1+ i)) (vref V (1- i))))
   (vref C i) (- (vref V (1+ i)) (vref V i))
   (vref D i) (* 6.0 (- (/ (- (vref Temp (1+ i)) (vref Temp i)) (vref C i))
          (/ (- (vref Temp i) (vref Temp (1- i))) (vref A i))))))
    (loop for i from 3 to (1- m)
 do
   (setf (vref B i) (- (vref B i)
         (/ (* (vref A i)
        (vref C (1- i)))
     (vref B (1- i))))
  (vref D i) (- (vref D i)
         (/ (* (vref A i)
        (vref D (1- i)))
     (vref B (1- i))))))
    (setf (vref T2 1) 0.0
   (vref T2 m) 0.0
   (vref T2 (1- m)) (/ (vref D (1- m)) (vref B (1- m))))
    (let (IN)
      (loop for i from 2 to (- m 2)
   do (setf IN (- m i)
     (vref T2 IN) (/ (- (vref D IN)
          (* (vref C IN)
      (vref T2 (1+ IN))))
       (vref B IN)))))
    T2))

(defun spline-interpolate (V Temp vp)
  (let* ((m (length V))
  (T2 (derivative m V Temp))
  TP)
    (loop for i from 1 to (1- m)
 do (when (<= vp (vref V (1+ i)))
      (let ((S1 (- (vref V (1+ i)) (vref V i)))
     (S2 (- vp (vref V i)))
     (S3 (- (vref V (1+ i)) vp)))
        (setf TP (+ (/ (* (vref T2 i) S3 (- (/ (expt S3 2) S1) S1)) 6.0)
      (/ (* (vref T2 (1+ i)) S2 (- (/ (expt S2 2) S1) S1)) 6.0)
      (/ (* (vref Temp i) S3) S1)
      (/ (* (vref Temp (1+ i)) S2) S1)))
        (return))))
    TP))