1 ;;; -*- Mode: Lisp; Package: Maxima; Syntax: Common-Lisp; Base: 10 -*- ;;;;
2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3 ;;; The data in this file contains enhancments. ;;;;;
5 ;;; Copyright (c) 1984,1987 by William Schelter,University of Texas ;;;;;
6 ;;; All rights reserved ;;;;;
7 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8 ;;; (c) Copyright 1982 Massachusetts Institute of Technology ;;;
9 ;;; Original code by CFFK. Modified to interface correctly with TRANSL ;;;
10 ;;; and the rest of macsyma by GJC ;;;
11 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15 (macsyma-module rombrg
)
17 (load-macsyma-macros transm
)
19 (defmvar $rombergit
11 "the maximum number of iterations")
20 (defmvar $rombergmin
0 "the minimum number of iterations")
21 (defmvar $rombergtol
1e-4 "the relative tolerance of error")
22 (defmvar $rombergabs
0.0 "the absolute tolerance of error")
23 (defmvar $rombergit_used
0 "the number of iterations actually used.")
25 (defun romberg-subr (f left right
)
28 (tt (make-array $rombergit
:element-type
'flonum
))
29 (rr (make-array $rombergit
:element-type
'flonum
)))
30 (let (($numer t
) ($%enumer t
))
34 (if (not (and (numberp a
) (numberp b
)))
35 (return-from romberg-subr
(values nil a b
)))
40 (fab (funcall f
(* (+ b a
) 0.5))))
46 (return-from romberg-subr
(values nil a b
))
48 (setf (aref tt
0) (* x
(+ fb fa
) 0.5))
49 (setf (aref rr
0) (* x fab
)))))
57 (merror "`romberg' failed to converge"))
58 (declare (fixnum l m
))
59 (setq y
(float m
) z
(/ x y
))
60 (setf (aref tt l
) (* (+ (aref tt
(1- l
))
61 (aref rr
(1- l
))) 0.5))
62 (setf (aref rr l
) 0.0)
66 ((fzi+a
(funcall f
(+ (* z
(float i
)) a
))))
67 (if (not (numberp fzi
+a
))
68 (return-from romberg-subr
(values nil a b
))
69 (setf (aref rr l
) (+ fzi
+a
(aref rr l
))))))
71 (setf (aref rr l
) (* z
(aref rr l
) 2))
73 (do ((k l
(1- k
))) ((= k
0))
75 (setq y
(+ (* y
4) 3))
76 (setf (aref tt
(1- k
))
80 (setf (aref rr
(1- k
))
81 (+ (/ (- (aref rr k
) (aref rr
(1- k
))) y
)
83 (setq y
(* (+ (aref tt
0) (aref rr
0)) 0.5))
84 ;;; this is the WIN condition test.
85 (cond ((and (or (not (< $rombergabs
86 (setq cerr
(abs (- (aref tt
0) (aref rr
0))))))
88 ;; cerr = "calculated error"; used for ^]
89 (setq cerr
(/ cerr
(if (zerop y
) 1.0 (abs y
)))))))
91 (setq $rombergit_used l
)
92 (return-from romberg-subr
(values y nil nil
)))))))
94 (defun $romberg
(&rest args
)
99 ;; BIND EVIL SPECIAL VARIABLE *PLOT-REALPART* HERE ...
100 (let (($numer t
) ($%enumer t
) (*plot-realpart
* nil
))
102 (coerce-float-fun (first args
))
107 `(($romberg
) ,(first args
) ,left
,right
))))
109 (when ($constantp
(second args
))
111 "romberg: variable of integration cannot be a constant; found ~M"
115 ;; BIND EVIL SPECIAL VARIABLE *PLOT-REALPART* HERE ...
116 (let (($numer t
) ($%enumer t
) (*plot-realpart
* nil
))
118 (coerce-float-fun (first args
) `((mlist) ,(second args
)))
123 `(($romberg
) ,(first args
) ,(second args
) ,left
,right
))))
125 (wna-err '$romberg
))))