Function: math-brent-min

math-brent-min is a byte-compiled function defined in calcalg3.el.gz.

Signature

(math-brent-min EXPR PREC A VA X VX B VB)

Source Code

;; Defined in /usr/src/emacs/lisp/calc/calcalg3.el.gz
;;; "brent"
(defun math-brent-min (expr prec a _va x vx b _vb)
  (let ((iters (+ 20 (* 5 prec)))
	(w x)
	(vw vx)
	(v x)
	(vv vx)
	(tol (list 'float 1 (- -1 prec)))
	(zeps (list 'float 1 (- -5 prec)))
	(e '(float 0 0))
	d u vu xm tol1 tol2 etemp p q r xv xw)
    (while (progn
	     (setq xm (math-mul-float '(float 5 -1)
				      (math-add-float a b))
		   tol1 (math-add-float
			 zeps
			 (math-mul-float tol (math-abs x)))
		   tol2 (math-mul-float tol1 '(float 2 0)))
	     (math-lessp-float (math-sub-float tol2
					       (math-mul-float
						'(float 5 -1)
						(math-sub-float b a)))
			       (math-abs (math-sub-float x xm))))
      (if (= (setq iters (1- iters)) 0)
	  (math-reject-arg nil (format "*Unable to converge on a %s"
				       math-min-or-max)))
      (math-working "brent" x)
      (if (math-lessp-float (math-abs e) tol1)
	  (setq e (if (math-lessp-float x xm)
		      (math-sub-float b x)
		    (math-sub-float a x))
		d (math-mul-float '(float 381966 -6) e))
	(setq xw (math-sub-float x w)
	      r (math-mul-float xw (math-sub-float vx vv))
	      xv (math-sub-float x v)
	      q (math-mul-float xv (math-sub-float vx vw))
	      p (math-sub-float (math-mul-float xv q)
				(math-mul-float xw r))
	      q (math-mul-float '(float 2 0) (math-sub-float q r)))
	(if (math-posp q)
	    (setq p (math-neg-float p))
	  (setq q (math-neg-float q)))
	(setq etemp e
	      e d)
	(if (and (math-lessp-float (math-abs p)
				   (math-abs (math-mul-float
					      '(float 5 -1)
					      (math-mul-float q etemp))))
		 (math-lessp-float (math-mul-float
				    q (math-sub-float a x)) p)
		 (math-lessp-float p (math-mul-float
				      q (math-sub-float b x))))
	    (progn
	      (setq d (math-div-float p q)
		    u (math-add-float x d))
	      (if (or (math-lessp-float (math-sub-float u a) tol2)
		      (math-lessp-float (math-sub-float b u) tol2))
		  (setq d (if (math-lessp-float xm x)
			      (math-neg-float tol1)
			    tol1))))
	  (setq e (if (math-lessp-float x xm)
		      (math-sub-float b x)
		    (math-sub-float a x))
		d (math-mul-float '(float 381966 -6) e))))
      (setq u (math-add-float x
			      (if (math-lessp-float (math-abs d) tol1)
				  (if (math-negp d)
				      (math-neg-float tol1)
				    tol1)
				d))
	    vu (math-min-eval expr u))
      (if (math-lessp-float vx vu)
	  (progn
	    (if (math-lessp-float u x)
		(setq a u)
	      (setq b u))
	    (if (or (equal w x)
		    (not (math-lessp-float vw vu)))
		(setq v w  vv vw
		      w u  vw vu)
	      (if (or (equal v x)
		      (equal v w)
		      (not (math-lessp-float vv vu)))
		  (setq v u  vv vu))))
	(if (math-lessp-float u x)
	    (setq b x)
	  (setq a x))
	(setq v w  vv vw
	      w x  vw vx
	      x u  vx vu)))
    (list 'vec x vx)))