intervals.... more



here's a sketch of a working (but incomplete) interval evaluator.
More stuff is needed from my generic arithmetic package, on my web page..


#| a Maxima interpreter for intervals |#

(in-package :ri)			; real intervals

(defun maxima::$IEVAL(expr)(ieval (meval expr)))

(defun ieval(e)
  
  (cond ((realp e) (widen-ri e e)) ;3.0 -> [3-eps,3+eps]
	
	((atom e) 
	 (error "IEVAL cannot handle ~s" e))
	(t (case 
	       (caar e) 

	   (maxima::MPLUS 
	    (cond ((null (cdr e)) 0)
		  ((null (cddr e))(ieval (cadr e)))
		  (t  (+ (ieval (cadr e)) ;this + is a real-interval +
			 (ieval (cons (car e) (cddr e)))))))
	   (maxima::MTIMES
	    (cond ((null (cdr e)) 0)
		  ((null (cddr e))(ieval (cadr e)))
		  (t  (* (ieval (cadr e)) ; this * is a real-interval *
			 (ieval (cons (car e) (cddr e)))))))
	   (maxima:: MLIST
		     ;; make a real interval, a structure of type ri
		     ;; check it is a list of 2 items
		     ;; both numbers, in order, 
		     (let ((a (second e))(b (third e)))
		       (if (and (realp a)
				(realp b)  ;; optional? (<= a b)
				(null(cdddr e)))
			   (widen-ri (cadr e)(caddr e))
			 (error "can't convert ~s to interval")))
	   (otherwise
	    ;; look on property list of (car e) 
	    ;; to see if it has an ieval property. eg.
	    (if (setf fn (get (caar e) 
			      'ieval))
		(apply fn (mapcar #'ieval (cdr e)))
	      (error "IEVAL cannot handle ~s" e)))))))


(setf (get '$includes 'ieval) #'include-ri)
(setf (get '$intersects 'ieval) #'intersect-ri)
(setf (get '$min 'ieval) #'(lambda(x)(ri-lo x)))
(setf (get '$max 'ieval) #'(lambda(x)(ri-hi x)))

(setf (get '$sin 'ieval) #'intsin) ;; etc etc

(defun maxima::$RealInterval(a b )(ri a b))

;; etc