From cefb7c3f5cd50c84bcedd94b5bc35197442c92e9 Mon Sep 17 00:00:00 2001
From: Liam Healy <liam@thinkpad.local>
Date: Wed, 18 Feb 2009 19:10:35 -0500
Subject: [PATCH] GSL features added in version 1.12; fix spelling

Added faster simplex mininimser using the symbol
+simplex-nelder-mead+; the old one is now called
+simplex-nelder-mead-on2+.  Added new functions #'order, #'size,
#'coefficients for Chebyshev; #'order is a generic function.
Added methods for vectors with complex elements for elt+, elt-, elt*,
elt/.  Fix spelling of "paraboloid".
---
 basis-splines.lisp                         |  5 +-
 chebyshev.lisp                             | 21 +++++-
 data/both.lisp                             | 14 ++--
 documentation/missing-features.text        | 13 ----
 init/defmfun-single.lisp                   |  8 +-
 init/mobject.lisp                          |  6 +-
 solve-minimize-fit/minimization-multi.lisp | 86 +++++++++++++++-------
 tests/minimization-multi.lisp              |  2 +-
 8 files changed, 101 insertions(+), 54 deletions(-)

diff --git a/basis-splines.lisp b/basis-splines.lisp
index ae3554eb..b08de23f 100644
--- a/basis-splines.lisp
+++ b/basis-splines.lisp
@@ -1,6 +1,6 @@
 ;; Basis splines.
 ;; Liam Healy 2008-02-18 14:43:20EST basis-splines.lisp
-;; Time-stamp: <2009-02-17 22:21:59EST basis-splines.lisp>
+;; Time-stamp: <2009-02-17 22:45:41EST basis-splines.lisp>
 ;; $Id$
 
 (in-package :gsl)
@@ -67,9 +67,10 @@
   :c-return sizet
   :gsl-version (1 9))
 
-(defmfun order (bspline)
+(defmfun order ((bspline basis-spline))
   "gsl_bspline_order"
   (((mpointer bspline) :pointer))
+  :definition :method
   :c-return sizet
   :gsl-version (1 9))
 
diff --git a/chebyshev.lisp b/chebyshev.lisp
index 85776c32..181c1b35 100644
--- a/chebyshev.lisp
+++ b/chebyshev.lisp
@@ -1,6 +1,6 @@
 ;; Chebyshev Approximations
 ;; Liam Healy Sat Nov 17 2007 - 20:36
-;; Time-stamp: <2009-02-15 11:23:40EST chebyshev.lisp>
+;; Time-stamp: <2009-02-17 22:52:51EST chebyshev.lisp>
 ;; $Id$
 
 (in-package :gsl)
@@ -23,6 +23,25 @@
   ((callback :pointer) (lower-limit :double) (upper-limit :double))
   :singular (function))
 
+(defmfun order ((object chebyshev))
+  "gsl_cheb_order"
+  (((mpointer object) :pointer))
+  :definition :method
+  :c-return sizet
+  :gsl-version (1 12))
+
+(defmfun size (chebyshev)
+  "gsl_cheb_size"
+  (((mpointer chebyshev) :pointer))
+  :c-return sizet
+  :gsl-version (1 12))
+
+(defmfun coefficients (chebyshev)
+  "gsl_cheb_coeffs"
+  (((mpointer chebyshev) :pointer))
+  :c-return sizet
+  :gsl-version (1 12))
+
 ;;;;****************************************************************************
 ;;;; Chebyshev series evaluation
 ;;;;****************************************************************************
diff --git a/data/both.lisp b/data/both.lisp
index 2881e76e..a964ede3 100644
--- a/data/both.lisp
+++ b/data/both.lisp
@@ -1,6 +1,6 @@
 ;; Functions for both vectors and matrices.
 ;; Liam Healy 2008-04-26 20:48:44EDT both.lisp
-;; Time-stamp: <2009-02-16 18:59:47EST both.lisp>
+;; Time-stamp: <2009-02-18 19:00:55EST both.lisp>
 ;; $Id$
 
 (in-package :gsl)
@@ -125,7 +125,7 @@
   ("gsl_" :category :type "_add")
   (((mpointer a) :pointer) ((mpointer b) :pointer))
   :definition :generic
-  :element-types :no-complex
+  :element-types #.(if (have-at-least-gsl-version '(1 12)) t :no-complex)
   :inputs (a b)
   :outputs (a)
   :return (a)
@@ -137,7 +137,7 @@
   ("gsl_" :category :type "_add_constant")
   (((mpointer a) :pointer) (x :double))
   :definition :methods
-  :element-types :no-complex
+  :element-types #.(if (have-at-least-gsl-version '(1 12)) t :no-complex)
   :inputs (a)
   :outputs (a)
   :return (a)
@@ -151,7 +151,7 @@
   ("gsl_" :category :type "_sub")
   (((mpointer a) :pointer) ((mpointer b) :pointer))
   :definition :generic
-  :element-types :no-complex
+  :element-types #.(if (have-at-least-gsl-version '(1 12)) t :no-complex)
   :inputs (a b)
   :outputs (a)
   :return (a)
@@ -163,7 +163,7 @@
   ("gsl_" :category :type "_mul")
   (((mpointer a) :pointer) ((mpointer b) :pointer))
   :definition :generic
-  :element-types :no-complex
+  :element-types #.(if (have-at-least-gsl-version '(1 12)) t :no-complex)
   :inputs (a b)
   :outputs (a)
   :return (a)
@@ -184,7 +184,7 @@
   ("gsl_" :category :type "_div")
   (((mpointer a) :pointer) ((mpointer b) :pointer))
   :definition :generic
-  :element-types :no-complex
+  :element-types #.(if (have-at-least-gsl-version '(1 12)) t :no-complex)
   :inputs (a b)
   :outputs (a)
   :return (a)
@@ -205,7 +205,7 @@
   ("gsl_" :category :type "_scale")
   (((mpointer a) :pointer) (x :double))
   :definition :methods
-  :element-types :no-complex
+  :element-types #.(if (have-at-least-gsl-version '(1 12)) t :no-complex)
   :inputs (a)
   :outputs (a)
   :return (a)
diff --git a/documentation/missing-features.text b/documentation/missing-features.text
index e0da973b..24a405ea 100644
--- a/documentation/missing-features.text
+++ b/documentation/missing-features.text
@@ -6,19 +6,6 @@ All file input and output (fread, fwrite) functions.
 All submatrix functions and views.
 Stride is always set to 1 in GSL functions that take a stride.
 
-Some things that have been added to GSL since version 1.11 that should
-be added to GSLL:
-
-GSL 1.12
-http://lists.gnu.org/archive/html/info-gsl/2008-12/msg00001.html
-** Added a faster simplex mininimser gsl_multimin_fminimizer_nmsimplex2
-   which is O(N) instead of O(N^2) [bug #24418]
-** Added new auxiliary functions gsl_cheb_order, gsl_cheb_size,
-   gsl_cheb_coeffs for Chebyshev series [bug #21830]
-** Added missing functions gsl_vector_complex_{isnonneg,add,sub,mul,
-   div,scale,add_constant} and gsl_matrix_complex_float_isnonneg [bug
-   #22478]
-
 *******************
 Wishlist
 Be able to set the real and imaginary parts of an array to a real
diff --git a/init/defmfun-single.lisp b/init/defmfun-single.lisp
index 5765cbdc..b60b1e1d 100644
--- a/init/defmfun-single.lisp
+++ b/init/defmfun-single.lisp
@@ -1,6 +1,6 @@
 ;; Helpers that define a single GSL function interface
 ;; Liam Healy 2009-01-07 22:02:20EST defmfun-single.lisp
-;; Time-stamp: <2009-02-16 22:24:39EST defmfun-single.lisp>
+;; Time-stamp: <2009-02-18 18:33:05EST defmfun-single.lisp>
 ;; $Id: $
 
 (in-package :gsl)
@@ -61,7 +61,7 @@
    (lambda (condition stream)
      (apply 'format stream
 	    "Function ~a (~a) is not available in the ~
-               ~%currently loaded releases ~a of GSL; it was introduced in release ~d.~d."
+               ~%currently loaded release ~a of GSL; it was introduced in release ~d.~d."
 	    (name condition)
 	    (gsl-name condition)
 	    *gsl-version*
@@ -115,8 +115,8 @@
 	     ,@(when (and name (not (defgeneric-method-p name)))
 		     (list name))
 	     ,@(when qualifier (list qualifier))
-	   (&rest args)
-	   (declare (ignore args))
+	   ,arglist
+	   (declare (ignore ,@(arglist-plain-and-categories arglist)))
 	   (error 'obsolete-gsl-version
 		  :name ',name :gsl-name ,gsl-name :gsl-version ',gsl-version)))))
 
diff --git a/init/mobject.lisp b/init/mobject.lisp
index 33b28db4..2b3e4adc 100644
--- a/init/mobject.lisp
+++ b/init/mobject.lisp
@@ -1,6 +1,6 @@
 ;; Definition of GSL objects and ways to use them.
 ;; Liam Healy, Sun Dec  3 2006 - 10:21
-;; Time-stamp: <2009-02-16 16:24:42EST mobject.lisp>
+;; Time-stamp: <2009-02-17 22:48:40EST mobject.lisp>
 
 ;;; GSL objects are represented in GSLL as and instance of a 'mobject.
 ;;; The macro demobject takes care of defining the appropriate
@@ -259,6 +259,10 @@
   (check-type object #.+foreign-pointer-type+)
   object)
 
+(export 'order)
+(defgeneric order (object)
+  (:documentation "The order of the GSL object."))
+
 ;;;;****************************************************************************
 ;;;; Making objects from existing objects
 ;;;;****************************************************************************
diff --git a/solve-minimize-fit/minimization-multi.lisp b/solve-minimize-fit/minimization-multi.lisp
index af94fff6..d0351ae0 100644
--- a/solve-minimize-fit/minimization-multi.lisp
+++ b/solve-minimize-fit/minimization-multi.lisp
@@ -1,13 +1,13 @@
 ;; Multivariate minimization.
 ;; Liam Healy  <Tue Jan  8 2008 - 21:28>
-;; Time-stamp: <2009-02-16 18:58:26EST minimization-multi.lisp>
+;; Time-stamp: <2009-02-18 18:18:13EST minimization-multi.lisp>
 ;; $Id$
 
 (in-package :gsl)
 
 ;;; /usr/include/gsl/gsl_multimin.h
 
-;;; In the parabaloid example, I notice that the consruct 
+;;; In the paraboloid example, I notice that the consruct 
 ;;; (min-test-gradient (mfdfminimizer-gradient minimizer) 1.0d-3)
 ;;; is constructing a CL vector-double-float (in mfdfminimizer-gradient) and
 ;;; then immediately pulling out the pointer (in min-test-gradient).  It
@@ -289,7 +289,7 @@
    use (larger values correspond to less accurate line searches)."
   :gsl-version (1 9))
 
-(defmpar +simplex-nelder-mead+
+(defmpar +simplex-nelder-mead-on2+
     "gsl_multimin_fminimizer_nmsimplex"
   ;; FDL
   "The Simplex algorithm of Nelder and Mead. It constructs 
@@ -316,7 +316,43 @@
    average distance from the geometrical center of the simplex to all its
    vertices.  This size can be used as a stopping criteria, as the simplex
    contracts itself near the minimum. The size is returned by the function
-   #'mfminimizer-size.")
+   #'mfminimizer-size.
+
+   This version is O(n^2).")
+
+(defmpar +simplex-nelder-mead+
+    "gsl_multimin_fminimizer_nmsimplex2"
+  ;; FDL
+  "The Simplex algorithm of Nelder and Mead. It constructs 
+   n vectors p_i from the
+   starting vector initial and the vector step-size as follows:
+   p_0 = (x_0, x_1, ... , x_n) 
+   p_1 = (x_0 + step_size_0, x_1, ... , x_n) 
+   p_2 = (x_0, x_1 + step_size_1, ... , x_n) 
+   ... = ...
+   p_n = (x_0, x_1, ... , x_n+step_size_n)
+   These vectors form the n+1 vertices of a simplex in n
+   dimensions.  On each iteration the algorithm tries to improve
+   the parameter vector p_i corresponding to the highest
+   function value by simple geometrical transformations.  These
+   are reflection, reflection followed by expansion, contraction and multiple
+   contraction. Using these transformations the simplex moves through 
+   the parameter space towards the minimum, where it contracts itself.  
+
+   After each iteration, the best vertex is returned.  Note, that due to
+   the nature of the algorithm not every step improves the current
+   best parameter vector.  Usually several iterations are required.
+
+   The routine calculates the minimizer specific characteristic size as the
+   average distance from the geometrical center of the simplex to all its
+   vertices.  This size can be used as a stopping criteria, as the simplex
+   contracts itself near the minimum. The size is returned by the function
+   #'mfminimizer-size.
+
+   This version is O(n); calculates the size of simplex as the rms
+   distance of each vertex from the center rather than the mean
+   distance, which has the advantage of allowing a linear update."
+  :gsl-version (1 12))
 
 ;;;;****************************************************************************
 ;;;; Examples
@@ -324,28 +360,28 @@
 
 ;;; Examples from Sec. 35.8.
 
-(defparameter *parabaloid-center* #(1.0d0 2.0d0))
+(defparameter *paraboloid-center* #(1.0d0 2.0d0))
 
 ;;; Example without derivatives taking scalars.
 
-(defun parabaloid-scalar (x y)
-  "A parabaloid function of two arguments, given in GSL manual Sec. 35.4.
+(defun paraboloid-scalar (x y)
+  "A paraboloid function of two arguments, given in GSL manual Sec. 35.4.
    This version takes scalar arguments."
-  (let ((dp0 (aref *parabaloid-center* 0))
-	(dp1 (aref *parabaloid-center* 1)))
+  (let ((dp0 (aref *paraboloid-center* 0))
+	(dp1 (aref *paraboloid-center* 1)))
     (+ (* 10 (expt (- x dp0) 2))
        (* 20 (expt (- y dp1) 2))
        30)))
 
-(make-callbacks multi-dimensional-minimizer-f parabaloid-scalar 2 t)
+(make-callbacks multi-dimensional-minimizer-f paraboloid-scalar 2 t)
 
 (defun multimin-example-no-derivative
-    (&optional (method +simplex-nelder-mead+) (print-steps t))
+    (&optional (method +simplex-nelder-mead-on2+) (print-steps t))
   (let ((step-size (make-marray 'double-float :dimensions 2)))
     (set-all step-size 1.0d0)
     (let ((minimizer
 	   (make-multi-dimensional-minimizer-f
-	    method 2 'parabaloid-scalar
+	    method 2 'paraboloid-scalar
 	    #m(5.0d0 7.0d0) step-size)))
       (loop with status = T and size
 	 for iter from 0 below 100
@@ -372,37 +408,37 @@
 ;;; accept the correct number of scalar double-floats, in which case
 ;;; the last argument to the make-callbacks form would be t.
 
-(defun parabaloid-vector (gsl-vector)
-  "A parabaloid function of two arguments, given in GSL manual Sec. 35.4.
+(defun paraboloid-vector (gsl-vector)
+  "A paraboloid function of two arguments, given in GSL manual Sec. 35.4.
    This version takes a vector-double-float argument."
   (let ((x (maref gsl-vector 0))
 	(y (maref gsl-vector 1))
-	(dp0 (aref *parabaloid-center* 0))
-	(dp1 (aref *parabaloid-center* 1)))
+	(dp0 (aref *paraboloid-center* 0))
+	(dp1 (aref *paraboloid-center* 1)))
     (+ (* 10 (expt (- x dp0) 2))
        (* 20 (expt (- y dp1) 2))
        30)))
 
-(defun parabaloid-derivative
+(defun paraboloid-derivative
     (arguments-gv-pointer derivative-gv-pointer)
   (let ((x (maref arguments-gv-pointer 0))
 	(y (maref arguments-gv-pointer 1))
-	(dp0 (aref *parabaloid-center* 0))
-	(dp1 (aref *parabaloid-center* 1)))
+	(dp0 (aref *paraboloid-center* 0))
+	(dp1 (aref *paraboloid-center* 1)))
     (setf (maref derivative-gv-pointer 0)
 	  (* 20 (- x dp0))
 	  (maref derivative-gv-pointer 1)
 	  (* 40 (- y dp1)))))
 
-(defun parabaloid-and-derivative (arguments-gv-pointer derivative-gv-pointer)
+(defun paraboloid-and-derivative (arguments-gv-pointer derivative-gv-pointer)
   (prog1
-      (parabaloid-vector arguments-gv-pointer)
-    (parabaloid-derivative
+      (paraboloid-vector arguments-gv-pointer)
+    (paraboloid-derivative
      arguments-gv-pointer derivative-gv-pointer)))
 
 (make-callbacks
  multi-dimensional-minimizer-fdf
- parabaloid-vector parabaloid-derivative parabaloid-and-derivative 2 nil)
+ paraboloid-vector paraboloid-derivative paraboloid-and-derivative 2 nil)
 
 (defun multimin-example-derivative
     (&optional (method +conjugate-fletcher-reeves+) (print-steps t))
@@ -410,7 +446,7 @@
 	 (minimizer
 	  (make-multi-dimensional-minimizer-fdf
 	   method 2
-	   '(parabaloid-vector parabaloid-derivative parabaloid-and-derivative)
+	   '(paraboloid-vector paraboloid-derivative paraboloid-and-derivative)
 	   initial 0.01d0 1.0d-4)))
     (loop with status = T
        for iter from 0 below 100
@@ -432,7 +468,7 @@
 	   (values (maref x 0) (maref x 1) (function-value minimizer)))))))
 
 (save-test minimization-multi
- (multimin-example-no-derivative +simplex-nelder-mead+ nil)
+ (multimin-example-no-derivative +simplex-nelder-mead-on2+ nil)
  (multimin-example-derivative +conjugate-fletcher-reeves+ nil)
  (multimin-example-derivative +conjugate-polak-ribiere+ nil)
  (multimin-example-derivative +vector-bfgs+ nil)
diff --git a/tests/minimization-multi.lisp b/tests/minimization-multi.lisp
index fbbfb25d..004d064f 100644
--- a/tests/minimization-multi.lisp
+++ b/tests/minimization-multi.lisp
@@ -7,7 +7,7 @@
                         (LIST 0.9920430849306285d0 1.9969168063253164d0
                               30.000823246638923d0)
                         (MULTIPLE-VALUE-LIST
-                         (MULTIMIN-EXAMPLE-NO-DERIVATIVE +SIMPLEX-NELDER-MEAD+
+                         (MULTIMIN-EXAMPLE-NO-DERIVATIVE +SIMPLEX-NELDER-MEAD-on2+
                                                          NIL)))
                        (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
                         (LIST 0.9999999999999997d0 2.0d0 30.0d0)
-- 
GitLab