diff -Nru yorick-optimpack-1.3.2+dfsg/AUTHORS yorick-optimpack-1.3.2+dfsg+1.4.0/AUTHORS --- yorick-optimpack-1.3.2+dfsg/AUTHORS 2007-07-06 22:57:25.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/AUTHORS 2017-01-10 22:16:57.000000000 +0000 @@ -1 +1 @@ -Eric Thiébaut (Observatoire de Lyon, France) +Eric Thiébaut (Centre de Recherche Astrophysique de Lyon, France) diff -Nru yorick-optimpack-1.3.2+dfsg/debian/changelog yorick-optimpack-1.3.2+dfsg+1.4.0/debian/changelog --- yorick-optimpack-1.3.2+dfsg/debian/changelog 2012-06-28 12:07:26.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/debian/changelog 2017-01-16 15:46:00.000000000 +0000 @@ -1,3 +1,10 @@ +yorick-optimpack (1.3.2+dfsg+1.4.0-1) unstable; urgency=low + + * New upstream release + * Provide both the old OptimPack1 and the new optimpacklegacy interface. + + -- Thibaut Paumard Mon, 16 Jan 2017 16:46:00 +0100 + yorick-optimpack (1.3.2+dfsg-1) unstable; urgency=low * New upstream diff -Nru yorick-optimpack-1.3.2+dfsg/debian/check.i yorick-optimpack-1.3.2+dfsg+1.4.0/debian/check.i --- yorick-optimpack-1.3.2+dfsg/debian/check.i 2012-06-28 11:49:45.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/debian/check.i 2017-01-16 15:44:02.000000000 +0000 @@ -1,4 +1,7 @@ -plug_dir,_(".", plug_dir()); -#include "OptimPack1-test.i" +plug_dir,_("./yorick", "optimpack1/yorick", plug_dir()); +set_path, "./yorick:optimpack1/yorick:"+get_path(); +#include "yorick/optimpacklegacy-tests.i" +#include "optimpack1/yorick/OptimPack1-test.i" +for (i=1;i<=18;++i) opl_test_um, prob=i, method=0, verb=1; for (i=1;i<=18;++i) op_test_um, prob=i, method=0, verb=1; quit; diff -Nru yorick-optimpack-1.3.2+dfsg/debian/compat yorick-optimpack-1.3.2+dfsg+1.4.0/debian/compat --- yorick-optimpack-1.3.2+dfsg/debian/compat 2012-06-28 11:49:45.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/debian/compat 2017-01-16 15:44:02.000000000 +0000 @@ -1 +1 @@ -7 +9 diff -Nru yorick-optimpack-1.3.2+dfsg/debian/control yorick-optimpack-1.3.2+dfsg+1.4.0/debian/control --- yorick-optimpack-1.3.2+dfsg/debian/control 2012-06-28 11:58:09.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/debian/control 2017-01-16 15:46:00.000000000 +0000 @@ -2,17 +2,17 @@ Section: science Priority: extra Maintainer: Debian Science Maintainers -Uploaders: Thibaut Paumard -DM-Upload-Allowed: yes -Build-Depends: debhelper (>= 7.0.50~), yorick-dev (>= 2.1.05+dfsg-2~bpo40+1) -Standards-Version: 3.9.3 -Vcs-Git: git://git.debian.org/git/debian-science/packages/yorick-optimpack.git -Vcs-Browser: http://git.debian.org/?p=debian-science/packages/yorick-optimpack.git -Homepage: http://www-obs.univ-lyon1.fr/labo/perso/eric.thiebaut/optimpack.html +Uploaders: Thibaut Paumard +Build-Depends: debhelper (>= 9), yorick-dev (>= 2.1.05+dfsg-2~bpo40+1) +Standards-Version: 3.9.8 +Vcs-Git: https://anonscm.debian.org/git/debian-science/packages/yorick-optimpack.git +Vcs-Browser: https://anonscm.debian.org/git/debian-science/packages/yorick-optimpack.git +Homepage: https://cral.univ-lyon1.fr/labo/perso/eric.thiebaut/?Software/OptimPack Package: yorick-optimpack Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, yorick (>= 1.6.02) +Provides: yorick-optimpacklegacy Description: optimization of large scale problems for the Yorick language OptimPack is a portable C library which implements algorithms for optimization of large scale problems with bound constraints. Large @@ -24,4 +24,6 @@ with Moré & Thuente inexact line search and gradient projection to account for bounds. . - This package contains a Yorick plug-in based on OptimPack. \ No newline at end of file + This package contains two Yorick plug-ins: one based on the newer + OptimPackLegacy version and, for backward compatibility, one based on the + previous OptimPack1 implementation. diff -Nru yorick-optimpack-1.3.2+dfsg/debian/docs yorick-optimpack-1.3.2+dfsg+1.4.0/debian/docs --- yorick-optimpack-1.3.2+dfsg/debian/docs 2012-06-28 11:49:45.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/debian/docs 2017-01-16 15:44:02.000000000 +0000 @@ -1,2 +1,2 @@ -NEWS -TODO +NEWS.md +TODO.md diff -Nru yorick-optimpack-1.3.2+dfsg/debian/examples yorick-optimpack-1.3.2+dfsg+1.4.0/debian/examples --- yorick-optimpack-1.3.2+dfsg/debian/examples 2012-06-28 11:49:45.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/debian/examples 2017-01-16 15:44:02.000000000 +0000 @@ -1 +1 @@ -yorick/OptimPack1-test.i +yorick/optimpacklegacy-tests.i diff -Nru yorick-optimpack-1.3.2+dfsg/debian/optimpack.info yorick-optimpack-1.3.2+dfsg+1.4.0/debian/optimpack.info --- yorick-optimpack-1.3.2+dfsg/debian/optimpack.info 2012-06-28 11:49:45.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/debian/optimpack.info 2017-01-16 15:46:00.000000000 +0000 @@ -1,6 +1,6 @@ Package: optimpack Kind: plugin -Version: 1.3 +Version: 1.4.0 Description: optimization of large scale problems License: GPL Author: Eric Thiebault diff -Nru yorick-optimpack-1.3.2+dfsg/debian/patches/configure yorick-optimpack-1.3.2+dfsg+1.4.0/debian/patches/configure --- yorick-optimpack-1.3.2+dfsg/debian/patches/configure 2012-06-28 11:49:45.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/debian/patches/configure 2017-01-16 15:44:02.000000000 +0000 @@ -3,15 +3,34 @@ which modifies Makefile. Modifying source files at build time is not very well supported in the quilt / git workflow, so let's just patch Makefile and not run yorick -batch make.i at build time. + Likewise let's configure the library build the same way. Author: Thibaut Paumard Origin: Vendor Forwarded: not-needed -Last-Update: 2012-06-27 +Last-Update: 2017-01-07 --- This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ --- a/yorick/Makefile +++ b/yorick/Makefile -@@ -27,11 +27,12 @@ +@@ -30,11 +30,11 @@ + + # ---------------------------------------------------------------- Yorick setup + # these values filled in by `yorick -batch make.i` +-Y_MAKEDIR= +-Y_EXE= ++Y_MAKEDIR=/usr/lib/yorick ++Y_EXE=/usr/lib/yorick/bin/yorick + Y_EXE_PKGS= +-Y_EXE_HOME= +-Y_EXE_SITE= ++Y_EXE_HOME=/usr/lib/yorick ++Y_EXE_SITE=/usr/lib/yorick + Y_HOME_PKG= + + # ---------------------------------------------------------- optimization flags +--- a/optimpack1/yorick/Makefile ++++ b/optimpack1/yorick/Makefile +@@ -27,11 +27,11 @@ # ---------------------------------------------------------------- Yorick setup # these values filled in by yorick -batch make.i @@ -24,7 +43,32 @@ -Y_EXE_SITE=/usr/local/libexec/yorick +Y_EXE_HOME=/usr/lib/yorick +Y_EXE_SITE=/usr/lib/yorick -+Y_HOME_PKG= # ---------------------------------------------------------- optimization flags +--- a/src/Makefile ++++ b/src/Makefile +@@ -33,8 +33,8 @@ + INSTALL = cp -p + + CC = gcc -pipe +-#CPPFLAGS = -I. -DOP_INTEGER=long -DOP_LOGICAL=int +-CPPFLAGS = -I. ++CPPFLAGS = -I. -DOP_INTEGER=long -DOP_LOGICAL=int ++#CPPFLAGS = -I. + CFLAGS = -O2 -Wall + + RM = rm -f +--- a/optimpack1/Makefile ++++ b/optimpack1/Makefile +@@ -2,8 +2,8 @@ + INSTALL=cp -p + + CC = gcc -pipe +-#CPPFLAGS = -I. -DOP_INTEGER=long -DOP_LOGICAL=int +- CPPFLAGS = -I. ++ CPPFLAGS = -I. -DOP_INTEGER=long -DOP_LOGICAL=int ++#CPPFLAGS = -I. + CFLAGS = -O2 -Wall + + RM = rm -f diff -Nru yorick-optimpack-1.3.2+dfsg/debian/patches/makefile-configure yorick-optimpack-1.3.2+dfsg+1.4.0/debian/patches/makefile-configure --- yorick-optimpack-1.3.2+dfsg/debian/patches/makefile-configure 2012-06-28 11:49:45.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/debian/patches/makefile-configure 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -Author: Thibaut Paumard -Description: Configure the package by editing the Makefile -Forwarded: not-needed - ---- a/Makefile -+++ b/Makefile -@@ -2,8 +2,8 @@ - INSTALL=cp -p - - CC = gcc -pipe --#CPPFLAGS = -I. -DOP_INTEGER=long -DOP_LOGICAL=int -- CPPFLAGS = -I. -+ CPPFLAGS = -I. -DOP_INTEGER=long -DOP_LOGICAL=int -+#CPPFLAGS = -I. - CFLAGS = -O2 -Wall - - RM = rm -f diff -Nru yorick-optimpack-1.3.2+dfsg/debian/patches/series yorick-optimpack-1.3.2+dfsg+1.4.0/debian/patches/series --- yorick-optimpack-1.3.2+dfsg/debian/patches/series 2012-06-28 11:49:45.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/debian/patches/series 2017-01-16 15:44:02.000000000 +0000 @@ -1,2 +1 @@ configure -makefile-configure diff -Nru yorick-optimpack-1.3.2+dfsg/debian/README.source yorick-optimpack-1.3.2+dfsg+1.4.0/debian/README.source --- yorick-optimpack-1.3.2+dfsg/debian/README.source 2012-06-28 11:49:45.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/debian/README.source 2017-01-16 15:46:00.000000000 +0000 @@ -15,4 +15,8 @@ in the Debian package and some have a dubious copyright statement, presumably non-DFSG. - -- Thibaut Paumard , Wed, 27 Jun 2012 14:59:23 +0200 +Staring January 2017, the main source code is actually optimpacklegacy from +https://github.com/emmt/OptimPackLegacy. The previous, coinstallable version is +included in the optimpack1 subdirectory. + + -- Thibaut Paumard , Mon, 16 Jan 2017 17:51:23 +0100 diff -Nru yorick-optimpack-1.3.2+dfsg/debian/rules yorick-optimpack-1.3.2+dfsg+1.4.0/debian/rules --- yorick-optimpack-1.3.2+dfsg/debian/rules 2012-06-28 11:59:38.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/debian/rules 2017-01-16 15:44:02.000000000 +0000 @@ -12,20 +12,26 @@ $(MAKE) COPT_DEFAULT="" \ Y_CFLAGS="$(CFLAGS) $(CPPFLAGS)" \ Y_LDFLAGS="$(LDFLAGS)" + cd optimpack1; $(MAKE) CPPFLAGS="$(CPPFLAGS)" CFLAGS="$(CFLAGS)" + cd optimpack1/yorick; \ + $(MAKE) COPT_DEFAULT="" \ + Y_CFLAGS="$(CFLAGS) $(CPPFLAGS)" \ + Y_LDFLAGS="$(LDFLAGS)" override_dh_auto_test: ifeq (,$(filter nocheck, $(DEB_BUILD_OPTIONS))) - cd yorick; yorick -batch ../debian/check.i + yorick -batch debian/check.i endif override_dh_auto_install: dh_installyorick --no-make-install override_dh_clean: - dh_clean --exclude=yorick/OptimPack1-test.out.orig + dh_clean --exclude=optimpack1/yorick/OptimPack1-test.out.orig override_dh_auto_clean: - $(MAKE) Y_MAKEDIR=/usr/lib/yorick Y_EXE=/usr/bin/yorick clean + $(MAKE) Y_MAKEDIR=/usr/lib/yorick Y_EXE=/usr/bin/yorick clean + cd optimpack1; $(MAKE) Y_MAKEDIR=/usr/lib/yorick Y_EXE=/usr/bin/yorick clean rm -f yorick/OptimPack1-test.out overrides_dh_installdocs: diff -Nru yorick-optimpack-1.3.2+dfsg/debian/watch yorick-optimpack-1.3.2+dfsg+1.4.0/debian/watch --- yorick-optimpack-1.3.2+dfsg/debian/watch 2012-06-28 11:49:45.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/debian/watch 2017-01-16 15:46:00.000000000 +0000 @@ -1,4 +1,3 @@ -version=3 -opts=dversionmangle=s/\+dfsg\d$// \ - http://www-obs.univ-lyon1.fr/labo/perso/eric.thiebaut/optimpack.html \ - files/OptimPack-(.*).tar.bz2 \ No newline at end of file +version=4 +opts="dversionmangle=s/1.3.\d\+dfsg\+//, uversionmangle=s/-pre/~pre/, filenamemangle=s/.+\/release-?(\d\S+)\.tar\.gz/yorick-optimpack-$1\.tar\.gz/" \ + https://github.com/emmt/OptimpackLegacy/tags .*/release-(\d\S+)\.tar\.gz diff -Nru yorick-optimpack-1.3.2+dfsg/debian/ynstall yorick-optimpack-1.3.2+dfsg+1.4.0/debian/ynstall --- yorick-optimpack-1.3.2+dfsg/debian/ynstall 2012-06-28 12:05:25.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/debian/ynstall 2017-01-16 15:46:00.000000000 +0000 @@ -1,8 +1,13 @@ -#yorick/lbfgs*.i -#yorick/op_deconv.i -yorick/OptimPack1.i i0 +yorick/optimpacklegacy.i i0 +optimpack1/yorick/OptimPack1.i i0 + yorick/*.so +optimpack1/yorick/*.so + debian/yorick-optimpack.packinfo debian/optimpack.info -debian/OptimPack1-auto.i i-start + +debian/OptimPack1-auto.i i-start +yorick/optimpacklegacy-start.i i-start + debian/lintian-overrides.d/* usr/share/lintian/overrides diff -Nru yorick-optimpack-1.3.2+dfsg/debian/yorick-optimpack.packinfo yorick-optimpack-1.3.2+dfsg+1.4.0/debian/yorick-optimpack.packinfo --- yorick-optimpack-1.3.2+dfsg/debian/yorick-optimpack.packinfo 2012-06-28 11:49:45.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/debian/yorick-optimpack.packinfo 2017-01-16 15:44:02.000000000 +0000 @@ -2,4 +2,7 @@ OptimPack: optimization of large scale problems :OptimPack1 -optimization algorithms for problems with many variables +optimization algorithms for problems with many variables (old version) + +:optimpacklegacy +optimization algorithms for problems with many variables (more recent version) diff -Nru yorick-optimpack-1.3.2+dfsg/.dir-locals.el yorick-optimpack-1.3.2+dfsg+1.4.0/.dir-locals.el --- yorick-optimpack-1.3.2+dfsg/.dir-locals.el 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/.dir-locals.el 2017-01-10 22:16:57.000000000 +0000 @@ -0,0 +1,14 @@ +((nil . ((indent-tabs-mode . nil) + (tab-width . 8) + (fill-column . 79) + (ispell-local-dictionary . "american"))) + (c-mode . ((c-file-style . "bsd") + (c-basic-offset . 2))) + (java-mode . ((c-basic-offset . 4))) + (julia-mode . ()) + (makefile-gmake-mode . ((indent-tabs-mode . t))) + (sh-mode . ((sh-basic-offset . 4))) + (tcl-mode . ((tcl-default-application . "wish") + (tcl-indent-level . 2))) + (yorick-mode . ((c-basic-offset . 2))) +) diff -Nru yorick-optimpack-1.3.2+dfsg/.gitignore yorick-optimpack-1.3.2+dfsg+1.4.0/.gitignore --- yorick-optimpack-1.3.2+dfsg/.gitignore 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/.gitignore 2017-01-10 22:16:57.000000000 +0000 @@ -0,0 +1,16 @@ +*~ +*.bak +*.o +*.lo +*.la +lib*.a +*.so +*.dll +*.tar.gz +*.txz +*.tar.bz2 +*.zip +*.log +yorick/ywrap.c +RCS/ +devel/ diff -Nru yorick-optimpack-1.3.2+dfsg/Makefile yorick-optimpack-1.3.2+dfsg+1.4.0/Makefile --- yorick-optimpack-1.3.2+dfsg/Makefile 2010-07-05 20:41:47.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/Makefile 2017-01-10 22:16:57.000000000 +0000 @@ -1,56 +1,115 @@ - PREFIX= - INSTALL=cp -p - - CC = gcc -pipe -#CPPFLAGS = -I. -DOP_INTEGER=long -DOP_LOGICAL=int - CPPFLAGS = -I. - CFLAGS = -O2 -Wall - - RM = rm -f - AR = ar - ARFLAGS = rv - - LIBNAME = liboptimpack.a - VERSION = 1.0 - OBJS = op_lnsrch.o op_utils.o op_vmlmb.o - DIRS = yorick idl - -all: $(LIBNAME) -install: $(LIBNAME) - @if [ "x$(PREFIX)" = "x" ]; then \ - echo "You must define PREFIX macro, e.g.:"; \ - echo " > make PREFIX=/usr/local install"; \ - else \ - [ -d "$(PREFIX)/lib" ] || mkdir -p "$(PREFIX)/lib"; \ - $(INSTALL) $(LIBNAME) "$(PREFIX)/lib/."; \ - [ -d "$(PREFIX)/include" ] || mkdir -p "$(PREFIX)/include"; \ - $(INSTALL) optimpack.h "$(PREFIX)/include/."; \ - [ -d "$(PREFIX)/doc/OptimPack-$(VERSION)" ] || \ - mkdir -p "$(PREFIX)/doc/OptimPack-$(VERSION)"; \ - $(INSTALL) README AUTHORS LICENSE optimpack.h \ - "$(PREFIX)/doc/OptimPack-$(VERSION)/."; \ - fi +# +# Makefile -- +# +# Makefile for OptimPackLegacy. +# +#------------------------------------------------------------------------------ +# +# Copyright (c) 2003, 2016 Éric Thiébaut. +# +# This file is part of OptimPack . +# +# OptimPack is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# OptimPack is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with OptimPack (file "LICENSE" in the top source directory); if not, +# write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, +# Boston, MA 02111-1307 USA +# +#------------------------------------------------------------------------------ + +srcdir = . + +VERSION = `sed < VERSION -e 's/ //g'` +SUBDIRS = yorick idl src + +DISTRIB_SRC = $(srcdir) +DISTRIB_FILES = AUTHORS LICENSE Makefile NEWS.md README.md TODO.md \ + optimpack.bib + +CODE_SRC = $(srcdir)/src +CODE_FILES = opl_algebra.c opl_lnsrch.c opl_vmlmb.c opl_utils.c \ + opl_limits.h opl_private.h optimpacklegacy.h + +YORICK_SRC = $(srcdir)/yorick +YORICK_FILES = Makefile opl_yorick.c optimpacklegacy.i \ + optimpacklegacy-start.i \ + optimpacklegacy-tests.i optimpacklegacy-tests.out + +all: + @echo "No default target" + +distrib: + @version=$(VERSION); \ + if test "x$$version" = "x"; then \ + echo >&2 "bad VERSION"; \ + return 1; \ + fi; \ + pkgdir=OptimPackLegacy-$$version; \ + archive=$$pkgdir.tar.bz2; \ + if test -e "$$pkgdir"; then \ + echo >&2 "error: $$pkgdir already exists"; \ + return 1; \ + fi; \ + if test -e "$$archive"; then \ + echo >&2 "error: $$archive already exists"; \ + return 1; \ + fi; \ + dstdir=$$pkgdir/yorick; \ + mkdir -p "$$dstdir"; \ + chmod 755 "$$dstdir"; \ + for file in $(YORICK_FILES); do \ + src=$(YORICK_SRC)/$$file; \ + dst=$$dstdir/$$file; \ + cp -p "$$src" "$$dst"; \ + chmod 644 "$$dst"; \ + done; \ + dstdir=$$pkgdir; \ + mkdir -p "$$dstdir"; \ + chmod 755 "$$dstdir"; \ + for file in $(DISTRIB_FILES); do \ + src=$(DISTRIB_SRC)/$$file; \ + dst=$$dstdir/$$file; \ + cp -p "$$src" "$$dst"; \ + chmod 644 "$$dst"; \ + done; \ + dst=$$dstdir/VERSION; \ + echo "$$version" >"$$dst"; \ + chmod 644 "$$dst"; \ + dstdir=$$pkgdir/src; \ + mkdir -p "$$dstdir"; \ + chmod 755 "$$dstdir"; \ + for file in $(CODE_FILES); do \ + src=$(CODE_SRC)/$$file; \ + dst=$$dstdir/$$file; \ + cp -p "$$src" "$$dst"; \ + chmod 644 "$$dst"; \ + done; \ + tar cf - "$$pkgdir" | bzip2 -9 > "$$archive"; \ + rm -rf "$$pkgdir"; \ + echo "archive $$archive created"; \ + return 0 clean: - $(RM) *~ $(OBJS) $(LIBNAME) - for dir in $(DIRS); do \ + $(RM) *~ + for dir in $(SUBDIRS); do \ if [ -f "$$dir/Makefile" ]; then \ (cd $$dir; make clean); \ fi; \ done distclean: clean - $(RM) $(LIBNAME) + for dir in $(SUBDIRS); do \ + if [ -f "$$dir/Makefile" ]; then \ + (cd $$dir; make distclean); \ + fi; \ + done -$(LIBNAME): $(OBJS) - $(RM) $(LIBNAME) - $(AR) $(ARFLAGS) $(LIBNAME) $(OBJS) - -op_lnsrch.o: op_lnsrch.c optimpack.h - $(CC) $(CFLAGS) $(CPPFLAGS) -c $(@:.o=.c) -o $@ -op_vmlmb.o: op_vmlmb.c optimpack.h - $(CC) $(CFLAGS) $(CPPFLAGS) -c $(@:.o=.c) -o $@ -op_cgmnb.o: op_cgmnb.c optimpack.h - $(CC) $(CFLAGS) $(CPPFLAGS) -c $(@:.o=.c) -o $@ -op_utils.o: op_utils.c optimpack.h - $(CC) $(CFLAGS) $(CPPFLAGS) -c $(@:.o=.c) -o $@ diff -Nru yorick-optimpack-1.3.2+dfsg/NEWS yorick-optimpack-1.3.2+dfsg+1.4.0/NEWS --- yorick-optimpack-1.3.2+dfsg/NEWS 2010-07-05 21:00:18.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/NEWS 1970-01-01 00:00:00.000000000 +0000 @@ -1,63 +0,0 @@ -------------------------------------------------------------------------------- - -2010-05-07: - * OptimPack-1.3.2 released. - * Makefile fixed thanks to Michael Williamson. - -------------------------------------------------------------------------------- - -2009-09-23: - * OptimPack-1.3.1 released. - * Bugs fixed in Yorick interface with the size of workspace arrays - ISAVE and DSAVE. - -------------------------------------------------------------------------------- - -2009-05-14: - OptimPack-1.3 released. - -2008-02-07: - - * FMIN is now an optional parameter. Functions op_get/set_fmin - and op_vmlmb_first have changed. Accordingly, the Yorick - interface have changed. - - * IDL interface needs to be updated... - -------------------------------------------------------------------------------- - -2008-01-31: - OptimPack-1.2 released. - -------------------------------------------------------------------------------- - -2008-01-30: - OptimPack-1.1 released. - -2007-06-27: - - * Yorick interface to OptimPack reworked. - - * In IDL interface, some fixes by Laurent Mugnier: - - syntax errors in op_vmlmb_msg.pro; - - bugs in parsing of arguments in op_idl.c (function - op_idl_vmlmb_next). - - * New function fmin_op in directory 'idl/contrib' by Laurent - Mugnier (license is CeCILL not GPL). - - * GNU Public License updated. - - -2006-04-26: - - Integrate changes made by Laurent Mugnier (thanks to him!) - in IDL interface to support for Linux and 64 bit machines. - -------------------------------------------------------------------------------- - -2003-04-22: - - OptimPack-1.0 released. - -------------------------------------------------------------------------------- diff -Nru yorick-optimpack-1.3.2+dfsg/NEWS.md yorick-optimpack-1.3.2+dfsg+1.4.0/NEWS.md --- yorick-optimpack-1.3.2+dfsg/NEWS.md 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/NEWS.md 2017-01-10 22:16:57.000000000 +0000 @@ -0,0 +1,94 @@ +## Version 1.4.0 (2017-01-10) + +* VMLMB workspace is now a single opaque handle. All needed data can be saved + in a single block of memory (*monolithic* workspace) provided by the caller + or allocated by the library (and possibly split in small blocks). This + simplifies the use of VMLMB both in C and in other programming languages + and add flexibility for very large problems. + +* In case of early stopping (i.e., during a line search), it is now posible to + restore the variables at the start of the line search. This is expected to + be nearly the best ones so far. + +* Rewrite VMLMB code for better readability, to remove unecessary variables and + avoid unecessary computations. This also fixes some inconsistencies. Opaque + structures are now used instead of arrays of values, hopefully not to the + detriment of portability. + +* IDL port has been temporarily removed (will be back soon). + + +## Version 1.3.3 (2016-12-13) + +* Parameter `delta > 0` is used to specify a relative small step size. + +* Parameter `epsilon ≥ 0` is used to check for the sufficient descent + condition. Seems to speed up convergence in many cases. + +* In Yorick interface: + + - The norm of the *projected* gradient is displayed and used to check for the + convergence when there are bounds. + + - New `op_vmlmb` interface in Yorick which controls the convergence based on + the gradient via keywords `gatol` and `grtol`. + + - The `op_mnb` driver is deprecated in favor of `op_vmlmb`. + + - By default, the best solution found so far is returned by `op_vmlmb` (see + keyword `savebest`). convergence when there are bounds. + +* Code cleanup: get rid of non-linear conjugate gradients (never implemented in + this version). + +* `make distrib VERSION=...` can be used to archive the sources. + +* Move sources to `src` and update make target/rules. + +* OptimPack (version 1) is now on GitHub at + https://github.com/emmt/OptimPackLegacy + + +**Version 1.3.2 (2010-05-07)** + +* Makefile fixed thanks to Michael Williamson. + + +**Version 1.3.1 (2009-09-23)** + +* Bugs fixed in Yorick interface with the size of workspace arrays + ISAVE and DSAVE. + + +**Version 1.3.0 (2009-05-14)** + +* `fmin` is now an optional parameter. Functions `op_get/set_fmin` and + `op_vmlmb_first` have changed. Accordingly, the Yorick interface have + changed. + +* IDL interface needs to be updated... + + +**Version 1.2.0 (2008-01-31)** + + +**Version 1.1.0 (2008-01-30)** + +* Yorick interface to OptimPack reworked. + +* In IDL interface, some fixes by Laurent Mugnier: + + - syntax errors in `op_vmlmb_msg.pro`; + + - bugs in parsing of arguments in `op_idl.c` (function `op_idl_vmlmb_next`). + + - New function `fmin_op` in directory `idl/contrib` by Laurent Mugnier + (license is CeCILL not GPL). + +* GNU Public License updated. + +* Integrate changes made by Laurent Mugnier (thanks to him!) in IDL interface + to support for Linux and 64 bit machines. + + +**Version 1.0.0 (2003-04-22)** diff -Nru yorick-optimpack-1.3.2+dfsg/op_limits.h yorick-optimpack-1.3.2+dfsg+1.4.0/op_limits.h --- yorick-optimpack-1.3.2+dfsg/op_limits.h 2003-02-26 12:38:44.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/op_limits.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,161 +0,0 @@ -/* - * op_limits.h -- - * - * Definitions to guess sizes of integers on this machine. - * - *----------------------------------------------------------------------------- - * - * Copyright (c) 2003, Eric THIEBAUT. - * - * This file is part of OptimPack. - * - * OptimPack is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2 of the License, - * or (at your option) any later version. - * - * OptimPack is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with OptimPack (file "LICENSE" in the top source directory); - * if not, write to the Free Software Foundation, Inc., 59 Temple - * Place, Suite 330, Boston, MA 02111-1307 USA - * - *----------------------------------------------------------------------------- - * - * $Id$ - * $Log$ - * - *----------------------------------------------------------------------------- - */ - -#ifndef _OP_LIMITS_H -#define _OP_LIMITS_H 1 - -#include - -#define OP_INT16_MIN (-32768) -#define OP_INT16_MAX 32767 -#define OP_UINT16_MAX 65535 - -#define OP_INT32_MIN (-2147483648L) -#define OP_INT32_MAX 2147483647L -#define OP_UINT32_MAX 4294967295U - -#define OP_INT64_MIN (-9223372036854775808L) -#define OP_INT64_MAX 9223372036854775807L -#define OP_UINT64_MAX 18446744073709551615UL - -#if ! defined (OP_SHRT_BITS) && defined(USHRT_MAX) -# if (USHRT_MAX == OP_UINT16_MAX) -# define OP_SHRT_BITS 16 -# else -# if (USHRT_MAX == OP_UINT32_MAX) -# define OP_SHRT_BITS 32 -# else -# if (USHRT_MAX == OP_UINT64_MAX) -# define OP_SHRT_BITS 64 -# endif -# endif -# endif -#endif -#if ! defined (OP_SHRT_BITS) && defined(SHRT_MIN) && defined(SHRT_MAX) -# if (SHRT_MIN == OP_INT16_MIN) && SHRT_MAX == OP_INT16_MAX) -# define OP_SHRT_BITS 16 -# else -# if (SHRT_MIN == OP_INT32_MIN) && SHRT_MAX == OP_INT32_MAX) -# define OP_SHRT_BITS 32 -# else -# if (SHRT_MIN == OP_INT64_MIN) && SHRT_MAX == OP_INT64_MAX) -# define OP_SHRT_BITS 64 -# endif -# endif -# endif -#endif - -#if ! defined (OP_INT_BITS) && defined(UINT_MAX) -# if (UINT_MAX == OP_UINT16_MAX) -# define OP_INT_BITS 16 -# else -# if (UINT_MAX == OP_UINT32_MAX) -# define OP_INT_BITS 32 -# else -# if (UINT_MAX == OP_UINT64_MAX) -# define OP_INT_BITS 64 -# endif -# endif -# endif -#endif -#if ! defined (OP_INT_BITS) && defined(INT_MIN) && defined(INT_MAX) -# if (INT_MIN == OP_INT16_MIN) && (INT_MAX == OP_INT16_MAX) -# define OP_INT_BITS 16 -# else -# if (INT_MIN == OP_INT32_MIN) && (INT_MAX == OP_INT32_MAX) -# define OP_INT_BITS 32 -# else -# if (INT_MIN == OP_INT64_MIN) && (INT_MAX == OP_INT64_MAX) -# define OP_INT_BITS 64 -# endif -# endif -# endif -#endif - -#if ! defined (OP_LONG_BITS) && defined(ULONG_MAX) -# if (ULONG_MAX == OP_UINT16_MAX) -# define OP_LONG_BITS 16 -# else -# if (ULONG_MAX == OP_UINT32_MAX) -# define OP_LONG_BITS 32 -# else -# if (ULONG_MAX == OP_UINT64_MAX) -# define OP_LONG_BITS 64 -# endif -# endif -# endif -#endif -#if ! defined (OP_LONG_BITS) && defined(LONG_MIN) && defined(LONG_MAX) -# if (LONG_MIN == OP_INT16_MIN) && (LONG_MAX == OP_INT16_MAX) -# define OP_LONG_BITS 16 -# else -# if (LONG_MIN == OP_INT32_MIN) && (LONG_MAX == OP_INT32_MAX) -# define OP_LONG_BITS 32 -# else -# if (LONG_MIN == OP_INT64_MIN) && (LONG_MAX == OP_INT64_MAX) -# define OP_LONG_BITS 64 -# endif -# endif -# endif -#endif - -#if ! defined (OP_LLONG_BITS) && defined(ULLONG_MAX) -# if (ULLONG_MAX == OP_UINT16_MAX) -# define OP_LLONG_BITS 16 -# else -# if (ULLONG_MAX == OP_UINT32_MAX) -# define OP_LLONG_BITS 32 -# else -# if (ULLONG_MAX == OP_UINT64_MAX) -# define OP_LLONG_BITS 64 -# endif -# endif -# endif -#endif -#if ! defined (OP_LLONG_BITS) && defined(LLONG_MIN) && defined(LLONG_MAX) -# if (LLONG_MIN == OP_INT16_MIN) && (LLONG_MAX == OP_INT16_MAX) -# define OP_LLONG_BITS 16 -# else -# if (LLONG_MIN == OP_INT32_MIN) && (LLONG_MAX == OP_INT32_MAX) -# define OP_LLONG_BITS 32 -# else -# if (LLONG_MIN == OP_INT64_MIN) && (LLONG_MAX == OP_INT64_MAX) -# define OP_LLONG_BITS 64 -# endif -# endif -# endif -#endif - -/*---------------------------------------------------------------------------*/ -#endif /* _OP_LIMITS_H */ diff -Nru yorick-optimpack-1.3.2+dfsg/op_lnsrch.c yorick-optimpack-1.3.2+dfsg+1.4.0/op_lnsrch.c --- yorick-optimpack-1.3.2+dfsg/op_lnsrch.c 2003-03-21 11:56:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/op_lnsrch.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,438 +0,0 @@ -/* - * op_lnsrch.h -- - * - * Line search routines for OptimPack library. - * - *----------------------------------------------------------------------------- - * - * Copyright (c) 2003, Eric THIEBAUT. - * - * This file is part of OptimPack. - * - * OptimPack is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2 of the License, - * or (at your option) any later version. - * - * OptimPack is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with OptimPack (file "LICENSE" in the top source directory); - * if not, write to the Free Software Foundation, Inc., 59 Temple - * Place, Suite 330, Boston, MA 02111-1307 USA - * - *----------------------------------------------------------------------------- - * - * $Id: op_lnsrch.c,v 1.1 2003/03/12 15:11:52 eric Exp $ - * $Log: op_lnsrch.c,v $ - * Revision 1.1 2003/03/12 15:11:52 eric - * Initial revision - * - * - *----------------------------------------------------------------------------- - */ - -#include -#include -#include "optimpack.h" - -/*---------------------------------------------------------------------------*/ - -/* Indices of variables saved in ISAVE array: */ -#define INDEX_OF_BRACKT 0 -#define INDEX_OF_STAGE 1 - -/* Indices of variables saved in DSAVE array: */ -#define INDEX_OF_FINIT 0 -#define INDEX_OF_GINIT 1 -#define INDEX_OF_STX 2 -#define INDEX_OF_FX 3 -#define INDEX_OF_GX 4 -#define INDEX_OF_STY 5 -#define INDEX_OF_FY 6 -#define INDEX_OF_GY 7 -#define INDEX_OF_STMIN 8 -#define INDEX_OF_STMAX 9 -#define INDEX_OF_WIDTH 10 -#define INDEX_OF_WIDTH1 11 - -#define SET_TASK(val, str) *task = (val); op_mcopy("op_csrch: " str, csave) - -int op_csrch(double f, double g, double *stp_ptr, - double ftol, double gtol, double xtol, - double stpmin, double stpmax, int *task, - char csave[], op_integer_t isave[], double dsave[]) -{ - const double zero = 0.0; - const double xtrapl = 1.1; - const double xtrapu = 4.0; - int brackt, stage, info; - double finit, ginit, ftest, gtest; - double fx, gx, stx; - double fy, gy, sty; - double width, width1; - double stmin, stmax; - double stp = *stp_ptr; - - if (*task == OP_TASK_START) { - /* Check the input arguments for errors. - Exit if there are errors on input. */ -#define RETURN_ERROR(I,S) SET_TASK(OP_TASK_ERROR, S); return (I) - if (stpmax < stpmin) { RETURN_ERROR( 0, "STPMAX < STPMIN"); } - if (stpmin < zero) { RETURN_ERROR(-3,"STPMIN < 0"); } - if (xtol < zero) { RETURN_ERROR(-4, "XTOL < 0"); } - if (ftol <= zero) { RETURN_ERROR(-5, "FTOL <= 0"); } - if (gtol <= zero) { RETURN_ERROR(-6, "GTOL <= 0"); } - if (g >= zero) { RETURN_ERROR(-7, "initial G >= 0"); } - if (stp > stpmax) { RETURN_ERROR(-8, "STP > STPMAX"); } - if (stp < stpmin) { RETURN_ERROR(-9, "STP < STPMIN"); } -#undef RETURN_ERROR - - /* Initialize local variables. - The variables STX, FX, GX contain the values of the step, - function, and derivative at the best step. - The variables STY, FY, GY contain the value of the step, - function, and derivative at STY. - The variables STP, F, G contain the values of the step, - function, and derivative at STP. */ - isave[INDEX_OF_BRACKT] = 0; - isave[INDEX_OF_STAGE] = 1; - dsave[INDEX_OF_FINIT] = f; - dsave[INDEX_OF_GINIT] = g; - dsave[INDEX_OF_STX] = zero; - dsave[INDEX_OF_FX] = f; - dsave[INDEX_OF_GX] = g; - dsave[INDEX_OF_STY] = zero; - dsave[INDEX_OF_FY] = f; - dsave[INDEX_OF_GY] = g; - dsave[INDEX_OF_STMIN] = zero; - dsave[INDEX_OF_STMAX] = stp + stp*xtrapu; - dsave[INDEX_OF_WIDTH] = stpmax - stpmin; - dsave[INDEX_OF_WIDTH1] = 2.0*(stpmax - stpmin); - *task = OP_TASK_FG; - return 1; - } - - /* Restore local variables. */ - brackt = isave[INDEX_OF_BRACKT]; - stage = isave[INDEX_OF_STAGE]; - finit = dsave[INDEX_OF_FINIT]; - ginit = dsave[INDEX_OF_GINIT]; - stx = dsave[INDEX_OF_STX]; - fx = dsave[INDEX_OF_FX]; - gx = dsave[INDEX_OF_GX]; - sty = dsave[INDEX_OF_STY]; - fy = dsave[INDEX_OF_FY]; - gy = dsave[INDEX_OF_GY]; - stmin = dsave[INDEX_OF_STMIN]; - stmax = dsave[INDEX_OF_STMAX]; - width = dsave[INDEX_OF_WIDTH]; - width1 = dsave[INDEX_OF_WIDTH1]; - - /* If psi(stp) <= 0 and f'(stp) >= 0 for some step, then the - algorithm enters the second stage. */ - gtest = ftol*ginit; - ftest = finit + stp*gtest; - if (stage == 1 && f <= ftest && g >= zero) stage = 2; - - /* Test for termination: convergence or warnings. */ - if (f <= ftest && fabs(g) <= gtol*(-ginit)) { - /* Strong Wolfe conditions both satisfied. */ - SET_TASK(OP_TASK_CONV, "convergence of line search"); - info = 2; - } else if (stp == stpmin && (f > ftest || g >= gtest)) { - SET_TASK(OP_TASK_WARN, "STP = STPMIN"); - info = 3; - } else if (stp == stpmax && f <= ftest && g <= gtest) { - SET_TASK(OP_TASK_WARN, "STP = STPMAX"); - info = 4; - } else if (brackt && stmax - stmin <= xtol*stmax) { - SET_TASK(OP_TASK_WARN, "XTOL test satisfied"); - info = 5; - } else if (brackt && (stp <= stmin || stp >= stmax)) { - SET_TASK(OP_TASK_WARN, "rounding errors prevent progress"); - info = 6; - } else { - - /* A modified function is used to predict the step during the first - stage if a lower function value has been obtained but the decrease - is not sufficient. */ - - if (stage == 1 && f <= fx && f > ftest) { - - /* Define the modified function and derivative values. */ - double fm = f - stp*gtest; - double fxm = fx - stx*gtest; - double fym = fy - sty*gtest; - double gm = g - gtest; - double gxm = gx - gtest; - double gym = gy - gtest; - - /* Call op_cstep to update STX, STY, and to compute the new step. */ - info = op_cstep(&stx, &fxm, &gxm, - &sty, &fym, &gym, - &stp, fm, gm, - &brackt, stmin, stmax, csave); - if (info <= 0) { - *task = OP_TASK_ERROR; - return info; - } - - /* Reset the function and derivative values for F. */ - fx = fxm + stx*gtest; - fy = fym + sty*gtest; - gx = gxm + gtest; - gy = gym + gtest; - - } else { - - /* Call op_cstep to update STX, STY, and to compute the new step. */ - info = op_cstep(&stx, &fx, &gx, - &sty, &fy, &gy, - &stp, f, g, - &brackt, stmin, stmax, csave); - if (info <= 0) { - *task = OP_TASK_ERROR; - return info; - } - - } - - /* Decide if a bisection step is needed. */ - if (brackt) { - double wcur = fabs(sty - stx); - if (wcur >= 0.66*width1) stp = stx + 0.5*(sty - stx); - width1 = width; - width = wcur; - } - - /* Set the minimum and maximum steps allowed for STP. */ - if (brackt) { - if (stx <= sty) { - stmin = stx; - stmax = sty; - } else { - stmin = sty; - stmax = stx; - } - } else { - stmin = stp + xtrapl*(stp - stx); - stmax = stp + xtrapu*(stp - stx); - } - - /* Force the step to be within the bounds STPMAX and STPMIN. */ - if (stp > stpmax) stp = stpmax; - if (stp < stpmin) stp = stpmin; - - /* If further progress is not possible, let STP be the best - point obtained during the search. */ - if (brackt && (stp <= stmin || stp >= stmax || - stmax - stmin <= xtol*stmax)) stp = stx; - - /* Obtain another function and derivative. */ - if (csave) csave[0] = 0; - *task = OP_TASK_FG; - info = 1; - } - - /* Save local variables (only the ones that may have changed). */ - *stp_ptr = stp; - isave[INDEX_OF_BRACKT] = brackt; - isave[INDEX_OF_STAGE] = stage; - dsave[INDEX_OF_STX] = stx; - dsave[INDEX_OF_FX] = fx; - dsave[INDEX_OF_GX] = gx; - dsave[INDEX_OF_STY] = sty; - dsave[INDEX_OF_FY] = fy; - dsave[INDEX_OF_GY] = gy; - dsave[INDEX_OF_STMIN] = stmin; - dsave[INDEX_OF_STMAX] = stmax; - dsave[INDEX_OF_WIDTH] = width; - dsave[INDEX_OF_WIDTH1] = width1; - return info; -} - -#undef stp -#undef SET_TASK - -/*---------------------------------------------------------------------------*/ - -int op_cstep(double *stx_ptr, double *fx_ptr, double *dx_ptr, - double *sty_ptr, double *fy_ptr, double *dy_ptr, - double *stp_ptr, double fp, double dp, - int *brackt, double stpmin, double stpmax, - char csave[]) -{ - /* Constants. */ - const double zero = 0.0; - - /* Get values of input/output variables. */ - double stx = *stx_ptr, fx = *fx_ptr, dx = *dx_ptr; - double sty = *sty_ptr, fy = *fy_ptr, dy = *dy_ptr; - double stp = *stp_ptr; - - /* Local variables. */ - double gamma, theta, p, q, r, s, t; - double stpc; /* cubic step */ - double stpq; /* quadratic step */ - double sgnd, stpf; - int info; - - /* Check the input parameters for errors. */ - if (*brackt && (stx < sty ? (stp <= stx || stp >= sty) - : (stp >= stx || stp <= sty))) { - op_mcopy("op_cstep: STP outside bracket (STX,STY)", csave); - return -2; - } else if (dx*(stp - stx) >= zero) { - op_mcopy("op_cstep: descent condition violated", csave); - return -1; - } else if (stpmax < stpmin) { - op_mcopy("op_cstep: STPMAX < STPMIN", csave); - return 0; - } - - /* Determine if the derivatives have opposite sign. */ - sgnd = (dx/fabs(dx))*dp; - - if (fp > fx) { - /* First case. A higher function value. The minimum is bracketed. If - the cubic step is closer to STX than the quadratic step, the cubic - step is taken, otherwise the average of the cubic and quadratic - steps is taken. */ - info = 1; - theta = 3.0*(fx - fp)/(stp - stx) + dx + dp; - s = fabs(theta); - if (s < (t = fabs(dx))) s = t; - if (s < (t = fabs(dp))) s = t; - t = theta/s; - gamma = s*sqrt(t*t - (dx/s)*(dp/s)); - if (stp < stx) gamma = -gamma; - p = (gamma - dx) + theta; - q = ((gamma - dx) + gamma) + dp; - r = p/q; - stpc = stx + r*(stp - stx); - stpq = stx + ((dx/((fx - fp)/(stp - stx) + dx))/2.0)*(stp - stx); - if (fabs(stpc - stx) < fabs(stpq - stx)) { - stpf = stpc; - } else { - stpf = stpc + (stpq - stpc)/2.0; - } - *brackt = 1; - } else if (sgnd < zero) { - /* Second case. A lower function value and derivatives of opposite - sign. The minimum is bracketed. If the cubic step is farther from - STP than the secant (quadratic) step, the cubic step is taken, - otherwise the secant step is taken. */ - info = 2; - theta = 3.0*(fx - fp)/(stp - stx) + dx + dp; - s = fabs(theta); - if (s < (t = fabs(dx))) s = t; - if (s < (t = fabs(dp))) s = t; - t = theta/s; - gamma = s*sqrt(t*t - (dx/s)*(dp/s)); - if (stp > stx) gamma = -gamma; - p = (gamma - dp) + theta; - q = ((gamma - dp) + gamma) + dx; - r = p/q; - stpc = stp + r*(stx - stp); - stpq = stp + (dp/(dp - dx))*(stx - stp); - if (fabs(stpc - stp) > fabs(stpq - stp)) { - stpf = stpc; - } else { - stpf = stpq; - } - *brackt = 1; - } else if (fabs(dp) < fabs(dx)) { - /* Third case. A lower function value, derivatives of the same sign, - and the magnitude of the derivative decreases. The cubic step is - computed only if the cubic tends to infinity in the direction of the - step or if the minimum of the cubic is beyond STP. Otherwise the - cubic step is defined to be the secant step. */ - info = 3; - theta = 3.0*(fx - fp)/(stp - stx) + dx + dp; - s = fabs(theta); - if (s < (t = fabs(dx))) s = t; - if (s < (t = fabs(dp))) s = t; - /* The case GAMMA = 0 only arises if the cubic does not tend to - infinity in the direction of the step. */ - t = theta/s; - t = t*t - (dx/s)*(dp/s); - gamma = (t > zero ? s*sqrt(t) : zero); - if (stp > stx) gamma = -gamma; - p = (gamma - dp) + theta; - /*q = ((gamma - dp) + gamma) + dx;*/ - q = (gamma + (dx - dp)) + gamma; - r = p/q; - if (r < zero && gamma != zero) { - stpc = stp + r*(stx - stp); - } else if (stp > stx) { - stpc = stpmax; - } else { - stpc = stpmin; - } - stpq = stp + (dp/(dp - dx))*(stx - stp); - if (*brackt) { - /* A minimizer has been bracketed. If the cubic step is closer to - STP than the secant step, the cubic step is taken, otherwise the - secant step is taken. */ - stpf = fabs(stpc - stp) < fabs(stpq - stp) ? stpc : stpq; - t = stp + 0.66*(sty - stp); - if (stp > stx ? stpf > t : stpf < t) stpf = t; - } else { - /* A minimizer has not been bracketed. If the cubic step is farther - from stp than the secant step, the cubic step is taken, otherwise - the secant step is taken. */ - stpf = fabs(stpc - stp) > fabs(stpq - stp) ? stpc : stpq; - if (stpf > stpmax) stpf = stpmax; - if (stpf < stpmin) stpf = stpmin; - } - } else { - /* Fourth case. A lower function value, derivatives of the same sign, - and the magnitude of the derivative does not decrease. If the - minimum is not bracketed, the step is either STPMIN or STPMAX, - otherwise the cubic step is taken. */ - info = 4; - if (*brackt) { - theta = 3.0*(fp - fy)/(sty - stp) + dy + dp; - s = fabs(theta); - if (s < (t = fabs(dy))) s = t; - if (s < (t = fabs(dp))) s = t; - t = theta/s; - gamma = s*sqrt(t*t - (dy/s)*(dp/s)); - if (stp > sty) gamma = -gamma; - p = (gamma - dp) + theta; - q = ((gamma - dp) + gamma) + dy; - r = p/q; - stpc = stp + r*(sty - stp); - stpf = stpc; - } else if (stp > stx) { - stpf = stpmax; - } else { - stpf = stpmin; - } - } - - /* Update the interval which contains a minimizer and guess for next - step. */ - if (fp > fx) { - *sty_ptr = stp; - *fy_ptr = fp; - *dy_ptr = dp; - } else { - if (sgnd < zero) { - *sty_ptr = stx; - *fy_ptr = fx; - *dy_ptr = dx; - } - *stx_ptr = stp; - *fx_ptr = fp; - *dx_ptr = dp; - } - *stp_ptr = stpf; - return info; -} - -/*---------------------------------------------------------------------------*/ diff -Nru yorick-optimpack-1.3.2+dfsg/optimpack1/AUTHORS yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/AUTHORS --- yorick-optimpack-1.3.2+dfsg/optimpack1/AUTHORS 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/AUTHORS 2007-07-06 22:57:25.000000000 +0000 @@ -0,0 +1 @@ +Eric Thiébaut (Observatoire de Lyon, France) diff -Nru yorick-optimpack-1.3.2+dfsg/optimpack1/LICENSE yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/LICENSE --- yorick-optimpack-1.3.2+dfsg/optimpack1/LICENSE 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/LICENSE 2005-05-05 20:01:35.000000000 +0000 @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff -Nru yorick-optimpack-1.3.2+dfsg/optimpack1/Makefile yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/Makefile --- yorick-optimpack-1.3.2+dfsg/optimpack1/Makefile 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/Makefile 2010-07-05 20:41:47.000000000 +0000 @@ -0,0 +1,56 @@ + PREFIX= + INSTALL=cp -p + + CC = gcc -pipe +#CPPFLAGS = -I. -DOP_INTEGER=long -DOP_LOGICAL=int + CPPFLAGS = -I. + CFLAGS = -O2 -Wall + + RM = rm -f + AR = ar + ARFLAGS = rv + + LIBNAME = liboptimpack.a + VERSION = 1.0 + OBJS = op_lnsrch.o op_utils.o op_vmlmb.o + DIRS = yorick idl + +all: $(LIBNAME) +install: $(LIBNAME) + @if [ "x$(PREFIX)" = "x" ]; then \ + echo "You must define PREFIX macro, e.g.:"; \ + echo " > make PREFIX=/usr/local install"; \ + else \ + [ -d "$(PREFIX)/lib" ] || mkdir -p "$(PREFIX)/lib"; \ + $(INSTALL) $(LIBNAME) "$(PREFIX)/lib/."; \ + [ -d "$(PREFIX)/include" ] || mkdir -p "$(PREFIX)/include"; \ + $(INSTALL) optimpack.h "$(PREFIX)/include/."; \ + [ -d "$(PREFIX)/doc/OptimPack-$(VERSION)" ] || \ + mkdir -p "$(PREFIX)/doc/OptimPack-$(VERSION)"; \ + $(INSTALL) README AUTHORS LICENSE optimpack.h \ + "$(PREFIX)/doc/OptimPack-$(VERSION)/."; \ + fi + +clean: + $(RM) *~ $(OBJS) $(LIBNAME) + for dir in $(DIRS); do \ + if [ -f "$$dir/Makefile" ]; then \ + (cd $$dir; make clean); \ + fi; \ + done + +distclean: clean + $(RM) $(LIBNAME) + +$(LIBNAME): $(OBJS) + $(RM) $(LIBNAME) + $(AR) $(ARFLAGS) $(LIBNAME) $(OBJS) + +op_lnsrch.o: op_lnsrch.c optimpack.h + $(CC) $(CFLAGS) $(CPPFLAGS) -c $(@:.o=.c) -o $@ +op_vmlmb.o: op_vmlmb.c optimpack.h + $(CC) $(CFLAGS) $(CPPFLAGS) -c $(@:.o=.c) -o $@ +op_cgmnb.o: op_cgmnb.c optimpack.h + $(CC) $(CFLAGS) $(CPPFLAGS) -c $(@:.o=.c) -o $@ +op_utils.o: op_utils.c optimpack.h + $(CC) $(CFLAGS) $(CPPFLAGS) -c $(@:.o=.c) -o $@ diff -Nru yorick-optimpack-1.3.2+dfsg/optimpack1/NEWS yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/NEWS --- yorick-optimpack-1.3.2+dfsg/optimpack1/NEWS 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/NEWS 2010-07-05 21:00:18.000000000 +0000 @@ -0,0 +1,63 @@ +------------------------------------------------------------------------------- + +2010-05-07: + * OptimPack-1.3.2 released. + * Makefile fixed thanks to Michael Williamson. + +------------------------------------------------------------------------------- + +2009-09-23: + * OptimPack-1.3.1 released. + * Bugs fixed in Yorick interface with the size of workspace arrays + ISAVE and DSAVE. + +------------------------------------------------------------------------------- + +2009-05-14: + OptimPack-1.3 released. + +2008-02-07: + + * FMIN is now an optional parameter. Functions op_get/set_fmin + and op_vmlmb_first have changed. Accordingly, the Yorick + interface have changed. + + * IDL interface needs to be updated... + +------------------------------------------------------------------------------- + +2008-01-31: + OptimPack-1.2 released. + +------------------------------------------------------------------------------- + +2008-01-30: + OptimPack-1.1 released. + +2007-06-27: + + * Yorick interface to OptimPack reworked. + + * In IDL interface, some fixes by Laurent Mugnier: + - syntax errors in op_vmlmb_msg.pro; + - bugs in parsing of arguments in op_idl.c (function + op_idl_vmlmb_next). + + * New function fmin_op in directory 'idl/contrib' by Laurent + Mugnier (license is CeCILL not GPL). + + * GNU Public License updated. + + +2006-04-26: + + Integrate changes made by Laurent Mugnier (thanks to him!) + in IDL interface to support for Linux and 64 bit machines. + +------------------------------------------------------------------------------- + +2003-04-22: + + OptimPack-1.0 released. + +------------------------------------------------------------------------------- diff -Nru yorick-optimpack-1.3.2+dfsg/optimpack1/op_limits.h yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/op_limits.h --- yorick-optimpack-1.3.2+dfsg/optimpack1/op_limits.h 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/op_limits.h 2003-02-26 12:38:44.000000000 +0000 @@ -0,0 +1,161 @@ +/* + * op_limits.h -- + * + * Definitions to guess sizes of integers on this machine. + * + *----------------------------------------------------------------------------- + * + * Copyright (c) 2003, Eric THIEBAUT. + * + * This file is part of OptimPack. + * + * OptimPack is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, + * or (at your option) any later version. + * + * OptimPack is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OptimPack (file "LICENSE" in the top source directory); + * if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + * + *----------------------------------------------------------------------------- + * + * $Id$ + * $Log$ + * + *----------------------------------------------------------------------------- + */ + +#ifndef _OP_LIMITS_H +#define _OP_LIMITS_H 1 + +#include + +#define OP_INT16_MIN (-32768) +#define OP_INT16_MAX 32767 +#define OP_UINT16_MAX 65535 + +#define OP_INT32_MIN (-2147483648L) +#define OP_INT32_MAX 2147483647L +#define OP_UINT32_MAX 4294967295U + +#define OP_INT64_MIN (-9223372036854775808L) +#define OP_INT64_MAX 9223372036854775807L +#define OP_UINT64_MAX 18446744073709551615UL + +#if ! defined (OP_SHRT_BITS) && defined(USHRT_MAX) +# if (USHRT_MAX == OP_UINT16_MAX) +# define OP_SHRT_BITS 16 +# else +# if (USHRT_MAX == OP_UINT32_MAX) +# define OP_SHRT_BITS 32 +# else +# if (USHRT_MAX == OP_UINT64_MAX) +# define OP_SHRT_BITS 64 +# endif +# endif +# endif +#endif +#if ! defined (OP_SHRT_BITS) && defined(SHRT_MIN) && defined(SHRT_MAX) +# if (SHRT_MIN == OP_INT16_MIN) && SHRT_MAX == OP_INT16_MAX) +# define OP_SHRT_BITS 16 +# else +# if (SHRT_MIN == OP_INT32_MIN) && SHRT_MAX == OP_INT32_MAX) +# define OP_SHRT_BITS 32 +# else +# if (SHRT_MIN == OP_INT64_MIN) && SHRT_MAX == OP_INT64_MAX) +# define OP_SHRT_BITS 64 +# endif +# endif +# endif +#endif + +#if ! defined (OP_INT_BITS) && defined(UINT_MAX) +# if (UINT_MAX == OP_UINT16_MAX) +# define OP_INT_BITS 16 +# else +# if (UINT_MAX == OP_UINT32_MAX) +# define OP_INT_BITS 32 +# else +# if (UINT_MAX == OP_UINT64_MAX) +# define OP_INT_BITS 64 +# endif +# endif +# endif +#endif +#if ! defined (OP_INT_BITS) && defined(INT_MIN) && defined(INT_MAX) +# if (INT_MIN == OP_INT16_MIN) && (INT_MAX == OP_INT16_MAX) +# define OP_INT_BITS 16 +# else +# if (INT_MIN == OP_INT32_MIN) && (INT_MAX == OP_INT32_MAX) +# define OP_INT_BITS 32 +# else +# if (INT_MIN == OP_INT64_MIN) && (INT_MAX == OP_INT64_MAX) +# define OP_INT_BITS 64 +# endif +# endif +# endif +#endif + +#if ! defined (OP_LONG_BITS) && defined(ULONG_MAX) +# if (ULONG_MAX == OP_UINT16_MAX) +# define OP_LONG_BITS 16 +# else +# if (ULONG_MAX == OP_UINT32_MAX) +# define OP_LONG_BITS 32 +# else +# if (ULONG_MAX == OP_UINT64_MAX) +# define OP_LONG_BITS 64 +# endif +# endif +# endif +#endif +#if ! defined (OP_LONG_BITS) && defined(LONG_MIN) && defined(LONG_MAX) +# if (LONG_MIN == OP_INT16_MIN) && (LONG_MAX == OP_INT16_MAX) +# define OP_LONG_BITS 16 +# else +# if (LONG_MIN == OP_INT32_MIN) && (LONG_MAX == OP_INT32_MAX) +# define OP_LONG_BITS 32 +# else +# if (LONG_MIN == OP_INT64_MIN) && (LONG_MAX == OP_INT64_MAX) +# define OP_LONG_BITS 64 +# endif +# endif +# endif +#endif + +#if ! defined (OP_LLONG_BITS) && defined(ULLONG_MAX) +# if (ULLONG_MAX == OP_UINT16_MAX) +# define OP_LLONG_BITS 16 +# else +# if (ULLONG_MAX == OP_UINT32_MAX) +# define OP_LLONG_BITS 32 +# else +# if (ULLONG_MAX == OP_UINT64_MAX) +# define OP_LLONG_BITS 64 +# endif +# endif +# endif +#endif +#if ! defined (OP_LLONG_BITS) && defined(LLONG_MIN) && defined(LLONG_MAX) +# if (LLONG_MIN == OP_INT16_MIN) && (LLONG_MAX == OP_INT16_MAX) +# define OP_LLONG_BITS 16 +# else +# if (LLONG_MIN == OP_INT32_MIN) && (LLONG_MAX == OP_INT32_MAX) +# define OP_LLONG_BITS 32 +# else +# if (LLONG_MIN == OP_INT64_MIN) && (LLONG_MAX == OP_INT64_MAX) +# define OP_LLONG_BITS 64 +# endif +# endif +# endif +#endif + +/*---------------------------------------------------------------------------*/ +#endif /* _OP_LIMITS_H */ diff -Nru yorick-optimpack-1.3.2+dfsg/optimpack1/op_lnsrch.c yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/op_lnsrch.c --- yorick-optimpack-1.3.2+dfsg/optimpack1/op_lnsrch.c 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/op_lnsrch.c 2003-03-21 11:56:00.000000000 +0000 @@ -0,0 +1,438 @@ +/* + * op_lnsrch.h -- + * + * Line search routines for OptimPack library. + * + *----------------------------------------------------------------------------- + * + * Copyright (c) 2003, Eric THIEBAUT. + * + * This file is part of OptimPack. + * + * OptimPack is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, + * or (at your option) any later version. + * + * OptimPack is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OptimPack (file "LICENSE" in the top source directory); + * if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + * + *----------------------------------------------------------------------------- + * + * $Id: op_lnsrch.c,v 1.1 2003/03/12 15:11:52 eric Exp $ + * $Log: op_lnsrch.c,v $ + * Revision 1.1 2003/03/12 15:11:52 eric + * Initial revision + * + * + *----------------------------------------------------------------------------- + */ + +#include +#include +#include "optimpack.h" + +/*---------------------------------------------------------------------------*/ + +/* Indices of variables saved in ISAVE array: */ +#define INDEX_OF_BRACKT 0 +#define INDEX_OF_STAGE 1 + +/* Indices of variables saved in DSAVE array: */ +#define INDEX_OF_FINIT 0 +#define INDEX_OF_GINIT 1 +#define INDEX_OF_STX 2 +#define INDEX_OF_FX 3 +#define INDEX_OF_GX 4 +#define INDEX_OF_STY 5 +#define INDEX_OF_FY 6 +#define INDEX_OF_GY 7 +#define INDEX_OF_STMIN 8 +#define INDEX_OF_STMAX 9 +#define INDEX_OF_WIDTH 10 +#define INDEX_OF_WIDTH1 11 + +#define SET_TASK(val, str) *task = (val); op_mcopy("op_csrch: " str, csave) + +int op_csrch(double f, double g, double *stp_ptr, + double ftol, double gtol, double xtol, + double stpmin, double stpmax, int *task, + char csave[], op_integer_t isave[], double dsave[]) +{ + const double zero = 0.0; + const double xtrapl = 1.1; + const double xtrapu = 4.0; + int brackt, stage, info; + double finit, ginit, ftest, gtest; + double fx, gx, stx; + double fy, gy, sty; + double width, width1; + double stmin, stmax; + double stp = *stp_ptr; + + if (*task == OP_TASK_START) { + /* Check the input arguments for errors. + Exit if there are errors on input. */ +#define RETURN_ERROR(I,S) SET_TASK(OP_TASK_ERROR, S); return (I) + if (stpmax < stpmin) { RETURN_ERROR( 0, "STPMAX < STPMIN"); } + if (stpmin < zero) { RETURN_ERROR(-3,"STPMIN < 0"); } + if (xtol < zero) { RETURN_ERROR(-4, "XTOL < 0"); } + if (ftol <= zero) { RETURN_ERROR(-5, "FTOL <= 0"); } + if (gtol <= zero) { RETURN_ERROR(-6, "GTOL <= 0"); } + if (g >= zero) { RETURN_ERROR(-7, "initial G >= 0"); } + if (stp > stpmax) { RETURN_ERROR(-8, "STP > STPMAX"); } + if (stp < stpmin) { RETURN_ERROR(-9, "STP < STPMIN"); } +#undef RETURN_ERROR + + /* Initialize local variables. + The variables STX, FX, GX contain the values of the step, + function, and derivative at the best step. + The variables STY, FY, GY contain the value of the step, + function, and derivative at STY. + The variables STP, F, G contain the values of the step, + function, and derivative at STP. */ + isave[INDEX_OF_BRACKT] = 0; + isave[INDEX_OF_STAGE] = 1; + dsave[INDEX_OF_FINIT] = f; + dsave[INDEX_OF_GINIT] = g; + dsave[INDEX_OF_STX] = zero; + dsave[INDEX_OF_FX] = f; + dsave[INDEX_OF_GX] = g; + dsave[INDEX_OF_STY] = zero; + dsave[INDEX_OF_FY] = f; + dsave[INDEX_OF_GY] = g; + dsave[INDEX_OF_STMIN] = zero; + dsave[INDEX_OF_STMAX] = stp + stp*xtrapu; + dsave[INDEX_OF_WIDTH] = stpmax - stpmin; + dsave[INDEX_OF_WIDTH1] = 2.0*(stpmax - stpmin); + *task = OP_TASK_FG; + return 1; + } + + /* Restore local variables. */ + brackt = isave[INDEX_OF_BRACKT]; + stage = isave[INDEX_OF_STAGE]; + finit = dsave[INDEX_OF_FINIT]; + ginit = dsave[INDEX_OF_GINIT]; + stx = dsave[INDEX_OF_STX]; + fx = dsave[INDEX_OF_FX]; + gx = dsave[INDEX_OF_GX]; + sty = dsave[INDEX_OF_STY]; + fy = dsave[INDEX_OF_FY]; + gy = dsave[INDEX_OF_GY]; + stmin = dsave[INDEX_OF_STMIN]; + stmax = dsave[INDEX_OF_STMAX]; + width = dsave[INDEX_OF_WIDTH]; + width1 = dsave[INDEX_OF_WIDTH1]; + + /* If psi(stp) <= 0 and f'(stp) >= 0 for some step, then the + algorithm enters the second stage. */ + gtest = ftol*ginit; + ftest = finit + stp*gtest; + if (stage == 1 && f <= ftest && g >= zero) stage = 2; + + /* Test for termination: convergence or warnings. */ + if (f <= ftest && fabs(g) <= gtol*(-ginit)) { + /* Strong Wolfe conditions both satisfied. */ + SET_TASK(OP_TASK_CONV, "convergence of line search"); + info = 2; + } else if (stp == stpmin && (f > ftest || g >= gtest)) { + SET_TASK(OP_TASK_WARN, "STP = STPMIN"); + info = 3; + } else if (stp == stpmax && f <= ftest && g <= gtest) { + SET_TASK(OP_TASK_WARN, "STP = STPMAX"); + info = 4; + } else if (brackt && stmax - stmin <= xtol*stmax) { + SET_TASK(OP_TASK_WARN, "XTOL test satisfied"); + info = 5; + } else if (brackt && (stp <= stmin || stp >= stmax)) { + SET_TASK(OP_TASK_WARN, "rounding errors prevent progress"); + info = 6; + } else { + + /* A modified function is used to predict the step during the first + stage if a lower function value has been obtained but the decrease + is not sufficient. */ + + if (stage == 1 && f <= fx && f > ftest) { + + /* Define the modified function and derivative values. */ + double fm = f - stp*gtest; + double fxm = fx - stx*gtest; + double fym = fy - sty*gtest; + double gm = g - gtest; + double gxm = gx - gtest; + double gym = gy - gtest; + + /* Call op_cstep to update STX, STY, and to compute the new step. */ + info = op_cstep(&stx, &fxm, &gxm, + &sty, &fym, &gym, + &stp, fm, gm, + &brackt, stmin, stmax, csave); + if (info <= 0) { + *task = OP_TASK_ERROR; + return info; + } + + /* Reset the function and derivative values for F. */ + fx = fxm + stx*gtest; + fy = fym + sty*gtest; + gx = gxm + gtest; + gy = gym + gtest; + + } else { + + /* Call op_cstep to update STX, STY, and to compute the new step. */ + info = op_cstep(&stx, &fx, &gx, + &sty, &fy, &gy, + &stp, f, g, + &brackt, stmin, stmax, csave); + if (info <= 0) { + *task = OP_TASK_ERROR; + return info; + } + + } + + /* Decide if a bisection step is needed. */ + if (brackt) { + double wcur = fabs(sty - stx); + if (wcur >= 0.66*width1) stp = stx + 0.5*(sty - stx); + width1 = width; + width = wcur; + } + + /* Set the minimum and maximum steps allowed for STP. */ + if (brackt) { + if (stx <= sty) { + stmin = stx; + stmax = sty; + } else { + stmin = sty; + stmax = stx; + } + } else { + stmin = stp + xtrapl*(stp - stx); + stmax = stp + xtrapu*(stp - stx); + } + + /* Force the step to be within the bounds STPMAX and STPMIN. */ + if (stp > stpmax) stp = stpmax; + if (stp < stpmin) stp = stpmin; + + /* If further progress is not possible, let STP be the best + point obtained during the search. */ + if (brackt && (stp <= stmin || stp >= stmax || + stmax - stmin <= xtol*stmax)) stp = stx; + + /* Obtain another function and derivative. */ + if (csave) csave[0] = 0; + *task = OP_TASK_FG; + info = 1; + } + + /* Save local variables (only the ones that may have changed). */ + *stp_ptr = stp; + isave[INDEX_OF_BRACKT] = brackt; + isave[INDEX_OF_STAGE] = stage; + dsave[INDEX_OF_STX] = stx; + dsave[INDEX_OF_FX] = fx; + dsave[INDEX_OF_GX] = gx; + dsave[INDEX_OF_STY] = sty; + dsave[INDEX_OF_FY] = fy; + dsave[INDEX_OF_GY] = gy; + dsave[INDEX_OF_STMIN] = stmin; + dsave[INDEX_OF_STMAX] = stmax; + dsave[INDEX_OF_WIDTH] = width; + dsave[INDEX_OF_WIDTH1] = width1; + return info; +} + +#undef stp +#undef SET_TASK + +/*---------------------------------------------------------------------------*/ + +int op_cstep(double *stx_ptr, double *fx_ptr, double *dx_ptr, + double *sty_ptr, double *fy_ptr, double *dy_ptr, + double *stp_ptr, double fp, double dp, + int *brackt, double stpmin, double stpmax, + char csave[]) +{ + /* Constants. */ + const double zero = 0.0; + + /* Get values of input/output variables. */ + double stx = *stx_ptr, fx = *fx_ptr, dx = *dx_ptr; + double sty = *sty_ptr, fy = *fy_ptr, dy = *dy_ptr; + double stp = *stp_ptr; + + /* Local variables. */ + double gamma, theta, p, q, r, s, t; + double stpc; /* cubic step */ + double stpq; /* quadratic step */ + double sgnd, stpf; + int info; + + /* Check the input parameters for errors. */ + if (*brackt && (stx < sty ? (stp <= stx || stp >= sty) + : (stp >= stx || stp <= sty))) { + op_mcopy("op_cstep: STP outside bracket (STX,STY)", csave); + return -2; + } else if (dx*(stp - stx) >= zero) { + op_mcopy("op_cstep: descent condition violated", csave); + return -1; + } else if (stpmax < stpmin) { + op_mcopy("op_cstep: STPMAX < STPMIN", csave); + return 0; + } + + /* Determine if the derivatives have opposite sign. */ + sgnd = (dx/fabs(dx))*dp; + + if (fp > fx) { + /* First case. A higher function value. The minimum is bracketed. If + the cubic step is closer to STX than the quadratic step, the cubic + step is taken, otherwise the average of the cubic and quadratic + steps is taken. */ + info = 1; + theta = 3.0*(fx - fp)/(stp - stx) + dx + dp; + s = fabs(theta); + if (s < (t = fabs(dx))) s = t; + if (s < (t = fabs(dp))) s = t; + t = theta/s; + gamma = s*sqrt(t*t - (dx/s)*(dp/s)); + if (stp < stx) gamma = -gamma; + p = (gamma - dx) + theta; + q = ((gamma - dx) + gamma) + dp; + r = p/q; + stpc = stx + r*(stp - stx); + stpq = stx + ((dx/((fx - fp)/(stp - stx) + dx))/2.0)*(stp - stx); + if (fabs(stpc - stx) < fabs(stpq - stx)) { + stpf = stpc; + } else { + stpf = stpc + (stpq - stpc)/2.0; + } + *brackt = 1; + } else if (sgnd < zero) { + /* Second case. A lower function value and derivatives of opposite + sign. The minimum is bracketed. If the cubic step is farther from + STP than the secant (quadratic) step, the cubic step is taken, + otherwise the secant step is taken. */ + info = 2; + theta = 3.0*(fx - fp)/(stp - stx) + dx + dp; + s = fabs(theta); + if (s < (t = fabs(dx))) s = t; + if (s < (t = fabs(dp))) s = t; + t = theta/s; + gamma = s*sqrt(t*t - (dx/s)*(dp/s)); + if (stp > stx) gamma = -gamma; + p = (gamma - dp) + theta; + q = ((gamma - dp) + gamma) + dx; + r = p/q; + stpc = stp + r*(stx - stp); + stpq = stp + (dp/(dp - dx))*(stx - stp); + if (fabs(stpc - stp) > fabs(stpq - stp)) { + stpf = stpc; + } else { + stpf = stpq; + } + *brackt = 1; + } else if (fabs(dp) < fabs(dx)) { + /* Third case. A lower function value, derivatives of the same sign, + and the magnitude of the derivative decreases. The cubic step is + computed only if the cubic tends to infinity in the direction of the + step or if the minimum of the cubic is beyond STP. Otherwise the + cubic step is defined to be the secant step. */ + info = 3; + theta = 3.0*(fx - fp)/(stp - stx) + dx + dp; + s = fabs(theta); + if (s < (t = fabs(dx))) s = t; + if (s < (t = fabs(dp))) s = t; + /* The case GAMMA = 0 only arises if the cubic does not tend to + infinity in the direction of the step. */ + t = theta/s; + t = t*t - (dx/s)*(dp/s); + gamma = (t > zero ? s*sqrt(t) : zero); + if (stp > stx) gamma = -gamma; + p = (gamma - dp) + theta; + /*q = ((gamma - dp) + gamma) + dx;*/ + q = (gamma + (dx - dp)) + gamma; + r = p/q; + if (r < zero && gamma != zero) { + stpc = stp + r*(stx - stp); + } else if (stp > stx) { + stpc = stpmax; + } else { + stpc = stpmin; + } + stpq = stp + (dp/(dp - dx))*(stx - stp); + if (*brackt) { + /* A minimizer has been bracketed. If the cubic step is closer to + STP than the secant step, the cubic step is taken, otherwise the + secant step is taken. */ + stpf = fabs(stpc - stp) < fabs(stpq - stp) ? stpc : stpq; + t = stp + 0.66*(sty - stp); + if (stp > stx ? stpf > t : stpf < t) stpf = t; + } else { + /* A minimizer has not been bracketed. If the cubic step is farther + from stp than the secant step, the cubic step is taken, otherwise + the secant step is taken. */ + stpf = fabs(stpc - stp) > fabs(stpq - stp) ? stpc : stpq; + if (stpf > stpmax) stpf = stpmax; + if (stpf < stpmin) stpf = stpmin; + } + } else { + /* Fourth case. A lower function value, derivatives of the same sign, + and the magnitude of the derivative does not decrease. If the + minimum is not bracketed, the step is either STPMIN or STPMAX, + otherwise the cubic step is taken. */ + info = 4; + if (*brackt) { + theta = 3.0*(fp - fy)/(sty - stp) + dy + dp; + s = fabs(theta); + if (s < (t = fabs(dy))) s = t; + if (s < (t = fabs(dp))) s = t; + t = theta/s; + gamma = s*sqrt(t*t - (dy/s)*(dp/s)); + if (stp > sty) gamma = -gamma; + p = (gamma - dp) + theta; + q = ((gamma - dp) + gamma) + dy; + r = p/q; + stpc = stp + r*(sty - stp); + stpf = stpc; + } else if (stp > stx) { + stpf = stpmax; + } else { + stpf = stpmin; + } + } + + /* Update the interval which contains a minimizer and guess for next + step. */ + if (fp > fx) { + *sty_ptr = stp; + *fy_ptr = fp; + *dy_ptr = dp; + } else { + if (sgnd < zero) { + *sty_ptr = stx; + *fy_ptr = fx; + *dy_ptr = dx; + } + *stx_ptr = stp; + *fx_ptr = fp; + *dx_ptr = dp; + } + *stp_ptr = stpf; + return info; +} + +/*---------------------------------------------------------------------------*/ diff -Nru yorick-optimpack-1.3.2+dfsg/optimpack1/optimpack.bib yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/optimpack.bib --- yorick-optimpack-1.3.2+dfsg/optimpack1/optimpack.bib 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/optimpack.bib 2003-03-12 10:08:27.000000000 +0000 @@ -0,0 +1,12 @@ +@article{192132, + author = {Jorge J. Mor{\'e} and David J. Thuente}, + title = {Line search algorithms with guaranteed sufficient decrease}, + journal = {ACM Transactions on Mathematical Software (TOMS)}, + volume = {20}, + number = {3}, + year = {1994}, + issn = {0098-3500}, + pages = {286--307}, + doi = {http://doi.acm.org/10.1145/192115.192132}, + publisher = {ACM Press}, + } diff -Nru yorick-optimpack-1.3.2+dfsg/optimpack1/optimpack.h yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/optimpack.h --- yorick-optimpack-1.3.2+dfsg/optimpack1/optimpack.h 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/optimpack.h 2009-04-23 11:24:41.000000000 +0000 @@ -0,0 +1,763 @@ +/* + * optimpack.h -- + * + * Definitions for optimization routines implemented in OptimPack + * library. + * + *----------------------------------------------------------------------------- + * + * Copyright (c) 2003, Eric THIEBAUT. + * + * This file is part of OptimPack. + * + * OptimPack is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, + * or (at your option) any later version. + * + * OptimPack is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OptimPack (file "LICENSE" in the top source directory); + * if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + * + *----------------------------------------------------------------------------- + * + * $Id$ + * $Log$ + * + *----------------------------------------------------------------------------- + */ + +#ifndef _OPTIMPACK_H +#define _OPTIMPACK_H 1 + +/* Customizable data types: + * OP_INTEGER = data type used to store array indices + * OP_LOGICAL = data type of the result of a logical test + */ +#ifndef OP_INTEGER +# define OP_INTEGER int +#endif +#ifndef OP_LOGICAL +# define OP_LOGICAL int +#endif + + +/* Values returned by OptimPack routines: */ +#define OP_ERROR 1 +#define OP_OK 0 + +#define OP_TRUE 1 +#define OP_FALSE 0 + +/*---------------------------------------------------------------------------*/ +/* USEFUL MACROS */ + +/* OP_STRINGIFY takes an argument and wraps it in "" (double quotation + marks), OP_CONCAT concatenates two arguments. */ +#ifdef __STDC__ +# define OP_STRINGIFY(x) #x +# define OP_CONCAT(a,b) a##b +# define OP_CONCAT2(a,b) a##b +# define OP_CONCAT3(a,b,c) a##b##c +# define OP_CONCAT4(a,b,c,d) a##b##c##d +#else +# define OP_STRINGIFY(x) "x" +# define OP_CONCAT(a,b) a/**/b +# define OP_CONCAT2(a,b) a/**/b +# define OP_CONCAT3(a,b,c) a/**/b/**/c +# define OP_CONCAT4(a,b,c,d) a/**/b/**/c/**/d +#endif + +/* Computes absolute value: */ +#define OP_ABS(a) ((a)>=0?(a):-(a)) + +/* Computes min/max values: */ +#define OP_MIN(a,b) ((a)<=(b)?(a):(b)) +#define OP_MAX(a,b) ((a)>=(b)?(a):(b)) + +/* Computes minimal number of chunks with M elements + needed to store N elements: */ +#define OP_HOW_MANY(n, m) (((n)+((m)-1))/(m)) + +/* Returns N elements rounding up to a multiple of M elements: */ +#define OP_ROUND_UP(n, m) (OP_HOW_MANY(n, m)*(m)) + +/* Offset (in bytes) of member M in structure S: */ +#define OP_OFFSET_OF(s, m) ((size_t) &((s *)0)->m) + +/* C++ needs to know that types and declarations are C, not C++. */ +#ifdef __cplusplus +# define _OP_BEGIN_DECLS extern "C" { +# define _OP_END_DECLS } +#else +# define _OP_BEGIN_DECLS /* empty */ +# define _OP_END_DECLS /* empty */ +#endif +_OP_BEGIN_DECLS + +typedef OP_INTEGER op_integer_t; +typedef OP_LOGICAL op_logical_t; + +/*---------------------------------------------------------------------------*/ +/* LINE SEARCH */ + +#define OP_TASK_START 0 /* first entry, start search */ +#define OP_TASK_FG 1 /* computation of F and G requested */ +#define OP_TASK_NEWX 2 /* new improved solution available for inspection */ +#define OP_TASK_CONV 3 /* search has converged */ +#define OP_TASK_WARN 4 /* search aborted with warning */ +#define OP_TASK_ERROR 5 /* search aborted with error */ + +extern int op_csrch(double f, double g, double *stp_ptr, + double ftol, double gtol, double xtol, + double stpmin, double stpmax, int *task, + char csave[], op_integer_t isave[], double dsave[]); +/* + * DESCRIPTION: + * This subroutine finds a step that satisfies a sufficient decrease + * condition and a curvature condition. + * + * Each call of the subroutine updates an interval with endpoints STX and + * STY. The interval is initially chosen so that it contains a minimizer + * of the modified function: + * + * psi(stp) = f(stp) - f(0) - ftol*stp*g(0) + * + * where g(0) = f'(0). If psi(stp) <= 0 and g(stp) >= 0 for some step, + * then the interval is chosen so that it contains a minimizer of f. The + * algorithm is designed to find a step that satisfies the sufficient + * decrease condition: + * + * f(stp) <= f(0) + ftol*stp*g(0), (1) + * + * and the curvature condition: + * + * abs(g(stp)) <= gtol*abs(g(0)). (2) + * + * Relations (1) and (2) are called the strong Wolfe conditions. If FTOL + * is less than GTOL and if, for example, the function is bounded below, + * then there is always a step which satisfies both conditions. If no + * step can be found that satisfies both conditions, then the algorithm + * stops with a warning. In this case STP only satisfies the sufficient + * decrease condition. + * + * + * ARGUMENTS: + * (Note: the user must not alter TASK and work arrays ISAVE and DSAVE + * between calls.) + * + * F is a double precision variable. On initial entry, F is the value of + * the function at 0. On subsequent entries, F is the value of the + * function at STP. On exit, F is left unchanged. + * + * G is a double precision variable. On initial entry, G is the + * derivative of the function at 0. On subsequent entries, G is the + * derivative of the function at STP. On exit, G is left unchanged. + * + * STP is a double precision variable. On entry, STP is the current + * estimate of a satisfactory step. On initial entry, a positive + * initial estimate must be provided. On exit with TASK=OP_TASK_FG, + * STP is the new estimate of a satisfactory step. On exit with + * TASK=OP_TASK_CONV, STP is left unchanged and satisfies the + * sufficient decrease and curvature condition. On exit with TASK not + * equal to OP_TASK_CONV, STP is left unchanged. + * + * FTOL is a double precision variable. On entry, FTOL specifies a + * nonnegative tolerance for the sufficient decrease condition. On + * exit, FTOL is unchanged. You should take 0 < FTOL < 0.5 + * + * GTOL is a double precision variable. On entry, GTOL specifies a + * nonnegative tolerance for the curvature condition. On exit, GTOL is + * unchanged. You should take FTOL < GTOL < 1. + * + * XTOL is a double precision variable. On entry, XTOL specifies a + * nonnegative relative tolerance for an acceptable step. The + * subroutine exits with a warning if the relative difference between + * STY and STX is less than XTOL. On exit, XTOL is unchanged. + * + * STPMIN is a double precision variable. On entry, STPMIN is a + * nonnegative lower bound for the step. On exit, STPMIN is unchanged. + * + * STPMAX is a double precision variable. On entry, STPMAX is a + * nonnegative upper bound for the step. On exit, STPMAX is unchanged. + * + * TASK is an integer variable. On initial entry, task must be set to + * OP_TASK_START. On exit, TASK indicates the required action: + * + * If TASK=OP_TASK_FG then evaluate the function and derivative at + * STP and call op_dcsrch again. + * + * If TASK=OP_TASK_CONV then the search is successful. + * + * If TASK=OP_TASK_WARN then the subroutine is not able to satisfy + * the convergence conditions. The exit value of stp contains the + * best point found during the search. + * + * If TASK=OP_TASK_ERROR then there is an error in the input + * arguments. + * + * On exit with convergence, a warning or an error, the array CSAVE + * contains additional information (unless it was NULL). + * + * CSAVE is a character work array of, at least, OP_MSG_SIZE elements + * which is used to store a message corresponding to the value of TASK. + * + * ISAVE is an integer work array of, at least, 2 elements. + * + * DSAVE is a double precision work array of, at least, 12 elements. + * + * + * RETURNED VALUE: + * The returned value is less or equal zero to signal an error: + * 0 if STPMAX < STPMIN + * -1 if descent condition violated, i.e. DX*(STP - STX) >= 0 + * -2 if STP outside bracket (STX,STY) + * -3 if STPMIN < 0 + * -4 if XTOL < 0 + * -5 if FTOL <= 0 + * -6 if GTOL <= 0 + * -7 if initial G >= 0 + * -8 if STP > STPMAX + * -9 if STP < STPMIN + * The returned value is greater or equal 3 to indicate that the line + * search cannot converge (warning): + * 3 if STP = STPMIN + * 4 if STP = STPMAX + * 5 if XTOL test satisfied + * 6 if rounding errors prevent progress + * Otherwise (normal return), the returned value is: + * 1 if caller must evaluate (i.e. TASK = OP_TASK_FG) + * 2 if line search has convergenced (i.e. TASK = OP_TASK_CONV) + * + * + * EXEMPLE: + * A typical invocation of op_csrch has the following outline: + * + * task = OP_TASK_START; + * f = ...; // function value for STP=0 + * g = ...; // derivative value for STP=0 + * stp = ...; // guess for next STP value to try (STP > 0.0) + * for (;;) { + * op_csrch(f, g, &stp, ftol, gtol, xtol, stpmin, stpmax, &task, + * csave, isave, dsave); + * if (task == OP_TASK_FG) { + * // Evaluate the function and the gradient at STP. + * f = func(STP); + * g = grad(STP); + * } else if (task == OP_TASK_CONV) { + * // Search has converged. + * break; + * } else if (task == OP_TASK_WARN) { + * // Some problem prevents further progress. + * fprintf(stderr, "warning in %s\n", csave); + * exit(1); + * } else { + * // An error occured. + * fprintf(stderr, "error in %s\n", csave); + * exit(1); + * } + * } + * + * + * REFERENCES: + * [1] Jorge J. Moré and David J. Thuente, "Line search algorithms with + * guaranteed sufficient decrease" in ACM Transactions on + * Mathematical Software (TOMS) Volume 20, Issue 3, Pages 286-307 + * (September 1994). + * + * + * HISTORY: + * MINPACK-1 Project. June 1983. + * Argonne National Laboratory. + * Jorge J. Moré and David J. Thuente. + * + * MINPACK-2 Project. November 1993. + * Argonne National Laboratory and University of Minnesota. + * Brett M. Averick, Richard G. Carter, and Jorge J. Moré. + * + * Yorick translation an improvements. October 2001. + * C-version. February 2003. + * Observatoire de Lyon (France). + * Eric Thiébaut. + */ + +extern int op_cstep(double *stx_ptr, double *fx_ptr, double *dx_ptr, + double *sty_ptr, double *fy_ptr, double *dy_ptr, + double *stp_ptr, double fp, double dp, + int *brackt_ptr, double stpmin, double stpmax, + char *errmsg); +/* + * DESCRIPTION: + * These functions compute a safeguarded step for a search procedure and + * updates an interval that contains a step that satisfies a sufficient + * decrease and a curvature condition [1]. + * + * The parameter STX contains the step with the least function value. If + * BRACKT is set to true (i.e. non-zero) then a minimizer has been + * bracketed in an interval with endpoints STX and STY. The parameter + * STP contains the current step. The subroutine assumes that if BRACKT + * is true then: + * + * min(STX,STY) < STP < max(STX,STY), + * + * and that the derivative at STX is negative in the direction of the + * step. + * + * + * ARGUMENTS: + * STX_PTR, FX_PTR and DX_PTR are the addresses where the values of STX, + * FX and DX are stored. STX, FX, and DX specify the step, the + * function, and the derivative at the best step obtained so far. The + * derivative must be negative in the direction of the step, that is, + * DX and STP-STX must have opposite signs. On output these parameters + * are updated appropriately. + * + * STY_PTR, FY_PTR and DY_PTR are the addresses where the values of STY, + * FY and DY are stored. STY, FY, and DY specify the step, the + * function, and the derivative at the other endpoint of the interval + * of uncertainty. On output these parameters are updated + * appropriately. + * + * STP_PTR is the addresses where the value of STP is stored. STP, FP, + * and DP specify the step, the function, and the derivative at the + * current step. If BRACKT is set true then on input STP must be + * between STX and STY. On output STP (i.e. the value at address + * STP_PTR) is set to the new step. + * + * + * BRACKT_PTR is the addresses where the value of BRACKT is stored. + * BRACKT is a logical variable. On entry, BRACKT specifies if a + * minimizer has been bracketed. Initially BRACKT must be set to false + * (i.e zero). On exit, BRACKT specifies if a minimizer has been + * bracketed. When a minimizer is bracketed, BRACKT (i.e. the value at + * address BRACKT_PTR) is set to true (i.e. non-zero). + * + * STPMIN and STPMAX specify lower and upper bounds for the step. + * + * ERRMSG is a character buffer with at least OP_MSG_SIZE bytes (or NULL + * to have no error message) used to store an error message if the + * routine returns OP_ERROR. + * + * + * RETURNED VALUE: + * The returned value is less or equal zero to signal an error: + * 0 if STPMAX < STPMIN + * -1 if descent condition violated, i.e. DX*(STP - STX) >= 0 + * -2 if STP outside bracket (STX,STY) + * otherwise (no error) the returned value is 1, 2, 3 or 4 to indicate + * which how the new step was guessed (see the code and ref. [1] for + * details). + * + * + * REFERENCES: + * [1] Jorge J. Moré and David J. Thuente, "Line search algorithms with + * guaranteed sufficient decrease" in ACM Transactions on + * Mathematical Software (TOMS) Volume 20, Issue 3, Pages 286-307 + * (September 1994). + * + * + * HISTORY: + * MINPACK-1 Project. June 1983 + * Argonne National Laboratory. + * Jorge J. Moré and David J. Thuente. + * + * MINPACK-2 Project. November 1993. + * Argonne National Laboratory and University of Minnesota. + * Brett M. Averick and Jorge J. Moré. + * + * Yorick translation an improvements. October 2001. + * C-version. February 2003. + * Observatoire de Lyon (France). + * Eric Thiébaut. + */ + +/*---------------------------------------------------------------------------*/ +/* VMLMB - limited memory variable metric method (BFGS) + with/without bound constraints */ + +#define OP_VMLMB_CSAVE_NUMBER OP_MSG_SIZE +#define OP_VMLMB_ISAVE_NUMBER 12 +#define OP_VMLMB_DSAVE_NUMBER(n, m) (27 + (n) + 2*(m)*((n) + 1)) + +extern int op_vmlmb_first(op_integer_t n, op_integer_t m, + double fatol, double frtol, + double sftol, double sgtol, double sxtol, + double epsilon, double costheta, + char csave[], op_integer_t isave[], double dsave[]); +extern int op_vmlmb_next(double x[], double *f, double g[], + op_logical_t active[], const double h[], + char csave[], op_integer_t isave[], double dsave[]); +/* VMLM-B computes a local minimizer of a function of N variables by a + * limited memory variable metric (BFGS) method; optionally, the parameters + * may be bounded. The user must evaluate the function and the gradient. + * + * VMLM-B is implemented via two functions: op_vmlmb_first for + * initialization and op_vmlmb_next for further iterations. These + * functions use reverse communication. The user must choose an initial + * approximation X to the minimizer, evaluate the function and the gradient + * at X, and make the initial call with TASK set to "start". On exit TASK + * indicates the required action. + * + * The arguments are: + * + * N is the number of parameters. + * + * M is the number of correction pairs to remember in order to compute + * the limited memory variable metric (BFGS) approximation of the + * inverse of the Hessian. For large problems, M = 3 to 5 gives good + * results. For small problems, M should be less or equal N. The + * larger is M (and N) the more computer memory will be needed to + * store the workspaces (see DSAVE). + * + * FRTOL is the relative error desired in the function (e.g. + * FRTOL=1e-8). Convergence occurs if the estimate of the relative + * error between F(X) and F(XSOL), where XSOL is a local minimizer, + * is less or equal FRTOL. FRTOL must have a non-negative floating + * point value. + * + * FATOL is the absolute error desired in the function (e.g. FATOL=0.0). + * Convergence occurs if the estimate of the absolute error between + * F(X) and F(XSOL), where XSOL is a local minimizer, is less or + * equal FATOL. FATOL must have a non-negative floating point value. + * + * SFTOL, SGTOL, and SXTOL are tolerances for the line search subroutine + * (see op_csrch). Recommended values: SFTOL=0.001, SGTOL=0.9, + * SXTOL=0.1 (other values may be more suitable for highly + * non-quadratic penalty function). + * + * EPSILON is a small (strictly positive) value used to discard BFGS updates + * that may yield a non positive definite Hessian approximation. + * + * COSTHETA is a small value, in the range [0,1), equals to the cosine of + * the maximum angle between the search direction and the anti-gradient. + * The BFGS recursion is restarted, whenever the search direction is not + * sufficiently "descending". + * + * CSAVE is a character workspace array of length OP_VMLMB_CSAVE_NUMBER + * (same as OP_MSG_SIZE) which is used to store additional + * information on exit with convergence, a warning or an error. + * + * ISAVE is an integer workspace array of length OP_VMLMB_ISAVE_NUMBER. + * + * DSAVE is a floating point workspace array of length equal to the value + * returned by the macro OP_VMLMB_DSAVE_NUMBER(N, M): + * 26 + N + 2*M*(N + 1). + * + * X is a double precision array of length N. On entry, X is an + * approximation to the solution. On exit with TASK=OP_TASK_CONV, X + * is the current approximation. + * + * F is the address of a double precision variable. On entry, F is the + * value of the function at X. On final exit, F is the function + * value at X. + * + * G is a double precision array of length N. On entry, G is the value + * of the gradient at X. On final exit, G is the value of the + * gradient at X. + * + * ACTIVE is an optional integer array with length N provided by the + * caller if the values in X has bounds. If the parameters have no + * bounds, ACTIVE should be NULL (unconstrained minimization). + * Otherwise, elements set to zero in ACTIVE indicate that the + * corresponding values in X has reached a bound and should not be + * changed during the next step because the gradient has the wrong + * sign (i.e. the steepest descent direction would violate the bound + * constraints): + * ACTIVE[i] = 0 if i-th value has a lower bound XLO[i] + * and X[i]=XLO[i] and G[i]>=0 + * 0 if i-th value has an upper bound XHI[i] + * and X[i]=XHI[i] and G[i]<=0 + * 1 (or any non-zero value) otherwise + * + * ACTIVE needs only to be computed (and specified) the first time + * op_vmlmb_next is called and when TASK=OP_TASK_NEWX (i.e. after a + * successful step). ACTIVE may also be specified when + * TASK=OP_TASK_CONV (i.e. after convergence if caller wish to + * continue with minimization). If X has (some) bounds, the caller + * is responsible for applying the bounds to X before evaluating the + * function value F and the gradient G (i.e. when TASK=OP_TASK_FG), + * e.g.: + * if (X[i] < XLO[i]) X[i] = XLO[i]; + * if (X[i] > XHI[i]) X[i] = XHI[i]; + * + * If H is not specified (i.e. H is NULL) or if H[i] > 0 for all i + * such that ACTIVE[i] is non-zero, then ACTIVE is left unchanged. + * + * H is an optional double precision array with length N provided by the + * caller and such that diag(H) is an approximation of the inverse of + * the Hessian matrix. If H is NULL, then the inverse of the Hessian + * is approximated by a simple rescaling using Shanno & Phua formula. + * Otherwise, if ACTIVE is NULL, all elements of H must be strictly + * greater than zero; else ACTIVE[i] is set to zero if H[i] <= 0 + * (this is the only case where ACTIVE is modified). As for ACTIVE, + * H needs only to be specifed the first time op_vmlmb is called and + * when JOB=2. + * + * TASK is the value returned by op_vmlmb_first and op_vmlmb_next. It + * can have one of the following values: + * OP_TASK_FG - caller must evaluate the function and gradient at + * X and call op_vmlm_next. + * OP_TASK_NEWX - a new iterate has been computed. The + * approximation X, function F, and gradient G are available + * for examination. + * + * OP_TASK_CONV - the search is successful. The solution, + * function value and gradient are available in X, F and G. + * + * OP_TASK_WARN - VMLMB is not able to satisfy the convergence + * conditions. The exit value of X contains the best + * approximation found so far. Warning message is available + * in CSAVE. + * OP_TASK_ERROR then there is an error in the input arguments. + * Error message is available in CSAVE. + * + * The caller must not modify the workspace arrays CSAVE, ISAVE and DSAVE + * between calls to op_vmlmb_first and further calls to op_vmlmb_next. + * + * A typical invocation of VMLMB for unconstrained minimization has the + * following outline: + * + * // Choose a starting vector: + * for (i=0 ; i XMIN[i] || G[i] < 0) && (X[i] < XMAX[i] || G[i] > 0) */ + +extern op_integer_t op_bounds_check(op_integer_t n, const double xmin[], + const double xmax[]); +/* Check correctness of bounds XMIN and XMAX (see op_bounds_apply for + the definition of the arguments). This function returns -1 if the + bounds are such that XMIN[i] <= XMAX[i] for all i=0,...,N-1; + otherwise, the function return the value i of the first index (i >= + 0) for which the condition is violated. */ + +extern void op_lower_bound_apply(op_integer_t n, double x[], double xmin); +extern void op_lower_bound_active(op_integer_t n, op_logical_t active[], + const double x[], const double g[], + double xmin); +/* These routines are similar to op_bounds_apply and op_bounds_active but + for a scalar lower bound XMIN that is the same for all parameters X. */ + +extern void op_upper_bound_apply(op_integer_t n, double x[], double xmax); +extern void op_upper_bound_active(op_integer_t n, op_logical_t active[], + const double x[], const double g[], + double xmax); +/* These routines are similar to op_bounds_apply and op_bounds_active but + for a scalar upper bound XMAX that is the same for all parameters X. */ + +extern void op_interval_apply(op_integer_t n, double x[], double a, double b); +extern void op_interval_active(op_integer_t n, op_logical_t active[], + const double x[], const double g[], + double a, double b); +/* These routines are similar to op_bounds_apply and op_bounds_active + but for a scalar lower bound XMIN=min(A,B) and a scalar upper bound + XMAX=max(A,B) that are the same for all parameters X. */ + +/*---------------------------------------------------------------------------*/ +/* UTILITIES */ + +#define OP_MSG_LEN 127 +#define OP_MSG_SIZE (OP_MSG_LEN + 1) +extern int op_error(char *buf, const char *errmsg); +/* Copy ERRMSG in BUF and return OP_ERROR. BUF must have at least + OP_MSG_SIZE bytes. At most OP_MSG_SIZE - 1 bytes get copied and BUF is + guaranted to be 0-terminated. */ + +extern void op_mcopy(const char *msg, char *buf); +/* Copy string MSG into BUF (if non-NULL). BUF must have at least + OP_MSG_SIZE bytes. At most OP_MSG_SIZE - 1 bytes get copied and BUF is + guaranted to be 0-terminated. */ + +extern double op_dnrm2(op_integer_t n, const double x[]); +/* Returns the Euclidian norm of X: sqrt(X'.X), taking care of overflows. */ + + +extern void op_dcopy(op_integer_t n, const double x[], double y[]); +extern void op_dcopy_active(op_integer_t n, const double x[], + double y[], const op_logical_t active[]); +/* Copy elements of X into Y. Does Y[i] = X[i] for i=0,...,N-1. If ACTIVE + is non-NULL, only elements for which ACTIVE[i] is true (non-zero) are + taken into account. */ + +extern void op_daxpy(op_integer_t n, double a, + const double x[], double y[]); +extern void op_daxpy_active(op_integer_t n, double a, + const double x[], double y[], + const op_logical_t active[]); +/* Does Y[i] += A*X[i] for i=0,...,N-1. If ACTIVE is non-NULL, only + elements for which ACTIVE[i] is true (non-zero) are taken into + account. */ + +extern double op_ddot(op_integer_t n, const double x[], const double y[]); +extern double op_ddot_active(op_integer_t n, const double x[], + const double y[], const op_logical_t active[]); +/* Computes dot product of N-element vectors X and Y. If ACTIVE is + non-NULL, only elements for which ACTIVE[i] is true (non-zero) are taken + into account. */ + +extern void op_dscal(op_integer_t n, double a, double x[]); +/* Scales N-element vector X by scalar A. */ + +/*---------------------------------------------------------------------------*/ +/* YORICK-LIKE ROUTINES */ + +extern int op_anyof(op_integer_t n, const double x[]); +/* Returns true (non-zero) if any element of X is non-zero; returns faslse + (zero) otherwise. N is the number of elements of X. */ + +extern int op_noneof(op_integer_t n, const double x[]); +/* Returns true (non-zero) if all elements of X are zero; returns faslse + (zero) otherwise. N is the number of elements of X. */ + +extern int op_allof(op_integer_t n, const double x[]); +/* Returns true (non-zero) if all elements of X are non-zero; returns faslse + (zero) otherwise. N is the number of elements of X. */ + +/*---------------------------------------------------------------------------*/ +_OP_END_DECLS +#endif /* _OPTIMPACK_H */ diff -Nru yorick-optimpack-1.3.2+dfsg/optimpack1/op_utils.c yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/op_utils.c --- yorick-optimpack-1.3.2+dfsg/optimpack1/op_utils.c 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/op_utils.c 2003-03-21 11:56:56.000000000 +0000 @@ -0,0 +1,326 @@ +/* + * op_utils -- + * + * Utilities routines for OptimPack library. + * + *----------------------------------------------------------------------------- + * + * Copyright (c) 2003, Eric THIEBAUT. + * + * This file is part of OptimPack. + * + * OptimPack is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, + * or (at your option) any later version. + * + * OptimPack is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OptimPack (file "LICENSE" in the top source directory); + * if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + * + *----------------------------------------------------------------------------- + * + * $Id$ + * $Log$ + * + *----------------------------------------------------------------------------- + */ + +#include +#include +#include "optimpack.h" + +/*---------------------------------------------------------------------------*/ + +int op_error(char *buf, const char *errmsg) +{ + if (buf) { + if (! errmsg) errmsg = "unknown error"; + strncpy(buf, errmsg, OP_MSG_LEN); + buf[OP_MSG_LEN] = 0; + } + return OP_ERROR; +} + +void op_mcopy(const char *msg, char *buf) +{ + if (buf) { + if (msg) { + strncpy(buf, msg, OP_MSG_LEN); + buf[OP_MSG_LEN] = 0; + } else { + buf[0] = 0; + } + } +} + +/*---------------------------------------------------------------------------*/ +/* APPLY BOUND CONSTRAINTS */ + +#define ACTIVE_LO_GRD(x, lo, g) ((x) > (lo) || (g) < zero) +#define ACTIVE_HI_GRD(x, hi, g) ((x) < (hi) || (g) > zero) +#define ACTIVE_LO_DIR(x, lo, d) ((x) > (lo) || (d) > zero) +#define ACTIVE_HI_DIR(x, hi, d) ((x) < (hi) || (d) < zero) + +op_integer_t op_bounds_check(op_integer_t n, const double xmin[], + const double xmax[]) +{ + op_integer_t i; + if (xmin && xmax) { + for (i=0 ; i xmax[i]) return i; + } + } + return -1; +} + +void op_bounds_apply(op_integer_t n, double x[], + const double xmin[], const double xmax[]) +{ + op_integer_t i; + if (xmin) { + if (xmax) { + /* Lower _and_ upper bounds. */ + for (i=0 ; i xmax[i]) x[i] = xmax[i]; + } + } else { + /* Only lower bounds. */ + for (i=0 ; i xmax[i]) x[i] = xmax[i]; + } + } +} + +void op_bounds_active(op_integer_t n, op_logical_t active[], + const double x[], const double g[], + const double xmin[], const double xmax[]) +{ + const double zero = 0.0; + op_integer_t i; + + if (xmin) { + if (xmax) { + /* Lower _and_ upper bounds. */ + for (i=0 ; i xmax) x[i] = xmax; +} + +void op_upper_bound_active(op_integer_t n, op_logical_t active[], + const double x[], const double g[], + double xmax) +{ + const double zero = 0.0; + op_integer_t i; + for (i=0 ; i b) { double c=a; a=b; b=c; } + for (i=0 ; i b) x[i] = b; + } +} + +void op_interval_active(op_integer_t n, op_logical_t active[], + const double x[], const double g[], + double a, double b) +{ + const double zero = 0.0; + op_integer_t i; + if (a > b) { double c=a; a=b; b=c; } + for (i=0 ; i 1) { + op_integer_t i; + double ssq = zero, scale = zero; + for (i=0 ; i +#include +#include +#include "optimpack.h" + +#define op_dcopy(n, x, y) memcpy((y), (x), (n)*sizeof(double)) + +/*---------------------------------------------------------------------------*/ +/* LIMITED MEMORY VARIABLE METRIC METHOD (BFGS) + WITH/WITHOUT BOUND CONSTRAINTS */ + +/* Indices 0-1 in ISAVE are reserved for op_cshrc. */ +#define INDEX_OF_TASK 2 +#define INDEX_OF_STAGE 3 +#define INDEX_OF_M 4 +#define INDEX_OF_N 5 +#define INDEX_OF_ITER 6 +#define INDEX_OF_MARK 7 +#define INDEX_OF_MP 8 +#define INDEX_OF_FLAGS 9 +#define INDEX_OF_NEVALS 10 +#define INDEX_OF_NRESTARTS 11 +#if (OP_VMLMB_ISAVE_NUMBER != INDEX_OF_NRESTARTS + 1) +# error bad ISAVE settings +#endif + +/* Indices 0-11 in ISAVE are reserved for op_cshrc. */ +#define INDEX_OF_SFTOL 12 +#define INDEX_OF_SGTOL 13 +#define INDEX_OF_SXTOL 14 +#define INDEX_OF_FRTOL 15 +#define INDEX_OF_FATOL 16 +#define INDEX_OF_FMIN 17 +#define INDEX_OF_F0 18 +#define INDEX_OF_GD 19 +#define INDEX_OF_GD0 20 +#define INDEX_OF_STP 21 +#define INDEX_OF_STPMIN 22 +#define INDEX_OF_STPMAX 23 +#define INDEX_OF_EPSILON 24 +#define INDEX_OF_COSTHETA 25 +#define INDEX_OF_DELTA 26 +#define INDEX_OF_WORK 27 /* must be the last one */ +#if (OP_VMLMB_DSAVE_NUMBER(0,0) != INDEX_OF_WORK) +# error bad DSAVE settings +#endif + +#define FLAG(n) (1 << (n)) +#define FLAG_IS_SET(value, flag) (((value) & (flag)) != 0) +#define FLAG_FMIN FLAG(0) +#define FLAG_DELTA FLAG(1) + +#define SET_TASK(val, str) \ + (op_mcopy("op_vmlmb_first: " str, csave), task=(val)) + +int op_vmlmb_first(op_integer_t n, op_integer_t m, + double fatol, double frtol, + double sftol, double sgtol, double sxtol, + double epsilon, double costheta, + char csave[], op_integer_t isave[], double dsave[]) +{ + int task = OP_TASK_FG; + if (n <= 0) return SET_TASK(OP_TASK_ERROR, "N <= 0"); + if (m <= 0) return SET_TASK(OP_TASK_ERROR, "M <= 0"); + if (fatol < 0.0) return SET_TASK(OP_TASK_ERROR, "FATOL < 0"); + if (frtol < 0.0) return SET_TASK(OP_TASK_ERROR, "FRTOL < 0"); + if (sxtol <= 0.0) return SET_TASK(OP_TASK_ERROR, "SXTOL <= 0"); + if (sxtol >= 1.0) return SET_TASK(OP_TASK_ERROR, "SXTOL >= 1"); + if (sftol <= 0.0) return SET_TASK(OP_TASK_ERROR, "SFTOL <= 0"); + if (sftol >= 1.0) return SET_TASK(OP_TASK_ERROR, "SFTOL >= 1"); + if (sgtol <= 0.0) return SET_TASK(OP_TASK_ERROR, "SGTOL <= 0"); + if (sgtol >= 1.0) return SET_TASK(OP_TASK_ERROR, "SGTOL >= 1"); + if (sftol >= sgtol) return SET_TASK(OP_TASK_ERROR, "SFTOL >= SGTOL"); + if (epsilon <= 0.0) return SET_TASK(OP_TASK_ERROR, "EPSILON <= 0"); + if (costheta < 0.0) return SET_TASK(OP_TASK_ERROR, "COSTHETA < 0"); + if (costheta >= 1.0) return SET_TASK(OP_TASK_ERROR, "COSTHETA >= 1"); + + isave[INDEX_OF_TASK] = OP_TASK_FG; + isave[INDEX_OF_STAGE] = 0L; + isave[INDEX_OF_M] = m; + isave[INDEX_OF_N] = n; + isave[INDEX_OF_ITER] = 0L; + isave[INDEX_OF_MARK] = 0L; + isave[INDEX_OF_MP] = 0L; + isave[INDEX_OF_FLAGS] = 0L; + isave[INDEX_OF_NEVALS] = 0L; + isave[INDEX_OF_NRESTARTS] = 0L; + + dsave[INDEX_OF_SFTOL] = sftol; + dsave[INDEX_OF_SGTOL] = sgtol; + dsave[INDEX_OF_SXTOL] = sxtol; + dsave[INDEX_OF_FRTOL] = frtol; + dsave[INDEX_OF_FATOL] = fatol; + dsave[INDEX_OF_FMIN] = 0.0; + dsave[INDEX_OF_F0] = 0.0; + dsave[INDEX_OF_GD] = 0.0; + dsave[INDEX_OF_GD0] = 0.0; + dsave[INDEX_OF_STP] = 0.0; + dsave[INDEX_OF_STPMIN] = 0.0; + dsave[INDEX_OF_STPMAX] = 0.0; + dsave[INDEX_OF_EPSILON] = epsilon; + dsave[INDEX_OF_COSTHETA] = costheta; + dsave[INDEX_OF_DELTA] = 0.0; + + return isave[INDEX_OF_TASK]; +} +#undef SET_TASK + +/*---------------------------------------------------------------------------*/ + +static int check_active(op_integer_t n, op_logical_t active[], const double h[], + int *task, char csave[]); +/* Check H and ACTIVE arrays, possibly fix ACTIVE, returns non-zero + in case of error. */ + +#define S(K) &s[(K)*n] +#define Y(K) &y[(K)*n] +#define SET_TASK(val, str) (op_mcopy("op_vmlmb_next: " str, csave), task=(val)) + +int op_vmlmb_next(double x[], double *f, double g[], + op_logical_t active[], const double h[], + char csave[], op_integer_t isave[], double dsave[]) +{ + const double zero = 0.0; + + /* Get local variables. (Note: depending on the value of STAGE, it is + possible to restore only _some_ of theses variables, but this would + result in a less readable code with negligible speedup gain.) */ + int task = isave[INDEX_OF_TASK]; + int stage = isave[INDEX_OF_STAGE]; + op_integer_t m = isave[INDEX_OF_M]; + op_integer_t n = isave[INDEX_OF_N]; + op_integer_t iter = isave[INDEX_OF_ITER]; + op_integer_t mark = isave[INDEX_OF_MARK]; + op_integer_t mp = isave[INDEX_OF_MP]; + op_integer_t flags = isave[INDEX_OF_FLAGS]; + op_integer_t nevals = isave[INDEX_OF_NEVALS]; + op_integer_t nrestarts = isave[INDEX_OF_NRESTARTS]; + int have_fmin = ((flags & FLAG_FMIN) != 0); + int delta_set = ((flags & FLAG_DELTA) != 0); + + double sftol = dsave[INDEX_OF_SFTOL]; + double sgtol = dsave[INDEX_OF_SGTOL]; + double sxtol = dsave[INDEX_OF_SXTOL]; + double fmin = (have_fmin ? dsave[INDEX_OF_FMIN] : zero); + double frtol = dsave[INDEX_OF_FRTOL]; + double fatol = dsave[INDEX_OF_FATOL]; + double f0 = dsave[INDEX_OF_F0]; + double gd = dsave[INDEX_OF_GD]; + double gd0 = dsave[INDEX_OF_GD0]; + double stp = dsave[INDEX_OF_STP]; + double stpmin = dsave[INDEX_OF_STPMIN]; + double stpmax = dsave[INDEX_OF_STPMAX]; + double epsilon = dsave[INDEX_OF_EPSILON]; + double costheta = dsave[INDEX_OF_COSTHETA]; + double delta = (delta_set ? dsave[INDEX_OF_DELTA] : zero); + /*double delta = dsave[INDEX_OF_DELTA];*/ + + double gpnorm, xnorm, snorm; + + double *alpha = dsave + INDEX_OF_WORK; + double *rho = alpha + m; + double *x0 = rho + m; + double *s = x0 + n; + double *y = s + n*m; + double *ptr; + int info; + op_integer_t i, j, k; + + /* + * Differences with original FORTRAN version: + * + * (5) The effective step is used instead of the search direction times + * the step size (useful, e.g., when parameter constraints are imposed + * by projections or when rounding or truncation errors dominate). + * + * (6) It is possible to use an active subset of parameters, e.g. to apply + * bound constraints. + * + * (7) Discard pairs for which RHO = S'.Y <= 0 (i.e. H must be positive + * definite). + * + * STAGE is: 0 - first entry + * 1 - start line search + * 2 - line search in progress + * 3 - line search converged + * + * S(MARK) = -D(k) where D(k) is the k-th search direction and MARK is + * current iteration index (modulo M). + */ + + if (task == OP_TASK_FG) { + ++nevals; + } + + if (stage == 0) { + /* First search direction is the (normalized) steepest descent. */ + if (have_fmin && *f <= fmin) { + SET_TASK(OP_TASK_ERROR, "initial F <= FMIN"); + goto done; + } + iter = 0L; /* number of successful iterations */ + nevals = 1L; + nrestarts = 0L; + restart: + mark = 0; /* index of current direction */ + mp = 0; /* number of saved directions */ + if (check_active(n, active, h, &task, csave) != 0) goto done; + op_dcopy_active(n, g, S(mark), active); /* steepest ascent */ + gpnorm = op_dnrm2(n, S(mark)); /* norm of the projected gradient */ + if (gpnorm == zero) { + SET_TASK(OP_TASK_CONV, "local minimum found"); + goto done; + } + if (h == NULL) { + /* No preconditioning, use scaled steepest ascent. */ + xnorm = op_dnrm2(n, x); + if (xnorm > zero) { /* FIXME: use parameter (not constant) and better test */ + snorm = 1E-2*xnorm; + } else { + snorm = 1.0; + } + op_dscal(n, snorm/gpnorm, S(mark)); + gd = -snorm*gpnorm; + } else { + /* Use diagonal preconditioner to compute initial search direction. */ + for (ptr = S(mark), i = 0; i < n; ++i) { + ptr[i] *= h[i]; + } + gd = -op_ddot(n, g, S(mark)); + if (gd >= zero) { + SET_TASK(OP_TASK_ERROR, "preconditioner is not positive definite"); + goto done; + } + } + stage = 1; /* set STAGE to initialize the line search */ + + } else if (stage == 3) { + + /* Previous step was successful. Compute new search direction H(k).g(k) + * based on the two-loop recursion L-BFGS formula. H(k) is the limited + * memory BFGS approximation of the inverse Hessian, g(k) is the + * gradient at k-th step. H(k) is approximated by using the M last + * pairs (s, y) where: + * + * s(j) = x(j+1) - x(j) + * y(j) = g(j+1) - g(j) + * + * The two-loop recursion algorithm writes: + * + * 1- start with current gradient: + * v := g(k) + * + * 2- for j = k-1, ..., k-m + * rho(j) = s(j)'.y(j) (save rho(j)) + * alpha(j) = (s(j)'.v)/rho(j) (save alpha(j)) + * v := v - alpha(j) y(j) + * + * 3- apply approximation of inverse k-th Hessian: + * v := H0(k).v + * for instance: + * v := (rho(k-1)/(y(k-1)'.y(k-1))) v + * + * 4- for j = k-m, ..., k-1 + * v := v + (alpha(j) - (y(j)'.v)/rho(j)) s(j) + * + * Note: in fact, this program saves -S and -Y, but by looking at + * above relations it is clear that this change of sign: + * - has no influence on RHO, and dot products between S and Y; + * - changes the sign of ALPHA but not that of ALPHA(j) times + * S(j) or Y(j); + * the two-loop recursion therefore involves the same equations + * with: s(j) = x(j+1) - x(j) and y(j) = g(j+1) - g(j) + * or with: s(j) = x(j) - x(j+1) and y(j) = g(j) - g(j+1). + */ + double *v = x0; + double gamma = zero; + op_integer_t mm = mark + m; + + if (check_active(n, active, h, &task, csave) != 0) goto done; + op_dcopy_active(n, g, v, active); + for (k = 0; k < mp; ++k) { + j = (mm - k)%m; + if (active != NULL) rho[j] = op_ddot_active(n, S(j), Y(j), active); + if (rho[j] <= zero) continue; /* FIXME: should be relative to |y|^2 or |s|^2 */ + alpha[j] = op_ddot(n, S(j), v)/rho[j]; + op_daxpy_active(n, -alpha[j], Y(j), v, active); + if (gamma <= zero) gamma = rho[j]/op_ddot_active(n, Y(j), Y(j), active); + } + if (h != NULL) { + /* Apply diagonal preconditioner. */ + for (i = 0; i < n; ++i) { + v[i] *= h[i]; + } + } else if (gamma > zero) { + /* Apply initial H (i.e. just scale V) and perform the second stage of + the 2-loop recursion. */ + op_dscal(n, gamma, v); + } else { + /* All correction pairs are invalid: restart the BFGS recursion. */ + ++nrestarts; + goto restart; + } + for (k = mp - 1; k >= 0; --k) { + j = (mm - k)%m; + if (rho[j] <= zero) continue; /* FIXME: see above */ + op_daxpy_active(n, alpha[j] - op_ddot(n, Y(j), v)/rho[j], + S(j), v, active); + } + + /* Compute dot product of gradient and search direction. */ + gd = -op_ddot(n, g, v); /* FIXME: should be GP? */ + if (gd >= zero) { + /* L-BFGS recursion yields a search direction which is not a descent. + We therefore restart the algorithm with steepest descent. */ + ++nrestarts; + goto restart; + } + + /* Save anti-search direction (in place of oldest memorized S). */ + mark = (mark + 1)%m; + op_dcopy(n, v, S(mark)); + + /* Set STAGE to initialize the line search. */ + stage = 1; + + } else /* FIXME: check stage? */ { + /* Line search in progress: compute derivative with respect to step + size. */ + gd = -op_ddot(n, g, S(mark)); /* FIXME: should be GP? */ + } + + if (stage == 1) { + /* Set variables so as to initialize the line search subroutine. */ + f0 = *f; + gd0 = gd; + stpmin = zero; +#if 1 + stpmax = 1E10; /* FIXME: use a suitable value */ +#else + if (have_fmin) { + stpmax = (fmin - f0)/(sgtol*gd0); + } else { + double temp = fabs(f0); + if (temp < 1.0) { + temp = 1.0; + } + stpmax = temp/(sgtol*gd0); + } +#endif + stp = OP_MIN(1.0, stpmax); + op_dcopy(n, x, x0); /* save parameters */ + op_dcopy(n, g, Y(mark)); /* save gradient in place of oldest Y */ + stage = 2; + task = OP_TASK_START; /* set TASK so as to start line search */ + } else { + task = OP_TASK_FG; /* set TASK so as to continue line search */ + } + + if (stage == 2) { + /* Determine the line search parameter. */ + if (have_fmin && *f < fmin) { + SET_TASK(OP_TASK_WARN, "F < FMIN"); + } else { + /* Call line search iterator. */ + info = op_csrch(*f, gd, &stp, sftol, sgtol, sxtol, stpmin, stpmax, &task, + csave, isave, dsave); + if (info == 1) { + /* Compute the new iterate. */ + for (ptr = S(mark), i = 0; i < n; ++i) { + /* FIXME: use DCOPY and DAXPY */ + x[i] = x0[i] - stp*ptr[i]; + } + } else if (info == 2 || info == 5) { + /* Line search has converged. */ + ++iter; + if (mp < m) ++mp; + stage = 3; + + /* Compute the step and gradient change. Note: we always compute the + effective step (parameter difference) to account for bound + constraints and, at least, numerical rounding or truncation + errors. */ + for (ptr = Y(mark), i = 0; i < n; ++i) ptr[i] -= g[i]; + for (ptr = S(mark), i = 0; i < n; ++i) ptr[i] = x0[i] - x[i]; + if (active == NULL) rho[mark] = op_ddot(n, Y(mark), S(mark)); + + /* Test for global convergence otherwise set TASK to signal a new + iterate. Set STAGE to compute a new search direction. */ + if (op_noneof(n, S(mark))) { + SET_TASK(OP_TASK_WARN, "no parameter change"); + } else if (op_noneof(n, Y(mark))) { + SET_TASK(OP_TASK_WARN, "no gradient change"); + } else { + double change1 = fabs(*f - f0); + double change2 = fabs(stp*gd0); + double change = OP_MAX(change1, change2); + if (change <= frtol*fabs(f0)) { + SET_TASK(OP_TASK_CONV, "FRTOL test satisfied"); + } else if (change <= fatol) { + SET_TASK(OP_TASK_CONV, "FATOL test satisfied"); + } else { + SET_TASK(OP_TASK_NEWX, + "new improved solution available for inspection"); + } + } + } else if (info >= 3) { + /* INFO >= 3 means that line search could not converge. + Restore solution at start of line search. */ + op_dcopy(n, x0, x); + op_dcopy(n, Y(mark), g); + *f = f0; + } + } + } + + /* Save local variables (but constant ones) and return TASK. */ + done: + isave[INDEX_OF_TASK] = task; /* FIXME: task not needed, for debug only? */ + isave[INDEX_OF_STAGE] = stage; + isave[INDEX_OF_ITER] = iter; + isave[INDEX_OF_MARK] = mark; + isave[INDEX_OF_MP] = mp; +#if 0 + isave[INDEX_OF_FLAGS] = flags; /* constant */ +#endif + isave[INDEX_OF_NEVALS] = nevals; + isave[INDEX_OF_NRESTARTS] = nrestarts; + +#if 0 + dsave[INDEX_OF_SFTOL] = sftol; /* constant */ + dsave[INDEX_OF_SGTOL] = sgtol; /* constant */ + dsave[INDEX_OF_SXTOL] = sxtol; /* constant */ + dsave[INDEX_OF_FRTOL] = frtol; /* constant */ + dsave[INDEX_OF_FATOL] = fatol; /* constant */ + dsave[INDEX_OF_FMIN] = fmin; /* constant */ +#endif + dsave[INDEX_OF_F0] = f0; + dsave[INDEX_OF_GD] = gd; + dsave[INDEX_OF_GD0] = gd0; + dsave[INDEX_OF_STP] = stp; + dsave[INDEX_OF_STPMIN] = stpmin; + dsave[INDEX_OF_STPMAX] = stpmax; +#if 0 + dsave[INDEX_OF_EPSILON] = epsilon; /* constant */ + dsave[INDEX_OF_COSTHETA] = costheta; /* constant */ +#endif + return task; +} + +#undef SET_TASK +#undef Y +#undef S + +/*---------------------------------------------------------------------------*/ + +static int check_active(op_integer_t n, op_logical_t active[], + const double h[], int *task, char csave[]) +{ + if (h != NULL) { + const double zero = 0.0; + op_integer_t i; + if (active != NULL) { + /* fix ACTIVE array */ + for (i = 0; i < n; ++i) { + if (active[i] && h[i] <= zero) { + active[i] = 0; + } + } + } else { + /* check that H is positive definite */ + for (i = 0; i < n; ++i) { + if (h[i] <= zero) { + op_mcopy("op_vmlmb_next: H is not positive definite", csave); + *task = OP_TASK_ERROR; + return -1; + } + } + + } + } + return 0; +} + +/*---------------------------------------------------------------------------*/ + +#define EMIT_CODE(name, NAME) \ +int op_vmlmb_set_##name(const char csave[], op_integer_t isave[], \ + double dsave[], double new_value, double *old_value) \ +{ \ + int test = ((isave[INDEX_OF_FLAGS] & FLAG_##NAME) != 0); \ + if (test && old_value != (double *)NULL) { \ + *old_value = dsave[INDEX_OF_##NAME]; \ + } \ + dsave[INDEX_OF_##NAME] = new_value; \ + isave[INDEX_OF_FLAGS] |= FLAG_##NAME; \ + return test; \ +} \ +int op_vmlmb_get_##name(const char csave[], const op_integer_t isave[], \ + const double dsave[], double *ptr) \ +{ \ + int test = ((isave[INDEX_OF_FLAGS] & FLAG_##NAME) != 0); \ + if (test && ptr != (double *)NULL) { \ + *ptr = dsave[INDEX_OF_##NAME]; \ + } \ + return test; \ +} +EMIT_CODE(fmin, FMIN) +EMIT_CODE(delta, DELTA) +#undef EMIT_CODE + +#define EMIT_CODE(type, foo, FOO, save) \ +type OP_CONCAT(op_vmlmb_get_,foo)(const char csave[], \ + const op_integer_t isave[], \ + const double dsave[]) \ +{ return dsave[OP_CONCAT(INDEX_OF_,FOO)]; } +EMIT_CODE(double, sftol, SFTOL, dsave) +EMIT_CODE(double, sgtol, SGTOL, dsave) +EMIT_CODE(double, sxtol, SXTOL, dsave) +EMIT_CODE(double, frtol, FRTOL, dsave) +EMIT_CODE(double, fatol, FATOL, dsave) +EMIT_CODE(double, step, STP, dsave) +EMIT_CODE(double, epsilon, EPSILON, dsave) +EMIT_CODE(double, costheta, COSTHETA, dsave) +EMIT_CODE(op_integer_t, iter, ITER, isave) +EMIT_CODE(op_integer_t, nevals, NEVALS, isave) +EMIT_CODE(op_integer_t, nrestarts, NRESTARTS, isave) +#undef EMIT_CODE + +/*---------------------------------------------------------------------------*/ + +/* + * Local Variables: + * mode: C + * tab-width: 8 + * c-basic-offset: 2 + * fill-column: 78 + * coding: latin-1 + * End: + */ diff -Nru yorick-optimpack-1.3.2+dfsg/optimpack1/README yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/README --- yorick-optimpack-1.3.2+dfsg/optimpack1/README 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/README 2008-01-31 15:03:36.000000000 +0000 @@ -0,0 +1,109 @@ + + OptimPack + (version 1.3) + by Eric Thiébaut + + + This is OptimPack, a C library for optimization. This version + implements: + + - inexact line search (see ref. [1]); + + - limited memory BFGS (variable metric) possibly with bound constraints + and/or preconditioning; + + In order to make embedding OptimPack into another language as easy as + possible, the routines use reverse communication: all local variables + needed by the optimization routines get saved into workspace arrays + provided by the caller and the optimization routines never explicitely + call the penalty function to optimize. + + Most of the documention is in the header file "optimpack.h". + + Directory idl contains an implementation of OptimPack support in IDL + (using CALL_EXTERNAL). + + Directory yorick contains an implementation of OptimPack support in + Yorick. + + +REFERENCES + + [1] Jorge J. Moré and David J. Thuente, "Line search algorithms with + guaranteed sufficient decrease" in ACM Transactions on Mathematical + Software (TOMS) Volume 20, Issue 3, Pages 286-307 (September 1994). + + +INSTALLATION + + 1. Edit the Makefile (see "Portability Issues" below). + + 2. Compile the library: + + make + + 3. Optionaly install the software, for instance: + + make PREFIX=/usr/local install + + which will copy: + + liboptimpack.a into /usr/local/lib + optimpack.h into /usr/local/include + + and creates directory /usr/local/doc/OptimPack-$VERSION with some + documentation and legal stuff. + + +YORICK INSTALLATION + + 1. Go to directory "yorick". + + 2. Edit the very first part of Makefile whether you want or don't want + support for LBFGS and LBFGSB algorithms. + + 3. Setup for compilation and compile the plugin code: + + yorick -batch make.i + make clean + make + + 4. Optionaly install plugin in Yorick tree: + + make install + + +PORTABILITY ISSUES + + OptimPack is written in standard ANSI-C and should pose no problem of + portability. However, in order to match the data types used in your + software, you may have to set the values of the following macros: + + OP_INTEGER = data type used to store array indices + OP_LOGICAL = data type of the result of a logical test + + This must be done _before_ "optimpack.h" get included. If these macros + are not defined, the default assumed in "optimpack.h" is: + + OP_INTEGER = int + OP_LOGICAL = int + + For instance, one should write: + + #define OP_INTEGER long + #define OP_LOGICAL int + #include "optimpack.h" + ... + + Of course, the installed OptimPack library must have been compiled with + the correct data types. Another possibility is to define these macros + when calling CPP (the C preprocessor) e.g. in Makefile: + + CPPFLAGS = -DOP_INTEGER=long -DOP_LOGICAL=int -I. + + a final possibility is to edit "optimpack.h" and to adjust the default + values of these macros (at the very beginning of this file). If you plan + to install in your system, the best is probably to fix the definitions in + "optimpack.h", then compile the library and finally install the library + and the header file "optimpack.h" in proper system directories (e.g. with + "make install PREFIX=..."). diff -Nru yorick-optimpack-1.3.2+dfsg/optimpack1/TODO yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/TODO --- yorick-optimpack-1.3.2+dfsg/optimpack1/TODO 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/TODO 2009-04-23 14:34:49.000000000 +0000 @@ -0,0 +1,21 @@ +* means to force a restart of VMLMB + +* backtrack (Armijo's rule) when at least one bound constraint + becomes active along the line search + +* check Zoutendijk condition + +* implement damped BFGS updating + see Nocédal & Wright p. 537. + +* scale initial gradient + perhaps use a typical value for the step norm + +* improve convergence test + +* change API + use a structure for the workspace + +* doxygen documentation + +* safeguard the step diff -Nru yorick-optimpack-1.3.2+dfsg/optimpack1/VERSION yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/VERSION --- yorick-optimpack-1.3.2+dfsg/optimpack1/VERSION 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/VERSION 2010-07-05 20:42:05.000000000 +0000 @@ -0,0 +1 @@ +1.3.2 diff -Nru yorick-optimpack-1.3.2+dfsg/optimpack1/yorick/do_test.i yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/yorick/do_test.i --- yorick-optimpack-1.3.2+dfsg/optimpack1/yorick/do_test.i 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/yorick/do_test.i 2003-03-12 11:21:07.000000000 +0000 @@ -0,0 +1,29 @@ +#include "optimpack-test.i" +require, "utils.i"; + +func do_test(fatol=, frtol=, sftol=, sgtol=, sxtol=, output=) +{ + keys = ["fatol", "frtol", "sftol", "sgtol", "sxtol"]; + code = "for (i=1;i<=18;++i) optim_test_um, prob=i, method=0, verb=1"; + for (i=1;i<=numberof(keys);++i) { + key = keys(i); + val = symbol_def(key); + if (! is_void(val)) code += ", "+key+"="+val; + } + if (! is_void(output)) { + code += ", output=\""+output+"\";"; + write, open(output, "w"), linesize=1000, format="# %s\n", code; + } else { + code += ";"; + } + eval, code, debug=0; +} + +do_test, output="test1", + fatol="0.0", frtol="1e-12", sftol="1e-3", sgtol="0.9", sxtol="0.1"; +do_test, output="test2", + fatol="0.0", frtol="1e-12", sftol="1e-3", sgtol="0.1", sxtol="0.1"; +do_test, output="test3", + fatol="0.0", frtol="1e-12", sftol="1e-2", sgtol="0.1", sxtol="0.1"; +do_test, output="test4", + fatol="0.0", frtol="1e-12", sftol="5e-2", sgtol="0.1", sxtol="0.1"; diff -Nru yorick-optimpack-1.3.2+dfsg/optimpack1/yorick/f2c.i yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/yorick/f2c.i --- yorick-optimpack-1.3.2+dfsg/optimpack1/yorick/f2c.i 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/yorick/f2c.i 2003-03-11 16:17:17.000000000 +0000 @@ -0,0 +1,371 @@ +func f2c_warn(s) { write, format="WARNING: %s\n", s; } +func f2c_load(file) +{ + if (structof(file) == string) file = open(file); + buf = rdline(file, 10); + while (buf(0)) grow, buf, rdline(file, numberof(buf)); + return buf(where(buf)); +} + +func f2c_save(filename, buf, overwrite=) +{ + if (! overwrite && open(filename, "r", 1)) error, "file already exists"; + write, open(filename, "w"), format="%s\n", linesize=100000, buf; +} + +func f2c(file, trunc=) +/* + + Assume the source lines follows the "Standard Fixed Format": + - The first 72 columns of each line are scanned. + - The first five columns must be blank or contain a numeric label. + - Continuation lines are identified by a nonblank, nonzero in column 6. + - Short lines are padded to 72 characters. + - Long lines are truncated. + - A line with a 'c', 'C', or '*' in column one is a comment line. + - A totally blank line is a comment line. + + + */ +{ + nil = string(0); + code = f2c_load(file); + + /* delete exceeding spaces */ + code = regsub("[ \t]+$", code, ""); + + /* check for bad characters */ + if (anyof(regmatch("[\t]", code))) error, "some bad characters"; + + /* Isolate comments from code (a totally blank line or a line with a + 'c', 'C', or '*' in column one is a comment line). */ + is_comment = regmatch("^([cC*]|$)", code); + comment_lines = where(is_comment); + comment = code(comment_lines); + code_lines = where(! is_comment); + code = code(code_lines); + + /* Convert FORTRAN comments to C-style comments. */ + if (is_array(comment)) { + comment = strpart(comment, 2:0); + n = numberof(comment); + length = strlen(comment); + (continued = array(int, n))(1:-1) = (comment_lines(dif) == 1); + new = 1n; + for (i=1 ; i<=n ; ++i) { + if (continued(i)) { + comment(i) = (new ? "/*" : " *") + comment(i); + new = 0n; + } else if (length(i)) { + comment(i) = (new ? "/*" : " *") + comment(i) + " */"; + new = 1n; + } else { + comment(i) = (new ? nil : " */"); + new = 1n; + } + } + continued = new = length = []; + } + + /* Deal with lines longer that 72 characters */ + if (max(strlen(code)) > 72) { + if (trunc) { + f2c_warn, "truncating lines longer than 72 characters"; + code = strpart(code, 1:72); + } else { + f2c_warn, "some lines are longer than 72 characters"; + } + } + + /* Join continuation lines in code (continuation lines are identified by + a nonblank, nonzero in column 6). */ + local tail; + i = where(regmatch("^ [^ 0] *(.*)", code, /* match0 */, tail)); + if (is_array(i)) { + n = numberof(i); + if (min(i) <= 1) error, swrite(format="bad continuation line (%d)", + code_lines(min(i))); + code(i) = nil; + kp1 = 0; + for (j=1 ; j<=n ; ++j) { + if ((k = i(j)) != kp1) l = k - 1; + code(l) += tail(k); + kp1 = k + 1; + } + i = []; + } + + /* Locate labels (the first five columns in code lines must be blank or + contain a numeric label). */ + label_cols = strpart(code, 1:5); + i = where(regmatch("^ *[0-9]+ *$", label_cols)); + if (is_array(i)) { + label_value = array(long, numberof(i)); + sread, label_cols(i), label_value; + label_lines = code_lines(i); + } else { + label_value = label_lines = []; + } + label_cols = []; + + /* Convert code to lower case. */ + code = strlower(code); + + /* Simplify some FORTRAN keywords. */ + code = regsub("([^a-z0-9])go +to([^a-z0-9])", code, "\\1goto\\2", all=1); + code = regsub("([^a-z0-9])end *(do|if)$", code, "\\1end"); + + + /* replace some FORTRAN intrinsics */ + code = regsub("^ *subroutine +\(.*\)", code, "void \\1\n{", all=1); + code = regsub(" *\\.eq\\. *", code, " == ", all=1); + code = regsub(" *\\.ne\\. *", code, " != ", all=1); + code = regsub(" *\\.lt\\. *", code, " < ", all=1); + code = regsub(" *\\.le\\. *", code, " <= ", all=1); + code = regsub(" *\\.gt\\. *", code, " > ", all=1); + code = regsub(" *\\.ge\\. *", code, " >= ", all=1); + code = regsub("\\.true\\.", code, " TRUE ", all=1); + code = regsub("\\.false\\.", code, " FALSE ", all=1); + + + return merge(comment, code, is_comment); +} + +/* IF (arithmetic) + IF ( expr ) s1, s2, s3 + -> { type __tmp = expr; + if (__tmp < (type)0) goto s1; + if (__tmp == (type)0) goto s2; + goto s3; + } + + IF (block) + IF ( e1 ) THEN + ... + ELSE IF ( e2 ) THEN + ... + ELSE + ... + END IF + -> if (e1) { + ...; + } else if (e2) { + ...; + } else { + ...; + } + + + IF (logical) + IF ( e ) statement + -> if (e) statement; + + + DO label [,] variable = start, stop [, incr ] + + The expressions e1, e2, and e3 are evaluated. If e3 is not present, its + value is assumed to be one. + + The iteration count is established as the value of the expression: + MAX (INT ((e2 - e1 + e3) / e3 ), 0) + + The iteration count is zero if either of the following is true: + + e1 \> e2 and e3 \> zero. + e1 < e2 and e3 < zero. + + The iteration count is tested, and, if it is greater than zero, the + range of the DO loop is executed. + + -> { + TYPE __stop = e2, __incr = e3; + for (var = e1 ; + (__incr > (TYPE)0 ? var <= __stop : var >= __stop) ; + var += __incr) { + ...; + } + } + +*/ + +#if 0 +/* + * COMMENT + * CONTINUATION + * [LABEL] ASSIGN_STMT + * [LABEL] IF_STMT + * [LABEL] DO_STMT + * [LABEL] RETURN_STMT + */ +func f2c_ +{ + extern _f2c_re_label; + local label_values; + label_cols = strpart(code, 1:5); + i = where(regmatch("^ *([0-9]+) *$", strpart(code, 1:5), /* match0 */, + label_values)); + if (is_array(i)) { + label_values = array(long, numberof(i)); + sread, label_cols(i), label_values; + label_lines = code_lines(i); + + label_nrefs = h_new(); + label_lines = h_new(); + n = numberof(i); + for (j=1 ; j<=n ; ++j) { + key = swrite(format="%d", label_values(i)); + if (h_has(label_nrefs, key)) error, "duplicate label ("+key+")"; + h_set, label_nrefs, key, 0; + h_set, label_lines, key, code_lines(i(j)); + } + } else { + label_values = label_lines = []; + } + + + regmatch, ; +} + +local _f2c_column, _f2c_line; + +/* f2c_parse_line - must be called after dealing with commentary lines and + continuation lines and after some FORTRAN keywords have been simplified + ("go to" -> "goto", "end..." -> "end") */ +func f2c_parse_line(linestr, linechar, linetype) +{ + + column = 0; + index = bufchar + 1; + buftype = F2C_TYPE_TABLE(index); + buf_is_type = F2C_TYPE_TABLE(index); + + + extern _f2c_column, _f2c_linenumber, _f2c_line; + + /* skip spaces */ + while ((c = linechar(++_f2c_column)) == ' ') /* noop */ ; + + //if (_f2c_column == 1) { + // /* Comment or end of file. */ + // if (c == 'c' || c == 'C' || c == '*') { + // return COMMENT; + // } + // if (c == '\n') { + // ++_f2c_linenumber; + // return NEWLINE; + // } + // if (c == '\0') { + // return EOF; + // } + // error, swrite(format="illegal character in first column at line %d", + // _f2c_linenumber); + //} + if (_f2c_column >= 6) { + i1 = i2 = _f2c_column; + type = F2C_TYPE(c + 1); + if (type == F2C_ALPHA) { + while ((x = linetype(++i2)) >= F2C_ALPHA && x <= F2C_DOLLAR) /* noop */ ; + range = i1:i2-1; + token = strpart(line_str, range); + if (h_has(F2C_KEYWORDS, token)) { + return F2C_KEYWORD; + } + return F2C_VARIABLE; + } + if (type == F2C_DIGIT) { + } + if (type == F2C_OPEN || type == F2C_CLOSE) { + } + if (type == F2C_PERIOD) { + next_type = ...; + if (next_type == F2C_ALPHA) { + while ((x = linetype(++i2)) == F2C_ALPHA) /* noop */ ; + if (x == F2C_PERIOD) { + range = i1:i2; + token = strpart(line_str, range); + _f2c_column = i2; + return F2C_INTRINSIC; + } + } else if (next_type == F2C_DIGIT) { + + } + range = i1:i2-1; + + } + } + + + + do { + x = linetype(++i2); + } while (x >= F2C_ALPHA && x <= ); + + while (linetype(++i2) == char(++_f2c_column)) == ' ') /* noop */ ; + + + } else { + + } + + if (_f2c_index < _f2c_length) { + c = linechar(++_f2c_index); + type = _f2c_type(c + 1); + } +} + +/* + -1 - illegal character + 0 - end-of-file or end-of-line + 1 - space + 2 - numerical + 3 - alphabetical (can be first letter in a variable name or part of + variable) + 4 - operator or punctuation +*/ + +local F2C_DIGIT; + +func f2c_init(extended) +{ + extern _f2c_type; + extern F2C_SPACE; F2C_SPACE = 1; + extern F2C_ALPHA; F2C_ALPHA = 2; + extern F2C_DIGIT; F2C_DIGIT = 3; + extern F2C_DOLLAR; F2C_DOLLAR = 4; + + extern F2C_OPEN; F2C_OPEN = ; + extern F2C_; F2C_ = ; + + if (F2C_DIGIT != F2C_ALPHA + 1 || + F2C_DOLLAR != F2C_ALPHA + 2) error, "assertion failed"; + + _f2c_type = array(-1, 256); + _f2c_type('\0' + 1) = 0; + _f2c_type('\n' + 1) = 0; + _f2c_type(' ' + 1) = 1; + _f2c_type(indgen('0'+1:'9'+1)) = F2C_DIGIT; + _f2c_type(indgen('A'+1:'Z'+1)) = F2C_ALPHA; + _f2c_type(indgen('a'+1:'z'+1)) = F2C_ALPHA; + _f2c_type('=' + 1) = F2C_ASSIGN; + _f2c_type('+' + 1) = F2C_PLUS; + _f2c_type('-' + 1) = F2C_MINUS; + _f2c_type('*' + 1) = F2C_ASTERISK; + _f2c_type('/' + 1) = F2C_SLASH; + _f2c_type('(' + 1) = F2C_OPEN; + _f2c_type(')' + 1) = F2C_CLOSE; + _f2c_type(',' + 1) = F2C_COMMA; + _f2c_type('.' + 1) = F2C_PERIOD; + _f2c_type('\'' + 1) = F2C_QUOTE; + + if (extended) { + _f2c_type('_' + 1) = F2C_ALPHA; + _f2c_type('$' + 1) = F2C_NAME; + } + + + _F2C_IS_ALPHA = array(0n, 256); + _F2C_IS_ALPHA(indgen('A'+1:'Z'+1)) = 1n; + _F2C_IS_ALPHA(indgen('a'+1:'z'+1)) = 4; + +} +#endif diff -Nru yorick-optimpack-1.3.2+dfsg/optimpack1/yorick/history.i yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/yorick/history.i --- yorick-optimpack-1.3.2+dfsg/optimpack1/yorick/history.i 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/yorick/history.i 2003-03-17 13:04:27.000000000 +0000 @@ -0,0 +1,72 @@ +#include "/work/home/eric/work/yeti-5.3.3/optimpack/yorick/op_deconv.i" +#include "/work/home/eric/work/yeti-5.3.3/optimpack/yorick/op_deconv.i" +#include "/work/home/eric/work/deconvolution/yan-0.1.0/deconv_sn1987a_init.i" +x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1) +#include "/work/home/eric/work/yeti-5.3.3/optimpack/yorick/op_deconv.i" +x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1) +#include "/work/home/eric/work/yeti-5.3.3/optimpack/yorick/op_deconv.i" +x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1) + +info,lkl_h +dbexit +#include "/work/home/eric/work/yeti-5.3.3/optimpack/yorick/op_deconv.i" +x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1) +#include "/work/home/eric/work/yeti-5.3.3/optimpack/yorick/optimpack.i" +x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1) +x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=0) +#include "/work/home/eric/work/yeti-5.3.3/optimpack/yorick/op_deconv.i" +x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=0) + +m +n +#include "/work/home/eric/work/yeti-5.3.3/optimpack/yorick/op_deconv.i" +dbexit +x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=0) +#include "/home/eric/work/yeti-5.3.3/optimpack/yorick/lbfgsb.i" +x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=0) +x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=0,beta=0) +pli,x; +palette,"stern.gp" +x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=0,beta=0,mu=0.1) +x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=1,beta=0,mu=0.1) +x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=2,beta=0,mu=0.1) +fma;pli,x; +x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=2,beta=0,mu=10.) +fma;pli,x; +x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=2,beta=1,mu=10.) +fma;pli,x; +x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=2,beta=1,mu=10.) +x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=1,beta=1,mu=10.) +fma;pli,x; +x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=1,beta=1,mu=1e2) +fma;pli,x; +x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=1,beta=1,mu=1e4) +fma;pli,x; +x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=1,beta=0,mu=1e4) +x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=1,beta=0,mu=1e6) +fma;pli,x; +x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=1,beta=0,mu=1e9) +fma;pli,x; +x=[] +x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=1,beta=0,mu=1e9) +x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=1,beta=0,mu=1e9) +fma;pli,x; +x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=2,beta=0,mu=1e9) +x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=2,beta=0,mu=1e9,frtol=1e-15) +x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=2,beta=0,mu=1e8,frtol=1e-15) +fma;pli,x; +x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=2,beta=0,mu=1e7,frtol=1e-15) +fma;pli,x; +x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=2,beta=0,mu=1e6,frtol=1e-15) +x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=2,beta=0,mu=1e6,frtol=1e-15) +fma;pli,x; +fma;pli,log(x); +x = op_deconv(img,psf,,entropy=1,maxiter=10,verb=1,method=2,beta=0,mu=1e6,frtol=1e-15) +fma;pli,x; +fma;pli,log(x); +x = op_deconv(img,psf,,entropy=1,maxiter=10,verb=1,method=1,beta=0,mu=1e6,frtol=1e-15) +#include "/work/home/eric/work/yeti-5.3.3/optimpack/yorick/op_deconv.i" +x = op_deconv(img,psf,,entropy=1,maxiter=10,verb=1,method=1,beta=0,mu=1e6,frtol=1e-15) +x = op_deconv(img,psf,,entropy=1,maxiter=10,verb=1,method=2,beta=0,mu=1e6,frtol=1e-15) +x = op_deconv(img,psf,,entropy=1,maxiter=10,verb=1,method=2,beta=0,mu=1e7,frtol=1e-15) +fma;pli,x; diff -Nru yorick-optimpack-1.3.2+dfsg/optimpack1/yorick/Makefile yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/yorick/Makefile --- yorick-optimpack-1.3.2+dfsg/optimpack1/yorick/Makefile 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/yorick/Makefile 2009-04-23 10:37:47.000000000 +0000 @@ -0,0 +1,123 @@ +# -*- Makefile -*- +# Makefile -- +# +# Makefile for YOP (Yorick + OptimPack). +# +# History: +# $Id: Makefile,v 1.2 2007/07/05 09:20:55 eric Exp $ +# $Log: Makefile,v $ +# Revision 1.2 2007/07/05 09:20:55 eric +# Changed 'optimpack.i' into 'OptimPack1.i' to avoid confusion +# with pure Yorick implementation of OptimPack. +# +# Revision 1.1 2007/07/05 09:10:00 eric +# Initial revision +# +#------------------------------------------------------------------------------ + +# Comment out the following definitions if you don't want LBFGS: +#LBFGS_OBJS = lbfgs.o lbfgs_wrapper.o +#LBFGS_I = lbfgs.i + +# Comment out the following definitions if you don't want LBFGSB: +#LBFGS_OBJS = lbfgsb.o lbfgsb_wrapper.o +#LBFGS_I = lbfgsb.i + +OPTIMPACK_OBJS = op_lnsrch.o op_utils.o op_vmlmb.o + +# ---------------------------------------------------------------- Yorick setup +# these values filled in by yorick -batch make.i +Y_MAKEDIR=/usr/local/libexec/yorick +Y_EXE=/usr/local/libexec/yorick/bin/yorick +Y_EXE_PKGS= +Y_EXE_HOME=/usr/local/libexec/yorick +Y_EXE_SITE=/usr/local/libexec/yorick + +# ---------------------------------------------------------- optimization flags + +# options for make command line, e.g.- make COPT=-g TGT=exe +COPT=$(COPT_DEFAULT) +TGT=$(DEFAULT_TGT) + +# ----------------------------------------------------- macros for this package + +PKG_NAME=OptimPack1 +PKG_I=OptimPack1.i + +OBJS= $(LBFGS_OBJS) $(LBFGSB_OBJS) $(OPTIMPACK_OBJS) + +# change to give the executable a name other than yorick +PKG_EXENAME=yorick + +# PKG_DEPLIBS=-Lsomedir -lsomelib for dependencies of this package +PKG_DEPLIBS= +# set compiler (or rarely loader) flags specific to this package +PKG_CFLAGS= -DOP_INTEGER=long +PKG_LDFLAGS= + +# list of additional package names you want in PKG_EXENAME +# (typically Y_EXE_PKGS should be first here) +EXTRA_PKGS=$(Y_EXE_PKGS) + +# list of additional files for clean +PKG_CLEAN= + +# autoload file for this package, if any +PKG_I_START=$(LBFGSB_I) $(LBFGS_I) +# non-pkg.i include files for this package, if any +PKG_I_EXTRA= + +# ------------------------------------- standard targets and rules (in Makepkg) + +# set macros Makepkg uses in target and dependency names +# DLL_TARGETS, LIB_TARGETS, EXE_TARGETS +# are any additional targets (defined below) prerequisite to +# the plugin library, archive library, and executable, respectively +PKG_I_DEPS=$(PKG_I) +Y_DISTMAKE=distmake + +include $(Y_MAKEDIR)/Make.cfg +include $(Y_MAKEDIR)/Makepkg +include $(Y_MAKEDIR)/Make$(TGT) + +# override macros Makepkg sets for rules and other macros +# Y_HOME and Y_SITE in Make.cfg may not be correct (e.g.- relocatable) +Y_HOME=$(Y_EXE_HOME) +Y_SITE=$(Y_EXE_SITE) + +# reduce chance of yorick-1.5 corrupting this Makefile +MAKE_TEMPLATE = protect-against-1.5 + +# ------------------------------------------ targets and rules for this package + +# simple example: +#myfunc.o: myapi.h +# more complex example (also consider using PKG_CFLAGS above): +#myfunc.o: myapi.h myfunc.c +# $(CC) $(CPPFLAGS) $(CFLAGS) -DMY_SWITCH -o $@ -c myfunc.c + +#op_lnsrch.o: ../op_lnsrch.c ../optimpack.h +# $(CC) $(CPPFLAGS) $(CFLAGS) -c ../$(@:.o=.c) -o $@ +#op_vmlmb.o: ../op_vmlmb.c ../optimpack.h +# $(CC) $(CPPFLAGS) $(CFLAGS) -c ../$(@:.o=.c) -o $@ +#op_cgmnb.o: ../op_cgmnb.c ../optimpack.h +# $(CC) $(CPPFLAGS) $(CFLAGS) -c ../$(@:.o=.c) -o $@ +#op_utils.o: ../op_utils.c ../optimpack.h +# $(CC) $(CPPFLAGS) $(CFLAGS) -c ../$(@:.o=.c) -o $@ + +op_%.o: ../op_%.c ../optimpack.h + $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -c $< + +# L-BGFS-B stuff: +lbfgsb_wrapper.o: lbfgsb_wrapper.c + $(CC) $(CFLAGS) -c $< +lbfgsb.o: lbfgsb.f + $(FC) $(FFLAGS) -c $< + +# L-BGFS stuff: +lbfgs_wrapper.o: lbfgs_wrapper.c + $(CC) $(CFLAGS) -c $< +lbfgs.o: lbfgs.f + $(FC) $(FFLAGS) -c $< + +# ------------------------------------------------------------- end of Makefile diff -Nru yorick-optimpack-1.3.2+dfsg/optimpack1/yorick/mira-debug.i yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/yorick/mira-debug.i --- yorick-optimpack-1.3.2+dfsg/optimpack1/yorick/mira-debug.i 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/yorick/mira-debug.i 2009-04-23 11:58:21.000000000 +0000 @@ -0,0 +1,86 @@ +#! /usr/local/bin/yorick -i + +plug_dir, "~/work/OptimPack-1.3/yorick/"; +include, "~/work/OptimPack-1.3/yorick/OptimPack1.i"; +include, "yeti_fftw.i"; +include, "~/work/mira/src/mira.i"; + +/* Load OI-FITS data file ('mh1' will be our MIRA instance for this + data file; if there are several spectral channels in the data file, + you must choose one with keyword EFF_WAVE or choose a spectral + range with keywords EFF_WAVE and EFF_BAND): */ +mh1 = mira_new(MIRA_HOME+"data/data1.oifits"); + +/* Configure data instance for image reconstruction parameters (DIM is + the number of pixels along the width and height of the restored + image; FOV is the size of the corresponding field of view in + radians; XFORM is the name of the method to approximate the Fourier + transform, can be "exact" or "fft", default is "exact"): */ +mira_config, mh1, dim=256, pixelsize=0.1*MIRA_MILLIARCSECOND, xform="fft"; + +/* Smooth support. */ +dim = mira_get_dim(mh1); +r = abs(mira_get_x(mh1), mira_get_x(mh1)(-,)); +prior = 1.0/(1.0 + (2.0*r/(5.0*MIRA_MILLIARCSECOND))^2); +prior *= 1.0/sum(prior); +rgl_config, (rgl = rgl_new("quadratic")), "W", linop_new("diagonal", 1.0/prior); + + + +if (! window_exists(0)) { + window, 0, style="work.gs", dpi=75, width=550, height=450; +} else { + window, 0, style="work.gs"; +} +limits,10,-10,-10,10; +palette, "heat.gp"; + +if (! window_exists(1)) { + window, 1, style="work.gs", dpi=75, width=450, height=450; +} else { + window, 1, style="work.gs"; +} +palette, "heat.gp"; + +/*---------------------------------------------------------------------------*/ +/* RECONSTRUCTION WITH PHASE CLOSURE */ + +/* seed rotated final penalty + * 0.1 yes 4.94723e3 (viusaly the best) + * 0.2 bad 6.95202e3 + * 0.3 bad 6.96364e3 + * 0.4 yes 4.96052e3 + * 0.5 bad 6.95272e3 + * 0.6 no 7.27172e3 + * 0.7 bad 6.67580e3 + * 0.8 no 4.94379e3 + * 0.9 bad 5.62120e3 + * 1.0 yes 4.91903e3 + */ +random_seed, (is_func(fftw) ? 0.2 : 0.7); +img0 = random(dim, dim); + +rdline, prompt="hit [Return] to start reconstruction"; +img1 = mira_solve(mh1, img0, maxeval=0, verb=1, xmin=0.0, normalization=1, regul=rgl, mu=1e5, view=3, title="Reconstruction with phase closure"); +rdline, prompt="hit [Return] to continue reconstruction"; +img1 = mira_solve(mh1, img1, maxeval=100, verb=1, xmin=0.0, normalization=1, regul=rgl, mu=1e5, view=3, title="Reconstruction with phase closure"); +img1 = mira_solve(mh1, img1, maxeval=100, verb=1, xmin=0.0, normalization=1, regul=rgl, mu=1e4, view=3, title="Reconstruction with phase closure"); +img1 = mira_solve(mh1, img1, maxeval=200, verb=1, xmin=0.0, normalization=1, regul=rgl, mu=1e3, view=3, title="Reconstruction with phase closure"); +rdline, prompt="hit [Return] to start reconstruction"; + +random_seed, (is_func(fftw) ? 0.1 : 0.7); +img0 = random(dim, dim)//(::-1,::-1); + +img4 = mira_solve(mh1, img0, maxeval=0, verb=1, xmin=0.0, normalization=1, regul=rgl, mu=1e5, zap_phase=1, view=3, title="Reconstruction with no phase data"); +rdline, prompt="hit [Return] to start reconstruction"; +img4 = mira_solve(mh1, img0, maxeval=50, verb=1, xmin=0.0, normalization=1, regul=rgl, mu=1e5, zap_phase=1, view=3, title="Reconstruction with no phase data"); +img4 = mira_solve(mh1, img4, maxeval=50, verb=1, xmin=0.0, normalization=1, regul=rgl, mu=5e4, zap_phase=1, view=3, title="Reconstruction with no phase data"); +img4 = mira_solve(mh1, img4, maxeval=50, verb=1, xmin=0.0, normalization=1, regul=rgl, mu=2e4, zap_phase=1, view=3, title="Reconstruction with no phase data"); +img4 = mira_solve(mh1, img4, maxeval=50, verb=1, xmin=0.0, normalization=1, regul=rgl, mu=1e4, zap_phase=1, view=3, title="Reconstruction with no phase data"); +img4 = mira_solve(mh1, img4, maxeval=50, verb=1, xmin=0.0, normalization=1, regul=rgl, mu=5e3, zap_phase=1, view=3, title="Reconstruction with no phase data"); +img4 = mira_solve(mh1, img4, maxeval=70, verb=1, xmin=0.0, normalization=1, regul=rgl, mu=3e3, zap_phase=1, view=3, title="Reconstruction with no phase data"); +//img4 = mira_solve(mh1, img4, maxeval=50, verb=1, xmin=0.0, normalization=1, regul=rgl, mu=2e3, zap_phase=1, view=3, title="Reconstruction with no phase data"); +//img4 = mira_solve(mh1, img4, maxeval=50, verb=1, xmin=0.0, normalization=1, regul=rgl, mu=1e3, zap_phase=1, view=3, title="Reconstruction with no phase data"); + +rdline, prompt="hit [Return] to turn the image"; +img4 = mira_solve(mh1, img4(::-1,::-1), maxeval=70, verb=1, xmin=0.0, normalization=1, regul=rgl, mu=3e3, zap_phase=1, view=3, title="Reconstruction with no phase data"); diff -Nru yorick-optimpack-1.3.2+dfsg/optimpack1/yorick/op_deconv.i yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/yorick/op_deconv.i --- yorick-optimpack-1.3.2+dfsg/optimpack1/yorick/op_deconv.i 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/yorick/op_deconv.i 2007-07-11 06:16:26.000000000 +0000 @@ -0,0 +1,564 @@ +/* + * op_deconv.i + * + * Regularized deconvolution in Yorick by various iterative optimization + * methods. + */ + +require, "fft_utils.i"; + +func mks(n) +{ + a = array(long, n, n); + a(1,1) = 3; + a(0,0) = 3; + if (n >= 3) a(n+2:n*(n-1)-1:n+1) = 2; + a(2:n*(n-1):n+1) = 1; + a(n+1:n*n-1:n+1) = 1; + return 0.25*a; +} + + + + +func op_deconv(data, psf, x, weight=, rescale=, positive=, + maxeval=, maxiter=, ndirs=, verb=, output=, save=, + frtol=, fatol=, factr=, method=, + mu=, wiener=, bootstrap=, normalize=, + entropy=, beta=, prior=, tiny=, + tikhonov=, roughness=) +/* DOCUMENT op_deconv(data, psf) + -or- op_deconv(data, psf, x) + + + FIXME: + + Returns the deconvolution of DATA by PSF; X is the optional starting + solution. The solution is obtained by minimizing the penalty + function: + + psi(X) = LKL(X) + MU*RGL(X) + + where RGL is a regularization term (see below) and the likelihood term + is: + + LKL(X) = 0.5*sum(WEIGHT*(model(X) - DATA)^2) + + where WEIGHT is given by the value of optional keyword WEIGHT (default + is WEIGHT=1.0), PRIOR is given by the value of optional keyword PRIOR + (default is PRIOR=0.0) and model(X) is the model of the data: + + model(X) = inverse_fft(fft(PSF)*fft(X))) + + + If keyword SAVE is true, then if first least significant bit of SAVE + is set (i.e. SAVE&1 == 1) the model is saved in external variable + op_deconv_model and/or if second least significant bit of SAVE is set + (i.e. SAVE&2 == 2) the penalty is saved in external variable + op_deconv_penalty: + op_deconv_penalty(1) = MU + op_deconv_penalty(2) = LKL + op_deconv_penalty(3) = RGL + + Keyword METHOD: + METHOD = 0 - LBFGSB + = 1 - VMLMB (no preconditioning) + = 2 - VMLMB with preconditioning + = 3 - conjugate gradient (Fletcher-Reeves) + = 4 - conjugate gradient (Polak-Ribiére) + = 5 - conjugate gradient (Polak-Ribiére with positive BETA) + the default is METHOD=2 + + If keyword BOOTSTRAP is true and X is not specified, then the starting + solution is the solution of: + + X0 = arg min sum((model(X) - DATA)^2) + sum(PRIOR*abs(fft(X))^2) + = arg min sum(abs(fft(PSF)*fft(X) - fft(DATA))^2) + + N*sum(PRIOR*abs(fft(X))^2) + = inverse_fft(conj(fft(PSF))*fft(DATA)/(abs(fft(PSF))^2 + N*PRIOR)) + + with N=numberof(DATA). + + The definitions of the forward and backward FFT's are: + fft(X) = fft(X, -1) + inverse_fft(X) = (1.0/numberof(X))*double(fft(X, +1)) + + With these definitions, Parseval's theorem reads: + sum(abs(X)^2) = (1.0/numberof(X))*sum(abs(fft(X))^2) + + Keyword MU can be used to set the level of regularization (by default + MU=1, if some regularization is used; MU=0 otherwise). There are + several types of regularization: + + - Wiener regularization is used if WIENER keyword is set. The Wiener + regularization term is: + + RGL_WIENER(X) = sum(WIENER*abs(fft(X))^2) + + The regularized unconstrained Wiener solution is given by: + + fft(X_WIENER) = conj(MTF)*fft(DATA)/(abs(MTF)^2 + MU*WIENER) + + If no initial X is specified, X_WIENER is used as the starting + solution to find the constrained solution unless keyword BOOTSTRAP + is explicitely set to 0. + + - Maximum entropy regularization is used if keyword ENTROPY is true + (non-nil and non-zero). In this case, the regularization term is: + + RGL_ENTROPY(X) = BETA*KL(X, PRIOR) + (1 - BETA)*KL(PRIOR, X) + + where KL() is the Kullback-Leibler distance between the solution X + and an a priori or default solution PRIOR. KL is defined by: + + KL(X, P) = sum(X*log(X/P) + P - X) + + Keyword PRIOR can be used to specify the a priori, by default a + uniform prior is used. + + Keyword BETA can be used to adjust the definition of the + regularization term (by default, BETA=0.5). The regularization + term reduces to the negative Shannon entropy if BETA=1 and to the + negative Burg entropy if BETA=0. + + - Tikhonov regularization is used + + + This solution is obtained value + of the WIENER keyword is the Fourier weigths: + + + SEE ALSO: deconv_lbfgsb. */ +{ + require, "optim_pack.i"; + + /* Setup for optional outputs. */ + extern op_deconv_model, op_deconv_penalty; + if (! save) { + save_model = save_penalty = 0n; + } else { + save_model = (save&1 ? 1n : 0n); + save_penalty = (save&2 ? 1n : 0n); + } + + /* Initialize FFT stuff and compute MTF = FFT(PSF). */ + local __fft_setup, __fft_number; + dims = dimsof(data); + __fft_init, dims; + fft = __fft; + mtf = fft(psf, -1); + conj_mtf = conj(mtf); + fft_scale = 1.0/numberof(data); + + /* Type of regularization. */ + regul = ((is_void(wiener) ? 0 : 1) + + (anyof(tikhonov) ? 2 : 0) + + (roughness ? 4 : 0) + + (entropy ? 8 : 0)); + if (is_void(mu)) mu = (regul ? 1.0 : 0.0); + xmin = 0.0; + if (regul == 0) { + /* No regularization. */ + op = __op_deconv; + } else if (regul == 1) { + /* Wiener regularization. */ + op = __op_deconv_wiener; + if (mu != 1.0) wiener *= mu; + } else if (regul == 2) { + /* Tikhonov regularization. */ + op = __op_deconv_tikhonov; + } else if (regul == 4) { + /* Roughness regularization. */ + op = (roughness==2 ? __op_deconv_relative_roughness + : __op_deconv_absolute_roughness); + } else if (regul == 8) { + /* Regularization by maximum entropy. */ + op = __op_deconv_entropy; + positive = 1n; /* force positivity for maximum entropy method */ + if (is_void(beta)) beta = 0.5; + else if (beta < 0.0 || beta > 1.0) error, "bad value for BETA"; + if (is_void(tiny)) tiny = 1e-30; + else if (tiny <= 0.0) error, "TINY must be strictly positive"; + xavg = (normalize ? 1.0/numberof(data) : avg(data)/sum(psf)); + if (is_void(prior)) + prior = array(xavg, dimsof(data)); /* Uniform prior by default. */ + xmin = tiny*xavg; + } else { + error, "only one of WIENER, TIKHONOV, ROUGHNESS or ENTROPY is allowed"; + } + + /* Starting solution. */ + if (is_void(x)) { + if (bootstrap) { + x = fft(data, -1); + if (is_void(wiener)) x /= mtf; + else x *= conj_mtf/(abs2(mtf) + numberof(data)*wiener); + x = fft_scale*double(fft(x, +1)); + } else { + x = array(avg(data)/sum(psf), dims); + } + } + + /* Initialization of workspace according to optimization method + and options. */ + if (is_void(frtol)) frtol = 1e-8; + if (is_void(fatol)) fatol = 0.0; + if (is_void(factr)) factr = 1e7; + if (is_void(method)) method = 2; /* default is VMLMB with preconditioning */ + if (positive || method == 0) { + /* Apply constraints and make XMIN an array to speedup things and + because this is required by LBFGSB. */ + xmin = array(xmin, dims); + if (positive) x = max(x, xmin); + } + precond = 0n; + if (is_void(ndirs)) ndirs = 5; + if (method == 0) { + /* Use L-BFGS-B method. */ + if (! is_func(op_lbfgsb)) + error, "you must have L-BFGS-B compiled in Yorick"; + bnd = array((positive ? 1 : 0), dims); + pgtol = 0.0; + ws = op_lbfgsb_setup(ndirs, x, xmin, xmin /* unused upper bound */, + bnd, factr, pgtol); + get_msg = op_lbfgsb_msg; + } else if (method == 1 || method == 2) { + /* Use variable metric. */ + fmin = 0.0; // FIXME: + ws = op_vmlmb_setup(numberof(data), ndirs, fmin, fatol=fatol, frtol=frtol); + get_msg = op_vmlmb_msg; + if (method == 2) precond = 1n; + } else { + error, "bad METHOD"; + } + job = 1; + + /* Do we need to explicitely apply constraints (not needed fo LBFGSB)? */ + apply_constraints = (positive && method != 0); + + /* Prepare for verbose output. */ + if (verb) { + if (is_void(output)) { + prefix = " "; + } else { + if (structof(output) == string) { + output = open(output, "a"); + } else if (typeof(output) != "text_stream") { + error, "bad value for keyword OUTPUT"; + } + prefix = "#"; + } + write, output, format="%s%s\n%s%s\n", prefix, + "ITER EVAL FFT PENALTY LIKELIHOOD REGUL.", + prefix, + "---- ---- ----- --------------------- ----------- -----------"; + } + + /* Optimization loop. */ + iter = eval = 0; + for (;;) { + local lkl, lkl_h, rgl, rgl_h, grd, h, prior_over_x, sum_x; /* ouputs */ + + if (job == 1) { + /* Compute function and gradient. */ + + /* Apply constraints. */ + if (apply_constraints) x = max(x, xmin); + + /* Compute model. */ + fft_x = fft(x, -1); + model = fft_scale*double(fft(mtf*fft_x, +1)); + scale = (rescale ? op_deconv_scale() : 1.0); + if (rescale) { + if ((scale = op_deconv_scale(data, model, weight)) != 1.0) { + model *= scale; + } + } else { + scale = 1.0; + } + + /* Compute penalty. */ + op, 1; + err = lkl + mu*rgl; + ++eval; + } + + // FIXME: hack to save best solution found so far + local best_err; + if (eval == 1 || err < best_err) { + if (save_model) eq_nocopy, op_deconv_model, model; + best_err = err; + best_x = (scale == 1.0 ? x : scale*x); + } + + /* Check for convergence and, possibly, print iteration values. */ + if (job != 1 || eval == 1) { + if (job == 2 || job == 3) ++iter; + if ((stop = (job >= 3))) { + msg = get_msg(ws); + } else if ((stop = (! is_void(maxiter) && iter >= maxiter))) { + msg = swrite(format="warning: too many iterations (%d)", iter); + } else if ((stop = (! is_void(maxeval) && eval >= maxeval))) { + msg = swrite(format="warning: too many function evaluations (%d)", + eval); + } + if (verb && (stop || iter%verb == 0)) { + write, output, format=" %4d %4d %5d %-22.14e %-11.3e %-11.3e\n", + iter, eval, __fft_number, err, lkl, rgl; + } + if (stop) { + /* Return current solution. */ + if (verb || job != 3) write, output, format=prefix+"%s\n", msg; + if (save_penalty) op_deconv_penalty = [mu, lkl, rgl]; + return best_x; + } + } + + /* Call optimizer. */ + if (method == 0) { + job = op_lbfgsb(x, err, grd, ws); + } else { + local h, active; + if (job != 1 || eval == 1) { + if (positive) active = (x > xmin) | (grd < 0.0); + if (precond) op, 0; + } + //info, h; + job = op_vmlmb_next(x, err, grd, ws, active, h); + } + } +#if 0 + if (0) { + if (is_void(weight)) { + alpha = sum(psf*psf); + } else { + alpha = fft_scale*double(fft(fft(weight, -1)*fft(psf*psf, -1), +1)); + } + } else { + if (is_void(weight)) { + alpha = fft_scale*double(fft(abs2(mtf), +1)); + } else { + alpha = fft_scale*double(fft(fft(weight, -1)*abs2(mtf), +1)); + } + } + if (numberof(alpha) > 1) { + window,7;fma;pli,alpha;palette,"stern.gp";pause,1; + } + if (entropy) { + tmp = x*x; + tmp /= ((1.0 - beta)*prior + beta*x + alpha*tmp); + next_stage, x, psi, grd, task, ws, bnd, tmp; + tmp = []; + } else { + if (first_time) { + tmp_i = 0; + tmp_stride = 1; + tmp_dims = dimsof(x); + tmp_n = numberof(tmp_dims); + tmp = array(0.0, tmp_dims); + for (k=2;k<=tmp_n;++k) { + tmp_i = tmp_i*tmp_stride + tmp_dims(k)/2; + tmp_stride *= tmp_dims(k); + } + tmp(tmp_i) = mu; + tmp = ((smooth(tmp) - tmp)(tmp_i))^2; + write, tmp; + alpha = 1.0/(alpha + tmp); + } + next_stage, x, psi, grd, task, ws, bnd, alpha; + } + first_time = 0n; +#endif +} + + + +/* KL entropy: + + +rgl = (2.0*beta - 1.0)*(p - x) + ((beta - 1.0)*p + beta*x)*log(x/p); +grd = (1.0 - beta)*(1.0 - p/x) + beta*log(x/p); +hes = ((1.0 - beta)*(p/x) + beta)/x; + +u = p/x; + l = log(u); + rgl = (2.0*beta - 1.0)*(p - x) + ((1.0 - beta)*p - beta*x)*l; + grd = (1.0 - beta)*(1.0 - u) - beta*l; + hes = ((1.0 - beta)*u + beta)/x; + + h = 1/diag(H) + = 1/(lkl_h + mu*rgl_h) + = x/(lkl_h*x + mu*((1.0 - beta)*u + beta)); +*/ + +func __op_deconv_entropy(job) +{ + extern h, lkl_h, rgl_h; + extern lkl, rgl, grd; /* ouputs */ + extern prior_over_x; + if (job == 1) { + /* Compute likelihood term and its gradient. */ + local weight_r; + r = model - data; /* anti-residuals */ + if (is_void(weight)) eq_nocopy, weight_r, r; + else weight_r = weight*r; + grd = double(fft(conj_mtf*fft((fft_scale*scale)*weight_r, -1), +1)); + lkl = 0.5*sum(weight_r*r); + + /* Compute regularization. */ + prior_over_x = prior/x; + log_prior_over_x = log(prior_over_x); + rgl = sum((2.0*beta - 1.0)*(prior - x) + + ((1.0 - beta)*prior - beta*x)*log_prior_over_x); + grd += mu*((1.0 - beta)*(1.0 - prior_over_x) - beta*log_prior_over_x); + } else { + /* Compute preconditioning. */ + if (is_void(lkl_h)) { + lkl_h = (is_void(weigth) ? sum(psf*psf) : + fft_scale*double(fft(fft(weigth, -1)*fft(psf*psf, -1), +1))); + } + h = x/(lkl_h*x + mu*((1.0 - beta)*prior_over_x + beta)); + } +} + + +func op_deconv_scale(data, model, weight) +/* DOCUMENT op_deconv_scale(data, model) + -or- op_deconv_scale(data, model, weight) + Computes and returns the scale ALPHA such that the following quantity + is minimized: + sum(WEIGHT*(ALPHA*MODEL - DATA)^2) + or sum((ALPHA*MODEL - DATA)^2) if WEIGHT is missing. + + SEE ALSO: op_deconv. */ +{ + if (is_void(weight)) { + if ((tmp = sum(model*model)) > 0.0) return sum(model*data)/tmp; + } else if ((tmp = sum((weight_model = weight*model)*model)) > 0.0) { + return sum(weight_model*data)/tmp; + } + return 1.0; +} + +func __op_deconv +{ + extern lkl, rgl, grd; /* ouputs */ + + /* Compute likelihood term and (FFT of) gradient. */ + local weight_r; + r = model - data; /* anti-residuals */ + if (is_void(weight)) eq_nocopy, weight_r, r; + else weight_r = weight*r; + grd = double(fft(conj_mtf*fft((fft_scale*scale)*weight_r, -1), +1)); + lkl = 0.5*sum(weight_r*r); + rgl = 0.0; +} + +func __op_deconv_tikhonov +{ + extern lkl, rgl, grd, sum_x; /* ouputs */ + + /* Compute likelihood term and (FFT of) gradient. */ + local weight_r; + r = model - data; /* anti-residuals */ + if (is_void(weight)) eq_nocopy, weight_r, r; + else weight_r = weight*r; + grd = double(fft(conj_mtf*fft((fft_scale*scale)*weight_r, -1), +1)); + rgl = 0.5*sum(weight_r*r); + weight_r = r = []; + + if (normalize) { + if ((sum_x = sum(x)) > 0.0) { + u = x*(1.0/sum_x); + v = tikhonov*u; + uv = sum(u*v); + grd += (mu/sum_x)*(v - uv); + rgl = 0.5*uv; + u = v = []; + } else { + rgl = 0.0; + } + } else { + v = tikhonov*x; + rgl = 0.5*sum(v*x); + grd += mu*v; + } +} + +func __op_deconv_roughness +{ + extern h, lkl, rgl, grd, sum_x; /* ouputs */ + + /* Compute likelihood term and (FFT of) gradient. */ + local weight_r; + r = model - data; /* anti-residuals */ + if (is_void(weight)) eq_nocopy, weight_r, r; + else weight_r = weight*r; + grd = double(fft(conj_mtf*fft((fft_scale*scale)*weight_r, -1), +1)); + rgl = 0.5*sum(weight_r*r); + weight_r = r = []; + + if (precond && eval == 1) { + /* Computes the diagonal of the Hessian. */ + dims = dimsof(x); + dims(2:) = 5; + r = array(double, dims); + r((numberof(r) + 1)/2) = 1.0; + r = smooth(r) - r; + rgl_h = sum(r*r); + if (is_void(weigth)) { + lkl_h = sum(psf*psf); + } else { + lkl_h = fft_scale*double(fft(fft(weigth, -1)*fft(psf*psf, -1), +1)); + } + h = 1.0/(lkl_h + mu*rgl_h); + } + if (normalize) { + if ((sum_x = sum(x)) > 0.0) { + u = x*(1.0/sum_x); + r = smooth(u) - u; + rr = sum(r*r); + grd += (mu/sum_x)*(smooth(r) - r - rr); + rgl = 0.5*rr; + } else { + rgl = 0.0; + } + } else { + r = smooth(x) - x; + rgl = 0.5*sum(r*r); + grd += mu*(smooth(r) - r); + } +} + + +func op_deconv_lcurve(data, psf, x, weight=, rescale=, positive=, + maxeval=, maxiter=, ndirs=, verb=, output=, save=, + frtol=, fatol=, factr=, method=, + mu=, wiener=, bootstrap=, normalize=, + entropy=, beta=, prior=, tiny=, + tikhonov=, roughness=, precond=, + color=, win=, symbol=) +{ + /* sort regularization weight in descending order */ + mu = mu(sort(mu)(::-1)); + result = array(double, 3, numberof(mu)); + for (i=1 ; i<=numberof(mu) ; ++i) { + local op_deconv_penalty; + x = op_deconv(data, psf, x, weight=weight, rescale=rescale, + positive=positive, maxeval=maxeval, maxiter=maxiter, + ndirs=ndirs, verb=verb, output=output, save=2, + frtol=frtol, fatol=fatol, factr=factr, method=method, + mu=mu(i), wiener=wiener, bootstrap=bootstrap, + normalize=normalize, entropy=entropy, beta=beta, + prior=prior, tiny=tiny, tikhonov=tikhonov, + roughness=roughness); + q = op_deconv_penalty; + if (! is_void(win)) { + window, win, wait=1; + plp, q(3), q(2), color=color, symbol=symbol; + pause, 1; + } + result(,i) = q; + } + return result; +} diff -Nru yorick-optimpack-1.3.2+dfsg/optimpack1/yorick/OptimPack1.i yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/yorick/OptimPack1.i --- yorick-optimpack-1.3.2+dfsg/optimpack1/yorick/OptimPack1.i 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/yorick/OptimPack1.i 2009-09-23 12:36:35.000000000 +0000 @@ -0,0 +1,515 @@ +/* + * OptimPack1.i -- + * + * Main startup file for OptimPack extension of Yorick. + * + *----------------------------------------------------------------------------- + * + * Copyright (C) 2003-2007 Eric Thiébaut. + * + * This file is part of OptimPack. + * + * OptimPack is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * OptimPack is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with OptimPack (file "COPYING" in the top source + * directory); if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *----------------------------------------------------------------------------- + * + * History: + * $Id$ + * $Log: OptimPack1.i,v $ + * Revision 1.2 2007/07/11 06:16:01 eric + * New function op_mnb which is a "simple" driver to OptimPack routines. + * + * Revision 1.1 2007/07/05 10:13:21 eric + * Initial revision + * + *----------------------------------------------------------------------------- + */ + +if (is_func(plug_in)) plug_in, "OptimPack1"; + +extern __op_csrch; +/* PROTOTYPE + int op_csrch(double f, double g, double array stp, + double ftol, double gtol, double xtol, + double stpmin, double stpmax, int array task, + char array csave, long array isave, double array dsave); +*/ + +func op_csrch(f, g, &stp, ftol, gtol, xtol, stpmin, stpmax, &task, + &csave, isave, dsave) +{ + if (numberof(task) != 1) error, "TASK must be a scalar"; + if (structof(isave) != long || numberof(isave) < 2) + error, "bad ISAVE array"; + if (structof(dsave) != double || numberof(dsave) < 12) + error, "bad DSAVE array"; + itask = int(task); + cbuf = array(char, 128); + info = __op_csrch(f, g, stp, ftol, gtol, xtol, stpmin, stpmax, itask, + cbuf, isave, dsave); + task = long(itask); + csave = string((task == 1 ? 0 : &cbuf)); + return long(info); +} + +func op_vmlmb_setup(n, m, fmin=, fatol=, frtol=, sftol=, sgtol=, sxtol=, + epsilon=, costheta=) +{ + csave = array(char, 128); + isave = array(long, 12); + dsave = array(double, 27 + n + 2*m*(n + 1)); + if (is_void(frtol)) frtol = 1e-10; + if (is_void(fatol)) fatol = 1e-13; + if (is_void(sftol)) sftol = 0.001; + if (is_void(sgtol)) sgtol = 0.9; + if (is_void(sxtol)) sxtol = 0.1; + if (is_void(epsilon)) epsilon = 1E-8; + if (is_void(costheta)) costheta = 1E-2; + task = long(__op_vmlmb_first(n, m, fatol, frtol, sftol, sgtol, sxtol, + epsilon, costheta, csave, isave, dsave)); + if (task != 1) error, string(&csave); + ws = [&csave, &isave, &dsave]; + if (! is_void(fmin)) { + op_vmlmb_set_fmin, ws, fmin; + } + return ws; +} + +func op_vmlmb_msg(ws) { return string(ws(1)); } + +func op_vmlmb_next(x, &f, &g, ws, active, h) +{ + local csave; eq_nocopy, csave, *ws(1); + if (structof(csave) != char || numberof(csave) != 128) + error, "corrupted workspace (CSAVE)"; + + local isave; eq_nocopy, isave, *ws(2); + if (structof(isave) != long || numberof(isave) != 12) + error, "corrupted workspace (ISAVE)"; + m = isave(5); + n = isave(6); + + local dsave; eq_nocopy, dsave, *ws(3); + if (structof(dsave) != double || numberof(dsave) != 27 + n + 2*m*(1 + n)) + error, "corrupted workspace (DSAVE)"; + + if (structof(x) != double || numberof(x) != n) + error, "bad parameter array X"; + if (structof(f) != double || dimsof(f)(1)) + error, "bad function value F"; + if (structof(g) != double || numberof(g) != n) + error, "bad gradient array G"; + + if (! is_void(active) && (structof(active) != int || + numberof(active) != n )) error, "bad array ACTIVE"; + + if (! is_void(h) && (structof(h) != double || + numberof(h) != n )) error, "bad array H"; + + return long(__op_vmlmb_next(x, f, g, &active, &h, csave, isave, dsave)); +} + +extern __op_vmlmb_next; +/* PROTOTYPE + int op_vmlmb_next(double array x, double array f, double array g, + pointer active, pointer h, + char array csave, long array isave, double array dsave); +*/ + +//extern op_vmlmb_first; +///* DOCUMENT op_vmlmb_first(n, m, fatol, frtol, sftol, sgtol, sxtol, +// csave, isave, dsave); +// The returned value should be 1 unless there is an error. +//*/ + +extern __op_vmlmb_first; +/* PROTOTYPE + int op_vmlmb_first(long n, long m, + double fatol, double frtol, + double sftol, double sgtol, double sxtol, + double epsilon, double costheta, + char array csave, long array isave, double array dsave); +*/ + +extern __op_vmlmb_set_fmin; +/* PROTOTYPE + int op_vmlmb_set_fmin(char array csave, + long array isave, + double array dsave, + double new_value, + double array old_value); +*/ +extern __op_vmlmb_get_fmin; +/* PROTOTYPE + int op_vmlmb_get_fmin(char array csave, + long array isave, + double array dsave, + double array value); +*/ + +local op_vmlmb_set_fmin; +local op_vmlmb_get_fmin; +/* DOCUMENT old = op_vmlmb_set_fmin(ws, fmin); + * -or- fmin = op_vmlmb_get_fmin(ws); + * + * The function op_vmlmb_set_fmin set the value of FMIN in workspace WS + * and returns the previous value of FMIN if any (nil otherwise). + * + * The function op_vmlmb_get_fmin returns the actual value of FMIN in + * workspace WS or nil if FMIN has never been set. + * + SEE ALSO: op_vmlmb_first. + */ +func op_vmlmb_set_fmin(ws, new) +{ + old = 0.0; + if (__op_vmlmb_set_fmin(*ws(1), *ws(2), *ws(3), new, old)) { + return old; + } +} +func op_vmlmb_get_fmin(ws) +{ + fmin = 0.0; + if (__op_vmlmb_get_fmin(*ws(1), *ws(2), *ws(3), fmin)) { + return fmin; + } +} + +func op_mnb(f, x, &fx, &gx, fmin=, + extra=, xmin=, xmax=, method=, mem=, verb=, quiet=, + viewer=, printer=, + maxiter=, maxeval=, output=, + frtol=, fatol=, sftol=, sgtol=, sxtol=) +/* DOCUMENT op_mnb(f, x) + * -or- op_mnb(f, x, fout, gout) + * + * Returns a minimum of a multivariate function by an iterative + * minimization algorithm (conjugate gradient or limited memory variable + * metric) possibly with simple bound constraints on the parameters. + * Arguments are: + * + * F - User defined function to optimize. + * The prototype of F is: + * func F(x, &gx) { + * fx = ....; // compute function value at X + * gx = ....; // store gradient of F in GX + * return fx; // return F(X) + * } + * + * X - Starting solution (a floating point array). + * + * FOUT - Optional output variable to store the value of F at the + * minimum. + * + * GOUT - optional output variable to store the value of the gradient + * of F at the minimum. + * + * If the multivariate function has more than one minimum, which minimum + * is returned is undefined (although it depends on the starting + * parameters X). + * + * In case of early termination, the best solution found so far is + * returned. + * + * + * KEYWORDS + * + * EXTRA - Supplemental argument for F; if non-nil, F is called as + * F(X,GX,EXTRA) so its prototype must be: func F(x, &gx, extra). + * + * XMIN, XMAX - Lower/upper bounds for X. Must be conformable with X. + * For instance with XMIN=0, the non-negative solution will be + * returned. + * + * METHOD - Scalar integer which defines the optimization method to use. + * Conjugate gradient algorithm is used if one of the bits + * OP_FLAG_POLAK_RIBIERE, OP_FLAG_FLETCHER_REEVES, or + * OP_FLAG_HESTENES_STIEFEL is set; otherwise, a limited memory + * variable metric algorithm (VMLM-B) is used. If METHOD is not + * specified and if MEM=0, a conjugate gradient search is attempted + * with flags: (OP_FLAG_UPDATE_WITH_GP | + * OP_FLAG_SHANNO_PHUA | + * OP_FLAG_MORE_THUENTE | + * OP_FLAG_POLAK_RIBIERE | + * OP_FLAG_POWELL_RESTART) + * otherwise VMLM-B is used with flags: (OP_FLAG_UPDATE_WITH_GP | + * OP_FLAG_SHANNO_PHUA | + * OP_FLAG_MORE_THUENTE). + * See documentation of op_get_flags to figure out the allowed bit + * flags and their meaning. + * + * MEM - Number of previous directions used in variable metric limited + * memory method (default min(7, numberof(X))). + * + * MAXITER - Maximum number of iterations (default: no limits). + * + * MAXEVAL - Maximum number of function evaluations (default: no limits). + * + * FTOL - Relative function change tolerance for convergence (default: + * 1.5e-8). + * + * GTOL - Gradient tolerance for convergence (default: 3.7e-11). + * + * VERB - Verbose mode? If non-nil and non-zero, print out information + * every VERB iterations and for the final one. + * + * QUIET - If true and not in verbose mode, do not print warning nor + * convergence error messages. + * + * OUPTPUT - Output for verbose mode. For instance, text file stream + * opened for writing. + * + * VIEWER - User defined subroutine to call every VERB iterations (see + * keyword VERB above)to display the solution X. The subroutine will + * be called as: + * viewer, x, extra; + * where X is the current solution and EXTRA is the value of keyword + * EXTRA (which to see). If the viewer uses Yorick graphics + * window(s) it may call "pause, 1;" before returning to make sure + * that graphics get correctly updated. + * + * PRINTER - User defined subroutine to call every VERB iterations (see + * keyword VERB above) to printout iteration information. + * The subroutine will be called as: + * printer, output, iter, eval, cpu, fx, gnorm, steplen, x, extra; + * where OUTPUT is the value of keyword OUTPUT (which to see), ITER + * is the number of iterations, EVAL is the number of function + * evaluations, CPU is the elapsed CPU time in seconds, FX is the + * function value at X, GNORM is the Euclidean norm of the gradient + * at X, STEPLEN is the length of the step along the search + * direction, X is the current solution and EXTRA is the value of + * keyword EXTRA (which to see). + * + * SFTOL, SGTOL, SXTOL, SXBIG - Line search tolerance and safeguard + * parameters (see op_csrch). + * + * SEE ALSO: op_get_flags, op_csrch, + * op_cgmnb_setup, op_cgmnb_next, + * op_vmlmb_setup, op_vmlmb_next. + */ +{ + local result, gx; + + /* Get function. */ + if (! is_func(f)) { + error, "expecting a function for argument F"; + } + use_extra = (! is_void(extra)); + + /* Starting parameters. */ + if ((s = structof(x)) != double && s != float && s != long && + s != int && s != short && s != char) { + error, "expecting a numerical array for initial parameters X"; + } + n = numberof(x); + dims = dimsof(x); + + /* Bounds on parameters. */ + bounds = 0; + if (! is_void(xmin)) { + if (is_void((t = dimsof(x, xmin))) || t(1) != dims(1) + || anyof(t != dims)) { + error, "bad dimensions for lower bound XMIN"; + } + if ((convert = (s = structof(xmin)) != double) && s != float && + s != long && s != int && s != short && s != char) { + error, "bad data type for lower bound XMIN"; + } + if (convert || (t = dimsof(xmin))(1) != dims(1) || anyof(t != dims)) { + xmin += array(double, dims); + } + bounds |= 1; + } + if (! is_void(xmax)) { + if (is_void((t = dimsof(x, xmax))) || t(1) != dims(1) + || anyof(t != dims)) { + error, "bad dimensions for lower bound XMAX"; + } + if ((convert = (s = structof(xmax)) != double) && s != float && + s != long && s != int && s != short && s != char) { + error, "bad data type for lower bound XMAX"; + } + if (convert || (t = dimsof(xmax))(1) != dims(1) || anyof(t != dims)) { + xmax += array(double, dims); + } + bounds |= 2; + } + + /* Output stream. */ + if (! is_void(output)) { + if (structof(output) == string) { + output = open(output, "a"); + } else if (typeof(output) != "text_stream") { + error, "bad value for keyword OUTPUT"; + } + } + + /* Maximum number of iterations and function evaluations. */ + check_iter = (! is_void(maxiter)); + check_eval = (! is_void(maxeval)); + + /* Viewer and printer subroutines. */ + if (is_void(printer)) { + use_printer = 0n; + } else if (is_func(printer)) { + use_printer = 1n; + } else { + error, "bad value for keyword PRINTER"; + } + if (is_void(viewer)) { + use_viewer = 0n; + } else if (is_func(viewer)) { + use_viewer = 1n; + } else { + error, "bad value for keyword VIEWER"; + } + + + /* Choose minimization method. */ + //if (is_void(frtol)) frtol = 1e-10; + //if (is_void(fatol)) fatol = 1e-10; + if (! method) { + /* Variable metric. */ + if (is_void(mem)) mem = min(n, 7); + if (is_void(fmin)) fmin = 0.0; + method = 0; + method_name = swrite(format="Limited Memory BFGS (VMLM with MEM=%d)", + mem); + ws = op_vmlmb_setup(n, mem, /*fmin=fmin,*/ + fatol=fatol, frtol=frtol, + sftol=sftol, sgtol=sgtol, sxtol=sxtol); + } else if (method < 0) { + if (is_void(mem)) mem = min(n, 7); + method_name = swrite(format="Limited Memory BFGS (LBFGS with MEM=%d)", + mem); + ws = op_lbfgs_setup(n, mem); + } else if (method >= 1 && method <= 15) { + /* Conjugate gradient. */ + mem = 2; + error, "conjugate-gradient method not yet implemented"; + method_name = swrite(format="Conjugate Gradient (%s)", + ["Fletcher-Reeves", "Polak-Ribiere", + "Polak-Ribiere with non-negative BETA"](method&3)); + ws = optim_cgmn_setup(method, fmin=fmin, fatol=fatol, frtol=frtol); + } else { + error, "bad METHOD"; + } + step = 0.0; + task = 1; + eval = iter = 0; + stop = 0n; + if (verb) { + elapsed = array(double, 3); + timer, elapsed; + cpu_start = elapsed(1); + } + for (;;) { + local gx; /* to store the gradient */ + if (task == 1) { + /* Evaluate function and gradient. */ + if (bounds) { + if (bounds & 1) { + x = max(x, xmin); + } + if (bounds & 2) { + x = min(x, xmax); + } + } + fx = (use_extra ? f(x, gx, extra) : f(x, gx)); + ++eval; + if (bounds) { + /* Figure out the set of free parameters: + * ACTIVE(i) = 0 if X(i) has a lower bound XMIN(i) + * and X(i) = XMIN(i) and GX(i) >= 0 + * 0 if X(i) value has an upper bound XMAX(i) + * and X(i) = XMAX(i) and GX(i) <= 0 + * 1 (or any non-zero value) otherwise + */ + if (bounds == 1) { + active = ((x > xmin) | (gx < 0.0)); + } else if (bounds == 2) { + active = ((x < xmax) | (gx > 0.0)); + } else { + active = (((x > xmin) | (gx < 0.0)) | ((x < xmax) | (gx > 0.0))); + } + } + } + + /* Check for convergence. */ + if (task != 1 || eval == 1) { + if (task > 2) { + stop = 1n; + msg = op_vmlmb_msg(ws); + } else if (check_iter && iter > maxiter) { + stop = 1n; + msg = swrite(format="warning: too many iterations (%d)\n", iter); + } else if (check_eval && eval > maxeval) { + stop = 1n; + msg = swrite(format="warning: too many function evaluations (%d)\n", + eval); + } + if (verb) { + if (eval == 1 && ! use_printer) { + write, output, format="# Method %d (MEM=%d): %s\n#\n", + method, mem, method_name; + write, output, format="# %s\n# %s\n", + "ITER EVAL CPU (ms) FUNC GNORM STEPLEN", + "---------------------------------------------------------------"; + } + if (stop || ! (iter % verb)) { + timer, elapsed; + cpu = 1e3*(elapsed(1) - cpu_start); + gnorm = sqrt(sum(gx*gx)); + if (use_printer) { + printer, output, iter, eval, cpu, fx, gnorm, steplen, x, extra; + } else { + write, output, format=" %5d %5d %10.3f %+-24.15e%-9.1e%-9.1e\n", + iter, eval, cpu, fx, gnorm, step; + } + if (use_viewer) { + viewer, x, extra; + } + } + } + if (stop) { + if (msg && (verb || (task != 3 && ! quiet))) { + write, output, format="# %s\n#\n", msg; + } + return x; + } + } + + /* Call optimizer. */ + if (! method) { + task = op_vmlmb_next(x, fx, gx, ws, active); + iter = (*ws(2))(7); + step = (*ws(3))(22); + } else if (method < 0) { + task = op_lbfgs_next(x, fx, gx, ws); + if (task == 2 || task == 3) ++iter; + step = -1.0; + } + } +} + +/*---------------------------------------------------------------------------* + * Local Variables: * + * mode: Yorick * + * c-basic-offset: 2 * + * tab-width: 8 * + * fill-column: 78 * + * coding: latin-1 * + * End: * + *---------------------------------------------------------------------------*/ diff -Nru yorick-optimpack-1.3.2+dfsg/optimpack1/yorick/OptimPack1-test.i yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/yorick/OptimPack1-test.i --- yorick-optimpack-1.3.2+dfsg/optimpack1/yorick/OptimPack1-test.i 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/yorick/OptimPack1-test.i 2008-02-07 10:45:53.000000000 +0000 @@ -0,0 +1,1026 @@ +/* + * OptimPack1-test.i -- + * + * Various tests from MINPACK suite for the optimization routines in + * OptimPack extension for Yorick. + * + *----------------------------------------------------------------------------- + * + * Copyright (C) 2003-2007 Eric Thiébaut. + * + * This file is part of OptimPack. + * + * OptimPack is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * OptimPack is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with OptimPack (file "COPYING" in the top source + * directory); if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *----------------------------------------------------------------------------- + * + * History: + * $Id: OptimPack1-test.i,v 1.1 2007/07/05 10:13:11 eric Exp eric $ + * $Log: OptimPack1-test.i,v $ + * Revision 1.1 2007/07/05 10:13:11 eric + * Initial revision + * + *----------------------------------------------------------------------------- + */ + +require, "OptimPack1.i"; + +#if 0 +#include "OptimPack1-test.i" +for (i=1;i<=18;++i) op_test_um, prob=i, method=0, verb=1, output="OptimPack1-test.out"; + +// Since the CPU time may change, you can compare the outputs +// with: +// sed -e 's/^\( *[0-9]* *[0-9]*\) *[^ ]*/\1/' +// +#endif + + +local op_rosenbrock_nevals; +op_rosenbrock_nevals=0; + +func op_test_rosenbrock(nil, start=, method=, ndirs=, frtol=) +/* DOCUMENT op_test_rosenbrock, ...; + Test op_driver with Rosenbrock function. + + SEE ALSO: op_test_rosenbrock_func. */ +{ + x = is_void(start) ? [0.0, 0.0] : start; + return op_driver(op_test_rosenbrock_func, + (is_void(start) ? [0.0, 0.0] : start), + method=method, fmin=0.0, verb=1, ndirs=ndirs, + frtol=frtol); +} + +func op_test_rosenbrock_func(x, &g) +{ + // Rosenbrock: + // f = 100*(x2 - x1^2)^2 + (1 - x1)^2 + x1 = x(1); + u = x(2) - x1*x1; + v = 1.0 - x1; + f = 100.0*u*u + v*v; + g = [-400.0*u*x1 - 2.0*v, 200.0*u]; + ++op_rosenbrock_nevals; + return f; +} + +func op_test_quad(x, &g) +{ + u = (x - [1.0, 1.0, 1.0]); + w = [3.0, 7.0, 2.0]; + g = 2.0*w*u; + return sum(w*u*u); +} + +func op_test_um(prob=, n=, method=, ndir=, verb=, factor=, + maxiter=, maxeval=, frtol=, fatol=, + sftol=, sgtol=, sxtol=, + output=) +/* DOCUMENT op_test_um(...) + Check various optimization methods for eighteen nonlinear unconstrained + minimization problems. + + SEE ALSO: optim_vmlm, optim_cgmn, minpack1_umobj. */ +{ + /* Output array. */ + local result; + + /* Output stream. */ + if (! is_void(output)) { + if (structof(output) == string) { + output = open(output, "a"); + } else if (typeof(output) != "text_stream") { + error, "bad value for keyword OUTPUT"; + } + } + + /* Check compatibility of arguments N and PROB. */ + if (prob == 1) { + name = "Helical valley function."; + if (is_void(n)) n = 3; + else if (n != 3) error, "N must be 3 for problem #1"; + } else if (prob == 2) { + name = "Biggs exp6 function."; + if (is_void(n)) n = 6; + else if (n != 6) error, "N must be 6 for problem #2"; + } else if (prob == 3) { + name = "Gaussian function."; + if (is_void(n)) n = 3; + else if (n != 3) error, "N must be 3 for problem #3"; + } else if (prob == 4) { + name = "Powell badly scaled function."; + if (is_void(n)) n = 2; + else if (n != 2) error, "N must be 2 for problem #4"; + } else if (prob == 5) { + name = "Box 3-dimensional function."; + if (is_void(n)) n = 3; + else if (n != 3) error, "N must be 3 for problem #5"; + } else if (prob == 6) { + name = "Variably dimensioned function."; + if (is_void(n)) n = 10; + else if (n < 1) error, "N must be >= 1 in problem #6"; + } else if (prob == 7) { + name = "Watson function."; + msg = "N may be 2 or greater but is usually 6 or 9 for problem #7"; + if (is_void(n)) { + write, msg; + n = 6; + } else if (n < 2) error, msg; + } else if (prob == 8) { + name = "Penalty function I."; + if (is_void(n)) n = 10; + else if (n < 1) error, "N must be >= 1 in problem #8"; + } else if (prob == 9) { + name = "Penalty function II."; + if (is_void(n)) n = 10; + else if (n < 1) error, "N must be >= 1 in problem #9"; + } else if (prob == 10) { + name = "Brown badly scaled function."; + if (is_void(n)) n = 2; + else if (n != 2) error, "N must be 2 for problem #10"; + } else if (prob == 11) { + name = "Brown and Dennis function."; + if (is_void(n)) n = 4; + else if (n != 4) error, "N must be 4 for problem #11"; + } else if (prob == 12) { + name = "Gulf research and development function."; + if (is_void(n)) n = 3; + else if (n != 3) error, "N must be 3 for problem #12"; + } else if (prob == 13) { + name = "Trigonometric function."; + if (is_void(n)) n = 10; + else if (n < 1) error, "N must be >= 1 in problem #13"; + } else if (prob == 14) { + name = "Extended Rosenbrock function."; + if (is_void(n)) n = 10; + else if (n < 1 || n%2 != 0) + error, "N must be a multiple of 2 in problem #14"; + } else if (prob == 15) { + name = "Extended Powell function."; + if (is_void(n)) n = 12; + else if (n < 1 || n%4 != 0) + error, "N must be a multiple of 4 in problem #15"; + } else if (prob == 16) { + name = "Beale function."; + if (is_void(n)) n = 2; + else if (n != 2) error, "N must be 2 for problem #16"; + } else if (prob == 17) { + name = "Wood function."; + if (is_void(n)) n = 4; + else if (n != 4) error, "N must be 4 for problem #17"; + } else if (prob == 18) { + name = "Chebyquad function."; + if (is_void(n)) n = 25; + else if (n<1 || n>50) error, "N must be <=50 for problem #18"; + } else error, "PROB must be an integer between 1 and 18"; + + /* Maximum number of iterations and function evaluations. */ + if (is_void(maxiter)) maxiter = 100*n; + if (is_void(maxeval)) maxeval = 10*maxiter; + + /* Starting vector. */ + x = minpack1_umipt(n, prob, factor); + dims = dimsof(x); + + /* Choose minimization method. */ + //if (is_void(frtol)) frtol = 1e-10; + //if (is_void(fatol)) fatol = 1e-10; + if (is_void(method)) method = 0; + if (method == 0) { + /* Variable metric. */ + if (is_void(ndir)) ndir = n; + method_name = swrite(format="Limited Memory BFGS (VMLM with NDIR=%d)", + ndir); + ws = op_vmlmb_setup(n, ndir, fmin=0.0, + fatol=fatol, frtol=frtol, + sftol=sftol, sgtol=sgtol, sxtol=sxtol); + } else if (method < 0) { + if (is_void(ndir)) ndir = n; + method_name = swrite(format="Limited Memory BFGS (LBFGS with NDIR=%d)", + ndir); + ws = op_lbfgs_setup(n, ndir); + } else if (method >= 1 && method <= 15) { + /* Conjugate gradient. */ + ndir = 2; + method_name = swrite(format="Conjugate Gradient (%s)", + ["Fletcher-Reeves", "Polak-Ribiere", + "Polak-Ribiere with non-negative BETA"](method&3)); + ws = optim_cgmn_setup(method, fmin=fmin, fatol=fatol, frtol=frtol); + } else { + error, "bad METHOD"; + } + step = 0.0; + task = 1; + eval = iter = 0; + elapsed = array(double, 3); + timer, elapsed; + cpu_start = elapsed(1); + for (;;) { + if (task == 1) { + /* Evaluate function. */ + f = minpack1_umobj(x, prob); + g = minpack1_umgrd(x, prob); + ++eval; + } + + /* Check for convergence. */ + if (task != 1 || eval == 1) { + too_many_eval = (maxeval >= 1 && eval > maxeval); + too_many_iter = (maxiter >= 1 && iter > maxiter); + timer, elapsed; + cpu = elapsed(1) - cpu_start; + gnorm = sqrt(sum(g*g)); + if (verb) { + if (eval == 1) { + write, output, format="#\n# Problem %d (N=%d): %s\n", + prob, n, name; + write, output, format="# Method %d (NDIR=%d): %s\n#\n", + method, ndir, method_name; + write, output, format="# %s\n# %s\n", + "ITER EVAL CPU (ms) FUNC GNORM STEPLEN", + "---------------------------------------------------------------"; + } + write, output, format=" %5d %5d %10.3f %+-24.15e%-9.1e%-9.1e\n", + iter, eval, 1e3*cpu, f, gnorm, step; + } + if (! am_subroutine()) grow, result, [[iter, eval, 1e3*cpu, f, + gnorm, step]]; + if (task > 2) { + msg = op_vmlmb_msg(ws); + break; + } + if (maxiter >= 0 && iter > maxiter && task == 2) { + msg = swrite(format="warning: too many iterations (%d)\n", + iter); + break; + } + if (maxeval >= 0 && eval > maxeval) { + x = x0; + msg = swrite(format="warning: too many function evaluation (%d)\n", + eval); + break; + } + } + + + /* Call optimizer. */ + if (! method) { + task = op_vmlmb_next(x, f, g, ws); + iter = (*ws(2))(7); + step = (*ws(3))(22); + } else if (method < 0) { + task = op_lbfgs_next(x, f, g, ws); + if (task == 2 || task == 3) ++iter; + step = -1.0; + } else { + optim_cgmn, x, f, g, task, ws; + iter = optim_cgmn_iter(ws); + step = optim_cgmn_step(ws); + } + } + + if (task == 3) status = 0; + else if (ident == 4) status = 1; + else status = 2; + write, output, format=(verb?"# %s\n#\n":"*** %s\n"), msg; + return result; + //return [status, n, ndir, method, iter, eval, cpu, f]; + //return x; +} + +/*---------------------------------------------------------------------------*/ +/* NONLINEAR UNCONSTRAINED MINIMIZATION PROBLEMS + * + * This suite of problems is taken from the MINPACK Project. + * + * HISTORY: + * - Argonne National Laboratory. MINPACK Project. March 1980. + * Burton S. Garbow, Kenneth E. Hillstrom, Jorge J. More. + * - Conversion to Yorick. November 2001. Eric Thiebaut. + */ +_um_y = [9.0e-4, 4.4e-3, 1.75e-2, 5.4e-2, 1.295e-1, + 2.42e-1, 3.521e-1, 3.989e-1, 3.521e-1, 2.42e-1, + 1.295e-1, 5.4e-2, 1.75e-2, 4.4e-3, 9.0e-4]; + +func minpack1_umobj(x, prob) +/* DOCUMENT minpack1_umobj(x, prob) + Returns the objective functions of eighteen nonlinear unconstrained + minimization problems. X is the parameter array: a vector of length + N, PROB is the problem number (a positive integer between 1 and 18). + + The values of N for functions 1,2,3,4,5,10,11,12,16 and 17 are + 3,6,3,2,3,2,4,3,2 and 4, respectively. For function 7, n may be 2 or + greater but is usually 6 or 9. For functions 6,8,9,13,14,15 and 18, N + may be variable, however it must be even for function 14, a multiple + of 4 for function 15, and not greater than 50 for function 18. + + SEE ALSO: minpack1_umgrd, minpack1_umipt. */ +{ + n = numberof(x); + + /* Function routine selector. */ + if (prob == 1) { + /* Helical valley function. */ + tpi = 8.0*atan(1.0); + if (x(1) > 0.0) th = atan(x(2)/x(1))/tpi; + else if (x(1) < 0.0) th = atan(x(2)/x(1))/tpi + 0.5; + else th = (x(2) >= 0.0 ? 0.25 : -0.25); + arg = x(1)*x(1) + x(2)*x(2); + r = sqrt(arg); + t = x(3) - 10.0*th; + f = 100.0*(t*t + (r - 1.0)*(r - 1.0)) + x(3)*x(3); + return f; + } else if (prob == 2) { + /* Biggs exp6 function. */ + f = 0.0; + for (i=1 ; i<=13 ; i+=1) { + d1 = double(i)/10.0; + d2 = exp(-d1) - 5.0*exp(-10.0*d1) + 3.0*exp(-4.0*d1); + s1 = exp(-d1*x(1)); + s2 = exp(-d1*x(2)); + s3 = exp(-d1*x(5)); + t = x(3)*s1 - x(4)*s2 + x(6)*s3 - d2; + f += t*t; + } + return f; + } else if (prob == 3) { + /* Gaussian function. */ + f = 0.0; + for (i=1 ; i<=15 ; i+=1) { + d1 = 0.5*double(i-1); + d2 = 3.5 - d1 - x(3); + arg = -0.5*x(2)*d2*d2; + r = exp(arg); + t = x(1)*r - _um_y(i); + f += t*t; + } + return f; + } else if (prob == 4) { + /* Powell badly scaled function. */ + t1 = 1e4*x(1)*x(2) - 1.0; + s1 = exp(-x(1)); + s2 = exp(-x(2)); + t2 = s1 + s2 - 1.0001; + f = t1*t1 + t2*t2; + return f; + } else if (prob == 5) { + /* Box 3-dimensional function. */ + f = 0.0; + for (i=1 ; i<=10 ; i+=1) { + d1 = double(i); + d2 = d1/10.0; + s1 = exp(-d2*x(1)); + s2 = exp(-d2*x(2)); + s3 = exp(-d2) - exp(-d1); + t = s1 - s2 - s3*x(3); + f += t*t; + } + return f; + } else if (prob == 6) { + /* Variably dimensioned function. */ + t1 = 0.0; + t2 = 0.0; + for (j=1 ; j<=n ; j+=1) { + t1 += double(j)*(x(j) - 1.0); + t = x(j) - 1.0; + t2 += t*t; + } + t = t1*t1; + f = t2 + t*(1.0 + t); + return f; + } else if (prob == 7) { + /* Watson function. */ + f = 0.0; + for (i=1 ; i<=29 ; i+=1) { + d1 = double(i)/29.0; + s1 = 0.0; + d2 = 1.0; + for (j=2 ; j<=n ; j+=1) { + s1 += double(j-1)*d2*x(j); + d2 = d1*d2; + } + s2 = 0.0; + d2 = 1.0; + for (j=1 ; j<=n ; j+=1) { + s2 += d2*x(j); + d2 = d1*d2; + } + t = s1 - s2*s2 - 1.0; + f += t*t; + } + t = x(1)*x(1); + t1 = x(2) - t - 1.0; + f += t + t1*t1; + return f; + } else if (prob == 8) { + /* Penalty function I. */ + t1 = -0.25; + t2 = 0.0; + for (j=1 ; j<=n ; j+=1) { + t1 += x(j)*x(j); + t = x(j) - 1.0; + t2 += t*t; + } + f = 1e-5*t2 + t1*t1; + return f; + } else if (prob == 9) { + /* Penalty function II. */ + t1 = -1.0; + t2 = 0.0; + t3 = 0.0; + d1 = exp(0.1); + d2 = 1.0; + s2 = 0.0; /* avoid compiler warning about `s2' used uninitialized */ + for (j=1 ; j<=n ; j+=1) { + t1 += double(n-j+1)*x(j)*x(j); + s1 = exp(x(j)/10.0); + if (j > 1) { + s3 = s1 + s2 - d2*(d1 + 1.0); + t2 += s3*s3; + t = (s1 - 1.0/d1); + t3 += t*t; + } + s2 = s1; + d2 = d1*d2; + } + t = (x(1) - 0.2); + f = 1e-5*(t2 + t3) + t1*t1 + t*t; + return f; + } else if (prob == 10) { + /* Brown badly scaled function. */ + t1 = x(1) - 1e6; + t2 = x(2) - 2e-6; + t3 = x(1)*x(2) - 2.0; + f = t1*t1 + t2*t2 + t3*t3; + return f; + } else if (prob == 11) { + /* Brown and Dennis function. */ + f = 0.0; + for (i=1 ; i<=20 ; i+=1) { + d1 = double(i)/5.0; + d2 = sin(d1); + t1 = x(1) + d1*x(2) - exp(d1); + t2 = x(3) + d2*x(4) - cos(d1); + t = t1*t1 + t2*t2; + f += t*t; + } + return f; + } else if (prob == 12) { + /* Gulf research and development function. */ + f = 0.0; + d1 = 2.0/3.0; + for (i=1 ; i<=99 ; i+=1) { + arg = double(i)/100.0; + r = (-50.0*log(arg))^d1 + 25.0 - x(2); + t1 = (abs(r)^x(3))/x(1); + t2 = exp(-t1); + t = t2 - arg; + f += t*t; + } + return f; + } else if (prob == 13) { + /* Trigonometric function. */ + s1 = 0.0; + for (j=1 ; j<=n ; j+=1) { + s1 += cos(x(j)); + } + f = 0.0; + for (j=1 ; j<=n ; j+=1) { + t = double(n+j) - sin(x(j)) - s1 - double(j)*cos(x(j)); + f += t*t; + } + return f; + } else if (prob == 14) { + /* Extended Rosenbrock function. */ + f = 0.0; + for (j=1 ; j<=n ; j+=2) { + t1 = 1.0 - x(j); + t2 = 10.0*(x(j+1) - x(j)*x(j)); + f += t1*t1 + t2*t2; + } + return f; + } else if (prob == 15) { + /* Extended Powell function. */ + f = 0.0; + for (j=1 ; j<=n ; j+=4) { + t = x(j) + 10.0*x(j+1); + t1 = x(j+2) - x(j+3); + s1 = 5.0*t1; + t2 = x(j+1) - 2.0*x(j+2); + s2 = t2*t2*t2; + t3 = x(j) - x(j+3); + s3 = 10.0*t3*t3*t3; + f += t*t + s1*t1 + s2*t2 + s3*t3; + } + return f; + } else if (prob == 16) { + /* Beale function. */ + s1 = 1.0 - x(2); + t1 = 1.5 - x(1)*s1; + s2 = 1.0 - x(2)*x(2); + t2 = 2.25 - x(1)*s2; + s3 = 1.0 - x(2)*x(2)*x(2); + t3 = 2.625 - x(1)*s3; + f = t1*t1 + t2*t2 + t3*t3; + return f; + } else if (prob == 17) { + /* Wood function. */ + s1 = x(2) - x(1)*x(1); + s2 = 1.0 - x(1); + s3 = x(2) - 1.0; + t1 = x(4) - x(3)*x(3); + t2 = 1.0 - x(3); + t3 = x(4) - 1.0; + f = 100.0*s1*s1 + s2*s2 + 90.0*t1*t1 + t2*t2 + \ + 10.0*(s3 + t3)*(s3 + t3) + (s3 - t3)*(s3 - t3)/10.0; + return f; + } else if (prob == 18) { + /* Chebyquad function. */ + fvec = array(0.0, n); + for (j=1 ; j<=n ; j+=1) { + t1 = 1.0; + t2 = 2.0*x(j) - 1.0; + t = 2.0*t2; + for (i=1 ; i<=n ; i+=1) { + fvec(i) += t2; + th = t*t2 - t1; + t1 = t2; + t2 = th; + } + } + f = 0.0; + d1 = 1.0/double(n); + iev = -1; + for (i=1 ; i<=n ; i+=1) { + t = d1*fvec(i); + if (iev > 0) t += 1.0/(double(i)*double(i) - 1.0); + f += t*t; + iev = -iev; + } + return f; + } + return 0.0; +} + +func minpack1_umgrd(x, prob) +/* DOCUMENT minpack1_umgrd(x, prob) + Returns the gradient vectors of eighteen nonlinear unconstrained + minimization problems. The problem dimensions are as described in the + prologue comments of minpack1_umobj. + + SEE ALSO: minpack1_umobj, minpack1_umipt. */ +{ + n = numberof(x); + g = array(double, n); + + /* Gradient routine selector. */ + if (prob == 1) { + /* Helical valley function. */ + tpi = 8.0*atan(1.0); + if (x(1) > 0.0) th = atan(x(2)/x(1))/tpi; + else if (x(1) < 0.0) th = atan(x(2)/x(1))/tpi + 0.5; + else th = (x(2) >= 0.0 ? 0.25 : -0.25); + arg = x(1)*x(1) + x(2)*x(2); + r = sqrt(arg); + t = x(3) - 10.0*th; + s1 = 10.0*t/(tpi*arg); + g(1) = 200.0*(x(1) - x(1)/r + x(2)*s1); + g(2) = 200.0*(x(2) - x(2)/r - x(1)*s1); + g(3) = 2.0*(100.0*t + x(3)); + } else if (prob == 2) { + /* Biggs exp6 function. */ + for (j=1 ; j<=6 ; ++j) g(j) = 0.0; + for (i=1 ; i<=13 ; ++i) { + d1 = double(i)/10.0; + d2 = exp(-d1) - 5.0*exp(-10.0*d1) + 3.0*exp(-4.0*d1); + s1 = exp(-d1*x(1)); + s2 = exp(-d1*x(2)); + s3 = exp(-d1*x(5)); + t = x(3)*s1 - x(4)*s2 + x(6)*s3 - d2; + th = d1*t; + g(1) = g(1) - s1*th; + g(2) = g(2) + s2*th; + g(3) = g(3) + s1*t; + g(4) = g(4) - s2*t; + g(5) = g(5) - s3*th; + g(6) = g(6) + s3*t; + } + g(1) = 2.0*x(3)*g(1); + g(2) = 2.0*x(4)*g(2); + g(3) = 2.0*g(3); + g(4) = 2.0*g(4); + g(5) = 2.0*x(6)*g(5); + g(6) = 2.0*g(6); + } else if (prob == 3) { + /* Gaussian function. */ + g(1) = 0.0; + g(2) = 0.0; + g(3) = 0.0; + for (i=1 ; i<=15 ; ++i) { + d1 = 0.5*double(i-1); + d2 = 3.5 - d1 - x(3); + arg = -0.5*x(2)*d2*d2; + r = exp(arg); + t = x(1)*r - _um_y(i); + s1 = r*t; + s2 = d2*s1; + g(1) = g(1) + s1; + g(2) = g(2) - d2*s2; + g(3) = g(3) + s2; + } + g(1) = 2.0*g(1); + g(2) = x(1)*g(2); + g(3) = 2.0*x(1)*x(2)*g(3); + } else if (prob == 4) { + /* Powell badly scaled function. */ + t1 = 1e4*x(1)*x(2) - 1.0; + s1 = exp(-x(1)); + s2 = exp(-x(2)); + t2 = s1 + s2 - 1.0001; + g(1) = 2.0*(1e4*x(2)*t1 - s1*t2); + g(2) = 2.0*(1e4*x(1)*t1 - s2*t2); + } else if (prob == 5) { + /* Box 3-dimensional function. */ + g(1) = 0.0; + g(2) = 0.0; + g(3) = 0.0; + for (i=1 ; i<=10 ; ++i) { + d1 = double(i); + d2 = d1/10.0; + s1 = exp(-d2*x(1)); + s2 = exp(-d2*x(2)); + s3 = exp(-d2) - exp(-d1); + t = s1 - s2 - s3*x(3); + th = d2*t; + g(1) = g(1) - s1*th; + g(2) = g(2) + s2*th; + g(3) = g(3) - s3*t; + } + g(1) = 2.0*g(1); + g(2) = 2.0*g(2); + g(3) = 2.0*g(3); + } else if (prob == 6) { + /* Variably dimensioned function. */ + t1 = 0.0; + for (j=1 ; j<=n ; ++j) { + t1 += double(j)*(x(j) - 1.0); + } + t = t1*(1.0 + 2.0*t1*t1); + for (j=1 ; j<=n ; ++j) { + g(j) = 2.0*(x(j) - 1.0 + double(j)*t); + } + } else if (prob == 7) { + /* Watson function. */ + for (j=1 ; j<=n ; ++j) { + g(j) = 0.0; + } + for (i=1 ; i<=29 ; ++i) { + d1 = double(i)/29.0; + s1 = 0.0; + d2 = 1.0; + for (j=2 ; j<=n ; ++j) { + s1 += double(j-1)*d2*x(j); + d2 = d1*d2; + } + s2 = 0.0; + d2 = 1.0; + for (j=1 ; j<=n ; ++j) { + s2 += d2*x(j); + d2 = d1*d2; + } + t = s1 - s2*s2 - 1.0; + s3 = 2.0*d1*s2; + d2 = 2.0/d1; + for (j=1 ; j<=n ; ++j) { + g(j) = g(j) + d2*(double(j-1) - s3)*t; + d2 = d1*d2; + } + } + t1 = x(2) - x(1)*x(1) - 1.0; + g(1) = g(1) + x(1)*(2.0 - 4.0*t1); + g(2) = g(2) + 2.0*t1; + } else if (prob == 8) { + /* Penalty function I. */ + t1 = -0.25; + for (j=1 ; j<=n ; ++j) { + t1 += x(j)*x(j); + } + d1 = 2.0*1e-5; + th = 4.0*t1; + for (j=1 ; j<=n ; ++j) { + g(j) = d1*(x(j) - 1.0) + x(j)*th; + } + } else if (prob == 9) { + /* Penalty function II. */ + s2 = 0.0; /* avoid compiler warning about `s2' used uninitialized */ + t1 = -1.0; + for (j=1 ; j<=n ; ++j) { + t1 += double(n-j+1)*x(j)*x(j); + } + d1 = exp(0.1); + d2 = 1.0; + th = 4.0*t1; + for (j=1 ; j<=n ; ++j) { + g(j) = double(n-j+1)*x(j)*th; + s1 = exp(x(j)/10.0); + if (j > 1) { + s3 = s1 + s2 - d2*(d1 + 1.0); + g(j) = g(j) + 1e-5*s1*(s3 + s1 - 1.0/d1)/5.0; + g(j-1) = g(j-1) + 1e-5*s2*s3/5.0; + } + s2 = s1; + d2 = d1*d2; + } + g(1) = g(1) + 2.0*(x(1) - 0.2); + } else if (prob == 10) { + /* Brown badly scaled function. */ + t1 = x(1) - 1e6; + t2 = x(2) - 2e-6; + t3 = x(1)*x(2) - 2.0; + g(1) = 2.0*(t1 + x(2)*t3); + g(2) = 2.0*(t2 + x(1)*t3); + } else if (prob == 11) { + /* Brown and Dennis function. */ + g(1) = 0.0; + g(2) = 0.0; + g(3) = 0.0; + g(4) = 0.0; + for (i=1 ; i<=20 ; ++i) { + d1 = double(i)/5.0; + d2 = sin(d1); + t1 = x(1) + d1*x(2) - exp(d1); + t2 = x(3) + d2*x(4) - cos(d1); + t = t1*t1 + t2*t2; + s1 = t1*t; + s2 = t2*t; + g(1) = g(1) + s1; + g(2) = g(2) + d1*s1; + g(3) = g(3) + s2; + g(4) = g(4) + d2*s2; + } + g(1) = 4.0*g(1); + g(2) = 4.0*g(2); + g(3) = 4.0*g(3); + g(4) = 4.0*g(4); + } else if (prob == 12) { + /* Gulf research and development function. */ + g(1) = 0.0; + g(2) = 0.0; + g(3) = 0.0; + d1 = 2.0/3.0; + for (i=1 ; i<=99 ; ++i) { + arg = double(i)/100.0; + r = (-50.0*log(arg))^d1 + 25.0 - x(2); + t1 = (abs(r)^x(3))/x(1); + t2 = exp(-t1); + t = t2 - arg; + s1 = t1*t2*t; + g(1) = g(1) + s1; + g(2) = g(2) + s1/r; + g(3) = g(3) - s1*log(abs(r)); + } + g(1) = 2.0*g(1)/x(1); + g(2) = 2.0*x(3)*g(2); + g(3) = 2.0*g(3); + } else if (prob == 13) { + /* Trigonometric function. */ + s1 = 0.0; + for (j=1 ; j<=n ; ++j) { + g(j) = cos(x(j)); + s1 += g(j); + } + s2 = 0.0; + for (j=1 ; j<=n ; ++j) { + th = sin(x(j)); + t = double(n+j) - th - s1 - double(j)*g(j); + s2 += t; + g(j) = (double(j)*th - g(j))*t; + } + for (j=1 ; j<=n ; ++j) { + g(j) = 2.0*(g(j) + sin(x(j))*s2); + } + } else if (prob == 14) { + /* Extended Rosenbrock function. */ + for (j=1 ; j<=n ; j+=2) { + t1 = 1.0 - x(j); + g(j+1) = 200.0*(x(j+1) - x(j)*x(j)); + g(j) = -2.0*(x(j)*g(j+1) + t1); + } + } else if (prob == 15) { + /* Extended Powell function. */ + for (j=1 ; j<=n ; j+=4) { + t = x(j) + 10.0*x(j+1); + t1 = x(j+2) - x(j+3); + s1 = 5.0*t1; + t2 = x(j+1) - 2.0*x(j+2); + s2 = 4.0*t2*t2*t2; + t3 = x(j) - x(j+3); + s3 = 20.0*t3*t3*t3; + g(j) = 2.0*(t + s3); + g(j+1) = 20.0*t + s2; + g(j+2) = 2.0*(s1 - s2); + g(j+3) = -2.0*(s1 + s3); + } + } else if (prob == 16) { + /* Beale function. */ + s1 = 1.0 - x(2); + t1 = 1.5 - x(1)*s1; + s2 = 1.0 - x(2)*x(2); + t2 = 2.25 - x(1)*s2; + s3 = 1.0 - x(2)*x(2)*x(2); + t3 = 2.625 - x(1)*s3; + g(1) = -2.0*(s1*t1 + s2*t2 + s3*t3); + g(2) = 2.0*x(1)*(t1 + x(2)*(2.0*t2 + 3.0*x(2)*t3)); + } else if (prob == 17) { + /* Wood function. */ + s1 = x(2) - x(1)*x(1); + s2 = 1.0 - x(1); + s3 = x(2) - 1.0; + t1 = x(4) - x(3)*x(3); + t2 = 1.0 - x(3); + t3 = x(4) - 1.0; + g(1) = -2.0*(200.0*x(1)*s1 + s2); + g(2) = 200.0*s1 + 20.2*s3 + 19.8*t3; + g(3) = -2.0*(180.0*x(3)*t1 + t2); + g(4) = 180.0*t1 + 20.2*t3 + 19.8*s3; + } else if (prob == 18) { + /* Chebyquad function. */ + fvec = array(0.0, n); + for (j=1 ; j<=n ; ++j) { + t1 = 1.0; + t2 = 2.0*x(j) - 1.0; + t = 2.0*t2; + for (i=1 ; i<=n ; ++i) { + fvec(i) += t2; + th = t*t2 - t1; + t1 = t2; + t2 = th; + } + } + d1 = 1.0/double(n); + iev = -1; + for (i=1 ; i<=n ; ++i) { + fvec(i) *= d1; + if (iev > 0) fvec(i) += 1.0/(double(i)*double(i) - 1.0); + iev = -iev; + } + for (j=1 ; j<=n ; ++j) { + g(j) = 0.0; + t1 = 1.0; + t2 = 2.0*x(j) - 1.0; + t = 2.0*t2; + s1 = 0.0; + s2 = 2.0; + for (i=1 ; i<=n ; ++i) { + g(j) = g(j) + fvec(i)*s2; + th = 4.0*t2 + t*s2 - s1; + s1 = s2; + s2 = th; + th = t*t2 - t1; + t1 = t2; + t2 = th; + } + } + d2 = 2.0*d1; + for (j=1 ; j<=n ; ++j) g(j) *= d2; + } + return g; +} + +func minpack1_umipt(n, prob, factor) +/* DOCUMENT minpack1_umipt(n, prob, factor) + Returns the standard starting points for the functions defined by + subroutine minpack1_umobj. The function returns a vector X of N + elements, X is a multiple (times FACTOR, default 1.0) of the standard + starting point. For the seventh function the standard starting point + is 0.0, so in this case, if FACTOR is not unity, then the function + returns X filled with FACTOR. PROB has the same meaning as in + minpack1_umobj. + + SEE ALSO: minpack1_umobj, minpack1_umipt. */ +{ + if (is_void(factor)) factor = 1.0; + x = array(double, n); + + /* Selection of initial point. */ + if (prob == 1) { + /* Helical valley function. */ + x(1) = -1.0; + x(2) = 0.0; + x(3) = 0.0; + } else if (prob == 2) { + /* Biggs exp6 function. */ + x(1) = 1.0; + x(2) = 2.0; + x(3) = 1.0; + x(4) = 1.0; + x(5) = 1.0; + x(6) = 1.0; + } else if (prob == 3) { + /* Gaussian function. */ + x(1) = 0.4; + x(2) = 1.0; + x(3) = 0.0; + } else if (prob == 4) { + /* Powell badly scaled function. */ + x(1) = 0.0; + x(2) = 1.0; + } else if (prob == 5) { + /* Box 3-dimensional function. */ + x(1) = 0.0; + x(2) = 10.0; + x(3) = 20.0; + } else if (prob == 6) { + /* Variably dimensioned function. */ + h = 1.0/double(n); + for (j=1 ; j<=n ; ++j) x(j) = 1.0 - double(j)*h; + } else if (prob == 7) { + /* Watson function. */ + for (j=1 ; j<=n ; ++j) x(j) = 0.0; + } else if (prob == 8) { + /* Penalty function I. */ + for (j=1 ; j<=n ; ++j) x(j) = double(j); + } else if (prob == 9) { + /* Penalty function II. */ + for (j=1 ; j<=n ; ++j) x(j) = 0.5; + } else if (prob == 10) { + /* Brown badly scaled function. */ + x(1) = 1.0; + x(2) = 1.0; + } else if (prob == 11) { + /* Brown and Dennis function. */ + x(1) = 25.0; + x(2) = 5.0; + x(3) = -5.0; + x(4) = -1.0; + } else if (prob == 12) { + /* Gulf research and development function. */ + x(1) = 5.0; + x(2) = 2.5; + x(3) = 0.15; + } else if (prob == 13) { + /* Trigonometric function. */ + h = 1.0/double(n); + for (j=1 ; j<=n ; ++j) x(j) = h; + } else if (prob == 14) { + /* Extended Rosenbrock function. */ + for (j=1 ; j<=n ; j+=2) { + x(j) = -1.2; + x(j+1) = 1.0; + } + } else if (prob == 15) { + /* Extended Powell singular function. */ + for (j=1 ; j<=n ; j+=4) { + x(j) = 3.0; + x(j+1) = -1.0; + x(j+2) = 0.0; + x(j+3) = 1.0; + } + } else if (prob == 16) { + /* Beale function. */ + x(1) = 1.0; + x(2) = 1.0; + } else if (prob == 17) { + /* Wood function. */ + x(1) = -3.0; + x(2) = -1.0; + x(3) = -3.0; + x(4) = -1.0; + } else if (prob == 18) { + /* Chebyquad function. */ + h = 1.0/double(n+1); + for (j=1 ; j<=n ; ++j) x(j) = double(j)*h; + } + + /* Compute multiple of initial point. */ + if (factor != 1.0) { + if (prob == 7) { + for (j=1 ; j<=n ; ++j) x(j) = factor; + } else { + for (j=1 ; j<=n ; ++j) x(j) *= factor; + } + } + return x; +} + +/*---------------------------------------------------------------------------* + * Local Variables: * + * mode: Yorick * + * tab-width: 8 * + * fill-column: 75 * + * coding: latin-1 * + * End: * + *---------------------------------------------------------------------------*/ diff -Nru yorick-optimpack-1.3.2+dfsg/optimpack1/yorick/OptimPack1-test.out.orig yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/yorick/OptimPack1-test.out.orig --- yorick-optimpack-1.3.2+dfsg/optimpack1/yorick/OptimPack1-test.out.orig 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/yorick/OptimPack1-test.out.orig 2007-07-05 10:02:54.000000000 +0000 @@ -0,0 +1,1281 @@ +# +# Problem 1 (N=3): Helical valley function. +# Method 0 (NDIR=3): Limited Memory BFGS (VMLM with NDIR=3) +# +# ITER EVAL CPU (ms) FUNC GNORM STEPLEN +# --------------------------------------------------------------- + 0 1 0.000 +2.500000000000000e+03 1.9e+03 0.0e+00 + 1 2 0.000 +1.132008103520547e+03 1.1e+03 1.0e+00 + 2 3 0.000 +3.073911905701987e+02 4.7e+02 7.8e-01 + 3 4 0.000 +8.534071352331746e+01 2.1e+02 9.3e-01 + 4 5 0.000 +3.541502648995344e+01 1.1e+02 1.0e+00 + 5 6 0.000 +1.762519408308565e+01 7.3e+01 1.0e+00 + 6 7 0.000 +6.010226268823216e+00 1.7e+01 9.0e-01 + 7 8 0.000 +5.492716897495775e+00 6.3e+00 1.0e+00 + 8 9 0.000 +5.425503969579507e+00 4.3e+00 1.0e+00 + 9 10 0.000 +5.265630629847704e+00 7.5e+00 1.0e+00 + 10 11 0.000 +4.809839791888933e+00 1.9e+01 1.0e+00 + 11 12 0.000 +3.522455208281464e+00 3.0e+01 1.0e+00 + 12 14 0.000 +3.068297969073592e+00 2.7e+01 1.3e-01 + 13 15 0.000 +2.100951192748246e+00 1.5e+01 1.0e+00 + 14 16 0.000 +1.706672666076662e+00 1.3e+01 1.0e+00 + 15 17 0.000 +8.286257916242681e-01 6.9e+00 1.0e+00 + 16 18 4.001 +5.922941003132391e-01 9.6e+00 1.0e+00 + 17 20 4.001 +5.103420996864492e-01 1.1e+01 4.4e-01 + 18 21 4.001 +2.916460245825456e-01 7.0e+00 1.0e+00 + 19 22 4.001 +1.004295671502106e-01 3.3e+00 1.0e+00 + 20 23 4.001 +4.654709712389724e-02 1.3e+00 8.3e-01 + 21 24 4.001 +1.427494728803810e-02 2.6e+00 4.6e-01 + 22 25 4.001 +4.543295602689820e-03 1.0e-00 4.3e-01 + 23 26 4.001 +1.007118040044901e-03 4.6e-01 9.2e-01 + 24 27 4.001 +2.061213550356601e-04 1.9e-01 6.1e-01 + 25 28 4.001 +4.141146958118607e-05 9.1e-02 5.9e-01 + 26 29 4.001 +9.246362768846678e-06 4.6e-02 5.6e-01 + 27 30 4.001 +3.194411530932206e-06 3.5e-02 3.1e-01 + 28 31 4.001 +6.501783574339488e-07 1.4e-02 5.4e-01 + 29 32 4.001 +1.343722348096534e-07 5.4e-03 5.9e-01 + 30 33 4.001 +2.750162245743687e-08 2.3e-03 5.9e-01 + 31 34 4.001 +6.952580275602280e-09 3.8e-04 5.4e-01 + 32 35 4.001 +1.473890736071037e-09 2.1e-04 4.1e-01 + 33 36 4.001 +3.751052304854505e-10 2.5e-04 4.4e-01 + 34 37 4.001 +7.625216557423310e-11 9.0e-05 5.1e-01 + 35 38 4.001 +1.622952431278697e-11 6.6e-05 5.2e-01 + 36 39 4.001 +7.337759316133232e-12 3.6e-05 2.9e-01 + 37 40 4.001 +1.484824633556255e-12 1.6e-05 5.6e-01 + 38 41 4.001 +4.578352609117974e-13 1.2e-05 4.6e-01 + 39 42 4.001 +9.211331598248391e-14 4.8e-06 4.1e-01 + 40 43 4.001 +1.831236718906136e-14 2.5e-06 5.5e-01 + 41 44 4.001 +5.028878022134398e-15 2.4e-07 5.2e-01 +# op_vmlmb_next: FATOL test satisfied +# +# +# Problem 2 (N=6): Biggs exp6 function. +# Method 0 (NDIR=6): Limited Memory BFGS (VMLM with NDIR=6) +# +# ITER EVAL CPU (ms) FUNC GNORM STEPLEN +# --------------------------------------------------------------- + 0 1 0.000 +7.790700756559702e-01 2.6e+00 0.0e+00 + 1 3 4.000 +6.063399881248565e-01 1.4e+00 1.4e-01 + 2 4 4.000 +5.345518690614532e-01 1.2e+00 1.0e+00 + 3 5 4.000 +3.079086646397058e-01 4.0e-01 1.0e+00 + 4 6 4.000 +2.937191017970756e-01 1.2e-01 1.0e+00 + 5 7 4.000 +2.921168291268924e-01 3.4e-02 1.0e+00 + 6 8 4.000 +2.918462455582488e-01 4.3e-02 1.0e+00 + 7 9 4.000 +2.907755492762679e-01 9.9e-02 1.0e+00 + 8 10 4.000 +2.881208307389913e-01 1.7e-01 1.0e+00 + 9 11 4.000 +2.777833991389049e-01 4.6e-01 1.0e+00 + 10 13 4.000 +2.612679403981057e-01 6.3e-01 5.2e-01 + 11 14 4.000 +2.469361666977165e-01 9.9e-01 1.0e+00 + 12 15 4.000 +2.036078330726717e-01 1.0e-00 1.0e+00 + 13 16 4.000 +7.767306534374016e-02 3.6e-01 3.7e-01 + 14 17 4.000 +5.174481985556744e-02 2.1e-01 1.0e+00 + 15 18 4.000 +4.438442687186699e-02 3.2e-02 1.0e+00 + 16 19 4.000 +4.327020633870218e-02 2.0e-02 1.0e+00 + 17 20 4.000 +4.270533262117948e-02 2.0e-02 1.0e+00 + 18 21 4.000 +3.969619752160380e-02 2.1e-01 1.0e+00 + 19 22 4.000 +3.608256498897430e-02 2.2e-01 1.0e+00 + 20 23 8.000 +2.496078630339771e-02 8.7e-03 1.0e+00 + 21 25 8.000 +2.354604949127677e-02 1.2e-01 2.2e-01 + 22 26 8.000 +1.888593515049183e-02 1.4e-01 1.0e+00 + 23 27 8.000 +1.155437130469526e-02 7.9e-02 1.0e+00 + 24 28 8.000 +8.080802739733741e-03 4.6e-02 1.0e+00 + 25 30 8.000 +7.156021780018340e-03 1.1e-01 4.9e-01 + 26 31 8.000 +6.273418884507282e-03 7.0e-02 1.0e+00 + 27 32 8.000 +5.939819199276478e-03 9.8e-03 1.0e+00 + 28 33 8.000 +5.908026441632852e-03 1.0e-02 1.0e+00 + 29 35 8.000 +5.859754857684088e-03 1.0e-02 2.8e-02 + 30 36 8.000 +5.765713460425574e-03 7.4e-03 1.0e+00 + 31 37 8.000 +5.675434828171089e-03 7.0e-03 1.0e+00 + 32 38 8.000 +5.657523454643495e-03 3.2e-03 1.0e+00 + 33 39 8.000 +5.655833463796146e-03 4.4e-04 1.0e+00 + 34 40 8.000 +5.655671174917713e-03 2.4e-04 1.0e+00 + 35 42 8.000 +5.655652521284395e-03 1.2e-04 3.3e-01 + 36 43 8.000 +5.655650195207963e-03 3.0e-05 1.0e+00 + 37 44 12.000 +5.655649926013700e-03 6.4e-07 1.0e+00 + 38 45 12.000 +5.655649925527675e-03 2.3e-07 1.0e+00 + 39 46 12.000 +5.655649925502423e-03 9.0e-08 1.0e+00 +# op_vmlmb_next: FRTOL test satisfied +# +# +# Problem 3 (N=3): Gaussian function. +# Method 0 (NDIR=3): Limited Memory BFGS (VMLM with NDIR=3) +# +# ITER EVAL CPU (ms) FUNC GNORM STEPLEN +# --------------------------------------------------------------- + 0 1 0.000 +3.888106991166885e-06 7.5e-03 0.0e+00 + 1 2 0.000 +7.716984735720412e-07 3.3e-03 5.8e-04 + 2 3 0.000 +1.561242789005403e-07 1.4e-03 5.6e-01 + 3 4 0.000 +3.476004610942878e-08 5.7e-04 6.0e-01 + 4 5 0.000 +1.232954447864692e-08 9.3e-05 8.4e-01 + 5 6 0.000 +1.171122486137217e-08 1.1e-05 1.0e+00 + 6 8 0.000 +1.163182146077833e-08 1.2e-05 5.0e+00 + 7 9 0.000 +1.130733360163093e-08 1.6e-05 1.0e+00 + 8 10 0.000 +1.127985527183232e-08 2.7e-06 1.0e+00 + 9 11 0.000 +1.127932791925235e-08 4.0e-08 1.0e+00 + 10 12 0.000 +1.127932769618526e-08 8.6e-12 1.0e+00 +# op_vmlmb_next: FATOL test satisfied +# +# +# Problem 4 (N=2): Powell badly scaled function. +# Method 0 (NDIR=2): Limited Memory BFGS (VMLM with NDIR=2) +# +# ITER EVAL CPU (ms) FUNC GNORM STEPLEN +# --------------------------------------------------------------- + 0 1 0.000 +1.135261717348378e+00 2.0e+04 0.0e+00 + 1 2 0.000 +2.716142498422306e-01 7.4e+03 6.3e-05 + 2 3 0.000 +1.351881720546067e-01 2.7e-01 1.0e+00 + 3 14 0.000 +1.347499857711354e-01 1.7e+02 1.4e+06 + 4 15 0.000 +1.325667967357710e-01 6.0e+02 1.0e+00 + 5 16 0.000 +1.268168829890248e-01 1.4e+03 1.0e+00 + 6 17 0.000 +1.130266725138436e-01 2.2e+03 1.0e+00 + 7 18 0.000 +7.189847553126569e-02 2.1e+03 1.0e+00 + 8 20 0.000 +6.626840795010225e-02 7.5e+01 3.3e-03 + 9 21 0.000 +4.050790583682891e-02 5.5e+02 1.0e+00 + 10 22 0.000 +2.603122017596488e-02 2.9e+03 1.0e+00 + 11 23 0.000 +1.344335372038092e-02 1.8e+03 8.0e-01 + 12 24 0.000 +7.754280961808157e-03 1.8e+03 1.0e+00 + 13 25 0.000 +6.035962443792143e-03 6.0e+02 1.0e+00 + 14 26 0.000 +3.520105110849622e-03 2.7e+02 1.0e+00 + 15 27 0.000 +2.370401920922337e-03 1.3e+03 1.0e+00 + 16 28 0.000 +1.111838810799019e-03 5.4e+02 8.5e-01 + 17 30 0.000 +7.562658146984992e-04 4.1e+02 4.8e-01 + 18 31 0.000 +6.291294727585325e-04 7.2e+02 1.0e+00 + 19 32 0.000 +4.125929545959699e-04 4.0e+02 1.0e+00 + 20 33 0.000 +2.786252603932807e-04 2.3e+02 1.0e+00 + 21 34 0.000 +1.865344312220937e-04 6.5e+01 1.0e+00 + 22 36 0.000 +1.746213097705067e-04 2.7e+02 1.2e-01 + 23 37 0.000 +1.311007032893237e-04 3.1e+02 1.0e+00 + 24 38 0.000 +8.604790308724185e-05 9.6e+01 1.0e+00 + 25 40 0.000 +6.713643137639769e-05 1.5e+02 3.7e-01 + 26 41 0.000 +6.009576963699230e-05 3.4e+02 1.0e+00 + 27 42 0.000 +4.592112785957327e-05 1.3e+02 1.0e+00 + 28 43 0.000 +3.318733434604557e-05 1.3e+02 1.0e+00 + 29 45 0.000 +3.153928824477498e-05 7.9e-01 2.0e-04 + 30 46 0.000 +2.316717042185159e-05 1.3e+02 1.0e+00 + 31 47 0.000 +1.983842227523587e-05 1.8e+02 1.0e+00 + 32 48 0.000 +1.370511800174228e-05 1.2e+02 1.0e+00 + 33 50 0.000 +1.002231977553119e-05 2.0e+01 3.7e-01 + 34 52 4.001 +9.448845461709604e-06 7.8e+01 3.1e-01 + 35 53 4.001 +8.796547092034665e-06 8.8e+01 1.0e+00 + 36 54 4.001 +6.012203046585967e-06 3.7e+00 1.0e+00 + 37 56 4.001 +5.591031631209653e-06 5.2e+01 2.2e-01 + 38 57 4.001 +5.042798867261178e-06 8.1e+01 1.0e+00 + 39 58 4.001 +4.037916381025496e-06 4.9e+01 1.0e+00 + 40 59 4.001 +3.325226275541043e-06 2.6e+01 1.0e+00 + 41 61 4.001 +3.145813424606391e-06 5.4e+01 2.7e-01 + 42 62 4.001 +2.620153892100086e-06 5.5e+01 1.0e+00 + 43 64 4.001 +2.415748503691216e-06 2.5e+00 2.2e-02 + 44 65 4.001 +2.007550819175101e-06 3.0e+01 1.0e+00 + 45 67 4.001 +1.890695485188910e-06 5.1e+01 4.5e-01 + 46 68 4.001 +1.536361962738215e-06 3.0e+01 1.0e+00 + 47 69 4.001 +1.311168885938422e-06 2.0e+01 1.0e+00 + 48 70 4.001 +1.246078119694974e-06 4.5e+01 1.0e+00 + 49 72 4.001 +9.491335127465187e-07 7.2e+00 3.3e-01 + 50 74 4.001 +8.891242770948279e-07 2.8e+01 6.9e-02 + 51 75 4.001 +8.700737460692882e-07 1.9e+01 1.0e+00 + 52 76 4.001 +7.774251370222714e-07 7.0e+00 1.0e+00 + 53 78 4.001 +7.054120977646890e-07 1.4e+01 3.9e-01 + 54 80 4.001 +6.079579263162548e-07 2.2e+01 3.9e-01 + 55 81 4.001 +4.495947084220561e-07 1.7e+01 1.0e+00 + 56 83 4.001 +3.956164009642611e-07 6.9e+00 5.9e-02 + 57 85 4.001 +3.842041614956623e-07 1.6e+01 4.7e-01 + 58 86 4.001 +3.650291414806386e-07 2.0e+01 1.0e+00 + 59 87 4.001 +2.977310422144736e-07 1.0e+01 1.0e+00 + 60 88 4.001 +2.645228220544150e-07 8.7e+00 1.0e+00 + 61 90 4.001 +2.625753218665754e-07 2.1e+00 1.3e-02 + 62 92 4.001 +2.351392468128754e-07 7.8e+00 5.3e-01 + 63 94 4.001 +2.228437274607579e-07 1.5e+01 3.0e-01 + 64 95 4.001 +1.908884988619849e-07 1.6e+01 1.0e+00 + 65 97 4.001 +1.775213596206642e-07 1.5e+00 7.7e-02 + 66 98 4.001 +1.563404116641290e-07 9.7e+00 1.0e+00 + 67 100 4.001 +1.512029496166810e-07 1.4e+01 4.4e-01 + 68 101 4.001 +1.307607535470326e-07 9.5e+00 1.0e+00 + 69 102 4.001 +1.175169650897558e-07 2.0e+00 1.0e+00 + 70 104 4.001 +1.072392194161219e-07 5.1e+00 2.9e-01 + 71 106 4.001 +1.037392963035747e-07 9.8e+00 2.9e-01 + 72 107 4.001 +9.620878417591773e-08 1.0e+01 1.0e+00 + 73 109 4.001 +9.039151653346654e-08 1.6e+00 8.0e-02 + 74 110 4.001 +8.006176991138113e-08 8.3e+00 1.0e+00 + 75 111 4.001 +7.595885339417243e-08 1.0e+01 1.0e+00 + 76 112 4.001 +6.314410560360231e-08 4.1e-01 1.0e+00 + 77 114 4.001 +6.008323382664185e-08 5.3e+00 2.6e-01 + 78 115 4.001 +5.774858820209131e-08 1.1e+01 1.0e+00 + 79 116 4.001 +5.227214564981060e-08 4.5e+00 1.0e+00 + 80 117 4.001 +4.671286653797208e-08 7.9e+00 1.0e+00 + 81 118 4.001 +4.218605795772740e-08 4.0e+00 1.0e+00 + 82 120 4.001 +3.978787254803439e-08 7.2e+00 5.2e-01 + 83 121 4.001 +3.475025245891024e-08 4.6e+00 1.0e+00 + 84 122 4.001 +3.131608455766981e-08 8.5e-01 1.0e+00 + 85 124 4.001 +2.975290789910577e-08 4.2e+00 1.9e-01 + 86 125 4.001 +2.844598223236710e-08 8.2e+00 1.0e+00 + 87 126 4.001 +2.529667836942072e-08 2.4e+00 1.0e+00 + 88 127 4.001 +2.285266654491062e-08 5.8e+00 1.0e+00 + 89 128 4.001 +2.110270876321310e-08 3.4e+00 1.0e+00 + 90 130 4.001 +1.982830112972024e-08 4.6e+00 4.7e-01 + 91 131 4.001 +1.556088550165383e-08 1.6e-01 1.0e+00 + 92 133 4.001 +1.509931751153993e-08 2.7e+00 1.1e-01 + 93 134 4.001 +1.441420778804029e-08 3.7e+00 1.0e+00 + 94 135 4.001 +1.303715234141585e-08 4.6e+00 1.0e+00 + 95 137 4.001 +1.183143970298517e-08 1.5e+00 1.6e-01 + 96 139 4.001 +1.083047880278837e-08 4.3e-01 4.4e-01 + 97 141 4.001 +1.033931695032363e-08 3.5e+00 1.4e-01 + 98 142 4.001 +9.955899460561576e-09 2.8e+00 1.0e+00 + 99 143 4.001 +8.883196616290377e-09 4.3e+00 1.0e+00 + 100 145 4.001 +7.742742776189192e-09 2.1e+00 2.7e-01 + 101 147 4.001 +6.834754461132445e-09 9.3e-01 4.0e-01 + 102 149 4.001 +6.666959323631201e-09 2.3e+00 1.9e-01 + 103 150 4.001 +6.411180662499273e-09 2.8e+00 1.0e+00 + 104 151 4.001 +5.435981187381998e-09 2.0e+00 1.0e+00 + 105 153 4.001 +5.283745805222238e-09 1.1e-01 2.0e-01 + 106 154 4.001 +4.667635231009192e-09 2.4e+00 1.0e+00 + 107 155 4.001 +4.374389490301682e-09 2.4e+00 1.0e+00 + 108 157 8.001 +4.163941820284297e-09 7.6e-02 1.3e-02 + 109 158 8.001 +3.677160794243351e-09 1.7e+00 1.0e+00 + 110 160 8.001 +3.556463460936755e-09 2.4e+00 4.1e-01 + 111 161 8.001 +3.036430367400247e-09 1.7e+00 1.0e+00 + 112 162 8.001 +2.784362981880398e-09 1.2e+00 1.0e+00 + 113 164 8.001 +2.406505899582082e-09 6.4e-01 4.2e-01 + 114 166 8.001 +2.340080591653236e-09 1.5e+00 1.6e-01 + 115 167 8.001 +2.232707735696947e-09 1.8e+00 1.0e+00 + 116 168 8.001 +1.807669675248058e-09 8.9e-01 1.0e+00 + 117 169 8.001 +1.621579861725144e-09 1.5e+00 1.0e+00 + 118 171 8.001 +1.260526356088865e-09 4.8e-01 3.1e-01 + 119 173 8.001 +1.158748732953299e-09 1.3e+00 1.3e-01 + 120 174 8.001 +1.091888811725686e-09 1.0e+00 1.0e+00 + 121 175 8.001 +9.252174759540841e-10 1.4e+00 1.0e+00 + 122 177 8.001 +8.177332024184264e-10 5.0e-01 7.1e-02 + 123 180 8.001 +6.877682728262519e-10 9.4e-01 6.3e-01 + 124 181 8.001 +6.521162246605309e-10 1.4e+00 1.0e+00 + 125 182 8.001 +5.245455884270034e-10 5.8e-01 1.0e+00 + 126 183 8.001 +4.740039908668378e-10 1.4e+00 1.0e+00 + 127 184 8.001 +3.675734148905452e-10 1.5e-01 1.0e+00 + 128 186 8.001 +3.278212930002444e-10 7.1e-01 4.5e-01 + 129 187 8.001 +2.991826277801766e-10 1.1e+00 1.0e+00 + 130 188 8.001 +2.261615323913900e-10 2.1e-01 1.0e+00 + 131 190 8.001 +1.996749791891283e-10 6.8e-01 5.4e-01 + 132 191 8.001 +1.748408381668149e-10 7.5e-01 1.0e+00 + 133 193 8.001 +1.441186976349858e-10 2.6e-01 3.3e-01 + 134 195 8.001 +1.168134759399082e-10 1.2e-01 5.0e-01 + 135 197 8.001 +1.065919364144133e-10 4.5e-01 1.6e-01 + 136 198 8.001 +9.624408438738366e-11 5.9e-01 1.0e+00 + 137 199 8.001 +6.522624230099676e-11 2.6e-01 1.0e+00 + 138 200 8.001 +5.382979150929681e-11 5.4e-01 1.0e+00 + 139 201 8.001 +2.357595065249005e-11 5.6e-02 9.4e-01 + 140 203 8.001 +2.194863217396652e-11 2.2e-01 2.0e-01 + 141 204 8.001 +1.824678260827043e-11 2.6e-01 1.0e+00 + 142 205 8.001 +1.007427717509816e-11 1.8e-01 1.0e+00 + 143 207 8.001 +9.240366653486143e-12 1.5e-02 1.2e-01 + 144 208 8.001 +5.277029415816368e-12 1.3e-01 1.0e+00 + 145 209 8.001 +4.150258646119530e-12 2.7e-01 1.0e+00 + 146 210 8.001 +1.419227552276263e-12 3.3e-02 6.6e-01 + 147 211 8.001 +6.157107277445726e-13 6.3e-02 1.0e+00 + 148 212 8.001 +2.164773422247019e-13 5.5e-02 1.0e+00 + 149 213 8.001 +1.645865002459103e-13 2.4e-02 3.0e-02 + 150 214 8.001 +3.516759308772241e-14 4.5e-03 8.8e-01 + 151 215 8.001 +1.152075456477990e-14 1.4e-02 7.0e-01 +# op_vmlmb_next: FATOL test satisfied +# +# +# Problem 5 (N=3): Box 3-dimensional function. +# Method 0 (NDIR=3): Limited Memory BFGS (VMLM with NDIR=3) +# +# ITER EVAL CPU (ms) FUNC GNORM STEPLEN +# --------------------------------------------------------------- + 0 1 0.000 +1.031153810609398e+03 1.5e+02 0.0e+00 + 1 4 0.000 +5.051751883930287e+02 1.4e+02 3.2e+00 + 2 7 0.000 +4.693698123274796e+02 6.3e+01 9.6e-03 + 3 8 0.000 +4.196780145077672e+02 7.3e+01 1.0e+00 + 4 9 0.000 +9.577851908664192e+01 7.3e+01 6.4e-01 + 5 10 0.000 +2.963077540829067e+01 6.2e+01 8.2e-01 + 6 11 0.000 +1.472450551152400e+01 1.0e+01 1.3e-01 + 7 12 0.000 +4.692489499264585e+00 1.1e+01 9.0e-01 + 8 13 0.000 +2.930070582447900e+00 9.1e+00 1.0e+00 + 9 14 0.000 +1.626093588037745e+00 5.9e+00 1.0e+00 + 10 15 0.000 +6.607304557529599e-01 1.5e+00 1.0e+00 + 11 16 0.000 +2.360905443567035e-01 1.2e+00 1.0e+00 + 12 17 0.000 +9.771929015861618e-02 7.4e-01 1.0e+00 + 13 18 4.000 +2.921048390382599e-02 3.1e-01 1.0e+00 + 14 19 4.000 +7.162028854070950e-03 1.4e-01 1.0e+00 + 15 20 4.000 +1.918627248183639e-03 3.8e-02 8.5e-01 + 16 21 4.000 +5.706147462900988e-04 4.1e-02 5.0e-01 + 17 22 4.000 +1.767122289515497e-04 5.9e-03 6.7e-01 + 18 23 4.000 +1.388438676986920e-04 1.1e-03 1.0e+00 + 19 24 4.000 +1.380987151663160e-04 1.5e-03 1.0e+00 + 20 25 4.000 +1.375596494219131e-04 1.6e-03 1.0e+00 + 21 26 4.000 +1.348123100471587e-04 2.7e-03 1.0e+00 + 22 27 4.000 +1.273751593447703e-04 2.4e-03 1.0e+00 + 23 29 4.000 +1.236844681639359e-04 8.5e-03 3.4e-01 + 24 30 4.000 +1.111624159031401e-04 6.1e-03 1.0e+00 + 25 31 4.000 +7.709438714814043e-05 4.2e-03 1.0e+00 + 26 32 4.000 +3.555022908765118e-05 5.5e-03 1.0e+00 + 27 33 4.000 +1.388449576270083e-05 1.2e-02 8.4e-01 + 28 34 4.000 +3.499447500852135e-06 4.8e-03 2.5e-01 + 29 35 4.000 +7.802810396086031e-07 1.7e-03 7.4e-01 + 30 36 4.000 +1.797026655239720e-07 4.0e-04 6.9e-01 + 31 37 4.000 +4.113226590053436e-08 1.4e-04 6.9e-01 + 32 38 4.000 +1.170488139789506e-08 6.3e-06 5.5e-01 + 33 39 4.000 +8.860893531384294e-09 2.9e-04 7.0e-01 + 34 40 4.000 +3.295705185007528e-09 6.7e-05 1.0e+00 + 35 41 4.000 +1.824061308183375e-09 2.4e-05 1.0e+00 + 36 42 4.000 +4.894303628176848e-10 4.1e-05 8.8e-01 + 37 43 4.000 +1.063838077120574e-10 2.6e-05 7.7e-01 + 38 44 4.000 +2.936005901492016e-11 4.7e-06 4.7e-01 + 39 45 4.000 +7.520001768792375e-12 1.9e-06 6.8e-01 + 40 46 4.000 +3.232186206428190e-12 2.7e-06 1.0e+00 + 41 47 4.000 +2.382259476974284e-12 7.7e-07 1.0e+00 + 42 48 4.000 +1.627836101802466e-12 7.8e-07 1.0e+00 + 43 49 4.000 +8.722135008897642e-13 1.8e-06 1.0e+00 + 44 50 4.000 +3.181054605846769e-13 1.3e-06 1.0e+00 + 45 51 4.000 +1.819403692094123e-13 5.7e-07 1.0e+00 + 46 52 4.000 +1.552379827036547e-13 2.8e-07 1.0e+00 +# op_vmlmb_next: FATOL test satisfied +# +# +# Problem 6 (N=10): Variably dimensioned function. +# Method 0 (NDIR=10): Limited Memory BFGS (VMLM with NDIR=10) +# +# ITER EVAL CPU (ms) FUNC GNORM STEPLEN +# --------------------------------------------------------------- + 0 1 0.000 +2.198551162500000e+06 4.5e+06 0.0e+00 + 1 2 0.000 +5.982233536014224e+05 1.7e+06 5.5e-01 + 2 3 0.000 +2.077189332476444e+05 7.6e+05 1.0e+00 + 3 4 4.000 +6.578142669110338e+04 3.2e+05 1.0e+00 + 4 5 4.000 +2.160249233159776e+04 1.4e+05 1.0e+00 + 5 6 4.000 +7.004735376311746e+03 6.0e+04 1.0e+00 + 6 7 4.000 +2.287386781801080e+03 2.6e+04 1.0e+00 + 7 8 4.000 +7.476983219073760e+02 1.1e+04 1.0e+00 + 8 9 4.000 +2.458538169695109e+02 4.8e+03 1.0e+00 + 9 10 4.000 +8.149749297306352e+01 2.1e+03 1.0e+00 + 10 11 4.000 +2.737280609091122e+01 9.0e+02 1.0e+00 + 11 12 4.000 +9.362878818503740e+00 3.9e+02 1.0e+00 + 12 13 4.000 +3.269284473674885e+00 1.7e+02 1.0e+00 + 13 14 4.000 +1.153504000090763e+00 7.7e+01 1.0e+00 + 14 15 4.000 +3.936136413645998e-01 3.5e+01 1.0e+00 + 15 16 4.000 +1.147737756239351e-01 1.5e+01 1.0e+00 + 16 17 4.000 +2.581587916978744e-02 6.5e+00 9.1e-01 + 17 18 4.000 +5.303642148696754e-03 2.9e+00 7.0e-01 + 18 19 4.000 +1.056848632834968e-03 1.3e+00 5.9e-01 + 19 20 4.000 +2.091314644328269e-04 5.7e-01 5.6e-01 + 20 21 4.000 +4.132449788388705e-05 2.5e-01 5.6e-01 + 21 22 4.000 +8.163433357518874e-06 1.1e-01 5.6e-01 + 22 23 4.000 +1.612552275601864e-06 5.0e-02 5.6e-01 + 23 24 4.000 +3.185297119742180e-07 2.2e-02 5.6e-01 + 24 25 4.000 +6.291948312422135e-08 9.9e-03 5.6e-01 + 25 26 4.000 +1.242854119682474e-08 4.4e-03 5.6e-01 + 26 27 4.000 +2.455020534958202e-09 1.9e-03 5.6e-01 + 27 28 4.000 +4.849423299090284e-10 8.7e-04 5.6e-01 + 28 29 4.000 +9.579107757034683e-11 3.8e-04 5.6e-01 + 29 30 4.000 +1.892169434557917e-11 1.7e-04 5.6e-01 + 30 31 4.000 +3.737618638352018e-12 7.6e-05 5.6e-01 + 31 32 4.000 +7.382950396510434e-13 3.4e-05 5.6e-01 + 32 33 4.000 +1.458360569885202e-13 1.5e-05 5.6e-01 + 33 34 4.000 +2.880712217942045e-14 6.7e-06 5.6e-01 + 34 35 4.000 +5.690295862135377e-15 3.0e-06 5.6e-01 +# op_vmlmb_next: FATOL test satisfied +# +# +# Problem 7 (N=6): Watson function. +# Method 0 (NDIR=6): Limited Memory BFGS (VMLM with NDIR=6) +# +# ITER EVAL CPU (ms) FUNC GNORM STEPLEN +# --------------------------------------------------------------- + 0 1 0.000 +3.000000000000000e+01 1.4e+02 0.0e+00 + 1 2 0.000 +1.153491761608158e+01 3.6e+01 2.4e-01 + 2 3 0.000 +8.662294302946657e+00 2.7e+01 1.0e+00 + 3 4 0.000 +2.159765745956006e+00 1.3e+01 1.0e+00 + 4 5 0.000 +9.370932269174013e-01 9.6e+00 6.9e-01 + 5 6 0.000 +6.260360367334762e-01 2.7e+00 1.0e+00 + 6 7 0.000 +5.588208440197413e-01 2.9e+00 1.0e+00 + 7 8 0.000 +4.320129246513010e-01 4.0e+00 1.0e+00 + 8 9 0.000 +1.782329757356047e-01 4.6e+00 1.0e+00 + 9 10 4.001 +4.357179339744174e-02 1.6e+00 6.4e-01 + 10 11 4.001 +2.446191487403206e-02 4.8e-01 1.0e+00 + 11 12 4.001 +2.250413138430174e-02 3.4e-01 1.0e+00 + 12 13 4.001 +2.111722399878381e-02 5.5e-01 1.0e+00 + 13 14 4.001 +1.606205485982599e-02 8.0e-01 1.0e+00 + 14 16 8.001 +1.060663387077928e-02 1.8e-01 5.1e-01 + 15 17 8.001 +1.023711762982278e-02 2.1e-01 1.0e+00 + 16 18 8.001 +1.014232386791980e-02 2.5e-02 1.0e+00 + 17 19 8.001 +1.012808413731048e-02 3.0e-02 1.0e+00 + 18 20 8.001 +1.011416301337225e-02 1.9e-02 1.0e+00 + 19 21 12.001 +1.010622490501859e-02 1.7e-02 1.0e+00 + 20 22 12.001 +1.005354212767259e-02 2.5e-02 1.0e+00 + 21 23 12.001 +9.914998965299265e-03 4.3e-02 1.0e+00 + 22 24 12.001 +9.633255378335592e-03 5.2e-02 1.0e+00 + 23 25 12.001 +9.435981241419105e-03 3.2e-01 1.0e+00 + 24 26 12.001 +9.074119841420146e-03 9.2e-02 1.0e+00 + 25 27 16.001 +8.948864483207091e-03 2.6e-02 1.0e+00 + 26 28 16.001 +8.942033313705005e-03 9.7e-03 1.0e+00 + 27 29 16.001 +8.940317436619535e-03 7.6e-03 1.0e+00 + 28 30 16.001 +8.936673299222047e-03 1.6e-02 1.0e+00 + 29 31 16.001 +8.932411285273037e-03 2.3e-02 1.0e+00 + 30 32 16.001 +8.923876594747306e-03 2.4e-02 1.0e+00 + 31 34 20.002 +8.919738995782814e-03 6.0e-02 1.4e-01 + 32 35 20.002 +8.900791041922290e-03 5.2e-02 1.0e+00 + 33 36 20.002 +8.821982716914249e-03 5.8e-02 1.0e+00 + 34 37 20.002 +8.676125612127840e-03 4.9e-02 1.0e+00 + 35 38 20.002 +8.443320768310978e-03 3.1e-01 1.0e+00 + 36 39 24.002 +7.962339610876239e-03 1.2e-01 1.0e+00 + 37 40 24.002 +7.700051635114865e-03 9.5e-02 1.0e+00 + 38 41 24.002 +7.564775888244103e-03 9.7e-02 1.0e+00 + 39 43 24.002 +7.490280990021314e-03 2.0e-01 8.1e-02 + 40 44 24.002 +7.225853155050442e-03 1.1e-01 1.0e+00 + 41 45 28.002 +7.027986857610604e-03 6.7e-02 1.0e+00 + 42 46 28.002 +6.898992549696143e-03 1.2e-01 1.0e+00 + 43 47 28.002 +6.696669267370094e-03 1.1e-01 1.0e+00 + 44 48 28.002 +6.521394247682940e-03 3.6e-01 1.0e+00 + 45 49 28.002 +5.900564228855348e-03 1.5e-01 1.0e+00 + 46 50 28.002 +5.436162501033610e-03 1.2e-01 1.0e+00 + 47 51 32.002 +5.185527792214816e-03 1.9e-01 1.0e+00 + 48 52 32.002 +4.977046075759494e-03 1.4e-01 1.0e+00 + 49 53 32.002 +4.658566016994147e-03 7.2e-02 1.0e+00 + 50 54 32.002 +4.308711947089532e-03 1.0e-01 1.0e+00 + 51 55 32.002 +3.919697403900082e-03 1.9e-01 1.0e+00 + 52 56 32.002 +3.280783714973028e-03 1.9e-01 1.0e+00 + 53 57 36.003 +2.520432499557056e-03 1.6e-01 1.0e+00 + 54 59 36.003 +2.457626981592080e-03 1.4e-01 2.8e-02 + 55 60 36.003 +2.311981662769732e-03 5.2e-02 1.0e+00 + 56 61 36.003 +2.289345802013666e-03 6.1e-03 1.0e+00 + 57 62 36.003 +2.288985893595373e-03 2.9e-03 1.0e+00 + 58 63 40.003 +2.288455672536768e-03 2.7e-03 1.0e+00 + 59 64 40.003 +2.287793236670549e-03 1.9e-03 1.0e+00 + 60 65 40.003 +2.287695261121659e-03 1.5e-03 1.0e+00 + 61 67 40.003 +2.287684367911231e-03 6.3e-04 4.8e-01 + 62 68 40.003 +2.287676176945362e-03 3.6e-04 1.0e+00 + 63 70 44.003 +2.287675098559974e-03 2.0e-04 3.4e-01 + 64 71 44.003 +2.287673953644514e-03 6.5e-05 1.0e+00 + 65 72 44.003 +2.287673573776456e-03 5.8e-05 1.0e+00 + 66 73 44.003 +2.287672636686810e-03 1.3e-04 1.0e+00 + 67 74 44.003 +2.287671819591959e-03 1.5e-04 1.0e+00 + 68 76 48.003 +2.287671215406123e-03 3.4e-04 3.9e-01 + 69 77 48.003 +2.287670175158950e-03 7.6e-05 1.0e+00 + 70 78 48.003 +2.287670069963467e-03 3.0e-05 1.0e+00 + 71 79 48.003 +2.287670055842873e-03 1.1e-05 1.0e+00 + 72 80 48.003 +2.287670054951157e-03 7.6e-06 1.0e+00 + 73 81 52.004 +2.287670054462369e-03 2.6e-06 1.0e+00 + 74 82 52.004 +2.287670054258627e-03 1.8e-06 1.0e+00 + 75 83 52.004 +2.287670053768855e-03 4.4e-06 1.0e+00 + 76 85 52.004 +2.287670053701440e-03 2.1e-06 3.5e-01 +# op_vmlmb_next: FRTOL test satisfied +# +# +# Problem 8 (N=10): Penalty function I. +# Method 0 (NDIR=10): Limited Memory BFGS (VMLM with NDIR=10) +# +# ITER EVAL CPU (ms) FUNC GNORM STEPLEN +# --------------------------------------------------------------- + 0 1 0.000 +1.480325653500000e+05 3.0e+04 0.0e+00 + 1 2 0.000 +1.200672187926850e+05 2.6e+04 1.0e+00 + 2 3 0.000 +3.265992616691508e+04 9.7e+03 8.8e-01 + 3 4 0.000 +1.132290692299289e+04 4.4e+03 1.0e+00 + 4 5 0.000 +3.577134652544013e+03 1.9e+03 1.0e+00 + 5 6 0.000 +1.169681852985238e+03 8.0e+02 1.0e+00 + 6 7 0.000 +3.764229133643723e+02 3.4e+02 1.0e+00 + 7 8 4.000 +1.213086610658549e+02 1.5e+02 1.0e+00 + 8 9 4.000 +3.874731549111131e+01 6.3e+01 1.0e+00 + 9 10 4.000 +1.223737772730658e+01 2.7e+01 1.0e+00 + 10 11 4.000 +3.782057667252822e+00 1.2e+01 1.0e+00 + 11 12 4.000 +1.125513580941122e+00 4.9e+00 1.0e+00 + 12 13 4.000 +3.129446120087767e-01 2.0e+00 1.0e+00 + 13 14 4.000 +7.756206235205798e-02 8.1e-01 1.0e-00 + 14 15 4.000 +1.827422007113406e-02 3.3e-01 9.2e-01 + 15 16 4.000 +4.085118985926949e-03 1.4e-01 8.1e-01 + 16 17 4.000 +8.877332480334356e-04 6.0e-02 7.2e-01 + 17 18 4.000 +2.065403882446298e-04 2.4e-02 6.9e-01 + 18 19 4.000 +7.703710321289555e-05 3.2e-03 9.3e-01 + 19 20 4.000 +7.446943015394475e-05 1.1e-04 1.0e+00 + 20 21 4.000 +7.446618591447701e-05 2.9e-05 1.0e+00 + 21 23 4.000 +7.446415870380601e-05 5.2e-05 5.0e+00 + 22 24 4.000 +7.445657592228791e-05 1.2e-04 1.0e+00 + 23 25 4.000 +7.442752521815094e-05 2.8e-04 1.0e+00 + 24 26 4.000 +7.434003956432855e-05 5.2e-04 1.0e+00 + 25 29 4.000 +7.349631102481636e-05 6.1e-04 5.9e-01 + 26 31 4.000 +7.349026117318990e-05 4.7e-04 2.2e-01 + 27 33 4.000 +7.331713301296246e-05 4.0e-04 5.0e+00 + 28 35 4.000 +7.310908109664723e-05 5.5e-04 4.7e-01 + 29 36 4.000 +7.281998859159809e-05 8.1e-04 1.0e+00 + 30 37 4.000 +7.250779119403938e-05 2.0e-04 1.0e+00 + 31 39 4.000 +7.230694011645983e-05 2.8e-04 3.9e-01 + 32 41 4.000 +7.225525250357204e-05 5.3e-04 2.7e-01 + 33 42 4.000 +7.216099121388021e-05 5.7e-04 1.0e+00 + 34 43 4.000 +7.193027784341741e-05 4.0e-04 1.0e+00 + 35 44 4.000 +7.175919696417940e-05 1.9e-04 1.0e+00 + 36 46 4.000 +7.170723123651528e-05 4.2e-04 2.5e-01 + 37 47 4.000 +7.158287428953024e-05 7.8e-04 1.0e+00 + 38 48 4.000 +7.144374877244074e-05 2.2e-04 1.0e+00 + 39 49 4.000 +7.133466251468262e-05 1.7e-04 1.0e+00 + 40 51 4.000 +7.131147537304108e-05 3.4e-04 2.7e-01 + 41 52 4.000 +7.127028433699874e-05 3.7e-04 1.0e+00 + 42 53 4.000 +7.117077758835362e-05 2.6e-04 1.0e+00 + 43 54 4.000 +7.110140571775857e-05 9.8e-05 1.0e+00 + 44 56 4.000 +7.108040834207843e-05 2.5e-04 2.2e-01 + 45 57 4.000 +7.103394859713061e-05 3.8e-04 1.0e+00 + 46 58 4.000 +7.098405566611185e-05 1.8e-05 1.0e+00 + 47 59 4.000 +7.095277805502977e-05 2.3e-04 1.0e+00 + 48 60 4.000 +7.093698079764311e-05 1.3e-04 1.0e+00 + 49 62 4.000 +7.092411497593044e-05 1.6e-04 3.6e-01 + 50 63 4.000 +7.090081388960589e-05 8.4e-05 1.0e+00 + 51 64 4.000 +7.089092762586513e-05 7.5e-05 1.0e+00 + 52 65 4.000 +7.088414527104555e-05 8.0e-05 1.0e+00 + 53 67 4.000 +7.087881487192198e-05 7.0e-06 1.7e-01 + 54 69 4.000 +7.087808649792271e-05 4.1e-05 4.0e-01 + 55 70 8.000 +7.087756682229364e-05 3.7e-05 1.0e+00 + 56 71 8.000 +7.087666490410433e-05 6.3e-06 1.0e+00 + 57 72 8.000 +7.087654244772589e-05 9.0e-06 1.0e+00 + 58 73 8.000 +7.087651609138998e-05 1.9e-06 1.0e+00 + 59 74 8.000 +7.087651467883146e-05 1.2e-07 1.0e+00 + 60 75 8.000 +7.087651467090616e-05 2.6e-09 1.0e+00 +# op_vmlmb_next: FATOL test satisfied +# +# +# Problem 9 (N=10): Penalty function II. +# Method 0 (NDIR=10): Limited Memory BFGS (VMLM with NDIR=10) +# +# ITER EVAL CPU (ms) FUNC GNORM STEPLEN +# --------------------------------------------------------------- + 0 1 0.000 +1.626527765659671e+02 5.0e+02 0.0e+00 + 1 2 0.000 +4.478644776655588e+01 1.9e+02 3.6e-01 + 2 3 0.000 +1.567407090737728e+01 8.6e+01 1.0e+00 + 3 4 0.000 +4.595268667402950e+00 3.5e+01 1.0e+00 + 4 5 0.000 +1.269158916418052e+00 1.5e+01 1.0e+00 + 5 6 0.000 +3.110713197933571e-01 5.8e+00 9.7e-01 + 6 7 0.000 +7.571688000474813e-02 2.3e+00 9.0e-01 + 7 8 0.000 +2.213120188520761e-02 6.8e-01 9.4e-01 + 8 9 0.000 +1.485561199109297e-02 2.3e-01 1.0e+00 + 9 10 0.000 +1.306075025095904e-02 2.3e-01 1.0e+00 + 10 11 0.000 +8.330391266572293e-03 2.9e-01 1.0e+00 + 11 12 0.000 +2.118643374119330e-03 1.6e-01 5.4e-01 + 12 13 0.000 +1.676859414703804e-03 2.0e-01 1.0e+00 + 13 14 0.000 +6.085265554844259e-04 7.2e-02 1.0e+00 + 14 15 0.000 +3.602520091513869e-04 2.9e-02 1.0e+00 + 15 16 0.000 +3.000429994250958e-04 1.2e-02 1.0e+00 + 16 17 0.000 +2.942768976757234e-04 1.9e-03 1.0e+00 + 17 18 0.000 +2.941190006037160e-04 2.6e-03 1.0e+00 + 18 19 0.000 +2.940276365124544e-04 4.2e-05 1.0e+00 + 19 20 0.000 +2.940276143217213e-04 7.9e-06 1.0e+00 + 20 22 0.000 +2.940276088743079e-04 1.3e-05 5.0e+00 + 21 23 0.000 +2.940275674459129e-04 4.1e-05 1.0e+00 + 22 24 0.000 +2.940274684490467e-04 8.4e-05 1.0e+00 + 23 25 0.000 +2.940272019219013e-04 1.6e-04 1.0e+00 + 24 26 0.000 +2.940265308678704e-04 2.7e-04 1.0e+00 + 25 27 0.000 +2.940249257417753e-04 4.6e-04 1.0e+00 + 26 28 0.000 +2.940218267746400e-04 7.0e-04 1.0e+00 + 27 29 0.000 +2.940167114119969e-04 9.1e-04 1.0e+00 + 28 30 0.000 +2.940057396280275e-04 1.0e-03 1.0e+00 + 29 31 0.000 +2.939847652858170e-04 6.7e-04 1.0e+00 + 30 32 0.000 +2.939671940695009e-04 3.5e-04 1.0e+00 + 31 34 4.000 +2.939605724251989e-04 7.1e-04 3.6e-01 + 32 35 4.000 +2.939456480560964e-04 1.3e-03 1.0e+00 + 33 36 4.000 +2.939328151552932e-04 8.5e-04 1.0e+00 + 34 37 4.000 +2.939141108236152e-04 2.0e-04 1.0e+00 + 35 39 4.000 +2.939111211303367e-04 5.4e-04 3.7e-01 + 36 40 4.000 +2.939053168820111e-04 6.0e-04 1.0e+00 + 37 41 4.000 +2.938883629324550e-04 6.3e-04 1.0e+00 + 38 42 4.000 +2.938747221912601e-04 2.5e-05 1.0e+00 + 39 44 4.000 +2.938682139412850e-04 4.2e-04 2.0e-01 + 40 46 4.000 +2.938639778872194e-04 7.4e-04 5.2e-01 + 41 47 4.000 +2.938560543957402e-04 6.0e-04 1.0e+00 + 42 48 4.000 +2.938431790575485e-04 1.9e-04 1.0e+00 + 43 50 4.000 +2.938394172992321e-04 5.0e-04 1.9e-01 + 44 51 4.000 +2.938332461245707e-04 9.1e-04 1.0e+00 + 45 52 4.000 +2.938232087891656e-04 9.5e-05 1.0e+00 + 46 53 4.000 +2.938162192572837e-04 3.1e-04 1.0e+00 + 47 54 4.000 +2.938134286486824e-04 7.5e-04 1.0e+00 + 48 55 4.000 +2.938046050490839e-04 1.2e-04 1.0e+00 + 49 56 4.000 +2.937958615389975e-04 2.5e-04 1.0e+00 + 50 58 4.000 +2.937915280165045e-04 5.2e-04 4.3e-01 + 51 59 4.000 +2.937829339096076e-04 3.9e-04 1.0e+00 + 52 60 4.000 +2.937787756979532e-04 1.2e-04 1.0e+00 + 53 62 4.000 +2.937767478240379e-04 3.5e-04 2.1e-01 + 54 63 4.000 +2.937740704182577e-04 5.8e-04 1.0e+00 + 55 64 4.000 +2.937692673453995e-04 3.0e-04 1.0e+00 + 56 66 4.000 +2.937653648012842e-04 4.2e-04 4.6e-01 + 57 67 4.000 +2.937586070665360e-04 6.9e-04 1.0e+00 + 58 69 4.000 +2.937544459124473e-04 8.5e-05 4.5e-01 + 59 70 4.000 +2.937530885438273e-04 1.3e-04 1.0e+00 + 60 72 4.000 +2.937500033638618e-04 3.4e-04 4.1e-01 + 61 73 8.001 +2.937462650101101e-04 4.1e-04 1.0e+00 + 62 74 8.001 +2.937436103075173e-04 7.7e-05 1.0e+00 + 63 76 8.001 +2.937411292974525e-04 1.1e-04 4.1e-01 + 64 78 8.001 +2.937396821963436e-04 3.1e-04 1.7e-01 + 65 79 8.001 +2.937381391529797e-04 3.8e-04 1.0e+00 + 66 80 8.001 +2.937365816728961e-04 1.4e-04 1.0e+00 + 67 81 8.001 +2.937347185972254e-04 2.4e-04 1.0e+00 + 68 82 8.001 +2.937318532989324e-04 3.7e-04 1.0e+00 + 69 83 8.001 +2.937287934342775e-04 4.3e-05 1.0e+00 + 70 85 8.001 +2.937271147643474e-04 2.1e-04 5.1e-01 + 71 87 8.001 +2.937263798718626e-04 3.0e-04 5.2e-01 + 72 88 8.001 +2.937246531357029e-04 2.2e-04 1.0e+00 + 73 89 8.001 +2.937232048142877e-04 1.0e-04 1.0e+00 + 74 91 8.001 +2.937223578268570e-04 2.2e-04 4.0e-01 + 75 92 8.001 +2.937201426598879e-04 2.4e-04 1.0e+00 + 76 93 8.001 +2.937187758592068e-04 1.8e-04 1.0e+00 + 77 95 8.001 +2.937169668102822e-04 6.6e-05 5.0e-01 + 78 97 8.001 +2.937167045913685e-04 1.6e-04 1.9e-01 + 79 98 12.001 +2.937161308786513e-04 1.9e-04 1.0e+00 + 80 99 12.001 +2.937145418783188e-04 2.1e-04 1.0e+00 + 81 100 12.001 +2.937126830402479e-04 7.7e-05 1.0e+00 + 82 102 12.001 +2.937119950899304e-04 1.9e-04 3.4e-01 + 83 103 12.001 +2.937103197572409e-04 3.0e-04 1.0e+00 + 84 104 12.001 +2.937081325220577e-04 1.3e-04 1.0e+00 + 85 106 12.001 +2.937067731152529e-04 1.5e-05 4.2e-01 + 86 109 12.001 +2.937061298844395e-04 9.7e-05 5.7e-02 + 87 110 12.001 +2.937057792029250e-04 3.3e-04 1.0e+00 + 88 111 12.001 +2.937048989862912e-04 1.6e-04 1.0e+00 + 89 112 12.001 +2.937037498661225e-04 6.0e-05 1.0e+00 + 90 113 12.001 +2.937020302605030e-04 2.2e-04 1.0e+00 + 91 114 12.001 +2.937011876780409e-04 2.4e-04 1.0e+00 + 92 116 12.001 +2.936994036462835e-04 2.7e-04 4.0e-01 + 93 117 12.001 +2.936932742505855e-04 4.2e-05 1.0e+00 + 94 119 12.001 +2.936925011344764e-04 2.5e-04 1.2e-01 + 95 120 12.001 +2.936903903706649e-04 2.4e-04 1.0e+00 + 96 121 12.001 +2.936864971751230e-04 1.6e-04 1.0e+00 + 97 122 12.001 +2.936833519272741e-04 2.7e-05 1.0e+00 + 98 125 12.001 +2.936823989527786e-04 1.3e-04 5.9e-02 + 99 127 12.001 +2.936814369909003e-04 2.8e-04 5.1e-01 + 100 128 12.001 +2.936801889576564e-04 2.5e-04 1.0e+00 + 101 129 12.001 +2.936781670510260e-04 6.2e-06 1.0e+00 + 102 131 12.001 +2.936773383070480e-04 1.3e-04 2.7e-01 + 103 133 12.001 +2.936767971224333e-04 2.1e-04 4.8e-01 + 104 134 12.001 +2.936757371420169e-04 2.0e-04 1.0e+00 + 105 136 12.001 +2.936755119527722e-04 1.9e-04 1.7e-01 + 106 137 12.001 +2.936739331071090e-04 6.8e-05 1.0e+00 + 107 139 16.001 +2.936733609422002e-04 6.7e-05 2.4e-01 + 108 141 16.001 +2.936731441199923e-04 1.5e-04 4.5e-01 + 109 142 16.001 +2.936728734176120e-04 1.5e-04 1.0e+00 + 110 143 16.001 +2.936727646558677e-04 1.2e-04 1.0e+00 + 111 144 16.001 +2.936720719650833e-04 5.3e-05 1.0e+00 + 112 146 16.001 +2.936718160655674e-04 5.7e-05 5.0e-01 + 113 147 16.001 +2.936716335691947e-04 8.9e-05 1.0e+00 + 114 148 16.001 +2.936713673939239e-04 1.0e-04 1.0e+00 + 115 149 16.001 +2.936711604644687e-04 1.8e-06 1.0e+00 + 116 150 16.001 +2.936710464585561e-04 7.8e-05 1.0e+00 + 117 151 16.001 +2.936709734203265e-04 2.0e-05 1.0e+00 + 118 152 16.001 +2.936709005854026e-04 2.0e-05 1.0e+00 + 119 154 16.001 +2.936708447037076e-04 5.4e-05 3.7e-01 + 120 155 16.001 +2.936707215906627e-04 5.5e-05 1.0e+00 + 121 156 16.001 +2.936703043174316e-04 1.9e-05 1.0e+00 + 122 158 16.001 +2.936700146863054e-04 9.4e-05 4.5e-01 + 123 160 16.001 +2.936693047392297e-04 1.0e-04 5.0e-01 + 124 161 16.001 +2.936685401469610e-04 1.2e-04 1.0e+00 + 125 163 16.001 +2.936679641926337e-04 1.8e-05 1.9e-01 + 126 165 16.001 +2.936674792095312e-04 1.1e-04 3.2e-01 + 127 166 16.001 +2.936668316559686e-04 2.9e-04 1.0e+00 + 128 167 16.001 +2.936662100391527e-04 5.3e-05 1.0e+00 + 129 168 16.001 +2.936656178325533e-04 8.7e-05 1.0e+00 + 130 170 16.001 +2.936651583330866e-04 1.5e-04 5.0e-01 + 131 171 16.001 +2.936647742964451e-04 1.4e-04 1.0e+00 + 132 173 16.001 +2.936646566758439e-04 1.2e-04 2.0e-01 + 133 174 16.001 +2.936641713973722e-04 7.2e-05 1.0e+00 + 134 176 16.001 +2.936637890170677e-04 1.2e-04 4.3e-01 + 135 177 20.001 +2.936630264588969e-04 4.5e-05 1.0e+00 + 136 179 20.001 +2.936628969739628e-04 1.1e-04 4.5e-01 + 137 180 20.001 +2.936625655838410e-04 8.3e-05 1.0e+00 + 138 181 20.001 +2.936624300065082e-04 2.9e-05 1.0e+00 + 139 182 20.001 +2.936622977829990e-04 7.7e-05 1.0e+00 + 140 183 20.001 +2.936622477588315e-04 1.0e-05 1.0e+00 + 141 184 20.001 +2.936622031232782e-04 1.4e-05 1.0e+00 + 142 185 20.001 +2.936621779293315e-04 4.8e-05 1.0e+00 + 143 186 20.001 +2.936621567734476e-04 3.0e-06 1.0e+00 + 144 187 20.001 +2.936621506624571e-04 2.4e-06 1.0e+00 + 145 188 20.001 +2.936621474513797e-04 7.8e-06 1.0e+00 + 146 189 20.001 +2.936621458663817e-04 2.2e-06 1.0e+00 + 147 190 20.001 +2.936621447656716e-04 1.4e-06 1.0e+00 + 148 191 20.001 +2.936621438322216e-04 3.6e-06 1.0e+00 + 149 192 20.001 +2.936621407224748e-04 7.2e-06 1.0e+00 + 150 193 20.001 +2.936621353581356e-04 8.7e-06 1.0e+00 + 151 194 20.001 +2.936621275310319e-04 7.5e-06 1.0e+00 + 152 195 20.001 +2.936621223335431e-04 6.9e-06 1.0e+00 + 153 197 20.001 +2.936621209792176e-04 3.3e-06 2.2e-01 + 154 198 20.001 +2.936621173468774e-04 7.0e-06 1.0e+00 + 155 199 20.001 +2.936621156967350e-04 1.2e-05 1.0e+00 + 156 200 20.001 +2.936621127659403e-04 1.1e-05 1.0e+00 + 157 201 20.001 +2.936620879068670e-04 1.8e-05 1.0e+00 + 158 202 20.001 +2.936620341924160e-04 1.5e-06 1.0e+00 + 159 204 20.001 +2.936619396711716e-04 1.8e-05 4.0e-01 + 160 206 20.001 +2.936618809583579e-04 4.6e-05 4.9e-01 + 161 207 20.001 +2.936618437961445e-04 3.1e-05 1.0e+00 + 162 208 20.001 +2.936618135595330e-04 1.7e-05 1.0e+00 + 163 209 20.001 +2.936617994124585e-04 1.5e-05 1.0e+00 + 164 211 20.001 +2.936617977401772e-04 8.7e-06 2.1e-01 + 165 212 20.001 +2.936617949948577e-04 7.8e-06 1.0e+00 + 166 213 24.002 +2.936617942029165e-04 4.8e-06 1.0e+00 + 167 214 24.002 +2.936617936336488e-04 7.0e-07 1.0e+00 + 168 215 24.002 +2.936617935577645e-04 6.6e-07 1.0e+00 +# op_vmlmb_next: FATOL test satisfied +# +# +# Problem 10 (N=2): Brown badly scaled function. +# Method 0 (NDIR=2): Limited Memory BFGS (VMLM with NDIR=2) +# +# ITER EVAL CPU (ms) FUNC GNORM STEPLEN +# --------------------------------------------------------------- + 0 1 0.000 +9.999980000030000e+11 2.0e+06 0.0e+00 + 1 10 0.000 +8.405068809937695e+11 1.5e+10 8.7e+04 + 2 12 0.000 +6.534530905604027e+11 2.6e+10 1.2e-01 + 3 14 0.000 +5.259989045876316e+11 1.6e+11 2.1e-01 + 4 16 0.000 +2.692902690480896e+11 8.1e+10 3.7e-01 + 5 17 0.000 +1.587055937831890e+11 4.5e+11 1.8e-01 + 6 18 0.000 +5.786251940191312e+10 3.2e+10 9.8e-01 + 7 19 0.000 +2.014729184788555e+10 1.3e+11 1.0e+00 + 8 20 0.000 +3.789073790387382e+09 6.5e+10 7.6e-01 + 9 21 0.000 +7.582658601419518e+08 2.1e+10 4.9e-01 + 10 22 0.000 +1.532406522092270e+08 1.3e+10 5.1e-01 + 11 23 0.000 +8.382857608319093e+07 6.5e+09 3.7e-01 + 12 24 0.000 +1.653294988314359e+07 2.9e+09 5.7e-01 + 13 25 0.000 +3.263611062004277e+06 1.3e+09 5.5e-01 + 14 26 0.000 +6.471465292335765e+05 6.7e+08 5.5e-01 + 15 27 0.000 +2.722789943285238e+05 4.0e+08 5.0e-01 + 16 28 0.000 +5.377870916293834e+04 1.7e+08 5.3e-01 + 17 29 0.000 +1.062250565109277e+04 7.8e+07 5.6e-01 + 18 30 0.000 +2.098255912542021e+03 3.5e+07 5.6e-01 + 19 31 0.000 +4.150644198176832e+02 1.4e+07 5.6e-01 + 20 32 0.000 +9.195149511769590e+01 1.2e+07 5.4e-01 + 21 33 0.000 +7.394055311418897e+01 6.1e+06 1.4e-02 + 22 34 0.000 +1.460552054965025e+01 2.7e+06 5.6e-01 + 23 35 0.000 +2.885039269609231e+00 1.2e+06 5.6e-01 + 24 36 0.000 +5.698841404349454e-01 5.4e+05 5.6e-01 + 25 37 0.000 +1.125697148814101e-01 2.4e+05 5.6e-01 + 26 38 0.000 +2.223674412281545e-02 1.1e+05 5.6e-01 + 27 39 0.000 +4.419596330611485e-03 3.8e+04 5.6e-01 + 28 40 0.000 +1.226680528641698e-03 5.3e+04 5.2e-01 + 29 41 0.000 +3.552382989525306e-04 9.7e+03 4.1e-02 + 30 42 0.000 +7.017052848565110e-05 4.3e+03 5.6e-01 + 31 43 0.000 +1.386084529266547e-05 1.9e+03 5.6e-01 + 32 44 0.000 +2.737944677494988e-06 8.5e+02 5.6e-01 + 33 45 0.000 +5.408290745856043e-07 3.8e+02 5.6e-01 + 34 46 0.000 +1.069191494379131e-07 1.5e+02 5.6e-01 + 35 47 0.000 +3.099248909852002e-08 2.6e+02 5.4e-01 + 36 48 0.000 +8.015714097213813e-09 5.7e+01 7.0e-02 + 37 49 0.000 +1.583352621921838e-09 2.5e+01 5.6e-01 + 38 50 0.000 +3.127629493167706e-10 1.1e+01 5.6e-01 + 39 51 0.000 +6.178050732586073e-11 5.0e+00 5.6e-01 + 40 52 0.000 +1.220343418206337e-11 2.2e+00 5.6e-01 + 41 53 0.000 +2.410577466990187e-12 9.9e-01 5.6e-01 + 42 54 0.000 +4.761860264644440e-13 4.5e-01 5.6e-01 + 43 55 0.000 +9.529309271044640e-14 1.3e-01 5.5e-01 + 44 56 0.000 +3.454718805039423e-14 3.0e-01 4.7e-01 + 45 57 0.000 +7.000760536493319e-15 1.2e-01 2.0e-01 +# op_vmlmb_next: FATOL test satisfied +# +# +# Problem 11 (N=4): Brown and Dennis function. +# Method 0 (NDIR=4): Limited Memory BFGS (VMLM with NDIR=4) +# +# ITER EVAL CPU (ms) FUNC GNORM STEPLEN +# --------------------------------------------------------------- + 0 1 0.000 +7.926693336997432e+06 2.1e+06 0.0e+00 + 1 2 0.000 +6.049349781006352e+06 1.6e+06 1.0e+00 + 2 3 0.000 +2.838871733130934e+06 4.3e+05 1.0e+00 + 3 4 0.000 +2.432298103636766e+06 2.6e+05 1.0e+00 + 4 5 0.000 +2.100775303409475e+06 3.1e+05 1.0e+00 + 5 6 0.000 +1.323784908907083e+06 3.3e+05 1.0e+00 + 6 7 0.000 +5.656591397675695e+05 8.5e+04 1.0e+00 + 7 8 4.000 +3.430980546283170e+05 4.1e+04 1.0e+00 + 8 9 4.000 +1.878284295308689e+05 3.3e+04 1.0e+00 + 9 11 4.000 +1.436998832262278e+05 7.0e+04 4.8e-01 + 10 12 4.000 +9.738492091554010e+04 2.9e+04 1.0e+00 + 11 13 4.000 +9.084457699916144e+04 9.6e+03 1.0e+00 + 12 14 4.000 +8.891237239806094e+04 5.0e+03 1.0e+00 + 13 15 4.000 +8.705530186352410e+04 6.8e+03 1.0e+00 + 14 16 4.000 +8.608483951495643e+04 1.3e+03 1.0e+00 + 15 17 4.000 +8.599075237276051e+04 7.5e+02 1.0e+00 + 16 18 4.000 +8.590306517851379e+04 9.1e+02 1.0e+00 + 17 20 4.000 +8.585776884341528e+04 1.4e+03 3.1e-01 + 18 21 4.000 +8.582231434220298e+04 9.3e+01 1.0e+00 + 19 22 4.000 +8.582220228898624e+04 4.8e+00 1.0e+00 + 20 23 4.000 +8.582220180473091e+04 2.0e+00 1.0e+00 + 21 24 4.000 +8.582220164639555e+04 3.4e-01 1.0e+00 + 22 25 4.000 +8.582220163995650e+04 2.7e-01 1.0e+00 +# op_vmlmb_next: FRTOL test satisfied +# +# +# Problem 12 (N=3): Gulf research and development function. +# Method 0 (NDIR=3): Limited Memory BFGS (VMLM with NDIR=3) +# +# ITER EVAL CPU (ms) FUNC GNORM STEPLEN +# --------------------------------------------------------------- + 0 1 4.000 +1.211070582556949e+01 4.0e+01 0.0e+00 + 1 3 4.000 +7.037432998984529e+00 1.5e+01 1.7e-01 + 2 5 4.000 +6.621351881374275e+00 3.1e-01 5.0e-01 + 3 6 8.000 +6.621101702040585e+00 2.3e-01 1.0e+00 + 4 7 8.000 +6.620679188673091e+00 3.3e-01 1.0e+00 + 5 8 8.000 +6.619037491331203e+00 8.0e-01 1.0e+00 + 6 9 8.000 +6.615310780340258e+00 1.5e+00 1.0e+00 + 7 10 8.000 +6.604547336243583e+00 2.7e+00 1.0e+00 + 8 11 8.000 +6.573884980436160e+00 4.7e+00 1.0e+00 + 9 12 12.001 +6.499049562962999e+00 7.4e+00 1.0e+00 + 10 13 12.001 +6.336057520157562e+00 8.7e+00 1.0e+00 + 11 14 12.001 +5.892999608485755e+00 2.4e+00 1.0e+00 + 12 15 12.001 +5.662280493431998e+00 1.4e+01 1.0e+00 + 13 16 12.001 +5.449061619118568e+00 3.9e+00 1.0e+00 + 14 17 16.001 +5.234241685722618e+00 2.1e+00 1.0e+00 + 15 18 16.001 +4.865169222646597e+00 1.8e+01 1.0e+00 + 16 19 16.001 +4.453895249926380e+00 5.9e+00 1.0e+00 + 17 20 16.001 +3.976830574245754e+00 2.9e+00 1.0e+00 + 18 22 20.001 +1.779414184967219e-01 5.4e+00 1.7e+00 + 19 24 20.001 +1.417710645204940e-01 3.9e+00 8.2e-02 + 20 25 20.001 +2.557537679786676e-02 1.8e+00 7.2e-01 + 21 26 20.001 +6.611690206271554e-03 6.2e-01 5.2e-01 + 22 27 24.001 +4.564494341401721e-03 3.3e-02 1.0e+00 + 23 28 24.001 +4.543334030131170e-03 1.0e-02 1.0e+00 + 24 29 24.001 +4.539678138594905e-03 1.0e-02 1.0e+00 + 25 31 24.001 +4.538933737699077e-03 2.0e-03 4.3e-02 + 26 32 28.002 +4.538084042484109e-03 1.2e-03 1.0e+00 + 27 37 32.002 +3.469460838544598e-03 3.0e-01 3.4e+02 + 28 38 32.002 +2.928359037254009e-03 1.6e-01 1.0e+00 + 29 40 32.002 +2.474054806017020e-03 2.4e-01 2.6e-01 + 30 41 32.002 +1.565633067221580e-03 2.3e-01 1.0e+00 + 31 43 36.002 +1.413550255660053e-03 1.2e-01 9.7e-02 + 32 44 36.002 +9.024611061567671e-04 1.6e-02 1.0e+00 + 33 46 36.002 +7.003267516821486e-04 1.1e-01 1.8e-01 + 34 47 36.002 +5.735129820311213e-04 2.3e-01 1.0e+00 + 35 48 40.002 +3.123330023579667e-04 4.1e-02 1.0e+00 + 36 49 40.002 +1.947752299522285e-04 3.4e-02 1.0e+00 + 37 51 40.002 +1.638242201908890e-04 8.3e-02 2.9e-01 + 38 52 40.002 +1.048439465991671e-04 7.0e-02 1.0e+00 + 39 53 44.003 +3.709259481404306e-05 2.7e-03 5.5e-01 + 40 54 44.003 +1.091378850908817e-05 2.3e-02 8.2e-01 + 41 55 44.003 +2.536658359037260e-06 1.5e-02 7.5e-01 + 42 56 44.003 +5.748894725508491e-07 4.4e-03 6.2e-01 + 43 57 44.003 +1.301070142934200e-07 3.2e-03 5.7e-01 + 44 58 48.003 +8.850638573840128e-08 1.2e-03 1.6e-01 + 45 59 48.003 +1.929576324643203e-08 4.9e-04 6.2e-01 + 46 60 48.003 +5.601806973787550e-09 2.1e-04 7.4e-01 + 47 61 48.003 +2.535490761789031e-09 3.4e-05 1.0e+00 + 48 62 48.003 +1.322572045394975e-09 7.9e-05 1.0e+00 + 49 63 52.003 +8.287306876272502e-10 1.5e-04 1.0e+00 + 50 64 52.003 +3.454513513192700e-10 7.7e-05 1.0e+00 + 51 65 52.003 +1.279735809853422e-10 6.8e-05 1.0e+00 + 52 66 52.003 +2.590444871831076e-11 3.7e-05 5.6e-01 + 53 67 52.003 +5.131187839211650e-12 1.8e-05 5.6e-01 + 54 68 56.003 +1.096260941388581e-12 4.6e-06 5.5e-01 + 55 69 56.003 +2.320936116341532e-13 3.7e-06 4.9e-01 + 56 71 56.003 +1.720714526990411e-13 3.0e-07 3.5e-02 + 57 72 56.003 +3.399938346550955e-14 1.3e-07 5.6e-01 + 58 73 60.004 +6.724520326208138e-15 6.0e-08 5.6e-01 +# op_vmlmb_next: FATOL test satisfied +# +# +# Problem 13 (N=10): Trigonometric function. +# Method 0 (NDIR=10): Limited Memory BFGS (VMLM with NDIR=10) +# +# ITER EVAL CPU (ms) FUNC GNORM STEPLEN +# --------------------------------------------------------------- + 0 1 0.000 +7.075759466222607e-03 9.9e-02 0.0e+00 + 1 2 0.000 +1.847318266210997e-03 2.8e-02 7.9e-02 + 2 3 0.000 +1.337289272696683e-03 2.6e-02 1.0e+00 + 3 4 0.000 +9.099932601024449e-04 2.0e-02 1.0e+00 + 4 5 0.000 +6.559192696755177e-04 1.4e-02 1.0e+00 + 5 6 0.000 +4.686579245332390e-04 1.5e-02 1.0e+00 + 6 7 0.000 +2.915051473509156e-04 1.4e-02 1.0e+00 + 7 8 0.000 +1.433277880070397e-04 1.7e-02 1.7e-01 + 8 9 0.000 +7.147757750781793e-05 5.4e-03 5.9e-01 + 9 10 0.000 +5.887928681982255e-05 2.8e-03 1.0e+00 + 10 11 0.000 +5.263481793491030e-05 2.1e-03 1.0e+00 + 11 12 0.000 +4.522784407286506e-05 1.8e-03 1.0e+00 + 12 13 0.000 +4.260697310099406e-05 1.7e-03 1.0e+00 + 13 14 0.000 +4.033897074809929e-05 1.2e-03 1.0e+00 + 14 15 0.000 +3.597768894272814e-05 1.6e-03 1.0e+00 + 15 17 0.000 +3.282850339569031e-05 1.9e-03 4.0e-01 + 16 19 0.000 +3.030246929870708e-05 1.7e-03 4.7e-01 + 17 20 0.000 +2.874543857699578e-05 1.2e-03 1.0e+00 + 18 21 0.000 +2.839516499584868e-05 7.6e-04 1.0e+00 + 19 22 0.000 +2.805891729461959e-05 3.7e-04 1.0e+00 + 20 23 0.000 +2.801778561737049e-05 1.4e-04 1.0e+00 + 21 24 0.000 +2.800096728737016e-05 1.1e-04 1.0e+00 + 22 25 0.000 +2.796003401543012e-05 9.0e-05 1.0e+00 + 23 26 0.000 +2.795364460348979e-05 8.1e-05 1.0e+00 + 24 27 0.000 +2.795145020217185e-05 4.2e-05 1.0e+00 + 25 28 0.000 +2.795057495098975e-05 4.8e-06 1.0e+00 + 26 29 0.000 +2.795056448092877e-05 1.7e-06 1.0e+00 + 27 30 0.000 +2.795056214675631e-05 9.8e-07 1.0e+00 + 28 31 0.000 +2.795056136433344e-05 7.1e-07 1.0e+00 + 29 32 0.000 +2.795056130890243e-05 5.4e-07 1.0e+00 + 30 33 0.000 +2.795056121893572e-05 1.6e-08 1.0e+00 + 31 34 0.000 +2.795056121878748e-05 3.9e-09 1.0e+00 +# op_vmlmb_next: FRTOL test satisfied +# +# +# Problem 14 (N=10): Extended Rosenbrock function. +# Method 0 (NDIR=10): Limited Memory BFGS (VMLM with NDIR=10) +# +# ITER EVAL CPU (ms) FUNC GNORM STEPLEN +# --------------------------------------------------------------- + 0 1 0.000 +1.210000000000000e+02 5.2e+02 0.0e+00 + 1 2 0.000 +3.333875559382903e+01 1.7e+02 2.6e-01 + 2 3 0.000 +2.099690543341773e+01 2.7e+01 1.0e+00 + 3 4 0.000 +2.064737829082273e+01 4.4e+00 1.0e+00 + 4 5 4.000 +2.062947719722462e+01 4.0e+00 1.0e+00 + 5 6 4.000 +2.055056296009381e+01 8.2e+00 1.0e+00 + 6 7 4.000 +2.036601960781752e+01 1.6e+01 1.0e+00 + 7 11 4.000 +1.270403994373162e+01 2.9e+01 7.3e+00 + 8 13 4.000 +1.266492082784074e+01 2.4e+01 1.3e-01 + 9 15 4.000 +1.160881636531017e+01 2.0e+01 5.0e+00 + 10 17 4.000 +1.014905429393288e+01 2.3e+01 5.2e-01 + 11 18 4.000 +8.256388073653257e+00 2.2e+01 1.0e+00 + 12 19 4.000 +6.515652375585378e+00 7.3e+00 1.0e+00 + 13 21 4.000 +5.313683620850455e+00 6.8e+00 3.2e-01 + 14 23 4.000 +5.001446956969033e+00 1.2e+01 2.3e-01 + 15 24 4.000 +4.582646809321272e+00 1.3e+01 1.0e+00 + 16 25 4.000 +3.603604585846324e+00 1.2e+01 1.0e+00 + 17 26 4.000 +2.675900088307497e+00 2.9e+00 1.0e+00 + 18 28 4.000 +2.296387307115140e+00 8.0e+00 3.1e-01 + 19 29 4.000 +1.954912440237827e+00 1.7e+01 1.0e+00 + 20 30 4.000 +1.378522055959003e+00 3.5e+00 1.0e+00 + 21 31 4.000 +9.484804947450111e-01 8.2e+00 1.0e+00 + 22 32 4.000 +6.713411428693927e-01 1.1e+01 1.0e+00 + 23 33 4.000 +3.822925991805740e-01 5.5e+00 1.0e+00 + 24 35 4.000 +2.191730723230072e-01 4.4e+00 4.7e-01 + 25 36 4.000 +1.887020522506004e-01 1.1e+01 1.0e+00 + 26 37 4.000 +1.125336324978479e-01 4.1e+00 1.0e+00 + 27 38 4.000 +4.747278490703725e-02 1.8e+00 1.0e+00 + 28 39 4.000 +2.164097573626416e-02 4.3e+00 1.0e+00 + 29 40 4.000 +5.971361214373413e-03 8.7e-01 8.5e-01 + 30 41 4.000 +1.514300265908568e-03 9.7e-01 7.8e-01 + 31 42 4.000 +3.293711779148185e-04 3.4e-01 6.8e-01 + 32 43 4.000 +6.882146001996125e-05 1.9e-01 6.4e-01 + 33 44 4.000 +1.402734044478412e-05 7.0e-02 5.9e-01 + 34 45 4.000 +2.827846239737803e-06 3.8e-02 5.7e-01 + 35 46 4.000 +5.657367678388773e-07 1.4e-02 5.6e-01 + 36 47 4.000 +1.126657341335922e-07 7.5e-03 5.5e-01 + 37 48 4.000 +2.236521035181264e-08 2.9e-03 5.5e-01 + 38 49 4.000 +4.430894630373603e-09 1.4e-03 5.5e-01 + 39 50 4.000 +8.766285485792653e-10 6.0e-04 5.5e-01 + 40 51 4.000 +1.751634425012838e-10 3.2e-04 5.5e-01 + 41 52 4.000 +4.269613882266779e-11 3.6e-05 5.1e-01 + 42 53 4.000 +8.563903609021838e-12 3.2e-05 5.0e-01 + 43 55 4.000 +8.011613923905404e-12 2.8e-06 8.9e-03 + 44 56 4.000 +1.582541862741472e-12 1.3e-06 5.6e-01 + 45 57 4.000 +3.126009356473569e-13 5.6e-07 5.6e-01 + 46 58 4.000 +6.174833942884158e-14 2.5e-07 5.6e-01 + 47 59 4.000 +1.219720341626072e-14 1.1e-07 5.6e-01 +# op_vmlmb_next: FATOL test satisfied +# +# +# Problem 15 (N=12): Extended Powell function. +# Method 0 (NDIR=12): Limited Memory BFGS (VMLM with NDIR=12) +# +# ITER EVAL CPU (ms) FUNC GNORM STEPLEN +# --------------------------------------------------------------- + 0 1 0.000 +6.450000000000000e+02 7.9e+02 0.0e+00 + 1 2 0.000 +2.126398786342238e+02 2.7e+02 9.0e-01 + 2 3 0.000 +1.002223459053673e+02 1.4e+02 1.0e+00 + 3 4 0.000 +4.372578508635030e+01 4.1e+01 1.0e+00 + 4 5 0.000 +3.492275772532622e+01 3.1e+01 1.0e+00 + 5 6 0.000 +2.371218382737346e+01 1.8e+01 1.0e+00 + 6 7 0.000 +1.840511402191540e+01 1.5e+01 1.0e+00 + 7 8 0.000 +5.385458666855794e+00 1.4e+01 1.0e+00 + 8 9 0.000 +1.387075054330895e+00 5.4e+00 7.5e-01 + 9 10 0.000 +4.338250784945510e-01 5.3e+00 1.0e+00 + 10 11 4.000 +2.021610832573901e-01 3.7e+00 9.0e-01 + 11 12 4.000 +8.424287893602030e-02 1.4e+00 1.0e+00 + 12 13 4.000 +2.416572403566977e-02 6.8e-01 9.8e-01 + 13 14 4.000 +9.539455035955798e-03 3.4e-01 1.0e+00 + 14 15 4.000 +4.018557231556538e-03 1.2e-01 1.0e+00 + 15 16 4.000 +2.359119570961944e-03 6.5e-02 1.0e+00 + 16 17 4.000 +1.410815508220599e-03 9.5e-02 1.0e+00 + 17 18 4.000 +6.664117905074039e-04 4.2e-02 1.0e+00 + 18 19 4.000 +3.278858525866031e-04 2.2e-02 1.0e+00 + 19 20 4.000 +1.301355227806065e-04 2.9e-02 1.0e+00 + 20 21 4.000 +5.051539438473153e-05 4.1e-02 9.6e-01 + 21 22 4.000 +1.933558681673291e-05 1.0e-02 1.0e+00 + 22 23 4.000 +1.385853063374876e-05 1.9e-03 1.0e+00 + 23 24 4.000 +1.325733364422288e-05 6.1e-03 1.0e+00 + 24 25 4.000 +1.042889374455694e-05 1.5e-02 1.0e+00 + 25 26 4.000 +5.019830828798650e-06 1.6e-02 1.0e+00 + 26 28 4.000 +4.246579321514016e-06 2.7e-03 3.0e-02 + 27 29 4.000 +1.264335976216658e-06 6.3e-04 1.0e+00 + 28 30 4.000 +4.235261754358550e-07 9.7e-05 1.0e+00 + 29 31 4.000 +1.358585713215724e-07 4.3e-05 1.0e+00 + 30 32 4.000 +4.490260964925541e-08 3.5e-04 1.0e+00 + 31 33 4.000 +1.435728201106651e-08 2.0e-04 1.0e+00 + 32 34 4.000 +4.659469517411141e-09 1.9e-05 1.0e+00 + 33 35 4.000 +3.197807521383443e-09 5.6e-04 9.5e-01 + 34 36 4.000 +8.129560805831940e-10 1.5e-04 8.3e-01 + 35 37 4.000 +2.639089711885569e-10 2.5e-05 1.0e+00 + 36 38 4.000 +1.238902847308503e-10 3.8e-05 1.0e+00 + 37 39 4.000 +3.693522871395788e-11 2.6e-05 1.0e+00 + 38 40 4.000 +1.262527367596187e-11 1.7e-05 9.9e-01 + 39 41 4.000 +4.121104687115640e-12 6.1e-06 8.0e-01 + 40 42 4.000 +1.510459349123597e-12 1.4e-06 1.0e+00 + 41 43 4.000 +5.074496790632610e-13 2.9e-07 1.0e+00 + 42 44 4.000 +1.788275537869560e-13 1.2e-06 1.0e+00 + 43 45 4.000 +5.912068107118078e-14 1.1e-06 1.0e+00 + 44 46 4.000 +2.328813604908046e-14 3.7e-07 1.0e+00 +# op_vmlmb_next: FATOL test satisfied +# +# +# Problem 16 (N=2): Beale function. +# Method 0 (NDIR=2): Limited Memory BFGS (VMLM with NDIR=2) +# +# ITER EVAL CPU (ms) FUNC GNORM STEPLEN +# --------------------------------------------------------------- + 0 1 0.000 +1.420312500000000e+01 2.8e+01 0.0e+00 + 1 2 0.000 +5.837321962114054e+00 9.0e+00 5.7e-01 + 2 3 0.000 +3.543247835494009e+00 6.4e+00 1.0e+00 + 3 4 0.000 +1.309302199158894e+00 2.7e+00 8.3e-01 + 4 5 0.000 +8.188817853278094e-01 2.2e+00 1.0e+00 + 5 6 0.000 +2.196594007426552e-01 9.2e-01 6.3e-01 + 6 7 0.000 +5.892697837805581e-02 3.1e-01 9.0e-01 + 7 8 0.000 +2.970214723480817e-02 1.1e+00 1.0e+00 + 8 9 0.000 +7.437526283530453e-03 2.6e-01 6.0e-01 + 9 10 0.000 +1.762547800263668e-03 5.2e-02 8.1e-01 + 10 11 0.000 +3.806254994795292e-04 3.8e-02 7.5e-01 + 11 13 0.000 +3.601037933927141e-04 1.8e-02 1.6e-02 + 12 14 0.000 +7.333268718739307e-05 6.9e-03 6.4e-01 + 13 15 0.000 +1.475615358477659e-05 3.5e-03 5.9e-01 + 14 17 0.000 +1.418392844246689e-05 6.2e-03 1.9e-02 + 15 18 0.000 +2.813440877948162e-06 2.6e-03 5.7e-01 + 16 19 0.000 +5.569285817905507e-07 1.1e-03 5.6e-01 + 17 20 0.000 +2.389901351508039e-07 3.9e-03 5.4e-01 + 18 21 0.000 +4.719137850755555e-08 1.7e-03 2.6e-01 + 19 22 0.000 +9.318027774792144e-09 7.6e-04 5.5e-01 + 20 23 0.000 +1.840271195971691e-09 3.4e-04 5.6e-01 + 21 24 0.000 +3.634816763291771e-10 1.5e-04 5.6e-01 + 22 25 0.000 +7.179633292922795e-11 6.7e-05 5.6e-01 + 23 26 0.000 +1.418177095511089e-11 3.0e-05 5.6e-01 + 24 27 0.000 +2.801318130710862e-12 1.3e-05 5.6e-01 + 25 28 0.000 +5.533450993015748e-13 5.9e-06 5.6e-01 + 26 29 0.000 +1.093025883599040e-13 2.6e-06 5.6e-01 + 27 30 0.000 +2.159062213224393e-14 1.2e-06 5.6e-01 + 28 31 0.000 +4.264813197124873e-15 5.2e-07 5.6e-01 +# op_vmlmb_next: FATOL test satisfied +# +# +# Problem 17 (N=4): Wood function. +# Method 0 (NDIR=4): Limited Memory BFGS (VMLM with NDIR=4) +# +# ITER EVAL CPU (ms) FUNC GNORM STEPLEN +# --------------------------------------------------------------- + 0 1 0.000 +1.919200000000000e+04 1.6e+04 0.0e+00 + 1 2 0.000 +7.427890102322217e+03 7.9e+03 1.0e+00 + 2 3 0.000 +2.438439115206284e+03 3.3e+03 1.0e+00 + 3 4 0.000 +8.528820526783926e+02 1.5e+03 1.0e+00 + 4 5 4.000 +2.768216485716339e+02 6.1e+02 1.0e+00 + 5 6 4.000 +8.327982562502508e+01 2.4e+02 1.0e+00 + 6 7 4.000 +3.108746833161832e+01 7.1e+01 1.0e+00 + 7 8 4.000 +2.380525415568198e+01 2.4e+01 1.0e+00 + 8 9 4.000 +2.251089219753886e+01 2.6e+01 1.0e+00 + 9 10 4.000 +1.855299679936986e+01 4.3e+01 1.0e+00 + 10 12 4.000 +1.160837562431893e+01 4.5e+01 3.8e-01 + 11 14 4.000 +8.137724551705739e+00 1.9e+01 1.1e-01 + 12 16 4.000 +7.878690238212614e+00 1.2e+00 3.4e-01 + 13 17 4.000 +7.877411159067403e+00 8.8e-01 1.0e+00 + 14 18 4.000 +7.876880489799159e+00 4.4e-02 1.0e+00 + 15 19 4.000 +7.876879132206481e+00 1.1e-02 1.0e+00 + 16 20 4.000 +7.876878876272726e+00 4.8e-03 1.0e+00 + 17 22 4.000 +7.876878490252988e+00 7.0e-03 5.0e+00 + 18 23 4.000 +7.876876755266399e+00 1.9e-02 1.0e+00 + 19 24 4.000 +7.876870816217647e+00 3.5e-02 1.0e+00 + 20 26 4.000 +7.876865204511740e+00 1.3e-01 4.0e-01 + 21 27 4.000 +7.876844389583843e+00 1.4e-01 1.0e+00 + 22 28 4.000 +7.876583706646104e+00 3.2e-01 1.0e+00 + 23 29 4.000 +7.876423129704414e+00 8.5e-01 1.0e+00 + 24 30 4.000 +7.875060453829682e+00 1.6e+00 1.0e+00 + 25 31 4.000 +7.872131119796703e+00 3.0e+00 1.0e+00 + 26 33 4.000 +7.869170139094837e+00 3.3e+00 2.0e-01 + 27 35 4.000 +7.864052623536911e+00 3.4e+00 3.6e-01 + 28 36 4.000 +7.855001610484345e+00 2.9e+00 1.0e+00 + 29 37 4.000 +7.849625111708809e+00 4.1e+00 1.0e+00 + 30 38 4.000 +7.839170804391435e+00 3.0e+00 1.0e+00 + 31 39 4.000 +7.824568101062441e+00 2.8e+00 1.0e+00 + 32 41 4.000 +7.813646935560872e+00 4.1e+00 2.4e-01 + 33 43 4.000 +7.789494013946371e+00 5.7e+00 2.3e-01 + 34 44 4.000 +7.722263757787657e+00 7.4e+00 1.0e+00 + 35 46 4.000 +7.693814493002182e+00 1.2e+01 1.6e-01 + 36 47 4.000 +7.541393104832614e+00 4.3e+00 1.0e+00 + 37 48 4.000 +7.434111139448211e+00 5.1e+00 1.0e+00 + 38 50 4.000 +7.420136912558213e+00 6.7e+00 9.8e-02 + 39 51 4.000 +7.323032564057124e+00 6.2e+00 1.0e+00 + 40 53 4.000 +7.216964400808464e+00 1.4e+01 2.7e-01 + 41 54 4.000 +6.911125334280928e+00 1.1e+01 1.0e+00 + 42 55 4.000 +6.512566568432114e+00 4.0e+01 1.0e+00 + 43 56 4.000 +5.720835039047132e+00 7.6e+00 1.0e+00 + 44 57 4.000 +5.672818396981924e+00 1.6e+01 1.0e+00 + 45 59 4.000 +5.202278173076890e+00 1.9e+01 2.2e-01 + 46 62 4.000 +5.061832019786340e+00 2.0e+01 6.4e-02 + 47 63 4.000 +4.875017742525158e+00 2.0e+01 1.0e+00 + 48 64 4.000 +4.616628933510177e+00 1.3e+01 1.0e+00 + 49 65 4.000 +4.405532645759691e+00 1.7e+01 1.0e+00 + 50 66 4.000 +3.915460121738099e+00 1.8e+01 1.0e+00 + 51 67 4.000 +3.571117225615803e+00 1.8e+01 1.0e+00 + 52 69 4.000 +3.342807282681064e+00 6.6e+00 3.0e-01 + 53 70 4.000 +3.169420327958804e+00 8.2e+00 1.0e+00 + 54 71 4.000 +3.083714115933907e+00 7.5e+00 1.0e+00 + 55 72 4.000 +2.842571930210177e+00 6.2e+00 1.0e+00 + 56 73 4.000 +2.407959483920122e+00 1.8e+01 1.0e+00 + 57 75 4.000 +2.310997032934655e+00 1.5e+01 2.4e-01 + 58 77 4.000 +1.874303903557421e+00 9.1e+00 3.9e-01 + 59 79 4.000 +1.747352207978819e+00 4.5e+00 4.3e-01 + 60 80 4.000 +1.616702123440979e+00 6.3e+00 1.0e+00 + 61 81 4.000 +1.551453286562933e+00 1.7e+01 1.0e+00 + 62 82 4.000 +1.445642573680781e+00 1.1e+01 1.0e+00 + 63 84 4.000 +1.291548725488739e+00 7.3e+00 5.2e-01 + 64 85 4.000 +1.146267070283055e+00 1.3e+01 1.0e+00 + 65 86 4.000 +8.736037619411690e-01 6.2e+00 1.0e+00 + 66 88 4.000 +7.587510486192135e-01 6.2e+00 4.3e-01 + 67 89 4.000 +6.272474461111625e-01 2.7e+00 1.0e+00 + 68 91 4.000 +6.154503738538099e-01 2.9e+00 3.6e-01 + 69 92 4.000 +6.025386870053662e-01 2.3e+00 1.0e+00 + 70 93 4.000 +5.569297053304927e-01 2.8e+00 1.0e+00 + 71 94 4.000 +4.939103897295918e-01 6.0e+00 1.0e+00 + 72 95 4.000 +3.289194049732398e-01 5.1e+00 1.0e+00 + 73 97 4.000 +2.689387273180264e-01 8.0e+00 2.0e-01 + 74 98 4.000 +1.220581321270582e-01 8.6e+00 8.6e-01 + 75 99 8.001 +6.663309577533551e-02 8.9e+00 4.3e-01 + 76 100 8.001 +3.637323340490146e-02 1.1e+00 1.0e+00 + 77 101 8.001 +2.712208655572348e-02 1.5e+00 1.0e+00 + 78 102 8.001 +1.116522496174569e-02 3.7e+00 7.9e-01 + 79 103 8.001 +3.900482707955074e-03 2.0e+00 4.8e-01 + 80 104 8.001 +1.004136803886999e-03 6.9e-01 9.3e-01 + 81 105 8.001 +2.226638008945489e-04 3.5e-01 7.3e-01 + 82 106 8.001 +5.106876720624694e-05 7.5e-02 6.0e-01 + 83 107 8.001 +1.071982128302296e-05 2.6e-02 6.0e-01 + 84 108 8.001 +4.441881481174797e-06 6.4e-02 5.2e-01 + 85 109 8.001 +9.368857777996710e-07 2.8e-02 4.1e-01 + 86 110 8.001 +1.923710022206024e-07 1.3e-02 5.7e-01 + 87 111 8.001 +4.207762167723878e-08 5.8e-03 6.1e-01 + 88 112 8.001 +1.181228459744630e-08 2.3e-03 7.0e-01 + 89 113 8.001 +6.562748229821411e-09 8.5e-04 1.0e+00 + 90 114 8.001 +5.554256689700290e-09 7.8e-04 1.0e+00 + 91 115 8.001 +3.484975951958208e-09 1.1e-03 1.0e+00 + 92 116 8.001 +8.872950699360685e-10 9.9e-04 9.6e-01 + 93 117 8.001 +1.837384368516011e-10 3.9e-04 4.7e-01 + 94 118 8.001 +3.863280276302230e-11 1.8e-04 5.7e-01 + 95 119 8.001 +9.862952976040704e-12 8.1e-05 6.1e-01 + 96 120 8.001 +3.643236162973744e-12 3.2e-05 6.8e-01 + 97 121 8.001 +2.484476074089160e-12 8.5e-06 1.0e+00 + 98 122 8.001 +2.082579068068493e-12 1.4e-05 1.0e+00 + 99 123 8.001 +7.291374932118642e-13 2.4e-05 1.0e+00 + 100 124 8.001 +3.315075555077437e-13 9.7e-06 5.1e-01 + 101 125 8.001 +7.622499994371465e-14 7.5e-06 7.5e-01 + 102 126 8.001 +4.174888567594510e-14 6.3e-06 1.5e-01 +# op_vmlmb_next: FATOL test satisfied +# +# +# Problem 18 (N=25): Chebyquad function. +# Method 0 (NDIR=25): Limited Memory BFGS (VMLM with NDIR=25) +# +# ITER EVAL CPU (ms) FUNC GNORM STEPLEN +# --------------------------------------------------------------- + 0 1 0.000 +1.248791904880204e-02 6.5e-01 0.0e+00 + 1 3 4.000 +1.049431287352932e-02 5.8e-01 5.7e-03 + 2 4 8.000 +9.609006926829304e-03 2.8e-01 1.0e+00 + 3 5 8.000 +9.337302507733160e-03 1.3e-01 1.0e+00 + 4 6 12.000 +9.170073298832805e-03 1.2e-01 1.0e+00 + 5 7 12.000 +8.991254191516106e-03 1.1e-01 1.0e+00 + 6 8 16.001 +8.846941541915740e-03 7.7e-02 1.0e+00 + 7 9 16.001 +8.801166872704557e-03 9.3e-02 1.0e+00 + 8 10 20.001 +8.756693487815655e-03 4.5e-02 1.0e+00 + 9 11 20.001 +8.739152782891746e-03 3.3e-02 1.0e+00 + 10 12 20.001 +8.714552799449523e-03 3.1e-02 1.0e+00 + 11 13 24.001 +8.692796444352035e-03 3.2e-02 1.0e+00 + 12 14 24.001 +8.667777829095081e-03 2.6e-02 1.0e+00 + 13 15 28.001 +8.654662603946484e-03 4.0e-02 1.0e+00 + 14 16 28.001 +8.643693770592379e-03 1.7e-02 1.0e+00 + 15 17 32.002 +8.637815829617758e-03 1.5e-02 1.0e+00 + 16 18 32.002 +8.633008188826369e-03 1.8e-02 1.0e+00 + 17 19 36.002 +8.620907535587131e-03 4.2e-02 1.0e+00 + 18 21 40.002 +8.614998716828056e-03 2.6e-02 4.1e-01 + 19 22 40.002 +8.610412652519038e-03 1.1e-02 1.0e+00 + 20 23 40.002 +8.608556239357218e-03 7.1e-03 1.0e+00 + 21 24 44.002 +8.607605459630636e-03 6.9e-03 1.0e+00 + 22 25 44.002 +8.602572986472511e-03 1.3e-02 1.0e+00 + 23 26 48.003 +8.590054454806751e-03 2.8e-02 1.0e+00 + 24 27 48.003 +8.564183633311328e-03 7.5e-02 1.0e+00 + 25 28 52.003 +8.532458576242349e-03 9.3e-02 1.0e+00 + 26 29 52.003 +8.493452768781006e-03 7.0e-02 1.0e+00 + 27 30 56.003 +8.474787010915145e-03 6.7e-02 1.0e+00 + 28 31 56.003 +8.458773326847066e-03 4.5e-02 1.0e+00 + 29 32 60.003 +8.457999627479094e-03 4.1e-02 1.0e+00 + 30 33 60.003 +8.449532870934518e-03 2.2e-02 1.0e+00 + 31 34 64.004 +8.447840743807028e-03 2.8e-02 1.0e+00 + 32 35 64.004 +8.445692845529283e-03 1.1e-02 1.0e+00 + 33 36 68.004 +8.444165323560711e-03 9.6e-03 1.0e+00 + 34 37 68.004 +8.443207951672584e-03 1.0e-02 1.0e+00 + 35 38 68.004 +8.441994339191562e-03 2.0e-02 1.0e+00 + 36 39 72.004 +8.439832619160158e-03 1.4e-02 1.0e+00 + 37 40 72.004 +8.437231750924349e-03 1.1e-02 1.0e+00 + 38 41 76.004 +8.433302937380200e-03 1.2e-02 1.0e+00 + 39 43 80.005 +8.432489353555114e-03 9.1e-03 3.7e-01 + 40 44 80.005 +8.432123509481731e-03 4.7e-03 1.0e+00 + 41 45 84.005 +8.432035588096611e-03 2.3e-03 1.0e+00 + 42 46 84.005 +8.431999120538823e-03 1.5e-03 1.0e+00 + 43 47 88.005 +8.431966728031759e-03 1.2e-03 1.0e+00 + 44 48 88.005 +8.431924365562692e-03 1.6e-03 1.0e+00 + 45 50 92.005 +8.431891947171172e-03 3.1e-03 4.2e-01 + 46 51 92.005 +8.431831354671862e-03 2.3e-03 1.0e+00 + 47 52 96.006 +8.431668636095641e-03 3.3e-03 1.0e+00 + 48 53 96.006 +8.431437099609954e-03 5.4e-03 1.0e+00 + 49 54 100.006 +8.431000851063426e-03 5.3e-03 1.0e+00 + 50 55 100.006 +8.430678732503366e-03 1.6e-02 1.0e+00 + 51 56 104.006 +8.429876682496911e-03 7.2e-03 1.0e+00 + 52 57 104.006 +8.428910142166941e-03 6.9e-03 1.0e+00 + 53 58 108.006 +8.428161202850929e-03 9.8e-03 1.0e+00 + 54 59 108.006 +8.427149557235504e-03 1.2e-02 1.0e+00 + 55 60 112.007 +8.426884594329293e-03 1.0e-02 1.0e+00 + 56 62 116.007 +8.425929204745749e-03 9.6e-03 4.4e-01 + 57 63 116.007 +8.425078821369147e-03 6.2e-03 1.0e+00 + 58 65 120.007 +8.424962146289759e-03 6.7e-03 2.7e-01 + 59 66 124.007 +8.424706166580516e-03 6.3e-03 1.0e+00 + 60 67 124.007 +8.424483854096705e-03 4.1e-03 1.0e+00 + 61 68 124.007 +8.424346241895737e-03 2.7e-03 1.0e+00 + 62 69 128.008 +8.424196521199122e-03 4.1e-03 1.0e+00 + 63 70 128.008 +8.423947181728741e-03 3.3e-03 1.0e+00 + 64 72 132.008 +8.423857716916193e-03 3.9e-03 4.8e-01 + 65 73 136.008 +8.423772029357686e-03 1.3e-03 1.0e+00 + 66 74 136.008 +8.423740800437915e-03 1.7e-03 1.0e+00 + 67 75 140.008 +8.423721211048594e-03 2.0e-03 1.0e+00 + 68 76 140.008 +8.423707802726785e-03 6.8e-04 1.0e+00 + 69 77 144.009 +8.423705094214971e-03 2.9e-04 1.0e+00 + 70 78 144.009 +8.423704078604773e-03 2.7e-04 1.0e+00 + 71 79 148.009 +8.423703211145708e-03 2.3e-04 1.0e+00 + 72 80 148.009 +8.423702337458264e-03 1.9e-04 1.0e+00 + 73 81 148.009 +8.423702265665172e-03 4.1e-04 1.0e+00 + 74 82 152.009 +8.423701658411723e-03 1.6e-04 1.0e+00 + 75 83 152.009 +8.423701425312869e-03 1.7e-04 1.0e+00 + 76 84 156.009 +8.423700442240544e-03 3.0e-04 1.0e+00 + 77 85 156.009 +8.423698956540247e-03 4.1e-04 1.0e+00 + 78 86 160.010 +8.423696594839578e-03 6.2e-04 1.0e+00 + 79 87 160.010 +8.423693749784765e-03 5.9e-04 1.0e+00 + 80 88 164.010 +8.423691373336607e-03 3.1e-04 1.0e+00 + 81 89 164.010 +8.423689724709164e-03 1.6e-04 1.0e+00 + 82 91 168.010 +8.423689561087022e-03 2.0e-04 4.0e-01 + 83 92 172.010 +8.423689406081498e-03 1.2e-04 1.0e+00 + 84 93 172.010 +8.423689325881282e-03 3.0e-05 1.0e+00 + 85 94 172.010 +8.423689316751977e-03 2.9e-05 1.0e+00 + 86 95 176.011 +8.423689305145607e-03 2.4e-05 1.0e+00 + 87 96 176.011 +8.423689289622477e-03 2.8e-05 1.0e+00 + 88 97 180.011 +8.423689257662553e-03 3.4e-05 1.0e+00 + 89 98 180.011 +8.423689218774710e-03 3.7e-05 1.0e+00 + 90 99 184.011 +8.423689151546083e-03 7.2e-05 1.0e+00 + 91 100 184.011 +8.423689072351309e-03 6.8e-05 1.0e+00 + 92 101 188.011 +8.423688995763033e-03 6.2e-05 1.0e+00 + 93 102 188.011 +8.423688928736774e-03 7.4e-05 1.0e+00 + 94 103 192.012 +8.423688881914616e-03 4.9e-05 1.0e+00 + 95 104 192.012 +8.423688840104407e-03 4.0e-05 1.0e+00 + 96 106 196.012 +8.423688821486053e-03 7.3e-05 4.4e-01 + 97 107 196.012 +8.423688798581467e-03 3.0e-05 1.0e+00 + 98 108 200.012 +8.423688787360375e-03 1.9e-05 1.0e+00 + 99 109 200.012 +8.423688776709048e-03 1.3e-05 1.0e+00 + 100 111 204.012 +8.423688774926129e-03 2.1e-05 4.6e-01 + 101 112 208.013 +8.423688773115171e-03 7.6e-06 1.0e+00 + 102 113 208.013 +8.423688772436546e-03 6.9e-06 1.0e+00 + 103 114 212.013 +8.423688771155470e-03 1.1e-05 1.0e+00 + 104 115 212.013 +8.423688769387254e-03 1.4e-05 1.0e+00 + 105 116 216.013 +8.423688766337282e-03 1.4e-05 1.0e+00 + 106 118 220.013 +8.423688765114607e-03 1.5e-05 2.8e-01 + 107 119 220.013 +8.423688763449228e-03 6.4e-06 1.0e+00 + 108 120 220.013 +8.423688762532369e-03 7.1e-06 1.0e+00 + 109 121 224.014 +8.423688761837404e-03 9.9e-06 1.0e+00 + 110 122 224.014 +8.423688760262529e-03 1.3e-05 1.0e+00 + 111 123 228.014 +8.423688759272251e-03 3.6e-05 1.0e+00 + 112 124 228.014 +8.423688756130365e-03 1.7e-05 1.0e+00 + 113 125 232.014 +8.423688753374270e-03 9.2e-06 1.0e+00 + 114 126 232.014 +8.423688751373724e-03 1.1e-05 1.0e+00 + 115 127 236.014 +8.423688750014176e-03 7.3e-06 1.0e+00 + 116 128 236.014 +8.423688749391211e-03 7.7e-06 1.0e+00 + 117 129 240.015 +8.423688748986261e-03 5.8e-06 1.0e+00 +# op_vmlmb_next: FRTOL test satisfied +# diff -Nru yorick-optimpack-1.3.2+dfsg/optimpack1/yorick/optimpack.c yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/yorick/optimpack.c --- yorick-optimpack-1.3.2+dfsg/optimpack1/yorick/optimpack.c 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack1/yorick/optimpack.c 2007-07-05 09:38:20.000000000 +0000 @@ -0,0 +1,125 @@ +/* + * optimpack.c -- + * + * Implementation of Yorick wrapper for OptimPack. + * + *----------------------------------------------------------------------------- + * + * Copyright (C) 2003-2007 Eric Thiébaut. + * + * This file is part of OptimPack. + * + * OptimPack is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * OptimPack is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with OptimPack (file "COPYING" in the top source + * directory); if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *----------------------------------------------------------------------------- + * + * History: + * $Id$ + * $Log$ + *----------------------------------------------------------------------------- + */ + +void Y_op_vmlmb_first(int argc) +{ + Dimension *dims; + Symbol *argv = sp - argc + 1; + long n, m; + double fmin, fatol, frtol, sftol, sgtol, sxtol; + char *csave; + long *isave; + double *dsave; + long ncsave, nisave, ndsave; + long task; + if (argc != 11) YError("op_vmlmb_first takes exactly 11 arguments"); + n = YGetInteger(&argv[0]); + m = YGetInteger(&argv[1]); + fmin = YGetReal(&argv[2]); + fatol = YGetReal(&argv[3]); + frtol = YGetReal(&argv[4]); + sftol = YGetReal(&argv[5]); + sgtol = YGetReal(&argv[6]); + sxtol = YGetReal(&argv[7]); + csave = get_char_array(&argv[8], 0, &ncsave); + isave = get_long_array(&argv[9], 0, &nisave); + dsave = get_double_array(&argv[10], 0, &ndsave); + if (ncsave < OP_MSG_SIZE) YError("too few elements for CSAVE"); + if (nisave < ???) YError("too few elements for ISAVE"); + if (ndsave < ???) YError("too few elements for DSAVE"); + task = op_vmlmb_first(n, m, fmin, fatol, frtol, sftol, sgtol, sxtol, + csave, isave, dsave); + if (task != OP_TASK_FG) YError(csave); + PushLongValue(task); +} + +static void parse_ws(Symbol *s, + char **csave_ptr, long ncsave, + long **isave_ptr, long nisave, + double **dsave_ptr, long ndsave) +{ + void *ptr; + Operand op; + if (!s->ops) YError("unexpected keyword argument"); + s->ops->FormOperand(s, &op); + if (op.ops->typeID!=T_POINTER || op.type.number != 3) + YError("expecting array of 3 pointers"); + ptr = *(void **)op.value; + +} + +#define IS_REF(S) ((S)->ops == &referenceSym) +#define DEREF_SYMBOL(S) (IS_REF(S) ? &globTab[(S)->index] : (S)) + +static void unexpected_keyword_argument(const char *name) +{ + if (name && strlen(name) < 30) { + char msg[80]; + strcpy(msg, "unexpected keyword argument for "); + strcat(msg, name); + YError(msg); + } else { + YError("unexpected keyword argument"); + } +} + +static char *get_char_array(const char *name, Symbol *s, + int nil_ok, long *number); +static char *get_char_array(const char *name, Symbol *s, + int nil_ok, long *number) +{ + Operand op; + if (! s->ops) YError("unexpected keyword argument"); + s->ops->FormOperand(s, &op); + if (op.ops->typeID == T_CHAR) { + if (nil_ok && ) { + if (number) *number = 0; + return NULL; + } + YError("expecting character array argument"); + } + if (number) *number = op.type.number; + return ; + if (op.ops->typeID!=T_POINTER || op.type.dims) + YError("expecting scalar pointer argument"); + return *(void **)op.value; +} + +/*---------------------------------------------------------------------------* + * Local Variables: * + * mode: C * + * tab-width: 8 * + * fill-column: 75 * + * coding: latin-1 * + * End: * + *---------------------------------------------------------------------------*/ diff -Nru yorick-optimpack-1.3.2+dfsg/optimpack.bib yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack.bib --- yorick-optimpack-1.3.2+dfsg/optimpack.bib 2003-03-12 10:08:27.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack.bib 2017-01-10 22:16:57.000000000 +0000 @@ -1,12 +1,28 @@ -@article{192132, - author = {Jorge J. Mor{\'e} and David J. Thuente}, - title = {Line search algorithms with guaranteed sufficient decrease}, - journal = {ACM Transactions on Mathematical Software (TOMS)}, - volume = {20}, - number = {3}, - year = {1994}, - issn = {0098-3500}, - pages = {286--307}, - doi = {http://doi.acm.org/10.1145/192115.192132}, - publisher = {ACM Press}, - } +@Article{More_Thente-1994-line_search, + Author = {Jorge J. Mor{\'e} and David J. Thuente}, + Title = {Line search algorithms with guaranteed sufficient decrease}, + Journal = {ACM Transactions on Mathematical Software (TOMS)}, + Volume = {20}, + Number = {3}, + Year = {1994}, + Issn = {0098-3500}, + Pages = {286--307}, + Doi = {10.1145/192115.192132}, + Publisher = {ACM Press} +} + +@InProceedings{Thiebaut-2002-optimization, + Title = {Optimization issues in blind deconvolution algorithms}, + Author = {{\'E}ric Thiébaut}, + Booktitle = {Astronomical Data Analysis {II}}, + Year = {2002}, + Address = {Bellingham, Washington}, + Editor = {Jean-Luc Starck and Fionn D. Murtagh}, + Organization = {SPIE}, + Pages = {174--183}, + Volume = {4847}, + Bibcode = {2002SPIE.4847..174T}, + Doi = {10.1117/12.461151}, + File = {Thiebaut-2002-optim_bdec.pdf:Thiebaut-2002-optim_bdec.pdf:PDF}, + Keywords = {large-scale optimization; VMLM-B; VMLMB; blind deconvolution} +} diff -Nru yorick-optimpack-1.3.2+dfsg/optimpack.h yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack.h --- yorick-optimpack-1.3.2+dfsg/optimpack.h 2009-04-23 11:24:41.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/optimpack.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,763 +0,0 @@ -/* - * optimpack.h -- - * - * Definitions for optimization routines implemented in OptimPack - * library. - * - *----------------------------------------------------------------------------- - * - * Copyright (c) 2003, Eric THIEBAUT. - * - * This file is part of OptimPack. - * - * OptimPack is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2 of the License, - * or (at your option) any later version. - * - * OptimPack is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with OptimPack (file "LICENSE" in the top source directory); - * if not, write to the Free Software Foundation, Inc., 59 Temple - * Place, Suite 330, Boston, MA 02111-1307 USA - * - *----------------------------------------------------------------------------- - * - * $Id$ - * $Log$ - * - *----------------------------------------------------------------------------- - */ - -#ifndef _OPTIMPACK_H -#define _OPTIMPACK_H 1 - -/* Customizable data types: - * OP_INTEGER = data type used to store array indices - * OP_LOGICAL = data type of the result of a logical test - */ -#ifndef OP_INTEGER -# define OP_INTEGER int -#endif -#ifndef OP_LOGICAL -# define OP_LOGICAL int -#endif - - -/* Values returned by OptimPack routines: */ -#define OP_ERROR 1 -#define OP_OK 0 - -#define OP_TRUE 1 -#define OP_FALSE 0 - -/*---------------------------------------------------------------------------*/ -/* USEFUL MACROS */ - -/* OP_STRINGIFY takes an argument and wraps it in "" (double quotation - marks), OP_CONCAT concatenates two arguments. */ -#ifdef __STDC__ -# define OP_STRINGIFY(x) #x -# define OP_CONCAT(a,b) a##b -# define OP_CONCAT2(a,b) a##b -# define OP_CONCAT3(a,b,c) a##b##c -# define OP_CONCAT4(a,b,c,d) a##b##c##d -#else -# define OP_STRINGIFY(x) "x" -# define OP_CONCAT(a,b) a/**/b -# define OP_CONCAT2(a,b) a/**/b -# define OP_CONCAT3(a,b,c) a/**/b/**/c -# define OP_CONCAT4(a,b,c,d) a/**/b/**/c/**/d -#endif - -/* Computes absolute value: */ -#define OP_ABS(a) ((a)>=0?(a):-(a)) - -/* Computes min/max values: */ -#define OP_MIN(a,b) ((a)<=(b)?(a):(b)) -#define OP_MAX(a,b) ((a)>=(b)?(a):(b)) - -/* Computes minimal number of chunks with M elements - needed to store N elements: */ -#define OP_HOW_MANY(n, m) (((n)+((m)-1))/(m)) - -/* Returns N elements rounding up to a multiple of M elements: */ -#define OP_ROUND_UP(n, m) (OP_HOW_MANY(n, m)*(m)) - -/* Offset (in bytes) of member M in structure S: */ -#define OP_OFFSET_OF(s, m) ((size_t) &((s *)0)->m) - -/* C++ needs to know that types and declarations are C, not C++. */ -#ifdef __cplusplus -# define _OP_BEGIN_DECLS extern "C" { -# define _OP_END_DECLS } -#else -# define _OP_BEGIN_DECLS /* empty */ -# define _OP_END_DECLS /* empty */ -#endif -_OP_BEGIN_DECLS - -typedef OP_INTEGER op_integer_t; -typedef OP_LOGICAL op_logical_t; - -/*---------------------------------------------------------------------------*/ -/* LINE SEARCH */ - -#define OP_TASK_START 0 /* first entry, start search */ -#define OP_TASK_FG 1 /* computation of F and G requested */ -#define OP_TASK_NEWX 2 /* new improved solution available for inspection */ -#define OP_TASK_CONV 3 /* search has converged */ -#define OP_TASK_WARN 4 /* search aborted with warning */ -#define OP_TASK_ERROR 5 /* search aborted with error */ - -extern int op_csrch(double f, double g, double *stp_ptr, - double ftol, double gtol, double xtol, - double stpmin, double stpmax, int *task, - char csave[], op_integer_t isave[], double dsave[]); -/* - * DESCRIPTION: - * This subroutine finds a step that satisfies a sufficient decrease - * condition and a curvature condition. - * - * Each call of the subroutine updates an interval with endpoints STX and - * STY. The interval is initially chosen so that it contains a minimizer - * of the modified function: - * - * psi(stp) = f(stp) - f(0) - ftol*stp*g(0) - * - * where g(0) = f'(0). If psi(stp) <= 0 and g(stp) >= 0 for some step, - * then the interval is chosen so that it contains a minimizer of f. The - * algorithm is designed to find a step that satisfies the sufficient - * decrease condition: - * - * f(stp) <= f(0) + ftol*stp*g(0), (1) - * - * and the curvature condition: - * - * abs(g(stp)) <= gtol*abs(g(0)). (2) - * - * Relations (1) and (2) are called the strong Wolfe conditions. If FTOL - * is less than GTOL and if, for example, the function is bounded below, - * then there is always a step which satisfies both conditions. If no - * step can be found that satisfies both conditions, then the algorithm - * stops with a warning. In this case STP only satisfies the sufficient - * decrease condition. - * - * - * ARGUMENTS: - * (Note: the user must not alter TASK and work arrays ISAVE and DSAVE - * between calls.) - * - * F is a double precision variable. On initial entry, F is the value of - * the function at 0. On subsequent entries, F is the value of the - * function at STP. On exit, F is left unchanged. - * - * G is a double precision variable. On initial entry, G is the - * derivative of the function at 0. On subsequent entries, G is the - * derivative of the function at STP. On exit, G is left unchanged. - * - * STP is a double precision variable. On entry, STP is the current - * estimate of a satisfactory step. On initial entry, a positive - * initial estimate must be provided. On exit with TASK=OP_TASK_FG, - * STP is the new estimate of a satisfactory step. On exit with - * TASK=OP_TASK_CONV, STP is left unchanged and satisfies the - * sufficient decrease and curvature condition. On exit with TASK not - * equal to OP_TASK_CONV, STP is left unchanged. - * - * FTOL is a double precision variable. On entry, FTOL specifies a - * nonnegative tolerance for the sufficient decrease condition. On - * exit, FTOL is unchanged. You should take 0 < FTOL < 0.5 - * - * GTOL is a double precision variable. On entry, GTOL specifies a - * nonnegative tolerance for the curvature condition. On exit, GTOL is - * unchanged. You should take FTOL < GTOL < 1. - * - * XTOL is a double precision variable. On entry, XTOL specifies a - * nonnegative relative tolerance for an acceptable step. The - * subroutine exits with a warning if the relative difference between - * STY and STX is less than XTOL. On exit, XTOL is unchanged. - * - * STPMIN is a double precision variable. On entry, STPMIN is a - * nonnegative lower bound for the step. On exit, STPMIN is unchanged. - * - * STPMAX is a double precision variable. On entry, STPMAX is a - * nonnegative upper bound for the step. On exit, STPMAX is unchanged. - * - * TASK is an integer variable. On initial entry, task must be set to - * OP_TASK_START. On exit, TASK indicates the required action: - * - * If TASK=OP_TASK_FG then evaluate the function and derivative at - * STP and call op_dcsrch again. - * - * If TASK=OP_TASK_CONV then the search is successful. - * - * If TASK=OP_TASK_WARN then the subroutine is not able to satisfy - * the convergence conditions. The exit value of stp contains the - * best point found during the search. - * - * If TASK=OP_TASK_ERROR then there is an error in the input - * arguments. - * - * On exit with convergence, a warning or an error, the array CSAVE - * contains additional information (unless it was NULL). - * - * CSAVE is a character work array of, at least, OP_MSG_SIZE elements - * which is used to store a message corresponding to the value of TASK. - * - * ISAVE is an integer work array of, at least, 2 elements. - * - * DSAVE is a double precision work array of, at least, 12 elements. - * - * - * RETURNED VALUE: - * The returned value is less or equal zero to signal an error: - * 0 if STPMAX < STPMIN - * -1 if descent condition violated, i.e. DX*(STP - STX) >= 0 - * -2 if STP outside bracket (STX,STY) - * -3 if STPMIN < 0 - * -4 if XTOL < 0 - * -5 if FTOL <= 0 - * -6 if GTOL <= 0 - * -7 if initial G >= 0 - * -8 if STP > STPMAX - * -9 if STP < STPMIN - * The returned value is greater or equal 3 to indicate that the line - * search cannot converge (warning): - * 3 if STP = STPMIN - * 4 if STP = STPMAX - * 5 if XTOL test satisfied - * 6 if rounding errors prevent progress - * Otherwise (normal return), the returned value is: - * 1 if caller must evaluate (i.e. TASK = OP_TASK_FG) - * 2 if line search has convergenced (i.e. TASK = OP_TASK_CONV) - * - * - * EXEMPLE: - * A typical invocation of op_csrch has the following outline: - * - * task = OP_TASK_START; - * f = ...; // function value for STP=0 - * g = ...; // derivative value for STP=0 - * stp = ...; // guess for next STP value to try (STP > 0.0) - * for (;;) { - * op_csrch(f, g, &stp, ftol, gtol, xtol, stpmin, stpmax, &task, - * csave, isave, dsave); - * if (task == OP_TASK_FG) { - * // Evaluate the function and the gradient at STP. - * f = func(STP); - * g = grad(STP); - * } else if (task == OP_TASK_CONV) { - * // Search has converged. - * break; - * } else if (task == OP_TASK_WARN) { - * // Some problem prevents further progress. - * fprintf(stderr, "warning in %s\n", csave); - * exit(1); - * } else { - * // An error occured. - * fprintf(stderr, "error in %s\n", csave); - * exit(1); - * } - * } - * - * - * REFERENCES: - * [1] Jorge J. Moré and David J. Thuente, "Line search algorithms with - * guaranteed sufficient decrease" in ACM Transactions on - * Mathematical Software (TOMS) Volume 20, Issue 3, Pages 286-307 - * (September 1994). - * - * - * HISTORY: - * MINPACK-1 Project. June 1983. - * Argonne National Laboratory. - * Jorge J. Moré and David J. Thuente. - * - * MINPACK-2 Project. November 1993. - * Argonne National Laboratory and University of Minnesota. - * Brett M. Averick, Richard G. Carter, and Jorge J. Moré. - * - * Yorick translation an improvements. October 2001. - * C-version. February 2003. - * Observatoire de Lyon (France). - * Eric Thiébaut. - */ - -extern int op_cstep(double *stx_ptr, double *fx_ptr, double *dx_ptr, - double *sty_ptr, double *fy_ptr, double *dy_ptr, - double *stp_ptr, double fp, double dp, - int *brackt_ptr, double stpmin, double stpmax, - char *errmsg); -/* - * DESCRIPTION: - * These functions compute a safeguarded step for a search procedure and - * updates an interval that contains a step that satisfies a sufficient - * decrease and a curvature condition [1]. - * - * The parameter STX contains the step with the least function value. If - * BRACKT is set to true (i.e. non-zero) then a minimizer has been - * bracketed in an interval with endpoints STX and STY. The parameter - * STP contains the current step. The subroutine assumes that if BRACKT - * is true then: - * - * min(STX,STY) < STP < max(STX,STY), - * - * and that the derivative at STX is negative in the direction of the - * step. - * - * - * ARGUMENTS: - * STX_PTR, FX_PTR and DX_PTR are the addresses where the values of STX, - * FX and DX are stored. STX, FX, and DX specify the step, the - * function, and the derivative at the best step obtained so far. The - * derivative must be negative in the direction of the step, that is, - * DX and STP-STX must have opposite signs. On output these parameters - * are updated appropriately. - * - * STY_PTR, FY_PTR and DY_PTR are the addresses where the values of STY, - * FY and DY are stored. STY, FY, and DY specify the step, the - * function, and the derivative at the other endpoint of the interval - * of uncertainty. On output these parameters are updated - * appropriately. - * - * STP_PTR is the addresses where the value of STP is stored. STP, FP, - * and DP specify the step, the function, and the derivative at the - * current step. If BRACKT is set true then on input STP must be - * between STX and STY. On output STP (i.e. the value at address - * STP_PTR) is set to the new step. - * - * - * BRACKT_PTR is the addresses where the value of BRACKT is stored. - * BRACKT is a logical variable. On entry, BRACKT specifies if a - * minimizer has been bracketed. Initially BRACKT must be set to false - * (i.e zero). On exit, BRACKT specifies if a minimizer has been - * bracketed. When a minimizer is bracketed, BRACKT (i.e. the value at - * address BRACKT_PTR) is set to true (i.e. non-zero). - * - * STPMIN and STPMAX specify lower and upper bounds for the step. - * - * ERRMSG is a character buffer with at least OP_MSG_SIZE bytes (or NULL - * to have no error message) used to store an error message if the - * routine returns OP_ERROR. - * - * - * RETURNED VALUE: - * The returned value is less or equal zero to signal an error: - * 0 if STPMAX < STPMIN - * -1 if descent condition violated, i.e. DX*(STP - STX) >= 0 - * -2 if STP outside bracket (STX,STY) - * otherwise (no error) the returned value is 1, 2, 3 or 4 to indicate - * which how the new step was guessed (see the code and ref. [1] for - * details). - * - * - * REFERENCES: - * [1] Jorge J. Moré and David J. Thuente, "Line search algorithms with - * guaranteed sufficient decrease" in ACM Transactions on - * Mathematical Software (TOMS) Volume 20, Issue 3, Pages 286-307 - * (September 1994). - * - * - * HISTORY: - * MINPACK-1 Project. June 1983 - * Argonne National Laboratory. - * Jorge J. Moré and David J. Thuente. - * - * MINPACK-2 Project. November 1993. - * Argonne National Laboratory and University of Minnesota. - * Brett M. Averick and Jorge J. Moré. - * - * Yorick translation an improvements. October 2001. - * C-version. February 2003. - * Observatoire de Lyon (France). - * Eric Thiébaut. - */ - -/*---------------------------------------------------------------------------*/ -/* VMLMB - limited memory variable metric method (BFGS) - with/without bound constraints */ - -#define OP_VMLMB_CSAVE_NUMBER OP_MSG_SIZE -#define OP_VMLMB_ISAVE_NUMBER 12 -#define OP_VMLMB_DSAVE_NUMBER(n, m) (27 + (n) + 2*(m)*((n) + 1)) - -extern int op_vmlmb_first(op_integer_t n, op_integer_t m, - double fatol, double frtol, - double sftol, double sgtol, double sxtol, - double epsilon, double costheta, - char csave[], op_integer_t isave[], double dsave[]); -extern int op_vmlmb_next(double x[], double *f, double g[], - op_logical_t active[], const double h[], - char csave[], op_integer_t isave[], double dsave[]); -/* VMLM-B computes a local minimizer of a function of N variables by a - * limited memory variable metric (BFGS) method; optionally, the parameters - * may be bounded. The user must evaluate the function and the gradient. - * - * VMLM-B is implemented via two functions: op_vmlmb_first for - * initialization and op_vmlmb_next for further iterations. These - * functions use reverse communication. The user must choose an initial - * approximation X to the minimizer, evaluate the function and the gradient - * at X, and make the initial call with TASK set to "start". On exit TASK - * indicates the required action. - * - * The arguments are: - * - * N is the number of parameters. - * - * M is the number of correction pairs to remember in order to compute - * the limited memory variable metric (BFGS) approximation of the - * inverse of the Hessian. For large problems, M = 3 to 5 gives good - * results. For small problems, M should be less or equal N. The - * larger is M (and N) the more computer memory will be needed to - * store the workspaces (see DSAVE). - * - * FRTOL is the relative error desired in the function (e.g. - * FRTOL=1e-8). Convergence occurs if the estimate of the relative - * error between F(X) and F(XSOL), where XSOL is a local minimizer, - * is less or equal FRTOL. FRTOL must have a non-negative floating - * point value. - * - * FATOL is the absolute error desired in the function (e.g. FATOL=0.0). - * Convergence occurs if the estimate of the absolute error between - * F(X) and F(XSOL), where XSOL is a local minimizer, is less or - * equal FATOL. FATOL must have a non-negative floating point value. - * - * SFTOL, SGTOL, and SXTOL are tolerances for the line search subroutine - * (see op_csrch). Recommended values: SFTOL=0.001, SGTOL=0.9, - * SXTOL=0.1 (other values may be more suitable for highly - * non-quadratic penalty function). - * - * EPSILON is a small (strictly positive) value used to discard BFGS updates - * that may yield a non positive definite Hessian approximation. - * - * COSTHETA is a small value, in the range [0,1), equals to the cosine of - * the maximum angle between the search direction and the anti-gradient. - * The BFGS recursion is restarted, whenever the search direction is not - * sufficiently "descending". - * - * CSAVE is a character workspace array of length OP_VMLMB_CSAVE_NUMBER - * (same as OP_MSG_SIZE) which is used to store additional - * information on exit with convergence, a warning or an error. - * - * ISAVE is an integer workspace array of length OP_VMLMB_ISAVE_NUMBER. - * - * DSAVE is a floating point workspace array of length equal to the value - * returned by the macro OP_VMLMB_DSAVE_NUMBER(N, M): - * 26 + N + 2*M*(N + 1). - * - * X is a double precision array of length N. On entry, X is an - * approximation to the solution. On exit with TASK=OP_TASK_CONV, X - * is the current approximation. - * - * F is the address of a double precision variable. On entry, F is the - * value of the function at X. On final exit, F is the function - * value at X. - * - * G is a double precision array of length N. On entry, G is the value - * of the gradient at X. On final exit, G is the value of the - * gradient at X. - * - * ACTIVE is an optional integer array with length N provided by the - * caller if the values in X has bounds. If the parameters have no - * bounds, ACTIVE should be NULL (unconstrained minimization). - * Otherwise, elements set to zero in ACTIVE indicate that the - * corresponding values in X has reached a bound and should not be - * changed during the next step because the gradient has the wrong - * sign (i.e. the steepest descent direction would violate the bound - * constraints): - * ACTIVE[i] = 0 if i-th value has a lower bound XLO[i] - * and X[i]=XLO[i] and G[i]>=0 - * 0 if i-th value has an upper bound XHI[i] - * and X[i]=XHI[i] and G[i]<=0 - * 1 (or any non-zero value) otherwise - * - * ACTIVE needs only to be computed (and specified) the first time - * op_vmlmb_next is called and when TASK=OP_TASK_NEWX (i.e. after a - * successful step). ACTIVE may also be specified when - * TASK=OP_TASK_CONV (i.e. after convergence if caller wish to - * continue with minimization). If X has (some) bounds, the caller - * is responsible for applying the bounds to X before evaluating the - * function value F and the gradient G (i.e. when TASK=OP_TASK_FG), - * e.g.: - * if (X[i] < XLO[i]) X[i] = XLO[i]; - * if (X[i] > XHI[i]) X[i] = XHI[i]; - * - * If H is not specified (i.e. H is NULL) or if H[i] > 0 for all i - * such that ACTIVE[i] is non-zero, then ACTIVE is left unchanged. - * - * H is an optional double precision array with length N provided by the - * caller and such that diag(H) is an approximation of the inverse of - * the Hessian matrix. If H is NULL, then the inverse of the Hessian - * is approximated by a simple rescaling using Shanno & Phua formula. - * Otherwise, if ACTIVE is NULL, all elements of H must be strictly - * greater than zero; else ACTIVE[i] is set to zero if H[i] <= 0 - * (this is the only case where ACTIVE is modified). As for ACTIVE, - * H needs only to be specifed the first time op_vmlmb is called and - * when JOB=2. - * - * TASK is the value returned by op_vmlmb_first and op_vmlmb_next. It - * can have one of the following values: - * OP_TASK_FG - caller must evaluate the function and gradient at - * X and call op_vmlm_next. - * OP_TASK_NEWX - a new iterate has been computed. The - * approximation X, function F, and gradient G are available - * for examination. - * - * OP_TASK_CONV - the search is successful. The solution, - * function value and gradient are available in X, F and G. - * - * OP_TASK_WARN - VMLMB is not able to satisfy the convergence - * conditions. The exit value of X contains the best - * approximation found so far. Warning message is available - * in CSAVE. - * OP_TASK_ERROR then there is an error in the input arguments. - * Error message is available in CSAVE. - * - * The caller must not modify the workspace arrays CSAVE, ISAVE and DSAVE - * between calls to op_vmlmb_first and further calls to op_vmlmb_next. - * - * A typical invocation of VMLMB for unconstrained minimization has the - * following outline: - * - * // Choose a starting vector: - * for (i=0 ; i XMIN[i] || G[i] < 0) && (X[i] < XMAX[i] || G[i] > 0) */ - -extern op_integer_t op_bounds_check(op_integer_t n, const double xmin[], - const double xmax[]); -/* Check correctness of bounds XMIN and XMAX (see op_bounds_apply for - the definition of the arguments). This function returns -1 if the - bounds are such that XMIN[i] <= XMAX[i] for all i=0,...,N-1; - otherwise, the function return the value i of the first index (i >= - 0) for which the condition is violated. */ - -extern void op_lower_bound_apply(op_integer_t n, double x[], double xmin); -extern void op_lower_bound_active(op_integer_t n, op_logical_t active[], - const double x[], const double g[], - double xmin); -/* These routines are similar to op_bounds_apply and op_bounds_active but - for a scalar lower bound XMIN that is the same for all parameters X. */ - -extern void op_upper_bound_apply(op_integer_t n, double x[], double xmax); -extern void op_upper_bound_active(op_integer_t n, op_logical_t active[], - const double x[], const double g[], - double xmax); -/* These routines are similar to op_bounds_apply and op_bounds_active but - for a scalar upper bound XMAX that is the same for all parameters X. */ - -extern void op_interval_apply(op_integer_t n, double x[], double a, double b); -extern void op_interval_active(op_integer_t n, op_logical_t active[], - const double x[], const double g[], - double a, double b); -/* These routines are similar to op_bounds_apply and op_bounds_active - but for a scalar lower bound XMIN=min(A,B) and a scalar upper bound - XMAX=max(A,B) that are the same for all parameters X. */ - -/*---------------------------------------------------------------------------*/ -/* UTILITIES */ - -#define OP_MSG_LEN 127 -#define OP_MSG_SIZE (OP_MSG_LEN + 1) -extern int op_error(char *buf, const char *errmsg); -/* Copy ERRMSG in BUF and return OP_ERROR. BUF must have at least - OP_MSG_SIZE bytes. At most OP_MSG_SIZE - 1 bytes get copied and BUF is - guaranted to be 0-terminated. */ - -extern void op_mcopy(const char *msg, char *buf); -/* Copy string MSG into BUF (if non-NULL). BUF must have at least - OP_MSG_SIZE bytes. At most OP_MSG_SIZE - 1 bytes get copied and BUF is - guaranted to be 0-terminated. */ - -extern double op_dnrm2(op_integer_t n, const double x[]); -/* Returns the Euclidian norm of X: sqrt(X'.X), taking care of overflows. */ - - -extern void op_dcopy(op_integer_t n, const double x[], double y[]); -extern void op_dcopy_active(op_integer_t n, const double x[], - double y[], const op_logical_t active[]); -/* Copy elements of X into Y. Does Y[i] = X[i] for i=0,...,N-1. If ACTIVE - is non-NULL, only elements for which ACTIVE[i] is true (non-zero) are - taken into account. */ - -extern void op_daxpy(op_integer_t n, double a, - const double x[], double y[]); -extern void op_daxpy_active(op_integer_t n, double a, - const double x[], double y[], - const op_logical_t active[]); -/* Does Y[i] += A*X[i] for i=0,...,N-1. If ACTIVE is non-NULL, only - elements for which ACTIVE[i] is true (non-zero) are taken into - account. */ - -extern double op_ddot(op_integer_t n, const double x[], const double y[]); -extern double op_ddot_active(op_integer_t n, const double x[], - const double y[], const op_logical_t active[]); -/* Computes dot product of N-element vectors X and Y. If ACTIVE is - non-NULL, only elements for which ACTIVE[i] is true (non-zero) are taken - into account. */ - -extern void op_dscal(op_integer_t n, double a, double x[]); -/* Scales N-element vector X by scalar A. */ - -/*---------------------------------------------------------------------------*/ -/* YORICK-LIKE ROUTINES */ - -extern int op_anyof(op_integer_t n, const double x[]); -/* Returns true (non-zero) if any element of X is non-zero; returns faslse - (zero) otherwise. N is the number of elements of X. */ - -extern int op_noneof(op_integer_t n, const double x[]); -/* Returns true (non-zero) if all elements of X are zero; returns faslse - (zero) otherwise. N is the number of elements of X. */ - -extern int op_allof(op_integer_t n, const double x[]); -/* Returns true (non-zero) if all elements of X are non-zero; returns faslse - (zero) otherwise. N is the number of elements of X. */ - -/*---------------------------------------------------------------------------*/ -_OP_END_DECLS -#endif /* _OPTIMPACK_H */ diff -Nru yorick-optimpack-1.3.2+dfsg/op_utils.c yorick-optimpack-1.3.2+dfsg+1.4.0/op_utils.c --- yorick-optimpack-1.3.2+dfsg/op_utils.c 2003-03-21 11:56:56.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/op_utils.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,326 +0,0 @@ -/* - * op_utils -- - * - * Utilities routines for OptimPack library. - * - *----------------------------------------------------------------------------- - * - * Copyright (c) 2003, Eric THIEBAUT. - * - * This file is part of OptimPack. - * - * OptimPack is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2 of the License, - * or (at your option) any later version. - * - * OptimPack is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with OptimPack (file "LICENSE" in the top source directory); - * if not, write to the Free Software Foundation, Inc., 59 Temple - * Place, Suite 330, Boston, MA 02111-1307 USA - * - *----------------------------------------------------------------------------- - * - * $Id$ - * $Log$ - * - *----------------------------------------------------------------------------- - */ - -#include -#include -#include "optimpack.h" - -/*---------------------------------------------------------------------------*/ - -int op_error(char *buf, const char *errmsg) -{ - if (buf) { - if (! errmsg) errmsg = "unknown error"; - strncpy(buf, errmsg, OP_MSG_LEN); - buf[OP_MSG_LEN] = 0; - } - return OP_ERROR; -} - -void op_mcopy(const char *msg, char *buf) -{ - if (buf) { - if (msg) { - strncpy(buf, msg, OP_MSG_LEN); - buf[OP_MSG_LEN] = 0; - } else { - buf[0] = 0; - } - } -} - -/*---------------------------------------------------------------------------*/ -/* APPLY BOUND CONSTRAINTS */ - -#define ACTIVE_LO_GRD(x, lo, g) ((x) > (lo) || (g) < zero) -#define ACTIVE_HI_GRD(x, hi, g) ((x) < (hi) || (g) > zero) -#define ACTIVE_LO_DIR(x, lo, d) ((x) > (lo) || (d) > zero) -#define ACTIVE_HI_DIR(x, hi, d) ((x) < (hi) || (d) < zero) - -op_integer_t op_bounds_check(op_integer_t n, const double xmin[], - const double xmax[]) -{ - op_integer_t i; - if (xmin && xmax) { - for (i=0 ; i xmax[i]) return i; - } - } - return -1; -} - -void op_bounds_apply(op_integer_t n, double x[], - const double xmin[], const double xmax[]) -{ - op_integer_t i; - if (xmin) { - if (xmax) { - /* Lower _and_ upper bounds. */ - for (i=0 ; i xmax[i]) x[i] = xmax[i]; - } - } else { - /* Only lower bounds. */ - for (i=0 ; i xmax[i]) x[i] = xmax[i]; - } - } -} - -void op_bounds_active(op_integer_t n, op_logical_t active[], - const double x[], const double g[], - const double xmin[], const double xmax[]) -{ - const double zero = 0.0; - op_integer_t i; - - if (xmin) { - if (xmax) { - /* Lower _and_ upper bounds. */ - for (i=0 ; i xmax) x[i] = xmax; -} - -void op_upper_bound_active(op_integer_t n, op_logical_t active[], - const double x[], const double g[], - double xmax) -{ - const double zero = 0.0; - op_integer_t i; - for (i=0 ; i b) { double c=a; a=b; b=c; } - for (i=0 ; i b) x[i] = b; - } -} - -void op_interval_active(op_integer_t n, op_logical_t active[], - const double x[], const double g[], - double a, double b) -{ - const double zero = 0.0; - op_integer_t i; - if (a > b) { double c=a; a=b; b=c; } - for (i=0 ; i 1) { - op_integer_t i; - double ssq = zero, scale = zero; - for (i=0 ; i -#include -#include -#include "optimpack.h" - -#define op_dcopy(n, x, y) memcpy((y), (x), (n)*sizeof(double)) - -/*---------------------------------------------------------------------------*/ -/* LIMITED MEMORY VARIABLE METRIC METHOD (BFGS) - WITH/WITHOUT BOUND CONSTRAINTS */ - -/* Indices 0-1 in ISAVE are reserved for op_cshrc. */ -#define INDEX_OF_TASK 2 -#define INDEX_OF_STAGE 3 -#define INDEX_OF_M 4 -#define INDEX_OF_N 5 -#define INDEX_OF_ITER 6 -#define INDEX_OF_MARK 7 -#define INDEX_OF_MP 8 -#define INDEX_OF_FLAGS 9 -#define INDEX_OF_NEVALS 10 -#define INDEX_OF_NRESTARTS 11 -#if (OP_VMLMB_ISAVE_NUMBER != INDEX_OF_NRESTARTS + 1) -# error bad ISAVE settings -#endif - -/* Indices 0-11 in ISAVE are reserved for op_cshrc. */ -#define INDEX_OF_SFTOL 12 -#define INDEX_OF_SGTOL 13 -#define INDEX_OF_SXTOL 14 -#define INDEX_OF_FRTOL 15 -#define INDEX_OF_FATOL 16 -#define INDEX_OF_FMIN 17 -#define INDEX_OF_F0 18 -#define INDEX_OF_GD 19 -#define INDEX_OF_GD0 20 -#define INDEX_OF_STP 21 -#define INDEX_OF_STPMIN 22 -#define INDEX_OF_STPMAX 23 -#define INDEX_OF_EPSILON 24 -#define INDEX_OF_COSTHETA 25 -#define INDEX_OF_DELTA 26 -#define INDEX_OF_WORK 27 /* must be the last one */ -#if (OP_VMLMB_DSAVE_NUMBER(0,0) != INDEX_OF_WORK) -# error bad DSAVE settings -#endif - -#define FLAG(n) (1 << (n)) -#define FLAG_IS_SET(value, flag) (((value) & (flag)) != 0) -#define FLAG_FMIN FLAG(0) -#define FLAG_DELTA FLAG(1) - -#define SET_TASK(val, str) \ - (op_mcopy("op_vmlmb_first: " str, csave), task=(val)) - -int op_vmlmb_first(op_integer_t n, op_integer_t m, - double fatol, double frtol, - double sftol, double sgtol, double sxtol, - double epsilon, double costheta, - char csave[], op_integer_t isave[], double dsave[]) -{ - int task = OP_TASK_FG; - if (n <= 0) return SET_TASK(OP_TASK_ERROR, "N <= 0"); - if (m <= 0) return SET_TASK(OP_TASK_ERROR, "M <= 0"); - if (fatol < 0.0) return SET_TASK(OP_TASK_ERROR, "FATOL < 0"); - if (frtol < 0.0) return SET_TASK(OP_TASK_ERROR, "FRTOL < 0"); - if (sxtol <= 0.0) return SET_TASK(OP_TASK_ERROR, "SXTOL <= 0"); - if (sxtol >= 1.0) return SET_TASK(OP_TASK_ERROR, "SXTOL >= 1"); - if (sftol <= 0.0) return SET_TASK(OP_TASK_ERROR, "SFTOL <= 0"); - if (sftol >= 1.0) return SET_TASK(OP_TASK_ERROR, "SFTOL >= 1"); - if (sgtol <= 0.0) return SET_TASK(OP_TASK_ERROR, "SGTOL <= 0"); - if (sgtol >= 1.0) return SET_TASK(OP_TASK_ERROR, "SGTOL >= 1"); - if (sftol >= sgtol) return SET_TASK(OP_TASK_ERROR, "SFTOL >= SGTOL"); - if (epsilon <= 0.0) return SET_TASK(OP_TASK_ERROR, "EPSILON <= 0"); - if (costheta < 0.0) return SET_TASK(OP_TASK_ERROR, "COSTHETA < 0"); - if (costheta >= 1.0) return SET_TASK(OP_TASK_ERROR, "COSTHETA >= 1"); - - isave[INDEX_OF_TASK] = OP_TASK_FG; - isave[INDEX_OF_STAGE] = 0L; - isave[INDEX_OF_M] = m; - isave[INDEX_OF_N] = n; - isave[INDEX_OF_ITER] = 0L; - isave[INDEX_OF_MARK] = 0L; - isave[INDEX_OF_MP] = 0L; - isave[INDEX_OF_FLAGS] = 0L; - isave[INDEX_OF_NEVALS] = 0L; - isave[INDEX_OF_NRESTARTS] = 0L; - - dsave[INDEX_OF_SFTOL] = sftol; - dsave[INDEX_OF_SGTOL] = sgtol; - dsave[INDEX_OF_SXTOL] = sxtol; - dsave[INDEX_OF_FRTOL] = frtol; - dsave[INDEX_OF_FATOL] = fatol; - dsave[INDEX_OF_FMIN] = 0.0; - dsave[INDEX_OF_F0] = 0.0; - dsave[INDEX_OF_GD] = 0.0; - dsave[INDEX_OF_GD0] = 0.0; - dsave[INDEX_OF_STP] = 0.0; - dsave[INDEX_OF_STPMIN] = 0.0; - dsave[INDEX_OF_STPMAX] = 0.0; - dsave[INDEX_OF_EPSILON] = epsilon; - dsave[INDEX_OF_COSTHETA] = costheta; - dsave[INDEX_OF_DELTA] = 0.0; - - return isave[INDEX_OF_TASK]; -} -#undef SET_TASK - -/*---------------------------------------------------------------------------*/ - -static int check_active(op_integer_t n, op_logical_t active[], const double h[], - int *task, char csave[]); -/* Check H and ACTIVE arrays, possibly fix ACTIVE, returns non-zero - in case of error. */ - -#define S(K) &s[(K)*n] -#define Y(K) &y[(K)*n] -#define SET_TASK(val, str) (op_mcopy("op_vmlmb_next: " str, csave), task=(val)) - -int op_vmlmb_next(double x[], double *f, double g[], - op_logical_t active[], const double h[], - char csave[], op_integer_t isave[], double dsave[]) -{ - const double zero = 0.0; - - /* Get local variables. (Note: depending on the value of STAGE, it is - possible to restore only _some_ of theses variables, but this would - result in a less readable code with negligible speedup gain.) */ - int task = isave[INDEX_OF_TASK]; - int stage = isave[INDEX_OF_STAGE]; - op_integer_t m = isave[INDEX_OF_M]; - op_integer_t n = isave[INDEX_OF_N]; - op_integer_t iter = isave[INDEX_OF_ITER]; - op_integer_t mark = isave[INDEX_OF_MARK]; - op_integer_t mp = isave[INDEX_OF_MP]; - op_integer_t flags = isave[INDEX_OF_FLAGS]; - op_integer_t nevals = isave[INDEX_OF_NEVALS]; - op_integer_t nrestarts = isave[INDEX_OF_NRESTARTS]; - int have_fmin = ((flags & FLAG_FMIN) != 0); - int delta_set = ((flags & FLAG_DELTA) != 0); - - double sftol = dsave[INDEX_OF_SFTOL]; - double sgtol = dsave[INDEX_OF_SGTOL]; - double sxtol = dsave[INDEX_OF_SXTOL]; - double fmin = (have_fmin ? dsave[INDEX_OF_FMIN] : zero); - double frtol = dsave[INDEX_OF_FRTOL]; - double fatol = dsave[INDEX_OF_FATOL]; - double f0 = dsave[INDEX_OF_F0]; - double gd = dsave[INDEX_OF_GD]; - double gd0 = dsave[INDEX_OF_GD0]; - double stp = dsave[INDEX_OF_STP]; - double stpmin = dsave[INDEX_OF_STPMIN]; - double stpmax = dsave[INDEX_OF_STPMAX]; - double epsilon = dsave[INDEX_OF_EPSILON]; - double costheta = dsave[INDEX_OF_COSTHETA]; - double delta = (delta_set ? dsave[INDEX_OF_DELTA] : zero); - /*double delta = dsave[INDEX_OF_DELTA];*/ - - double gpnorm, xnorm, snorm; - - double *alpha = dsave + INDEX_OF_WORK; - double *rho = alpha + m; - double *x0 = rho + m; - double *s = x0 + n; - double *y = s + n*m; - double *ptr; - int info; - op_integer_t i, j, k; - - /* - * Differences with original FORTRAN version: - * - * (5) The effective step is used instead of the search direction times - * the step size (useful, e.g., when parameter constraints are imposed - * by projections or when rounding or truncation errors dominate). - * - * (6) It is possible to use an active subset of parameters, e.g. to apply - * bound constraints. - * - * (7) Discard pairs for which RHO = S'.Y <= 0 (i.e. H must be positive - * definite). - * - * STAGE is: 0 - first entry - * 1 - start line search - * 2 - line search in progress - * 3 - line search converged - * - * S(MARK) = -D(k) where D(k) is the k-th search direction and MARK is - * current iteration index (modulo M). - */ - - if (task == OP_TASK_FG) { - ++nevals; - } - - if (stage == 0) { - /* First search direction is the (normalized) steepest descent. */ - if (have_fmin && *f <= fmin) { - SET_TASK(OP_TASK_ERROR, "initial F <= FMIN"); - goto done; - } - iter = 0L; /* number of successful iterations */ - nevals = 1L; - nrestarts = 0L; - restart: - mark = 0; /* index of current direction */ - mp = 0; /* number of saved directions */ - if (check_active(n, active, h, &task, csave) != 0) goto done; - op_dcopy_active(n, g, S(mark), active); /* steepest ascent */ - gpnorm = op_dnrm2(n, S(mark)); /* norm of the projected gradient */ - if (gpnorm == zero) { - SET_TASK(OP_TASK_CONV, "local minimum found"); - goto done; - } - if (h == NULL) { - /* No preconditioning, use scaled steepest ascent. */ - xnorm = op_dnrm2(n, x); - if (xnorm > zero) { /* FIXME: use parameter (not constant) and better test */ - snorm = 1E-2*xnorm; - } else { - snorm = 1.0; - } - op_dscal(n, snorm/gpnorm, S(mark)); - gd = -snorm*gpnorm; - } else { - /* Use diagonal preconditioner to compute initial search direction. */ - for (ptr = S(mark), i = 0; i < n; ++i) { - ptr[i] *= h[i]; - } - gd = -op_ddot(n, g, S(mark)); - if (gd >= zero) { - SET_TASK(OP_TASK_ERROR, "preconditioner is not positive definite"); - goto done; - } - } - stage = 1; /* set STAGE to initialize the line search */ - - } else if (stage == 3) { - - /* Previous step was successful. Compute new search direction H(k).g(k) - * based on the two-loop recursion L-BFGS formula. H(k) is the limited - * memory BFGS approximation of the inverse Hessian, g(k) is the - * gradient at k-th step. H(k) is approximated by using the M last - * pairs (s, y) where: - * - * s(j) = x(j+1) - x(j) - * y(j) = g(j+1) - g(j) - * - * The two-loop recursion algorithm writes: - * - * 1- start with current gradient: - * v := g(k) - * - * 2- for j = k-1, ..., k-m - * rho(j) = s(j)'.y(j) (save rho(j)) - * alpha(j) = (s(j)'.v)/rho(j) (save alpha(j)) - * v := v - alpha(j) y(j) - * - * 3- apply approximation of inverse k-th Hessian: - * v := H0(k).v - * for instance: - * v := (rho(k-1)/(y(k-1)'.y(k-1))) v - * - * 4- for j = k-m, ..., k-1 - * v := v + (alpha(j) - (y(j)'.v)/rho(j)) s(j) - * - * Note: in fact, this program saves -S and -Y, but by looking at - * above relations it is clear that this change of sign: - * - has no influence on RHO, and dot products between S and Y; - * - changes the sign of ALPHA but not that of ALPHA(j) times - * S(j) or Y(j); - * the two-loop recursion therefore involves the same equations - * with: s(j) = x(j+1) - x(j) and y(j) = g(j+1) - g(j) - * or with: s(j) = x(j) - x(j+1) and y(j) = g(j) - g(j+1). - */ - double *v = x0; - double gamma = zero; - op_integer_t mm = mark + m; - - if (check_active(n, active, h, &task, csave) != 0) goto done; - op_dcopy_active(n, g, v, active); - for (k = 0; k < mp; ++k) { - j = (mm - k)%m; - if (active != NULL) rho[j] = op_ddot_active(n, S(j), Y(j), active); - if (rho[j] <= zero) continue; /* FIXME: should be relative to |y|^2 or |s|^2 */ - alpha[j] = op_ddot(n, S(j), v)/rho[j]; - op_daxpy_active(n, -alpha[j], Y(j), v, active); - if (gamma <= zero) gamma = rho[j]/op_ddot_active(n, Y(j), Y(j), active); - } - if (h != NULL) { - /* Apply diagonal preconditioner. */ - for (i = 0; i < n; ++i) { - v[i] *= h[i]; - } - } else if (gamma > zero) { - /* Apply initial H (i.e. just scale V) and perform the second stage of - the 2-loop recursion. */ - op_dscal(n, gamma, v); - } else { - /* All correction pairs are invalid: restart the BFGS recursion. */ - ++nrestarts; - goto restart; - } - for (k = mp - 1; k >= 0; --k) { - j = (mm - k)%m; - if (rho[j] <= zero) continue; /* FIXME: see above */ - op_daxpy_active(n, alpha[j] - op_ddot(n, Y(j), v)/rho[j], - S(j), v, active); - } - - /* Compute dot product of gradient and search direction. */ - gd = -op_ddot(n, g, v); /* FIXME: should be GP? */ - if (gd >= zero) { - /* L-BFGS recursion yields a search direction which is not a descent. - We therefore restart the algorithm with steepest descent. */ - ++nrestarts; - goto restart; - } - - /* Save anti-search direction (in place of oldest memorized S). */ - mark = (mark + 1)%m; - op_dcopy(n, v, S(mark)); - - /* Set STAGE to initialize the line search. */ - stage = 1; - - } else /* FIXME: check stage? */ { - /* Line search in progress: compute derivative with respect to step - size. */ - gd = -op_ddot(n, g, S(mark)); /* FIXME: should be GP? */ - } - - if (stage == 1) { - /* Set variables so as to initialize the line search subroutine. */ - f0 = *f; - gd0 = gd; - stpmin = zero; -#if 1 - stpmax = 1E10; /* FIXME: use a suitable value */ -#else - if (have_fmin) { - stpmax = (fmin - f0)/(sgtol*gd0); - } else { - double temp = fabs(f0); - if (temp < 1.0) { - temp = 1.0; - } - stpmax = temp/(sgtol*gd0); - } -#endif - stp = OP_MIN(1.0, stpmax); - op_dcopy(n, x, x0); /* save parameters */ - op_dcopy(n, g, Y(mark)); /* save gradient in place of oldest Y */ - stage = 2; - task = OP_TASK_START; /* set TASK so as to start line search */ - } else { - task = OP_TASK_FG; /* set TASK so as to continue line search */ - } - - if (stage == 2) { - /* Determine the line search parameter. */ - if (have_fmin && *f < fmin) { - SET_TASK(OP_TASK_WARN, "F < FMIN"); - } else { - /* Call line search iterator. */ - info = op_csrch(*f, gd, &stp, sftol, sgtol, sxtol, stpmin, stpmax, &task, - csave, isave, dsave); - if (info == 1) { - /* Compute the new iterate. */ - for (ptr = S(mark), i = 0; i < n; ++i) { - /* FIXME: use DCOPY and DAXPY */ - x[i] = x0[i] - stp*ptr[i]; - } - } else if (info == 2 || info == 5) { - /* Line search has converged. */ - ++iter; - if (mp < m) ++mp; - stage = 3; - - /* Compute the step and gradient change. Note: we always compute the - effective step (parameter difference) to account for bound - constraints and, at least, numerical rounding or truncation - errors. */ - for (ptr = Y(mark), i = 0; i < n; ++i) ptr[i] -= g[i]; - for (ptr = S(mark), i = 0; i < n; ++i) ptr[i] = x0[i] - x[i]; - if (active == NULL) rho[mark] = op_ddot(n, Y(mark), S(mark)); - - /* Test for global convergence otherwise set TASK to signal a new - iterate. Set STAGE to compute a new search direction. */ - if (op_noneof(n, S(mark))) { - SET_TASK(OP_TASK_WARN, "no parameter change"); - } else if (op_noneof(n, Y(mark))) { - SET_TASK(OP_TASK_WARN, "no gradient change"); - } else { - double change1 = fabs(*f - f0); - double change2 = fabs(stp*gd0); - double change = OP_MAX(change1, change2); - if (change <= frtol*fabs(f0)) { - SET_TASK(OP_TASK_CONV, "FRTOL test satisfied"); - } else if (change <= fatol) { - SET_TASK(OP_TASK_CONV, "FATOL test satisfied"); - } else { - SET_TASK(OP_TASK_NEWX, - "new improved solution available for inspection"); - } - } - } else if (info >= 3) { - /* INFO >= 3 means that line search could not converge. - Restore solution at start of line search. */ - op_dcopy(n, x0, x); - op_dcopy(n, Y(mark), g); - *f = f0; - } - } - } - - /* Save local variables (but constant ones) and return TASK. */ - done: - isave[INDEX_OF_TASK] = task; /* FIXME: task not needed, for debug only? */ - isave[INDEX_OF_STAGE] = stage; - isave[INDEX_OF_ITER] = iter; - isave[INDEX_OF_MARK] = mark; - isave[INDEX_OF_MP] = mp; -#if 0 - isave[INDEX_OF_FLAGS] = flags; /* constant */ -#endif - isave[INDEX_OF_NEVALS] = nevals; - isave[INDEX_OF_NRESTARTS] = nrestarts; - -#if 0 - dsave[INDEX_OF_SFTOL] = sftol; /* constant */ - dsave[INDEX_OF_SGTOL] = sgtol; /* constant */ - dsave[INDEX_OF_SXTOL] = sxtol; /* constant */ - dsave[INDEX_OF_FRTOL] = frtol; /* constant */ - dsave[INDEX_OF_FATOL] = fatol; /* constant */ - dsave[INDEX_OF_FMIN] = fmin; /* constant */ -#endif - dsave[INDEX_OF_F0] = f0; - dsave[INDEX_OF_GD] = gd; - dsave[INDEX_OF_GD0] = gd0; - dsave[INDEX_OF_STP] = stp; - dsave[INDEX_OF_STPMIN] = stpmin; - dsave[INDEX_OF_STPMAX] = stpmax; -#if 0 - dsave[INDEX_OF_EPSILON] = epsilon; /* constant */ - dsave[INDEX_OF_COSTHETA] = costheta; /* constant */ -#endif - return task; -} - -#undef SET_TASK -#undef Y -#undef S - -/*---------------------------------------------------------------------------*/ - -static int check_active(op_integer_t n, op_logical_t active[], - const double h[], int *task, char csave[]) -{ - if (h != NULL) { - const double zero = 0.0; - op_integer_t i; - if (active != NULL) { - /* fix ACTIVE array */ - for (i = 0; i < n; ++i) { - if (active[i] && h[i] <= zero) { - active[i] = 0; - } - } - } else { - /* check that H is positive definite */ - for (i = 0; i < n; ++i) { - if (h[i] <= zero) { - op_mcopy("op_vmlmb_next: H is not positive definite", csave); - *task = OP_TASK_ERROR; - return -1; - } - } - - } - } - return 0; -} - -/*---------------------------------------------------------------------------*/ - -#define EMIT_CODE(name, NAME) \ -int op_vmlmb_set_##name(const char csave[], op_integer_t isave[], \ - double dsave[], double new_value, double *old_value) \ -{ \ - int test = ((isave[INDEX_OF_FLAGS] & FLAG_##NAME) != 0); \ - if (test && old_value != (double *)NULL) { \ - *old_value = dsave[INDEX_OF_##NAME]; \ - } \ - dsave[INDEX_OF_##NAME] = new_value; \ - isave[INDEX_OF_FLAGS] |= FLAG_##NAME; \ - return test; \ -} \ -int op_vmlmb_get_##name(const char csave[], const op_integer_t isave[], \ - const double dsave[], double *ptr) \ -{ \ - int test = ((isave[INDEX_OF_FLAGS] & FLAG_##NAME) != 0); \ - if (test && ptr != (double *)NULL) { \ - *ptr = dsave[INDEX_OF_##NAME]; \ - } \ - return test; \ -} -EMIT_CODE(fmin, FMIN) -EMIT_CODE(delta, DELTA) -#undef EMIT_CODE - -#define EMIT_CODE(type, foo, FOO, save) \ -type OP_CONCAT(op_vmlmb_get_,foo)(const char csave[], \ - const op_integer_t isave[], \ - const double dsave[]) \ -{ return dsave[OP_CONCAT(INDEX_OF_,FOO)]; } -EMIT_CODE(double, sftol, SFTOL, dsave) -EMIT_CODE(double, sgtol, SGTOL, dsave) -EMIT_CODE(double, sxtol, SXTOL, dsave) -EMIT_CODE(double, frtol, FRTOL, dsave) -EMIT_CODE(double, fatol, FATOL, dsave) -EMIT_CODE(double, step, STP, dsave) -EMIT_CODE(double, epsilon, EPSILON, dsave) -EMIT_CODE(double, costheta, COSTHETA, dsave) -EMIT_CODE(op_integer_t, iter, ITER, isave) -EMIT_CODE(op_integer_t, nevals, NEVALS, isave) -EMIT_CODE(op_integer_t, nrestarts, NRESTARTS, isave) -#undef EMIT_CODE - -/*---------------------------------------------------------------------------*/ - -/* - * Local Variables: - * mode: C - * tab-width: 8 - * c-basic-offset: 2 - * fill-column: 78 - * coding: latin-1 - * End: - */ diff -Nru yorick-optimpack-1.3.2+dfsg/README yorick-optimpack-1.3.2+dfsg+1.4.0/README --- yorick-optimpack-1.3.2+dfsg/README 2008-01-31 15:03:36.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/README 1970-01-01 00:00:00.000000000 +0000 @@ -1,109 +0,0 @@ - - OptimPack - (version 1.3) - by Eric Thiébaut - - - This is OptimPack, a C library for optimization. This version - implements: - - - inexact line search (see ref. [1]); - - - limited memory BFGS (variable metric) possibly with bound constraints - and/or preconditioning; - - In order to make embedding OptimPack into another language as easy as - possible, the routines use reverse communication: all local variables - needed by the optimization routines get saved into workspace arrays - provided by the caller and the optimization routines never explicitely - call the penalty function to optimize. - - Most of the documention is in the header file "optimpack.h". - - Directory idl contains an implementation of OptimPack support in IDL - (using CALL_EXTERNAL). - - Directory yorick contains an implementation of OptimPack support in - Yorick. - - -REFERENCES - - [1] Jorge J. Moré and David J. Thuente, "Line search algorithms with - guaranteed sufficient decrease" in ACM Transactions on Mathematical - Software (TOMS) Volume 20, Issue 3, Pages 286-307 (September 1994). - - -INSTALLATION - - 1. Edit the Makefile (see "Portability Issues" below). - - 2. Compile the library: - - make - - 3. Optionaly install the software, for instance: - - make PREFIX=/usr/local install - - which will copy: - - liboptimpack.a into /usr/local/lib - optimpack.h into /usr/local/include - - and creates directory /usr/local/doc/OptimPack-$VERSION with some - documentation and legal stuff. - - -YORICK INSTALLATION - - 1. Go to directory "yorick". - - 2. Edit the very first part of Makefile whether you want or don't want - support for LBFGS and LBFGSB algorithms. - - 3. Setup for compilation and compile the plugin code: - - yorick -batch make.i - make clean - make - - 4. Optionaly install plugin in Yorick tree: - - make install - - -PORTABILITY ISSUES - - OptimPack is written in standard ANSI-C and should pose no problem of - portability. However, in order to match the data types used in your - software, you may have to set the values of the following macros: - - OP_INTEGER = data type used to store array indices - OP_LOGICAL = data type of the result of a logical test - - This must be done _before_ "optimpack.h" get included. If these macros - are not defined, the default assumed in "optimpack.h" is: - - OP_INTEGER = int - OP_LOGICAL = int - - For instance, one should write: - - #define OP_INTEGER long - #define OP_LOGICAL int - #include "optimpack.h" - ... - - Of course, the installed OptimPack library must have been compiled with - the correct data types. Another possibility is to define these macros - when calling CPP (the C preprocessor) e.g. in Makefile: - - CPPFLAGS = -DOP_INTEGER=long -DOP_LOGICAL=int -I. - - a final possibility is to edit "optimpack.h" and to adjust the default - values of these macros (at the very beginning of this file). If you plan - to install in your system, the best is probably to fix the definitions in - "optimpack.h", then compile the library and finally install the library - and the header file "optimpack.h" in proper system directories (e.g. with - "make install PREFIX=..."). diff -Nru yorick-optimpack-1.3.2+dfsg/README.md yorick-optimpack-1.3.2+dfsg+1.4.0/README.md --- yorick-optimpack-1.3.2+dfsg/README.md 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/README.md 2017-01-10 22:16:57.000000000 +0000 @@ -0,0 +1,111 @@ +# OptimPackLegacy (version 1) + +This is **OptimPackLegacy**, a C library for optimization of large scale +problems possibly with bound constraints. This version implements: + +- Moré and Thuente method for inexact line search; + +- VMLMB algorithm by Éric Thiébaut which is a limited memory BFGS (variable + metric) method possibly with bound constraints and/or preconditioning. + +In order to make embedding OptimPackLegacy into another language as easy as +possible, the routines use reverse communication: all local variables needed by +the optimization routines get saved into workspace structures (allocated by the +library or provided by the caller) and the optimization routines never +explicitely call the penalty function to optimize. + +Most of the documention is in the header file +[optimpacklegacy.h](src/optimpacklegacy.h). + +Another version of OptimPack is under development and available +[here](https://github.com/emmt/OptimPack). This new version implements a +completely different memory management system to be more flexible and allow for +various kinds of storage (standard memory, distributed memory, GPU, *etc.*). + +Directory [yorick](yorick) contains an implementation of OptimPack support in +Yorick. + + +## References + +* Jorge J. Moré and David J. Thuente, "*Line search algorithms with guaranteed + sufficient decrease*" in ACM Transactions on Mathematical Software (TOMS) + Volume **20**, Issue 3, Pages 286-307 (September 1994). + +* Éric Thiébaut, "*Optimization issues in blind deconvolution algorithms*", + SPIE Conf. Astronomical Data Analysis II, **4847**, 174-183 (2002). + + +## Installation + +To install the library (not needed for Yorick nor for IDL): + +1. Edit the file `src/Makefile` (see "Portability Issues" below). + +2. Compile the library: + + cd src + make + +3. Optionaly install the software, for instance: + + make PREFIX=/usr/local install + + which will copy: + + liboptimpacklegacy.a into /usr/local/lib + optimpacklegacy.h into /usr/local/include + + and creates directory `/usr/local/doc/OptimPack-${VERSION}` with some + documentation and legal stuff. + + +## Yorick Installation + +1. Go to directory `yorick`. + +2. Setup for compilation and compile the plugin code: + + yorick -batch make.i + make clean + make + +3. Optionaly install plugin in Yorick tree: + + make install + + +## Portability Issues + +OptimPackLegacy is written in standard ANSI-C and should pose no problem of +portability. However, in order to match the data types used in your software, +you may have to set the values of the following macros: + + OPL_INTEGER = data type used to store array indices + OPL_LOGICAL = data type of the result of a logical test + +This must be done *before* `optimpacklegacy.h` get included. If these macros +are not defined, the default assumed in `optimpacklegacy.h` is: + + OPL_INTEGER = int + OPL_LOGICAL = int + +For instance, one should write: + + #define OPL_INTEGER long + #define OPL_LOGICAL int + #include "optimpacklegacy.h" + ... + +Of course, the installed OptimPackLegacy library must have been compiled with +the correct data types. Another possibility is to define these macros when +calling CPP (the C preprocessor), *e.g.* in `src/Makefile`: + + CPPFLAGS = -DOPL_INTEGER=long -DOPL_LOGICAL=int -I. + +a final possibility is to edit `optimpacklegacy.h` and to adjust the default +values of these macros (at the very beginning of this file). If you plan to +install in your system, the best is probably to fix the definitions in +`optimpacklegacy.h`, then compile the library and finally install the library +and the header file `optimpacklegacy.h` in proper system directories (*e.g.* +with `make install PREFIX=...`). diff -Nru yorick-optimpack-1.3.2+dfsg/src/Makefile yorick-optimpack-1.3.2+dfsg+1.4.0/src/Makefile --- yorick-optimpack-1.3.2+dfsg/src/Makefile 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/src/Makefile 2017-01-10 22:16:57.000000000 +0000 @@ -0,0 +1,77 @@ +# +# Makefile -- +# +# Makefile for OptimPackLegacy. +# +#------------------------------------------------------------------------------ +# +# Copyright (c) 2003, 2016 Éric Thiébaut. +# +# This file is part of OptimPack . +# +# OptimPack is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# OptimPack is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with OptimPack (file "LICENSE" in the top source directory); if not, +# write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, +# Boston, MA 02111-1307 USA +# +#------------------------------------------------------------------------------ + +srcdir = . + +PREFIX = +DESTDIR = +INSTALL = cp -p + +CC = gcc -pipe +#CPPFLAGS = -I. -DOP_INTEGER=long -DOP_LOGICAL=int +CPPFLAGS = -I. +CFLAGS = -O2 -Wall + +RM = rm -f +AR = ar +ARFLAGS = rv + +LIBNAME = liboptimpacklegacy.a +VERSION = `sed < $(srcdir)/../VERSION -e 's/ //g'` +OBJS = opl_algebra.o opl_lnsrch.o opl_utils.o opl_vmlmb.o + +all: $(LIBNAME) + +install: $(LIBNAME) + @version=$(VERSION); \ + if test "x$(PREFIX)" = "x"; then \ + echo "You must define PREFIX macro, e.g.:"; \ + echo " > make PREFIX=/usr/local install"; \ + else \ + test -d "$(PREFIX)/lib" || mkdir -p "$(PREFIX)/lib"; \ + $(INSTALL) $(LIBNAME) "$(PREFIX)/lib/."; \ + test -d "$(PREFIX)/include" || mkdir -p "$(PREFIX)/include"; \ + $(INSTALL) optimpacklegacy.h "$(PREFIX)/include/."; \ + test -d "$(PREFIX)/doc/OptimPack-$${version}" || \ + mkdir -p "$(PREFIX)/doc/OptimPack-$${version}"; \ + $(INSTALL) $(srcdir)/../README.md $(srcdir)/../AUTHORS \ + $(srcdir)/../LICENSE $(srcdir)/optimpacklegacy.h \ + "$(PREFIX)/doc/OptimPack-$${version}/."; \ + fi + +clean: + $(RM) *~ $(OBJS) $(LIBNAME) + +distclean: clean + +$(LIBNAME): $(OBJS) + $(RM) $(LIBNAME) + $(AR) $(ARFLAGS) $(LIBNAME) $(OBJS) + +%.o: %.c opl_private.h optimpacklegacy.h + $(CC) $(CFLAGS) $(CPPFLAGS) -c $(@:.o=.c) -o $@ diff -Nru yorick-optimpack-1.3.2+dfsg/src/opl_algebra.c yorick-optimpack-1.3.2+dfsg+1.4.0/src/opl_algebra.c --- yorick-optimpack-1.3.2+dfsg/src/opl_algebra.c 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/src/opl_algebra.c 2017-01-10 22:16:57.000000000 +0000 @@ -0,0 +1,374 @@ +/* + * opl_algebra.c -- + * + * Basic linear algebra routines for OptimPackLegacy library. + * + *----------------------------------------------------------------------------- + * + * Copyright (c) 2003, 2016 Éric Thiébaut. + * + * This file is part of OptimPack . + * + * OptimPack is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * OptimPack is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * OptimPack (file "LICENSE" in the top source directory); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + *----------------------------------------------------------------------------- + */ + +#include +#include +#include "opl_private.h" + +/*---------------------------------------------------------------------------*/ +/* APPLY BOUND CONSTRAINTS */ + +#define ISFREE_LO_GRD(x, lo, g) ((x) > (lo) || (g) < zero) +#define ISFREE_HI_GRD(x, hi, g) ((x) < (hi) || (g) > zero) +#define ISFREE_LO_DIR(x, lo, d) ((x) > (lo) || (d) > zero) +#define ISFREE_HI_DIR(x, hi, d) ((x) < (hi) || (d) < zero) + +opl_integer_t opl_bounds_check(opl_integer_t n, const double xmin[], + const double xmax[]) +{ + opl_integer_t i; + if (xmin && xmax) { + for (i = 0; i < n; ++i) { + if (xmin[i] > xmax[i]) { + return i; + } + } + } + return -1; +} + +void opl_bounds_apply(opl_integer_t n, double x[], + const double xmin[], const double xmax[]) +{ + opl_integer_t i; + if (xmin) { + if (xmax) { + /* Lower _and_ upper bounds. */ + for (i = 0; i < n; ++i) { + if (x[i] < xmin[i]) { + x[i] = xmin[i]; + } + if (x[i] > xmax[i]) { + x[i] = xmax[i]; + } + } + } else { + /* Only lower bounds. */ + for (i = 0; i < n; ++i) { + if (x[i] < xmin[i]) { + x[i] = xmin[i]; + } + } + } + } else if (xmax) { + /* Only upper bounds. */ + for (i = 0; i < n; ++i) { + if (x[i] > xmax[i]) { + x[i] = xmax[i]; + } + } + } +} + +void opl_bounds_free(opl_integer_t n, opl_logical_t isfree[], + const double x[], const double g[], + const double xmin[], const double xmax[]) +{ + const double zero = 0.0; + opl_integer_t i; + + if (xmin) { + if (xmax) { + /* Lower _and_ upper bounds. */ + for (i = 0; i < n; ++i) { + isfree[i] = (ISFREE_LO_GRD(x[i], xmin[i], g[i]) && + ISFREE_HI_GRD(x[i], xmax[i], g[i])); + } + } else { + /* Only lower bounds. */ + for (i = 0; i < n; ++i) { + isfree[i] = ISFREE_LO_GRD(x[i], xmin[i], g[i]); + } + } + } else if (xmax) { + /* Only upper bounds. */ + for (i = 0; i < n; ++i) { + isfree[i] = ISFREE_HI_GRD(x[i], xmax[i], g[i]); + } + } +} + +void opl_lower_bound_apply(opl_integer_t n, double x[], double xmin) +{ + opl_integer_t i; + for (i = 0; i < n; ++i) { + if (x[i] < xmin) { + x[i] = xmin; + } + } +} + +void opl_lower_bound_free(opl_integer_t n, opl_logical_t isfree[], + const double x[], const double g[], + double xmin) +{ + const double zero = 0.0; + opl_integer_t i; + for (i = 0; i < n; ++i) { + isfree[i] = ISFREE_LO_GRD(x[i], xmin, g[i]); + } +} + +void opl_upper_bound_apply(opl_integer_t n, double x[], double xmax) +{ + opl_integer_t i; + for (i = 0; i < n; ++i) { + if (x[i] > xmax) { + x[i] = xmax; + } + } +} + +void opl_upper_bound_free(opl_integer_t n, opl_logical_t isfree[], + const double x[], const double g[], + double xmax) +{ + const double zero = 0.0; + opl_integer_t i; + for (i = 0; i < n; ++i) { + isfree[i] = ISFREE_HI_GRD(x[i], xmax, g[i]); + } +} + +void opl_interval_apply(opl_integer_t n, double x[], double a, double b) +{ + opl_integer_t i; + if (a > b) { + double c = a; + a = b; + b = c; + } + for (i = 0; i < n; ++i) { + if (x[i] < a) x[i] = a; + if (x[i] > b) x[i] = b; + } +} + +void opl_interval_free(opl_integer_t n, opl_logical_t isfree[], + const double x[], const double g[], + double a, double b) +{ + const double zero = 0.0; + opl_integer_t i; + if (a > b) { double c=a; a=b; b=c; } + for (i = 0; i < n; ++i) { + isfree[i] = (ISFREE_LO_GRD(x[i], a, g[i]) && + ISFREE_HI_GRD(x[i], b, g[i])); + } +} + +/*---------------------------------------------------------------------------*/ +/* VARIANTS OF LEVEL 1 BLAS ROUTINES */ + +double opl_dnrm2(opl_integer_t n, const double x[]) +{ + const double one = 1.0, zero = 0.0; + if (n > 1) { + opl_integer_t i; + double ssq = zero, scale = zero; + for (i = 0; i < n; ++i) { + if (x[i]) { + double absxi = fabs(x[i]); + if (scale < absxi) { + double tmp = scale/absxi; + ssq = one + ssq*tmp*tmp; + scale = absxi; + } else { + double tmp = absxi/scale; + ssq += tmp*tmp; + } + } + } + return scale*sqrt(ssq); + } else if (n == 1) { + return fabs(x[0]); + } + return zero; +} + +void opl_dscal(opl_integer_t n, double a, double x[]) +{ + opl_integer_t i; + if (a == 0.0) { + memset(x, 0, n*sizeof(double)); + } else if (a == -1.0) { + for (i = 0; i < n; ++i) { + x[i] -= x[i]; + } + } else if (a != 1.0) { + for (i = 0; i < n; ++i) { + x[i] *= a; + } + } +} + +void opl_dcopy(opl_integer_t n, const double x[], double y[]) +{ + memcpy(y, x, n*sizeof(double)); +} + +void opl_dcopy_free(opl_integer_t n, const double x[], double y[], + const opl_logical_t isfree[]) +{ + if (isfree != NULL) { + const double zero = 0.0; + opl_integer_t i; + for (i = 0; i < n; ++i) { + y[i] = (isfree[i] ? x[i] : zero); + } + } else { + memcpy(y, x, n*sizeof(double)); + } +} + +void opl_daxpy(opl_integer_t n, double a, const double x[], double y[]) +{ + opl_integer_t i; + if (a == 1.0) { + for (i = 0; i < n; ++i) { + y[i] += x[i]; + } + } else if (a == -1.0) { + for (i = 0; i < n; ++i) { + y[i] -= x[i]; + } + } else if (a != 0.0) { + for (i = 0; i < n; ++i) { + y[i] += a*x[i]; + } + } +} + +void opl_daxpy_free(opl_integer_t n, double a, const double x[], + double y[], const opl_logical_t isfree[]) +{ + opl_integer_t i; + if (isfree != NULL) { + if (a == 1.0) { + for (i = 0; i < n; ++i) { + if (isfree[i]) { + y[i] += x[i]; + } + } + } else if (a == -1.0) { + for (i = 0; i < n; ++i) { + if (isfree[i]) { + y[i] -= x[i]; + } + } + } else if (a != 0.0) { + for (i = 0; i < n; ++i) { + if (isfree[i]) { + y[i] += a*x[i]; + } + } + } + } else { + if (a == 1.0) { + for (i = 0; i < n; ++i) { + y[i] += x[i]; + } + } else if (a == -1.0) { + for (i = 0; i < n; ++i) { + y[i] -= x[i]; + } + } else if (a != 0.0) { + for (i = 0; i < n; ++i) { + y[i] += a*x[i]; + } + } + } +} + +double opl_ddot(opl_integer_t n, const double x[], const double y[]) +{ + opl_integer_t i; + double s = 0.0; + for (i = 0; i < n; ++i) { + s += x[i]*y[i]; + } + return s; +} + +double opl_ddot_free(opl_integer_t n, const double x[], const double y[], + const opl_logical_t isfree[]) +{ + opl_integer_t i; + double s = 0.0; + if (isfree != NULL) { + for (i = 0; i < n; ++i) { + if (isfree[i]) { + s += x[i]*y[i]; + } + } + } else { + for (i = 0; i < n; ++i) { + s += x[i]*y[i]; + } + } + return s; +} + +/*---------------------------------------------------------------------------*/ +/* YORICK-LIKE ROUTINES */ + +int opl_anyof(opl_integer_t n, const double x[]) +{ + opl_integer_t i; + for (i = 0; i < n; ++i) { + if (x[i]) { + return 1; + } + } + return 0; +} + +int opl_noneof(opl_integer_t n, const double x[]) +{ + opl_integer_t i; + for (i = 0; i < n; ++i) { + if (x[i]) { + return 0; + } + } + return 1; +} + +int opl_allof(opl_integer_t n, const double x[]) +{ + opl_integer_t i; + for (i = 0; i < n; ++i) { + if (! x[i]) { + return 0; + } + } + return 1; +} + +/*---------------------------------------------------------------------------*/ diff -Nru yorick-optimpack-1.3.2+dfsg/src/opl_limits.h yorick-optimpack-1.3.2+dfsg+1.4.0/src/opl_limits.h --- yorick-optimpack-1.3.2+dfsg/src/opl_limits.h 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/src/opl_limits.h 2017-01-10 22:16:57.000000000 +0000 @@ -0,0 +1,156 @@ +/* + * opl_limits.h -- + * + * Definitions to guess sizes of integers on this machine. + * + *----------------------------------------------------------------------------- + * + * Copyright (c) 2003, 2016 Éric Thiébaut. + * + * This file is part of OptimPack . + * + * OptimPack is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * OptimPack is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * OptimPack (file "LICENSE" in the top source directory); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + *----------------------------------------------------------------------------- + */ + +#ifndef _OPL_LIMITS_H +#define _OPL_LIMITS_H 1 + +#include + +#define OPL_INT16_MIN (-32768) +#define OPL_INT16_MAX 32767 +#define OPL_UINT16_MAX 65535 + +#define OPL_INT32_MIN (-2147483648L) +#define OPL_INT32_MAX 2147483647L +#define OPL_UINT32_MAX 4294967295U + +#define OPL_INT64_MIN (-9223372036854775808L) +#define OPL_INT64_MAX 9223372036854775807L +#define OPL_UINT64_MAX 18446744073709551615UL + +#if ! defined (OPL_SHRT_BITS) && defined(USHRT_MAX) +# if (USHRT_MAX == OPL_UINT16_MAX) +# define OPL_SHRT_BITS 16 +# else +# if (USHRT_MAX == OPL_UINT32_MAX) +# define OPL_SHRT_BITS 32 +# else +# if (USHRT_MAX == OPL_UINT64_MAX) +# define OPL_SHRT_BITS 64 +# endif +# endif +# endif +#endif +#if ! defined (OPL_SHRT_BITS) && defined(SHRT_MIN) && defined(SHRT_MAX) +# if (SHRT_MIN == OPL_INT16_MIN) && SHRT_MAX == OPL_INT16_MAX) +# define OPL_SHRT_BITS 16 +# else +# if (SHRT_MIN == OPL_INT32_MIN) && SHRT_MAX == OPL_INT32_MAX) +# define OPL_SHRT_BITS 32 +# else +# if (SHRT_MIN == OPL_INT64_MIN) && SHRT_MAX == OPL_INT64_MAX) +# define OPL_SHRT_BITS 64 +# endif +# endif +# endif +#endif + +#if ! defined (OPL_INT_BITS) && defined(UINT_MAX) +# if (UINT_MAX == OPL_UINT16_MAX) +# define OPL_INT_BITS 16 +# else +# if (UINT_MAX == OPL_UINT32_MAX) +# define OPL_INT_BITS 32 +# else +# if (UINT_MAX == OPL_UINT64_MAX) +# define OPL_INT_BITS 64 +# endif +# endif +# endif +#endif +#if ! defined (OPL_INT_BITS) && defined(INT_MIN) && defined(INT_MAX) +# if (INT_MIN == OPL_INT16_MIN) && (INT_MAX == OPL_INT16_MAX) +# define OPL_INT_BITS 16 +# else +# if (INT_MIN == OPL_INT32_MIN) && (INT_MAX == OPL_INT32_MAX) +# define OPL_INT_BITS 32 +# else +# if (INT_MIN == OPL_INT64_MIN) && (INT_MAX == OPL_INT64_MAX) +# define OPL_INT_BITS 64 +# endif +# endif +# endif +#endif + +#if ! defined (OPL_LONG_BITS) && defined(ULONG_MAX) +# if (ULONG_MAX == OPL_UINT16_MAX) +# define OPL_LONG_BITS 16 +# else +# if (ULONG_MAX == OPL_UINT32_MAX) +# define OPL_LONG_BITS 32 +# else +# if (ULONG_MAX == OPL_UINT64_MAX) +# define OPL_LONG_BITS 64 +# endif +# endif +# endif +#endif +#if ! defined (OPL_LONG_BITS) && defined(LONG_MIN) && defined(LONG_MAX) +# if (LONG_MIN == OPL_INT16_MIN) && (LONG_MAX == OPL_INT16_MAX) +# define OPL_LONG_BITS 16 +# else +# if (LONG_MIN == OPL_INT32_MIN) && (LONG_MAX == OPL_INT32_MAX) +# define OPL_LONG_BITS 32 +# else +# if (LONG_MIN == OPL_INT64_MIN) && (LONG_MAX == OPL_INT64_MAX) +# define OPL_LONG_BITS 64 +# endif +# endif +# endif +#endif + +#if ! defined (OPL_LLONG_BITS) && defined(ULLONG_MAX) +# if (ULLONG_MAX == OPL_UINT16_MAX) +# define OPL_LLONG_BITS 16 +# else +# if (ULLONG_MAX == OPL_UINT32_MAX) +# define OPL_LLONG_BITS 32 +# else +# if (ULLONG_MAX == OPL_UINT64_MAX) +# define OPL_LLONG_BITS 64 +# endif +# endif +# endif +#endif +#if ! defined (OPL_LLONG_BITS) && defined(LLONG_MIN) && defined(LLONG_MAX) +# if (LLONG_MIN == OPL_INT16_MIN) && (LLONG_MAX == OPL_INT16_MAX) +# define OPL_LLONG_BITS 16 +# else +# if (LLONG_MIN == OPL_INT32_MIN) && (LLONG_MAX == OPL_INT32_MAX) +# define OPL_LLONG_BITS 32 +# else +# if (LLONG_MIN == OPL_INT64_MIN) && (LLONG_MAX == OPL_INT64_MAX) +# define OPL_LLONG_BITS 64 +# endif +# endif +# endif +#endif + +/*---------------------------------------------------------------------------*/ +#endif /* _OPL_LIMITS_H */ diff -Nru yorick-optimpack-1.3.2+dfsg/src/opl_lnsrch.c yorick-optimpack-1.3.2+dfsg+1.4.0/src/opl_lnsrch.c --- yorick-optimpack-1.3.2+dfsg/src/opl_lnsrch.c 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/src/opl_lnsrch.c 2017-01-10 22:16:57.000000000 +0000 @@ -0,0 +1,515 @@ +/* + * opl_lnsrch.c -- + * + * Line search routines for OptimPackLegacy library. + * + *----------------------------------------------------------------------------- + * + * Copyright (c) 2003, 2016 Éric Thiébaut. + * + * This file is part of OptimPack . + * + * OptimPack is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * OptimPack is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * OptimPack (file "LICENSE" in the top source directory); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + *----------------------------------------------------------------------------- + */ + +#include +#include +#include +#include +#include "opl_private.h" + +/* Constants. */ +static const double zero = 0.0; +static const double xtrapl = 1.1; +static const double xtrapu = 4.0; + +/*---------------------------------------------------------------------------*/ + +const size_t OPL_CSRCH_WORKSPACE_SIZE = + OPL_ROUND_UP(sizeof(opl_csrch_workspace_t), sizeof(double)); + +size_t +opl_csrch_get_workspace_size() +{ + return OPL_CSRCH_WORKSPACE_SIZE; +} + +opl_csrch_workspace_t* +opl_csrch_create_workspace() +{ + opl_csrch_workspace_t* ws = OPL_NEW(opl_csrch_workspace_t, 1); + if (ws != NULL) { + memset(ws, 0, sizeof(opl_csrch_workspace_t)); + opl_initialize_context(&ws->context); + } + return ws; +} + +void +opl_csrch_destroy_workspace(opl_csrch_workspace_t* ws) +{ + if (ws != NULL) { + free((void*)ws); + } +} + +opl_task_t +opl_csrch_get_task(opl_csrch_workspace_t* ws) +{ + return (ws != NULL ? ws->task : OPL_TASK_ERROR); +} + +opl_task_t +opl_csrch_get_status(opl_csrch_workspace_t* ws) +{ + return (ws != NULL ? ws->context.status : OPL_ILLEGAL_ADDRESS); +} + +const char* +opl_csrch_get_reason(opl_csrch_workspace_t* ws) +{ + return (ws != NULL ? ws->context.message : "illegal workspace address"); +} + +static opl_status_t +report(opl_csrch_workspace_t* ws, + opl_task_t task, opl_status_t status, const char* mesg) +{ + ws->task = task; + return opl_set_context((opl_context_t*)ws, status, mesg, OPL_PERMANENT); +} + +opl_status_t +opl_csrch_start(opl_csrch_workspace_t* ws, double f, double g, double stp, + double ftol, double gtol, double xtol, + double stpmin, double stpmax) +{ + /* Minimal checking. */ + if (ws == NULL) { + errno = EFAULT; + return OPL_ILLEGAL_ADDRESS; + } + + /* Check the input arguments for errors. + Exit if there are errors on input. */ +#define ERROR(I,S) report(ws, OPL_TASK_ERROR, I, "opl_csrch_start: " S) + if (stpmax < stpmin) { + return ERROR(OPL_STPMAX_LT_STPMIN, "STPMAX < STPMIN"); + } + if (stpmin < zero) { + return ERROR(OPL_STPMIN_LT_ZERO, "STPMIN < 0"); + } + if (xtol < zero) { + return ERROR(OPL_XTOL_LT_ZERO, "XTOL < 0"); + } + if (ftol <= zero) { + return ERROR(OPL_FTOL_LE_ZERO, "FTOL <= 0"); + } + if (gtol <= zero) { + return ERROR(OPL_GTOL_LE_ZERO, "GTOL <= 0"); + } + if (g >= zero) { + return ERROR(OPL_NOT_A_DESCENT, "initial G >= 0"); + } + if (stp > stpmax) { + return ERROR(OPL_STP_GT_STPMAX, "STP > STPMAX"); + } + if (stp < stpmin) { + return ERROR(OPL_STP_LT_STPMIN, "STP < STPMIN"); + } +#undef ERROR + + /* Initialize local variables. + The variables STX, FX, GX contain the values of the step, + function, and derivative at the best step. + The variables STY, FY, GY contain the value of the step, + function, and derivative at STY. + The variables STP, F, G contain the values of the step, + function, and derivative at STP. */ + ws->ftol = ftol; + ws->gtol = gtol; + ws->xtol = xtol; + ws->stpmin = stpmin; + ws->stpmax = stpmax; + ws->finit = f; + ws->ginit = g; + ws->stx = zero; + ws->fx = f; + ws->gx = g; + ws->sty = zero; + ws->fy = f; + ws->gy = g; + ws->stmin = zero; + ws->stmax = stp + stp*xtrapu; + ws->width = stpmax - stpmin; + ws->width1 = 2.0*(stpmax - stpmin); + ws->brackt = 0; + ws->stage = 1; + ws->task = OPL_TASK_FG; + return opl_success((opl_context_t*)ws); +} + +opl_status_t +opl_csrch_iterate(opl_csrch_workspace_t* ws, + double f, double g, double *stp_ptr) +{ + /* Define macros to make the code simpler and easier to read. */ +# define ftol (ws->ftol) +# define gtol (ws->gtol) +# define xtol (ws->xtol) +# define stpmin (ws->stpmin) +# define stpmax (ws->stpmax) +# define finit (ws->finit) +# define ginit (ws->ginit) +# define stx (ws->stx) +# define fx (ws->fx) +# define gx (ws->gx) +# define sty (ws->sty) +# define fy (ws->fy) +# define gy (ws->gy) +# define stmin (ws->stmin) +# define stmax (ws->stmax) +# define width (ws->width) +# define width1 (ws->width1) +# define task (ws->task) +# define stage (ws->stage) +# define brackt (ws->brackt) + + /* Local variables. */ + double ftest, gtest, stp; + opl_status_t status; + + /* Minimal checking. */ + if (ws == NULL) { + errno = EFAULT; + return OPL_ILLEGAL_ADDRESS; + } + + /* Initialize local variables. */ + stp = *stp_ptr; + + /* If psi(stp) <= 0 and f'(stp) >= 0 for some step, then the algorithm enters + the second stage. */ + gtest = ftol*ginit; + ftest = finit + stp*gtest; + if (stage == 1 && f <= ftest && g >= zero) { + stage = 2; + } + + /* Test for termination: convergence or warnings. */ + if (f <= ftest && fabs(g) <= gtol*(-ginit)) { + return report(ws, OPL_TASK_CONV, + OPL_SUCCESS, "strong Wolfe conditions both satisfied"); + } + if (stp == stpmin && (f > ftest || g >= gtest)) { + return report(ws, OPL_TASK_WARN, + OPL_STP_EQ_STPMIN, "step at lower bound"); + } + if (stp == stpmax && f <= ftest && g <= gtest) { + return report(ws, OPL_TASK_WARN, + OPL_STP_EQ_STPMAX, "step at upper bound"); + } + if (brackt && stmax - stmin <= xtol*stmax) { + return report(ws, OPL_TASK_WARN, + OPL_XTOL_TEST_SATISFIED, "XTOL test satisfied"); + } + if (brackt && (stp <= stmin || stp >= stmax)) { + return report(ws, OPL_TASK_WARN, + OPL_ROUNDING_ERROR, "rounding errors prevent progress"); + } + + /* A modified function is used to predict the step during the first + stage if a lower function value has been obtained but the decrease + is not sufficient. */ + + if (stage == 1 && f <= fx && f > ftest) { + + /* Define the modified function and derivative values. */ + double fm = f - stp*gtest; + double fxm = fx - stx*gtest; + double fym = fy - sty*gtest; + double gm = g - gtest; + double gxm = gx - gtest; + double gym = gy - gtest; + + /* Call opl_cstep to update STX, STY, and to compute the new step. */ + status = opl_cstep((opl_context_t*)ws, &brackt, stmin, stmax, + &stx, &fxm, &gxm, + &sty, &fym, &gym, + &stp, fm, gm); + if (status != OPL_SUCCESS) { + task = OPL_TASK_ERROR; + return status; + } + + /* Reset the function and derivative values for F. */ + fx = fxm + stx*gtest; + fy = fym + sty*gtest; + gx = gxm + gtest; + gy = gym + gtest; + + } else { + + /* Call opl_cstep to update STX, STY, and to compute the new step. */ + status = opl_cstep((opl_context_t*)ws, &brackt, stmin, stmax, + &stx, &fx, &gx, + &sty, &fy, &gy, + &stp, f, g); + if (status != OPL_SUCCESS) { + task = OPL_TASK_ERROR; + return status; + } + + } + + /* Decide if a bisection step is needed. */ + if (brackt) { + double wcur = fabs(sty - stx); + if (wcur >= 0.66*width1) stp = stx + 0.5*(sty - stx); + width1 = width; + width = wcur; + } + + /* Set the minimum and maximum steps allowed for STP. */ + if (brackt) { + if (stx <= sty) { + stmin = stx; + stmax = sty; + } else { + stmin = sty; + stmax = stx; + } + } else { + stmin = stp + xtrapl*(stp - stx); + stmax = stp + xtrapu*(stp - stx); + } + + /* Force the step to be within the bounds STPMAX and STPMIN. */ + if (stp > stpmax) stp = stpmax; + if (stp < stpmin) stp = stpmin; + + /* If further progress is not possible, let STP be the best + point obtained during the search. */ + if (brackt && (stp <= stmin || stp >= stmax || + stmax - stmin <= xtol*stmax)) { + stp = stx; + } + + /* Save local variables. */ + *stp_ptr = stp; + + /* Obtain another function and derivative. */ + return report(ws, OPL_TASK_FG, + OPL_SUCCESS, "compute f(x) and g(x)"); + + /* Undefine macros. */ +# undef ftol +# undef gtol +# undef xtol +# undef stpmin +# undef stpmax +# undef finit +# undef ginit +# undef stx +# undef fx +# undef gx +# undef sty +# undef fy +# undef gy +# undef stmin +# undef stmax +# undef width +# undef width1 +# undef task +# undef stage +# undef brackt +} + +/*---------------------------------------------------------------------------*/ +/* SAFEGUARDED CUBIC STEP */ + +opl_status_t +opl_cstep(opl_context_t* ctx, opl_boolean_t *brackt, + double stpmin, double stpmax, + double *stx_ptr, double *fx_ptr, double *dx_ptr, + double *sty_ptr, double *fy_ptr, double *dy_ptr, + double *stp_ptr, double fp, double dp) +{ + /* Get values of input/output variables. */ + double stx = *stx_ptr, fx = *fx_ptr, dx = *dx_ptr; + double sty = *sty_ptr, fy = *fy_ptr, dy = *dy_ptr; + double stp = *stp_ptr; + + /* Local variables. */ + double gamma, theta, p, q, r, s, t; + double stpc; /* cubic step */ + double stpq; /* quadratic step */ + double sgnd, stpf; + + /* Check the input parameters for errors. */ +# define REPORT(status, mesg) opl_set_context(ctx, status, \ + "opl_cstep: " mesg, \ + OPL_PERMANENT) + if (*brackt && (stx < sty ? (stp <= stx || stp >= sty) + : (stp >= stx || stp <= sty))) { + return REPORT(OPL_OUT_OF_BOUNDS, "STP outside bracket (STX,STY)"); + } else if (dx*(stp - stx) >= zero) { + return REPORT(OPL_NOT_A_DESCENT, "descent condition violated"); + } else if (stpmax < stpmin) { + return REPORT(OPL_STPMAX_LT_STPMIN, "STPMAX < STPMIN"); + return 0; + } +# undef REPORT + + /* Determine if the derivatives have opposite sign. */ + sgnd = (dx/fabs(dx))*dp; + + if (fp > fx) { + /* First case. A higher function value. The minimum is bracketed. If the + cubic step is closer to STX than the quadratic step, the cubic step is + taken, otherwise the average of the cubic and quadratic steps is + taken. */ + theta = 3.0*(fx - fp)/(stp - stx) + dx + dp; + s = fabs(theta); + if (s < (t = fabs(dx))) s = t; + if (s < (t = fabs(dp))) s = t; + t = theta/s; + gamma = s*sqrt(t*t - (dx/s)*(dp/s)); + if (stp < stx) gamma = -gamma; + p = (gamma - dx) + theta; + q = ((gamma - dx) + gamma) + dp; + r = p/q; + stpc = stx + r*(stp - stx); + stpq = stx + ((dx/((fx - fp)/(stp - stx) + dx))/2.0)*(stp - stx); + if (fabs(stpc - stx) < fabs(stpq - stx)) { + stpf = stpc; + } else { + stpf = stpc + (stpq - stpc)/2.0; + } + *brackt = 1; + } else if (sgnd < zero) { + /* Second case. A lower function value and derivatives of opposite sign. + The minimum is bracketed. If the cubic step is farther from STP than + the secant (quadratic) step, the cubic step is taken, otherwise the + secant step is taken. */ + theta = 3.0*(fx - fp)/(stp - stx) + dx + dp; + s = fabs(theta); + if (s < (t = fabs(dx))) s = t; + if (s < (t = fabs(dp))) s = t; + t = theta/s; + gamma = s*sqrt(t*t - (dx/s)*(dp/s)); + if (stp > stx) gamma = -gamma; + p = (gamma - dp) + theta; + q = ((gamma - dp) + gamma) + dx; + r = p/q; + stpc = stp + r*(stx - stp); + stpq = stp + (dp/(dp - dx))*(stx - stp); + if (fabs(stpc - stp) > fabs(stpq - stp)) { + stpf = stpc; + } else { + stpf = stpq; + } + *brackt = 1; + } else if (fabs(dp) < fabs(dx)) { + /* Third case. A lower function value, derivatives of the same sign, and + the magnitude of the derivative decreases. The cubic step is computed + only if the cubic tends to infinity in the direction of the step or if + the minimum of the cubic is beyond STP. Otherwise the cubic step is + defined to be the secant step. */ + theta = 3.0*(fx - fp)/(stp - stx) + dx + dp; + s = fabs(theta); + if (s < (t = fabs(dx))) s = t; + if (s < (t = fabs(dp))) s = t; + /* The case GAMMA = 0 only arises if the cubic does not tend to infinity in + the direction of the step. */ + t = theta/s; + t = t*t - (dx/s)*(dp/s); + gamma = (t > zero ? s*sqrt(t) : zero); + if (stp > stx) gamma = -gamma; + p = (gamma - dp) + theta; + /*q = ((gamma - dp) + gamma) + dx;*/ + q = (gamma + (dx - dp)) + gamma; + r = p/q; + if (r < zero && gamma != zero) { + stpc = stp + r*(stx - stp); + } else if (stp > stx) { + stpc = stpmax; + } else { + stpc = stpmin; + } + stpq = stp + (dp/(dp - dx))*(stx - stp); + if (*brackt) { + /* A minimizer has been bracketed. If the cubic step is closer to STP + than the secant step, the cubic step is taken, otherwise the secant + step is taken. */ + stpf = fabs(stpc - stp) < fabs(stpq - stp) ? stpc : stpq; + t = stp + 0.66*(sty - stp); + if (stp > stx ? stpf > t : stpf < t) stpf = t; + } else { + /* A minimizer has not been bracketed. If the cubic step is farther from + stp than the secant step, the cubic step is taken, otherwise the + secant step is taken. */ + stpf = fabs(stpc - stp) > fabs(stpq - stp) ? stpc : stpq; + if (stpf > stpmax) stpf = stpmax; + if (stpf < stpmin) stpf = stpmin; + } + } else { + /* Fourth case. A lower function value, derivatives of the same sign, and + the magnitude of the derivative does not decrease. If the minimum is + not bracketed, the step is either STPMIN or STPMAX, otherwise the cubic + step is taken. */ + if (*brackt) { + theta = 3.0*(fp - fy)/(sty - stp) + dy + dp; + s = fabs(theta); + if (s < (t = fabs(dy))) s = t; + if (s < (t = fabs(dp))) s = t; + t = theta/s; + gamma = s*sqrt(t*t - (dy/s)*(dp/s)); + if (stp > sty) gamma = -gamma; + p = (gamma - dp) + theta; + q = ((gamma - dp) + gamma) + dy; + r = p/q; + stpc = stp + r*(sty - stp); + stpf = stpc; + } else if (stp > stx) { + stpf = stpmax; + } else { + stpf = stpmin; + } + } + + /* Update the interval which contains a minimizer and guess for next step. */ + if (fp > fx) { + *sty_ptr = stp; + *fy_ptr = fp; + *dy_ptr = dp; + } else { + if (sgnd < zero) { + *sty_ptr = stx; + *fy_ptr = fx; + *dy_ptr = dx; + } + *stx_ptr = stp; + *fx_ptr = fp; + *dx_ptr = dp; + } + *stp_ptr = stpf; + return opl_success(ctx); +} + +/*---------------------------------------------------------------------------*/ diff -Nru yorick-optimpack-1.3.2+dfsg/src/opl_private.h yorick-optimpack-1.3.2+dfsg+1.4.0/src/opl_private.h --- yorick-optimpack-1.3.2+dfsg/src/opl_private.h 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/src/opl_private.h 2017-01-10 22:16:57.000000000 +0000 @@ -0,0 +1,165 @@ +/* + * opl_private.h -- + * + * Private definitions for optimization routines implemented in Optimpacklegacy + * library. + * + *----------------------------------------------------------------------------- + * + * Copyright (c) 2003, 2016 Éric Thiébaut. + * + * This file is part of OptimPack . + * + * OptimPack is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * OptimPack is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * OptimPack (file "LICENSE" in the top source directory); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + *----------------------------------------------------------------------------- + */ + +#ifndef _OPL_PRIVATE_H +#define _OPL_PRIVATE_H 1 + +#include "optimpacklegacy.h" + +/*---------------------------------------------------------------------------*/ +/* USEFUL MACROS */ + +#ifndef _OPL_FORCE_INLINE +# if defined(_MSC_VER) /* Microsoft Visual Studio */ +# define _OPL_FORCE_INLINE __forceinline +# elif defined(__GNUC__) /* GNU Compiler */ +# define _OPL_FORCE_INLINE inline __attribute__((always_inline)) +# elif defined( __cplusplus) /* C++ Compiler */ +# define _OPL_FORCE_INLINE inline +# endif +#endif + +/* OPL_STRINGIFY takes an argument and wraps it in "" (double quotation + marks), OPL_CONCAT concatenates two arguments. */ +#ifdef __STDC__ +# define OPL_STRINGIFY(x) #x +# define OPL_CONCAT(a,b) a##b +# define OPL_CONCAT2(a,b) a##b +# define OPL_CONCAT3(a,b,c) a##b##c +# define OPL_CONCAT4(a,b,c,d) a##b##c##d +#else +# define OPL_STRINGIFY(x) "x" +# define OPL_CONCAT(a,b) a/**/b +# define OPL_CONCAT2(a,b) a/**/b +# define OPL_CONCAT3(a,b,c) a/**/b/**/c +# define OPL_CONCAT4(a,b,c,d) a/**/b/**/c/**/d +#endif + +/* Computes absolute value: */ +#define OPL_ABS(a) ((a)>=0?(a):-(a)) + +/* Computes min/max values: */ +#define OPL_MIN(a,b) ((a)<=(b)?(a):(b)) +#define OPL_MAX(a,b) ((a)>=(b)?(a):(b)) + +/* Computes minimal number of chunks with M elements + needed to store N elements: */ +#define OPL_HOW_MANY(n, m) (((n)+((m)-1))/(m)) + +/* Returns N elements rounding up to a multiple of M elements: */ +#define OPL_ROUND_UP(n, m) (OPL_HOW_MANY(n, m)*(m)) + +/* Offset (in bytes) of member M in structure S: */ +#define OPL_OFFSET_OF(s, m) ((size_t) &((s *)0)->m) + +/* Allocate memory for a given number of elements of a given type. */ +#define OPL_NEW(type, number) (type*)malloc((number)*sizeof(type)) + +/*---------------------------------------------------------------------------*/ +/* STRUCTURES */ + +/** + * The context structure. + */ +struct _opl_context { + const char* message; /* Current message. */ + opl_status_t status; /* Status code. */ + int syserr; /* Value of `errno` if status is + `OPL_SYSTEM_ERROR` */ + char buffer[128]; /* Internal buffer */ +}; + +/** Global message for successful operation. */ +extern const char* _opl_success_message; + +/** + * Set a context with a permanent message. + */ +#define _OPL_SET_CONTEXT(ctx, stat, mesg) \ + ((ctx)->message = (mesg), (ctx)->status = stat) + +#ifdef _OPL_FORCE_INLINE +opl_status_t _OPL_FORCE_INLINE _opl_success(opl_context_t* ctx) +{ + return _OPL_SET_CONTEXT(ctx, OPL_SUCCESS, _opl_success_message); +} +#endif + +/** + * Workspace data used for Moré & Thuente line search. + */ +struct _opl_csrch_workspace { + opl_context_t context; + double ftol, gtol, xtol; + double stpmin, stpmax; + double finit; + double ginit; + double stx, fx, gx; + double sty, fy, gy; + double stmin, stmax; + double width, width1; + opl_task_t task; + int stage; + opl_boolean_t brackt; +}; + +/** + * The workspace for VMLMB. + */ +struct _opl_vmlmb_workspace { + opl_csrch_workspace_t lnsrch; + opl_integer_t n; + opl_integer_t m; + opl_integer_t mp; + opl_integer_t mark; + opl_integer_t evaluations; + opl_integer_t iterations; + opl_integer_t restarts; + unsigned int flags; + void (*free)(void*); + double frtol; + double fatol; + double fmin; + double f0; + double gd; + double g0d; + double stp; + double delta; + double epsilon; + double gnorm; + double g0norm; + double* alpha; + double* rho; + double* d; + double** S; + double** Y; +}; + +#endif /* _OPL_PRIVATE_H */ diff -Nru yorick-optimpack-1.3.2+dfsg/src/opl_utils.c yorick-optimpack-1.3.2+dfsg+1.4.0/src/opl_utils.c --- yorick-optimpack-1.3.2+dfsg/src/opl_utils.c 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/src/opl_utils.c 2017-01-10 22:16:57.000000000 +0000 @@ -0,0 +1,192 @@ +/* + * opl_utils.c -- + * + * Utilities routines for OptimPackLegacy library. + * + *----------------------------------------------------------------------------- + * + * Copyright (c) 2003, 2016 Éric Thiébaut. + * + * This file is part of OptimPack . + * + * OptimPack is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * OptimPack is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * OptimPack (file "LICENSE" in the top source directory); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + *----------------------------------------------------------------------------- + */ + +#include +#include +#include +#include +#include "opl_private.h" + +/*---------------------------------------------------------------------------*/ +/* CONTEXT MANAGEMENT AND ERROR REPORTING */ + +const char* _opl_success_message = "Successful operation"; +static const char* _opl_insufficient_memory_message = "Insufficient memory"; +static const char* _opl_illegal_address_message = "Illegal address"; +static const char* _opl_invalid_argument_message = "Invalid argument"; +static const char* _opl_out_of_bounds_message = "Out of bounds size or index"; +static const char* _opl_corrupted_message = "Corrupted data"; +static const char* _opl_overflow_message = "Numerical overflow"; +#if 0 +static const char* _opl_syntax_error_message = "Syntax error"; +static const char* _opl_open_error_message = "Cannot open file"; +static const char* _opl_close_error_message = "Error while closing file"; +static const char* _opl_read_error_message = "Read error"; +static const char* _opl_write_error_message = "Write error"; +static const char* _opl_stat_error_message = "Cannot stat file"; +static const char* _opl_file_exists_message = "File already exists"; +static const char* _opl_zip_error_message = "Error with PkZip archive"; +#endif + +extern void +opl_initialize_context(opl_context_t* ctx) +{ + ctx->message = _opl_success_message; + ctx->status = OPL_SUCCESS; + ctx->syserr = 0; +} + +#define DEFINE_FUNCTION(name, NAME) \ + opl_status_t \ + opl_##name(opl_context_t* ctx) \ + { \ + return _OPL_SET_CONTEXT(ctx, OPL_##NAME, _opl_##name##_message); \ + } +DEFINE_FUNCTION(success, SUCCESS) +DEFINE_FUNCTION(insufficient_memory, INSUFFICIENT_MEMORY) +DEFINE_FUNCTION(illegal_address, ILLEGAL_ADDRESS) +DEFINE_FUNCTION(invalid_argument, INVALID_ARGUMENT) +DEFINE_FUNCTION(out_of_bounds, OUT_OF_BOUNDS) +DEFINE_FUNCTION(corrupted, CORRUPTED) +DEFINE_FUNCTION(overflow, OVERFLOW) +#if 0 +DEFINE_FUNCTION(syntax_error, SYNTAX_ERROR) +DEFINE_FUNCTION(open_error, OPEN_ERROR) +DEFINE_FUNCTION(close_error, CLOSE_ERROR) +DEFINE_FUNCTION(read_error, READ_ERROR) +DEFINE_FUNCTION(write_error, WRITE_ERROR) +DEFINE_FUNCTION(stat_error, STAT_ERROR) +DEFINE_FUNCTION(file_exists, FILE_EXISTS) +DEFINE_FUNCTION(zip_error, ZIP_ERROR) +#endif +#undef DEFINE_FUNCTION + +opl_status_t +opl_system_error(opl_context_t* ctx) +{ + int syserr = errno; + ctx->syserr = syserr; + ctx->message = strerror(syserr); + return (ctx->status = OPL_SYSTEM_ERROR); +} + +opl_status_t +opl_get_status(opl_context_t* ctx) +{ + return ctx->status; +} + +int +opl_get_errno(opl_context_t* ctx) +{ + return (ctx->status == OPL_SYSTEM_ERROR ? ctx->syserr : 0); +} + +const char* +opl_get_message(opl_context_t* ctx) +{ + return ctx->message; +} + +#define TRUNCATE(str, siz) \ + (str)[(siz) - 6] = '['; \ + (str)[(siz) - 5] = '.'; \ + (str)[(siz) - 4] = '.'; \ + (str)[(siz) - 3] = '.'; \ + (str)[(siz) - 2] = ']'; \ + (str)[(siz) - 1] = '\0' + +opl_status_t +opl_set_context(opl_context_t* ctx, opl_status_t status, + const char* message, opl_storage_type_t type) +{ + if (type == OPL_PERMANENT) { + ctx->message = message; + } else { + size_t size = sizeof(ctx->buffer); + size_t nchars = (message == NULL ? 0 : strlen(message)); + if (nchars <= 0) { + ctx->buffer[0] = '\0'; + } else if (nchars < size) { + memcpy(ctx->buffer, message, nchars + 1); + } else { + memcpy(ctx->buffer, message, size); + TRUNCATE(ctx->buffer, size); + } + ctx->message = ctx->buffer; + } + ctx->syserr = (status == OPL_SYSTEM_ERROR ? errno : 0); + return (ctx->status = status); +} + +opl_status_t +opl_format_context(opl_context_t* ctx, opl_status_t status, + const char* format, ...) +{ + const size_t size = sizeof(ctx->buffer); + va_list ap; + size_t nchars; + + va_start(ap, format); + nchars = vsnprintf(ctx->buffer, size, format, ap); + va_end(ap); + if (nchars >= size) { + TRUNCATE(ctx->buffer, size); + } + ctx->message = ctx->buffer; + ctx->syserr = (status == OPL_SYSTEM_ERROR ? errno : 0); + return (ctx->status = status); +} + +const char* +opl_get_default_message(opl_status_t status) +{ + switch(status) { + case OPL_SUCCESS: return _opl_success_message; + case OPL_INSUFFICIENT_MEMORY: return _opl_insufficient_memory_message; + case OPL_ILLEGAL_ADDRESS: return _opl_illegal_address_message; + case OPL_INVALID_ARGUMENT: return _opl_invalid_argument_message; + case OPL_OUT_OF_BOUNDS: return _opl_out_of_bounds_message; + case OPL_CORRUPTED: return _opl_corrupted_message; + case OPL_OVERFLOW: return _opl_overflow_message; +#if 0 + case OPL_SYNTAX_ERROR: return _opl_syntax_error_message; + case OPL_OPEN_ERROR: return _opl_open_error_message; + case OPL_CLOSE_ERROR: return _opl_close_error_message; + case OPL_READ_ERROR: return _opl_read_error_message; + case OPL_WRITE_ERROR: return _opl_write_error_message; + case OPL_STAT_ERROR: return _opl_stat_error_message; + case OPL_FILE_EXISTS: return _opl_file_exists_message; + case OPL_ZIP_ERROR: return _opl_zip_error_message; +#endif + default: return "Unknown status"; + } +} + +/*---------------------------------------------------------------------------*/ diff -Nru yorick-optimpack-1.3.2+dfsg/src/opl_vmlmb.c yorick-optimpack-1.3.2+dfsg+1.4.0/src/opl_vmlmb.c --- yorick-optimpack-1.3.2+dfsg/src/opl_vmlmb.c 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/src/opl_vmlmb.c 2017-01-10 22:16:57.000000000 +0000 @@ -0,0 +1,818 @@ +/* + * opl_vmlmb.c -- + * + * Variable Metric Limited Memory with Bound constraints for OptimPackLegacy + * library. + * + *----------------------------------------------------------------------------- + * + * Copyright (c) 2003-2009, 2016 Éric Thiébaut. + * + * This file is part of OptimPack . + * + * OptimPack is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * OptimPack is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * OptimPack (file "LICENSE" in the top source directory); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + *----------------------------------------------------------------------------- + */ + +#include +#include +#include +#include +#include +#include +#include "opl_private.h" + +typedef unsigned char byte_t; + +/* + * Some constants. + * + * Ssee http://stackoverflow.com/questions/1923837/how-to-use-nan-and-inf-in-c + * for a discussion about how to define NaN and infinite. Alternatives for Inf + * and NaN: + * + * double NaN = strtod("NaN", NULL); + * double Inf = strtod("Inf", NULL); + * + * but cannot be constants then. Some macros may be defined in (as + * part of C99 standard): + * + * #include + * #ifdef NAN + * const double NaN = NAN; + * #end + * #ifdef INFINITY + * const double Inf = INFINITY; + * #end + */ +static const double zero = 0.0; +static const double one = 1.0; +static const double NaN = 0.0/0.0; +static const double Inf = 1.0/0.0; + +/* Default settings. */ +#define DEFAULT_STPMAX 1e20 +#define DEFAULT_SFTOL 0.001 +#define DEFAULT_SGTOL 0.9 +#define DEFAULT_SXTOL 0.1 +#define DEFAULT_FATOL 0.0 +#define DEFAULT_FRTOL 1e-10 +#define DEFAULT_DELTA 1e-3 +#define DEFAULT_EPSILON 0.0 + +#define FLAG_FMIN (1 << 0) + +/* `task`, `context` and some other members are shared with the embedded + line search structure. */ +#define TASK(ws) (ws)->lnsrch.task +#define CONTEXT(ws) (ws)->lnsrch.context +#define STATUS(ws) (ws)->lnsrch.context.status +#define SXTOL(ws) (ws)->lnsrch.xtol +#define SFTOL(ws) (ws)->lnsrch.ftol +#define SGTOL(ws) (ws)->lnsrch.gtol +#define SXTOL(ws) (ws)->lnsrch.xtol +#define STPMIN(ws) (ws)->lnsrch.stpmin +#define STPMAX(ws) (ws)->lnsrch.stpmax + +/* Allocate an array of given type and size. */ +#define NEW(type, number) ((type*)malloc((number)*sizeof(type))) + +/*---------------------------------------------------------------------------*/ +/* PRIVATE FUNCTIONS */ + +static double min(double a, double b) { + return (a <= b ? a : b); +} + +static double max(double a, double b) { + return (a >= b ? a : b); +} + +/* Apply L-BFGS recursion to compute search direction. */ +static void +compute_direction(opl_vmlmb_workspace_t* ws, double d[], + const opl_logical_t isfree[], const double h[]); + +/* Compute next step and set task. */ +static opl_task_t +next_step(opl_vmlmb_workspace_t* ws, double x[]); + +/* Check H and ISFREE arrays, possibly fix ISFREE, returns non-zero + in case of error. */ +static int +check_free(opl_vmlmb_workspace_t* ws, opl_logical_t isfree[], const double h[]); + +/* Report a failure. */ +static opl_task_t +failure(opl_vmlmb_workspace_t* ws, opl_status_t status, const char* mesg) +{ + opl_set_context(&CONTEXT(ws), status, mesg, OPL_PERMANENT); + return (TASK(ws) = OPL_TASK_ERROR); +} + +/* Report a success. */ +static opl_task_t +success(opl_vmlmb_workspace_t* ws, opl_task_t task, const char* mesg) +{ + opl_set_context(&CONTEXT(ws), OPL_SUCCESS, mesg, OPL_PERMANENT); + return (TASK(ws) = task); +} + +/*---------------------------------------------------------------------------*/ + +#define GET_MEMBER(type, name, rvalue, invalid) \ + type \ + opl_vmlmb_get_##name(opl_vmlmb_workspace_t* ws) \ + { \ + if (ws == NULL) { \ + errno = EFAULT; \ + return invalid; \ + } \ + return rvalue; \ + } + +GET_MEMBER(double, fmin, ws->fmin, NaN); +GET_MEMBER(double, fatol, ws->fatol, NaN); +GET_MEMBER(double, frtol, ws->frtol, NaN); +GET_MEMBER(double, delta, ws->delta, NaN); +GET_MEMBER(double, epsilon, ws->epsilon, NaN); +GET_MEMBER(double, sxtol, SXTOL(ws), NaN); +GET_MEMBER(double, sftol, SFTOL(ws), NaN); +GET_MEMBER(double, sgtol, SGTOL(ws), NaN); +GET_MEMBER(double, step, ws->stp, NaN); +GET_MEMBER(double, gnorm, ws->gnorm, NaN); +GET_MEMBER(opl_task_t, task, TASK(ws), OPL_TASK_ERROR); +GET_MEMBER(opl_status_t, status, STATUS(ws), OPL_ILLEGAL_ADDRESS); +GET_MEMBER(opl_integer_t, iterations, ws->iterations, -1); +GET_MEMBER(opl_integer_t, evaluations, ws->evaluations, -1); +GET_MEMBER(opl_integer_t, restarts, ws->restarts, -1); +GET_MEMBER(const char*, reason, opl_get_message(&CONTEXT(ws)), NULL); + +#undef GET_MEMBER + +opl_status_t +opl_vmlmb_set_fmin(opl_vmlmb_workspace_t* ws, double value) +{ + if (ws == NULL) { + errno = EFAULT; + return OPL_ILLEGAL_ADDRESS; + } + if (isnan(value) || value < -DBL_MAX) { + ws->flags &= ~FLAG_FMIN; + ws->fmin = NaN; + } else { + ws->fmin = value; + } + return OPL_SUCCESS; +} + +#define SET_MEMBER(name, lvalue, invalid) \ + opl_status_t \ + opl_vmlmb_set_##name(opl_vmlmb_workspace_t* ws, double value) \ + { \ + if (ws == NULL) { \ + errno = EFAULT; \ + return OPL_ILLEGAL_ADDRESS; \ + } \ + if (invalid) { \ + errno = EINVAL; \ + return OPL_INVALID_ARGUMENT; \ + } \ + lvalue = value; \ + return OPL_SUCCESS; \ + } + +SET_MEMBER(fatol, ws->fatol, value < 0.0); +SET_MEMBER(frtol, ws->frtol, value < 0.0); +SET_MEMBER(delta, ws->delta, value < 0.0); +SET_MEMBER(epsilon, ws->epsilon, value < 0.0); +SET_MEMBER(sxtol, SXTOL(ws), value <= 0.0 || value >= 1.0); +SET_MEMBER(sftol, SFTOL(ws), value <= 0.0 || value >= 1.0); +SET_MEMBER(sgtol, SGTOL(ws), value <= 0.0 || value >= 1.0); + +#undef SET_MEMBER + +opl_task_t +opl_vmlmb_restart(opl_vmlmb_workspace_t* ws) +{ + if (ws == NULL) { + errno = EFAULT; + return OPL_TASK_ERROR; + } + ws->evaluations = 0; + ws->iterations = 0; + ws->restarts = 0; + ws->mark = -1; + ws->mp = 0; + ws->f0 = 0.0; + ws->gd = 0.0; + ws->g0d = 0.0; + ws->stp = 0.0; + STPMIN(ws) = 0.0; + STPMAX(ws) = 0.0; + ws->gnorm = -1.0; + ws->g0norm = -1.0; + return success(ws, OPL_TASK_FG, "compute f(x) and g(x)"); +} + +opl_task_t +opl_vmlmb_restore(opl_vmlmb_workspace_t* ws, + double x[], double *f, double g[]) +{ + if (ws == NULL || x == NULL || f == NULL || g == NULL) { + errno = EFAULT; + return OPL_TASK_ERROR; + } + if (TASK(ws) == OPL_TASK_FG && ws->evaluations > 0) { + *f = ws->f0; + ws->gnorm = ws->g0norm; + opl_dcopy(ws->n, ws->S[ws->mark], x); + opl_dcopy(ws->n, ws->Y[ws->mark], g); + success(ws, OPL_TASK_NEWX, "restored solution available for inspection"); + } + return TASK(ws); +} + +/*---------------------------------------------------------------------------*/ +/* PERFORM NEXT VMLMB STEP */ + +opl_task_t +opl_vmlmb_iterate(opl_vmlmb_workspace_t* ws, + double x[], double *f, double g[], + opl_logical_t isfree[], const double h[]) +{ + /* Local variables. */ + double stpmax; + opl_integer_t m = ws->m; + opl_integer_t n = ws->n; + double* d = ws->d; + double** S_ = ws->S; + double** Y_ = ws->Y; + double *Sm, *Ym; + opl_integer_t i; + int have_fmin = ((ws->flags & FLAG_FMIN) != 0); + +# define S(j) S_[j] +# define Y(j) Y_[j] + + switch (TASK(ws)) { + + case OPL_TASK_FG: + /* Caller has perfomed a new evaluation of the function and its gradient. */ + ++ws->evaluations; + if (have_fmin && *f <= ws->fmin) { + return failure(ws, OPL_F_LE_FMIN, "initial F <= FMIN"); + } + if (ws->evaluations > 1) { + opl_status_t status; + opl_task_t task; + + /* Compute directional derivative for the line search. */ + ws->gd = -opl_ddot(n, g, d); + + /* Call line search iterator to check for line search convergence. */ + opl_csrch_iterate(&ws->lnsrch, *f, ws->gd, &ws->stp); + task = TASK(ws); + if (task == OPL_TASK_FG) { + /* Line search has not converged. Compute a new iterate. */ + return next_step(ws, x); + } + status = STATUS(ws); + if (task == OPL_TASK_CONV || + (task == OPL_TASK_WARN && (status == OPL_XTOL_TEST_SATISFIED || + status == OPL_ROUNDING_ERROR))) { + /* Line search has converged. */ + ++ws->iterations; + } else { + /* Error or warning in line search (task and context should have been + set so as to describe the problem). Restore solution at start of + line search. */ + opl_dcopy(n, S(ws->mark), x); + opl_dcopy(n, Y(ws->mark), g); + ws->gnorm = ws->g0norm; + *f = ws->f0; + break; + } + } + + /* Request the caller to compute the set of unbinded variables. */ + return success(ws, OPL_TASK_FREEVARS, "determine free variables"); + + case OPL_TASK_FREEVARS: + /* Copy the (projected) gradient into D and compute the norm of the + (projected) gradient. */ + if (check_free(ws, isfree, h) != 0) { + break; + } + opl_dcopy_free(n, g, d, isfree); + ws->gnorm = opl_dnrm2(n, d); + if (ws->gnorm == zero) { + return success(ws, OPL_TASK_CONV, "local minimum found"); + } + if (ws->evaluations > 1) { + /* Compute the step and gradient change (i.e., update L-BFGS data). + Note: we always compute the effective step (parameter difference) to + account for bound constraints and, at least, numerical rounding or + truncation errors. */ + for (Ym = Y(ws->mark), i = 0; i < n; ++i) { + Ym[i] -= g[i]; + } + for (Sm = S(ws->mark), i = 0; i < n; ++i) { + Sm[i] -= x[i]; + } + if (isfree == NULL) { + ws->rho[ws->mark] = opl_ddot(n, Y(ws->mark), S(ws->mark)); + } + if (ws->mp < m) { + ++ws->mp; + } + + /* Test for global convergence. */ + if (opl_noneof(n, S(ws->mark))) { + return success(ws, OPL_TASK_WARN, "no parameter change"); + } else if (opl_noneof(n, Y(ws->mark))) { + return success(ws, OPL_TASK_WARN, "no gradient change"); + } else { + double change = max(fabs(*f - ws->f0), fabs(ws->stp*ws->g0d)); + if (change <= ws->frtol*fabs(ws->f0)) { + return success(ws, OPL_TASK_CONV, "FRTOL test satisfied"); + } else if (change <= ws->fatol) { + return success(ws, OPL_TASK_CONV, "FATOL test satisfied"); + } + } + } + + /* Set task to signal a new iterate. */ + return success(ws, OPL_TASK_NEWX, "new improved solution available for inspection"); + + case OPL_TASK_NEWX: + case OPL_TASK_CONV: + case OPL_TASK_WARN: + /* Compute a new search direction. D already contains the (projected) gradient. */ + if (ws->mp > 0) { + /* Apply L-BFGS recursion to compute a search direction. */ + compute_direction(ws, d, isfree, h); + if (ws->mp > 0) { + /* Set initial step size and compute dot product of gradient and search + direction. If L-BFGS recursion filed to produce a sufficient + descent search direction, we restart the algorithm with steepest + descent. */ + int descent; + ws->stp = 1.0; + ws->gd = -opl_ddot(n, g, d); + if (ws->epsilon > zero) { + descent = (ws->gd <= -ws->epsilon*ws->gnorm*opl_dnrm2(n, d)); + } else { + descent = (ws->gd < zero); + } + if (! descent) { + /* Manage to restart the L-BFGS with steepest descent. */ + ws->mp = 0; + opl_dcopy_free(n, g, d, isfree); + } + } + if (ws->mp <= 0) { + /* L-BFGS recursion has been restarter because it has failed to produce + an acceptable search direction. */ + ++ws->restarts; + } + } + + if (ws->mp == 0) { + /* Compute initial search direction (or after a restart). D is already + the (projected) gradient. */ + if (h != NULL) { + /* Use diagonal preconditioner to compute initial search direction. */ + for (i = 0; i < n; ++i) { + d[i] *= h[i]; + } + ws->stp = 1.0; + ws->gd = -opl_ddot(n, g, d); + if (ws->gd >= zero) { + return failure(ws, OPL_NOT_POSITIVE_DEFINITE, + "preconditioner is not positive definite"); + } + } else { + /* No preconditioning, use a small step along the steepest descent. */ + if (ws->delta > zero) { + ws->stp = (opl_dnrm2(n, x)/ws->gnorm)*ws->delta; + } else { + ws->stp = zero; + } + if (ws->stp <= zero) { + /* The following step length is quite arbitrary but to avoid this + would require to know the typical size of the variables. */ + ws->stp = one/ws->gnorm; + } + ws->gd = -ws->gnorm*ws->gnorm; + } + } + + /* Advance the mark and save point at start of line search. Note that this + point has forcibly been projected so it is feasible. */ + ws->mark = (ws->mark + 1)%m; + ws->f0 = *f; + ws->g0d = ws->gd; + ws->g0norm = ws->gnorm; + opl_dcopy(n, x, S(ws->mark)); /* save parameters X0 */ + opl_dcopy(n, g, Y(ws->mark)); /* save gradient G0 */ + + /* Set step bounds and task to start line search. */ +#if 1 + stpmax = DEFAULT_STPMAX; +#else + if (have_fmin) { + stpmax = (ws->fmin - ws->f0)/(SGTOL(ws)*ws->g0d); + } else { + double temp = fabs(ws->f0); + if (temp < 1.0) { + temp = 1.0; + } + stpmax = temp/(SGTOL(ws)*ws->g0d); + } +#endif + ws->stp = min(ws->stp, stpmax); + opl_csrch_start(&ws->lnsrch, *f, ws->gd, ws->stp, + SFTOL(ws), SGTOL(ws), SXTOL(ws), + zero, stpmax); + if (TASK(ws) != OPL_TASK_FG) { + /* Some error occured (task and context should have been set so as to + describe the problem). */ + break; + } + /* Compute the new iterate. */ + return next_step(ws, x); + + case OPL_TASK_ERROR: + /* Nothing to do then. */ + break; + + default: + /* Probably an error. */ + return failure(ws, OPL_CORRUPTED, "corrupted workspace"); + } + + return TASK(ws); + +# undef Y +# undef S +# undef SUCCESS +# undef FAILURE + +} + +/* + * Compute new search direction H(k).d(k) based on the two-loop recursion + * L-BFGS formula (operation is done in-place). H(k) is the limited memory + * BFGS approximation of the inverse Hessian, d(k) has been initialized with is + * the (projected) gradient at k-th step. H(k) is approximated by using the M + * last pairs (s, y) where: + * + * s(j) = x(j+1) - x(j) + * y(j) = g(j+1) - g(j) + * + * or: + * + * s(j) = x(j) - x(j+1) + * y(j) = g(j) - g(j+1) + * + * Indeed, the way the differences are computed does not matter (as far as all + * differences are computed similarly), because: it has no influence on RHO(j), + * and on dot products between S(j) and Y(j); it changes the sign of ALPHA(j) + * and BETA but not that of ALPHA(j) - BETA times S(j) or Y(j). + * + * The two-loop recursion algorithm writes: + * + * 1- start with current gradient: + * d := +/- g(k) + * + * 2- for j = k-1, ..., k-m + * rho(j) = s(j)'.y(j) (save rho(j)) + * alpha(j) = (s(j)'.d)/rho(j) (save alpha(j)) + * d := d - alpha(j) y(j) + * + * 3- apply approximation of inverse k-th Hessian: + * d := H0(k).d + * for instance: + * d := (rho(k-1)/(y(k-1)'.y(k-1))) d + * + * 4- for j = k-m, ..., k-1 + * d := d + (alpha(j) - (y(j)'.d)/rho(j)) s(j) + */ +static void +compute_direction(opl_vmlmb_workspace_t* ws, double d[], + const opl_logical_t isfree[], const double h[]) +{ + double gamma = zero; + opl_integer_t m = ws->m; + opl_integer_t mp = ws->mp; + opl_integer_t n = ws->n; + opl_integer_t off = ws->mark + m + 1; + opl_integer_t i, j, k; + double* rho = ws->rho; + double* alpha = ws->alpha; + double** S_ = ws->S; + double** Y_ = ws->Y; + +# define S(j) S_[j] +# define Y(j) Y_[j] + + /* First loop of the L-BFGS recursion. */ + for (k = 1; k <= mp; ++k) { + j = (off - k)%m; + if (isfree != NULL) { + rho[j] = opl_ddot_free(n, S(j), Y(j), isfree); + } + if (rho[j] > zero) { + alpha[j] = opl_ddot(n, S(j), d)/rho[j]; + opl_daxpy_free(n, -alpha[j], Y(j), d, isfree); + if (gamma <= zero) { + double yty = opl_ddot_free(n, Y(j), Y(j), isfree); + if (yty > zero) { + gamma = rho[j]/yty; + } + } + } + } + + /* Apply initial approximation of the inverse Hessian. */ + if (h != NULL) { + /* Apply diagonal preconditioner. */ + for (i = 0; i < n; ++i) { + d[i] *= h[i]; + } + } else if (gamma > zero) { + /* Apply initial H (i.e. just scale D) and perform the second stage of + the 2-loop recursion. */ + opl_dscal(n, gamma, d); + } else { + /* All correction pairs are invalid: manage to restart the L-BFGS + recursion. Note that D is left unchanged in that case. */ + ++ws->restarts; + ws->mp = 0; + return; + } + + /* Second loop of the L-BFGS recursion. */ + for (k = mp; k >= 1; --k) { + j = (off - k)%m; + if (rho[j] > zero) { + double beta = opl_ddot(n, Y(j), d)/rho[j]; + opl_daxpy_free(n, alpha[j] - beta, S(j), d, isfree); + } + } + +# undef S +# undef Y + +} + +static opl_task_t +next_step(opl_vmlmb_workspace_t* ws, double x[]) +{ + double stp = ws->stp; + const double* d = ws->d; + const double* x0 = ws->S[ws->mark]; + opl_integer_t i, n = ws->n; + + /* Compute the new iterate. */ + for (i = 0; i < n; ++i) { + x[i] = x0[i] - stp*d[i]; + } + + /* Require the caller to compute the function and its gradient. */ + opl_set_context(&CONTEXT(ws), OPL_SUCCESS, + "compute f(x) and g(x)", OPL_PERMANENT); + return (TASK(ws) = OPL_TASK_FG); +} + +static int +check_free(opl_vmlmb_workspace_t* ws, opl_logical_t isfree[], + const double h[]) +{ + if (h != NULL) { + const double zero = 0.0; + opl_integer_t i, n = ws->n; + if (isfree != NULL) { + /* fix ISFREE array */ + for (i = 0; i < n; ++i) { + if (isfree[i] && h[i] <= zero) { + isfree[i] = 0; + } + } + } else { + /* check that H is positive definite */ + for (i = 0; i < n; ++i) { + if (h[i] <= zero) { + failure(ws, OPL_NOT_POSITIVE_DEFINITE, + "initial inverse Hessian is not positive definite"); + return -1; + } + } + } + } + return 0; +} + +/*---------------------------------------------------------------------------*/ +/* MEMORY MANAGEMENT FOR VMLMB */ + +/* + * A monolithic workspace is organized in memory as follows (starting from the + * base address): + * + * base: workspace structure + * padding for proper alignment + * base + offset1: 2 arrays of M pointers (for S and Y) + * padding for proper alignment + * base + offset2: 2 arrays of M reals (for ALPHA and RHO) + * 1 array of N reals (for D, the search direction) + * 2*M arrays of N reals (for S and Y) + */ + +static const size_t offset1 = OPL_ROUND_UP(sizeof(opl_vmlmb_workspace_t), + sizeof(void*)); + +static size_t workspace_offset2(size_t m) +{ + return OPL_ROUND_UP(offset1 + 2*m*sizeof(void*), sizeof(double)); +} + +static size_t number_of_reals(size_t n, size_t m) +{ + return (2*m*(n + 1) + n); +} + +size_t +opl_vmlmb_monolithic_workspace_size(opl_integer_t n, opl_integer_t m) +{ + if (n <= 0 || m <= 0) { + errno = EINVAL; + return 0; + } + return workspace_offset2(m) + number_of_reals(n, m)*sizeof(double); +} + +opl_vmlmb_workspace_t* +opl_vmlmb_monolithic_workspace_init(void* buf, opl_integer_t n, opl_integer_t m) +{ + size_t offset2, size; + opl_integer_t k; + opl_vmlmb_workspace_t* ws; + double* arr; + + /* Check arguments. */ + if (buf == NULL) { + if (errno != ENOMEM) { + errno = EFAULT; + } + return NULL; + } + if (n <= 0 || m <= 0) { + errno = EINVAL; + return NULL; + } + + /* Compute offsets and size. Clear buffer. */ + offset2 = workspace_offset2(m); + size = offset2 + number_of_reals(n, m)*sizeof(double); + memset(buf, 0, size); + + /* Instanciate workspace. */ + ws = (opl_vmlmb_workspace_t*)buf; + ws->m = m; + ws->n = n; + ws->S = (double**)((byte_t*)ws + offset1); + ws->Y = ws->S + m; + ws->alpha = (double*)((byte_t*)ws + offset2); + ws->rho = ws->alpha + m; + ws->d = ws->rho + m; + arr = ws->d; + for (k = 0; k < m; ++k) { + ws->S[k] = (arr += n); + ws->Y[k] = (arr += n); + } + opl_vmlmb_restart(ws); + return opl_vmlmb_set_defaults(ws); +} + +opl_vmlmb_workspace_t* +opl_vmlmb_set_defaults(opl_vmlmb_workspace_t* ws) +{ + SFTOL(ws) = DEFAULT_SFTOL; + SGTOL(ws) = DEFAULT_SGTOL; + SXTOL(ws) = DEFAULT_SXTOL; + ws->fatol = DEFAULT_FATOL; + ws->frtol = DEFAULT_FRTOL; + ws->delta = DEFAULT_DELTA; + ws->epsilon = DEFAULT_EPSILON; + opl_vmlmb_set_fmin(ws, NaN); + return ws; +} + +static void +free_split_workspace(void* ptr) +{ + opl_vmlmb_workspace_t* ws = (opl_vmlmb_workspace_t*)ptr; + opl_integer_t k, m = ws->m; + double* tmp; + + if ((tmp = ws->d) != NULL) { + ws->d = NULL; + free(tmp); + } + for (k = 0; k < m; ++k) { + if ((tmp = ws->S[k]) != NULL) { + ws->S[k] = NULL; + free(tmp); + } + if ((tmp = ws->Y[k]) != NULL) { + ws->Y[k] = NULL; + free(tmp); + } + } + free(ws); +} + +opl_vmlmb_workspace_t* +opl_vmlmb_create(opl_integer_t n, opl_integer_t m) +{ + size_t offset2, size; + opl_integer_t k; + opl_vmlmb_workspace_t* ws; + + if (n <= 0 || m <= 0) { + errno = EINVAL; + return 0; + } + if (m*n <= 10000) { + /* For small problems, the workspace is allocated as a single block of + memory. */ + size = opl_vmlmb_monolithic_workspace_size(n, m); + ws = opl_vmlmb_monolithic_workspace_init(malloc(size), n, m); + if (ws == NULL) { + return NULL; + } + ws->free = free; + return ws; + } else { + /* For larger problems, the philosophy is to store the workspace structure + and related small arrays in a single block of memory, while larger + arrays (d, S and Y) are stored separately. */ + offset2 = workspace_offset2(m); + size = offset2 + 2*m*sizeof(double); + ws = (opl_vmlmb_workspace_t*)malloc(size); + if (ws == NULL) { + return NULL; + } + memset(ws, 0, size); + ws->free = free_split_workspace; + ws->m = m; + ws->n = n; + ws->S = (double**)((byte_t*)ws + offset1); + ws->Y = ws->S + m; + ws->alpha = (double*)((byte_t*)ws + offset2); + ws->rho = ws->alpha + m; + if ((ws->d = NEW(double, n)) == NULL) { + destroy: + opl_vmlmb_destroy(ws); + return NULL; + } + for (k = 0; k < m; ++k) { + if ((ws->S[k] = NEW(double, n)) == NULL || + (ws->Y[k] = NEW(double, n)) == NULL) { + goto destroy; + } + } + opl_vmlmb_restart(ws); + return opl_vmlmb_set_defaults(ws); + } +} + +void +opl_vmlmb_destroy(opl_vmlmb_workspace_t* ws) +{ + if (ws != NULL) { + if (ws->free == NULL) { + fprintf(stderr, "*** ERROR *** %s\n", + "attempt to destroy a foreign monolithic workspace, " + "read the documentation!"); + } else { + ws->free(ws); + } + } +} diff -Nru yorick-optimpack-1.3.2+dfsg/src/optimpacklegacy.h yorick-optimpack-1.3.2+dfsg+1.4.0/src/optimpacklegacy.h --- yorick-optimpack-1.3.2+dfsg/src/optimpacklegacy.h 1970-01-01 00:00:00.000000000 +0000 +++ yorick-optimpack-1.3.2+dfsg+1.4.0/src/optimpacklegacy.h 2017-01-10 22:16:57.000000000 +0000 @@ -0,0 +1,1066 @@ +/* + * optimpacklegacy.h -- + * + * Definitions for optimization routines implemented in Optimpacklegacy + * library. + * + *----------------------------------------------------------------------------- + * + * Copyright (c) 2003, 2016 Éric Thiébaut. + * + * This file is part of OptimPack . + * + * OptimPack is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * OptimPack is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * OptimPack (file "LICENSE" in the top source directory); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + *----------------------------------------------------------------------------- + */ + +#ifndef _OPTIMPACKLEGACY_H +#define _OPTIMPACKLEGACY_H 1 + +/** + * Customizable data types: + * OPL_INTEGER = data type used to store array indices + * OPL_LOGICAL = data type of the result of a logical test + */ +#ifndef OPL_INTEGER +# define OPL_INTEGER int +#endif +#ifndef OPL_LOGICAL +# define OPL_LOGICAL int +#endif + +typedef OPL_INTEGER opl_integer_t; +typedef OPL_LOGICAL opl_logical_t; + + +/*---------------------------------------------------------------------------*/ +/* USEFUL MACROS */ + +/* C++ needs to know that types and declarations are C, not C++. */ +#ifdef __cplusplus +# define _OPL_BEGIN_DECLS extern "C" { +# define _OPL_END_DECLS } +#else +# define _OPL_BEGIN_DECLS /* empty */ +# define _OPL_END_DECLS /* empty */ +#endif +_OPL_BEGIN_DECLS + +/** + * Possible values for a boolean. + */ +typedef enum { + OPL_FALSE = 0, + OPL_TRUE = 1 +} opl_boolean_t; + + +/*---------------------------------------------------------------------------*/ +/* STATUS AND ERROR REPORTING */ + +/** + * Standard result codes + * + * @brief These constants are the standard value returned by most dynamic + * buffer routines. + */ +typedef enum { + /* Success. */ + OPL_SUCCESS = 0, + + /* Warnings. */ + OPL_STP_EQ_STPMIN, + OPL_STP_EQ_STPMAX, + OPL_XTOL_TEST_SATISFIED, + OPL_ROUNDING_ERROR, + + /* Errors. */ + OPL_STPMAX_LT_STPMIN, + OPL_STPMIN_LT_ZERO, + OPL_XTOL_LT_ZERO, + OPL_FTOL_LE_ZERO, + OPL_GTOL_LE_ZERO, + OPL_NOT_A_DESCENT, + OPL_STP_GT_STPMAX, /* OPL_OUT_OF_BOUNDS? */ + OPL_STP_LT_STPMIN, /* OPL_OUT_OF_BOUNDS? */ + OPL_F_LE_FMIN, + OPL_NOT_POSITIVE_DEFINITE, + OPL_INSUFFICIENT_MEMORY, + OPL_ILLEGAL_ADDRESS, + OPL_INVALID_ARGUMENT, + OPL_OUT_OF_BOUNDS, + OPL_CORRUPTED, + OPL_OVERFLOW, +#if 0 + OPL_SYNTAX_ERROR, + OPL_OPEN_ERROR, + OPL_CLOSE_ERROR, + OPL_READ_ERROR, + OPL_WRITE_ERROR, + OPL_STAT_ERROR, + OPL_FILE_EXISTS, + OPL_ZIP_ERROR, +#endif + OPL_SYSTEM_ERROR /* System error, use errno code. */ +} opl_status_t; + +/** + * The context opaque structure. + */ +typedef struct _opl_context opl_context_t; + +/** + * Query status from context. + * + * @param ctx Context for error reporting. + * + * @return A status value. + */ +extern opl_status_t opl_get_status(opl_context_t* ctx); + +/** + * Query system error code from context. + * + * @param ctx Context for error reporting. + * + * @return If current context status is `OPL_SYSTEM_ERROR`, the system error + * code (a.k.a. `errno`) when the error occured is returned; otherwise, + * 0 is returned. + */ +extern int opl_get_errno(opl_context_t* ctx); + +/** + * Query message from context. + * + * @param ctx Context for error reporting. + * + * @return A human readable message. + */ +extern const char* opl_get_message(opl_context_t* ctx); + +/** + * Query an explanation about a status code. + * + * @param status Status value. + * + * @return A human readable message. + */ +extern const char* opl_get_default_message(opl_status_t status); + +/** + * Intialize a context. + * + * This function initializes a context to some consistent contents. It must + * be called before using the context. + * + * @param ctx The address of the context. + */ +extern void opl_initialize_context(opl_context_t* ctx); + +/** + * The different strorage types. + */ +typedef enum { + OPL_VOLATILE = 0, /** Storage is volatile, a copy must be done. */ + OPL_PERMANENT /** Storage is permanent, the same address can be used. */ +} opl_storage_type_t; + +/** + * Set a context contents. + * + * This function set the contents, that is the status and corresponding + * message, of a given context and return the status value. + * + * The given message must be a null terminated string. If the storage type of + * the message is `OPL_PERMANENT`, the context message will point to `message`; + * otherwise, the context message will point to the internal buffer of `ctx` + * after copying `message` in this buffer. In this latter case, if the message + * is too long to fit in the buffer, it will be truncated and terminated by the + * ellipsis text "[...]". + * + * @param ctx The address of the context. + * @param status The value of the status. + * @param message The message string. + * @param type The storage type of the message string. + * + * @return The value of `status`. + */ +extern opl_status_t opl_set_context(opl_context_t* ctx, + opl_status_t status, + const char* message, + opl_storage_type_t type); + +/** + * Set a context with a formated message. + * + * This function set the contents, that is the status and corresponding + * message, of a given context and return the status value. The message is + * formatted using the same mechanism as `printf`. If the resulting message is + * too long to fit in the internal buffer of the context, it will be truncated + * and terminated by the ellipsis text "[...]". + * + * @param ctx The address of the context. + * @param status The value of the status. + * @param format The format string. + * @param ... The arguments of the format. + * + * @return The value of `status`. + */ +extern opl_status_t opl_format_context(opl_context_t* ctx, + opl_status_t status, + const char* format, ...); + +/** + * Report successful operation. + * + * This (inlined) function is equivalent to: + * @code + * opl_set_context(ctx, OPL_SUCCESS, + * opl_get_default_message(OPL_SUCCESS), + * OPL_PERMANENT) + * @endcode + * + * @param ctx Context for error reporting. + * + * @return `OPL_SUCCESS`. + */ +extern opl_status_t opl_success(opl_context_t* ctx); + +/*---------------------------------------------------------------------------*/ +/* LINE SEARCH */ + +/** + * @addtogroup MoreThuenteLineSearch + * @{ + * + * @page csrch Moré & Thuente line search + * @tableofcontents + * + * Moré & Thuente line search method (@ref morethuente1984) finds a step that + * satisfies a sufficient decrease condition and a curvature condition. + * + * The function @link #opl_csrch_start should be called at the start of a line + * search to initiate the search. The function @link #opl_csrch_iterate should + * then be called for each new tried point along the line search until the + * convergence of the search. + * + * The method updates an interval with endpoints `stx` and `sty`. The + * interval is initially chosen so that it contains a minimizer of the + * modified function: + * + *
+ *       psi(stp) = f(stp) - f(0) - ftol*stp*g(0)
+ * 
+ * + * where `f(0)` and `g(0) = f'(0)` are the value of the function and its + * derivative for `stp = 0`. If `psi(stp) ≤ 0` and `g(stp) ≥ 0` for some step, + * then the interval is chosen so that it contains a minimizer of `f(stp)`. + * The algorithm is designed to find a step that satisfies the sufficient + * decrease condition: + * + *
+ *     f(stp) <= f(0) + ftol*stp*g(0),                            (1)
+ * 
+ * + * and the curvature condition: + * + *
+ *     abs(g(stp)) <= gtol*abs(g(0)).                             (2)
+ * 
+ * + * Relations (1) and (2) are called the strong Wolfe conditions. If `ftol` is + * less than `gtol` and if, for example, the function is bounded below, then + * there is always a step which satisfies both conditions. If no step can be + * found that satisfies both conditions, then the algorithm stops with a + * warning. In this case `stp` only satisfies the sufficient decrease + * condition. + * + * + * @subsection example Example + * + * A typical invocation of the method has the following outline: + * + *
+ * opl_csrch_create_workspace();
+ * double f = ...;   // function value for STP=0
+ * double g = ...;   // derivative value for STP=0
+ * double stp = ...; // guess for next STP value to try (STP > 0.0)
+ * double ftol = 1e-3;
+ * double gtol = 0.9;
+ * double xtol = 0.1;
+ * double stpmin = 0;
+ * double stpmax = 1e20*stp;
+ * opl_csrch_start(ws, f, g, stp, ftol, gtol, xtol, stpmin, stpmax);
+ * for (;;) {
+ *     opl_task_t task = opl_csrch_get_task(ws);
+ *     if (task == OPL_TASK_FG) {
+ *         // Evaluate the function and the gradient at `stp`.
+ *         f = func(stp);
+ *         g = grad(stp);
+ *     } else if (task == OPL_TASK_CONV) {
+ *         // Search has converged.
+ *         break;
+ *     } else if (task == OPL_TASK_WARN) {
+ *         // Some problem prevents further progress.
+ *         fprintf(stderr, "warning in %s\n", opl_csrch_get_reason(ws));
+ *         exit(1);
+ *     } else {
+ *         // An error occured.
+ *         fprintf(stderr, "error in %s\n", , opl_csrch_get_reason(ws));
+ *         exit(1);
+ *     }
+ * }
+ * 
+ * + * @subsection refs References + * + * @anchor morethuente1984 + * Jorge J. Moré and David J. Thuente, "Line search algorithms with + * guaranteed sufficient decrease" in ACM Transactions on Mathematical + * Software (TOMS) Volume 20, Issue 3, Pages 286-307 (September 1994). + * + * + * @subsection hist History + * + * MINPACK-1 Project. June 1983. + * Argonne National Laboratory. + * Jorge J. Moré and David J. Thuente. + * + * MINPACK-2 Project. November 1993. + * Argonne National Laboratory and University of Minnesota. + * Brett M. Averick, Richard G. Carter, and Jorge J. Moré. + * + * Yorick translation an improvements. October 2001. + * C-version. February 2003. + * Observatoire de Lyon (France). + * Éric Thiébaut. + * + * New C version with structured workspace. + * December 2016. + * Centre de Recherche Astrophysique de Lyon (France). + * Éric Thiébaut. + */ + +/** + * Possible values for an optimization task. + */ +typedef enum { + OPL_TASK_START = 0, /*< start line search */ + OPL_TASK_FG = 1, /*< caller has to compute function and gradient */ + OPL_TASK_FREEVARS = 2, /*< caller has to determine the free variables */ + OPL_TASK_NEWX = 3, /*< new variables available for inspection */ + OPL_TASK_CONV = 4, /*< search has converged */ + OPL_TASK_WARN = 5, /*< search aborted with warning */ + OPL_TASK_ERROR = 6 /*< search aborted with error */ +} opl_task_t; + +/** + * Opaque workspace used for Moré & Thuente line search. + */ +typedef struct _opl_csrch_workspace opl_csrch_workspace_t; + +/** + * Get the pending task of a line search instance. + */ +extern opl_task_t opl_csrch_get_task(opl_csrch_workspace_t* ws); + +/** + * Get the status of the last operation on a line search instance. + */ +extern opl_task_t opl_csrch_get_status(opl_csrch_workspace_t* ws); + + +/** + * Get the message explaining the result of the last operation on a line search + * instance. + */ +extern const char* opl_csrch_get_reason(opl_csrch_workspace_t* ws); + +/** + * Get the size of a Moré & Thuente line search instance. + * + * This function can be used to determine the size (in bytes) of a Moré & + * Thuente line search instance for applications which want to directly manage + * memory. A line search instance can be stored into any memory block of + * sufficient size and aligned on a multiple of the size of a `double`. + * However, the line search workspace can be assumed to have been properly + * initilaized only after a first call to @link #opl_csrch_start. + * + * @return The size in bytes of a Moré & Thuente line search instance. + */ +extern size_t opl_csrch_get_workspace_size(); + +/** + * Create a new instance of Moré & Thuente line search. + * + * @return A new instance of Moré & Thuente line search. When no longer + * needed, this instance must be destroyed with @link + * #olp_csrch_destroy_workspace. `NULL` is returned in case of error + * (i.e. insufficient memory). + */ +extern opl_csrch_workspace_t* opl_csrch_create_workspace(); + +/** + * Destroy an instance of Moré & Thuente line search. + * + * This function should only be called on an instance created by @link + * #opl_csrch_create_workspace. + * + * @param ws A line search instance created by @link + * #opl_csrch_create_workspace. + */ +extern void opl_csrch_destroy_workspace(opl_csrch_workspace_t* ws); + +/** + * Initiate a line search by Moré & Thuente method. + * + * @param ws The address of the line search workspace. + * + * @param f The value of the function at the start of the line search + * (that is for `stp = 0`). + * + * @param g The value of the directional derivative at the start of the + * line search (that is for `stp = 0`). + * + * @param stp The length of the first step to take along the search + * direction. Must be a strictly positive value. + * + * @param ftol A nonnegative tolerance for the sufficient decrease condition. + * One should take `0 < ftol < 1/2`. + * + * @param gtol A nonnegative tolerance for the curvature condition. One + * should take `ftol < gtol < 1`. + * + * @param xtol A nonnegative relative tolerance for an acceptable step. + * The line search will exit with a warning if the relative + * difference between `sty` and `stx` is less than `xtol`. + * + * @param stpmin A nonnegative lower bound for the step. + * + * @param stpmax A nonnegative upper bound for the step. + * + * @return A standard status: `OPL_SUCCESS` or any other value to indicate the + * error. + */ +extern opl_status_t +opl_csrch_start(opl_csrch_workspace_t* ws, double f, double g, double stp, + double ftol, double gtol, double xtol, + double stpmin, double stpmax); + +/** + * Iterate a line search by Moré & Thuente method. + * + * Upon return, @link #opl_csrch_get_task, @link #opl_csrch_get_status or @link + * #opl_csrch_get_reason can be used to retrieve the next pending task, the + * status of the last operation and the reason of the result of the las + * operation. + * + * @param ws The address of the line search workspace. + * + * @param f The value of the function for the current step along the line + * search. + * + * @param g The value of the derivative of the function for the current + * step along the line search. + * + * @param stp The address of the variable with, on entry, the length of the + * current step taken along the search direction. On exit with + * task `OPL_TASK_FG`, the variable will be set with the next + * step to take. On exit with task `OPL_TASK_CONV`, the variable + * is left unchanged. + * + * @return The following status values can be returned: + * + * - `OPL_SUCCESS`, then the task returned by @link #opl_csrch_get_task + * indicates the required action. If `task = OPL_TASK_FG`, then the callar + * shall evaluate the function and derivative at `*stp` and call + * `opl_csrch_iterate` again. If `task = OPL_TASK_CONV`, then the search is + * successful. If `task = OPL_TASK_WARN` then the subroutine is not able to + * satisfy the convergence conditions. The exit value of `*stp` contains the + * best point found during the search. If `task = OPL_TASK_ERROR` then there + * is an error in the input arguments. + * + * - `OPL_STP_EQ_STPMIN` with `task = OPL_TASK_WARN`: the search is blocked at + * the lower bound. + * + * - `OPL_STP_EQ_STPMAX` with `task = OPL_TASK_WARN`: the search is blocked at + * the upper bound. + * + * - `OPL_XTOL_TEST_SATISFIED` with `task = OPL_TASK_WARN`: `XTOL` test is + * satisfied. + * + * - `OPL_TASK_WARN` with `task = OPL_TASK_WARN`: rounding errors prevent + * progress. + * + * - `OPL_OUT_OF_BOUNDS` with `task = OPL_TASK_ERROR`: the step `*stp` is + * outside bracket `(stx,sty)`. + * + * - `OPL_NOT_A_DESCENT` with `task = OPL_TASK_ERROR`: the descent condition + * does not hold. + * + * - `OPL_STPMAX_LT_STPMIN` with `task = OPL_TASK_ERROR`: the search bounds are + * incompatible. + */ +extern opl_status_t +opl_csrch_iterate(opl_csrch_workspace_t* ws, double f, double g, + double *stp); + +/** + * Compute a safeguarded cubic step. + * + * This function computes a safeguarded step for a search procedure and updates + * an interval that contains a step that satisfies a sufficient decrease and a + * curvature condition [1]. + * + * The parameter `stx` contains the step with the least function value. If + * `brackt` is set to true (i.e. non-zero) then a minimizer has been bracketed + * in an interval with endpoints `stx` and `sty`. The parameter `stp` contains + * the current step. The subroutine assumes that if `brackt` is true then: + * + *
+ *     min(stx,sty) < stp < max(stx,sty),
+ * 
+ * + * and that the derivative at `stx` is negative in the direction of the step. + * + * On output, all the parameters passed by address are updated appropriately. + * + * @param ctx The address of a context structure for error reporting. + * + * @param brackt_ptr The addresses where the value of `brackt` is stored. + * `brackt` is a logical variable. On entry, `brackt` + * specifies if a minimizer has been bracketed. Initially + * `brackt` must be set to false. On exit, `brackt` specifies + * if a minimizer has been bracketed. When a minimizer is + * bracketed, `brackt` (i.e. the value at address + * `brackt_ptr`) is set to true. + * + * @param stpmin The lower bound for the step. + * + * @param stpmax The upper bound for the step. + * + * @param stx_ptr The address of `stx`, the best step obtained so far. + * + * @param fx_ptr The address of `fx`, the function at `stx`. + * + * @param dx_ptr The addresses of `dx`, the derivative at `stx` negative in + * the direction of the step, that is, `dx` and `stp - stx` + * must have opposite signs. + * + * @param sty_ptr The address of `sty`, the other endpoint of the interval + * of uncertainty. + * + * @param fy_ptr The address of `fy`, the function at `sty`. + * + * @param dy_ptr The address of `dy`, the derivative at `sty`. + * + * @param stp_ptr The address where the value of `stp`, the current step, + * is stored. If `brackt` is set true then on input `stp` + * must be between `stx` and `sty`. On output, the value at + * `stp_ptr` is set to the new step. + * + * @param fp The function at the current step. + * + * @param dp The derivative at the current step. + * + * @return The returned value indicates whether the operation was successful + * (failure can only occur with wrong arguments). The context `ctx` is + * used to report errors if any. + */ +extern opl_status_t +opl_cstep(opl_context_t* ctx, opl_boolean_t *brackt, + double stpmin, double stpmax, + double *stx_ptr, double *fx_ptr, double *dx_ptr, + double *sty_ptr, double *fy_ptr, double *dy_ptr, + double *stp_ptr, double fp, double dp); +/** + * @} + */ + +/*---------------------------------------------------------------------------*/ + +/** + * @addtogroup VMLMB + * @{ + * + * VMLMB is a limited memory variable metric method (BFGS) which can take into + * account bound constraints + */ + +/** + * The opaque workspace for VMLMB. + */ +typedef struct _opl_vmlmb_workspace opl_vmlmb_workspace_t; + +/** + * Return the size of a VMLMB workspace as one block. + * + * The returned size is a multiple of the size of a double precision floating + * point value. It may be stored in an array of such values. + * + * Typical usage: + *
+ *    size = opl_vmlmb_monolithic_workspace_size(n, m);
+ *    buffer = malloc(size);
+ *    ws = opl_vmlmb_monolithic_workspace_init(buffer, n, m);
+ *    ....;
+ *    free(buffer);
+ * 
+ * As it is guaranteed that the base address does not change, you can also do: + * + * size = opl_vmlmb_monolithic_workspace_size(n, m); + * ws = opl_vmlmb_monolithic_workspace_init(malloc(size), n, m); + * ....; + * free(ws); + *
+ *
+ * @param n   The number of variables.
+ *
+ * @param m   The number of memorized steps.
+ *
+ * @return The size in bytes of a monolithic workspace for VMLMB.  Zero is
+ *         returned if the arguments are invalid (not strictly positive).
+ */
+extern size_t
+opl_vmlmb_monolithic_workspace_size(opl_integer_t n, opl_integer_t m);
+
+/**
+ * Initialize a workspace allocated as one block.
+ *
+ * @param buf   The memory allocated by the caller of the workspace, it must
+ *              have at least the size given by
+ *              `opl_vmlmb_monolithic_workspace_size(n, m)`.
+ *
+ * @param n     The number of variables.
+ *
+ * @param m     The number of memorized steps.
+ *
+ * @return The workspace initialized with defaults.  `NULL` is returned
+ *         if `buf` is not a valid address.
+ */
+extern opl_vmlmb_workspace_t*
+opl_vmlmb_monolithic_workspace_init(void* buf,
+                                    opl_integer_t n, opl_integer_t m);
+
+extern opl_vmlmb_workspace_t*
+opl_vmlmb_set_defaults(opl_vmlmb_workspace_t* ws);
+
+extern opl_vmlmb_workspace_t*
+opl_vmlmb_create(opl_integer_t n, opl_integer_t m);
+
+extern void
+opl_vmlmb_destroy(opl_vmlmb_workspace_t* ws);
+
+/*
+ * VMLM-B computes a local minimizer of a function of N variables by a limited
+ * memory variable metric (BFGS) method; optionally, the parameters may be
+ * bounded.  The user must evaluate the function and the gradient.
+ *
+ * VMLM-B is implemented via two functions: opl_vmlmb_setup for initialization
+ * and opl_vmlmb_iterate for further iterations.  These functions use reverse
+ * communication.  The user must choose an initial approximation X to the
+ * minimizer, evaluate the function and the gradient at X, and make the initial
+ * call with TASK set to OPL_TASK_FG.  On exit TASK indicates the required
+ * action.
+ *
+ * The arguments are:
+ *
+ *   N is the number of parameters.
+ *
+ *   M is the number of correction pairs to remember in order to compute the
+ *       limited memory variable metric (BFGS) approximation of the inverse of
+ *       the Hessian.  For large problems, M = 3 to 5 gives good results.  For
+ *       small problems, M should be less or equal N.  The larger is M (and N)
+ *       the more computer memory will be needed to store the workspaces (see
+ *       DSAVE).
+ *
+ *   FRTOL is the relative error desired in the function (e.g.  FRTOL=1e-8).
+ *       Convergence occurs if the estimate of the relative error between F(X)
+ *       and F(XSOL), where XSOL is a local minimizer, is less or equal FRTOL.
+ *       FRTOL must have a non-negative floating point value.
+ *
+ *   FATOL is the absolute error desired in the function (e.g. FATOL=0.0).
+ *       Convergence occurs if the estimate of the absolute error between F(X)
+ *       and F(XSOL), where XSOL is a local minimizer, is less or equal FATOL.
+ *       FATOL must have a non-negative floating point value.
+ *
+ *   SFTOL, SGTOL, and SXTOL are tolerances for the line search subroutine (see
+ *       opl_csrch).   Recommended  values: SFTOL=0.001,  SGTOL=0.9,  SXTOL=0.1
+ *       (other values  may be more  suitable for highly  non-quadratic penalty
+ *       function).
+ *
+ *   DELTA is a small nonegative value used to compute a small initial step.
+ *
+ *   EPSILON is a small value, in the range [0,1), equals to the cosine of the
+ *       maximum angle between the search direction and the anti-gradient.  The
+ *       BFGS recursion is restarted, whenever the search direction is not
+ *       sufficiently "descending".
+ *
+ *   CSAVE is a character workspace array of length OPL_VMLMB_CSAVE_NUMBER
+ *       (same as OPL_MSG_SIZE) which is used to store additional information
+ *       on exit with convergence, a warning or an error.
+ *
+ *   ISAVE is an integer workspace array of length OPL_VMLMB_ISAVE_NUMBER.
+ *
+ *   DSAVE is a floating point workspace array of length equal to the value
+ *       returned by the macro OPL_VMLMB_DSAVE_NUMBER(N, M):
+ *
+ *           26 + N + 2*M*(N + 1).
+ *
+ *   X is a double precision array of length N.  On entry, X is an
+ *       approximation to the solution.  On exit with TASK = OPL_TASK_CONV, X
+ *       is the current approximation.
+ *
+ *   F is the address of a double precision variable.  On entry, F is the value
+ *       of the function at X.  On final exit, F is the function value at X.
+ *
+ *   G is a double precision array of length N.  On entry, G is the value of
+ *       the gradient at X.  On final exit, G is the value of the gradient at
+ *       X.
+ *
+ *   ISFREE is an optional integer array with length N provided by the caller
+ *       if the values in X have bounds.  If the parameters have no bounds,
+ *       ISFREE should be NULL (unconstrained minimization).  Otherwise,
+ *       elements set to zero in ISFREE indicate that the corresponding values
+ *       in X has reached a bound and should not be changed during the next
+ *       step because the gradient has the wrong sign (i.e.  the steepest
+ *       descent direction would violate the bound constraints):
+ *
+ *           ISFREE[i] = 0 if i-th value has a lower bound XLO[i]
+ *                         and X[i] = XLO[i] and G[i] >= 0
+ *                       0 if i-th value has an upper bound XHI[i]
+ *                         and X[i] = XHI[i] and G[i] <= 0
+ *                       1 otherwise
+ *
+ *       ISFREE needs only to be computed when TASK = OPL_TASK_FREEVARS.  If X
+ *       has (some) bounds, the caller is responsible for applying the bounds
+ *       to X before evaluating the function value F and the gradient G (i.e.,
+ *       when TASK = OPL_TASK_FG), e.g.:
+ *
+ *           if (X[i] < XLO[i]) X[i] = XLO[i];
+ *           if (X[i] > XHI[i]) X[i] = XHI[i];
+ *
+ *       If H is not specified (i.e., H is NULL) or if H[i] > 0 for all i such
+ *       that ISFREE[i] is non-zero, then ISFREE is left unchanged.
+ *
+ *   H is an optional double precision array with length N provided by the
+ *       caller and such that diag(H) is an approximation of the inverse of the
+ *       Hessian matrix.  If H is NULL, then the inverse of the Hessian is
+ *       approximated by a simple rescaling using Shanno & Phua formula.
+ *       Otherwise, if ISFREE is NULL, all elements of H must be strictly
+ *       greater than zero; else ISFREE[i] is set to zero if H[i] <= 0 (this is
+ *       the only case where ISFREE is modified).  As for ISFREE, H needs only
+ *       to be specifed the first time opl_vmlmb is called and when JOB=2.
+ *
+ *   TASK is the value returned by opl_vmlmb_setup and opl_vmlmb_iterate.  It
+ *       can have one of the following values:
+ *
+ *           OPL_TASK_FG - caller must evaluate the function and gradient at X
+ *               and call opl_vmlm_next.
+ *
+ *           OPL_TASK_FREEVARS - if variables are bounded, caller must
+ *               determine the set of free variables for the current variables
+ *               X and update IFREE accordingly.
+ *
+ *           OPL_TASK_NEWX - a new iterate has been computed.  The
+ *               approximation X, function F, and gradient G are available for
+ *               examination.
+ *
+ *           OPL_TASK_CONV - the search is successful.  The solution, function
+ *               value and gradient are available in X, F and G.
+ *
+ *           OPL_TASK_WARN - VMLMB is not able to satisfy the convergence
+ *               conditions.  The exit value of X contains the best
+ *               approximation found so far.  Warning message is available in
+ *               CSAVE.
+ *
+ *           OPL_TASK_ERROR then there is an error in the input arguments.
+ *               Error message is available in CSAVE.
+ *
+ * The caller must not modify the workspace arrays CSAVE, ISAVE and DSAVE
+ * between calls to opl_vmlmb_setup and further calls to opl_vmlmb_iterate.
+ *
+ * A typical invocation of VMLMB for unconstrained minimization has the
+ * following outline:
+ *
+ *    // Choose a starting vector:
+ *    for (i=0 ; i XMIN[i] || G[i] < 0) && (X[i] < XMAX[i] || G[i] > 0) */
+
+extern opl_integer_t opl_bounds_check(opl_integer_t n, const double xmin[],
+                                      const double xmax[]);
+/*	Check correctness of bounds XMIN and XMAX (see opl_bounds_apply for
+	the definition of the arguments).  This function returns -1 if the
+	bounds are such that XMIN[i] <= XMAX[i] for all i=0,...,N-1;
+	otherwise, the function return the value i of the first index (i >=
+	0) for which the condition is violated. */
+
+extern void opl_lower_bound_apply(opl_integer_t n, double x[], double xmin);
+extern void opl_lower_bound_free(opl_integer_t n, opl_logical_t isfree[],
+                                 const double x[], const double g[],
+                                 double xmin);
+/*	These routines are similar to opl_bounds_apply and opl_bounds_free but
+	for a scalar lower bound XMIN that is the same for all parameters X. */
+
+extern void opl_upper_bound_apply(opl_integer_t n, double x[], double xmax);
+extern void opl_upper_bound_free(opl_integer_t n, opl_logical_t isfree[],
+                                 const double x[], const double g[],
+                                 double xmax);
+/*	These routines are similar to opl_bounds_apply and opl_bounds_free but
+	for a scalar upper bound XMAX that is the same for all parameters X. */
+
+extern void opl_interval_apply(opl_integer_t n, double x[], double a, double b);
+extern void opl_interval_free(opl_integer_t n, opl_logical_t isfree[],
+                              const double x[], const double g[],
+                              double a, double b);
+/*	These routines are similar to opl_bounds_apply and opl_bounds_free
+	but for a scalar lower bound XMIN=min(A,B) and a scalar upper bound
+	XMAX=max(A,B) that are the same for all parameters X. */
+
+/*---------------------------------------------------------------------------*/
+/* UTILITIES */
+
+extern double opl_dnrm2(opl_integer_t n, const double x[]);
+/* Returns the Euclidian norm of X: sqrt(X'.X), taking care of overflows. */
+
+
+extern void opl_dcopy(opl_integer_t n, const double x[], double y[]);
+extern void opl_dcopy_free(opl_integer_t n, const double x[],
+                           double y[], const opl_logical_t isfree[]);
+/* Copy elements of X into Y.  Does Y[i] = X[i] for i=0,...,N-1.  If ISFREE
+   is non-NULL, only elements for which ISFREE[i] is true (non-zero) are
+   taken into account. */
+
+extern void opl_daxpy(opl_integer_t n, double a,
+		     const double x[], double y[]);
+extern void opl_daxpy_free(opl_integer_t n, double a,
+                           const double x[], double y[],
+                           const opl_logical_t isfree[]);
+/* Does Y[i] += A*X[i] for i=0,...,N-1.  If ISFREE is non-NULL, only
+   elements for which ISFREE[i] is true (non-zero) are taken into
+   account. */
+
+extern double opl_ddot(opl_integer_t n, const double x[], const double y[]);
+extern double opl_ddot_free(opl_integer_t n, const double x[],
+                            const double y[], const opl_logical_t isfree[]);
+/* Computes dot product of N-element vectors X and Y. If ISFREE is
+   non-NULL, only elements for which ISFREE[i] is true (non-zero) are taken
+   into account. */
+
+extern void opl_dscal(opl_integer_t n, double a, double x[]);
+/* Scales N-element vector X by scalar A. */
+
+/*---------------------------------------------------------------------------*/
+/* YORICK-LIKE ROUTINES */
+
+extern int opl_anyof(opl_integer_t n, const double x[]);
+/* Returns true (non-zero) if any element of X is non-zero; returns faslse
+   (zero) otherwise. N is the number of elements of X. */
+
+extern int opl_noneof(opl_integer_t n, const double x[]);
+/* Returns true (non-zero) if all elements of X are zero; returns faslse
+   (zero) otherwise. N is the number of elements of X. */
+
+extern int opl_allof(opl_integer_t n, const double x[]);
+/* Returns true (non-zero) if all elements of X are non-zero; returns faslse
+   (zero) otherwise. N is the number of elements of X. */
+
+/*---------------------------------------------------------------------------*/
+_OPL_END_DECLS
+#endif /* _OPTIMPACKLEGACY_H */
diff -Nru yorick-optimpack-1.3.2+dfsg/TODO yorick-optimpack-1.3.2+dfsg+1.4.0/TODO
--- yorick-optimpack-1.3.2+dfsg/TODO	2009-04-23 14:34:49.000000000 +0000
+++ yorick-optimpack-1.3.2+dfsg+1.4.0/TODO	1970-01-01 00:00:00.000000000 +0000
@@ -1,21 +0,0 @@
-* means to force a restart of VMLMB
-
-* backtrack (Armijo's rule) when at least one bound constraint
-  becomes active along the line search
-
-* check Zoutendijk condition
-
-* implement damped BFGS updating
-  see Nocédal & Wright p. 537.
-
-* scale initial gradient
-  perhaps use a typical value for the step norm
-
-* improve convergence test
-
-* change API
-  use a structure for the workspace
-
-* doxygen documentation
-
-* safeguard the step
diff -Nru yorick-optimpack-1.3.2+dfsg/TODO.md yorick-optimpack-1.3.2+dfsg+1.4.0/TODO.md
--- yorick-optimpack-1.3.2+dfsg/TODO.md	1970-01-01 00:00:00.000000000 +0000
+++ yorick-optimpack-1.3.2+dfsg+1.4.0/TODO.md	2017-01-10 22:16:57.000000000 +0000
@@ -0,0 +1,22 @@
+* Update documentation (use Doxygen?).
+
+* Implement gradient-based convergence test.
+
+* Use `fmin`.
+
+* `gamma` should be computed (and applied) when there is a preconditioner.
+
+* Backtrack (using Armijo's rule) when at least one bound constraint becomes
+  active along the line search.
+
+* Implement damped BFGS updating, see Nocédal & Wright p. 537.
+
+* Scale initial gradient.  Perhaps use a typical value for the step norm
+
+* Safeguard the step.
+
+* Implement BLMVM.
+
+* Saving best variables so far can be very cheap: it is sufficient to
+  remember the best step length, and corresponding function value and
+  gradient norm.  Not applicable with constraints.
diff -Nru yorick-optimpack-1.3.2+dfsg/VERSION yorick-optimpack-1.3.2+dfsg+1.4.0/VERSION
--- yorick-optimpack-1.3.2+dfsg/VERSION	2010-07-05 20:42:05.000000000 +0000
+++ yorick-optimpack-1.3.2+dfsg+1.4.0/VERSION	2017-01-10 22:16:57.000000000 +0000
@@ -1 +1 @@
-1.3.2
+1.4.0-pre1
diff -Nru yorick-optimpack-1.3.2+dfsg/yorick/do_test.i yorick-optimpack-1.3.2+dfsg+1.4.0/yorick/do_test.i
--- yorick-optimpack-1.3.2+dfsg/yorick/do_test.i	2003-03-12 11:21:07.000000000 +0000
+++ yorick-optimpack-1.3.2+dfsg+1.4.0/yorick/do_test.i	1970-01-01 00:00:00.000000000 +0000
@@ -1,29 +0,0 @@
-#include "optimpack-test.i"
-require, "utils.i";
-
-func do_test(fatol=, frtol=, sftol=, sgtol=, sxtol=, output=)
-{
-  keys = ["fatol", "frtol", "sftol", "sgtol", "sxtol"];
-  code = "for (i=1;i<=18;++i) optim_test_um, prob=i, method=0, verb=1";
-  for (i=1;i<=numberof(keys);++i) {
-    key = keys(i);
-    val = symbol_def(key);
-    if (! is_void(val)) code += ", "+key+"="+val;
-  }
-  if (! is_void(output)) {
-    code += ", output=\""+output+"\";";
-    write, open(output, "w"), linesize=1000, format="# %s\n", code;
-  } else {
-    code += ";";
-  }
-  eval, code, debug=0;
-}
-
-do_test, output="test1",
-  fatol="0.0", frtol="1e-12", sftol="1e-3", sgtol="0.9", sxtol="0.1";
-do_test, output="test2",
-  fatol="0.0", frtol="1e-12", sftol="1e-3", sgtol="0.1", sxtol="0.1";
-do_test, output="test3",
-  fatol="0.0", frtol="1e-12", sftol="1e-2", sgtol="0.1", sxtol="0.1";
-do_test, output="test4",
-  fatol="0.0", frtol="1e-12", sftol="5e-2", sgtol="0.1", sxtol="0.1";
diff -Nru yorick-optimpack-1.3.2+dfsg/yorick/f2c.i yorick-optimpack-1.3.2+dfsg+1.4.0/yorick/f2c.i
--- yorick-optimpack-1.3.2+dfsg/yorick/f2c.i	2003-03-11 16:17:17.000000000 +0000
+++ yorick-optimpack-1.3.2+dfsg+1.4.0/yorick/f2c.i	1970-01-01 00:00:00.000000000 +0000
@@ -1,371 +0,0 @@
-func f2c_warn(s) { write, format="WARNING: %s\n", s; }
-func f2c_load(file)
-{
-  if (structof(file) == string) file = open(file);
-  buf = rdline(file, 10);
-  while (buf(0)) grow, buf, rdline(file, numberof(buf));
-  return buf(where(buf));
-}
-
-func f2c_save(filename, buf, overwrite=)
-{
-  if (! overwrite && open(filename, "r", 1)) error, "file already exists";
-  write, open(filename, "w"), format="%s\n", linesize=100000, buf;
-}
-
-func f2c(file, trunc=)
-/*
-
-   Assume the source lines follows the "Standard Fixed Format":
-    - The first 72 columns of each line are scanned.
-    - The first five columns must be blank or contain a numeric label. 
-    - Continuation lines are identified by a nonblank, nonzero in column 6. 
-    - Short lines are padded to 72 characters. 
-    - Long lines are truncated.
-    - A line with a 'c', 'C', or '*' in column one is a comment line.
-    - A totally blank line is a comment line.
-
- 
- */
-{
-  nil = string(0);
-  code = f2c_load(file);
-
-  /* delete exceeding spaces */
-  code = regsub("[ \t]+$", code, "");
-
-  /* check for bad characters */
-  if (anyof(regmatch("[\t]", code))) error, "some bad characters";
-  
-  /* Isolate comments from code (a totally blank line or a line with a
-     'c', 'C', or '*' in column one is a comment line). */
-  is_comment = regmatch("^([cC*]|$)", code);
-  comment_lines = where(is_comment);
-  comment = code(comment_lines);
-  code_lines = where(! is_comment);
-  code = code(code_lines);
-
-  /* Convert FORTRAN comments to C-style comments. */
-  if (is_array(comment)) {
-    comment = strpart(comment, 2:0);
-    n = numberof(comment);
-    length = strlen(comment);
-    (continued = array(int, n))(1:-1) = (comment_lines(dif) == 1);
-    new = 1n;
-    for (i=1 ; i<=n ; ++i) {
-      if (continued(i)) {
-        comment(i) = (new ? "/*" : " *") + comment(i);
-        new = 0n;
-      } else if (length(i)) {
-        comment(i) = (new ? "/*" : " *") + comment(i) + " */";
-        new = 1n;
-      } else {
-        comment(i) = (new ? nil : " */");
-        new = 1n;
-      }
-    }
-    continued = new = length = [];
-  }
-  
-  /* Deal with lines longer that 72 characters */
-  if (max(strlen(code)) > 72) {
-    if (trunc) {
-      f2c_warn, "truncating lines longer than 72 characters";
-      code = strpart(code, 1:72);
-    } else {
-      f2c_warn, "some lines are longer than 72 characters";
-    }
-  }
-
-  /* Join continuation lines in code (continuation lines are identified by
-     a nonblank, nonzero in column 6). */
-  local tail;
-  i = where(regmatch("^     [^ 0] *(.*)", code, /* match0 */, tail));
-  if (is_array(i)) {
-    n = numberof(i);
-    if (min(i) <= 1) error, swrite(format="bad continuation line (%d)",
-                                   code_lines(min(i)));
-    code(i) = nil;
-    kp1 = 0;
-    for (j=1 ; j<=n ; ++j) {
-      if ((k = i(j)) != kp1) l = k - 1;
-      code(l) += tail(k);
-      kp1 = k + 1;
-    }
-    i = [];
-  }
-
-  /* Locate labels (the first five columns in code lines must be blank or
-     contain a numeric label). */
-  label_cols = strpart(code, 1:5);
-  i = where(regmatch("^ *[0-9]+ *$", label_cols));
-  if (is_array(i)) {
-    label_value = array(long, numberof(i));
-    sread, label_cols(i), label_value;
-    label_lines = code_lines(i);
-  } else {
-    label_value = label_lines = [];
-  }
-  label_cols = [];
-  
-  /* Convert code to lower case. */
-  code = strlower(code);
-
-  /* Simplify some FORTRAN keywords. */
-  code = regsub("([^a-z0-9])go +to([^a-z0-9])", code, "\\1goto\\2", all=1);  
-  code = regsub("([^a-z0-9])end *(do|if)$", code, "\\1end");
-  
-
-  /* replace some FORTRAN intrinsics */
-  code = regsub("^ *subroutine +\(.*\)", code, "void \\1\n{", all=1);
-  code = regsub(" *\\.eq\\. *", code, " == ", all=1);
-  code = regsub(" *\\.ne\\. *", code, " != ", all=1);
-  code = regsub(" *\\.lt\\. *", code, " < ", all=1);
-  code = regsub(" *\\.le\\. *", code, " <= ", all=1);
-  code = regsub(" *\\.gt\\. *", code, " > ", all=1);
-  code = regsub(" *\\.ge\\. *", code, " >= ", all=1);
-  code = regsub("\\.true\\.", code, " TRUE ", all=1);
-  code = regsub("\\.false\\.", code, " FALSE ", all=1);
-
-
-  return merge(comment, code, is_comment);
-}
-
-/* IF (arithmetic)
-     IF ( expr ) s1, s2, s3
-     -> { type __tmp = expr;
-          if (__tmp < (type)0) goto s1;
-          if (__tmp == (type)0) goto s2;
-          goto s3;
-        }
-
-   IF (block)
-     IF ( e1 ) THEN
-       ...
-     ELSE IF ( e2 ) THEN
-       ...
-     ELSE
-       ...
-     END IF
-     -> if (e1) {
-          ...;
-        } else if (e2) {
-          ...;
-        } else {
-          ...;
-        }
-
-   
-   IF (logical)
-     IF ( e ) statement
-     -> if (e) statement;
-
-
-   DO label [,] variable = start, stop [, incr ]
-
-   The expressions e1, e2, and e3 are evaluated. If e3 is not present, its
-   value is assumed to be one.
-
-   The iteration count is established as the value of the expression: 
-     MAX (INT ((e2 - e1 + e3) / e3 ), 0) 
-
-   The iteration count is zero if either of the following is true: 
-
-     e1 \> e2 and e3 \> zero. 
-     e1 < e2 and e3 < zero.
-
-   The iteration count is tested, and, if it is greater than zero, the
-   range of the DO loop is executed.
-
-   -> {
-         TYPE __stop = e2, __incr = e3;
-         for (var = e1 ;
-              (__incr > (TYPE)0 ? var <= __stop : var >= __stop) ;
-              var += __incr) {
-              ...;
-         }
-      }
-
-*/
-
-#if 0
-/*
- * COMMENT
- * CONTINUATION
- * [LABEL] ASSIGN_STMT
- * [LABEL] IF_STMT
- * [LABEL] DO_STMT
- * [LABEL] RETURN_STMT
- */
-func f2c_
-{
-  extern _f2c_re_label;
-  local label_values;
-  label_cols = strpart(code, 1:5);
-  i = where(regmatch("^ *([0-9]+) *$", strpart(code, 1:5), /* match0 */,
-                     label_values));
-  if (is_array(i)) {
-    label_values = array(long, numberof(i));
-    sread, label_cols(i), label_values;
-    label_lines = code_lines(i);
-
-    label_nrefs = h_new();
-    label_lines = h_new();
-    n = numberof(i);
-    for (j=1 ; j<=n ; ++j) {
-      key = swrite(format="%d", label_values(i));
-      if (h_has(label_nrefs, key)) error, "duplicate label ("+key+")";
-      h_set, label_nrefs, key, 0;
-      h_set, label_lines, key, code_lines(i(j));
-    }
-  } else {
-    label_values = label_lines = [];
-  }
-  
-  
-  regmatch, ;
-}
-
-local _f2c_column, _f2c_line;
-
-/* f2c_parse_line - must be called after dealing with commentary lines and
-   continuation lines and after some FORTRAN keywords have been simplified
-   ("go to" -> "goto", "end..." -> "end") */
-func f2c_parse_line(linestr, linechar, linetype)
-{
-
-  column = 0;
-  index = bufchar + 1;
-  buftype = F2C_TYPE_TABLE(index);
-  buf_is_type = F2C_TYPE_TABLE(index);
-  
-  
-  extern _f2c_column, _f2c_linenumber, _f2c_line;
-  
-  /* skip spaces */
-  while ((c = linechar(++_f2c_column)) == ' ') /* noop */ ;
-
-  //if (_f2c_column == 1) {
-  //  /* Comment or end of file.  */
-  //  if (c == 'c' || c == 'C' || c == '*') {
-  //    return COMMENT;
-  //  }
-  //  if (c == '\n') {
-  //    ++_f2c_linenumber;
-  //    return NEWLINE;
-  //  }
-  //  if (c == '\0') {
-  //    return EOF;
-  //  }
-  //  error, swrite(format="illegal character in first column at line %d",
-  //                _f2c_linenumber);
-  //}
-  if (_f2c_column >= 6) {
-    i1 = i2 = _f2c_column;
-    type = F2C_TYPE(c + 1);
-    if (type == F2C_ALPHA) {
-      while ((x = linetype(++i2)) >= F2C_ALPHA && x <= F2C_DOLLAR) /* noop */ ;
-      range = i1:i2-1;
-      token = strpart(line_str, range);
-      if (h_has(F2C_KEYWORDS, token)) {
-        return F2C_KEYWORD;
-      }
-      return F2C_VARIABLE;
-    }
-    if (type == F2C_DIGIT) {
-    }
-    if (type == F2C_OPEN || type == F2C_CLOSE) {
-    }
-    if (type == F2C_PERIOD) {
-      next_type = ...;
-      if (next_type == F2C_ALPHA) {
-        while ((x = linetype(++i2)) == F2C_ALPHA) /* noop */ ;
-        if (x == F2C_PERIOD) {
-          range = i1:i2;
-          token = strpart(line_str, range);
-          _f2c_column = i2;
-          return F2C_INTRINSIC;
-        }
-      } else if (next_type == F2C_DIGIT) {
-        
-      }
-      range = i1:i2-1;
-       
-      }
-    }
-    
-
-    
-      do {
-        x = linetype(++i2);
-      } while (x >= F2C_ALPHA && x <= );
-      
-      while (linetype(++i2) == char(++_f2c_column)) == ' ') /* noop */ ;
-    
-    
-  } else {
-    
-  }
-  
-  if (_f2c_index < _f2c_length) {
-    c = linechar(++_f2c_index);
-    type = _f2c_type(c + 1);
-  }
-}
-
-/*
-  -1 - illegal character
-   0 - end-of-file or end-of-line
-   1 - space
-   2 - numerical
-   3 - alphabetical (can be first letter in a variable name or part of
-       variable) 
-   4 - operator or punctuation
-*/
-
-local F2C_DIGIT;
-
-func f2c_init(extended)
-{
-  extern _f2c_type;
-  extern F2C_SPACE;  F2C_SPACE = 1;
-  extern F2C_ALPHA;  F2C_ALPHA = 2;
-  extern F2C_DIGIT;  F2C_DIGIT = 3;
-  extern F2C_DOLLAR; F2C_DOLLAR = 4;
-
-  extern F2C_OPEN; F2C_OPEN = ;
-  extern F2C_; F2C_ = ;
-  
-  if (F2C_DIGIT != F2C_ALPHA + 1 ||
-      F2C_DOLLAR != F2C_ALPHA + 2) error, "assertion failed";
-  
-  _f2c_type = array(-1, 256);
-  _f2c_type('\0' + 1) = 0;
-  _f2c_type('\n' + 1) = 0;
-  _f2c_type(' ' + 1) = 1;
-  _f2c_type(indgen('0'+1:'9'+1)) = F2C_DIGIT;
-  _f2c_type(indgen('A'+1:'Z'+1)) = F2C_ALPHA;
-  _f2c_type(indgen('a'+1:'z'+1)) = F2C_ALPHA;
-  _f2c_type('=' + 1) = F2C_ASSIGN;
-  _f2c_type('+' + 1) = F2C_PLUS;
-  _f2c_type('-' + 1) = F2C_MINUS;
-  _f2c_type('*' + 1) = F2C_ASTERISK;
-  _f2c_type('/' + 1) = F2C_SLASH;
-  _f2c_type('(' + 1) = F2C_OPEN;
-  _f2c_type(')' + 1) = F2C_CLOSE;
-  _f2c_type(',' + 1) = F2C_COMMA;
-  _f2c_type('.' + 1) = F2C_PERIOD;
-  _f2c_type('\'' + 1) = F2C_QUOTE;
-
-  if (extended) {
-    _f2c_type('_' + 1) = F2C_ALPHA;
-    _f2c_type('$' + 1) = F2C_NAME;
-  }
-    
-
-  _F2C_IS_ALPHA = array(0n, 256);
-  _F2C_IS_ALPHA(indgen('A'+1:'Z'+1)) = 1n;
-  _F2C_IS_ALPHA(indgen('a'+1:'z'+1)) = 4;
- 
-}
-#endif
diff -Nru yorick-optimpack-1.3.2+dfsg/yorick/history.i yorick-optimpack-1.3.2+dfsg+1.4.0/yorick/history.i
--- yorick-optimpack-1.3.2+dfsg/yorick/history.i	2003-03-17 13:04:27.000000000 +0000
+++ yorick-optimpack-1.3.2+dfsg+1.4.0/yorick/history.i	1970-01-01 00:00:00.000000000 +0000
@@ -1,72 +0,0 @@
-#include "/work/home/eric/work/yeti-5.3.3/optimpack/yorick/op_deconv.i"
-#include "/work/home/eric/work/yeti-5.3.3/optimpack/yorick/op_deconv.i"
-#include "/work/home/eric/work/deconvolution/yan-0.1.0/deconv_sn1987a_init.i"
-x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1)
-#include "/work/home/eric/work/yeti-5.3.3/optimpack/yorick/op_deconv.i"
-x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1)
-#include "/work/home/eric/work/yeti-5.3.3/optimpack/yorick/op_deconv.i"
-x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1)
-
-info,lkl_h
-dbexit
-#include "/work/home/eric/work/yeti-5.3.3/optimpack/yorick/op_deconv.i"
-x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1)
-#include "/work/home/eric/work/yeti-5.3.3/optimpack/yorick/optimpack.i"
-x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1)
-x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=0)
-#include "/work/home/eric/work/yeti-5.3.3/optimpack/yorick/op_deconv.i"
-x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=0)
-
-m
-n
-#include "/work/home/eric/work/yeti-5.3.3/optimpack/yorick/op_deconv.i"
-dbexit
-x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=0)
-#include "/home/eric/work/yeti-5.3.3/optimpack/yorick/lbfgsb.i"
-x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=0)
-x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=0,beta=0)
-pli,x;
-palette,"stern.gp"
-x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=0,beta=0,mu=0.1)
-x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=1,beta=0,mu=0.1)
-x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=2,beta=0,mu=0.1)
-fma;pli,x;
-x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=2,beta=0,mu=10.)
-fma;pli,x;
-x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=2,beta=1,mu=10.)
-fma;pli,x;
-x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=2,beta=1,mu=10.)
-x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=1,beta=1,mu=10.)
-fma;pli,x;
-x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=1,beta=1,mu=1e2)
-fma;pli,x;
-x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=1,beta=1,mu=1e4)
-fma;pli,x;
-x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=1,beta=0,mu=1e4)
-x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=1,beta=0,mu=1e6)
-fma;pli,x;
-x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=1,beta=0,mu=1e9)
-fma;pli,x;
-x=[]
-x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=1,beta=0,mu=1e9)
-x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=1,beta=0,mu=1e9)
-fma;pli,x;
-x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=2,beta=0,mu=1e9)
-x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=2,beta=0,mu=1e9,frtol=1e-15)
-x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=2,beta=0,mu=1e8,frtol=1e-15)
-fma;pli,x;
-x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=2,beta=0,mu=1e7,frtol=1e-15)
-fma;pli,x;
-x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=2,beta=0,mu=1e6,frtol=1e-15)
-x = op_deconv(img,psf,x,entropy=1,maxiter=10,verb=1,method=2,beta=0,mu=1e6,frtol=1e-15)
-fma;pli,x;
-fma;pli,log(x);
-x = op_deconv(img,psf,,entropy=1,maxiter=10,verb=1,method=2,beta=0,mu=1e6,frtol=1e-15)
-fma;pli,x;
-fma;pli,log(x);
-x = op_deconv(img,psf,,entropy=1,maxiter=10,verb=1,method=1,beta=0,mu=1e6,frtol=1e-15)
-#include "/work/home/eric/work/yeti-5.3.3/optimpack/yorick/op_deconv.i"
-x = op_deconv(img,psf,,entropy=1,maxiter=10,verb=1,method=1,beta=0,mu=1e6,frtol=1e-15)
-x = op_deconv(img,psf,,entropy=1,maxiter=10,verb=1,method=2,beta=0,mu=1e6,frtol=1e-15)
-x = op_deconv(img,psf,,entropy=1,maxiter=10,verb=1,method=2,beta=0,mu=1e7,frtol=1e-15)
-fma;pli,x;
diff -Nru yorick-optimpack-1.3.2+dfsg/yorick/Makefile yorick-optimpack-1.3.2+dfsg+1.4.0/yorick/Makefile
--- yorick-optimpack-1.3.2+dfsg/yorick/Makefile	2009-04-23 10:37:47.000000000 +0000
+++ yorick-optimpack-1.3.2+dfsg+1.4.0/yorick/Makefile	2017-01-10 22:16:57.000000000 +0000
@@ -1,58 +1,62 @@
-#                                                              -*- Makefile -*-
+#
 # Makefile --
 #
-#	Makefile for YOP (Yorick + OptimPack).
+# Makefile for YOPL (Yorick + OptimPackLegacy).
+#
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2003, 2016 Éric Thiébaut.
+#
+# This file is part of OptimPack .
 #
-# History:
-#	$Id: Makefile,v 1.2 2007/07/05 09:20:55 eric Exp $
-#	$Log: Makefile,v $
-#	Revision 1.2  2007/07/05 09:20:55  eric
-#	Changed 'optimpack.i' into 'OptimPack1.i' to avoid confusion
-#	with pure Yorick implementation of OptimPack.
+# OptimPack is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
 #
-#	Revision 1.1  2007/07/05 09:10:00  eric
-#	Initial revision
+# OptimPack is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with OptimPack (file "LICENSE" in the top source directory); if not,
+# write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+# Boston, MA 02111-1307 USA
 #
 #------------------------------------------------------------------------------
 
-# Comment out the following definitions if you don't want LBFGS:
-#LBFGS_OBJS = lbfgs.o lbfgs_wrapper.o
-#LBFGS_I    = lbfgs.i
-
-# Comment out the following definitions if you don't want LBFGSB:
-#LBFGS_OBJS = lbfgsb.o lbfgsb_wrapper.o
-#LBFGS_I    = lbfgsb.i
-
-OPTIMPACK_OBJS = op_lnsrch.o op_utils.o op_vmlmb.o
+srcdir = .
 
 # ---------------------------------------------------------------- Yorick setup
-# these values filled in by    yorick -batch make.i
-Y_MAKEDIR=/usr/local/libexec/yorick
-Y_EXE=/usr/local/libexec/yorick/bin/yorick
+# these values filled in by `yorick -batch make.i`
+Y_MAKEDIR=
+Y_EXE=
 Y_EXE_PKGS=
-Y_EXE_HOME=/usr/local/libexec/yorick
-Y_EXE_SITE=/usr/local/libexec/yorick
+Y_EXE_HOME=
+Y_EXE_SITE=
+Y_HOME_PKG=
 
 # ---------------------------------------------------------- optimization flags
 
-# options for make command line, e.g.-   make COPT=-g TGT=exe
+# options for make command line, e.g. `make COPT=-g TGT=exe`
 COPT=$(COPT_DEFAULT)
 TGT=$(DEFAULT_TGT)
 
 # ----------------------------------------------------- macros for this package
 
-PKG_NAME=OptimPack1
-PKG_I=OptimPack1.i
+PKG_NAME=optimpacklegacy
+PKG_I=optimpacklegacy.i
 
-OBJS= $(LBFGS_OBJS) $(LBFGSB_OBJS) $(OPTIMPACK_OBJS)
+OBJS= opl_algebra.o opl_lnsrch.o opl_utils.o opl_vmlmb.o opl_yorick.o
 
 # change to give the executable a name other than yorick
 PKG_EXENAME=yorick
 
-# PKG_DEPLIBS=-Lsomedir -lsomelib   for dependencies of this package
+# `PKG_DEPLIBS=-Lsomedir -lsomelib` for dependencies of this package
 PKG_DEPLIBS=
 # set compiler (or rarely loader) flags specific to this package
-PKG_CFLAGS= -DOP_INTEGER=long
+PKG_CFLAGS= -DOPL_INTEGER=long
 PKG_LDFLAGS=
 
 # list of additional package names you want in PKG_EXENAME
@@ -63,7 +67,8 @@
 PKG_CLEAN=
 
 # autoload file for this package, if any
-PKG_I_START=$(LBFGSB_I) $(LBFGS_I)
+PKG_I_START= optimpacklegacy-start.i
+
 # non-pkg.i include files for this package, if any
 PKG_I_EXTRA=
 
@@ -76,9 +81,13 @@
 PKG_I_DEPS=$(PKG_I)
 Y_DISTMAKE=distmake
 
+ifeq (,$(strip $(Y_MAKEDIR)))
+$(info *** WARNING: Y_MAKEDIR not defined, you may run 'yorick -batch make.i' first)
+else
 include $(Y_MAKEDIR)/Make.cfg
 include $(Y_MAKEDIR)/Makepkg
 include $(Y_MAKEDIR)/Make$(TGT)
+endif
 
 # override macros Makepkg sets for rules and other macros
 # Y_HOME and Y_SITE in Make.cfg may not be correct (e.g.- relocatable)
@@ -90,34 +99,19 @@
 
 # ------------------------------------------ targets and rules for this package
 
+# Directory where are the OptimPack sources:
+OPT_SRC = $(srcdir)/../src
+
 # simple example:
 #myfunc.o: myapi.h
 # more complex example (also consider using PKG_CFLAGS above):
 #myfunc.o: myapi.h myfunc.c
 #	$(CC) $(CPPFLAGS) $(CFLAGS) -DMY_SWITCH -o $@ -c myfunc.c
 
-#op_lnsrch.o: ../op_lnsrch.c ../optimpack.h
-#	$(CC) $(CPPFLAGS) $(CFLAGS) -c ../$(@:.o=.c) -o $@
-#op_vmlmb.o: ../op_vmlmb.c ../optimpack.h
-#	$(CC) $(CPPFLAGS) $(CFLAGS) -c ../$(@:.o=.c) -o $@
-#op_cgmnb.o: ../op_cgmnb.c ../optimpack.h
-#	$(CC) $(CPPFLAGS) $(CFLAGS) -c ../$(@:.o=.c) -o $@
-#op_utils.o: ../op_utils.c ../optimpack.h
-#	$(CC) $(CPPFLAGS) $(CFLAGS) -c ../$(@:.o=.c) -o $@
-
-op_%.o: ../op_%.c ../optimpack.h
-	$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -c $<
-
-# L-BGFS-B stuff:
-lbfgsb_wrapper.o: lbfgsb_wrapper.c
-	$(CC) $(CFLAGS) -c $<
-lbfgsb.o: lbfgsb.f
-	$(FC) $(FFLAGS) -c $<
-
-# L-BGFS stuff:
-lbfgs_wrapper.o: lbfgs_wrapper.c
-	$(CC) $(CFLAGS) -c $<
-lbfgs.o: lbfgs.f
-	$(FC) $(FFLAGS) -c $<
+opl_yorick.o: $(srcdir)/opl_yorick.c $(OPT_SRC)/optimpacklegacy.h
+	$(CC) $(CPPFLAGS) -I$(OPT_SRC) $(CFLAGS) -o $@ -c $<
+
+opl_%.o: $(OPT_SRC)/opl_%.c $(OPT_SRC)/opl_private.h $(OPT_SRC)/optimpacklegacy.h
+	$(CC) $(CPPFLAGS) -I$(OPT_SRC) $(CFLAGS) -o $@ -c $<
 
 # ------------------------------------------------------------- end of Makefile
diff -Nru yorick-optimpack-1.3.2+dfsg/yorick/mira-debug.i yorick-optimpack-1.3.2+dfsg+1.4.0/yorick/mira-debug.i
--- yorick-optimpack-1.3.2+dfsg/yorick/mira-debug.i	2009-04-23 11:58:21.000000000 +0000
+++ yorick-optimpack-1.3.2+dfsg+1.4.0/yorick/mira-debug.i	1970-01-01 00:00:00.000000000 +0000
@@ -1,86 +0,0 @@
-#! /usr/local/bin/yorick -i
-
-plug_dir, "~/work/OptimPack-1.3/yorick/";
-include, "~/work/OptimPack-1.3/yorick/OptimPack1.i";
-include, "yeti_fftw.i";
-include, "~/work/mira/src/mira.i";
-
-/* Load OI-FITS data file ('mh1' will be our MIRA instance for this
-   data file; if there are several spectral channels in the data file,
-   you must choose one with keyword EFF_WAVE or choose a spectral
-   range with keywords EFF_WAVE and EFF_BAND): */
-mh1 = mira_new(MIRA_HOME+"data/data1.oifits");
-
-/* Configure data instance for image reconstruction parameters (DIM is
-   the number of pixels along the width and height of the restored
-   image; FOV is the size of the corresponding field of view in
-   radians; XFORM is the name of the method to approximate the Fourier
-   transform, can be "exact" or "fft", default is "exact"): */
-mira_config, mh1, dim=256, pixelsize=0.1*MIRA_MILLIARCSECOND, xform="fft";
-
-/* Smooth support. */
-dim = mira_get_dim(mh1);
-r = abs(mira_get_x(mh1), mira_get_x(mh1)(-,));
-prior = 1.0/(1.0 + (2.0*r/(5.0*MIRA_MILLIARCSECOND))^2);
-prior *= 1.0/sum(prior);
-rgl_config, (rgl = rgl_new("quadratic")), "W", linop_new("diagonal", 1.0/prior);
-
-
-
-if (! window_exists(0)) {
-  window, 0, style="work.gs", dpi=75, width=550, height=450;
-} else {
-  window, 0, style="work.gs";
-}
-limits,10,-10,-10,10;
-palette, "heat.gp";
-
-if (! window_exists(1)) {
-  window, 1, style="work.gs", dpi=75, width=450, height=450;
-} else {
-  window, 1, style="work.gs";
-}
-palette, "heat.gp";
-
-/*---------------------------------------------------------------------------*/
-/* RECONSTRUCTION WITH PHASE CLOSURE */
-
-/*  seed  rotated  final penalty
- *   0.1  yes      4.94723e3 (viusaly the best)
- *   0.2  bad      6.95202e3
- *   0.3  bad      6.96364e3
- *   0.4  yes      4.96052e3
- *   0.5  bad      6.95272e3
- *   0.6  no       7.27172e3
- *   0.7  bad      6.67580e3
- *   0.8  no       4.94379e3
- *   0.9  bad      5.62120e3
- *   1.0  yes      4.91903e3
- */
-random_seed, (is_func(fftw) ? 0.2 : 0.7);
-img0 = random(dim, dim);
-
-rdline, prompt="hit [Return] to start reconstruction";
-img1 = mira_solve(mh1, img0, maxeval=0, verb=1, xmin=0.0, normalization=1, regul=rgl, mu=1e5, view=3, title="Reconstruction with phase closure");
-rdline, prompt="hit [Return] to continue reconstruction";
-img1 = mira_solve(mh1, img1, maxeval=100, verb=1, xmin=0.0, normalization=1, regul=rgl, mu=1e5, view=3, title="Reconstruction with phase closure");
-img1 = mira_solve(mh1, img1, maxeval=100, verb=1, xmin=0.0, normalization=1, regul=rgl, mu=1e4, view=3, title="Reconstruction with phase closure");
-img1 = mira_solve(mh1, img1, maxeval=200, verb=1, xmin=0.0, normalization=1, regul=rgl, mu=1e3, view=3, title="Reconstruction with phase closure");
-rdline, prompt="hit [Return] to start reconstruction";
-
-random_seed, (is_func(fftw) ? 0.1 : 0.7);
-img0 = random(dim, dim)//(::-1,::-1);
-
-img4 = mira_solve(mh1, img0, maxeval=0, verb=1, xmin=0.0, normalization=1, regul=rgl, mu=1e5, zap_phase=1, view=3, title="Reconstruction with no phase data");
-rdline, prompt="hit [Return] to start reconstruction";
-img4 = mira_solve(mh1, img0, maxeval=50, verb=1, xmin=0.0, normalization=1, regul=rgl, mu=1e5, zap_phase=1, view=3, title="Reconstruction with no phase data");
-img4 = mira_solve(mh1, img4, maxeval=50, verb=1, xmin=0.0, normalization=1, regul=rgl, mu=5e4, zap_phase=1, view=3, title="Reconstruction with no phase data");
-img4 = mira_solve(mh1, img4, maxeval=50, verb=1, xmin=0.0, normalization=1, regul=rgl, mu=2e4, zap_phase=1, view=3, title="Reconstruction with no phase data");
-img4 = mira_solve(mh1, img4, maxeval=50, verb=1, xmin=0.0, normalization=1, regul=rgl, mu=1e4, zap_phase=1, view=3, title="Reconstruction with no phase data");
-img4 = mira_solve(mh1, img4, maxeval=50, verb=1, xmin=0.0, normalization=1, regul=rgl, mu=5e3, zap_phase=1, view=3, title="Reconstruction with no phase data");
-img4 = mira_solve(mh1, img4, maxeval=70, verb=1, xmin=0.0, normalization=1, regul=rgl, mu=3e3, zap_phase=1, view=3, title="Reconstruction with no phase data");
-//img4 = mira_solve(mh1, img4, maxeval=50, verb=1, xmin=0.0, normalization=1, regul=rgl, mu=2e3, zap_phase=1, view=3, title="Reconstruction with no phase data");
-//img4 = mira_solve(mh1, img4, maxeval=50, verb=1, xmin=0.0, normalization=1, regul=rgl, mu=1e3, zap_phase=1, view=3, title="Reconstruction with no phase data");
-
-rdline, prompt="hit [Return] to turn the image";
-img4 = mira_solve(mh1, img4(::-1,::-1), maxeval=70, verb=1, xmin=0.0, normalization=1, regul=rgl, mu=3e3, zap_phase=1, view=3, title="Reconstruction with no phase data");
diff -Nru yorick-optimpack-1.3.2+dfsg/yorick/op_deconv.i yorick-optimpack-1.3.2+dfsg+1.4.0/yorick/op_deconv.i
--- yorick-optimpack-1.3.2+dfsg/yorick/op_deconv.i	2007-07-11 06:16:26.000000000 +0000
+++ yorick-optimpack-1.3.2+dfsg+1.4.0/yorick/op_deconv.i	1970-01-01 00:00:00.000000000 +0000
@@ -1,564 +0,0 @@
-/*
- * op_deconv.i
- *
- *	Regularized deconvolution in Yorick by various iterative optimization
- *	methods.
- */
-
-require, "fft_utils.i";
-
-func mks(n)
-{
-  a = array(long, n, n);
-  a(1,1) = 3;
-  a(0,0) = 3;
-  if (n >= 3) a(n+2:n*(n-1)-1:n+1) = 2;
-  a(2:n*(n-1):n+1) = 1;
-  a(n+1:n*n-1:n+1) = 1;
-  return 0.25*a;
-}
-
-
-
-
-func op_deconv(data, psf, x, weight=, rescale=, positive=,
-               maxeval=, maxiter=, ndirs=, verb=, output=, save=,
-               frtol=, fatol=, factr=, method=,
-               mu=, wiener=, bootstrap=, normalize=,
-               entropy=, beta=, prior=, tiny=,
-               tikhonov=, roughness=)
-/* DOCUMENT op_deconv(data, psf)
-       -or- op_deconv(data, psf, x)
-
-
-       FIXME:
-       
-     Returns the deconvolution  of DATA by PSF; X  is the optional starting
-     solution.   The  solution  is   obtained  by  minimizing  the  penalty
-     function:
-
-       psi(X) = LKL(X) + MU*RGL(X)
-       
-     where RGL is a regularization term (see below) and the likelihood term
-     is:
-       
-       LKL(X) = 0.5*sum(WEIGHT*(model(X) - DATA)^2)
-
-     where WEIGHT is given by the value of optional keyword WEIGHT (default
-     is WEIGHT=1.0), PRIOR is given  by the value of optional keyword PRIOR
-     (default is PRIOR=0.0) and model(X) is the model of the data:
-
-       model(X) = inverse_fft(fft(PSF)*fft(X)))
-
-
-     If keyword SAVE is true, then if first least significant bit of SAVE
-     is set (i.e. SAVE&1 == 1) the model is saved in external variable
-     op_deconv_model and/or if second least significant bit of SAVE is set
-     (i.e. SAVE&2 == 2) the penalty is saved in external variable
-     op_deconv_penalty:
-        op_deconv_penalty(1) = MU
-        op_deconv_penalty(2) = LKL
-        op_deconv_penalty(3) = RGL
-
-     Keyword METHOD:
-       METHOD = 0   - LBFGSB
-              = 1   - VMLMB (no preconditioning)
-              = 2   - VMLMB with preconditioning
-              = 3   - conjugate gradient (Fletcher-Reeves)
-              = 4   - conjugate gradient (Polak-Ribiére)
-              = 5   - conjugate gradient (Polak-Ribiére with positive BETA)
-     the default is METHOD=2
-     
-     If keyword BOOTSTRAP is true and X is not specified, then the starting
-     solution is the solution of:
-
-       X0 = arg min sum((model(X) - DATA)^2) + sum(PRIOR*abs(fft(X))^2)
-          = arg min   sum(abs(fft(PSF)*fft(X) - fft(DATA))^2)
-                    + N*sum(PRIOR*abs(fft(X))^2)
-          = inverse_fft(conj(fft(PSF))*fft(DATA)/(abs(fft(PSF))^2 + N*PRIOR))
-            
-      with N=numberof(DATA).
-            
-      The definitions of the forward and backward FFT's are:
-        fft(X) = fft(X, -1)
-        inverse_fft(X) = (1.0/numberof(X))*double(fft(X, +1))
-
-      With these definitions, Parseval's theorem reads:
-        sum(abs(X)^2) = (1.0/numberof(X))*sum(abs(fft(X))^2)
-
-      Keyword MU can be used to set the level of regularization (by default
-      MU=1,  if some regularization  is used;  MU=0 otherwise).   There are
-      several types of regularization:
-
-       - Wiener regularization is used if WIENER keyword is set. The Wiener
-         regularization term is:
- 
-           RGL_WIENER(X) = sum(WIENER*abs(fft(X))^2)
-           
-         The regularized unconstrained Wiener solution is given by:
-         
-           fft(X_WIENER) = conj(MTF)*fft(DATA)/(abs(MTF)^2 + MU*WIENER)
-
-         If no  initial X  is specified, X_WIENER  is used as  the starting
-         solution to find the constrained solution unless keyword BOOTSTRAP
-         is explicitely set to 0.
-
-       - Maximum entropy regularization is  used if keyword ENTROPY is true
-         (non-nil and non-zero).  In this case, the regularization term is:
-
-           RGL_ENTROPY(X) = BETA*KL(X, PRIOR) + (1 - BETA)*KL(PRIOR, X)
-
-         where KL() is the Kullback-Leibler distance between the solution X
-         and an a priori or default solution PRIOR.  KL is defined by:
-
-           KL(X, P) = sum(X*log(X/P) + P - X)
-
-         Keyword PRIOR  can be used to  specify the a priori,  by default a
-         uniform prior is used.
-         
-         Keyword  BETA  can  be  used  to  adjust  the  definition  of  the
-         regularization  term (by  default, BETA=0.5).   The regularization
-         term reduces to the negative  Shannon entropy if BETA=1 and to the
-         negative Burg entropy if BETA=0.
-
-       - Tikhonov regularization is used
-      
-
-         This solution is obtained  value
-         of the WIENER keyword is the Fourier weigths:
-       
-     
-   SEE ALSO: deconv_lbfgsb. */
-{
-  require, "optim_pack.i";
-
-  /* Setup for optional outputs. */
-  extern op_deconv_model, op_deconv_penalty;
-  if (! save) {
-    save_model = save_penalty = 0n;
-  } else {
-    save_model   = (save&1 ? 1n : 0n);
-    save_penalty = (save&2 ? 1n : 0n);
-  }
-
-  /* Initialize FFT stuff and compute MTF = FFT(PSF). */
-  local __fft_setup, __fft_number;
-  dims = dimsof(data);
-  __fft_init, dims;
-  fft = __fft;
-  mtf = fft(psf, -1);
-  conj_mtf = conj(mtf);
-  fft_scale = 1.0/numberof(data);
-
-  /* Type of regularization. */
-  regul = ((is_void(wiener) ? 0 : 1)
-           + (anyof(tikhonov)  ? 2 : 0)
-           + (roughness ? 4 : 0)
-           + (entropy   ? 8 : 0));
-  if (is_void(mu)) mu = (regul ? 1.0 : 0.0);
-  xmin = 0.0;
-  if (regul == 0) {
-    /* No regularization. */
-    op = __op_deconv;
-  } else if (regul == 1) {
-    /* Wiener regularization. */
-    op = __op_deconv_wiener;
-    if (mu != 1.0) wiener *= mu;
-  } else if (regul == 2) {
-    /* Tikhonov regularization. */
-    op = __op_deconv_tikhonov;
-  } else if (regul == 4) {
-    /* Roughness regularization. */
-    op = (roughness==2 ? __op_deconv_relative_roughness
-                       : __op_deconv_absolute_roughness);
-  } else if (regul == 8) {
-    /* Regularization by maximum entropy. */
-    op = __op_deconv_entropy;
-    positive = 1n; /* force positivity for maximum entropy method */
-    if (is_void(beta)) beta = 0.5;
-    else if (beta < 0.0 || beta > 1.0) error, "bad value for BETA";
-    if (is_void(tiny)) tiny = 1e-30;
-    else if (tiny <= 0.0) error, "TINY must be strictly positive";
-    xavg = (normalize ? 1.0/numberof(data) : avg(data)/sum(psf));
-    if (is_void(prior))
-      prior = array(xavg, dimsof(data)); /* Uniform prior by default. */
-    xmin = tiny*xavg;
-  } else {
-    error, "only one of WIENER, TIKHONOV, ROUGHNESS or ENTROPY is allowed";
-  }
-  
-  /* Starting solution. */
-  if (is_void(x)) {
-    if (bootstrap) {
-      x = fft(data, -1);
-      if (is_void(wiener)) x /= mtf;
-      else x *= conj_mtf/(abs2(mtf) + numberof(data)*wiener);
-      x = fft_scale*double(fft(x, +1));
-    } else {
-      x = array(avg(data)/sum(psf), dims);
-    }
-  }
-
-  /* Initialization of workspace according to optimization method
-     and options. */
-  if (is_void(frtol)) frtol = 1e-8;
-  if (is_void(fatol)) fatol = 0.0;
-  if (is_void(factr)) factr = 1e7;
-  if (is_void(method)) method = 2; /* default is VMLMB with preconditioning */
-  if (positive || method == 0) {
-    /* Apply constraints and make XMIN an array to speedup things and
-       because this is required by LBFGSB. */
-    xmin = array(xmin, dims);
-    if (positive) x = max(x, xmin);
-  }
-  precond = 0n;
-  if (is_void(ndirs)) ndirs = 5;
-  if (method == 0) {
-    /* Use L-BFGS-B method. */
-    if (! is_func(op_lbfgsb))
-      error, "you must have L-BFGS-B compiled in Yorick";
-    bnd = array((positive ? 1 : 0), dims);
-    pgtol = 0.0;
-    ws = op_lbfgsb_setup(ndirs, x, xmin, xmin /* unused upper bound */,
-                         bnd, factr, pgtol);
-    get_msg = op_lbfgsb_msg;
-  } else if (method == 1 || method == 2) {
-    /* Use variable metric. */
-    fmin = 0.0; // FIXME:
-    ws = op_vmlmb_setup(numberof(data), ndirs, fmin, fatol=fatol, frtol=frtol);
-    get_msg = op_vmlmb_msg;
-    if (method == 2) precond = 1n;
-  } else {
-    error, "bad METHOD";
-  }
-  job = 1;
-
-  /* Do we need to explicitely apply constraints (not needed fo LBFGSB)? */
-  apply_constraints = (positive && method != 0);
-  
-  /* Prepare for verbose output. */
-  if (verb) {
-    if (is_void(output)) {
-      prefix = " ";
-    } else {
-      if (structof(output) == string) {
-        output = open(output, "a");
-      } else if (typeof(output) != "text_stream") {
-        error, "bad value for keyword OUTPUT";
-      }
-      prefix = "#";
-    }
-    write, output, format="%s%s\n%s%s\n", prefix,
-      "ITER  EVAL   FFT          PENALTY         LIKELIHOOD      REGUL.",
-      prefix,
-      "----  ----  -----  ---------------------  -----------  -----------";
-  }
-
-  /* Optimization loop. */
-  iter = eval = 0;
-  for (;;) {
-    local lkl, lkl_h, rgl, rgl_h, grd, h, prior_over_x, sum_x; /* ouputs */
-    
-    if (job == 1) {
-      /* Compute function and gradient. */
-
-      /* Apply constraints. */
-      if (apply_constraints) x = max(x, xmin);
-
-      /* Compute model. */
-      fft_x = fft(x, -1);
-      model = fft_scale*double(fft(mtf*fft_x, +1));
-      scale = (rescale ? op_deconv_scale() : 1.0);
-      if (rescale) {
-        if ((scale = op_deconv_scale(data, model, weight)) != 1.0) {
-          model *= scale;
-        }
-      } else {
-        scale = 1.0;
-      }
-
-      /* Compute penalty. */
-      op, 1;
-      err = lkl + mu*rgl;
-      ++eval;
-    }
-
-    // FIXME: hack to save best solution found so far
-    local best_err;
-    if (eval == 1 || err < best_err) {
-      if (save_model) eq_nocopy, op_deconv_model, model;
-      best_err = err;
-      best_x = (scale == 1.0 ? x : scale*x);
-    }
-
-    /* Check for convergence and, possibly, print iteration values. */
-    if (job != 1 || eval == 1) {
-      if (job == 2 || job == 3) ++iter;
-      if ((stop = (job >= 3))) {
-        msg = get_msg(ws);
-      } else if ((stop = (! is_void(maxiter) && iter >= maxiter))) {
-        msg = swrite(format="warning: too many iterations (%d)", iter);
-      } else if ((stop = (! is_void(maxeval) && eval >= maxeval))) {
-        msg = swrite(format="warning: too many function evaluations (%d)",
-                     eval);
-      }
-      if (verb && (stop || iter%verb == 0)) {
-        write, output, format=" %4d  %4d  %5d  %-22.14e %-11.3e %-11.3e\n",
-          iter, eval, __fft_number, err, lkl, rgl;
-      }
-      if (stop) {
-        /* Return current solution. */
-        if (verb || job != 3) write, output, format=prefix+"%s\n", msg;
-        if (save_penalty) op_deconv_penalty = [mu, lkl, rgl];
-        return best_x;
-      }
-    }
-
-    /* Call optimizer. */
-    if (method == 0) {
-      job = op_lbfgsb(x, err, grd, ws);
-    } else {
-      local h, active;
-      if (job != 1 || eval == 1) {
-        if (positive) active = (x > xmin) | (grd < 0.0);
-        if (precond) op, 0;
-      }
-      //info, h;
-      job = op_vmlmb_next(x, err, grd, ws, active, h);
-    }
-  }
-#if 0
-    if (0) {
-      if (is_void(weight)) {
-        alpha = sum(psf*psf);
-      } else {
-        alpha = fft_scale*double(fft(fft(weight, -1)*fft(psf*psf, -1), +1));
-      }
-    } else {
-      if (is_void(weight)) {
-        alpha = fft_scale*double(fft(abs2(mtf), +1));
-      } else {
-        alpha = fft_scale*double(fft(fft(weight, -1)*abs2(mtf), +1));
-      }
-    }
-    if (numberof(alpha) > 1) {
-      window,7;fma;pli,alpha;palette,"stern.gp";pause,1;
-    }
-    if (entropy) {
-      tmp = x*x;
-      tmp /= ((1.0 - beta)*prior + beta*x + alpha*tmp);
-      next_stage, x, psi, grd, task, ws, bnd, tmp;
-      tmp = [];
-    } else {
-      if (first_time) {
-        tmp_i = 0;
-        tmp_stride = 1;
-        tmp_dims = dimsof(x);
-        tmp_n = numberof(tmp_dims);
-        tmp = array(0.0, tmp_dims);
-        for (k=2;k<=tmp_n;++k) {
-          tmp_i = tmp_i*tmp_stride + tmp_dims(k)/2;
-          tmp_stride *= tmp_dims(k);
-        }
-        tmp(tmp_i) = mu;
-        tmp = ((smooth(tmp) - tmp)(tmp_i))^2;
-        write, tmp;
-        alpha = 1.0/(alpha + tmp);
-      }
-      next_stage, x, psi, grd, task, ws, bnd, alpha;
-    }
-    first_time = 0n;
-#endif
-}
-
-
-
-/* KL entropy:
-   
-
-rgl = (2.0*beta - 1.0)*(p - x) + ((beta - 1.0)*p + beta*x)*log(x/p);
-grd = (1.0 - beta)*(1.0 - p/x) + beta*log(x/p);
-hes = ((1.0 - beta)*(p/x) + beta)/x;
-
-u = p/x;
- l = log(u);
- rgl = (2.0*beta - 1.0)*(p - x) + ((1.0 - beta)*p - beta*x)*l;
- grd = (1.0 - beta)*(1.0 - u) - beta*l;
- hes = ((1.0 - beta)*u + beta)/x;
-
- h = 1/diag(H)
-   = 1/(lkl_h + mu*rgl_h)
-   = x/(lkl_h*x + mu*((1.0 - beta)*u + beta));
-*/
-
-func __op_deconv_entropy(job)
-{
-  extern h, lkl_h, rgl_h;
-  extern lkl, rgl, grd; /* ouputs */
-  extern prior_over_x;
-  if (job == 1) {
-    /* Compute likelihood term and its gradient. */
-    local weight_r;
-    r = model - data; /* anti-residuals */
-    if (is_void(weight)) eq_nocopy, weight_r, r;
-    else weight_r = weight*r;
-    grd = double(fft(conj_mtf*fft((fft_scale*scale)*weight_r, -1), +1));
-    lkl = 0.5*sum(weight_r*r);
-
-    /* Compute regularization. */
-    prior_over_x = prior/x;
-    log_prior_over_x = log(prior_over_x);
-    rgl = sum((2.0*beta - 1.0)*(prior - x) +
-              ((1.0 - beta)*prior - beta*x)*log_prior_over_x);
-    grd += mu*((1.0 - beta)*(1.0 - prior_over_x) - beta*log_prior_over_x);
-  } else {
-    /* Compute preconditioning. */
-    if (is_void(lkl_h)) {
-      lkl_h = (is_void(weigth) ? sum(psf*psf) :
-               fft_scale*double(fft(fft(weigth, -1)*fft(psf*psf, -1), +1)));
-    }
-    h = x/(lkl_h*x + mu*((1.0 - beta)*prior_over_x + beta));
-  }
-}
-
-
-func op_deconv_scale(data, model, weight)
-/* DOCUMENT op_deconv_scale(data, model)
-       -or- op_deconv_scale(data, model, weight)
-     Computes and returns the scale ALPHA such that the following quantity
-     is minimized:
-        sum(WEIGHT*(ALPHA*MODEL - DATA)^2)
-     or sum((ALPHA*MODEL - DATA)^2)          if WEIGHT is missing.
-     
-   SEE ALSO: op_deconv. */
-{
-  if (is_void(weight)) {
-    if ((tmp = sum(model*model)) > 0.0) return sum(model*data)/tmp;
-  } else if ((tmp = sum((weight_model = weight*model)*model)) > 0.0) {
-    return sum(weight_model*data)/tmp;
-  }
-  return 1.0;
-}
-
-func __op_deconv
-{
-  extern lkl, rgl, grd; /* ouputs */
-  
-  /* Compute likelihood term and (FFT of) gradient. */
-  local weight_r;
-  r = model - data; /* anti-residuals */
-  if (is_void(weight)) eq_nocopy, weight_r, r;
-  else weight_r = weight*r;
-  grd = double(fft(conj_mtf*fft((fft_scale*scale)*weight_r, -1), +1));
-  lkl = 0.5*sum(weight_r*r);
-  rgl = 0.0;
-}
-
-func __op_deconv_tikhonov
-{
-  extern lkl, rgl, grd, sum_x; /* ouputs */
-  
-  /* Compute likelihood term and (FFT of) gradient. */
-  local weight_r;
-  r = model - data; /* anti-residuals */
-  if (is_void(weight)) eq_nocopy, weight_r, r;
-  else weight_r = weight*r;
-  grd = double(fft(conj_mtf*fft((fft_scale*scale)*weight_r, -1), +1));
-  rgl = 0.5*sum(weight_r*r);
-  weight_r = r = [];
-
-  if (normalize) {
-    if ((sum_x = sum(x)) > 0.0) {
-      u = x*(1.0/sum_x);
-      v = tikhonov*u;
-      uv = sum(u*v);
-      grd += (mu/sum_x)*(v - uv);
-      rgl = 0.5*uv;
-      u = v = [];
-    } else {
-      rgl = 0.0;
-    }
-  } else {
-    v = tikhonov*x;
-    rgl = 0.5*sum(v*x);
-    grd += mu*v;
-  }
-}
-
-func __op_deconv_roughness
-{
-  extern h, lkl, rgl, grd, sum_x; /* ouputs */
-  
-  /* Compute likelihood term and (FFT of) gradient. */
-  local weight_r;
-  r = model - data; /* anti-residuals */
-  if (is_void(weight)) eq_nocopy, weight_r, r;
-  else weight_r = weight*r;
-  grd = double(fft(conj_mtf*fft((fft_scale*scale)*weight_r, -1), +1));
-  rgl = 0.5*sum(weight_r*r);
-  weight_r = r = [];
-
-  if (precond && eval == 1) {
-    /* Computes the diagonal of the Hessian. */
-    dims = dimsof(x);
-    dims(2:) = 5;
-    r = array(double, dims);
-    r((numberof(r) + 1)/2) = 1.0;
-    r = smooth(r) - r;
-    rgl_h = sum(r*r);
-    if (is_void(weigth)) {
-      lkl_h = sum(psf*psf);
-    } else {
-      lkl_h = fft_scale*double(fft(fft(weigth, -1)*fft(psf*psf, -1), +1));
-    }
-    h = 1.0/(lkl_h + mu*rgl_h);
-  }
-  if (normalize) {
-    if ((sum_x = sum(x)) > 0.0) {
-      u = x*(1.0/sum_x);
-      r = smooth(u) - u;
-      rr = sum(r*r);
-      grd += (mu/sum_x)*(smooth(r) - r - rr);
-      rgl = 0.5*rr;
-    } else {
-      rgl = 0.0;
-    }
-  } else {
-    r = smooth(x) - x;
-    rgl = 0.5*sum(r*r);
-    grd += mu*(smooth(r) - r);
-  }
-}
-
-
-func op_deconv_lcurve(data, psf, x, weight=, rescale=, positive=,
-                      maxeval=, maxiter=, ndirs=, verb=, output=, save=,
-                      frtol=, fatol=, factr=, method=,
-                      mu=, wiener=, bootstrap=, normalize=,
-                      entropy=, beta=, prior=, tiny=,
-                      tikhonov=, roughness=, precond=,
-                      color=, win=, symbol=)
-{
-  /* sort regularization weight in descending order */
-  mu = mu(sort(mu)(::-1));
-  result = array(double, 3, numberof(mu));
-  for (i=1 ; i<=numberof(mu) ; ++i) {
-    local op_deconv_penalty;
-    x = op_deconv(data, psf, x, weight=weight, rescale=rescale,
-                  positive=positive, maxeval=maxeval, maxiter=maxiter,
-                  ndirs=ndirs, verb=verb, output=output, save=2,
-                  frtol=frtol, fatol=fatol, factr=factr, method=method,
-                  mu=mu(i), wiener=wiener, bootstrap=bootstrap,
-                  normalize=normalize, entropy=entropy, beta=beta,
-                  prior=prior, tiny=tiny, tikhonov=tikhonov,
-                  roughness=roughness);
-    q = op_deconv_penalty;
-    if (! is_void(win)) {
-      window, win, wait=1;
-      plp, q(3), q(2), color=color, symbol=symbol;
-      pause, 1;
-    }
-    result(,i) = q;
-  }
-  return result;
-}
diff -Nru yorick-optimpack-1.3.2+dfsg/yorick/opl_yorick.c yorick-optimpack-1.3.2+dfsg+1.4.0/yorick/opl_yorick.c
--- yorick-optimpack-1.3.2+dfsg/yorick/opl_yorick.c	1970-01-01 00:00:00.000000000 +0000
+++ yorick-optimpack-1.3.2+dfsg+1.4.0/yorick/opl_yorick.c	2017-01-10 22:16:57.000000000 +0000
@@ -0,0 +1,649 @@
+/*
+ * opl_yorick.c --
+ *
+ * Yorick interface for OptimPackLegacy library.
+ *
+ *-----------------------------------------------------------------------------
+ *
+ * Copyright (c) 2003, 2016 Éric Thiébaut.
+ *
+ * This file is part of OptimPack .
+ *
+ * OptimPack is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * OptimPack is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * OptimPack (file "LICENSE" in the top source directory); if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307 USA
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Yorick API. */
+#include 
+#include 
+#include 
+
+#include "optimpacklegacy.h"
+
+/* Define some macros to get rid of some GNU extensions when not compiling
+   with GCC. */
+#if ! (defined(__GNUC__) && __GNUC__ > 1)
+#   define __attribute__(x)
+#   define __inline__
+#   define __FUNCTION__        ""
+#   define __PRETTY_FUNCTION__ ""
+#endif
+
+#define TRUE  1
+#define FALSE 0
+
+PLUG_API void y_error(const char *) __attribute__ ((noreturn));
+static void error(const char *, ...) __attribute__ ((noreturn));
+
+/*---------------------------------------------------------------------------*/
+/* PRIVATE FUNCTIONS AND DATA */
+
+/* Indexes for fast parsing of keywords/members. */
+static long index_of_dims = -1;
+static long index_of_size = -1;
+static long index_of_mem = -1;
+static long index_of_task = -1;
+static long index_of_evaluations = -1;
+static long index_of_iterations = -1;
+static long index_of_restarts = -1;
+static long index_of_step = -1;
+static long index_of_gnorm = -1;
+static long index_of_fmin = -1;
+static long index_of_fatol = -1;
+static long index_of_frtol = -1;
+static long index_of_sftol = -1;
+static long index_of_sgtol = -1;
+static long index_of_sxtol = -1;
+static long index_of_delta = -1;
+static long index_of_epsilon = -1;
+static long index_of_status = -1;
+static long index_of_reason = -1;
+
+static void
+error(const char* format, ...)
+{
+  char buffer[256];
+  const size_t size = sizeof(buffer);
+  va_list ap;
+  size_t nchars;
+
+  va_start(ap, format);
+  nchars = vsnprintf(buffer, size, format, ap);
+  va_end(ap);
+  if (nchars >= size) {
+    buffer[size - 6] = '[';
+    buffer[size - 5] = '.';
+    buffer[size - 4] = '.';
+    buffer[size - 3] = '.';
+    buffer[size - 2] = ']';
+    buffer[size - 1] = '\0';
+  }
+  y_error(buffer);
+}
+
+/* Push a string on top of the stack. */
+static void
+push_string(const char* str)
+{
+  ypush_q(NULL)[0] = p_strcpy(str);
+}
+
+/* Define a Yorick global symbol with a long value. */
+static void
+define_long_const(const char* name, long value)
+{
+  ypush_long(value);
+  yput_global(yget_global(name, 0), 0);
+  yarg_drop(1);
+}
+
+/* Get Yorick type name. */
+static const char*
+type_name(int type)
+{
+  switch (type) {
+  case Y_CHAR: return "char";
+  case Y_SHORT: return "short";
+  case Y_INT: return "int";
+  case Y_LONG: return "long";
+  case Y_FLOAT: return "float";
+  case Y_DOUBLE: return "double";
+  case Y_COMPLEX: return "complex";
+  case Y_STRING: return "string";
+  case Y_POINTER: return "pointer";
+  case Y_STRUCT: return "struct";
+  case Y_RANGE: return "range";
+  case Y_VOID: return "void";
+  case Y_FUNCTION: return "function";
+  case Y_BUILTIN: return "builtin";
+  case Y_STRUCTDEF: return "structdef";
+  case Y_STREAM: return "stream";
+  case Y_OPAQUE: return "opaque";
+  default: return "";
+  }
+}
+
+/* Get an array of given type and dimensions. */
+static void*
+get_array(int iarg, int type, const long dims[],
+          const char* name, int nil_ok)
+{
+  int argtype = yarg_typeid(iarg);
+  if (argtype == type) {
+    long argdims[Y_DIMSIZE];
+    long i, rank;
+    void* ptr = ygeta_any(iarg, NULL, argdims, NULL);
+    if (argdims[0] != (rank = dims[0])) {
+      error("bad number of dimensions for argument `%s`", name);
+    }
+    for (i = 1; i <= rank; ++i) {
+      if (argdims[i] != dims[i]) {
+        error("bad dimension(s) for argument `%s`", name);
+      }
+    }
+    return ptr;
+  } else if (nil_ok && argtype == Y_VOID) {
+    return NULL;
+  } else {
+    error("bad data type for argument `%s`", name);
+  }
+  error("argument `%s` must be a %ld-D array of `%s`%s",
+        name, dims[0], type_name(type), (nil_ok ? " our nil" : ""));
+  return NULL;
+}
+
+/* Get a dimension list from the stack. */
+static long
+get_dims(int iarg, long dims[])
+{
+  int type = yarg_typeid(iarg);
+  if (type <= Y_LONG) {
+    long j, n, ntot,  rank;
+    long* arr = ygeta_l(iarg, &n, dims);
+    if (dims[0] == 0 || (dims[0] == 1 && arr[0] == n - 1)) {
+      if (dims[0] == 0) {
+        /* Got a scalar dimension. */
+        rank = 1;
+        arr -= 1; /* offset for indexing with j */
+      } else {
+        /* Got a vector of dimensions. */
+        if (n > Y_DIMSIZE) {
+          y_error("too many dimensions");
+        }
+        rank = n - 1;
+      }
+      ntot = 1;
+      dims[0] = rank;
+      for (j = 1; j <= rank; ++j) {
+        long len = arr[j];
+        if (len < 1) {
+          y_error("invalid dimension(s)");
+        }
+        dims[j] = len;
+        ntot *= len;
+      }
+      return ntot;
+    }
+  } else if (type == Y_VOID) {
+    dims[0] = 0;
+    return 1;
+  }
+  y_error("invalid dimension list");
+  return -1;
+}
+
+/* Function to call before critical code to lower the risk of being
+   interrupted. */
+static void
+critical()
+{
+  if (p_signalling) {
+    p_abort();
+  }
+}
+
+
+/*---------------------------------------------------------------------------*/
+/* IMPLEMENTATION OF VMLMB INSTANCE */
+
+/* Virtual methods for a VMLMB object. */
+static void vmlmb_free(void* ptr);
+static void vmlmb_print(void* ptr);
+static void vmlmb_eval(void* ptr, int argc);
+static void vmlmb_extract(void* ptr, char* name);
+
+/* VMLMB handle type. */
+static struct y_userobj_t vmlmb_type = {
+  "VMLMB workspace", vmlmb_free, vmlmb_print, vmlmb_eval, vmlmb_extract, NULL
+};
+
+/* VMLMB handle instance. (FIXME: save the dimensions as well). */
+typedef struct _vmlmb_object {
+  opl_vmlmb_workspace_t* ws;
+  long n, m;
+  long dims[Y_DIMSIZE];
+} vmlmb_object_t;
+
+static void
+vmlmb_free(void* ptr)
+{
+  opl_vmlmb_destroy(((vmlmb_object_t*)ptr)->ws);
+}
+
+static void
+vmlmb_print(void* ptr)
+{
+  char buffer[128];
+  vmlmb_object_t* obj = (vmlmb_object_t*)ptr;
+  long i, rank = obj->dims[0];
+  sprintf(buffer, "%s with size=%ld, dims=[",
+          vmlmb_type.type_name, obj->n);
+  y_print(buffer, FALSE);
+  for (i = 0; i <= rank; ++i) {
+    sprintf(buffer, (i == 0 ? "%ld" : ",%ld"), obj->dims[i]);
+    y_print(buffer, FALSE);
+  }
+  sprintf(buffer, "], mem=%ld, task=%d",
+          obj->m, opl_vmlmb_get_task(obj->ws));
+  y_print(buffer, TRUE);
+}
+
+static void
+vmlmb_eval(void* ptr, int argc)
+{
+  ypush_nil();
+}
+
+static void
+vmlmb_extract(void* ptr, char* name)
+{
+  vmlmb_object_t* obj = (vmlmb_object_t*)ptr;
+  long index = yget_global(name, 0);
+  if (index == index_of_iterations) {
+    ypush_long(opl_vmlmb_get_iterations(obj->ws));
+  } else if (index == index_of_evaluations) {
+    ypush_long(opl_vmlmb_get_evaluations(obj->ws));
+  } else if (index == index_of_restarts) {
+    ypush_long(opl_vmlmb_get_restarts(obj->ws));
+  } else if (index == index_of_task) {
+    ypush_long(opl_vmlmb_get_task(obj->ws));
+  } else if (index == index_of_step) {
+    ypush_double(opl_vmlmb_get_step(obj->ws));
+  } else if (index == index_of_gnorm) {
+    ypush_double(opl_vmlmb_get_gnorm(obj->ws));
+  } else if (index == index_of_fmin) {
+    ypush_double(opl_vmlmb_get_fmin(obj->ws));
+  } else if (index == index_of_fatol) {
+    ypush_double(opl_vmlmb_get_fatol(obj->ws));
+  } else if (index == index_of_frtol) {
+    ypush_double(opl_vmlmb_get_frtol(obj->ws));
+  } else if (index == index_of_sftol) {
+    ypush_double(opl_vmlmb_get_sftol(obj->ws));
+  } else if (index == index_of_sgtol) {
+    ypush_double(opl_vmlmb_get_sgtol(obj->ws));
+  } else if (index == index_of_sxtol) {
+    ypush_double(opl_vmlmb_get_sxtol(obj->ws));
+  } else if (index == index_of_delta) {
+    ypush_double(opl_vmlmb_get_delta(obj->ws));
+  } else if (index == index_of_epsilon) {
+    ypush_double(opl_vmlmb_get_epsilon(obj->ws));
+  } else if (index == index_of_size) {
+    ypush_long(obj->n);
+  } else if (index == index_of_mem) {
+    ypush_long(obj->m);
+  } else if (index == index_of_dims) {
+    long i, rank = obj->dims[0];
+    long dims[2];
+    long* arr;
+    dims[0] = 1;
+    dims[1] = rank + 1;
+    arr = ypush_l(dims);
+    for (i = 0; i <= rank; ++i) {
+      arr[i] = obj->dims[i];
+    }
+  } else if (index == index_of_status) {
+    ypush_long(opl_vmlmb_get_status(obj->ws));
+  } else if (index == index_of_reason) {
+    push_string(opl_vmlmb_get_reason(obj->ws));
+  } else {
+    y_error("unknown member");
+  }
+}
+
+static vmlmb_object_t*
+get_vmlmb(int iarg)
+{
+  return (vmlmb_object_t*)yget_obj(iarg, &vmlmb_type);
+}
+
+/*---------------------------------------------------------------------------*/
+/* BUILTIN FUNCTIONS */
+
+void
+Y_opl_vmlmb_create(int argc)
+{
+  long i, rank, m = -1, n = -1;
+  long dims[Y_DIMSIZE];
+  vmlmb_object_t* obj;
+  int iarg;
+  int fmin_iarg = -1;
+  int fatol_iarg = -1;
+  int frtol_iarg = -1;
+  int sftol_iarg = -1;
+  int sgtol_iarg = -1;
+  int sxtol_iarg = -1;
+  int delta_iarg = -1;
+  int epsilon_iarg = -1;
+
+  /* Parse arguments. */
+  for (iarg = argc - 1; iarg >= 0; --iarg) {
+    long index = yarg_key(iarg);
+    if (index < 0) {
+      /* Positional argument. */
+      if (n == -1) {
+        n = get_dims(iarg, dims);
+      } else if (m == -1) {
+        m = ygets_l(iarg);
+        if (m <= 0) {
+          y_error("invalid number of steps to memorize");
+        }
+        if (m > n) {
+          m = n;
+        }
+      } else {
+        y_error("too many arguments");
+      }
+    } else {
+      /* Keyword argument (skip its value). */
+      --iarg;
+      if (index == index_of_fmin) {
+        fmin_iarg = iarg;
+      } else if (index == index_of_fatol) {
+        fatol_iarg = iarg;
+      } else if (index == index_of_frtol) {
+        frtol_iarg = iarg;
+      } else if (index == index_of_sftol) {
+        sftol_iarg = iarg;
+      } else if (index == index_of_sgtol) {
+        sgtol_iarg = iarg;
+      } else if (index == index_of_sxtol) {
+        sxtol_iarg = iarg;
+      } else if (index == index_of_delta) {
+        delta_iarg = iarg;
+      } else if (index == index_of_epsilon) {
+        epsilon_iarg = iarg;
+      } else {
+        y_error("unsupported keyword");
+      }
+    }
+  }
+  if (n == -1) {
+    y_error("missing dimension list of variables");
+  }
+  if (m == -1) {
+    y_error("missing number of steps to memorize");
+  }
+
+  /* Create VMLMB instance. */
+  obj = (vmlmb_object_t*)ypush_obj(&vmlmb_type, sizeof(vmlmb_object_t));
+  critical();
+  obj->ws = opl_vmlmb_create(n, m);
+  if (obj->ws == NULL) {
+    if (errno == ENOMEM) {
+      y_error("insufficient memory");
+    } else {
+      y_error("unknown error");
+    }
+  }
+  obj->n = n;
+  obj->m = m;
+  rank = dims[0];
+  for (i = 0; i <= rank; ++i) {
+    obj->dims[i] = dims[i];
+  }
+
+  /* Configure VMLMB instance (adding +1 to iarg's because an element has been
+     pushed on top of the stack).. */
+# define SET_ATTRIBUTE(name, invalid)                           \
+  if (name##_iarg >= 0 && ! yarg_nil(name##_iarg + 1)) {        \
+    double value = ygets_d(name##_iarg + 1);                    \
+    if ((invalid) ||                                            \
+        opl_vmlmb_set_##name(obj->ws, value) != OPL_SUCCESS) {  \
+      y_error("invalid value for `" #name "`");                 \
+    }                                                           \
+  }
+  SET_ATTRIBUTE(fmin, FALSE);
+  SET_ATTRIBUTE(fatol, value < 0);
+  SET_ATTRIBUTE(frtol, value < 0);
+  SET_ATTRIBUTE(sftol, value <= 0 || value >= 1);
+  SET_ATTRIBUTE(sgtol, value <= 0 || value >= 1);
+  SET_ATTRIBUTE(sxtol, value <= 0 || value >= 1);
+  SET_ATTRIBUTE(delta, value < 0);
+  SET_ATTRIBUTE(epsilon, value < 0);
+# undef SET_ATTRIBUTE
+
+}
+
+void
+Y_opl_vmlmb_configure(int argc)
+{
+  vmlmb_object_t* obj = NULL;
+  int iarg;
+  int ndrop = 0;
+  int fmin_iarg = -1;
+  int fatol_iarg = -1;
+  int frtol_iarg = -1;
+  int sftol_iarg = -1;
+  int sgtol_iarg = -1;
+  int sxtol_iarg = -1;
+  int delta_iarg = -1;
+  int epsilon_iarg = -1;
+
+  /* Parse arguments. */
+  for (iarg = argc - 1; iarg >= 0; --iarg) {
+    long index = yarg_key(iarg);
+    if (index < 0) {
+      /* Positional argument. */
+      ndrop += 1;
+      if (obj == NULL) {
+        obj = get_vmlmb(iarg);
+        ndrop = 0;
+      } else {
+        y_error("too many arguments");
+      }
+    } else {
+      /* Keyword argument (skip its value). */
+      ndrop += 2;
+      --iarg;
+      if (index == index_of_fmin) {
+        fmin_iarg = iarg;
+      } else if (index == index_of_fatol) {
+        fatol_iarg = iarg;
+      } else if (index == index_of_frtol) {
+        frtol_iarg = iarg;
+      } else if (index == index_of_sftol) {
+        sftol_iarg = iarg;
+      } else if (index == index_of_sgtol) {
+        sgtol_iarg = iarg;
+      } else if (index == index_of_sxtol) {
+        sxtol_iarg = iarg;
+      } else if (index == index_of_delta) {
+        delta_iarg = iarg;
+      } else if (index == index_of_epsilon) {
+        epsilon_iarg = iarg;
+      } else {
+        y_error("unsupported keyword");
+      }
+    }
+  }
+  if (obj == NULL) {
+    y_error("missing VMLMB workspace");
+  }
+
+  /* Set attributes. */
+# define SET_ATTRIBUTE(name, invalid)                           \
+  if (name##_iarg >= 0 && ! yarg_nil(name##_iarg)) {            \
+    double value = ygets_d(name##_iarg);                        \
+    if ((invalid) ||                                            \
+        opl_vmlmb_set_##name(obj->ws, value) != OPL_SUCCESS) {  \
+      y_error("invalid value for `" #name "`");                 \
+    }                                                           \
+  }
+  SET_ATTRIBUTE(fmin, FALSE);
+  SET_ATTRIBUTE(fatol, value < 0);
+  SET_ATTRIBUTE(frtol, value < 0);
+  SET_ATTRIBUTE(sftol, value <= 0 || value >= 1);
+  SET_ATTRIBUTE(sgtol, value <= 0 || value >= 1);
+  SET_ATTRIBUTE(sxtol, value <= 0 || value >= 1);
+  SET_ATTRIBUTE(delta, value < 0);
+  SET_ATTRIBUTE(epsilon, value < 0);
+# undef SET_ATTRIBUTE
+
+  /* Manage to left WS on top of the stack. */
+  if (ndrop > 0) {
+    yarg_drop(ndrop);
+  }
+}
+
+void
+Y_opl_vmlmb_iterate(int argc)
+{
+  double f;
+  vmlmb_object_t* obj;
+  int* isfree;
+  double* x;
+  double* g;
+  double* h;
+  opl_task_t task;
+  long fref;
+  int iarg;
+
+  if (argc < 4 || argc > 6) {
+    y_error("expecting between 4 and 6 arguments");
+  }
+  iarg = argc;
+  obj = get_vmlmb(--iarg);
+  x = (double*)get_array(--iarg, Y_DOUBLE, obj->dims, "x", FALSE);
+  fref = yget_ref(--iarg);
+  if (fref < 0) {
+    y_error("expecting a simple variable reference for argument `f`");
+  }
+  f = ygets_d(iarg);
+  g = (double*)get_array(--iarg, Y_DOUBLE, obj->dims, "g", FALSE);
+  if (argc >= 5) {
+    isfree = (int*)get_array(--iarg, Y_INT, obj->dims, "isfree", TRUE);
+  } else {
+    isfree = NULL;
+  }
+  if (argc >= 6) {
+    h = (double*)get_array(--iarg, Y_DOUBLE, obj->dims, "h", TRUE);
+  } else {
+    h = NULL;
+  }
+  task = opl_vmlmb_iterate(obj->ws, x, &f, g, isfree, h);
+  ypush_double(f);
+  yput_global(fref, 0);
+  ypush_long(task);
+}
+
+void
+Y_opl_vmlmb_restart(int argc)
+{
+  vmlmb_object_t* obj;
+
+  if (argc != 1) {
+    y_error("expecting exactly one argument");
+  }
+  obj = get_vmlmb(0);
+  opl_vmlmb_restart(obj->ws);
+  ypush_long(opl_vmlmb_get_task(obj->ws));
+}
+
+void
+Y_opl_vmlmb_restore(int argc)
+{
+  double f;
+  vmlmb_object_t* obj;
+  double* x;
+  double* g;
+  long fref;
+  int iarg;
+
+  if (argc != 4) {
+    y_error("expecting exactly 4 arguments");
+  }
+  iarg = argc;
+  obj = get_vmlmb(--iarg);
+  x = (double*)get_array(--iarg, Y_DOUBLE, obj->dims, "x", FALSE);
+  fref = yget_ref(--iarg);
+  if (fref < 0) {
+    y_error("expecting a simple variable reference for argument `f`");
+  }
+  g = (double*)get_array(--iarg, Y_DOUBLE, obj->dims, "g", FALSE);
+  opl_vmlmb_restore(obj->ws, x, &f, g);
+  ypush_double(f);
+  yput_global(fref, 0);
+  ypush_long(opl_vmlmb_get_task(obj->ws));
+}
+
+void
+Y__opl_init(int argc)
+{
+  /* Define constants. */
+#define DEFINE_LONG_CONST(c) define_long_const(#c, c)
+  DEFINE_LONG_CONST(OPL_TASK_START);
+  DEFINE_LONG_CONST(OPL_TASK_FG);
+  DEFINE_LONG_CONST(OPL_TASK_FREEVARS);
+  DEFINE_LONG_CONST(OPL_TASK_NEWX);
+  DEFINE_LONG_CONST(OPL_TASK_CONV);
+  DEFINE_LONG_CONST(OPL_TASK_WARN);
+  DEFINE_LONG_CONST(OPL_TASK_ERROR);
+#undef DEFINE_LONG_CONST
+
+  /* Define fast keyword/member indexes. */
+#define INIT(s) if (index_of_##s == -1L) index_of_##s = yget_global(#s, 0)
+  INIT(dims);
+  INIT(size);
+  INIT(mem);
+  INIT(task);
+  INIT(evaluations);
+  INIT(iterations);
+  INIT(restarts);
+  INIT(step);
+  INIT(gnorm);
+  INIT(fmin);
+  INIT(fatol);
+  INIT(frtol);
+  INIT(sftol);
+  INIT(sgtol);
+  INIT(sxtol);
+  INIT(delta);
+  INIT(epsilon);
+  INIT(status);
+  INIT(reason);
+#undef INIT
+
+  /* In case of... */
+  ypush_nil();
+}
+
diff -Nru yorick-optimpack-1.3.2+dfsg/yorick/OptimPack1.i yorick-optimpack-1.3.2+dfsg+1.4.0/yorick/OptimPack1.i
--- yorick-optimpack-1.3.2+dfsg/yorick/OptimPack1.i	2009-09-23 12:36:35.000000000 +0000
+++ yorick-optimpack-1.3.2+dfsg+1.4.0/yorick/OptimPack1.i	1970-01-01 00:00:00.000000000 +0000
@@ -1,515 +0,0 @@
-/*
- * OptimPack1.i --
- *
- *	Main startup file for OptimPack extension of Yorick.
- *
- *-----------------------------------------------------------------------------
- *
- *	Copyright (C) 2003-2007 Eric Thiébaut.
- *
- *	This file is part of OptimPack.
- *
- *	OptimPack is free software; you can redistribute it and/or
- *	modify it under the terms of the GNU General Public License
- *	version 2 as published by the Free Software Foundation.
- *
- *	OptimPack is distributed in the hope that it will be useful,
- *	but WITHOUT ANY WARRANTY; without even the implied warranty of
- *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *	GNU General Public License for more details.
- *
- *	You should have received a copy of the GNU General Public
- *	License along with OptimPack (file "COPYING" in the top source
- *	directory); if not, write to the Free Software Foundation,
- *	Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *-----------------------------------------------------------------------------
- *
- * History:
- *	$Id$
- *	$Log: OptimPack1.i,v $
- *	Revision 1.2  2007/07/11 06:16:01  eric
- *	New function op_mnb which is a "simple" driver to OptimPack routines.
- *
- *	Revision 1.1  2007/07/05 10:13:21  eric
- *	Initial revision
- *
- *-----------------------------------------------------------------------------
- */
-
-if (is_func(plug_in)) plug_in, "OptimPack1";
-
-extern __op_csrch;
-/* PROTOTYPE
-   int op_csrch(double f, double g, double array stp,
-                double ftol, double gtol, double xtol,
-		double stpmin, double stpmax, int array task,
-		char array csave, long array isave, double array dsave);
-*/
-
-func op_csrch(f, g, &stp, ftol, gtol, xtol, stpmin, stpmax, &task,
-              &csave, isave, dsave)
-{
-  if (numberof(task) != 1) error, "TASK must be a scalar";
-  if (structof(isave) != long || numberof(isave) < 2)
-    error, "bad ISAVE array";
-  if (structof(dsave) != double || numberof(dsave) < 12)
-    error, "bad DSAVE array";
-  itask = int(task);
-  cbuf = array(char, 128);
-  info = __op_csrch(f, g, stp, ftol, gtol, xtol, stpmin, stpmax, itask,
-                    cbuf, isave, dsave);
-  task = long(itask);
-  csave = string((task == 1 ? 0 : &cbuf));
-  return long(info);
-}
-
-func op_vmlmb_setup(n, m, fmin=, fatol=, frtol=, sftol=, sgtol=, sxtol=,
-                    epsilon=, costheta=)
-{
-  csave = array(char, 128);
-  isave = array(long,  12);
-  dsave = array(double, 27 + n + 2*m*(n + 1));
-  if (is_void(frtol)) frtol = 1e-10;
-  if (is_void(fatol)) fatol = 1e-13;
-  if (is_void(sftol)) sftol = 0.001;
-  if (is_void(sgtol)) sgtol = 0.9;
-  if (is_void(sxtol)) sxtol = 0.1;
-  if (is_void(epsilon)) epsilon = 1E-8;
-  if (is_void(costheta)) costheta = 1E-2;
-  task = long(__op_vmlmb_first(n, m, fatol, frtol, sftol, sgtol, sxtol,
-                               epsilon, costheta, csave, isave, dsave));
-  if (task != 1) error, string(&csave);
-  ws = [&csave, &isave, &dsave];
-  if (! is_void(fmin)) {
-    op_vmlmb_set_fmin, ws, fmin;
-  }
-  return ws;
-}
-
-func op_vmlmb_msg(ws) { return string(ws(1)); }
-
-func op_vmlmb_next(x, &f, &g, ws, active, h)
-{
-  local csave; eq_nocopy, csave, *ws(1);
-  if (structof(csave) != char || numberof(csave) != 128)
-    error, "corrupted workspace (CSAVE)";
-
-  local isave; eq_nocopy, isave, *ws(2);
-  if (structof(isave) != long || numberof(isave) != 12)
-    error, "corrupted workspace (ISAVE)";
-  m = isave(5);
-  n = isave(6);
-  
-  local dsave; eq_nocopy, dsave, *ws(3);
-  if (structof(dsave) != double || numberof(dsave) != 27 + n + 2*m*(1 + n))
-    error, "corrupted workspace (DSAVE)";
-
-  if (structof(x) != double || numberof(x) != n)
-    error, "bad parameter array X";
-  if (structof(f) != double || dimsof(f)(1))
-    error, "bad function value F";
-  if (structof(g) != double || numberof(g) != n)
-    error, "bad gradient array G";
-  
-  if (! is_void(active) && (structof(active) != int ||
-                            numberof(active) != n )) error, "bad array ACTIVE";
-  
-  if (! is_void(h) && (structof(h) != double ||
-                       numberof(h) != n )) error, "bad array H";
-  
-  return long(__op_vmlmb_next(x, f, g, &active, &h, csave, isave, dsave));
-}
-
-extern __op_vmlmb_next;
-/* PROTOTYPE
-   int op_vmlmb_next(double array x, double array f, double array g,
-                     pointer active, pointer h,
-		     char array csave, long array isave, double array dsave);
-*/
-
-//extern op_vmlmb_first;
-///* DOCUMENT op_vmlmb_first(n, m, fatol, frtol, sftol, sgtol, sxtol,
-//                           csave, isave, dsave);
-//     The returned value should be 1 unless there is an error.
-//*/
-
-extern __op_vmlmb_first;
-/* PROTOTYPE
-   int op_vmlmb_first(long n, long m,
-                      double fatol, double frtol,
-                      double sftol, double sgtol, double sxtol,
-                      double epsilon, double costheta,
-                      char array csave, long array isave, double array dsave);
-*/
-
-extern __op_vmlmb_set_fmin;
-/* PROTOTYPE
-   int op_vmlmb_set_fmin(char array csave,
-                          long array isave,
-                          double array dsave,
-                          double new_value,
-                          double array old_value);
-*/
-extern __op_vmlmb_get_fmin;
-/* PROTOTYPE
-   int op_vmlmb_get_fmin(char array csave,
-                          long array isave,
-                          double array dsave,
-                          double array value);
-*/
-
-local op_vmlmb_set_fmin;
-local op_vmlmb_get_fmin;
-/* DOCUMENT old = op_vmlmb_set_fmin(ws, fmin);
- *     -or- fmin = op_vmlmb_get_fmin(ws);
- *
- *    The function op_vmlmb_set_fmin set the value of FMIN in workspace WS
- *    and returns the previous value of FMIN if any (nil otherwise).
- *
- *    The function op_vmlmb_get_fmin returns the actual value of FMIN in
- *    workspace WS or nil if FMIN has never been set.
- *
-   SEE ALSO: op_vmlmb_first.
- */
-func op_vmlmb_set_fmin(ws, new)
-{
-  old = 0.0;
-  if (__op_vmlmb_set_fmin(*ws(1), *ws(2), *ws(3), new, old)) {
-    return old;
-  }
-}
-func op_vmlmb_get_fmin(ws)
-{
-  fmin = 0.0;
-  if (__op_vmlmb_get_fmin(*ws(1), *ws(2), *ws(3), fmin)) {
-    return fmin;
-  }
-}
-
-func op_mnb(f, x, &fx, &gx, fmin=,
-            extra=, xmin=, xmax=, method=, mem=, verb=, quiet=,
-            viewer=, printer=,
-            maxiter=, maxeval=, output=,
-            frtol=, fatol=, sftol=, sgtol=, sxtol=)
-/* DOCUMENT op_mnb(f, x)
- *     -or- op_mnb(f, x, fout, gout)
- *     
- *   Returns a minimum of a multivariate function by an iterative
- *   minimization algorithm (conjugate gradient or limited memory variable
- *   metric) possibly with simple bound constraints on the parameters.
- *   Arguments are:
- *   
- *     F - User defined function to optimize.
- *         The prototype of F is:
- *           func F(x, &gx) {
- *             fx = ....; // compute function value at X
- *             gx = ....; // store gradient of F in GX
- *             return fx; // return F(X)
- *           }
- *
- *     X - Starting solution (a floating point array).
- *
- *     FOUT - Optional output variable to store the value of F at the
- *         minimum.
- *
- *     GOUT - optional output variable to store the value of the gradient
- *         of F at the minimum.
- *
- *   If the multivariate function has more than one minimum, which minimum
- *   is returned is undefined (although it depends on the starting
- *   parameters X).
- *
- *   In case of early termination, the best solution found so far is
- *   returned.
- *
- *
- * KEYWORDS
- *
- *   EXTRA - Supplemental argument for F; if non-nil, F is called as
- *       F(X,GX,EXTRA) so its prototype must be: func F(x, &gx, extra).
- *
- *   XMIN, XMAX  - Lower/upper bounds for  X.  Must be  conformable with X.
- *       For instance with XMIN=0, the non-negative solution will be
- *       returned.
- *
- *   METHOD - Scalar integer which  defines the optimization method to use.
- *       Conjugate  gradient   algorithm  is  used  if  one   of  the  bits
- *       OP_FLAG_POLAK_RIBIERE,         OP_FLAG_FLETCHER_REEVES,         or
- *       OP_FLAG_HESTENES_STIEFEL  is  set;  otherwise,  a  limited  memory
- *       variable  metric algorithm  (VMLM-B) is  used.  If  METHOD  is not
- *       specified and  if MEM=0, a conjugate gradient  search is attempted
- *       with flags: (OP_FLAG_UPDATE_WITH_GP |
- *                    OP_FLAG_SHANNO_PHUA    |
- *                    OP_FLAG_MORE_THUENTE   |
- *                    OP_FLAG_POLAK_RIBIERE  |
- *                    OP_FLAG_POWELL_RESTART)
- *       otherwise VMLM-B is used with flags: (OP_FLAG_UPDATE_WITH_GP |
- *                                             OP_FLAG_SHANNO_PHUA    |
- *                                             OP_FLAG_MORE_THUENTE).
- *       See documentation  of op_get_flags to  figure out the  allowed bit
- *       flags and their meaning.
- *
- *   MEM - Number of previous directions used in variable metric limited
- *       memory method (default min(7, numberof(X))).
- *
- *   MAXITER - Maximum number of iterations (default: no limits).
- *
- *   MAXEVAL - Maximum number of function evaluations (default: no limits).
- *
- *   FTOL - Relative function change tolerance for convergence (default:
- *       1.5e-8).
- *
- *   GTOL - Gradient tolerance for convergence (default: 3.7e-11).
- *
- *   VERB - Verbose mode?  If non-nil and non-zero, print out information
- *       every VERB iterations and for the final one.
- *
- *   QUIET - If true and not in verbose mode, do not print warning nor
- *       convergence error messages.
- *
- *   OUPTPUT - Output for verbose mode.  For instance, text file stream
- *       opened for writing.
- *
- *   VIEWER - User defined subroutine to call every VERB iterations (see
- *       keyword VERB above)to display the solution X.  The subroutine will
- *       be called as:
- *          viewer, x, extra;
- *       where X is the current solution and EXTRA is the value of keyword
- *       EXTRA (which to see).  If the viewer uses Yorick graphics
- *       window(s) it may call "pause, 1;" before returning to make sure
- *       that graphics get correctly updated.
- *
- *   PRINTER - User defined subroutine to call every VERB iterations (see
- *       keyword VERB above) to printout iteration information.
- *       The subroutine will be called as:
- *          printer, output, iter, eval, cpu, fx, gnorm, steplen, x, extra; 
- *       where OUTPUT is the value of keyword OUTPUT (which to see), ITER
- *       is the number of iterations, EVAL is the number of function
- *       evaluations, CPU is the elapsed CPU time in seconds, FX is the
- *       function value at X, GNORM is the Euclidean norm of the gradient
- *       at X, STEPLEN is the length of the step along the search
- *       direction, X is the current solution and EXTRA is the value of
- *       keyword EXTRA (which to see).
- *
- *   SFTOL, SGTOL, SXTOL, SXBIG - Line   search   tolerance  and  safeguard
- *      parameters (see op_csrch).
- *   
- * SEE ALSO: op_get_flags, op_csrch,
- *           op_cgmnb_setup, op_cgmnb_next,
- *           op_vmlmb_setup, op_vmlmb_next.
- */
-{
-  local result, gx;
-
-  /* Get function. */
-  if (! is_func(f)) {
-    error, "expecting a function for argument F";
-  }
-  use_extra = (! is_void(extra));
-
-  /* Starting parameters. */
-  if ((s = structof(x)) != double && s != float && s != long &&
-      s != int && s != short && s != char) {
-    error, "expecting a numerical array for initial parameters X";
-  }
-  n = numberof(x);
-  dims = dimsof(x);
-
-  /* Bounds on parameters. */
-  bounds = 0;
-  if (! is_void(xmin)) {
-    if (is_void((t = dimsof(x, xmin))) || t(1) != dims(1)
-        || anyof(t != dims)) {
-      error, "bad dimensions for lower bound XMIN";
-    }
-    if ((convert = (s = structof(xmin)) != double) && s != float &&
-        s != long && s != int && s != short && s != char) {
-      error, "bad data type for lower bound XMIN";
-    }
-    if (convert || (t = dimsof(xmin))(1) != dims(1) || anyof(t != dims)) {
-      xmin += array(double, dims);
-    }
-    bounds |= 1;
-  }
-  if (! is_void(xmax)) {
-    if (is_void((t = dimsof(x, xmax))) || t(1) != dims(1)
-        || anyof(t != dims)) {
-      error, "bad dimensions for lower bound XMAX";
-    }
-    if ((convert = (s = structof(xmax)) != double) && s != float &&
-        s != long && s != int && s != short && s != char) {
-      error, "bad data type for lower bound XMAX";
-    }
-    if (convert || (t = dimsof(xmax))(1) != dims(1) || anyof(t != dims)) {
-      xmax += array(double, dims);
-    }
-    bounds |= 2;
-  }
-  
-  /* Output stream. */
-  if (! is_void(output)) {
-    if (structof(output) == string) {
-      output = open(output, "a");
-    } else if (typeof(output) != "text_stream") {
-      error, "bad value for keyword OUTPUT";
-    }
-  }
-
-  /* Maximum number of iterations and function evaluations. */
-  check_iter = (! is_void(maxiter));
-  check_eval = (! is_void(maxeval));
-
-  /* Viewer and printer subroutines. */
-  if (is_void(printer)) {
-    use_printer = 0n;
-  } else if (is_func(printer)) {
-    use_printer = 1n;
-  } else {
-    error, "bad value for keyword PRINTER";
-  }
-  if (is_void(viewer)) {
-    use_viewer = 0n;
-  } else if (is_func(viewer)) {
-    use_viewer = 1n;
-  } else {
-    error, "bad value for keyword VIEWER";
-  }
-
-  
-  /* Choose minimization method. */
-  //if (is_void(frtol)) frtol = 1e-10;
-  //if (is_void(fatol)) fatol = 1e-10;
-  if (! method) {
-    /* Variable metric. */
-    if (is_void(mem)) mem = min(n, 7);
-    if (is_void(fmin)) fmin = 0.0;
-    method = 0;
-    method_name = swrite(format="Limited Memory BFGS (VMLM with MEM=%d)",
-                         mem);
-    ws = op_vmlmb_setup(n, mem, /*fmin=fmin,*/
-                        fatol=fatol, frtol=frtol,
-                        sftol=sftol, sgtol=sgtol, sxtol=sxtol);
-  } else if (method < 0) {
-    if (is_void(mem)) mem = min(n, 7);
-    method_name = swrite(format="Limited Memory BFGS (LBFGS with MEM=%d)",
-                         mem);
-    ws = op_lbfgs_setup(n, mem);
-  } else if (method >= 1 && method <= 15) {
-    /* Conjugate gradient. */
-    mem = 2;
-    error, "conjugate-gradient method not yet implemented";
-    method_name = swrite(format="Conjugate Gradient (%s)",
-                         ["Fletcher-Reeves", "Polak-Ribiere",
-                          "Polak-Ribiere with non-negative BETA"](method&3));
-    ws = optim_cgmn_setup(method, fmin=fmin, fatol=fatol, frtol=frtol);
-  } else {
-    error, "bad METHOD";
-  }
-  step = 0.0;
-  task = 1;
-  eval = iter = 0;
-  stop = 0n;
-  if (verb) {
-    elapsed = array(double, 3);
-    timer, elapsed;
-    cpu_start = elapsed(1);
-  }
-  for (;;) {
-    local gx; /* to store the gradient */
-    if (task == 1) {
-      /* Evaluate function and gradient. */
-      if (bounds) {
-        if (bounds & 1) {
-          x = max(x, xmin);
-        }
-        if (bounds & 2) {
-          x = min(x, xmax);
-        }
-      }
-      fx = (use_extra ? f(x, gx, extra) : f(x, gx));
-      ++eval;
-      if (bounds) {
-        /* Figure out the set of free parameters:
-         *   ACTIVE(i) = 0 if X(i) has a lower bound XMIN(i)
-         *                 and X(i) = XMIN(i) and GX(i) >= 0
-         *               0 if X(i) value has an upper bound XMAX(i)
-         *                 and X(i) = XMAX(i) and GX(i) <= 0
-         *               1 (or any non-zero value) otherwise
-         */
-        if (bounds == 1) {
-          active = ((x > xmin) | (gx < 0.0));
-        } else if (bounds == 2) {
-          active = ((x < xmax) | (gx > 0.0));
-        } else {
-          active = (((x > xmin) | (gx < 0.0)) | ((x < xmax) | (gx > 0.0)));
-        }
-      }
-    }
-
-    /* Check for convergence. */
-    if (task != 1 || eval == 1) {
-      if (task > 2) {
-        stop = 1n;
-        msg = op_vmlmb_msg(ws);
-      } else if (check_iter && iter > maxiter) {
-        stop = 1n;
-        msg = swrite(format="warning: too many iterations (%d)\n", iter);
-      } else if (check_eval && eval > maxeval) {
-        stop = 1n;
-        msg = swrite(format="warning: too many function evaluations (%d)\n",
-                     eval);
-      }
-      if (verb) {
-        if (eval == 1 && ! use_printer) {
-          write, output, format="# Method %d (MEM=%d): %s\n#\n",
-            method, mem, method_name;
-          write, output, format="# %s\n# %s\n",
-            "ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN",
-            "---------------------------------------------------------------";
-        }
-        if (stop || ! (iter % verb)) {
-          timer, elapsed;
-          cpu = 1e3*(elapsed(1) - cpu_start);
-          gnorm = sqrt(sum(gx*gx));
-          if (use_printer) {
-            printer, output, iter, eval, cpu, fx, gnorm, steplen, x, extra;
-          } else {
-            write, output, format=" %5d %5d %10.3f  %+-24.15e%-9.1e%-9.1e\n",
-              iter, eval, cpu, fx, gnorm, step;
-          }
-          if (use_viewer) {
-            viewer, x, extra;
-          }
-        }
-      }
-      if (stop) {
-        if (msg && (verb || (task != 3 && ! quiet))) {
-          write, output, format="# %s\n#\n", msg;
-        }
-        return x;
-      }
-    }
-    
-    /* Call optimizer. */
-    if (! method) {
-      task = op_vmlmb_next(x, fx, gx, ws, active);
-      iter = (*ws(2))(7);
-      step = (*ws(3))(22);
-    } else if (method < 0) {
-      task = op_lbfgs_next(x, fx, gx, ws);
-      if (task == 2 || task == 3) ++iter;
-      step = -1.0;
-    }
-  }
-}
-
-/*---------------------------------------------------------------------------*
- * Local Variables:                                                          *
- * mode: Yorick                                                              *
- * c-basic-offset: 2                                                         *
- * tab-width: 8                                                              *
- * fill-column: 78                                                           *
- * coding: latin-1                                                           *
- * End:                                                                      *
- *---------------------------------------------------------------------------*/
diff -Nru yorick-optimpack-1.3.2+dfsg/yorick/OptimPack1-test.i yorick-optimpack-1.3.2+dfsg+1.4.0/yorick/OptimPack1-test.i
--- yorick-optimpack-1.3.2+dfsg/yorick/OptimPack1-test.i	2008-02-07 10:45:53.000000000 +0000
+++ yorick-optimpack-1.3.2+dfsg+1.4.0/yorick/OptimPack1-test.i	1970-01-01 00:00:00.000000000 +0000
@@ -1,1026 +0,0 @@
-/*
- * OptimPack1-test.i --
- *
- *	Various tests from MINPACK suite for the optimization routines in
- *	OptimPack extension for Yorick.
- *
- *-----------------------------------------------------------------------------
- *
- *	Copyright (C) 2003-2007 Eric Thiébaut.
- *
- *	This file is part of OptimPack.
- *
- *	OptimPack is free software; you can redistribute it and/or
- *	modify it under the terms of the GNU General Public License
- *	version 2 as published by the Free Software Foundation.
- *
- *	OptimPack is distributed in the hope that it will be useful,
- *	but WITHOUT ANY WARRANTY; without even the implied warranty of
- *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *	GNU General Public License for more details.
- *
- *	You should have received a copy of the GNU General Public
- *	License along with OptimPack (file "COPYING" in the top source
- *	directory); if not, write to the Free Software Foundation,
- *	Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *-----------------------------------------------------------------------------
- *
- * History:
- *	$Id: OptimPack1-test.i,v 1.1 2007/07/05 10:13:11 eric Exp eric $
- *	$Log: OptimPack1-test.i,v $
- *	Revision 1.1  2007/07/05 10:13:11  eric
- *	Initial revision
- *
- *-----------------------------------------------------------------------------
- */
-
-require, "OptimPack1.i";
-
-#if 0
-#include "OptimPack1-test.i"
-for (i=1;i<=18;++i) op_test_um, prob=i, method=0, verb=1, output="OptimPack1-test.out";
-
-// Since the CPU time may change, you can compare the outputs
-// with:
-//   sed -e 's/^\( *[0-9]* *[0-9]*\) *[^ ]*/\1/'
-//
-#endif
-
-
-local op_rosenbrock_nevals;
-op_rosenbrock_nevals=0;
-
-func op_test_rosenbrock(nil, start=, method=, ndirs=, frtol=)
-/* DOCUMENT op_test_rosenbrock, ...;
-     Test op_driver with Rosenbrock function.
-     
-   SEE ALSO: op_test_rosenbrock_func. */
-{
-  x = is_void(start) ? [0.0, 0.0] : start;
-  return op_driver(op_test_rosenbrock_func,
-                   (is_void(start) ? [0.0, 0.0] : start),
-                   method=method, fmin=0.0, verb=1, ndirs=ndirs,
-                   frtol=frtol);
-}
-
-func op_test_rosenbrock_func(x, &g)
-{
-  // Rosenbrock:
-  //    f  = 100*(x2 - x1^2)^2 + (1 - x1)^2
-  x1 = x(1);
-  u = x(2) - x1*x1;
-  v = 1.0 - x1;
-  f = 100.0*u*u + v*v;
-  g = [-400.0*u*x1 - 2.0*v, 200.0*u];
-  ++op_rosenbrock_nevals;
-  return f;
-}
-
-func op_test_quad(x, &g)
-{
-  u = (x - [1.0, 1.0, 1.0]);
-  w = [3.0, 7.0, 2.0];
-  g = 2.0*w*u;
-  return sum(w*u*u);
-}
-
-func op_test_um(prob=, n=, method=, ndir=, verb=, factor=,
-                   maxiter=, maxeval=, frtol=, fatol=,
-                   sftol=, sgtol=, sxtol=,
-                   output=)
-/* DOCUMENT op_test_um(...)
-     Check various optimization methods for eighteen nonlinear unconstrained
-     minimization problems.
-
-   SEE ALSO: optim_vmlm, optim_cgmn, minpack1_umobj. */
-{
-  /* Output array. */
-  local result;
-
-  /* Output stream. */
-  if (! is_void(output)) {
-    if (structof(output) == string) {
-      output = open(output, "a");
-    } else if (typeof(output) != "text_stream") {
-      error, "bad value for keyword OUTPUT";
-    }
-  }
-  
-  /* Check compatibility of arguments N and PROB. */
-  if (prob == 1) {
-    name = "Helical valley function.";
-    if (is_void(n)) n = 3;
-    else if (n != 3) error, "N must be 3 for problem #1";
-  } else if (prob == 2) {
-    name = "Biggs exp6 function.";
-    if (is_void(n)) n = 6;
-    else if (n != 6) error, "N must be 6 for problem #2";
-  } else if (prob == 3) {
-    name = "Gaussian function.";
-    if (is_void(n)) n = 3;
-    else if (n != 3) error, "N must be 3 for problem #3";
-  } else if (prob == 4) {
-    name = "Powell badly scaled function.";
-    if (is_void(n)) n = 2;
-    else if (n != 2) error, "N must be 2 for problem #4";
-  } else if (prob == 5) {
-    name = "Box 3-dimensional function.";
-    if (is_void(n)) n = 3;
-    else if (n != 3) error, "N must be 3 for problem #5";
-  } else if (prob == 6) {
-    name = "Variably dimensioned function.";
-    if (is_void(n)) n = 10;
-    else if (n < 1) error, "N must be >= 1 in problem #6";
-  } else if (prob == 7) {
-    name = "Watson function.";
-    msg = "N may be 2 or greater but is usually 6 or 9 for problem #7";
-    if (is_void(n)) {
-      write, msg;
-      n = 6;
-    } else if (n < 2) error, msg;
-  } else if (prob == 8) {
-    name = "Penalty function I.";
-    if (is_void(n)) n = 10;
-    else if (n < 1) error, "N must be >= 1 in problem #8";
-  } else if (prob == 9) {
-    name = "Penalty function II.";
-    if (is_void(n)) n = 10;
-    else if (n < 1) error, "N must be >= 1 in problem #9";
-  } else if (prob == 10) {
-    name = "Brown badly scaled function.";
-    if (is_void(n)) n = 2;
-    else if (n != 2) error, "N must be 2 for problem #10";
-  } else if (prob == 11) {
-    name = "Brown and Dennis function.";
-    if (is_void(n)) n = 4;
-    else if (n != 4) error, "N must be 4 for problem #11";
-  } else if (prob == 12) {
-    name = "Gulf research and development function.";
-    if (is_void(n)) n = 3;
-    else if (n != 3) error, "N must be 3 for problem #12";
-  } else if (prob == 13) {
-    name = "Trigonometric function.";
-    if (is_void(n)) n = 10;
-    else if (n < 1) error, "N must be >= 1 in problem #13";
-  } else if (prob == 14) {
-    name = "Extended Rosenbrock function.";
-    if (is_void(n)) n = 10;
-    else if (n < 1 || n%2 != 0)
-      error, "N must be a multiple of 2 in problem #14";
-  } else if (prob == 15) {
-    name = "Extended Powell function.";
-    if (is_void(n)) n = 12;
-    else if (n < 1 || n%4 != 0)
-      error, "N must be a multiple of 4 in problem #15";
-  } else if (prob == 16) {
-    name = "Beale function.";
-    if (is_void(n)) n = 2;
-    else if (n != 2) error, "N must be 2 for problem #16";
-  } else if (prob == 17) {
-    name = "Wood function.";
-    if (is_void(n)) n = 4;
-    else if (n != 4) error, "N must be 4 for problem #17";
-  } else if (prob == 18) {
-    name = "Chebyquad function.";
-    if (is_void(n)) n = 25;
-    else if (n<1 || n>50) error, "N must be <=50 for problem #18";
-  } else error, "PROB must be an integer between 1 and 18";
-
-  /* Maximum number of iterations and function evaluations. */
-  if (is_void(maxiter)) maxiter = 100*n;
-  if (is_void(maxeval)) maxeval = 10*maxiter;
-
-  /* Starting vector. */
-  x = minpack1_umipt(n, prob, factor);
-  dims = dimsof(x);
-  
-  /* Choose minimization method. */
-  //if (is_void(frtol)) frtol = 1e-10;
-  //if (is_void(fatol)) fatol = 1e-10;
-  if (is_void(method)) method = 0;
-  if (method == 0) {
-    /* Variable metric. */
-    if (is_void(ndir)) ndir = n;
-    method_name = swrite(format="Limited Memory BFGS (VMLM with NDIR=%d)",
-                         ndir);
-    ws = op_vmlmb_setup(n, ndir, fmin=0.0,
-                        fatol=fatol, frtol=frtol,
-                        sftol=sftol, sgtol=sgtol, sxtol=sxtol);
-  } else if (method < 0) {
-    if (is_void(ndir)) ndir = n;
-    method_name = swrite(format="Limited Memory BFGS (LBFGS with NDIR=%d)",
-                         ndir);
-    ws = op_lbfgs_setup(n, ndir);
-  } else if (method >= 1 && method <= 15) {
-    /* Conjugate gradient. */
-    ndir = 2;
-    method_name = swrite(format="Conjugate Gradient (%s)",
-                         ["Fletcher-Reeves", "Polak-Ribiere",
-                          "Polak-Ribiere with non-negative BETA"](method&3));
-    ws = optim_cgmn_setup(method, fmin=fmin, fatol=fatol, frtol=frtol);
-  } else {
-    error, "bad METHOD";
-  }
-  step = 0.0;
-  task = 1;
-  eval = iter = 0;
-  elapsed = array(double, 3);
-  timer, elapsed;
-  cpu_start = elapsed(1);
-  for (;;) {
-    if (task == 1) {
-      /* Evaluate function. */
-      f = minpack1_umobj(x, prob);
-      g = minpack1_umgrd(x, prob);
-      ++eval;
-    }
-
-    /* Check for convergence. */
-    if (task != 1 || eval == 1) {
-      too_many_eval = (maxeval >= 1 && eval > maxeval);
-      too_many_iter = (maxiter >= 1 && iter > maxiter);
-      timer, elapsed;
-      cpu = elapsed(1) - cpu_start;
-      gnorm = sqrt(sum(g*g));
-      if (verb) {
-        if (eval == 1) {
-          write, output, format="#\n# Problem %d (N=%d): %s\n",
-            prob, n, name;
-          write, output, format="# Method %d (NDIR=%d): %s\n#\n",
-            method, ndir, method_name;
-          write, output, format="# %s\n# %s\n",
-            "ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN",
-            "---------------------------------------------------------------";
-        }
-        write, output, format=" %5d %5d %10.3f  %+-24.15e%-9.1e%-9.1e\n",
-          iter, eval, 1e3*cpu, f, gnorm, step;
-      }
-      if (! am_subroutine()) grow, result, [[iter, eval, 1e3*cpu, f,
-                                             gnorm, step]];
-      if (task > 2) {
-        msg = op_vmlmb_msg(ws);
-        break;
-      }
-      if (maxiter >= 0 && iter > maxiter && task == 2) {
-        msg = swrite(format="warning: too many iterations (%d)\n",
-                     iter);
-        break;
-      }
-      if (maxeval >= 0 && eval > maxeval) {
-        x = x0;
-        msg = swrite(format="warning: too many function evaluation (%d)\n",
-                     eval);
-        break;
-      }
-    }
-
-    
-    /* Call optimizer. */
-    if (! method) {
-      task = op_vmlmb_next(x, f, g, ws);
-      iter = (*ws(2))(7);
-      step = (*ws(3))(22);
-    } else if (method < 0) {
-      task = op_lbfgs_next(x, f, g, ws);
-      if (task == 2 || task == 3) ++iter;
-      step = -1.0;
-    } else {
-      optim_cgmn, x, f, g, task, ws;
-      iter = optim_cgmn_iter(ws);
-      step = optim_cgmn_step(ws);
-    }
-  }
-
-  if (task == 3) status = 0;
-  else if (ident == 4) status = 1;
-  else status = 2;
-  write, output, format=(verb?"# %s\n#\n":"*** %s\n"), msg;
-  return result;
-  //return [status, n, ndir, method, iter, eval, cpu, f];
-  //return x;
-}
-
-/*---------------------------------------------------------------------------*/
-/* NONLINEAR UNCONSTRAINED MINIMIZATION PROBLEMS
- *
- *   This suite of problems is taken from the MINPACK Project.
- *
- *   HISTORY:
- *     - Argonne National Laboratory. MINPACK Project. March 1980.
- *       Burton S. Garbow, Kenneth E. Hillstrom, Jorge J. More.
- *     - Conversion to Yorick. November 2001. Eric Thiebaut.
- */
-_um_y = [9.0e-4,   4.4e-3,   1.75e-2,  5.4e-2,   1.295e-1,
-         2.42e-1,  3.521e-1, 3.989e-1, 3.521e-1, 2.42e-1,
-         1.295e-1, 5.4e-2,   1.75e-2,  4.4e-3,   9.0e-4];
-
-func minpack1_umobj(x, prob)
-/* DOCUMENT minpack1_umobj(x, prob)
-     Returns  the objective functions  of eighteen  nonlinear unconstrained
-     minimization problems.  X  is the parameter array: a  vector of length
-     N, PROB is the problem number (a positive integer between 1 and 18).
-     
-     The  values  of  N  for  functions 1,2,3,4,5,10,11,12,16  and  17  are
-     3,6,3,2,3,2,4,3,2 and 4, respectively.  For  function 7, n may be 2 or
-     greater but is usually 6 or 9.  For functions 6,8,9,13,14,15 and 18, N
-     may be variable,  however it must be even for  function 14, a multiple
-     of 4 for function 15, and not greater than 50 for function 18.
-
-   SEE ALSO: minpack1_umgrd, minpack1_umipt. */
-{
-  n = numberof(x);
-  
-  /* Function routine selector. */
-  if (prob == 1) {
-    /* Helical valley function. */
-    tpi = 8.0*atan(1.0);
-    if      (x(1) > 0.0) th = atan(x(2)/x(1))/tpi;
-    else if (x(1) < 0.0) th = atan(x(2)/x(1))/tpi + 0.5;
-    else                 th = (x(2) >= 0.0 ? 0.25 : -0.25);
-    arg = x(1)*x(1) + x(2)*x(2);
-    r = sqrt(arg);
-    t = x(3) - 10.0*th;
-    f = 100.0*(t*t + (r - 1.0)*(r - 1.0)) + x(3)*x(3);
-    return f;
-  } else if (prob == 2) {
-    /* Biggs exp6 function. */
-    f = 0.0;
-    for (i=1 ; i<=13 ; i+=1) {
-      d1 = double(i)/10.0;
-      d2 = exp(-d1) - 5.0*exp(-10.0*d1) + 3.0*exp(-4.0*d1);
-      s1 = exp(-d1*x(1));
-      s2 = exp(-d1*x(2));
-      s3 = exp(-d1*x(5));
-      t = x(3)*s1 - x(4)*s2 + x(6)*s3 - d2;
-      f += t*t;
-    }
-    return f;
-  } else if (prob == 3) {
-    /* Gaussian function. */
-    f = 0.0;
-    for (i=1 ; i<=15 ; i+=1) {
-      d1 = 0.5*double(i-1);
-      d2 = 3.5 - d1 - x(3);
-      arg = -0.5*x(2)*d2*d2;
-      r = exp(arg);
-      t = x(1)*r - _um_y(i);
-      f += t*t;
-    }
-    return f;
-  } else if (prob == 4) {
-    /* Powell badly scaled function. */
-    t1 = 1e4*x(1)*x(2) - 1.0;
-    s1 = exp(-x(1));
-    s2 = exp(-x(2));
-    t2 = s1 + s2 - 1.0001;
-    f = t1*t1 + t2*t2;
-    return f;
-  } else if (prob == 5) {
-    /* Box 3-dimensional function. */
-    f = 0.0;
-    for (i=1 ; i<=10 ; i+=1) {
-      d1 = double(i);
-      d2 = d1/10.0;
-      s1 = exp(-d2*x(1));
-      s2 = exp(-d2*x(2));
-      s3 = exp(-d2) - exp(-d1);
-      t = s1 - s2 - s3*x(3);
-      f += t*t;
-    }
-    return f;
-  } else if (prob == 6) {
-    /* Variably dimensioned function. */
-    t1 = 0.0;
-    t2 = 0.0;
-    for (j=1 ; j<=n ; j+=1) {
-      t1 += double(j)*(x(j) - 1.0);
-      t = x(j) - 1.0;
-      t2 += t*t;
-    }
-    t = t1*t1;
-    f = t2 + t*(1.0 + t);
-    return f;
-  } else if (prob == 7) {
-    /* Watson function. */
-    f = 0.0;
-    for (i=1 ; i<=29 ; i+=1) {
-      d1 = double(i)/29.0;
-      s1 = 0.0;
-      d2 = 1.0;
-      for (j=2 ; j<=n ; j+=1) {
-	s1 += double(j-1)*d2*x(j);
-	d2 = d1*d2;
-      }
-      s2 = 0.0;
-      d2 = 1.0;
-      for (j=1 ; j<=n ; j+=1) {
-	s2 += d2*x(j);
-	d2 = d1*d2;
-      }
-      t = s1 - s2*s2 - 1.0;
-      f += t*t;
-    }
-    t = x(1)*x(1);
-    t1 = x(2) - t - 1.0;
-    f += t + t1*t1;
-    return f;
-  } else if (prob == 8) {
-    /* Penalty function I. */
-    t1 = -0.25;
-    t2 = 0.0;
-    for (j=1 ; j<=n ; j+=1) {
-      t1 += x(j)*x(j);
-      t = x(j) - 1.0;
-      t2 += t*t;
-    }
-    f = 1e-5*t2 + t1*t1;
-    return f;
-  } else if (prob == 9) {
-    /* Penalty function II. */
-    t1 = -1.0;
-    t2 = 0.0;
-    t3 = 0.0;
-    d1 = exp(0.1);
-    d2 = 1.0;
-    s2 = 0.0; /* avoid compiler warning about `s2' used uninitialized */
-    for (j=1 ; j<=n ; j+=1) {
-      t1 += double(n-j+1)*x(j)*x(j);
-      s1 = exp(x(j)/10.0);
-      if (j > 1) {
-	s3 = s1 + s2 - d2*(d1 + 1.0);
-	t2 += s3*s3;
-	t = (s1 - 1.0/d1);
-	t3 += t*t;
-      }
-      s2 = s1;
-      d2 = d1*d2;
-    }
-    t = (x(1) - 0.2);
-    f = 1e-5*(t2 + t3) + t1*t1 + t*t;
-    return f;
-  } else if (prob == 10) {
-    /* Brown badly scaled function. */
-    t1 = x(1) - 1e6;
-    t2 = x(2) - 2e-6;
-    t3 = x(1)*x(2) - 2.0;
-    f = t1*t1 + t2*t2 + t3*t3;
-    return f;
-  } else if (prob == 11) {
-    /* Brown and Dennis function. */
-    f = 0.0;
-    for (i=1 ; i<=20 ; i+=1) {
-      d1 = double(i)/5.0;
-      d2 = sin(d1);
-      t1 = x(1) + d1*x(2) - exp(d1);
-      t2 = x(3) + d2*x(4) - cos(d1);
-      t = t1*t1 + t2*t2;
-      f += t*t;
-    }
-    return f;
-  } else if (prob == 12) {
-    /* Gulf research and development function. */
-    f = 0.0;
-    d1 = 2.0/3.0;
-    for (i=1 ; i<=99 ; i+=1) {
-      arg = double(i)/100.0;
-      r = (-50.0*log(arg))^d1 + 25.0 - x(2);
-      t1 = (abs(r)^x(3))/x(1);
-      t2 = exp(-t1);
-      t = t2 - arg;
-      f += t*t;
-    }
-    return f;
-  } else if (prob == 13) {
-    /* Trigonometric function. */
-    s1 = 0.0;
-    for (j=1 ; j<=n ; j+=1) {
-      s1 += cos(x(j));
-    }
-    f = 0.0;
-    for (j=1 ; j<=n ; j+=1) {
-      t = double(n+j) - sin(x(j)) - s1 - double(j)*cos(x(j));
-      f += t*t;
-    }
-    return f;
-  } else if (prob == 14) {
-    /* Extended Rosenbrock function. */
-    f = 0.0;
-    for (j=1 ; j<=n ; j+=2) {
-      t1 = 1.0 - x(j);
-      t2 = 10.0*(x(j+1) - x(j)*x(j));
-      f += t1*t1 + t2*t2;
-    }
-    return f;
-  } else if (prob == 15) {
-    /* Extended Powell function. */
-    f = 0.0;
-    for (j=1 ; j<=n ; j+=4) {
-      t = x(j) + 10.0*x(j+1);
-      t1 = x(j+2) - x(j+3);
-      s1 = 5.0*t1;
-      t2 = x(j+1) - 2.0*x(j+2);
-      s2 = t2*t2*t2;
-      t3 = x(j) - x(j+3);
-      s3 = 10.0*t3*t3*t3;
-      f += t*t + s1*t1 + s2*t2 + s3*t3;
-    }
-    return f;
-  } else if (prob == 16) {
-    /* Beale function. */
-    s1 = 1.0 - x(2);
-    t1 = 1.5 - x(1)*s1;
-    s2 = 1.0 - x(2)*x(2);
-    t2 = 2.25 - x(1)*s2;
-    s3 = 1.0 - x(2)*x(2)*x(2);
-    t3 = 2.625 - x(1)*s3;
-    f = t1*t1 + t2*t2 + t3*t3;
-    return f;
-  } else if (prob == 17) {
-    /* Wood function. */
-    s1 = x(2) - x(1)*x(1);
-    s2 = 1.0 - x(1);
-    s3 = x(2) - 1.0;
-    t1 = x(4) - x(3)*x(3);
-    t2 = 1.0 - x(3);
-    t3 = x(4) - 1.0;
-    f = 100.0*s1*s1 + s2*s2 + 90.0*t1*t1 + t2*t2 + \
-      10.0*(s3 + t3)*(s3 + t3) + (s3 - t3)*(s3 - t3)/10.0;
-    return f;
-  } else if (prob == 18) {
-    /* Chebyquad function. */
-    fvec = array(0.0, n);
-    for (j=1 ; j<=n ; j+=1) {
-      t1 = 1.0;
-      t2 = 2.0*x(j) - 1.0;
-      t = 2.0*t2;
-      for (i=1 ; i<=n ; i+=1) {
-	fvec(i) += t2;
-	th = t*t2 - t1;
-	t1 = t2;
-	t2 = th;
-      }
-    }
-    f = 0.0;
-    d1 = 1.0/double(n);
-    iev = -1;
-    for (i=1 ; i<=n ; i+=1) {
-      t = d1*fvec(i);
-      if (iev > 0) t += 1.0/(double(i)*double(i) - 1.0);
-      f += t*t;
-      iev = -iev;
-    }
-    return f;
-  }
-  return 0.0;
-}
-
-func minpack1_umgrd(x, prob)
-/* DOCUMENT minpack1_umgrd(x, prob)
-     Returns  the  gradient  vectors  of eighteen  nonlinear  unconstrained
-     minimization problems. The problem  dimensions are as described in the
-     prologue comments of minpack1_umobj.
-
-   SEE ALSO: minpack1_umobj, minpack1_umipt. */
-{
-  n = numberof(x);
-  g = array(double, n);
-
-  /* Gradient routine selector. */
-  if (prob == 1) {
-    /* Helical valley function. */
-    tpi = 8.0*atan(1.0);
-    if      (x(1) > 0.0) th = atan(x(2)/x(1))/tpi;
-    else if (x(1) < 0.0) th = atan(x(2)/x(1))/tpi + 0.5;
-    else                 th = (x(2) >= 0.0 ? 0.25 : -0.25);
-    arg = x(1)*x(1) + x(2)*x(2);
-    r = sqrt(arg);
-    t = x(3) - 10.0*th;
-    s1 = 10.0*t/(tpi*arg);
-    g(1) = 200.0*(x(1) - x(1)/r + x(2)*s1);
-    g(2) = 200.0*(x(2) - x(2)/r - x(1)*s1);
-    g(3) = 2.0*(100.0*t + x(3));
-  } else if (prob == 2) {
-    /* Biggs exp6 function. */
-    for (j=1 ; j<=6 ; ++j) g(j) = 0.0;
-    for (i=1 ; i<=13 ; ++i) {
-      d1 = double(i)/10.0;
-      d2 = exp(-d1) - 5.0*exp(-10.0*d1) + 3.0*exp(-4.0*d1);
-      s1 = exp(-d1*x(1));
-      s2 = exp(-d1*x(2));
-      s3 = exp(-d1*x(5));
-      t = x(3)*s1 - x(4)*s2 + x(6)*s3 - d2;
-      th = d1*t;
-      g(1) = g(1) - s1*th;
-      g(2) = g(2) + s2*th;
-      g(3) = g(3) + s1*t;
-      g(4) = g(4) - s2*t;
-      g(5) = g(5) - s3*th;
-      g(6) = g(6) + s3*t;
-    }
-    g(1) = 2.0*x(3)*g(1);
-    g(2) = 2.0*x(4)*g(2);
-    g(3) = 2.0*g(3);
-    g(4) = 2.0*g(4);
-    g(5) = 2.0*x(6)*g(5);
-    g(6) = 2.0*g(6);
-  } else if (prob == 3) {
-    /* Gaussian function. */
-    g(1) = 0.0;
-    g(2) = 0.0;
-    g(3) = 0.0;
-    for (i=1 ; i<=15 ; ++i) {
-      d1 = 0.5*double(i-1);
-      d2 = 3.5 - d1 - x(3);
-      arg = -0.5*x(2)*d2*d2;
-      r = exp(arg);
-      t = x(1)*r - _um_y(i);
-      s1 = r*t;
-      s2 = d2*s1;
-      g(1) = g(1) + s1;
-      g(2) = g(2) - d2*s2;
-      g(3) = g(3) + s2;
-    }
-    g(1) = 2.0*g(1);
-    g(2) = x(1)*g(2);
-    g(3) = 2.0*x(1)*x(2)*g(3);
-  } else if (prob == 4) {
-    /* Powell badly scaled function. */
-    t1 = 1e4*x(1)*x(2) - 1.0;
-    s1 = exp(-x(1));
-    s2 = exp(-x(2));
-    t2 = s1 + s2 - 1.0001;
-    g(1) = 2.0*(1e4*x(2)*t1 - s1*t2);
-    g(2) = 2.0*(1e4*x(1)*t1 - s2*t2);
-  } else if (prob == 5) {
-    /* Box 3-dimensional function. */
-    g(1) = 0.0;
-    g(2) = 0.0;
-    g(3) = 0.0;
-    for (i=1 ; i<=10 ; ++i) {
-      d1 = double(i);
-      d2 = d1/10.0;
-      s1 = exp(-d2*x(1));
-      s2 = exp(-d2*x(2));
-      s3 = exp(-d2) - exp(-d1);
-      t = s1 - s2 - s3*x(3);
-      th = d2*t;
-      g(1) = g(1) - s1*th;
-      g(2) = g(2) + s2*th;
-      g(3) = g(3) - s3*t;
-    }
-    g(1) = 2.0*g(1);
-    g(2) = 2.0*g(2);
-    g(3) = 2.0*g(3);
-  } else if (prob == 6) {
-    /* Variably dimensioned function. */
-    t1 = 0.0;
-    for (j=1 ; j<=n ; ++j) {
-      t1 += double(j)*(x(j) - 1.0);
-    }
-    t = t1*(1.0 + 2.0*t1*t1);
-    for (j=1 ; j<=n ; ++j) {
-      g(j) = 2.0*(x(j) - 1.0 + double(j)*t);
-    }
-  } else if (prob == 7) {
-    /* Watson function. */
-    for (j=1 ; j<=n ; ++j) {
-      g(j) = 0.0;
-    }
-    for (i=1 ; i<=29 ; ++i) {
-      d1 = double(i)/29.0;
-      s1 = 0.0;
-      d2 = 1.0;
-      for (j=2 ; j<=n ; ++j) {
-	s1 += double(j-1)*d2*x(j);
-	d2 = d1*d2;
-      }
-      s2 = 0.0;
-      d2 = 1.0;
-      for (j=1 ; j<=n ; ++j) {
-	s2 += d2*x(j);
-	d2 = d1*d2;
-      }
-      t = s1 - s2*s2 - 1.0;
-      s3 = 2.0*d1*s2;
-      d2 = 2.0/d1;
-      for (j=1 ; j<=n ; ++j) {
-	g(j) = g(j) + d2*(double(j-1) - s3)*t;
-	d2 = d1*d2;
-      }
-    }
-    t1 = x(2) - x(1)*x(1) - 1.0;
-    g(1) = g(1) + x(1)*(2.0 - 4.0*t1);
-    g(2) = g(2) + 2.0*t1;
-  } else if (prob == 8) {
-    /* Penalty function I. */
-    t1 = -0.25;
-    for (j=1 ; j<=n ; ++j) {
-      t1 += x(j)*x(j);
-    }
-    d1 = 2.0*1e-5;
-    th = 4.0*t1;
-    for (j=1 ; j<=n ; ++j) {
-      g(j) = d1*(x(j) - 1.0) + x(j)*th;
-    }
-  } else if (prob == 9) {
-    /* Penalty function II. */
-    s2 = 0.0; /* avoid compiler warning about `s2' used uninitialized */
-    t1 = -1.0;
-    for (j=1 ; j<=n ; ++j) {
-      t1 += double(n-j+1)*x(j)*x(j);
-    }
-    d1 = exp(0.1);
-    d2 = 1.0;
-    th = 4.0*t1;
-    for (j=1 ; j<=n ; ++j) {
-      g(j) = double(n-j+1)*x(j)*th;
-      s1 = exp(x(j)/10.0);
-      if (j > 1) {
-	s3 = s1 + s2 - d2*(d1 + 1.0);
-	g(j) = g(j) + 1e-5*s1*(s3 + s1 - 1.0/d1)/5.0;
-	g(j-1) = g(j-1) + 1e-5*s2*s3/5.0;
-      }
-      s2 = s1;
-      d2 = d1*d2;
-    }
-    g(1) = g(1) + 2.0*(x(1) - 0.2);
-  } else if (prob == 10) {
-    /* Brown badly scaled function. */
-    t1 = x(1) - 1e6;
-    t2 = x(2) - 2e-6;
-    t3 = x(1)*x(2) - 2.0;
-    g(1) = 2.0*(t1 + x(2)*t3);
-    g(2) = 2.0*(t2 + x(1)*t3);
-  } else if (prob == 11) {
-    /* Brown and Dennis function. */
-    g(1) = 0.0;
-    g(2) = 0.0;
-    g(3) = 0.0;
-    g(4) = 0.0;
-    for (i=1 ; i<=20 ; ++i) {
-      d1 = double(i)/5.0;
-      d2 = sin(d1);
-      t1 = x(1) + d1*x(2) - exp(d1);
-      t2 = x(3) + d2*x(4) - cos(d1);
-      t = t1*t1 + t2*t2;
-      s1 = t1*t;
-      s2 = t2*t;
-      g(1) = g(1) + s1;
-      g(2) = g(2) + d1*s1;
-      g(3) = g(3) + s2;
-      g(4) = g(4) + d2*s2;
-    }
-    g(1) = 4.0*g(1);
-    g(2) = 4.0*g(2);
-    g(3) = 4.0*g(3);
-    g(4) = 4.0*g(4);
-  } else if (prob == 12) {
-    /* Gulf research and development function. */
-    g(1) = 0.0;
-    g(2) = 0.0;
-    g(3) = 0.0;
-    d1 = 2.0/3.0;
-    for (i=1 ; i<=99 ; ++i) {
-      arg = double(i)/100.0;
-      r = (-50.0*log(arg))^d1 + 25.0 - x(2);
-      t1 = (abs(r)^x(3))/x(1);
-      t2 = exp(-t1);
-      t = t2 - arg;
-      s1 = t1*t2*t;
-      g(1) = g(1) + s1;
-      g(2) = g(2) + s1/r;
-      g(3) = g(3) - s1*log(abs(r));
-    }
-    g(1) = 2.0*g(1)/x(1);
-    g(2) = 2.0*x(3)*g(2);
-    g(3) = 2.0*g(3);
-  } else if (prob == 13) {
-    /* Trigonometric function. */
-    s1 = 0.0;
-    for (j=1 ; j<=n ; ++j) {
-      g(j) = cos(x(j));
-      s1 += g(j);
-    }
-    s2 = 0.0;
-    for (j=1 ; j<=n ; ++j) {
-      th = sin(x(j));
-      t = double(n+j) - th - s1 - double(j)*g(j);
-      s2 += t;
-      g(j) = (double(j)*th - g(j))*t;
-    }
-    for (j=1 ; j<=n ; ++j) {
-      g(j) = 2.0*(g(j) + sin(x(j))*s2);
-    }
-  } else if (prob == 14) {
-    /* Extended Rosenbrock function. */
-    for (j=1 ; j<=n ; j+=2) {
-      t1 = 1.0 - x(j);
-      g(j+1) = 200.0*(x(j+1) - x(j)*x(j));
-      g(j) = -2.0*(x(j)*g(j+1) + t1);
-    }
-  } else if (prob == 15) {
-    /* Extended Powell function. */
-    for (j=1 ; j<=n ; j+=4) {
-      t = x(j) + 10.0*x(j+1);
-      t1 = x(j+2) - x(j+3);
-      s1 = 5.0*t1;
-      t2 = x(j+1) - 2.0*x(j+2);
-      s2 = 4.0*t2*t2*t2;
-      t3 = x(j) - x(j+3);
-      s3 = 20.0*t3*t3*t3;
-      g(j) = 2.0*(t + s3);
-      g(j+1) = 20.0*t + s2;
-      g(j+2) = 2.0*(s1 - s2);
-      g(j+3) = -2.0*(s1 + s3);
-    }
-  } else if (prob == 16) {
-    /* Beale function. */
-    s1 = 1.0 - x(2);
-    t1 = 1.5 - x(1)*s1;
-    s2 = 1.0 - x(2)*x(2);
-    t2 = 2.25 - x(1)*s2;
-    s3 = 1.0 - x(2)*x(2)*x(2);
-    t3 = 2.625 - x(1)*s3;
-    g(1) = -2.0*(s1*t1 + s2*t2 + s3*t3);
-    g(2) = 2.0*x(1)*(t1 + x(2)*(2.0*t2 + 3.0*x(2)*t3));
-  } else if (prob == 17) {
-    /* Wood function. */
-    s1 = x(2) - x(1)*x(1);
-    s2 = 1.0 - x(1);
-    s3 = x(2) - 1.0;
-    t1 = x(4) - x(3)*x(3);
-    t2 = 1.0 - x(3);
-    t3 = x(4) - 1.0;
-    g(1) = -2.0*(200.0*x(1)*s1 + s2);
-    g(2) = 200.0*s1 + 20.2*s3 + 19.8*t3;
-    g(3) = -2.0*(180.0*x(3)*t1 + t2);
-    g(4) = 180.0*t1 + 20.2*t3 + 19.8*s3;
-  } else if (prob == 18) {
-    /* Chebyquad function. */
-    fvec = array(0.0, n);
-    for (j=1 ; j<=n ; ++j) {
-      t1 = 1.0;
-      t2 = 2.0*x(j) - 1.0;
-      t = 2.0*t2;
-      for (i=1 ; i<=n ; ++i) {
-	fvec(i) += t2;
-	th = t*t2 - t1;
-	t1 = t2;
-	t2 = th;
-      }
-    }
-    d1 = 1.0/double(n);
-    iev = -1;
-    for (i=1 ; i<=n ; ++i) {
-      fvec(i) *= d1;
-      if (iev > 0) fvec(i) += 1.0/(double(i)*double(i) - 1.0);
-      iev = -iev;
-    }
-    for (j=1 ; j<=n ; ++j) {
-      g(j) = 0.0;
-      t1 = 1.0;
-      t2 = 2.0*x(j) - 1.0;
-      t = 2.0*t2;
-      s1 = 0.0;
-      s2 = 2.0;
-      for (i=1 ; i<=n ; ++i) {
-	g(j) = g(j) + fvec(i)*s2;
-	th = 4.0*t2 + t*s2 - s1;
-	s1 = s2;
-	s2 = th;
-	th = t*t2 - t1;
-	t1 = t2;
-	t2 = th;
-      }
-    }
-    d2 = 2.0*d1;
-    for (j=1 ; j<=n ; ++j) g(j) *= d2;
-  }
-  return g;
-}
-
-func minpack1_umipt(n, prob, factor)
-/* DOCUMENT minpack1_umipt(n, prob, factor)
-     Returns  the standard  starting points  for the  functions  defined by
-     subroutine  minpack1_umobj.  The  function  returns a  vector  X of  N
-     elements, X is a multiple  (times FACTOR, default 1.0) of the standard
-     starting point.  For the  seventh function the standard starting point
-     is 0.0,  so in this  case, if FACTOR  is not unity, then  the function
-     returns  X  filled with  FACTOR.   PROB has  the  same  meaning as  in
-     minpack1_umobj.
-
-   SEE ALSO: minpack1_umobj, minpack1_umipt. */
-{
-  if (is_void(factor)) factor = 1.0;
-  x = array(double, n);
-
-  /* Selection of initial point. */
-  if (prob == 1) {
-    /* Helical valley function. */
-    x(1) = -1.0;
-    x(2) = 0.0;
-    x(3) = 0.0;
-  } else if (prob == 2) {
-    /* Biggs exp6 function. */
-    x(1) = 1.0;
-    x(2) = 2.0;
-    x(3) = 1.0;
-    x(4) = 1.0;
-    x(5) = 1.0;
-    x(6) = 1.0;
-  } else if (prob == 3) {
-    /* Gaussian function. */
-    x(1) = 0.4;
-    x(2) = 1.0;
-    x(3) = 0.0;
-  } else if (prob == 4) {
-    /* Powell badly scaled function. */
-    x(1) = 0.0;
-    x(2) = 1.0;
-  } else if (prob == 5) {
-    /* Box 3-dimensional function. */
-    x(1) = 0.0;
-    x(2) = 10.0;
-    x(3) = 20.0;
-  } else if (prob == 6) {
-    /* Variably dimensioned function. */
-    h = 1.0/double(n);
-    for (j=1 ; j<=n ; ++j) x(j) = 1.0 - double(j)*h;
-  } else if (prob == 7) {
-    /* Watson function. */
-    for (j=1 ; j<=n ; ++j) x(j) = 0.0;
-  } else if (prob == 8) {
-    /* Penalty function I. */
-    for (j=1 ; j<=n ; ++j) x(j) = double(j);
-  } else if (prob == 9) {
-    /* Penalty function II. */
-    for (j=1 ; j<=n ; ++j) x(j) = 0.5;
-  } else if (prob == 10) {
-    /* Brown badly scaled function. */
-    x(1) = 1.0;
-    x(2) = 1.0;
-  } else if (prob == 11) {
-    /* Brown and Dennis function. */
-    x(1) = 25.0;
-    x(2) = 5.0;
-    x(3) = -5.0;
-    x(4) = -1.0;
-  } else if (prob == 12) {
-    /* Gulf research and development function. */
-    x(1) = 5.0;
-    x(2) = 2.5;
-    x(3) = 0.15;
-  } else if (prob == 13) {
-    /* Trigonometric function. */
-    h = 1.0/double(n);
-    for (j=1 ; j<=n ; ++j) x(j) = h;
-  } else if (prob == 14) {
-    /* Extended Rosenbrock function. */
-    for (j=1 ; j<=n ; j+=2) {
-      x(j) = -1.2;
-      x(j+1) = 1.0;
-    }
-  } else if (prob == 15) {
-    /* Extended Powell singular function. */
-    for (j=1 ; j<=n ; j+=4) {
-      x(j) = 3.0;
-      x(j+1) = -1.0;
-      x(j+2) = 0.0;
-      x(j+3) = 1.0;
-    }
-  } else if (prob == 16) {
-    /* Beale function. */
-    x(1) = 1.0;
-    x(2) = 1.0;
-  } else if (prob == 17) {
-    /* Wood function. */
-    x(1) = -3.0;
-    x(2) = -1.0;
-    x(3) = -3.0;
-    x(4) = -1.0;
-  } else if (prob == 18) {
-    /* Chebyquad function. */
-    h = 1.0/double(n+1);
-    for (j=1 ; j<=n ; ++j) x(j) = double(j)*h;
-  }
-  
-  /* Compute multiple of initial point. */
-  if (factor != 1.0) {
-    if (prob == 7) {
-      for (j=1 ; j<=n ; ++j) x(j) = factor;
-    } else {
-      for (j=1 ; j<=n ; ++j) x(j) *= factor;
-    }
-  }
-  return x;
-}
-
-/*---------------------------------------------------------------------------*
- * Local Variables:                                                          *
- * mode: Yorick                                                              *
- * tab-width: 8                                                              *
- * fill-column: 75                                                           *
- * coding: latin-1                                                           *
- * End:                                                                      *
- *---------------------------------------------------------------------------*/
diff -Nru yorick-optimpack-1.3.2+dfsg/yorick/OptimPack1-test.out.orig yorick-optimpack-1.3.2+dfsg+1.4.0/yorick/OptimPack1-test.out.orig
--- yorick-optimpack-1.3.2+dfsg/yorick/OptimPack1-test.out.orig	2007-07-05 10:02:54.000000000 +0000
+++ yorick-optimpack-1.3.2+dfsg+1.4.0/yorick/OptimPack1-test.out.orig	1970-01-01 00:00:00.000000000 +0000
@@ -1,1281 +0,0 @@
-#
-# Problem 1 (N=3): Helical valley function.
-# Method 0 (NDIR=3): Limited Memory BFGS (VMLM with NDIR=3)
-#
-# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
-# ---------------------------------------------------------------
-     0     1      0.000  +2.500000000000000e+03  1.9e+03  0.0e+00  
-     1     2      0.000  +1.132008103520547e+03  1.1e+03  1.0e+00  
-     2     3      0.000  +3.073911905701987e+02  4.7e+02  7.8e-01  
-     3     4      0.000  +8.534071352331746e+01  2.1e+02  9.3e-01  
-     4     5      0.000  +3.541502648995344e+01  1.1e+02  1.0e+00  
-     5     6      0.000  +1.762519408308565e+01  7.3e+01  1.0e+00  
-     6     7      0.000  +6.010226268823216e+00  1.7e+01  9.0e-01  
-     7     8      0.000  +5.492716897495775e+00  6.3e+00  1.0e+00  
-     8     9      0.000  +5.425503969579507e+00  4.3e+00  1.0e+00  
-     9    10      0.000  +5.265630629847704e+00  7.5e+00  1.0e+00  
-    10    11      0.000  +4.809839791888933e+00  1.9e+01  1.0e+00  
-    11    12      0.000  +3.522455208281464e+00  3.0e+01  1.0e+00  
-    12    14      0.000  +3.068297969073592e+00  2.7e+01  1.3e-01  
-    13    15      0.000  +2.100951192748246e+00  1.5e+01  1.0e+00  
-    14    16      0.000  +1.706672666076662e+00  1.3e+01  1.0e+00  
-    15    17      0.000  +8.286257916242681e-01  6.9e+00  1.0e+00  
-    16    18      4.001  +5.922941003132391e-01  9.6e+00  1.0e+00  
-    17    20      4.001  +5.103420996864492e-01  1.1e+01  4.4e-01  
-    18    21      4.001  +2.916460245825456e-01  7.0e+00  1.0e+00  
-    19    22      4.001  +1.004295671502106e-01  3.3e+00  1.0e+00  
-    20    23      4.001  +4.654709712389724e-02  1.3e+00  8.3e-01  
-    21    24      4.001  +1.427494728803810e-02  2.6e+00  4.6e-01  
-    22    25      4.001  +4.543295602689820e-03  1.0e-00  4.3e-01  
-    23    26      4.001  +1.007118040044901e-03  4.6e-01  9.2e-01  
-    24    27      4.001  +2.061213550356601e-04  1.9e-01  6.1e-01  
-    25    28      4.001  +4.141146958118607e-05  9.1e-02  5.9e-01  
-    26    29      4.001  +9.246362768846678e-06  4.6e-02  5.6e-01  
-    27    30      4.001  +3.194411530932206e-06  3.5e-02  3.1e-01  
-    28    31      4.001  +6.501783574339488e-07  1.4e-02  5.4e-01  
-    29    32      4.001  +1.343722348096534e-07  5.4e-03  5.9e-01  
-    30    33      4.001  +2.750162245743687e-08  2.3e-03  5.9e-01  
-    31    34      4.001  +6.952580275602280e-09  3.8e-04  5.4e-01  
-    32    35      4.001  +1.473890736071037e-09  2.1e-04  4.1e-01  
-    33    36      4.001  +3.751052304854505e-10  2.5e-04  4.4e-01  
-    34    37      4.001  +7.625216557423310e-11  9.0e-05  5.1e-01  
-    35    38      4.001  +1.622952431278697e-11  6.6e-05  5.2e-01  
-    36    39      4.001  +7.337759316133232e-12  3.6e-05  2.9e-01  
-    37    40      4.001  +1.484824633556255e-12  1.6e-05  5.6e-01  
-    38    41      4.001  +4.578352609117974e-13  1.2e-05  4.6e-01  
-    39    42      4.001  +9.211331598248391e-14  4.8e-06  4.1e-01  
-    40    43      4.001  +1.831236718906136e-14  2.5e-06  5.5e-01  
-    41    44      4.001  +5.028878022134398e-15  2.4e-07  5.2e-01  
-# op_vmlmb_next: FATOL test satisfied
-#
-#
-# Problem 2 (N=6): Biggs exp6 function.
-# Method 0 (NDIR=6): Limited Memory BFGS (VMLM with NDIR=6)
-#
-# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
-# ---------------------------------------------------------------
-     0     1      0.000  +7.790700756559702e-01  2.6e+00  0.0e+00  
-     1     3      4.000  +6.063399881248565e-01  1.4e+00  1.4e-01  
-     2     4      4.000  +5.345518690614532e-01  1.2e+00  1.0e+00  
-     3     5      4.000  +3.079086646397058e-01  4.0e-01  1.0e+00  
-     4     6      4.000  +2.937191017970756e-01  1.2e-01  1.0e+00  
-     5     7      4.000  +2.921168291268924e-01  3.4e-02  1.0e+00  
-     6     8      4.000  +2.918462455582488e-01  4.3e-02  1.0e+00  
-     7     9      4.000  +2.907755492762679e-01  9.9e-02  1.0e+00  
-     8    10      4.000  +2.881208307389913e-01  1.7e-01  1.0e+00  
-     9    11      4.000  +2.777833991389049e-01  4.6e-01  1.0e+00  
-    10    13      4.000  +2.612679403981057e-01  6.3e-01  5.2e-01  
-    11    14      4.000  +2.469361666977165e-01  9.9e-01  1.0e+00  
-    12    15      4.000  +2.036078330726717e-01  1.0e-00  1.0e+00  
-    13    16      4.000  +7.767306534374016e-02  3.6e-01  3.7e-01  
-    14    17      4.000  +5.174481985556744e-02  2.1e-01  1.0e+00  
-    15    18      4.000  +4.438442687186699e-02  3.2e-02  1.0e+00  
-    16    19      4.000  +4.327020633870218e-02  2.0e-02  1.0e+00  
-    17    20      4.000  +4.270533262117948e-02  2.0e-02  1.0e+00  
-    18    21      4.000  +3.969619752160380e-02  2.1e-01  1.0e+00  
-    19    22      4.000  +3.608256498897430e-02  2.2e-01  1.0e+00  
-    20    23      8.000  +2.496078630339771e-02  8.7e-03  1.0e+00  
-    21    25      8.000  +2.354604949127677e-02  1.2e-01  2.2e-01  
-    22    26      8.000  +1.888593515049183e-02  1.4e-01  1.0e+00  
-    23    27      8.000  +1.155437130469526e-02  7.9e-02  1.0e+00  
-    24    28      8.000  +8.080802739733741e-03  4.6e-02  1.0e+00  
-    25    30      8.000  +7.156021780018340e-03  1.1e-01  4.9e-01  
-    26    31      8.000  +6.273418884507282e-03  7.0e-02  1.0e+00  
-    27    32      8.000  +5.939819199276478e-03  9.8e-03  1.0e+00  
-    28    33      8.000  +5.908026441632852e-03  1.0e-02  1.0e+00  
-    29    35      8.000  +5.859754857684088e-03  1.0e-02  2.8e-02  
-    30    36      8.000  +5.765713460425574e-03  7.4e-03  1.0e+00  
-    31    37      8.000  +5.675434828171089e-03  7.0e-03  1.0e+00  
-    32    38      8.000  +5.657523454643495e-03  3.2e-03  1.0e+00  
-    33    39      8.000  +5.655833463796146e-03  4.4e-04  1.0e+00  
-    34    40      8.000  +5.655671174917713e-03  2.4e-04  1.0e+00  
-    35    42      8.000  +5.655652521284395e-03  1.2e-04  3.3e-01  
-    36    43      8.000  +5.655650195207963e-03  3.0e-05  1.0e+00  
-    37    44     12.000  +5.655649926013700e-03  6.4e-07  1.0e+00  
-    38    45     12.000  +5.655649925527675e-03  2.3e-07  1.0e+00  
-    39    46     12.000  +5.655649925502423e-03  9.0e-08  1.0e+00  
-# op_vmlmb_next: FRTOL test satisfied
-#
-#
-# Problem 3 (N=3): Gaussian function.
-# Method 0 (NDIR=3): Limited Memory BFGS (VMLM with NDIR=3)
-#
-# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
-# ---------------------------------------------------------------
-     0     1      0.000  +3.888106991166885e-06  7.5e-03  0.0e+00  
-     1     2      0.000  +7.716984735720412e-07  3.3e-03  5.8e-04  
-     2     3      0.000  +1.561242789005403e-07  1.4e-03  5.6e-01  
-     3     4      0.000  +3.476004610942878e-08  5.7e-04  6.0e-01  
-     4     5      0.000  +1.232954447864692e-08  9.3e-05  8.4e-01  
-     5     6      0.000  +1.171122486137217e-08  1.1e-05  1.0e+00  
-     6     8      0.000  +1.163182146077833e-08  1.2e-05  5.0e+00  
-     7     9      0.000  +1.130733360163093e-08  1.6e-05  1.0e+00  
-     8    10      0.000  +1.127985527183232e-08  2.7e-06  1.0e+00  
-     9    11      0.000  +1.127932791925235e-08  4.0e-08  1.0e+00  
-    10    12      0.000  +1.127932769618526e-08  8.6e-12  1.0e+00  
-# op_vmlmb_next: FATOL test satisfied
-#
-#
-# Problem 4 (N=2): Powell badly scaled function.
-# Method 0 (NDIR=2): Limited Memory BFGS (VMLM with NDIR=2)
-#
-# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
-# ---------------------------------------------------------------
-     0     1      0.000  +1.135261717348378e+00  2.0e+04  0.0e+00  
-     1     2      0.000  +2.716142498422306e-01  7.4e+03  6.3e-05  
-     2     3      0.000  +1.351881720546067e-01  2.7e-01  1.0e+00  
-     3    14      0.000  +1.347499857711354e-01  1.7e+02  1.4e+06  
-     4    15      0.000  +1.325667967357710e-01  6.0e+02  1.0e+00  
-     5    16      0.000  +1.268168829890248e-01  1.4e+03  1.0e+00  
-     6    17      0.000  +1.130266725138436e-01  2.2e+03  1.0e+00  
-     7    18      0.000  +7.189847553126569e-02  2.1e+03  1.0e+00  
-     8    20      0.000  +6.626840795010225e-02  7.5e+01  3.3e-03  
-     9    21      0.000  +4.050790583682891e-02  5.5e+02  1.0e+00  
-    10    22      0.000  +2.603122017596488e-02  2.9e+03  1.0e+00  
-    11    23      0.000  +1.344335372038092e-02  1.8e+03  8.0e-01  
-    12    24      0.000  +7.754280961808157e-03  1.8e+03  1.0e+00  
-    13    25      0.000  +6.035962443792143e-03  6.0e+02  1.0e+00  
-    14    26      0.000  +3.520105110849622e-03  2.7e+02  1.0e+00  
-    15    27      0.000  +2.370401920922337e-03  1.3e+03  1.0e+00  
-    16    28      0.000  +1.111838810799019e-03  5.4e+02  8.5e-01  
-    17    30      0.000  +7.562658146984992e-04  4.1e+02  4.8e-01  
-    18    31      0.000  +6.291294727585325e-04  7.2e+02  1.0e+00  
-    19    32      0.000  +4.125929545959699e-04  4.0e+02  1.0e+00  
-    20    33      0.000  +2.786252603932807e-04  2.3e+02  1.0e+00  
-    21    34      0.000  +1.865344312220937e-04  6.5e+01  1.0e+00  
-    22    36      0.000  +1.746213097705067e-04  2.7e+02  1.2e-01  
-    23    37      0.000  +1.311007032893237e-04  3.1e+02  1.0e+00  
-    24    38      0.000  +8.604790308724185e-05  9.6e+01  1.0e+00  
-    25    40      0.000  +6.713643137639769e-05  1.5e+02  3.7e-01  
-    26    41      0.000  +6.009576963699230e-05  3.4e+02  1.0e+00  
-    27    42      0.000  +4.592112785957327e-05  1.3e+02  1.0e+00  
-    28    43      0.000  +3.318733434604557e-05  1.3e+02  1.0e+00  
-    29    45      0.000  +3.153928824477498e-05  7.9e-01  2.0e-04  
-    30    46      0.000  +2.316717042185159e-05  1.3e+02  1.0e+00  
-    31    47      0.000  +1.983842227523587e-05  1.8e+02  1.0e+00  
-    32    48      0.000  +1.370511800174228e-05  1.2e+02  1.0e+00  
-    33    50      0.000  +1.002231977553119e-05  2.0e+01  3.7e-01  
-    34    52      4.001  +9.448845461709604e-06  7.8e+01  3.1e-01  
-    35    53      4.001  +8.796547092034665e-06  8.8e+01  1.0e+00  
-    36    54      4.001  +6.012203046585967e-06  3.7e+00  1.0e+00  
-    37    56      4.001  +5.591031631209653e-06  5.2e+01  2.2e-01  
-    38    57      4.001  +5.042798867261178e-06  8.1e+01  1.0e+00  
-    39    58      4.001  +4.037916381025496e-06  4.9e+01  1.0e+00  
-    40    59      4.001  +3.325226275541043e-06  2.6e+01  1.0e+00  
-    41    61      4.001  +3.145813424606391e-06  5.4e+01  2.7e-01  
-    42    62      4.001  +2.620153892100086e-06  5.5e+01  1.0e+00  
-    43    64      4.001  +2.415748503691216e-06  2.5e+00  2.2e-02  
-    44    65      4.001  +2.007550819175101e-06  3.0e+01  1.0e+00  
-    45    67      4.001  +1.890695485188910e-06  5.1e+01  4.5e-01  
-    46    68      4.001  +1.536361962738215e-06  3.0e+01  1.0e+00  
-    47    69      4.001  +1.311168885938422e-06  2.0e+01  1.0e+00  
-    48    70      4.001  +1.246078119694974e-06  4.5e+01  1.0e+00  
-    49    72      4.001  +9.491335127465187e-07  7.2e+00  3.3e-01  
-    50    74      4.001  +8.891242770948279e-07  2.8e+01  6.9e-02  
-    51    75      4.001  +8.700737460692882e-07  1.9e+01  1.0e+00  
-    52    76      4.001  +7.774251370222714e-07  7.0e+00  1.0e+00  
-    53    78      4.001  +7.054120977646890e-07  1.4e+01  3.9e-01  
-    54    80      4.001  +6.079579263162548e-07  2.2e+01  3.9e-01  
-    55    81      4.001  +4.495947084220561e-07  1.7e+01  1.0e+00  
-    56    83      4.001  +3.956164009642611e-07  6.9e+00  5.9e-02  
-    57    85      4.001  +3.842041614956623e-07  1.6e+01  4.7e-01  
-    58    86      4.001  +3.650291414806386e-07  2.0e+01  1.0e+00  
-    59    87      4.001  +2.977310422144736e-07  1.0e+01  1.0e+00  
-    60    88      4.001  +2.645228220544150e-07  8.7e+00  1.0e+00  
-    61    90      4.001  +2.625753218665754e-07  2.1e+00  1.3e-02  
-    62    92      4.001  +2.351392468128754e-07  7.8e+00  5.3e-01  
-    63    94      4.001  +2.228437274607579e-07  1.5e+01  3.0e-01  
-    64    95      4.001  +1.908884988619849e-07  1.6e+01  1.0e+00  
-    65    97      4.001  +1.775213596206642e-07  1.5e+00  7.7e-02  
-    66    98      4.001  +1.563404116641290e-07  9.7e+00  1.0e+00  
-    67   100      4.001  +1.512029496166810e-07  1.4e+01  4.4e-01  
-    68   101      4.001  +1.307607535470326e-07  9.5e+00  1.0e+00  
-    69   102      4.001  +1.175169650897558e-07  2.0e+00  1.0e+00  
-    70   104      4.001  +1.072392194161219e-07  5.1e+00  2.9e-01  
-    71   106      4.001  +1.037392963035747e-07  9.8e+00  2.9e-01  
-    72   107      4.001  +9.620878417591773e-08  1.0e+01  1.0e+00  
-    73   109      4.001  +9.039151653346654e-08  1.6e+00  8.0e-02  
-    74   110      4.001  +8.006176991138113e-08  8.3e+00  1.0e+00  
-    75   111      4.001  +7.595885339417243e-08  1.0e+01  1.0e+00  
-    76   112      4.001  +6.314410560360231e-08  4.1e-01  1.0e+00  
-    77   114      4.001  +6.008323382664185e-08  5.3e+00  2.6e-01  
-    78   115      4.001  +5.774858820209131e-08  1.1e+01  1.0e+00  
-    79   116      4.001  +5.227214564981060e-08  4.5e+00  1.0e+00  
-    80   117      4.001  +4.671286653797208e-08  7.9e+00  1.0e+00  
-    81   118      4.001  +4.218605795772740e-08  4.0e+00  1.0e+00  
-    82   120      4.001  +3.978787254803439e-08  7.2e+00  5.2e-01  
-    83   121      4.001  +3.475025245891024e-08  4.6e+00  1.0e+00  
-    84   122      4.001  +3.131608455766981e-08  8.5e-01  1.0e+00  
-    85   124      4.001  +2.975290789910577e-08  4.2e+00  1.9e-01  
-    86   125      4.001  +2.844598223236710e-08  8.2e+00  1.0e+00  
-    87   126      4.001  +2.529667836942072e-08  2.4e+00  1.0e+00  
-    88   127      4.001  +2.285266654491062e-08  5.8e+00  1.0e+00  
-    89   128      4.001  +2.110270876321310e-08  3.4e+00  1.0e+00  
-    90   130      4.001  +1.982830112972024e-08  4.6e+00  4.7e-01  
-    91   131      4.001  +1.556088550165383e-08  1.6e-01  1.0e+00  
-    92   133      4.001  +1.509931751153993e-08  2.7e+00  1.1e-01  
-    93   134      4.001  +1.441420778804029e-08  3.7e+00  1.0e+00  
-    94   135      4.001  +1.303715234141585e-08  4.6e+00  1.0e+00  
-    95   137      4.001  +1.183143970298517e-08  1.5e+00  1.6e-01  
-    96   139      4.001  +1.083047880278837e-08  4.3e-01  4.4e-01  
-    97   141      4.001  +1.033931695032363e-08  3.5e+00  1.4e-01  
-    98   142      4.001  +9.955899460561576e-09  2.8e+00  1.0e+00  
-    99   143      4.001  +8.883196616290377e-09  4.3e+00  1.0e+00  
-   100   145      4.001  +7.742742776189192e-09  2.1e+00  2.7e-01  
-   101   147      4.001  +6.834754461132445e-09  9.3e-01  4.0e-01  
-   102   149      4.001  +6.666959323631201e-09  2.3e+00  1.9e-01  
-   103   150      4.001  +6.411180662499273e-09  2.8e+00  1.0e+00  
-   104   151      4.001  +5.435981187381998e-09  2.0e+00  1.0e+00  
-   105   153      4.001  +5.283745805222238e-09  1.1e-01  2.0e-01  
-   106   154      4.001  +4.667635231009192e-09  2.4e+00  1.0e+00  
-   107   155      4.001  +4.374389490301682e-09  2.4e+00  1.0e+00  
-   108   157      8.001  +4.163941820284297e-09  7.6e-02  1.3e-02  
-   109   158      8.001  +3.677160794243351e-09  1.7e+00  1.0e+00  
-   110   160      8.001  +3.556463460936755e-09  2.4e+00  4.1e-01  
-   111   161      8.001  +3.036430367400247e-09  1.7e+00  1.0e+00  
-   112   162      8.001  +2.784362981880398e-09  1.2e+00  1.0e+00  
-   113   164      8.001  +2.406505899582082e-09  6.4e-01  4.2e-01  
-   114   166      8.001  +2.340080591653236e-09  1.5e+00  1.6e-01  
-   115   167      8.001  +2.232707735696947e-09  1.8e+00  1.0e+00  
-   116   168      8.001  +1.807669675248058e-09  8.9e-01  1.0e+00  
-   117   169      8.001  +1.621579861725144e-09  1.5e+00  1.0e+00  
-   118   171      8.001  +1.260526356088865e-09  4.8e-01  3.1e-01  
-   119   173      8.001  +1.158748732953299e-09  1.3e+00  1.3e-01  
-   120   174      8.001  +1.091888811725686e-09  1.0e+00  1.0e+00  
-   121   175      8.001  +9.252174759540841e-10  1.4e+00  1.0e+00  
-   122   177      8.001  +8.177332024184264e-10  5.0e-01  7.1e-02  
-   123   180      8.001  +6.877682728262519e-10  9.4e-01  6.3e-01  
-   124   181      8.001  +6.521162246605309e-10  1.4e+00  1.0e+00  
-   125   182      8.001  +5.245455884270034e-10  5.8e-01  1.0e+00  
-   126   183      8.001  +4.740039908668378e-10  1.4e+00  1.0e+00  
-   127   184      8.001  +3.675734148905452e-10  1.5e-01  1.0e+00  
-   128   186      8.001  +3.278212930002444e-10  7.1e-01  4.5e-01  
-   129   187      8.001  +2.991826277801766e-10  1.1e+00  1.0e+00  
-   130   188      8.001  +2.261615323913900e-10  2.1e-01  1.0e+00  
-   131   190      8.001  +1.996749791891283e-10  6.8e-01  5.4e-01  
-   132   191      8.001  +1.748408381668149e-10  7.5e-01  1.0e+00  
-   133   193      8.001  +1.441186976349858e-10  2.6e-01  3.3e-01  
-   134   195      8.001  +1.168134759399082e-10  1.2e-01  5.0e-01  
-   135   197      8.001  +1.065919364144133e-10  4.5e-01  1.6e-01  
-   136   198      8.001  +9.624408438738366e-11  5.9e-01  1.0e+00  
-   137   199      8.001  +6.522624230099676e-11  2.6e-01  1.0e+00  
-   138   200      8.001  +5.382979150929681e-11  5.4e-01  1.0e+00  
-   139   201      8.001  +2.357595065249005e-11  5.6e-02  9.4e-01  
-   140   203      8.001  +2.194863217396652e-11  2.2e-01  2.0e-01  
-   141   204      8.001  +1.824678260827043e-11  2.6e-01  1.0e+00  
-   142   205      8.001  +1.007427717509816e-11  1.8e-01  1.0e+00  
-   143   207      8.001  +9.240366653486143e-12  1.5e-02  1.2e-01  
-   144   208      8.001  +5.277029415816368e-12  1.3e-01  1.0e+00  
-   145   209      8.001  +4.150258646119530e-12  2.7e-01  1.0e+00  
-   146   210      8.001  +1.419227552276263e-12  3.3e-02  6.6e-01  
-   147   211      8.001  +6.157107277445726e-13  6.3e-02  1.0e+00  
-   148   212      8.001  +2.164773422247019e-13  5.5e-02  1.0e+00  
-   149   213      8.001  +1.645865002459103e-13  2.4e-02  3.0e-02  
-   150   214      8.001  +3.516759308772241e-14  4.5e-03  8.8e-01  
-   151   215      8.001  +1.152075456477990e-14  1.4e-02  7.0e-01  
-# op_vmlmb_next: FATOL test satisfied
-#
-#
-# Problem 5 (N=3): Box 3-dimensional function.
-# Method 0 (NDIR=3): Limited Memory BFGS (VMLM with NDIR=3)
-#
-# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
-# ---------------------------------------------------------------
-     0     1      0.000  +1.031153810609398e+03  1.5e+02  0.0e+00  
-     1     4      0.000  +5.051751883930287e+02  1.4e+02  3.2e+00  
-     2     7      0.000  +4.693698123274796e+02  6.3e+01  9.6e-03  
-     3     8      0.000  +4.196780145077672e+02  7.3e+01  1.0e+00  
-     4     9      0.000  +9.577851908664192e+01  7.3e+01  6.4e-01  
-     5    10      0.000  +2.963077540829067e+01  6.2e+01  8.2e-01  
-     6    11      0.000  +1.472450551152400e+01  1.0e+01  1.3e-01  
-     7    12      0.000  +4.692489499264585e+00  1.1e+01  9.0e-01  
-     8    13      0.000  +2.930070582447900e+00  9.1e+00  1.0e+00  
-     9    14      0.000  +1.626093588037745e+00  5.9e+00  1.0e+00  
-    10    15      0.000  +6.607304557529599e-01  1.5e+00  1.0e+00  
-    11    16      0.000  +2.360905443567035e-01  1.2e+00  1.0e+00  
-    12    17      0.000  +9.771929015861618e-02  7.4e-01  1.0e+00  
-    13    18      4.000  +2.921048390382599e-02  3.1e-01  1.0e+00  
-    14    19      4.000  +7.162028854070950e-03  1.4e-01  1.0e+00  
-    15    20      4.000  +1.918627248183639e-03  3.8e-02  8.5e-01  
-    16    21      4.000  +5.706147462900988e-04  4.1e-02  5.0e-01  
-    17    22      4.000  +1.767122289515497e-04  5.9e-03  6.7e-01  
-    18    23      4.000  +1.388438676986920e-04  1.1e-03  1.0e+00  
-    19    24      4.000  +1.380987151663160e-04  1.5e-03  1.0e+00  
-    20    25      4.000  +1.375596494219131e-04  1.6e-03  1.0e+00  
-    21    26      4.000  +1.348123100471587e-04  2.7e-03  1.0e+00  
-    22    27      4.000  +1.273751593447703e-04  2.4e-03  1.0e+00  
-    23    29      4.000  +1.236844681639359e-04  8.5e-03  3.4e-01  
-    24    30      4.000  +1.111624159031401e-04  6.1e-03  1.0e+00  
-    25    31      4.000  +7.709438714814043e-05  4.2e-03  1.0e+00  
-    26    32      4.000  +3.555022908765118e-05  5.5e-03  1.0e+00  
-    27    33      4.000  +1.388449576270083e-05  1.2e-02  8.4e-01  
-    28    34      4.000  +3.499447500852135e-06  4.8e-03  2.5e-01  
-    29    35      4.000  +7.802810396086031e-07  1.7e-03  7.4e-01  
-    30    36      4.000  +1.797026655239720e-07  4.0e-04  6.9e-01  
-    31    37      4.000  +4.113226590053436e-08  1.4e-04  6.9e-01  
-    32    38      4.000  +1.170488139789506e-08  6.3e-06  5.5e-01  
-    33    39      4.000  +8.860893531384294e-09  2.9e-04  7.0e-01  
-    34    40      4.000  +3.295705185007528e-09  6.7e-05  1.0e+00  
-    35    41      4.000  +1.824061308183375e-09  2.4e-05  1.0e+00  
-    36    42      4.000  +4.894303628176848e-10  4.1e-05  8.8e-01  
-    37    43      4.000  +1.063838077120574e-10  2.6e-05  7.7e-01  
-    38    44      4.000  +2.936005901492016e-11  4.7e-06  4.7e-01  
-    39    45      4.000  +7.520001768792375e-12  1.9e-06  6.8e-01  
-    40    46      4.000  +3.232186206428190e-12  2.7e-06  1.0e+00  
-    41    47      4.000  +2.382259476974284e-12  7.7e-07  1.0e+00  
-    42    48      4.000  +1.627836101802466e-12  7.8e-07  1.0e+00  
-    43    49      4.000  +8.722135008897642e-13  1.8e-06  1.0e+00  
-    44    50      4.000  +3.181054605846769e-13  1.3e-06  1.0e+00  
-    45    51      4.000  +1.819403692094123e-13  5.7e-07  1.0e+00  
-    46    52      4.000  +1.552379827036547e-13  2.8e-07  1.0e+00  
-# op_vmlmb_next: FATOL test satisfied
-#
-#
-# Problem 6 (N=10): Variably dimensioned function.
-# Method 0 (NDIR=10): Limited Memory BFGS (VMLM with NDIR=10)
-#
-# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
-# ---------------------------------------------------------------
-     0     1      0.000  +2.198551162500000e+06  4.5e+06  0.0e+00  
-     1     2      0.000  +5.982233536014224e+05  1.7e+06  5.5e-01  
-     2     3      0.000  +2.077189332476444e+05  7.6e+05  1.0e+00  
-     3     4      4.000  +6.578142669110338e+04  3.2e+05  1.0e+00  
-     4     5      4.000  +2.160249233159776e+04  1.4e+05  1.0e+00  
-     5     6      4.000  +7.004735376311746e+03  6.0e+04  1.0e+00  
-     6     7      4.000  +2.287386781801080e+03  2.6e+04  1.0e+00  
-     7     8      4.000  +7.476983219073760e+02  1.1e+04  1.0e+00  
-     8     9      4.000  +2.458538169695109e+02  4.8e+03  1.0e+00  
-     9    10      4.000  +8.149749297306352e+01  2.1e+03  1.0e+00  
-    10    11      4.000  +2.737280609091122e+01  9.0e+02  1.0e+00  
-    11    12      4.000  +9.362878818503740e+00  3.9e+02  1.0e+00  
-    12    13      4.000  +3.269284473674885e+00  1.7e+02  1.0e+00  
-    13    14      4.000  +1.153504000090763e+00  7.7e+01  1.0e+00  
-    14    15      4.000  +3.936136413645998e-01  3.5e+01  1.0e+00  
-    15    16      4.000  +1.147737756239351e-01  1.5e+01  1.0e+00  
-    16    17      4.000  +2.581587916978744e-02  6.5e+00  9.1e-01  
-    17    18      4.000  +5.303642148696754e-03  2.9e+00  7.0e-01  
-    18    19      4.000  +1.056848632834968e-03  1.3e+00  5.9e-01  
-    19    20      4.000  +2.091314644328269e-04  5.7e-01  5.6e-01  
-    20    21      4.000  +4.132449788388705e-05  2.5e-01  5.6e-01  
-    21    22      4.000  +8.163433357518874e-06  1.1e-01  5.6e-01  
-    22    23      4.000  +1.612552275601864e-06  5.0e-02  5.6e-01  
-    23    24      4.000  +3.185297119742180e-07  2.2e-02  5.6e-01  
-    24    25      4.000  +6.291948312422135e-08  9.9e-03  5.6e-01  
-    25    26      4.000  +1.242854119682474e-08  4.4e-03  5.6e-01  
-    26    27      4.000  +2.455020534958202e-09  1.9e-03  5.6e-01  
-    27    28      4.000  +4.849423299090284e-10  8.7e-04  5.6e-01  
-    28    29      4.000  +9.579107757034683e-11  3.8e-04  5.6e-01  
-    29    30      4.000  +1.892169434557917e-11  1.7e-04  5.6e-01  
-    30    31      4.000  +3.737618638352018e-12  7.6e-05  5.6e-01  
-    31    32      4.000  +7.382950396510434e-13  3.4e-05  5.6e-01  
-    32    33      4.000  +1.458360569885202e-13  1.5e-05  5.6e-01  
-    33    34      4.000  +2.880712217942045e-14  6.7e-06  5.6e-01  
-    34    35      4.000  +5.690295862135377e-15  3.0e-06  5.6e-01  
-# op_vmlmb_next: FATOL test satisfied
-#
-#
-# Problem 7 (N=6): Watson function.
-# Method 0 (NDIR=6): Limited Memory BFGS (VMLM with NDIR=6)
-#
-# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
-# ---------------------------------------------------------------
-     0     1      0.000  +3.000000000000000e+01  1.4e+02  0.0e+00  
-     1     2      0.000  +1.153491761608158e+01  3.6e+01  2.4e-01  
-     2     3      0.000  +8.662294302946657e+00  2.7e+01  1.0e+00  
-     3     4      0.000  +2.159765745956006e+00  1.3e+01  1.0e+00  
-     4     5      0.000  +9.370932269174013e-01  9.6e+00  6.9e-01  
-     5     6      0.000  +6.260360367334762e-01  2.7e+00  1.0e+00  
-     6     7      0.000  +5.588208440197413e-01  2.9e+00  1.0e+00  
-     7     8      0.000  +4.320129246513010e-01  4.0e+00  1.0e+00  
-     8     9      0.000  +1.782329757356047e-01  4.6e+00  1.0e+00  
-     9    10      4.001  +4.357179339744174e-02  1.6e+00  6.4e-01  
-    10    11      4.001  +2.446191487403206e-02  4.8e-01  1.0e+00  
-    11    12      4.001  +2.250413138430174e-02  3.4e-01  1.0e+00  
-    12    13      4.001  +2.111722399878381e-02  5.5e-01  1.0e+00  
-    13    14      4.001  +1.606205485982599e-02  8.0e-01  1.0e+00  
-    14    16      8.001  +1.060663387077928e-02  1.8e-01  5.1e-01  
-    15    17      8.001  +1.023711762982278e-02  2.1e-01  1.0e+00  
-    16    18      8.001  +1.014232386791980e-02  2.5e-02  1.0e+00  
-    17    19      8.001  +1.012808413731048e-02  3.0e-02  1.0e+00  
-    18    20      8.001  +1.011416301337225e-02  1.9e-02  1.0e+00  
-    19    21     12.001  +1.010622490501859e-02  1.7e-02  1.0e+00  
-    20    22     12.001  +1.005354212767259e-02  2.5e-02  1.0e+00  
-    21    23     12.001  +9.914998965299265e-03  4.3e-02  1.0e+00  
-    22    24     12.001  +9.633255378335592e-03  5.2e-02  1.0e+00  
-    23    25     12.001  +9.435981241419105e-03  3.2e-01  1.0e+00  
-    24    26     12.001  +9.074119841420146e-03  9.2e-02  1.0e+00  
-    25    27     16.001  +8.948864483207091e-03  2.6e-02  1.0e+00  
-    26    28     16.001  +8.942033313705005e-03  9.7e-03  1.0e+00  
-    27    29     16.001  +8.940317436619535e-03  7.6e-03  1.0e+00  
-    28    30     16.001  +8.936673299222047e-03  1.6e-02  1.0e+00  
-    29    31     16.001  +8.932411285273037e-03  2.3e-02  1.0e+00  
-    30    32     16.001  +8.923876594747306e-03  2.4e-02  1.0e+00  
-    31    34     20.002  +8.919738995782814e-03  6.0e-02  1.4e-01  
-    32    35     20.002  +8.900791041922290e-03  5.2e-02  1.0e+00  
-    33    36     20.002  +8.821982716914249e-03  5.8e-02  1.0e+00  
-    34    37     20.002  +8.676125612127840e-03  4.9e-02  1.0e+00  
-    35    38     20.002  +8.443320768310978e-03  3.1e-01  1.0e+00  
-    36    39     24.002  +7.962339610876239e-03  1.2e-01  1.0e+00  
-    37    40     24.002  +7.700051635114865e-03  9.5e-02  1.0e+00  
-    38    41     24.002  +7.564775888244103e-03  9.7e-02  1.0e+00  
-    39    43     24.002  +7.490280990021314e-03  2.0e-01  8.1e-02  
-    40    44     24.002  +7.225853155050442e-03  1.1e-01  1.0e+00  
-    41    45     28.002  +7.027986857610604e-03  6.7e-02  1.0e+00  
-    42    46     28.002  +6.898992549696143e-03  1.2e-01  1.0e+00  
-    43    47     28.002  +6.696669267370094e-03  1.1e-01  1.0e+00  
-    44    48     28.002  +6.521394247682940e-03  3.6e-01  1.0e+00  
-    45    49     28.002  +5.900564228855348e-03  1.5e-01  1.0e+00  
-    46    50     28.002  +5.436162501033610e-03  1.2e-01  1.0e+00  
-    47    51     32.002  +5.185527792214816e-03  1.9e-01  1.0e+00  
-    48    52     32.002  +4.977046075759494e-03  1.4e-01  1.0e+00  
-    49    53     32.002  +4.658566016994147e-03  7.2e-02  1.0e+00  
-    50    54     32.002  +4.308711947089532e-03  1.0e-01  1.0e+00  
-    51    55     32.002  +3.919697403900082e-03  1.9e-01  1.0e+00  
-    52    56     32.002  +3.280783714973028e-03  1.9e-01  1.0e+00  
-    53    57     36.003  +2.520432499557056e-03  1.6e-01  1.0e+00  
-    54    59     36.003  +2.457626981592080e-03  1.4e-01  2.8e-02  
-    55    60     36.003  +2.311981662769732e-03  5.2e-02  1.0e+00  
-    56    61     36.003  +2.289345802013666e-03  6.1e-03  1.0e+00  
-    57    62     36.003  +2.288985893595373e-03  2.9e-03  1.0e+00  
-    58    63     40.003  +2.288455672536768e-03  2.7e-03  1.0e+00  
-    59    64     40.003  +2.287793236670549e-03  1.9e-03  1.0e+00  
-    60    65     40.003  +2.287695261121659e-03  1.5e-03  1.0e+00  
-    61    67     40.003  +2.287684367911231e-03  6.3e-04  4.8e-01  
-    62    68     40.003  +2.287676176945362e-03  3.6e-04  1.0e+00  
-    63    70     44.003  +2.287675098559974e-03  2.0e-04  3.4e-01  
-    64    71     44.003  +2.287673953644514e-03  6.5e-05  1.0e+00  
-    65    72     44.003  +2.287673573776456e-03  5.8e-05  1.0e+00  
-    66    73     44.003  +2.287672636686810e-03  1.3e-04  1.0e+00  
-    67    74     44.003  +2.287671819591959e-03  1.5e-04  1.0e+00  
-    68    76     48.003  +2.287671215406123e-03  3.4e-04  3.9e-01  
-    69    77     48.003  +2.287670175158950e-03  7.6e-05  1.0e+00  
-    70    78     48.003  +2.287670069963467e-03  3.0e-05  1.0e+00  
-    71    79     48.003  +2.287670055842873e-03  1.1e-05  1.0e+00  
-    72    80     48.003  +2.287670054951157e-03  7.6e-06  1.0e+00  
-    73    81     52.004  +2.287670054462369e-03  2.6e-06  1.0e+00  
-    74    82     52.004  +2.287670054258627e-03  1.8e-06  1.0e+00  
-    75    83     52.004  +2.287670053768855e-03  4.4e-06  1.0e+00  
-    76    85     52.004  +2.287670053701440e-03  2.1e-06  3.5e-01  
-# op_vmlmb_next: FRTOL test satisfied
-#
-#
-# Problem 8 (N=10): Penalty function I.
-# Method 0 (NDIR=10): Limited Memory BFGS (VMLM with NDIR=10)
-#
-# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
-# ---------------------------------------------------------------
-     0     1      0.000  +1.480325653500000e+05  3.0e+04  0.0e+00  
-     1     2      0.000  +1.200672187926850e+05  2.6e+04  1.0e+00  
-     2     3      0.000  +3.265992616691508e+04  9.7e+03  8.8e-01  
-     3     4      0.000  +1.132290692299289e+04  4.4e+03  1.0e+00  
-     4     5      0.000  +3.577134652544013e+03  1.9e+03  1.0e+00  
-     5     6      0.000  +1.169681852985238e+03  8.0e+02  1.0e+00  
-     6     7      0.000  +3.764229133643723e+02  3.4e+02  1.0e+00  
-     7     8      4.000  +1.213086610658549e+02  1.5e+02  1.0e+00  
-     8     9      4.000  +3.874731549111131e+01  6.3e+01  1.0e+00  
-     9    10      4.000  +1.223737772730658e+01  2.7e+01  1.0e+00  
-    10    11      4.000  +3.782057667252822e+00  1.2e+01  1.0e+00  
-    11    12      4.000  +1.125513580941122e+00  4.9e+00  1.0e+00  
-    12    13      4.000  +3.129446120087767e-01  2.0e+00  1.0e+00  
-    13    14      4.000  +7.756206235205798e-02  8.1e-01  1.0e-00  
-    14    15      4.000  +1.827422007113406e-02  3.3e-01  9.2e-01  
-    15    16      4.000  +4.085118985926949e-03  1.4e-01  8.1e-01  
-    16    17      4.000  +8.877332480334356e-04  6.0e-02  7.2e-01  
-    17    18      4.000  +2.065403882446298e-04  2.4e-02  6.9e-01  
-    18    19      4.000  +7.703710321289555e-05  3.2e-03  9.3e-01  
-    19    20      4.000  +7.446943015394475e-05  1.1e-04  1.0e+00  
-    20    21      4.000  +7.446618591447701e-05  2.9e-05  1.0e+00  
-    21    23      4.000  +7.446415870380601e-05  5.2e-05  5.0e+00  
-    22    24      4.000  +7.445657592228791e-05  1.2e-04  1.0e+00  
-    23    25      4.000  +7.442752521815094e-05  2.8e-04  1.0e+00  
-    24    26      4.000  +7.434003956432855e-05  5.2e-04  1.0e+00  
-    25    29      4.000  +7.349631102481636e-05  6.1e-04  5.9e-01  
-    26    31      4.000  +7.349026117318990e-05  4.7e-04  2.2e-01  
-    27    33      4.000  +7.331713301296246e-05  4.0e-04  5.0e+00  
-    28    35      4.000  +7.310908109664723e-05  5.5e-04  4.7e-01  
-    29    36      4.000  +7.281998859159809e-05  8.1e-04  1.0e+00  
-    30    37      4.000  +7.250779119403938e-05  2.0e-04  1.0e+00  
-    31    39      4.000  +7.230694011645983e-05  2.8e-04  3.9e-01  
-    32    41      4.000  +7.225525250357204e-05  5.3e-04  2.7e-01  
-    33    42      4.000  +7.216099121388021e-05  5.7e-04  1.0e+00  
-    34    43      4.000  +7.193027784341741e-05  4.0e-04  1.0e+00  
-    35    44      4.000  +7.175919696417940e-05  1.9e-04  1.0e+00  
-    36    46      4.000  +7.170723123651528e-05  4.2e-04  2.5e-01  
-    37    47      4.000  +7.158287428953024e-05  7.8e-04  1.0e+00  
-    38    48      4.000  +7.144374877244074e-05  2.2e-04  1.0e+00  
-    39    49      4.000  +7.133466251468262e-05  1.7e-04  1.0e+00  
-    40    51      4.000  +7.131147537304108e-05  3.4e-04  2.7e-01  
-    41    52      4.000  +7.127028433699874e-05  3.7e-04  1.0e+00  
-    42    53      4.000  +7.117077758835362e-05  2.6e-04  1.0e+00  
-    43    54      4.000  +7.110140571775857e-05  9.8e-05  1.0e+00  
-    44    56      4.000  +7.108040834207843e-05  2.5e-04  2.2e-01  
-    45    57      4.000  +7.103394859713061e-05  3.8e-04  1.0e+00  
-    46    58      4.000  +7.098405566611185e-05  1.8e-05  1.0e+00  
-    47    59      4.000  +7.095277805502977e-05  2.3e-04  1.0e+00  
-    48    60      4.000  +7.093698079764311e-05  1.3e-04  1.0e+00  
-    49    62      4.000  +7.092411497593044e-05  1.6e-04  3.6e-01  
-    50    63      4.000  +7.090081388960589e-05  8.4e-05  1.0e+00  
-    51    64      4.000  +7.089092762586513e-05  7.5e-05  1.0e+00  
-    52    65      4.000  +7.088414527104555e-05  8.0e-05  1.0e+00  
-    53    67      4.000  +7.087881487192198e-05  7.0e-06  1.7e-01  
-    54    69      4.000  +7.087808649792271e-05  4.1e-05  4.0e-01  
-    55    70      8.000  +7.087756682229364e-05  3.7e-05  1.0e+00  
-    56    71      8.000  +7.087666490410433e-05  6.3e-06  1.0e+00  
-    57    72      8.000  +7.087654244772589e-05  9.0e-06  1.0e+00  
-    58    73      8.000  +7.087651609138998e-05  1.9e-06  1.0e+00  
-    59    74      8.000  +7.087651467883146e-05  1.2e-07  1.0e+00  
-    60    75      8.000  +7.087651467090616e-05  2.6e-09  1.0e+00  
-# op_vmlmb_next: FATOL test satisfied
-#
-#
-# Problem 9 (N=10): Penalty function II.
-# Method 0 (NDIR=10): Limited Memory BFGS (VMLM with NDIR=10)
-#
-# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
-# ---------------------------------------------------------------
-     0     1      0.000  +1.626527765659671e+02  5.0e+02  0.0e+00  
-     1     2      0.000  +4.478644776655588e+01  1.9e+02  3.6e-01  
-     2     3      0.000  +1.567407090737728e+01  8.6e+01  1.0e+00  
-     3     4      0.000  +4.595268667402950e+00  3.5e+01  1.0e+00  
-     4     5      0.000  +1.269158916418052e+00  1.5e+01  1.0e+00  
-     5     6      0.000  +3.110713197933571e-01  5.8e+00  9.7e-01  
-     6     7      0.000  +7.571688000474813e-02  2.3e+00  9.0e-01  
-     7     8      0.000  +2.213120188520761e-02  6.8e-01  9.4e-01  
-     8     9      0.000  +1.485561199109297e-02  2.3e-01  1.0e+00  
-     9    10      0.000  +1.306075025095904e-02  2.3e-01  1.0e+00  
-    10    11      0.000  +8.330391266572293e-03  2.9e-01  1.0e+00  
-    11    12      0.000  +2.118643374119330e-03  1.6e-01  5.4e-01  
-    12    13      0.000  +1.676859414703804e-03  2.0e-01  1.0e+00  
-    13    14      0.000  +6.085265554844259e-04  7.2e-02  1.0e+00  
-    14    15      0.000  +3.602520091513869e-04  2.9e-02  1.0e+00  
-    15    16      0.000  +3.000429994250958e-04  1.2e-02  1.0e+00  
-    16    17      0.000  +2.942768976757234e-04  1.9e-03  1.0e+00  
-    17    18      0.000  +2.941190006037160e-04  2.6e-03  1.0e+00  
-    18    19      0.000  +2.940276365124544e-04  4.2e-05  1.0e+00  
-    19    20      0.000  +2.940276143217213e-04  7.9e-06  1.0e+00  
-    20    22      0.000  +2.940276088743079e-04  1.3e-05  5.0e+00  
-    21    23      0.000  +2.940275674459129e-04  4.1e-05  1.0e+00  
-    22    24      0.000  +2.940274684490467e-04  8.4e-05  1.0e+00  
-    23    25      0.000  +2.940272019219013e-04  1.6e-04  1.0e+00  
-    24    26      0.000  +2.940265308678704e-04  2.7e-04  1.0e+00  
-    25    27      0.000  +2.940249257417753e-04  4.6e-04  1.0e+00  
-    26    28      0.000  +2.940218267746400e-04  7.0e-04  1.0e+00  
-    27    29      0.000  +2.940167114119969e-04  9.1e-04  1.0e+00  
-    28    30      0.000  +2.940057396280275e-04  1.0e-03  1.0e+00  
-    29    31      0.000  +2.939847652858170e-04  6.7e-04  1.0e+00  
-    30    32      0.000  +2.939671940695009e-04  3.5e-04  1.0e+00  
-    31    34      4.000  +2.939605724251989e-04  7.1e-04  3.6e-01  
-    32    35      4.000  +2.939456480560964e-04  1.3e-03  1.0e+00  
-    33    36      4.000  +2.939328151552932e-04  8.5e-04  1.0e+00  
-    34    37      4.000  +2.939141108236152e-04  2.0e-04  1.0e+00  
-    35    39      4.000  +2.939111211303367e-04  5.4e-04  3.7e-01  
-    36    40      4.000  +2.939053168820111e-04  6.0e-04  1.0e+00  
-    37    41      4.000  +2.938883629324550e-04  6.3e-04  1.0e+00  
-    38    42      4.000  +2.938747221912601e-04  2.5e-05  1.0e+00  
-    39    44      4.000  +2.938682139412850e-04  4.2e-04  2.0e-01  
-    40    46      4.000  +2.938639778872194e-04  7.4e-04  5.2e-01  
-    41    47      4.000  +2.938560543957402e-04  6.0e-04  1.0e+00  
-    42    48      4.000  +2.938431790575485e-04  1.9e-04  1.0e+00  
-    43    50      4.000  +2.938394172992321e-04  5.0e-04  1.9e-01  
-    44    51      4.000  +2.938332461245707e-04  9.1e-04  1.0e+00  
-    45    52      4.000  +2.938232087891656e-04  9.5e-05  1.0e+00  
-    46    53      4.000  +2.938162192572837e-04  3.1e-04  1.0e+00  
-    47    54      4.000  +2.938134286486824e-04  7.5e-04  1.0e+00  
-    48    55      4.000  +2.938046050490839e-04  1.2e-04  1.0e+00  
-    49    56      4.000  +2.937958615389975e-04  2.5e-04  1.0e+00  
-    50    58      4.000  +2.937915280165045e-04  5.2e-04  4.3e-01  
-    51    59      4.000  +2.937829339096076e-04  3.9e-04  1.0e+00  
-    52    60      4.000  +2.937787756979532e-04  1.2e-04  1.0e+00  
-    53    62      4.000  +2.937767478240379e-04  3.5e-04  2.1e-01  
-    54    63      4.000  +2.937740704182577e-04  5.8e-04  1.0e+00  
-    55    64      4.000  +2.937692673453995e-04  3.0e-04  1.0e+00  
-    56    66      4.000  +2.937653648012842e-04  4.2e-04  4.6e-01  
-    57    67      4.000  +2.937586070665360e-04  6.9e-04  1.0e+00  
-    58    69      4.000  +2.937544459124473e-04  8.5e-05  4.5e-01  
-    59    70      4.000  +2.937530885438273e-04  1.3e-04  1.0e+00  
-    60    72      4.000  +2.937500033638618e-04  3.4e-04  4.1e-01  
-    61    73      8.001  +2.937462650101101e-04  4.1e-04  1.0e+00  
-    62    74      8.001  +2.937436103075173e-04  7.7e-05  1.0e+00  
-    63    76      8.001  +2.937411292974525e-04  1.1e-04  4.1e-01  
-    64    78      8.001  +2.937396821963436e-04  3.1e-04  1.7e-01  
-    65    79      8.001  +2.937381391529797e-04  3.8e-04  1.0e+00  
-    66    80      8.001  +2.937365816728961e-04  1.4e-04  1.0e+00  
-    67    81      8.001  +2.937347185972254e-04  2.4e-04  1.0e+00  
-    68    82      8.001  +2.937318532989324e-04  3.7e-04  1.0e+00  
-    69    83      8.001  +2.937287934342775e-04  4.3e-05  1.0e+00  
-    70    85      8.001  +2.937271147643474e-04  2.1e-04  5.1e-01  
-    71    87      8.001  +2.937263798718626e-04  3.0e-04  5.2e-01  
-    72    88      8.001  +2.937246531357029e-04  2.2e-04  1.0e+00  
-    73    89      8.001  +2.937232048142877e-04  1.0e-04  1.0e+00  
-    74    91      8.001  +2.937223578268570e-04  2.2e-04  4.0e-01  
-    75    92      8.001  +2.937201426598879e-04  2.4e-04  1.0e+00  
-    76    93      8.001  +2.937187758592068e-04  1.8e-04  1.0e+00  
-    77    95      8.001  +2.937169668102822e-04  6.6e-05  5.0e-01  
-    78    97      8.001  +2.937167045913685e-04  1.6e-04  1.9e-01  
-    79    98     12.001  +2.937161308786513e-04  1.9e-04  1.0e+00  
-    80    99     12.001  +2.937145418783188e-04  2.1e-04  1.0e+00  
-    81   100     12.001  +2.937126830402479e-04  7.7e-05  1.0e+00  
-    82   102     12.001  +2.937119950899304e-04  1.9e-04  3.4e-01  
-    83   103     12.001  +2.937103197572409e-04  3.0e-04  1.0e+00  
-    84   104     12.001  +2.937081325220577e-04  1.3e-04  1.0e+00  
-    85   106     12.001  +2.937067731152529e-04  1.5e-05  4.2e-01  
-    86   109     12.001  +2.937061298844395e-04  9.7e-05  5.7e-02  
-    87   110     12.001  +2.937057792029250e-04  3.3e-04  1.0e+00  
-    88   111     12.001  +2.937048989862912e-04  1.6e-04  1.0e+00  
-    89   112     12.001  +2.937037498661225e-04  6.0e-05  1.0e+00  
-    90   113     12.001  +2.937020302605030e-04  2.2e-04  1.0e+00  
-    91   114     12.001  +2.937011876780409e-04  2.4e-04  1.0e+00  
-    92   116     12.001  +2.936994036462835e-04  2.7e-04  4.0e-01  
-    93   117     12.001  +2.936932742505855e-04  4.2e-05  1.0e+00  
-    94   119     12.001  +2.936925011344764e-04  2.5e-04  1.2e-01  
-    95   120     12.001  +2.936903903706649e-04  2.4e-04  1.0e+00  
-    96   121     12.001  +2.936864971751230e-04  1.6e-04  1.0e+00  
-    97   122     12.001  +2.936833519272741e-04  2.7e-05  1.0e+00  
-    98   125     12.001  +2.936823989527786e-04  1.3e-04  5.9e-02  
-    99   127     12.001  +2.936814369909003e-04  2.8e-04  5.1e-01  
-   100   128     12.001  +2.936801889576564e-04  2.5e-04  1.0e+00  
-   101   129     12.001  +2.936781670510260e-04  6.2e-06  1.0e+00  
-   102   131     12.001  +2.936773383070480e-04  1.3e-04  2.7e-01  
-   103   133     12.001  +2.936767971224333e-04  2.1e-04  4.8e-01  
-   104   134     12.001  +2.936757371420169e-04  2.0e-04  1.0e+00  
-   105   136     12.001  +2.936755119527722e-04  1.9e-04  1.7e-01  
-   106   137     12.001  +2.936739331071090e-04  6.8e-05  1.0e+00  
-   107   139     16.001  +2.936733609422002e-04  6.7e-05  2.4e-01  
-   108   141     16.001  +2.936731441199923e-04  1.5e-04  4.5e-01  
-   109   142     16.001  +2.936728734176120e-04  1.5e-04  1.0e+00  
-   110   143     16.001  +2.936727646558677e-04  1.2e-04  1.0e+00  
-   111   144     16.001  +2.936720719650833e-04  5.3e-05  1.0e+00  
-   112   146     16.001  +2.936718160655674e-04  5.7e-05  5.0e-01  
-   113   147     16.001  +2.936716335691947e-04  8.9e-05  1.0e+00  
-   114   148     16.001  +2.936713673939239e-04  1.0e-04  1.0e+00  
-   115   149     16.001  +2.936711604644687e-04  1.8e-06  1.0e+00  
-   116   150     16.001  +2.936710464585561e-04  7.8e-05  1.0e+00  
-   117   151     16.001  +2.936709734203265e-04  2.0e-05  1.0e+00  
-   118   152     16.001  +2.936709005854026e-04  2.0e-05  1.0e+00  
-   119   154     16.001  +2.936708447037076e-04  5.4e-05  3.7e-01  
-   120   155     16.001  +2.936707215906627e-04  5.5e-05  1.0e+00  
-   121   156     16.001  +2.936703043174316e-04  1.9e-05  1.0e+00  
-   122   158     16.001  +2.936700146863054e-04  9.4e-05  4.5e-01  
-   123   160     16.001  +2.936693047392297e-04  1.0e-04  5.0e-01  
-   124   161     16.001  +2.936685401469610e-04  1.2e-04  1.0e+00  
-   125   163     16.001  +2.936679641926337e-04  1.8e-05  1.9e-01  
-   126   165     16.001  +2.936674792095312e-04  1.1e-04  3.2e-01  
-   127   166     16.001  +2.936668316559686e-04  2.9e-04  1.0e+00  
-   128   167     16.001  +2.936662100391527e-04  5.3e-05  1.0e+00  
-   129   168     16.001  +2.936656178325533e-04  8.7e-05  1.0e+00  
-   130   170     16.001  +2.936651583330866e-04  1.5e-04  5.0e-01  
-   131   171     16.001  +2.936647742964451e-04  1.4e-04  1.0e+00  
-   132   173     16.001  +2.936646566758439e-04  1.2e-04  2.0e-01  
-   133   174     16.001  +2.936641713973722e-04  7.2e-05  1.0e+00  
-   134   176     16.001  +2.936637890170677e-04  1.2e-04  4.3e-01  
-   135   177     20.001  +2.936630264588969e-04  4.5e-05  1.0e+00  
-   136   179     20.001  +2.936628969739628e-04  1.1e-04  4.5e-01  
-   137   180     20.001  +2.936625655838410e-04  8.3e-05  1.0e+00  
-   138   181     20.001  +2.936624300065082e-04  2.9e-05  1.0e+00  
-   139   182     20.001  +2.936622977829990e-04  7.7e-05  1.0e+00  
-   140   183     20.001  +2.936622477588315e-04  1.0e-05  1.0e+00  
-   141   184     20.001  +2.936622031232782e-04  1.4e-05  1.0e+00  
-   142   185     20.001  +2.936621779293315e-04  4.8e-05  1.0e+00  
-   143   186     20.001  +2.936621567734476e-04  3.0e-06  1.0e+00  
-   144   187     20.001  +2.936621506624571e-04  2.4e-06  1.0e+00  
-   145   188     20.001  +2.936621474513797e-04  7.8e-06  1.0e+00  
-   146   189     20.001  +2.936621458663817e-04  2.2e-06  1.0e+00  
-   147   190     20.001  +2.936621447656716e-04  1.4e-06  1.0e+00  
-   148   191     20.001  +2.936621438322216e-04  3.6e-06  1.0e+00  
-   149   192     20.001  +2.936621407224748e-04  7.2e-06  1.0e+00  
-   150   193     20.001  +2.936621353581356e-04  8.7e-06  1.0e+00  
-   151   194     20.001  +2.936621275310319e-04  7.5e-06  1.0e+00  
-   152   195     20.001  +2.936621223335431e-04  6.9e-06  1.0e+00  
-   153   197     20.001  +2.936621209792176e-04  3.3e-06  2.2e-01  
-   154   198     20.001  +2.936621173468774e-04  7.0e-06  1.0e+00  
-   155   199     20.001  +2.936621156967350e-04  1.2e-05  1.0e+00  
-   156   200     20.001  +2.936621127659403e-04  1.1e-05  1.0e+00  
-   157   201     20.001  +2.936620879068670e-04  1.8e-05  1.0e+00  
-   158   202     20.001  +2.936620341924160e-04  1.5e-06  1.0e+00  
-   159   204     20.001  +2.936619396711716e-04  1.8e-05  4.0e-01  
-   160   206     20.001  +2.936618809583579e-04  4.6e-05  4.9e-01  
-   161   207     20.001  +2.936618437961445e-04  3.1e-05  1.0e+00  
-   162   208     20.001  +2.936618135595330e-04  1.7e-05  1.0e+00  
-   163   209     20.001  +2.936617994124585e-04  1.5e-05  1.0e+00  
-   164   211     20.001  +2.936617977401772e-04  8.7e-06  2.1e-01  
-   165   212     20.001  +2.936617949948577e-04  7.8e-06  1.0e+00  
-   166   213     24.002  +2.936617942029165e-04  4.8e-06  1.0e+00  
-   167   214     24.002  +2.936617936336488e-04  7.0e-07  1.0e+00  
-   168   215     24.002  +2.936617935577645e-04  6.6e-07  1.0e+00  
-# op_vmlmb_next: FATOL test satisfied
-#
-#
-# Problem 10 (N=2): Brown badly scaled function.
-# Method 0 (NDIR=2): Limited Memory BFGS (VMLM with NDIR=2)
-#
-# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
-# ---------------------------------------------------------------
-     0     1      0.000  +9.999980000030000e+11  2.0e+06  0.0e+00  
-     1    10      0.000  +8.405068809937695e+11  1.5e+10  8.7e+04  
-     2    12      0.000  +6.534530905604027e+11  2.6e+10  1.2e-01  
-     3    14      0.000  +5.259989045876316e+11  1.6e+11  2.1e-01  
-     4    16      0.000  +2.692902690480896e+11  8.1e+10  3.7e-01  
-     5    17      0.000  +1.587055937831890e+11  4.5e+11  1.8e-01  
-     6    18      0.000  +5.786251940191312e+10  3.2e+10  9.8e-01  
-     7    19      0.000  +2.014729184788555e+10  1.3e+11  1.0e+00  
-     8    20      0.000  +3.789073790387382e+09  6.5e+10  7.6e-01  
-     9    21      0.000  +7.582658601419518e+08  2.1e+10  4.9e-01  
-    10    22      0.000  +1.532406522092270e+08  1.3e+10  5.1e-01  
-    11    23      0.000  +8.382857608319093e+07  6.5e+09  3.7e-01  
-    12    24      0.000  +1.653294988314359e+07  2.9e+09  5.7e-01  
-    13    25      0.000  +3.263611062004277e+06  1.3e+09  5.5e-01  
-    14    26      0.000  +6.471465292335765e+05  6.7e+08  5.5e-01  
-    15    27      0.000  +2.722789943285238e+05  4.0e+08  5.0e-01  
-    16    28      0.000  +5.377870916293834e+04  1.7e+08  5.3e-01  
-    17    29      0.000  +1.062250565109277e+04  7.8e+07  5.6e-01  
-    18    30      0.000  +2.098255912542021e+03  3.5e+07  5.6e-01  
-    19    31      0.000  +4.150644198176832e+02  1.4e+07  5.6e-01  
-    20    32      0.000  +9.195149511769590e+01  1.2e+07  5.4e-01  
-    21    33      0.000  +7.394055311418897e+01  6.1e+06  1.4e-02  
-    22    34      0.000  +1.460552054965025e+01  2.7e+06  5.6e-01  
-    23    35      0.000  +2.885039269609231e+00  1.2e+06  5.6e-01  
-    24    36      0.000  +5.698841404349454e-01  5.4e+05  5.6e-01  
-    25    37      0.000  +1.125697148814101e-01  2.4e+05  5.6e-01  
-    26    38      0.000  +2.223674412281545e-02  1.1e+05  5.6e-01  
-    27    39      0.000  +4.419596330611485e-03  3.8e+04  5.6e-01  
-    28    40      0.000  +1.226680528641698e-03  5.3e+04  5.2e-01  
-    29    41      0.000  +3.552382989525306e-04  9.7e+03  4.1e-02  
-    30    42      0.000  +7.017052848565110e-05  4.3e+03  5.6e-01  
-    31    43      0.000  +1.386084529266547e-05  1.9e+03  5.6e-01  
-    32    44      0.000  +2.737944677494988e-06  8.5e+02  5.6e-01  
-    33    45      0.000  +5.408290745856043e-07  3.8e+02  5.6e-01  
-    34    46      0.000  +1.069191494379131e-07  1.5e+02  5.6e-01  
-    35    47      0.000  +3.099248909852002e-08  2.6e+02  5.4e-01  
-    36    48      0.000  +8.015714097213813e-09  5.7e+01  7.0e-02  
-    37    49      0.000  +1.583352621921838e-09  2.5e+01  5.6e-01  
-    38    50      0.000  +3.127629493167706e-10  1.1e+01  5.6e-01  
-    39    51      0.000  +6.178050732586073e-11  5.0e+00  5.6e-01  
-    40    52      0.000  +1.220343418206337e-11  2.2e+00  5.6e-01  
-    41    53      0.000  +2.410577466990187e-12  9.9e-01  5.6e-01  
-    42    54      0.000  +4.761860264644440e-13  4.5e-01  5.6e-01  
-    43    55      0.000  +9.529309271044640e-14  1.3e-01  5.5e-01  
-    44    56      0.000  +3.454718805039423e-14  3.0e-01  4.7e-01  
-    45    57      0.000  +7.000760536493319e-15  1.2e-01  2.0e-01  
-# op_vmlmb_next: FATOL test satisfied
-#
-#
-# Problem 11 (N=4): Brown and Dennis function.
-# Method 0 (NDIR=4): Limited Memory BFGS (VMLM with NDIR=4)
-#
-# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
-# ---------------------------------------------------------------
-     0     1      0.000  +7.926693336997432e+06  2.1e+06  0.0e+00  
-     1     2      0.000  +6.049349781006352e+06  1.6e+06  1.0e+00  
-     2     3      0.000  +2.838871733130934e+06  4.3e+05  1.0e+00  
-     3     4      0.000  +2.432298103636766e+06  2.6e+05  1.0e+00  
-     4     5      0.000  +2.100775303409475e+06  3.1e+05  1.0e+00  
-     5     6      0.000  +1.323784908907083e+06  3.3e+05  1.0e+00  
-     6     7      0.000  +5.656591397675695e+05  8.5e+04  1.0e+00  
-     7     8      4.000  +3.430980546283170e+05  4.1e+04  1.0e+00  
-     8     9      4.000  +1.878284295308689e+05  3.3e+04  1.0e+00  
-     9    11      4.000  +1.436998832262278e+05  7.0e+04  4.8e-01  
-    10    12      4.000  +9.738492091554010e+04  2.9e+04  1.0e+00  
-    11    13      4.000  +9.084457699916144e+04  9.6e+03  1.0e+00  
-    12    14      4.000  +8.891237239806094e+04  5.0e+03  1.0e+00  
-    13    15      4.000  +8.705530186352410e+04  6.8e+03  1.0e+00  
-    14    16      4.000  +8.608483951495643e+04  1.3e+03  1.0e+00  
-    15    17      4.000  +8.599075237276051e+04  7.5e+02  1.0e+00  
-    16    18      4.000  +8.590306517851379e+04  9.1e+02  1.0e+00  
-    17    20      4.000  +8.585776884341528e+04  1.4e+03  3.1e-01  
-    18    21      4.000  +8.582231434220298e+04  9.3e+01  1.0e+00  
-    19    22      4.000  +8.582220228898624e+04  4.8e+00  1.0e+00  
-    20    23      4.000  +8.582220180473091e+04  2.0e+00  1.0e+00  
-    21    24      4.000  +8.582220164639555e+04  3.4e-01  1.0e+00  
-    22    25      4.000  +8.582220163995650e+04  2.7e-01  1.0e+00  
-# op_vmlmb_next: FRTOL test satisfied
-#
-#
-# Problem 12 (N=3): Gulf research and development function.
-# Method 0 (NDIR=3): Limited Memory BFGS (VMLM with NDIR=3)
-#
-# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
-# ---------------------------------------------------------------
-     0     1      4.000  +1.211070582556949e+01  4.0e+01  0.0e+00  
-     1     3      4.000  +7.037432998984529e+00  1.5e+01  1.7e-01  
-     2     5      4.000  +6.621351881374275e+00  3.1e-01  5.0e-01  
-     3     6      8.000  +6.621101702040585e+00  2.3e-01  1.0e+00  
-     4     7      8.000  +6.620679188673091e+00  3.3e-01  1.0e+00  
-     5     8      8.000  +6.619037491331203e+00  8.0e-01  1.0e+00  
-     6     9      8.000  +6.615310780340258e+00  1.5e+00  1.0e+00  
-     7    10      8.000  +6.604547336243583e+00  2.7e+00  1.0e+00  
-     8    11      8.000  +6.573884980436160e+00  4.7e+00  1.0e+00  
-     9    12     12.001  +6.499049562962999e+00  7.4e+00  1.0e+00  
-    10    13     12.001  +6.336057520157562e+00  8.7e+00  1.0e+00  
-    11    14     12.001  +5.892999608485755e+00  2.4e+00  1.0e+00  
-    12    15     12.001  +5.662280493431998e+00  1.4e+01  1.0e+00  
-    13    16     12.001  +5.449061619118568e+00  3.9e+00  1.0e+00  
-    14    17     16.001  +5.234241685722618e+00  2.1e+00  1.0e+00  
-    15    18     16.001  +4.865169222646597e+00  1.8e+01  1.0e+00  
-    16    19     16.001  +4.453895249926380e+00  5.9e+00  1.0e+00  
-    17    20     16.001  +3.976830574245754e+00  2.9e+00  1.0e+00  
-    18    22     20.001  +1.779414184967219e-01  5.4e+00  1.7e+00  
-    19    24     20.001  +1.417710645204940e-01  3.9e+00  8.2e-02  
-    20    25     20.001  +2.557537679786676e-02  1.8e+00  7.2e-01  
-    21    26     20.001  +6.611690206271554e-03  6.2e-01  5.2e-01  
-    22    27     24.001  +4.564494341401721e-03  3.3e-02  1.0e+00  
-    23    28     24.001  +4.543334030131170e-03  1.0e-02  1.0e+00  
-    24    29     24.001  +4.539678138594905e-03  1.0e-02  1.0e+00  
-    25    31     24.001  +4.538933737699077e-03  2.0e-03  4.3e-02  
-    26    32     28.002  +4.538084042484109e-03  1.2e-03  1.0e+00  
-    27    37     32.002  +3.469460838544598e-03  3.0e-01  3.4e+02  
-    28    38     32.002  +2.928359037254009e-03  1.6e-01  1.0e+00  
-    29    40     32.002  +2.474054806017020e-03  2.4e-01  2.6e-01  
-    30    41     32.002  +1.565633067221580e-03  2.3e-01  1.0e+00  
-    31    43     36.002  +1.413550255660053e-03  1.2e-01  9.7e-02  
-    32    44     36.002  +9.024611061567671e-04  1.6e-02  1.0e+00  
-    33    46     36.002  +7.003267516821486e-04  1.1e-01  1.8e-01  
-    34    47     36.002  +5.735129820311213e-04  2.3e-01  1.0e+00  
-    35    48     40.002  +3.123330023579667e-04  4.1e-02  1.0e+00  
-    36    49     40.002  +1.947752299522285e-04  3.4e-02  1.0e+00  
-    37    51     40.002  +1.638242201908890e-04  8.3e-02  2.9e-01  
-    38    52     40.002  +1.048439465991671e-04  7.0e-02  1.0e+00  
-    39    53     44.003  +3.709259481404306e-05  2.7e-03  5.5e-01  
-    40    54     44.003  +1.091378850908817e-05  2.3e-02  8.2e-01  
-    41    55     44.003  +2.536658359037260e-06  1.5e-02  7.5e-01  
-    42    56     44.003  +5.748894725508491e-07  4.4e-03  6.2e-01  
-    43    57     44.003  +1.301070142934200e-07  3.2e-03  5.7e-01  
-    44    58     48.003  +8.850638573840128e-08  1.2e-03  1.6e-01  
-    45    59     48.003  +1.929576324643203e-08  4.9e-04  6.2e-01  
-    46    60     48.003  +5.601806973787550e-09  2.1e-04  7.4e-01  
-    47    61     48.003  +2.535490761789031e-09  3.4e-05  1.0e+00  
-    48    62     48.003  +1.322572045394975e-09  7.9e-05  1.0e+00  
-    49    63     52.003  +8.287306876272502e-10  1.5e-04  1.0e+00  
-    50    64     52.003  +3.454513513192700e-10  7.7e-05  1.0e+00  
-    51    65     52.003  +1.279735809853422e-10  6.8e-05  1.0e+00  
-    52    66     52.003  +2.590444871831076e-11  3.7e-05  5.6e-01  
-    53    67     52.003  +5.131187839211650e-12  1.8e-05  5.6e-01  
-    54    68     56.003  +1.096260941388581e-12  4.6e-06  5.5e-01  
-    55    69     56.003  +2.320936116341532e-13  3.7e-06  4.9e-01  
-    56    71     56.003  +1.720714526990411e-13  3.0e-07  3.5e-02  
-    57    72     56.003  +3.399938346550955e-14  1.3e-07  5.6e-01  
-    58    73     60.004  +6.724520326208138e-15  6.0e-08  5.6e-01  
-# op_vmlmb_next: FATOL test satisfied
-#
-#
-# Problem 13 (N=10): Trigonometric function.
-# Method 0 (NDIR=10): Limited Memory BFGS (VMLM with NDIR=10)
-#
-# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
-# ---------------------------------------------------------------
-     0     1      0.000  +7.075759466222607e-03  9.9e-02  0.0e+00  
-     1     2      0.000  +1.847318266210997e-03  2.8e-02  7.9e-02  
-     2     3      0.000  +1.337289272696683e-03  2.6e-02  1.0e+00  
-     3     4      0.000  +9.099932601024449e-04  2.0e-02  1.0e+00  
-     4     5      0.000  +6.559192696755177e-04  1.4e-02  1.0e+00  
-     5     6      0.000  +4.686579245332390e-04  1.5e-02  1.0e+00  
-     6     7      0.000  +2.915051473509156e-04  1.4e-02  1.0e+00  
-     7     8      0.000  +1.433277880070397e-04  1.7e-02  1.7e-01  
-     8     9      0.000  +7.147757750781793e-05  5.4e-03  5.9e-01  
-     9    10      0.000  +5.887928681982255e-05  2.8e-03  1.0e+00  
-    10    11      0.000  +5.263481793491030e-05  2.1e-03  1.0e+00  
-    11    12      0.000  +4.522784407286506e-05  1.8e-03  1.0e+00  
-    12    13      0.000  +4.260697310099406e-05  1.7e-03  1.0e+00  
-    13    14      0.000  +4.033897074809929e-05  1.2e-03  1.0e+00  
-    14    15      0.000  +3.597768894272814e-05  1.6e-03  1.0e+00  
-    15    17      0.000  +3.282850339569031e-05  1.9e-03  4.0e-01  
-    16    19      0.000  +3.030246929870708e-05  1.7e-03  4.7e-01  
-    17    20      0.000  +2.874543857699578e-05  1.2e-03  1.0e+00  
-    18    21      0.000  +2.839516499584868e-05  7.6e-04  1.0e+00  
-    19    22      0.000  +2.805891729461959e-05  3.7e-04  1.0e+00  
-    20    23      0.000  +2.801778561737049e-05  1.4e-04  1.0e+00  
-    21    24      0.000  +2.800096728737016e-05  1.1e-04  1.0e+00  
-    22    25      0.000  +2.796003401543012e-05  9.0e-05  1.0e+00  
-    23    26      0.000  +2.795364460348979e-05  8.1e-05  1.0e+00  
-    24    27      0.000  +2.795145020217185e-05  4.2e-05  1.0e+00  
-    25    28      0.000  +2.795057495098975e-05  4.8e-06  1.0e+00  
-    26    29      0.000  +2.795056448092877e-05  1.7e-06  1.0e+00  
-    27    30      0.000  +2.795056214675631e-05  9.8e-07  1.0e+00  
-    28    31      0.000  +2.795056136433344e-05  7.1e-07  1.0e+00  
-    29    32      0.000  +2.795056130890243e-05  5.4e-07  1.0e+00  
-    30    33      0.000  +2.795056121893572e-05  1.6e-08  1.0e+00  
-    31    34      0.000  +2.795056121878748e-05  3.9e-09  1.0e+00  
-# op_vmlmb_next: FRTOL test satisfied
-#
-#
-# Problem 14 (N=10): Extended Rosenbrock function.
-# Method 0 (NDIR=10): Limited Memory BFGS (VMLM with NDIR=10)
-#
-# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
-# ---------------------------------------------------------------
-     0     1      0.000  +1.210000000000000e+02  5.2e+02  0.0e+00  
-     1     2      0.000  +3.333875559382903e+01  1.7e+02  2.6e-01  
-     2     3      0.000  +2.099690543341773e+01  2.7e+01  1.0e+00  
-     3     4      0.000  +2.064737829082273e+01  4.4e+00  1.0e+00  
-     4     5      4.000  +2.062947719722462e+01  4.0e+00  1.0e+00  
-     5     6      4.000  +2.055056296009381e+01  8.2e+00  1.0e+00  
-     6     7      4.000  +2.036601960781752e+01  1.6e+01  1.0e+00  
-     7    11      4.000  +1.270403994373162e+01  2.9e+01  7.3e+00  
-     8    13      4.000  +1.266492082784074e+01  2.4e+01  1.3e-01  
-     9    15      4.000  +1.160881636531017e+01  2.0e+01  5.0e+00  
-    10    17      4.000  +1.014905429393288e+01  2.3e+01  5.2e-01  
-    11    18      4.000  +8.256388073653257e+00  2.2e+01  1.0e+00  
-    12    19      4.000  +6.515652375585378e+00  7.3e+00  1.0e+00  
-    13    21      4.000  +5.313683620850455e+00  6.8e+00  3.2e-01  
-    14    23      4.000  +5.001446956969033e+00  1.2e+01  2.3e-01  
-    15    24      4.000  +4.582646809321272e+00  1.3e+01  1.0e+00  
-    16    25      4.000  +3.603604585846324e+00  1.2e+01  1.0e+00  
-    17    26      4.000  +2.675900088307497e+00  2.9e+00  1.0e+00  
-    18    28      4.000  +2.296387307115140e+00  8.0e+00  3.1e-01  
-    19    29      4.000  +1.954912440237827e+00  1.7e+01  1.0e+00  
-    20    30      4.000  +1.378522055959003e+00  3.5e+00  1.0e+00  
-    21    31      4.000  +9.484804947450111e-01  8.2e+00  1.0e+00  
-    22    32      4.000  +6.713411428693927e-01  1.1e+01  1.0e+00  
-    23    33      4.000  +3.822925991805740e-01  5.5e+00  1.0e+00  
-    24    35      4.000  +2.191730723230072e-01  4.4e+00  4.7e-01  
-    25    36      4.000  +1.887020522506004e-01  1.1e+01  1.0e+00  
-    26    37      4.000  +1.125336324978479e-01  4.1e+00  1.0e+00  
-    27    38      4.000  +4.747278490703725e-02  1.8e+00  1.0e+00  
-    28    39      4.000  +2.164097573626416e-02  4.3e+00  1.0e+00  
-    29    40      4.000  +5.971361214373413e-03  8.7e-01  8.5e-01  
-    30    41      4.000  +1.514300265908568e-03  9.7e-01  7.8e-01  
-    31    42      4.000  +3.293711779148185e-04  3.4e-01  6.8e-01  
-    32    43      4.000  +6.882146001996125e-05  1.9e-01  6.4e-01  
-    33    44      4.000  +1.402734044478412e-05  7.0e-02  5.9e-01  
-    34    45      4.000  +2.827846239737803e-06  3.8e-02  5.7e-01  
-    35    46      4.000  +5.657367678388773e-07  1.4e-02  5.6e-01  
-    36    47      4.000  +1.126657341335922e-07  7.5e-03  5.5e-01  
-    37    48      4.000  +2.236521035181264e-08  2.9e-03  5.5e-01  
-    38    49      4.000  +4.430894630373603e-09  1.4e-03  5.5e-01  
-    39    50      4.000  +8.766285485792653e-10  6.0e-04  5.5e-01  
-    40    51      4.000  +1.751634425012838e-10  3.2e-04  5.5e-01  
-    41    52      4.000  +4.269613882266779e-11  3.6e-05  5.1e-01  
-    42    53      4.000  +8.563903609021838e-12  3.2e-05  5.0e-01  
-    43    55      4.000  +8.011613923905404e-12  2.8e-06  8.9e-03  
-    44    56      4.000  +1.582541862741472e-12  1.3e-06  5.6e-01  
-    45    57      4.000  +3.126009356473569e-13  5.6e-07  5.6e-01  
-    46    58      4.000  +6.174833942884158e-14  2.5e-07  5.6e-01  
-    47    59      4.000  +1.219720341626072e-14  1.1e-07  5.6e-01  
-# op_vmlmb_next: FATOL test satisfied
-#
-#
-# Problem 15 (N=12): Extended Powell function.
-# Method 0 (NDIR=12): Limited Memory BFGS (VMLM with NDIR=12)
-#
-# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
-# ---------------------------------------------------------------
-     0     1      0.000  +6.450000000000000e+02  7.9e+02  0.0e+00  
-     1     2      0.000  +2.126398786342238e+02  2.7e+02  9.0e-01  
-     2     3      0.000  +1.002223459053673e+02  1.4e+02  1.0e+00  
-     3     4      0.000  +4.372578508635030e+01  4.1e+01  1.0e+00  
-     4     5      0.000  +3.492275772532622e+01  3.1e+01  1.0e+00  
-     5     6      0.000  +2.371218382737346e+01  1.8e+01  1.0e+00  
-     6     7      0.000  +1.840511402191540e+01  1.5e+01  1.0e+00  
-     7     8      0.000  +5.385458666855794e+00  1.4e+01  1.0e+00  
-     8     9      0.000  +1.387075054330895e+00  5.4e+00  7.5e-01  
-     9    10      0.000  +4.338250784945510e-01  5.3e+00  1.0e+00  
-    10    11      4.000  +2.021610832573901e-01  3.7e+00  9.0e-01  
-    11    12      4.000  +8.424287893602030e-02  1.4e+00  1.0e+00  
-    12    13      4.000  +2.416572403566977e-02  6.8e-01  9.8e-01  
-    13    14      4.000  +9.539455035955798e-03  3.4e-01  1.0e+00  
-    14    15      4.000  +4.018557231556538e-03  1.2e-01  1.0e+00  
-    15    16      4.000  +2.359119570961944e-03  6.5e-02  1.0e+00  
-    16    17      4.000  +1.410815508220599e-03  9.5e-02  1.0e+00  
-    17    18      4.000  +6.664117905074039e-04  4.2e-02  1.0e+00  
-    18    19      4.000  +3.278858525866031e-04  2.2e-02  1.0e+00  
-    19    20      4.000  +1.301355227806065e-04  2.9e-02  1.0e+00  
-    20    21      4.000  +5.051539438473153e-05  4.1e-02  9.6e-01  
-    21    22      4.000  +1.933558681673291e-05  1.0e-02  1.0e+00  
-    22    23      4.000  +1.385853063374876e-05  1.9e-03  1.0e+00  
-    23    24      4.000  +1.325733364422288e-05  6.1e-03  1.0e+00  
-    24    25      4.000  +1.042889374455694e-05  1.5e-02  1.0e+00  
-    25    26      4.000  +5.019830828798650e-06  1.6e-02  1.0e+00  
-    26    28      4.000  +4.246579321514016e-06  2.7e-03  3.0e-02  
-    27    29      4.000  +1.264335976216658e-06  6.3e-04  1.0e+00  
-    28    30      4.000  +4.235261754358550e-07  9.7e-05  1.0e+00  
-    29    31      4.000  +1.358585713215724e-07  4.3e-05  1.0e+00  
-    30    32      4.000  +4.490260964925541e-08  3.5e-04  1.0e+00  
-    31    33      4.000  +1.435728201106651e-08  2.0e-04  1.0e+00  
-    32    34      4.000  +4.659469517411141e-09  1.9e-05  1.0e+00  
-    33    35      4.000  +3.197807521383443e-09  5.6e-04  9.5e-01  
-    34    36      4.000  +8.129560805831940e-10  1.5e-04  8.3e-01  
-    35    37      4.000  +2.639089711885569e-10  2.5e-05  1.0e+00  
-    36    38      4.000  +1.238902847308503e-10  3.8e-05  1.0e+00  
-    37    39      4.000  +3.693522871395788e-11  2.6e-05  1.0e+00  
-    38    40      4.000  +1.262527367596187e-11  1.7e-05  9.9e-01  
-    39    41      4.000  +4.121104687115640e-12  6.1e-06  8.0e-01  
-    40    42      4.000  +1.510459349123597e-12  1.4e-06  1.0e+00  
-    41    43      4.000  +5.074496790632610e-13  2.9e-07  1.0e+00  
-    42    44      4.000  +1.788275537869560e-13  1.2e-06  1.0e+00  
-    43    45      4.000  +5.912068107118078e-14  1.1e-06  1.0e+00  
-    44    46      4.000  +2.328813604908046e-14  3.7e-07  1.0e+00  
-# op_vmlmb_next: FATOL test satisfied
-#
-#
-# Problem 16 (N=2): Beale function.
-# Method 0 (NDIR=2): Limited Memory BFGS (VMLM with NDIR=2)
-#
-# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
-# ---------------------------------------------------------------
-     0     1      0.000  +1.420312500000000e+01  2.8e+01  0.0e+00  
-     1     2      0.000  +5.837321962114054e+00  9.0e+00  5.7e-01  
-     2     3      0.000  +3.543247835494009e+00  6.4e+00  1.0e+00  
-     3     4      0.000  +1.309302199158894e+00  2.7e+00  8.3e-01  
-     4     5      0.000  +8.188817853278094e-01  2.2e+00  1.0e+00  
-     5     6      0.000  +2.196594007426552e-01  9.2e-01  6.3e-01  
-     6     7      0.000  +5.892697837805581e-02  3.1e-01  9.0e-01  
-     7     8      0.000  +2.970214723480817e-02  1.1e+00  1.0e+00  
-     8     9      0.000  +7.437526283530453e-03  2.6e-01  6.0e-01  
-     9    10      0.000  +1.762547800263668e-03  5.2e-02  8.1e-01  
-    10    11      0.000  +3.806254994795292e-04  3.8e-02  7.5e-01  
-    11    13      0.000  +3.601037933927141e-04  1.8e-02  1.6e-02  
-    12    14      0.000  +7.333268718739307e-05  6.9e-03  6.4e-01  
-    13    15      0.000  +1.475615358477659e-05  3.5e-03  5.9e-01  
-    14    17      0.000  +1.418392844246689e-05  6.2e-03  1.9e-02  
-    15    18      0.000  +2.813440877948162e-06  2.6e-03  5.7e-01  
-    16    19      0.000  +5.569285817905507e-07  1.1e-03  5.6e-01  
-    17    20      0.000  +2.389901351508039e-07  3.9e-03  5.4e-01  
-    18    21      0.000  +4.719137850755555e-08  1.7e-03  2.6e-01  
-    19    22      0.000  +9.318027774792144e-09  7.6e-04  5.5e-01  
-    20    23      0.000  +1.840271195971691e-09  3.4e-04  5.6e-01  
-    21    24      0.000  +3.634816763291771e-10  1.5e-04  5.6e-01  
-    22    25      0.000  +7.179633292922795e-11  6.7e-05  5.6e-01  
-    23    26      0.000  +1.418177095511089e-11  3.0e-05  5.6e-01  
-    24    27      0.000  +2.801318130710862e-12  1.3e-05  5.6e-01  
-    25    28      0.000  +5.533450993015748e-13  5.9e-06  5.6e-01  
-    26    29      0.000  +1.093025883599040e-13  2.6e-06  5.6e-01  
-    27    30      0.000  +2.159062213224393e-14  1.2e-06  5.6e-01  
-    28    31      0.000  +4.264813197124873e-15  5.2e-07  5.6e-01  
-# op_vmlmb_next: FATOL test satisfied
-#
-#
-# Problem 17 (N=4): Wood function.
-# Method 0 (NDIR=4): Limited Memory BFGS (VMLM with NDIR=4)
-#
-# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
-# ---------------------------------------------------------------
-     0     1      0.000  +1.919200000000000e+04  1.6e+04  0.0e+00  
-     1     2      0.000  +7.427890102322217e+03  7.9e+03  1.0e+00  
-     2     3      0.000  +2.438439115206284e+03  3.3e+03  1.0e+00  
-     3     4      0.000  +8.528820526783926e+02  1.5e+03  1.0e+00  
-     4     5      4.000  +2.768216485716339e+02  6.1e+02  1.0e+00  
-     5     6      4.000  +8.327982562502508e+01  2.4e+02  1.0e+00  
-     6     7      4.000  +3.108746833161832e+01  7.1e+01  1.0e+00  
-     7     8      4.000  +2.380525415568198e+01  2.4e+01  1.0e+00  
-     8     9      4.000  +2.251089219753886e+01  2.6e+01  1.0e+00  
-     9    10      4.000  +1.855299679936986e+01  4.3e+01  1.0e+00  
-    10    12      4.000  +1.160837562431893e+01  4.5e+01  3.8e-01  
-    11    14      4.000  +8.137724551705739e+00  1.9e+01  1.1e-01  
-    12    16      4.000  +7.878690238212614e+00  1.2e+00  3.4e-01  
-    13    17      4.000  +7.877411159067403e+00  8.8e-01  1.0e+00  
-    14    18      4.000  +7.876880489799159e+00  4.4e-02  1.0e+00  
-    15    19      4.000  +7.876879132206481e+00  1.1e-02  1.0e+00  
-    16    20      4.000  +7.876878876272726e+00  4.8e-03  1.0e+00  
-    17    22      4.000  +7.876878490252988e+00  7.0e-03  5.0e+00  
-    18    23      4.000  +7.876876755266399e+00  1.9e-02  1.0e+00  
-    19    24      4.000  +7.876870816217647e+00  3.5e-02  1.0e+00  
-    20    26      4.000  +7.876865204511740e+00  1.3e-01  4.0e-01  
-    21    27      4.000  +7.876844389583843e+00  1.4e-01  1.0e+00  
-    22    28      4.000  +7.876583706646104e+00  3.2e-01  1.0e+00  
-    23    29      4.000  +7.876423129704414e+00  8.5e-01  1.0e+00  
-    24    30      4.000  +7.875060453829682e+00  1.6e+00  1.0e+00  
-    25    31      4.000  +7.872131119796703e+00  3.0e+00  1.0e+00  
-    26    33      4.000  +7.869170139094837e+00  3.3e+00  2.0e-01  
-    27    35      4.000  +7.864052623536911e+00  3.4e+00  3.6e-01  
-    28    36      4.000  +7.855001610484345e+00  2.9e+00  1.0e+00  
-    29    37      4.000  +7.849625111708809e+00  4.1e+00  1.0e+00  
-    30    38      4.000  +7.839170804391435e+00  3.0e+00  1.0e+00  
-    31    39      4.000  +7.824568101062441e+00  2.8e+00  1.0e+00  
-    32    41      4.000  +7.813646935560872e+00  4.1e+00  2.4e-01  
-    33    43      4.000  +7.789494013946371e+00  5.7e+00  2.3e-01  
-    34    44      4.000  +7.722263757787657e+00  7.4e+00  1.0e+00  
-    35    46      4.000  +7.693814493002182e+00  1.2e+01  1.6e-01  
-    36    47      4.000  +7.541393104832614e+00  4.3e+00  1.0e+00  
-    37    48      4.000  +7.434111139448211e+00  5.1e+00  1.0e+00  
-    38    50      4.000  +7.420136912558213e+00  6.7e+00  9.8e-02  
-    39    51      4.000  +7.323032564057124e+00  6.2e+00  1.0e+00  
-    40    53      4.000  +7.216964400808464e+00  1.4e+01  2.7e-01  
-    41    54      4.000  +6.911125334280928e+00  1.1e+01  1.0e+00  
-    42    55      4.000  +6.512566568432114e+00  4.0e+01  1.0e+00  
-    43    56      4.000  +5.720835039047132e+00  7.6e+00  1.0e+00  
-    44    57      4.000  +5.672818396981924e+00  1.6e+01  1.0e+00  
-    45    59      4.000  +5.202278173076890e+00  1.9e+01  2.2e-01  
-    46    62      4.000  +5.061832019786340e+00  2.0e+01  6.4e-02  
-    47    63      4.000  +4.875017742525158e+00  2.0e+01  1.0e+00  
-    48    64      4.000  +4.616628933510177e+00  1.3e+01  1.0e+00  
-    49    65      4.000  +4.405532645759691e+00  1.7e+01  1.0e+00  
-    50    66      4.000  +3.915460121738099e+00  1.8e+01  1.0e+00  
-    51    67      4.000  +3.571117225615803e+00  1.8e+01  1.0e+00  
-    52    69      4.000  +3.342807282681064e+00  6.6e+00  3.0e-01  
-    53    70      4.000  +3.169420327958804e+00  8.2e+00  1.0e+00  
-    54    71      4.000  +3.083714115933907e+00  7.5e+00  1.0e+00  
-    55    72      4.000  +2.842571930210177e+00  6.2e+00  1.0e+00  
-    56    73      4.000  +2.407959483920122e+00  1.8e+01  1.0e+00  
-    57    75      4.000  +2.310997032934655e+00  1.5e+01  2.4e-01  
-    58    77      4.000  +1.874303903557421e+00  9.1e+00  3.9e-01  
-    59    79      4.000  +1.747352207978819e+00  4.5e+00  4.3e-01  
-    60    80      4.000  +1.616702123440979e+00  6.3e+00  1.0e+00  
-    61    81      4.000  +1.551453286562933e+00  1.7e+01  1.0e+00  
-    62    82      4.000  +1.445642573680781e+00  1.1e+01  1.0e+00  
-    63    84      4.000  +1.291548725488739e+00  7.3e+00  5.2e-01  
-    64    85      4.000  +1.146267070283055e+00  1.3e+01  1.0e+00  
-    65    86      4.000  +8.736037619411690e-01  6.2e+00  1.0e+00  
-    66    88      4.000  +7.587510486192135e-01  6.2e+00  4.3e-01  
-    67    89      4.000  +6.272474461111625e-01  2.7e+00  1.0e+00  
-    68    91      4.000  +6.154503738538099e-01  2.9e+00  3.6e-01  
-    69    92      4.000  +6.025386870053662e-01  2.3e+00  1.0e+00  
-    70    93      4.000  +5.569297053304927e-01  2.8e+00  1.0e+00  
-    71    94      4.000  +4.939103897295918e-01  6.0e+00  1.0e+00  
-    72    95      4.000  +3.289194049732398e-01  5.1e+00  1.0e+00  
-    73    97      4.000  +2.689387273180264e-01  8.0e+00  2.0e-01  
-    74    98      4.000  +1.220581321270582e-01  8.6e+00  8.6e-01  
-    75    99      8.001  +6.663309577533551e-02  8.9e+00  4.3e-01  
-    76   100      8.001  +3.637323340490146e-02  1.1e+00  1.0e+00  
-    77   101      8.001  +2.712208655572348e-02  1.5e+00  1.0e+00  
-    78   102      8.001  +1.116522496174569e-02  3.7e+00  7.9e-01  
-    79   103      8.001  +3.900482707955074e-03  2.0e+00  4.8e-01  
-    80   104      8.001  +1.004136803886999e-03  6.9e-01  9.3e-01  
-    81   105      8.001  +2.226638008945489e-04  3.5e-01  7.3e-01  
-    82   106      8.001  +5.106876720624694e-05  7.5e-02  6.0e-01  
-    83   107      8.001  +1.071982128302296e-05  2.6e-02  6.0e-01  
-    84   108      8.001  +4.441881481174797e-06  6.4e-02  5.2e-01  
-    85   109      8.001  +9.368857777996710e-07  2.8e-02  4.1e-01  
-    86   110      8.001  +1.923710022206024e-07  1.3e-02  5.7e-01  
-    87   111      8.001  +4.207762167723878e-08  5.8e-03  6.1e-01  
-    88   112      8.001  +1.181228459744630e-08  2.3e-03  7.0e-01  
-    89   113      8.001  +6.562748229821411e-09  8.5e-04  1.0e+00  
-    90   114      8.001  +5.554256689700290e-09  7.8e-04  1.0e+00  
-    91   115      8.001  +3.484975951958208e-09  1.1e-03  1.0e+00  
-    92   116      8.001  +8.872950699360685e-10  9.9e-04  9.6e-01  
-    93   117      8.001  +1.837384368516011e-10  3.9e-04  4.7e-01  
-    94   118      8.001  +3.863280276302230e-11  1.8e-04  5.7e-01  
-    95   119      8.001  +9.862952976040704e-12  8.1e-05  6.1e-01  
-    96   120      8.001  +3.643236162973744e-12  3.2e-05  6.8e-01  
-    97   121      8.001  +2.484476074089160e-12  8.5e-06  1.0e+00  
-    98   122      8.001  +2.082579068068493e-12  1.4e-05  1.0e+00  
-    99   123      8.001  +7.291374932118642e-13  2.4e-05  1.0e+00  
-   100   124      8.001  +3.315075555077437e-13  9.7e-06  5.1e-01  
-   101   125      8.001  +7.622499994371465e-14  7.5e-06  7.5e-01  
-   102   126      8.001  +4.174888567594510e-14  6.3e-06  1.5e-01  
-# op_vmlmb_next: FATOL test satisfied
-#
-#
-# Problem 18 (N=25): Chebyquad function.
-# Method 0 (NDIR=25): Limited Memory BFGS (VMLM with NDIR=25)
-#
-# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
-# ---------------------------------------------------------------
-     0     1      0.000  +1.248791904880204e-02  6.5e-01  0.0e+00  
-     1     3      4.000  +1.049431287352932e-02  5.8e-01  5.7e-03  
-     2     4      8.000  +9.609006926829304e-03  2.8e-01  1.0e+00  
-     3     5      8.000  +9.337302507733160e-03  1.3e-01  1.0e+00  
-     4     6     12.000  +9.170073298832805e-03  1.2e-01  1.0e+00  
-     5     7     12.000  +8.991254191516106e-03  1.1e-01  1.0e+00  
-     6     8     16.001  +8.846941541915740e-03  7.7e-02  1.0e+00  
-     7     9     16.001  +8.801166872704557e-03  9.3e-02  1.0e+00  
-     8    10     20.001  +8.756693487815655e-03  4.5e-02  1.0e+00  
-     9    11     20.001  +8.739152782891746e-03  3.3e-02  1.0e+00  
-    10    12     20.001  +8.714552799449523e-03  3.1e-02  1.0e+00  
-    11    13     24.001  +8.692796444352035e-03  3.2e-02  1.0e+00  
-    12    14     24.001  +8.667777829095081e-03  2.6e-02  1.0e+00  
-    13    15     28.001  +8.654662603946484e-03  4.0e-02  1.0e+00  
-    14    16     28.001  +8.643693770592379e-03  1.7e-02  1.0e+00  
-    15    17     32.002  +8.637815829617758e-03  1.5e-02  1.0e+00  
-    16    18     32.002  +8.633008188826369e-03  1.8e-02  1.0e+00  
-    17    19     36.002  +8.620907535587131e-03  4.2e-02  1.0e+00  
-    18    21     40.002  +8.614998716828056e-03  2.6e-02  4.1e-01  
-    19    22     40.002  +8.610412652519038e-03  1.1e-02  1.0e+00  
-    20    23     40.002  +8.608556239357218e-03  7.1e-03  1.0e+00  
-    21    24     44.002  +8.607605459630636e-03  6.9e-03  1.0e+00  
-    22    25     44.002  +8.602572986472511e-03  1.3e-02  1.0e+00  
-    23    26     48.003  +8.590054454806751e-03  2.8e-02  1.0e+00  
-    24    27     48.003  +8.564183633311328e-03  7.5e-02  1.0e+00  
-    25    28     52.003  +8.532458576242349e-03  9.3e-02  1.0e+00  
-    26    29     52.003  +8.493452768781006e-03  7.0e-02  1.0e+00  
-    27    30     56.003  +8.474787010915145e-03  6.7e-02  1.0e+00  
-    28    31     56.003  +8.458773326847066e-03  4.5e-02  1.0e+00  
-    29    32     60.003  +8.457999627479094e-03  4.1e-02  1.0e+00  
-    30    33     60.003  +8.449532870934518e-03  2.2e-02  1.0e+00  
-    31    34     64.004  +8.447840743807028e-03  2.8e-02  1.0e+00  
-    32    35     64.004  +8.445692845529283e-03  1.1e-02  1.0e+00  
-    33    36     68.004  +8.444165323560711e-03  9.6e-03  1.0e+00  
-    34    37     68.004  +8.443207951672584e-03  1.0e-02  1.0e+00  
-    35    38     68.004  +8.441994339191562e-03  2.0e-02  1.0e+00  
-    36    39     72.004  +8.439832619160158e-03  1.4e-02  1.0e+00  
-    37    40     72.004  +8.437231750924349e-03  1.1e-02  1.0e+00  
-    38    41     76.004  +8.433302937380200e-03  1.2e-02  1.0e+00  
-    39    43     80.005  +8.432489353555114e-03  9.1e-03  3.7e-01  
-    40    44     80.005  +8.432123509481731e-03  4.7e-03  1.0e+00  
-    41    45     84.005  +8.432035588096611e-03  2.3e-03  1.0e+00  
-    42    46     84.005  +8.431999120538823e-03  1.5e-03  1.0e+00  
-    43    47     88.005  +8.431966728031759e-03  1.2e-03  1.0e+00  
-    44    48     88.005  +8.431924365562692e-03  1.6e-03  1.0e+00  
-    45    50     92.005  +8.431891947171172e-03  3.1e-03  4.2e-01  
-    46    51     92.005  +8.431831354671862e-03  2.3e-03  1.0e+00  
-    47    52     96.006  +8.431668636095641e-03  3.3e-03  1.0e+00  
-    48    53     96.006  +8.431437099609954e-03  5.4e-03  1.0e+00  
-    49    54    100.006  +8.431000851063426e-03  5.3e-03  1.0e+00  
-    50    55    100.006  +8.430678732503366e-03  1.6e-02  1.0e+00  
-    51    56    104.006  +8.429876682496911e-03  7.2e-03  1.0e+00  
-    52    57    104.006  +8.428910142166941e-03  6.9e-03  1.0e+00  
-    53    58    108.006  +8.428161202850929e-03  9.8e-03  1.0e+00  
-    54    59    108.006  +8.427149557235504e-03  1.2e-02  1.0e+00  
-    55    60    112.007  +8.426884594329293e-03  1.0e-02  1.0e+00  
-    56    62    116.007  +8.425929204745749e-03  9.6e-03  4.4e-01  
-    57    63    116.007  +8.425078821369147e-03  6.2e-03  1.0e+00  
-    58    65    120.007  +8.424962146289759e-03  6.7e-03  2.7e-01  
-    59    66    124.007  +8.424706166580516e-03  6.3e-03  1.0e+00  
-    60    67    124.007  +8.424483854096705e-03  4.1e-03  1.0e+00  
-    61    68    124.007  +8.424346241895737e-03  2.7e-03  1.0e+00  
-    62    69    128.008  +8.424196521199122e-03  4.1e-03  1.0e+00  
-    63    70    128.008  +8.423947181728741e-03  3.3e-03  1.0e+00  
-    64    72    132.008  +8.423857716916193e-03  3.9e-03  4.8e-01  
-    65    73    136.008  +8.423772029357686e-03  1.3e-03  1.0e+00  
-    66    74    136.008  +8.423740800437915e-03  1.7e-03  1.0e+00  
-    67    75    140.008  +8.423721211048594e-03  2.0e-03  1.0e+00  
-    68    76    140.008  +8.423707802726785e-03  6.8e-04  1.0e+00  
-    69    77    144.009  +8.423705094214971e-03  2.9e-04  1.0e+00  
-    70    78    144.009  +8.423704078604773e-03  2.7e-04  1.0e+00  
-    71    79    148.009  +8.423703211145708e-03  2.3e-04  1.0e+00  
-    72    80    148.009  +8.423702337458264e-03  1.9e-04  1.0e+00  
-    73    81    148.009  +8.423702265665172e-03  4.1e-04  1.0e+00  
-    74    82    152.009  +8.423701658411723e-03  1.6e-04  1.0e+00  
-    75    83    152.009  +8.423701425312869e-03  1.7e-04  1.0e+00  
-    76    84    156.009  +8.423700442240544e-03  3.0e-04  1.0e+00  
-    77    85    156.009  +8.423698956540247e-03  4.1e-04  1.0e+00  
-    78    86    160.010  +8.423696594839578e-03  6.2e-04  1.0e+00  
-    79    87    160.010  +8.423693749784765e-03  5.9e-04  1.0e+00  
-    80    88    164.010  +8.423691373336607e-03  3.1e-04  1.0e+00  
-    81    89    164.010  +8.423689724709164e-03  1.6e-04  1.0e+00  
-    82    91    168.010  +8.423689561087022e-03  2.0e-04  4.0e-01  
-    83    92    172.010  +8.423689406081498e-03  1.2e-04  1.0e+00  
-    84    93    172.010  +8.423689325881282e-03  3.0e-05  1.0e+00  
-    85    94    172.010  +8.423689316751977e-03  2.9e-05  1.0e+00  
-    86    95    176.011  +8.423689305145607e-03  2.4e-05  1.0e+00  
-    87    96    176.011  +8.423689289622477e-03  2.8e-05  1.0e+00  
-    88    97    180.011  +8.423689257662553e-03  3.4e-05  1.0e+00  
-    89    98    180.011  +8.423689218774710e-03  3.7e-05  1.0e+00  
-    90    99    184.011  +8.423689151546083e-03  7.2e-05  1.0e+00  
-    91   100    184.011  +8.423689072351309e-03  6.8e-05  1.0e+00  
-    92   101    188.011  +8.423688995763033e-03  6.2e-05  1.0e+00  
-    93   102    188.011  +8.423688928736774e-03  7.4e-05  1.0e+00  
-    94   103    192.012  +8.423688881914616e-03  4.9e-05  1.0e+00  
-    95   104    192.012  +8.423688840104407e-03  4.0e-05  1.0e+00  
-    96   106    196.012  +8.423688821486053e-03  7.3e-05  4.4e-01  
-    97   107    196.012  +8.423688798581467e-03  3.0e-05  1.0e+00  
-    98   108    200.012  +8.423688787360375e-03  1.9e-05  1.0e+00  
-    99   109    200.012  +8.423688776709048e-03  1.3e-05  1.0e+00  
-   100   111    204.012  +8.423688774926129e-03  2.1e-05  4.6e-01  
-   101   112    208.013  +8.423688773115171e-03  7.6e-06  1.0e+00  
-   102   113    208.013  +8.423688772436546e-03  6.9e-06  1.0e+00  
-   103   114    212.013  +8.423688771155470e-03  1.1e-05  1.0e+00  
-   104   115    212.013  +8.423688769387254e-03  1.4e-05  1.0e+00  
-   105   116    216.013  +8.423688766337282e-03  1.4e-05  1.0e+00  
-   106   118    220.013  +8.423688765114607e-03  1.5e-05  2.8e-01  
-   107   119    220.013  +8.423688763449228e-03  6.4e-06  1.0e+00  
-   108   120    220.013  +8.423688762532369e-03  7.1e-06  1.0e+00  
-   109   121    224.014  +8.423688761837404e-03  9.9e-06  1.0e+00  
-   110   122    224.014  +8.423688760262529e-03  1.3e-05  1.0e+00  
-   111   123    228.014  +8.423688759272251e-03  3.6e-05  1.0e+00  
-   112   124    228.014  +8.423688756130365e-03  1.7e-05  1.0e+00  
-   113   125    232.014  +8.423688753374270e-03  9.2e-06  1.0e+00  
-   114   126    232.014  +8.423688751373724e-03  1.1e-05  1.0e+00  
-   115   127    236.014  +8.423688750014176e-03  7.3e-06  1.0e+00  
-   116   128    236.014  +8.423688749391211e-03  7.7e-06  1.0e+00  
-   117   129    240.015  +8.423688748986261e-03  5.8e-06  1.0e+00  
-# op_vmlmb_next: FRTOL test satisfied
-#
diff -Nru yorick-optimpack-1.3.2+dfsg/yorick/optimpack.c yorick-optimpack-1.3.2+dfsg+1.4.0/yorick/optimpack.c
--- yorick-optimpack-1.3.2+dfsg/yorick/optimpack.c	2007-07-05 09:38:20.000000000 +0000
+++ yorick-optimpack-1.3.2+dfsg+1.4.0/yorick/optimpack.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,125 +0,0 @@
-/*
- * optimpack.c --
- *
- *	Implementation of Yorick wrapper for OptimPack.
- *
- *-----------------------------------------------------------------------------
- *
- *	Copyright (C) 2003-2007 Eric Thiébaut.
- *
- *	This file is part of OptimPack.
- *
- *	OptimPack is free software; you can redistribute it and/or
- *	modify it under the terms of the GNU General Public License
- *	version 2 as published by the Free Software Foundation.
- *
- *	OptimPack is distributed in the hope that it will be useful,
- *	but WITHOUT ANY WARRANTY; without even the implied warranty of
- *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *	GNU General Public License for more details.
- *
- *	You should have received a copy of the GNU General Public
- *	License along with OptimPack (file "COPYING" in the top source
- *	directory); if not, write to the Free Software Foundation,
- *	Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *-----------------------------------------------------------------------------
- *
- * History:
- *	$Id$
- *	$Log$
- *-----------------------------------------------------------------------------
- */
-
-void Y_op_vmlmb_first(int argc)
-{
-  Dimension *dims;
-  Symbol *argv = sp - argc + 1;
-  long n, m;
-  double fmin, fatol, frtol, sftol, sgtol, sxtol;
-  char *csave;
-  long *isave;
-  double *dsave;
-  long ncsave, nisave, ndsave;
-  long task;
-  if (argc != 11) YError("op_vmlmb_first takes exactly 11 arguments");
-  n = YGetInteger(&argv[0]);
-  m = YGetInteger(&argv[1]);
-  fmin = YGetReal(&argv[2]);
-  fatol = YGetReal(&argv[3]);
-  frtol = YGetReal(&argv[4]);
-  sftol = YGetReal(&argv[5]);
-  sgtol = YGetReal(&argv[6]);
-  sxtol = YGetReal(&argv[7]);
-  csave = get_char_array(&argv[8], 0, &ncsave);
-  isave = get_long_array(&argv[9], 0, &nisave);
-  dsave = get_double_array(&argv[10], 0, &ndsave);
-  if (ncsave < OP_MSG_SIZE) YError("too few elements for CSAVE");
-  if (nisave < ???) YError("too few elements for ISAVE");
-  if (ndsave < ???) YError("too few elements for DSAVE");
-  task = op_vmlmb_first(n, m, fmin, fatol, frtol, sftol, sgtol, sxtol,
-			csave, isave, dsave);
-  if (task != OP_TASK_FG) YError(csave);
-  PushLongValue(task);
-}
-
-static void parse_ws(Symbol *s,
-		     char   **csave_ptr, long ncsave,
-		     long   **isave_ptr, long nisave,
-		     double **dsave_ptr, long ndsave)
-{
-  void *ptr;
-  Operand op;
-  if (!s->ops) YError("unexpected keyword argument");
-  s->ops->FormOperand(s, &op);
-  if (op.ops->typeID!=T_POINTER || op.type.number != 3)
-    YError("expecting array of 3 pointers");
-  ptr = *(void **)op.value;
-
-}
-
-#define IS_REF(S)       ((S)->ops == &referenceSym)
-#define DEREF_SYMBOL(S) (IS_REF(S) ? &globTab[(S)->index] : (S))
-
-static void unexpected_keyword_argument(const char *name)
-{
-  if (name && strlen(name) < 30) {
-    char msg[80];
-    strcpy(msg, "unexpected keyword argument for ");
-    strcat(msg, name);
-    YError(msg);
-  } else {
-    YError("unexpected keyword argument");
-  }
-}
-
-static char *get_char_array(const char *name, Symbol *s,
-			    int nil_ok, long *number);
-static char *get_char_array(const char *name, Symbol *s,
-			    int nil_ok, long *number)
-{
-  Operand op;
-  if (! s->ops) YError("unexpected keyword argument");
-  s->ops->FormOperand(s, &op);
-  if (op.ops->typeID == T_CHAR) {
-    if (nil_ok && ) {
-      if (number) *number = 0;
-      return NULL;
-    }
-    YError("expecting character array argument");
-  }
-  if (number) *number = op.type.number;
-  return ;
-  if (op.ops->typeID!=T_POINTER || op.type.dims)
-    YError("expecting scalar pointer argument");
-  return *(void **)op.value;
-}
-
-/*---------------------------------------------------------------------------*
- * Local Variables:                                                          *
- * mode: C                                                                   *
- * tab-width: 8                                                              *
- * fill-column: 75                                                           *
- * coding: latin-1                                                           *
- * End:                                                                      *
- *---------------------------------------------------------------------------*/
diff -Nru yorick-optimpack-1.3.2+dfsg/yorick/optimpacklegacy.i yorick-optimpack-1.3.2+dfsg+1.4.0/yorick/optimpacklegacy.i
--- yorick-optimpack-1.3.2+dfsg/yorick/optimpacklegacy.i	1970-01-01 00:00:00.000000000 +0000
+++ yorick-optimpack-1.3.2+dfsg+1.4.0/yorick/optimpacklegacy.i	2017-01-10 22:16:57.000000000 +0000
@@ -0,0 +1,430 @@
+/*
+ * optimpacklegacy.i --
+ *
+ * Main startup file for OptimPackLegacy extension of Yorick.
+ *
+ *-----------------------------------------------------------------------------
+ *
+ * This file is part of OptimPack .
+ *
+ * Copyright (c) 2003-2009, 2016 Éric Thiébaut.
+ *
+ * OptimPack is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * OptimPack is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * OptimPack (file "LICENSE" in the top source directory); if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307 USA
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+if (is_func(plug_in)) plug_in, "optimpacklegacy";
+
+local OPL_TASK_START, OPL_TASK_FG, OPL_TASK_FREEVARS, OPL_TASK_NEWX;
+local OPL_TASK_CONV, OPL_TASK_WARN, OPL_TASK_ERROR;
+extern opl_vmlmb_create;
+/* DOCUMENT ws = opl_vmlmb_create(dims, mem, key1=val1, key2=val2, ...);
+
+     Create a new workspace for the VMLMB algorithm.  DIMS gives the dimension
+     list of the variables (like `dimsof`) and MEM is the number of previous
+     steps to memorize.
+
+     The workspace WS can be used to retrieve the following attributes:
+
+       ws.dims ............. Dimension list of the variables.
+       ws.size ............. Size of the problem (number of variables).
+       ws.mem .............. Number of previous steps to memorize.
+       ws.task ............. Current pending task.
+       ws.evaluations ...... Number of function calls.
+       ws.iterations ....... Number of iterations.
+       ws.restarts ......... Number of algorithm restarts.
+       ws.step ............. Lenght of the current or last step.
+       ws.status ........... Current status value.
+       ws.reason ........... Explanatory message about current status/task.
+       ws.gnorm ............ Euclidean norm of the (projected) gradient at the
+                             last successful step.
+       ws.fmin ............. Strict lower bound for the function (NaN if not
+                             set).
+       ws.fatol ............ Absolute function tolerance for the convergence.
+       ws.frtol ............ Relative function tolerance for the convergence.
+       ws.sftol ............ Tolerance for the sufficient decrease condition.
+       ws.sgtol ............ Tolerance for the curvature condition.
+       ws.sxtol ............ Relative tolerance for an acceptable step.
+       ws.delta ............ Relative size of a small step.
+       ws.epsilon .......... Threshold for the sufficient descent condition.
+
+     Attributes FMIN, FATOL, FRTOL, SFTOL, SGTOL, SXTOL, DELTA and EPSILON are
+     configurable via keywords when calling `opl_vmlmb_create`, they may be
+     configure later with `opl_vmlmb_configure`.  The other attributes are
+     read-only.
+
+     It not recommended to have MEM larger than the number of variables and it
+     is often the case that a modest value for MEM, say MEM=5, is as efficient
+     as larger values.  As you may expect, MEM has an incidence on the size of
+     the neessary memory which is about `(2*m*(n + 1) + n)*sizeof(double)`
+     where `n` is the number of variables and `m` is MEM.  Allocated memory is
+     automatically released when the returned workspace is no longer in use.
+
+     The pending task can take one of the following values:
+
+       OPL_TASK_START ...... Start line search.
+       OPL_TASK_FG ......... Caller has to compute function and gradient.
+       OPL_TASK_FREEVARS ... Caller has to determine the free variables.
+       OPL_TASK_NEWX ....... New variables available for inspection.
+       OPL_TASK_CONV ....... Search has converged.
+       OPL_TASK_WARN ....... Search aborted with warning.
+       OPL_TASK_ERROR ...... Search aborted with error.
+
+
+   SEE ALSO opl_vmlmb_configure, opl_vmlmb_iterate, dimsof.
+*/
+
+extern opl_vmlmb_configure;
+/* DOCUMENT opl_vmlmb_configure, ws, key1=val1, key2=val2, ...;
+
+     Configure VMLMB workspace WS.  Parameters are provided as keyword-value
+     pairs.  See `opl_vmlmb_create` for a list of configurable settings. When
+     called as a function, WS is returned.
+
+   SEE ALSO opl_vmlmb_create
+*/
+
+extern opl_vmlmb_iterate;
+/* DOCUMENT task = opl_vmlmb_iterate(ws, x, f, g);
+         or task = opl_vmlmb_iterate(ws, x, f, g, isfree);
+         or task = opl_vmlmb_iterate(ws, x, f, g, isfree, h);
+
+     Perform one step of the VMLMB algorithm.  WS is VMLMB workspace, X gives
+     the variables, F and G are the function value and gradient at X.  ISFREE
+     is an optional array which indicates which variables are free to vary.
+     H is an optional array which provides a diagonal preconditioner.  The
+     returned value is the next pending task.
+
+     All specified arrays must have the same dimensions as those expected by
+     WS.  F must be a simple variable reference (not an expression), X and G
+     must be arrays of double's; if specified, ISFREE is an array of int's; if
+     specified, H is an array of double's.
+
+   SEE ALSO opl_vmlmb_create, opl_vmlmb_restore.
+*/
+
+extern opl_vmlmb_restore;
+/* DOCUMENT task = opl_vmlmb_restore(ws, x, f, g);
+
+     Restore last line search starting point for VMLMB workspace WS.  Calling
+     this is only effective if task is OPL_TASK_FG.  Arguments X, F and G are
+     the same as in `opl_vmlmb_iterate`.
+
+   SEE ALSO opl_vmlmb_iterate.
+*/
+
+extern opl_vmlmb_restart;
+/* DOCUMENT task = opl_vmlmb_restart(ws);
+
+      Set VMLMB workspace WS so that it can be used for a new optimization with
+      the same parameters.
+
+   SEE ALSO opl_vmlmb_create, opl_vmlmb_iterate.
+*/
+
+func opl_vmlmb(f, x, &fx, &gx, fmin=, extra=, xmin=, xmax=, flags=, mem=,
+               verb=, quiet=, viewer=, printer=, maxiter=, maxeval=, output=,
+               frtol=, fatol=, gatol=, grtol=, sftol=, sgtol=, sxtol=)
+/* DOCUMENT opl_vmlmb(f, x);
+         or opl_vmlmb(f, x, fout, gout);
+
+     Returns a minimum of a multivariate function F by an iterative
+     minimization algorithm (limited memory variable metric) possibly with
+     simple bound constraints on the parameters.  F is the function
+     to minimize, its prototype is:
+
+         func f(x, &gx) {
+             fx = ....; // compute function value at X
+             gx = ....; // store gradient of F in GX
+             return fx; // return F(X)
+         }
+
+     Argument X is the starting solution (a double precision floating point
+     array).  FOUT and GOUT are optional output variables to store the value of
+     F and its gradient at the minimum.
+
+     If the multivariate function has more than one minimum, which minimum is
+     returned is undefined (although it depends on the starting parameters X).
+
+     In case of early termination, the best solution found so far is returned.
+
+
+   KEYWORDS
+
+     EXTRA - Supplemental argument for F; if non-nil, F is called as
+         F(X,GX,EXTRA) so its prototype must be: func F(x, &gx, extra).  It is
+         however more flexible to use a closure for F if additional data is
+         needed.
+
+     XMIN, XMAX - Lower/upper bounds for X.  Must be conformable with X.  For
+         instance with XMIN=0, the non-negative solution will be returned.
+
+     MEM - Number of previous directions used in variable metric limited memory
+         method (default min(7, numberof(X))).
+
+     MAXITER - Maximum number of iterations (default: no limits).
+
+     MAXEVAL - Maximum number of function evaluations (default: no limits).
+
+     FATOL, FRTOL - Relative function change tolerance for convergence
+         (default: 1.5e-8).
+
+     GATOL, GRTOL - Absolute and relative gradient tolerances for convergence
+         which is assumed whenever the Euclidean norm of the (projected)
+         gradient is smaller or equal max(GATOL, GRTOL*GINIT) where GINIT is
+         the Euclidean norm of the (projected) initila gradient.  By default,
+         GTAOL=0 and GRTOL=1e-6.
+
+     VERB - Verbose mode?  If non-nil and non-zero, print out information every
+         VERB iterations and for the final one.
+
+     QUIET - If true and not in verbose mode, do not print warning nor
+         convergence error messages.
+
+     OUPTPUT - Output for verbose mode.  For instance, text file stream opened
+         for writing.
+
+     VIEWER - User defined subroutine to call every VERB iterations (see
+         keyword VERB above)to display the solution X.  The subroutine will be
+         called as:
+
+            viewer, x, extra;
+
+         where X is the current solution and EXTRA is the value of keyword
+         EXTRA (which to see).  If the viewer uses Yorick graphics window(s) it
+         may call "pause, 1;" before returning to make sure that graphics get
+         correctly updated.
+
+     PRINTER - User defined subroutine to call every VERB iterations (see
+         keyword VERB above) to printout iteration information.  The subroutine
+         will be called as:
+
+            printer, output, iter, eval, cpu, fx, gnorm, steplen, x, extra;
+
+         where OUTPUT is the value of keyword OUTPUT (which to see), ITER is
+         the number of iterations, EVAL is the number of function evaluations,
+         CPU is the elapsed CPU time in seconds, FX is the function value at X,
+         GNORM is the Euclidean norm of the gradient at X, STEPLEN is the
+         length of the step along the search direction, X is the current
+         solution and EXTRA is the value of keyword EXTRA (which to see).
+
+     SFTOL, SGTOL, SXTOL - Line search tolerance and safeguard parameters (see
+        opl_csrch).
+
+   SEE ALSO: opl_vmlmb_config, opl_vmlmb_create, opl_vmlmb_iterate.
+*/
+{
+  /* Largest value of a long integer. */
+  LONG_MAX = (1 << (sizeof(long)*8 - 1)) - 1;
+
+  /* Get function. */
+  if (is_void(f) || is_array(f)) {
+    error, "expecting a function for argument F";
+  }
+  use_extra = (! is_void(extra));
+
+  /* Starting parameters. */
+  if ((s = structof(x)) != double && s != float && s != long &&
+      s != int && s != short && s != char) {
+    error, "expecting a numerical array for initial parameters X";
+  }
+  dims = dimsof(x);
+
+  /* Bounds on parameters. */
+  bounds = 0;
+  if (! is_void(xmin)) {
+    if (is_void((t = dimsof(x, xmin))) || t(1) != dims(1)
+        || anyof(t != dims)) {
+      error, "bad dimensions for lower bound XMIN";
+    }
+    if ((convert = (s = structof(xmin)) != double) && s != float &&
+        s != long && s != int && s != short && s != char) {
+      error, "bad data type for lower bound XMIN";
+    }
+    if (convert || (t = dimsof(xmin))(1) != dims(1) || anyof(t != dims)) {
+      xmin += array(double, dims);
+    }
+    bounds |= 1;
+  }
+  if (! is_void(xmax)) {
+    if (is_void((t = dimsof(x, xmax))) || t(1) != dims(1)
+        || anyof(t != dims)) {
+      error, "bad dimensions for lower bound XMAX";
+    }
+    if ((convert = (s = structof(xmax)) != double) && s != float &&
+        s != long && s != int && s != short && s != char) {
+      error, "bad data type for lower bound XMAX";
+    }
+    if (convert || (t = dimsof(xmax))(1) != dims(1) || anyof(t != dims)) {
+      xmax += array(double, dims);
+    }
+    bounds |= 2;
+  }
+
+  /* Output stream. */
+  if (! is_void(output)) {
+    if (structof(output) == string) {
+      output = open(output, "a");
+    } else if (typeof(output) != "text_stream") {
+      error, "bad value for keyword OUTPUT";
+    }
+  }
+
+  /* Maximum number of iterations and function evaluations. */
+  if (is_void(maxiter)) maxiter = LONG_MAX;
+  if (is_void(maxeval)) maxeval = LONG_MAX;
+  if (maxeval < 1) {
+    error, "MAXEVAL must be at least 1";
+  }
+
+  /* Viewer and printer subroutines. */
+  use_printer = (! is_void(printer));
+  use_viewer  = (! is_void(viewer));
+
+  /* Global convergence parameters. */
+  if (is_void(gatol)) {
+    gatol = 0.0;
+  } else if (is_scalar(gatol) && identof(gatol) <= Y_DOUBLE &&
+             gatol >= 0) {
+    gatol = double(gatol);
+  } else {
+    error, "bad value for GATOL";
+  }
+  if (is_void(grtol)) {
+    grtol = 0.0;
+  } else if (is_scalar(grtol) && identof(grtol) <= Y_DOUBLE &&
+             grtol >= 0 && grtol <= 1) {
+    grtol = double(grtol);
+  } else {
+    error, "bad value for GRTOL";
+  }
+  gtest = double(gatol);
+
+  /* Choose minimization method. */
+  if (is_void(mem)) mem = min(numberof(x), 7);
+  method_name = swrite(format="VMLMB %s bounds and MEM=%d",
+                       (bounds != 0 ? "with" : "without"), mem);
+  ws = opl_vmlmb_create(dims, mem, fmin=fmin,
+                        fatol=fatol, frtol=frtol,
+                        sftol=sftol, sgtol=sgtol, sxtol=sxtol);
+
+  /* Start iterations. */
+  task = 1;
+  eval = 0;
+  stop = 0n;
+  if (verb) {
+    elapsed = array(double, 3);
+    timer, elapsed;
+    cpu_start = elapsed(1);
+  }
+  if (structof(x) != double) {
+    x = double(x);
+  }
+  local gx, gnorm, isfree, iter, step;
+  task = ws.task;
+  for (;;) {
+    if (task == OPL_TASK_FG) {
+      /* Evaluate function and gradient. */
+      if (eval >= maxeval) {
+        /* Too many function evaluations.  We restore the variables at the
+           start of the line search which is a cheap way (no extra memory cost)
+           to recover variables which should be nearly the best ones. */
+        stop = 1n;
+        msg = swrite(format="too many function evaluations (%d)", eval);
+        opl_vmlmb_restore, ws, x, fx, gx;
+      } else {
+        if (bounds != 0) {
+          if ((bounds & 1) == 1) {
+            x = max(unref(x), xmin);
+          }
+          if ((bounds & 2) == 2) {
+            x = min(unref(x), xmax);
+          }
+        }
+        fx = (use_extra ? f(x, gx, extra) : f(x, gx));
+        ++eval;
+      }
+    }
+    if (task == OPL_TASK_FREEVARS && bounds != 0) {
+      /* Determine the set of free variables. */
+      isfree = [];
+      if (bounds == 1) {
+        isfree = ((x > xmin) | (gx < 0.0));
+      } else if (bounds == 2) {
+        isfree = ((x < xmax) | (gx > 0.0));
+      } else {
+        isfree = (((x > xmin) | (gx < 0.0)) & ((x < xmax) | (gx > 0.0)));
+      }
+    }
+
+    /* Check for convergence. */
+    if (task >= OPL_TASK_NEWX) {
+      iter = ws.iterations;
+      if (task >= OPL_TASK_WARN) {
+        /* Error or warning. */
+        stop = 1n;
+        msg = ws.reason;
+      } else if (ws.gnorm <= gtest) {
+        stop = 1n;
+        msg = swrite(format="convergence (%s)", "gradient small enough");
+      } else if (iter > maxiter) {
+        stop = 1n;
+        msg = swrite(format="too many iterations (%d)", iter);
+      }
+    }
+    if (verb && (stop || task >= OPL_TASK_NEWX && (iter % verb) == 0)) {
+      if (eval == 1 && ! use_printer) {
+        write, output, format="# Method %d (MEM=%d): %s\n#\n",
+          0, mem, method_name;
+        write, output, format="# %s\n# %s\n",
+          "ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN",
+          "---------------------------------------------------------------";
+      }
+      timer, elapsed;
+      cpu = 1e3*(elapsed(1) - cpu_start);
+      step = ws.step;
+      gnorm = ws.gnorm;
+      if (use_printer) {
+        printer, output, iter, eval, cpu, fx, gnorm, step, x, extra;
+      } else {
+        write, output, format=" %5d %5d %10.3f  %+-24.15e%-9.1e%-9.1e\n",
+          iter, eval, cpu, fx, gnorm, step;
+      }
+      if (use_viewer) {
+        viewer, x, extra;
+      }
+    }
+    if (stop) {
+      if (msg && (verb || (task != 3 && ! quiet))) {
+        write, output, format="# %s\n", strtrim(msg, 2, blank=" \t\v\n\r");
+      }
+      return x;
+    }
+
+    /* Call optimizer. */
+    task = opl_vmlmb_iterate(ws, x, fx, gx, isfree);
+  }
+}
+
+extern _opl_init;
+/* DOCUMENT _opl_init;
+
+     Restore/set global variables used by YOPL.  In principle, it is not needed
+     to call this subroutine (this is automatically done at startup) unless you
+     destroyed some constants.
+*/
+_opl_init; /* restore global variables */
diff -Nru yorick-optimpack-1.3.2+dfsg/yorick/optimpacklegacy-start.i yorick-optimpack-1.3.2+dfsg+1.4.0/yorick/optimpacklegacy-start.i
--- yorick-optimpack-1.3.2+dfsg/yorick/optimpacklegacy-start.i	1970-01-01 00:00:00.000000000 +0000
+++ yorick-optimpack-1.3.2+dfsg+1.4.0/yorick/optimpacklegacy-start.i	2017-01-10 22:16:57.000000000 +0000
@@ -0,0 +1,14 @@
+autoload, "optimpacklegacy.i",
+  opl_vmlmb,
+  opl_vmlmb_configure,
+  opl_vmlmb_create,
+  opl_vmlmb_iterate,
+  opl_vmlmb_restore,
+  opl_vmlmb_restart,
+  OPL_TASK_START,
+  OPL_TASK_FG,
+  OPL_TASK_FREEVARS,
+  OPL_TASK_NEWX,
+  OPL_TASK_CONV,
+  OPL_TASK_WARN,
+  OPL_TASK_ERROR;
diff -Nru yorick-optimpack-1.3.2+dfsg/yorick/optimpacklegacy-tests.i yorick-optimpack-1.3.2+dfsg+1.4.0/yorick/optimpacklegacy-tests.i
--- yorick-optimpack-1.3.2+dfsg/yorick/optimpacklegacy-tests.i	1970-01-01 00:00:00.000000000 +0000
+++ yorick-optimpack-1.3.2+dfsg+1.4.0/yorick/optimpacklegacy-tests.i	2017-01-10 22:16:57.000000000 +0000
@@ -0,0 +1,986 @@
+/*
+ * optimpacklegacy-tests.i --
+ *
+ * Various tests from MINPACK suite for the optimization routines in
+ * OptimPackLegacy extension for Yorick.
+ *
+ *-----------------------------------------------------------------------------
+ *
+ * This file is part of OptimPack .
+ *
+ * Copyright (c) 2003-2009, 2016 Éric Thiébaut.
+ *
+ * OptimPack is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * OptimPack is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * OptimPack (file "LICENSE" in the top source directory); if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307 USA
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+require, "optimpacklegacy.i";
+
+#if 0
+#include "optimpacklegacy-tests.i"
+opl_runtests, "optimpacklegacy-tests.out.new";
+
+// Since the CPU time may change, you can compare the outputs
+// with:
+//   sed -e 's/^\( *[0-9]* *[0-9]*\) *[^ ]*/\1/'
+//
+#endif
+
+func opl_runtests(output)
+{
+  for (i = 1; i <= 18; ++i) {
+    opl_test_um, prob=i, method=0, verb=1, output=output;
+  }
+}
+
+local opl_rosenbrock_nevals;
+opl_rosenbrock_nevals=0;
+
+func opl_test_rosenbrock(nil, start=, method=, ndirs=, frtol=)
+/* DOCUMENT opl_test_rosenbrock, ...;
+     Test opl_driver with Rosenbrock function.
+
+   SEE ALSO: opl_test_rosenbrock_func. */
+{
+  x = is_void(start) ? [0.0, 0.0] : start;
+  return opl_driver(opl_test_rosenbrock_func,
+                    (is_void(start) ? [0.0, 0.0] : start),
+                    method=method, fmin=0.0, verb=1, ndirs=ndirs,
+                    frtol=frtol);
+}
+
+func opl_test_rosenbrock_func(x, &g)
+{
+  // Rosenbrock:
+  //    f  = 100*(x2 - x1^2)^2 + (1 - x1)^2
+  x1 = x(1);
+  u = x(2) - x1*x1;
+  v = 1.0 - x1;
+  f = 100.0*u*u + v*v;
+  g = [-400.0*u*x1 - 2.0*v, 200.0*u];
+  ++opl_rosenbrock_nevals;
+  return f;
+}
+
+func opl_test_quad(x, &g)
+{
+  u = (x - [1.0, 1.0, 1.0]);
+  w = [3.0, 7.0, 2.0];
+  g = 2.0*w*u;
+  return sum(w*u*u);
+}
+
+func opl_test_um(prob=, n=, method=, ndir=, verb=, factor=,
+                maxiter=, maxeval=, frtol=, fatol=,
+                sftol=, sgtol=, sxtol=,
+                output=)
+/* DOCUMENT opl_test_um(...)
+     Check various optimization methods for eighteen nonlinear unconstrained
+     minimization problems.
+
+   SEE ALSO: optim_vmlm, optim_cgmn, minpack1_umobj. */
+{
+  /* Output array. */
+  local result;
+
+  /* Output stream. */
+  if (! is_void(output)) {
+    if (structof(output) == string) {
+      output = open(output, "a");
+    } else if (typeof(output) != "text_stream") {
+      error, "bad value for keyword OUTPUT";
+    }
+  }
+
+  /* Check compatibility of arguments N and PROB. */
+  if (prob == 1) {
+    name = "Helical valley function.";
+    if (is_void(n)) n = 3;
+    else if (n != 3) error, "N must be 3 for problem #1";
+  } else if (prob == 2) {
+    name = "Biggs exp6 function.";
+    if (is_void(n)) n = 6;
+    else if (n != 6) error, "N must be 6 for problem #2";
+  } else if (prob == 3) {
+    name = "Gaussian function.";
+    if (is_void(n)) n = 3;
+    else if (n != 3) error, "N must be 3 for problem #3";
+  } else if (prob == 4) {
+    name = "Powell badly scaled function.";
+    if (is_void(n)) n = 2;
+    else if (n != 2) error, "N must be 2 for problem #4";
+  } else if (prob == 5) {
+    name = "Box 3-dimensional function.";
+    if (is_void(n)) n = 3;
+    else if (n != 3) error, "N must be 3 for problem #5";
+  } else if (prob == 6) {
+    name = "Variably dimensioned function.";
+    if (is_void(n)) n = 10;
+    else if (n < 1) error, "N must be >= 1 in problem #6";
+  } else if (prob == 7) {
+    name = "Watson function.";
+    msg = "N may be 2 or greater but is usually 6 or 9 for problem #7";
+    if (is_void(n)) {
+      write, msg;
+      n = 6;
+    } else if (n < 2) error, msg;
+  } else if (prob == 8) {
+    name = "Penalty function I.";
+    if (is_void(n)) n = 10;
+    else if (n < 1) error, "N must be >= 1 in problem #8";
+  } else if (prob == 9) {
+    name = "Penalty function II.";
+    if (is_void(n)) n = 10;
+    else if (n < 1) error, "N must be >= 1 in problem #9";
+  } else if (prob == 10) {
+    name = "Brown badly scaled function.";
+    if (is_void(n)) n = 2;
+    else if (n != 2) error, "N must be 2 for problem #10";
+  } else if (prob == 11) {
+    name = "Brown and Dennis function.";
+    if (is_void(n)) n = 4;
+    else if (n != 4) error, "N must be 4 for problem #11";
+  } else if (prob == 12) {
+    name = "Gulf research and development function.";
+    if (is_void(n)) n = 3;
+    else if (n != 3) error, "N must be 3 for problem #12";
+  } else if (prob == 13) {
+    name = "Trigonometric function.";
+    if (is_void(n)) n = 10;
+    else if (n < 1) error, "N must be >= 1 in problem #13";
+  } else if (prob == 14) {
+    name = "Extended Rosenbrock function.";
+    if (is_void(n)) n = 10;
+    else if (n < 1 || n%2 != 0)
+      error, "N must be a multiple of 2 in problem #14";
+  } else if (prob == 15) {
+    name = "Extended Powell function.";
+    if (is_void(n)) n = 12;
+    else if (n < 1 || n%4 != 0)
+      error, "N must be a multiple of 4 in problem #15";
+  } else if (prob == 16) {
+    name = "Beale function.";
+    if (is_void(n)) n = 2;
+    else if (n != 2) error, "N must be 2 for problem #16";
+  } else if (prob == 17) {
+    name = "Wood function.";
+    if (is_void(n)) n = 4;
+    else if (n != 4) error, "N must be 4 for problem #17";
+  } else if (prob == 18) {
+    name = "Chebyquad function.";
+    if (is_void(n)) n = 25;
+    else if (n<1 || n>50) error, "N must be <=50 for problem #18";
+  } else error, "PROB must be an integer between 1 and 18";
+
+  /* Maximum number of iterations and function evaluations. */
+  if (is_void(maxiter)) maxiter = 100*n;
+  if (is_void(maxeval)) maxeval = 10*maxiter;
+
+  /* Starting vector. */
+  x = minpack1_umipt(n, prob, factor);
+  dims = dimsof(x);
+
+  /* Choose minimization method. */
+  if (! method) {
+    /* Variable metric. */
+    method = 0;
+    if (is_void(ndir)) ndir = n;
+    method_name = swrite(format="Limited Memory BFGS (VMLM with NDIR=%d)",
+                         ndir);
+    ws = opl_vmlmb_create(dimsof(x), ndir, fmin=0.0,
+                          fatol=fatol, frtol=frtol,
+                          sftol=sftol, sgtol=sgtol, sxtol=sxtol);
+  } else {
+    error, "bad METHOD";
+  }
+  step = 0.0;
+  eval = iter = 0;
+  elapsed = array(double, 3);
+  timer, elapsed;
+  cpu_start = elapsed(1);
+  task = ws.task;
+  for (;;) {
+    if (task == OPL_TASK_FG) {
+      /* Evaluate function and gradient. */
+      f = minpack1_umobj(x, prob);
+      g = minpack1_umgrd(x, prob);
+      ++eval;
+    }
+
+    /* Check for convergence. */
+    if (task >= OPL_TASK_NEWX) {
+      too_many_eval = (maxeval >= 1 && eval > maxeval);
+      too_many_iter = (maxiter >= 1 && iter > maxiter);
+      timer, elapsed;
+      cpu = elapsed(1) - cpu_start;
+      gnorm = ws.gnorm; // sqrt(sum(g*g));
+      if (verb) {
+        if (eval == 1) {
+          write, output, format="#\n# Problem %d (N=%d): %s\n",
+            prob, n, name;
+          write, output, format="# Method %d (NDIR=%d): %s\n#\n",
+            method, ndir, method_name;
+          write, output, format="# %s\n# %s\n",
+            "ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN",
+            "---------------------------------------------------------------";
+        }
+        write, output, format=" %5d %5d %10.3f  %+-24.15e%-9.1e%-9.1e\n",
+          iter, eval, 1e3*cpu, f, gnorm, step;
+      }
+      if (! am_subroutine()) grow, result, [[iter, eval, 1e3*cpu, f,
+                                             gnorm, step]];
+      if (task >= OPL_TASK_CONV) {
+        msg = ws.reason;
+        break;
+      }
+      if (maxiter >= 0 && iter > maxiter) {
+        task = OPL_TASK_WARN;
+        msg = swrite(format="warning: too many iterations (%d)\n", iter);
+        break;
+      }
+      if (maxeval >= 0 && eval > maxeval) {
+        task = OPL_TASK_WARN;
+        msg = swrite(format="warning: too many function evaluation (%d)\n",
+                     eval);
+        break;
+      }
+    }
+
+    /* Call optimizer. */
+    task = opl_vmlmb_iterate(ws, x, f, g);
+    iter = ws.iterations;
+    step = ws.step;
+  }
+
+  write, output, format=(verb?"# %s\n#\n":"*** %s\n"), msg;
+  return result;
+}
+
+/*---------------------------------------------------------------------------*/
+/* NONLINEAR UNCONSTRAINED MINIMIZATION PROBLEMS
+ *
+ *   This suite of problems is taken from the MINPACK Project.
+ *
+ *   HISTORY:
+ *     - Argonne National Laboratory. MINPACK Project. March 1980.
+ *       Burton S. Garbow, Kenneth E. Hillstrom, Jorge J. More.
+ *     - Conversion to Yorick. November 2001. Eric Thiebaut.
+ */
+_um_y = [9.0e-4,   4.4e-3,   1.75e-2,  5.4e-2,   1.295e-1,
+         2.42e-1,  3.521e-1, 3.989e-1, 3.521e-1, 2.42e-1,
+         1.295e-1, 5.4e-2,   1.75e-2,  4.4e-3,   9.0e-4];
+
+func minpack1_umobj(x, prob)
+/* DOCUMENT minpack1_umobj(x, prob)
+     Returns  the objective functions  of eighteen  nonlinear unconstrained
+     minimization problems.  X  is the parameter array: a  vector of length
+     N, PROB is the problem number (a positive integer between 1 and 18).
+
+     The  values  of  N  for  functions 1,2,3,4,5,10,11,12,16  and  17  are
+     3,6,3,2,3,2,4,3,2 and 4, respectively.  For  function 7, n may be 2 or
+     greater but is usually 6 or 9.  For functions 6,8,9,13,14,15 and 18, N
+     may be variable,  however it must be even for  function 14, a multiple
+     of 4 for function 15, and not greater than 50 for function 18.
+
+   SEE ALSO: minpack1_umgrd, minpack1_umipt. */
+{
+  n = numberof(x);
+
+  /* Function routine selector. */
+  if (prob == 1) {
+    /* Helical valley function. */
+    tpi = 8.0*atan(1.0);
+    if      (x(1) > 0.0) th = atan(x(2)/x(1))/tpi;
+    else if (x(1) < 0.0) th = atan(x(2)/x(1))/tpi + 0.5;
+    else                 th = (x(2) >= 0.0 ? 0.25 : -0.25);
+    arg = x(1)*x(1) + x(2)*x(2);
+    r = sqrt(arg);
+    t = x(3) - 10.0*th;
+    f = 100.0*(t*t + (r - 1.0)*(r - 1.0)) + x(3)*x(3);
+    return f;
+  } else if (prob == 2) {
+    /* Biggs exp6 function. */
+    f = 0.0;
+    for (i=1 ; i<=13 ; i+=1) {
+      d1 = double(i)/10.0;
+      d2 = exp(-d1) - 5.0*exp(-10.0*d1) + 3.0*exp(-4.0*d1);
+      s1 = exp(-d1*x(1));
+      s2 = exp(-d1*x(2));
+      s3 = exp(-d1*x(5));
+      t = x(3)*s1 - x(4)*s2 + x(6)*s3 - d2;
+      f += t*t;
+    }
+    return f;
+  } else if (prob == 3) {
+    /* Gaussian function. */
+    f = 0.0;
+    for (i=1 ; i<=15 ; i+=1) {
+      d1 = 0.5*double(i-1);
+      d2 = 3.5 - d1 - x(3);
+      arg = -0.5*x(2)*d2*d2;
+      r = exp(arg);
+      t = x(1)*r - _um_y(i);
+      f += t*t;
+    }
+    return f;
+  } else if (prob == 4) {
+    /* Powell badly scaled function. */
+    t1 = 1e4*x(1)*x(2) - 1.0;
+    s1 = exp(-x(1));
+    s2 = exp(-x(2));
+    t2 = s1 + s2 - 1.0001;
+    f = t1*t1 + t2*t2;
+    return f;
+  } else if (prob == 5) {
+    /* Box 3-dimensional function. */
+    f = 0.0;
+    for (i=1 ; i<=10 ; i+=1) {
+      d1 = double(i);
+      d2 = d1/10.0;
+      s1 = exp(-d2*x(1));
+      s2 = exp(-d2*x(2));
+      s3 = exp(-d2) - exp(-d1);
+      t = s1 - s2 - s3*x(3);
+      f += t*t;
+    }
+    return f;
+  } else if (prob == 6) {
+    /* Variably dimensioned function. */
+    t1 = 0.0;
+    t2 = 0.0;
+    for (j=1 ; j<=n ; j+=1) {
+      t1 += double(j)*(x(j) - 1.0);
+      t = x(j) - 1.0;
+      t2 += t*t;
+    }
+    t = t1*t1;
+    f = t2 + t*(1.0 + t);
+    return f;
+  } else if (prob == 7) {
+    /* Watson function. */
+    f = 0.0;
+    for (i=1 ; i<=29 ; i+=1) {
+      d1 = double(i)/29.0;
+      s1 = 0.0;
+      d2 = 1.0;
+      for (j=2 ; j<=n ; j+=1) {
+	s1 += double(j-1)*d2*x(j);
+	d2 = d1*d2;
+      }
+      s2 = 0.0;
+      d2 = 1.0;
+      for (j=1 ; j<=n ; j+=1) {
+	s2 += d2*x(j);
+	d2 = d1*d2;
+      }
+      t = s1 - s2*s2 - 1.0;
+      f += t*t;
+    }
+    t = x(1)*x(1);
+    t1 = x(2) - t - 1.0;
+    f += t + t1*t1;
+    return f;
+  } else if (prob == 8) {
+    /* Penalty function I. */
+    t1 = -0.25;
+    t2 = 0.0;
+    for (j=1 ; j<=n ; j+=1) {
+      t1 += x(j)*x(j);
+      t = x(j) - 1.0;
+      t2 += t*t;
+    }
+    f = 1e-5*t2 + t1*t1;
+    return f;
+  } else if (prob == 9) {
+    /* Penalty function II. */
+    t1 = -1.0;
+    t2 = 0.0;
+    t3 = 0.0;
+    d1 = exp(0.1);
+    d2 = 1.0;
+    s2 = 0.0; /* avoid compiler warning about `s2' used uninitialized */
+    for (j=1 ; j<=n ; j+=1) {
+      t1 += double(n-j+1)*x(j)*x(j);
+      s1 = exp(x(j)/10.0);
+      if (j > 1) {
+	s3 = s1 + s2 - d2*(d1 + 1.0);
+	t2 += s3*s3;
+	t = (s1 - 1.0/d1);
+	t3 += t*t;
+      }
+      s2 = s1;
+      d2 = d1*d2;
+    }
+    t = (x(1) - 0.2);
+    f = 1e-5*(t2 + t3) + t1*t1 + t*t;
+    return f;
+  } else if (prob == 10) {
+    /* Brown badly scaled function. */
+    t1 = x(1) - 1e6;
+    t2 = x(2) - 2e-6;
+    t3 = x(1)*x(2) - 2.0;
+    f = t1*t1 + t2*t2 + t3*t3;
+    return f;
+  } else if (prob == 11) {
+    /* Brown and Dennis function. */
+    f = 0.0;
+    for (i=1 ; i<=20 ; i+=1) {
+      d1 = double(i)/5.0;
+      d2 = sin(d1);
+      t1 = x(1) + d1*x(2) - exp(d1);
+      t2 = x(3) + d2*x(4) - cos(d1);
+      t = t1*t1 + t2*t2;
+      f += t*t;
+    }
+    return f;
+  } else if (prob == 12) {
+    /* Gulf research and development function. */
+    f = 0.0;
+    d1 = 2.0/3.0;
+    for (i=1 ; i<=99 ; i+=1) {
+      arg = double(i)/100.0;
+      r = (-50.0*log(arg))^d1 + 25.0 - x(2);
+      t1 = (abs(r)^x(3))/x(1);
+      t2 = exp(-t1);
+      t = t2 - arg;
+      f += t*t;
+    }
+    return f;
+  } else if (prob == 13) {
+    /* Trigonometric function. */
+    s1 = 0.0;
+    for (j=1 ; j<=n ; j+=1) {
+      s1 += cos(x(j));
+    }
+    f = 0.0;
+    for (j=1 ; j<=n ; j+=1) {
+      t = double(n+j) - sin(x(j)) - s1 - double(j)*cos(x(j));
+      f += t*t;
+    }
+    return f;
+  } else if (prob == 14) {
+    /* Extended Rosenbrock function. */
+    f = 0.0;
+    for (j=1 ; j<=n ; j+=2) {
+      t1 = 1.0 - x(j);
+      t2 = 10.0*(x(j+1) - x(j)*x(j));
+      f += t1*t1 + t2*t2;
+    }
+    return f;
+  } else if (prob == 15) {
+    /* Extended Powell function. */
+    f = 0.0;
+    for (j=1 ; j<=n ; j+=4) {
+      t = x(j) + 10.0*x(j+1);
+      t1 = x(j+2) - x(j+3);
+      s1 = 5.0*t1;
+      t2 = x(j+1) - 2.0*x(j+2);
+      s2 = t2*t2*t2;
+      t3 = x(j) - x(j+3);
+      s3 = 10.0*t3*t3*t3;
+      f += t*t + s1*t1 + s2*t2 + s3*t3;
+    }
+    return f;
+  } else if (prob == 16) {
+    /* Beale function. */
+    s1 = 1.0 - x(2);
+    t1 = 1.5 - x(1)*s1;
+    s2 = 1.0 - x(2)*x(2);
+    t2 = 2.25 - x(1)*s2;
+    s3 = 1.0 - x(2)*x(2)*x(2);
+    t3 = 2.625 - x(1)*s3;
+    f = t1*t1 + t2*t2 + t3*t3;
+    return f;
+  } else if (prob == 17) {
+    /* Wood function. */
+    s1 = x(2) - x(1)*x(1);
+    s2 = 1.0 - x(1);
+    s3 = x(2) - 1.0;
+    t1 = x(4) - x(3)*x(3);
+    t2 = 1.0 - x(3);
+    t3 = x(4) - 1.0;
+    f = 100.0*s1*s1 + s2*s2 + 90.0*t1*t1 + t2*t2 + \
+      10.0*(s3 + t3)*(s3 + t3) + (s3 - t3)*(s3 - t3)/10.0;
+    return f;
+  } else if (prob == 18) {
+    /* Chebyquad function. */
+    fvec = array(0.0, n);
+    for (j=1 ; j<=n ; j+=1) {
+      t1 = 1.0;
+      t2 = 2.0*x(j) - 1.0;
+      t = 2.0*t2;
+      for (i=1 ; i<=n ; i+=1) {
+	fvec(i) += t2;
+	th = t*t2 - t1;
+	t1 = t2;
+	t2 = th;
+      }
+    }
+    f = 0.0;
+    d1 = 1.0/double(n);
+    iev = -1;
+    for (i=1 ; i<=n ; i+=1) {
+      t = d1*fvec(i);
+      if (iev > 0) t += 1.0/(double(i)*double(i) - 1.0);
+      f += t*t;
+      iev = -iev;
+    }
+    return f;
+  }
+  return 0.0;
+}
+
+func minpack1_umgrd(x, prob)
+/* DOCUMENT minpack1_umgrd(x, prob)
+     Returns  the  gradient  vectors  of eighteen  nonlinear  unconstrained
+     minimization problems. The problem  dimensions are as described in the
+     prologue comments of minpack1_umobj.
+
+   SEE ALSO: minpack1_umobj, minpack1_umipt. */
+{
+  n = numberof(x);
+  g = array(double, n);
+
+  /* Gradient routine selector. */
+  if (prob == 1) {
+    /* Helical valley function. */
+    tpi = 8.0*atan(1.0);
+    if      (x(1) > 0.0) th = atan(x(2)/x(1))/tpi;
+    else if (x(1) < 0.0) th = atan(x(2)/x(1))/tpi + 0.5;
+    else                 th = (x(2) >= 0.0 ? 0.25 : -0.25);
+    arg = x(1)*x(1) + x(2)*x(2);
+    r = sqrt(arg);
+    t = x(3) - 10.0*th;
+    s1 = 10.0*t/(tpi*arg);
+    g(1) = 200.0*(x(1) - x(1)/r + x(2)*s1);
+    g(2) = 200.0*(x(2) - x(2)/r - x(1)*s1);
+    g(3) = 2.0*(100.0*t + x(3));
+  } else if (prob == 2) {
+    /* Biggs exp6 function. */
+    for (j=1 ; j<=6 ; ++j) g(j) = 0.0;
+    for (i=1 ; i<=13 ; ++i) {
+      d1 = double(i)/10.0;
+      d2 = exp(-d1) - 5.0*exp(-10.0*d1) + 3.0*exp(-4.0*d1);
+      s1 = exp(-d1*x(1));
+      s2 = exp(-d1*x(2));
+      s3 = exp(-d1*x(5));
+      t = x(3)*s1 - x(4)*s2 + x(6)*s3 - d2;
+      th = d1*t;
+      g(1) = g(1) - s1*th;
+      g(2) = g(2) + s2*th;
+      g(3) = g(3) + s1*t;
+      g(4) = g(4) - s2*t;
+      g(5) = g(5) - s3*th;
+      g(6) = g(6) + s3*t;
+    }
+    g(1) = 2.0*x(3)*g(1);
+    g(2) = 2.0*x(4)*g(2);
+    g(3) = 2.0*g(3);
+    g(4) = 2.0*g(4);
+    g(5) = 2.0*x(6)*g(5);
+    g(6) = 2.0*g(6);
+  } else if (prob == 3) {
+    /* Gaussian function. */
+    g(1) = 0.0;
+    g(2) = 0.0;
+    g(3) = 0.0;
+    for (i=1 ; i<=15 ; ++i) {
+      d1 = 0.5*double(i-1);
+      d2 = 3.5 - d1 - x(3);
+      arg = -0.5*x(2)*d2*d2;
+      r = exp(arg);
+      t = x(1)*r - _um_y(i);
+      s1 = r*t;
+      s2 = d2*s1;
+      g(1) = g(1) + s1;
+      g(2) = g(2) - d2*s2;
+      g(3) = g(3) + s2;
+    }
+    g(1) = 2.0*g(1);
+    g(2) = x(1)*g(2);
+    g(3) = 2.0*x(1)*x(2)*g(3);
+  } else if (prob == 4) {
+    /* Powell badly scaled function. */
+    t1 = 1e4*x(1)*x(2) - 1.0;
+    s1 = exp(-x(1));
+    s2 = exp(-x(2));
+    t2 = s1 + s2 - 1.0001;
+    g(1) = 2.0*(1e4*x(2)*t1 - s1*t2);
+    g(2) = 2.0*(1e4*x(1)*t1 - s2*t2);
+  } else if (prob == 5) {
+    /* Box 3-dimensional function. */
+    g(1) = 0.0;
+    g(2) = 0.0;
+    g(3) = 0.0;
+    for (i=1 ; i<=10 ; ++i) {
+      d1 = double(i);
+      d2 = d1/10.0;
+      s1 = exp(-d2*x(1));
+      s2 = exp(-d2*x(2));
+      s3 = exp(-d2) - exp(-d1);
+      t = s1 - s2 - s3*x(3);
+      th = d2*t;
+      g(1) = g(1) - s1*th;
+      g(2) = g(2) + s2*th;
+      g(3) = g(3) - s3*t;
+    }
+    g(1) = 2.0*g(1);
+    g(2) = 2.0*g(2);
+    g(3) = 2.0*g(3);
+  } else if (prob == 6) {
+    /* Variably dimensioned function. */
+    t1 = 0.0;
+    for (j=1 ; j<=n ; ++j) {
+      t1 += double(j)*(x(j) - 1.0);
+    }
+    t = t1*(1.0 + 2.0*t1*t1);
+    for (j=1 ; j<=n ; ++j) {
+      g(j) = 2.0*(x(j) - 1.0 + double(j)*t);
+    }
+  } else if (prob == 7) {
+    /* Watson function. */
+    for (j=1 ; j<=n ; ++j) {
+      g(j) = 0.0;
+    }
+    for (i=1 ; i<=29 ; ++i) {
+      d1 = double(i)/29.0;
+      s1 = 0.0;
+      d2 = 1.0;
+      for (j=2 ; j<=n ; ++j) {
+	s1 += double(j-1)*d2*x(j);
+	d2 = d1*d2;
+      }
+      s2 = 0.0;
+      d2 = 1.0;
+      for (j=1 ; j<=n ; ++j) {
+	s2 += d2*x(j);
+	d2 = d1*d2;
+      }
+      t = s1 - s2*s2 - 1.0;
+      s3 = 2.0*d1*s2;
+      d2 = 2.0/d1;
+      for (j=1 ; j<=n ; ++j) {
+	g(j) = g(j) + d2*(double(j-1) - s3)*t;
+	d2 = d1*d2;
+      }
+    }
+    t1 = x(2) - x(1)*x(1) - 1.0;
+    g(1) = g(1) + x(1)*(2.0 - 4.0*t1);
+    g(2) = g(2) + 2.0*t1;
+  } else if (prob == 8) {
+    /* Penalty function I. */
+    t1 = -0.25;
+    for (j=1 ; j<=n ; ++j) {
+      t1 += x(j)*x(j);
+    }
+    d1 = 2.0*1e-5;
+    th = 4.0*t1;
+    for (j=1 ; j<=n ; ++j) {
+      g(j) = d1*(x(j) - 1.0) + x(j)*th;
+    }
+  } else if (prob == 9) {
+    /* Penalty function II. */
+    s2 = 0.0; /* avoid compiler warning about `s2' used uninitialized */
+    t1 = -1.0;
+    for (j=1 ; j<=n ; ++j) {
+      t1 += double(n-j+1)*x(j)*x(j);
+    }
+    d1 = exp(0.1);
+    d2 = 1.0;
+    th = 4.0*t1;
+    for (j=1 ; j<=n ; ++j) {
+      g(j) = double(n-j+1)*x(j)*th;
+      s1 = exp(x(j)/10.0);
+      if (j > 1) {
+	s3 = s1 + s2 - d2*(d1 + 1.0);
+	g(j) = g(j) + 1e-5*s1*(s3 + s1 - 1.0/d1)/5.0;
+	g(j-1) = g(j-1) + 1e-5*s2*s3/5.0;
+      }
+      s2 = s1;
+      d2 = d1*d2;
+    }
+    g(1) = g(1) + 2.0*(x(1) - 0.2);
+  } else if (prob == 10) {
+    /* Brown badly scaled function. */
+    t1 = x(1) - 1e6;
+    t2 = x(2) - 2e-6;
+    t3 = x(1)*x(2) - 2.0;
+    g(1) = 2.0*(t1 + x(2)*t3);
+    g(2) = 2.0*(t2 + x(1)*t3);
+  } else if (prob == 11) {
+    /* Brown and Dennis function. */
+    g(1) = 0.0;
+    g(2) = 0.0;
+    g(3) = 0.0;
+    g(4) = 0.0;
+    for (i=1 ; i<=20 ; ++i) {
+      d1 = double(i)/5.0;
+      d2 = sin(d1);
+      t1 = x(1) + d1*x(2) - exp(d1);
+      t2 = x(3) + d2*x(4) - cos(d1);
+      t = t1*t1 + t2*t2;
+      s1 = t1*t;
+      s2 = t2*t;
+      g(1) = g(1) + s1;
+      g(2) = g(2) + d1*s1;
+      g(3) = g(3) + s2;
+      g(4) = g(4) + d2*s2;
+    }
+    g(1) = 4.0*g(1);
+    g(2) = 4.0*g(2);
+    g(3) = 4.0*g(3);
+    g(4) = 4.0*g(4);
+  } else if (prob == 12) {
+    /* Gulf research and development function. */
+    g(1) = 0.0;
+    g(2) = 0.0;
+    g(3) = 0.0;
+    d1 = 2.0/3.0;
+    for (i=1 ; i<=99 ; ++i) {
+      arg = double(i)/100.0;
+      r = (-50.0*log(arg))^d1 + 25.0 - x(2);
+      t1 = (abs(r)^x(3))/x(1);
+      t2 = exp(-t1);
+      t = t2 - arg;
+      s1 = t1*t2*t;
+      g(1) = g(1) + s1;
+      g(2) = g(2) + s1/r;
+      g(3) = g(3) - s1*log(abs(r));
+    }
+    g(1) = 2.0*g(1)/x(1);
+    g(2) = 2.0*x(3)*g(2);
+    g(3) = 2.0*g(3);
+  } else if (prob == 13) {
+    /* Trigonometric function. */
+    s1 = 0.0;
+    for (j=1 ; j<=n ; ++j) {
+      g(j) = cos(x(j));
+      s1 += g(j);
+    }
+    s2 = 0.0;
+    for (j=1 ; j<=n ; ++j) {
+      th = sin(x(j));
+      t = double(n+j) - th - s1 - double(j)*g(j);
+      s2 += t;
+      g(j) = (double(j)*th - g(j))*t;
+    }
+    for (j=1 ; j<=n ; ++j) {
+      g(j) = 2.0*(g(j) + sin(x(j))*s2);
+    }
+  } else if (prob == 14) {
+    /* Extended Rosenbrock function. */
+    for (j=1 ; j<=n ; j+=2) {
+      t1 = 1.0 - x(j);
+      g(j+1) = 200.0*(x(j+1) - x(j)*x(j));
+      g(j) = -2.0*(x(j)*g(j+1) + t1);
+    }
+  } else if (prob == 15) {
+    /* Extended Powell function. */
+    for (j=1 ; j<=n ; j+=4) {
+      t = x(j) + 10.0*x(j+1);
+      t1 = x(j+2) - x(j+3);
+      s1 = 5.0*t1;
+      t2 = x(j+1) - 2.0*x(j+2);
+      s2 = 4.0*t2*t2*t2;
+      t3 = x(j) - x(j+3);
+      s3 = 20.0*t3*t3*t3;
+      g(j) = 2.0*(t + s3);
+      g(j+1) = 20.0*t + s2;
+      g(j+2) = 2.0*(s1 - s2);
+      g(j+3) = -2.0*(s1 + s3);
+    }
+  } else if (prob == 16) {
+    /* Beale function. */
+    s1 = 1.0 - x(2);
+    t1 = 1.5 - x(1)*s1;
+    s2 = 1.0 - x(2)*x(2);
+    t2 = 2.25 - x(1)*s2;
+    s3 = 1.0 - x(2)*x(2)*x(2);
+    t3 = 2.625 - x(1)*s3;
+    g(1) = -2.0*(s1*t1 + s2*t2 + s3*t3);
+    g(2) = 2.0*x(1)*(t1 + x(2)*(2.0*t2 + 3.0*x(2)*t3));
+  } else if (prob == 17) {
+    /* Wood function. */
+    s1 = x(2) - x(1)*x(1);
+    s2 = 1.0 - x(1);
+    s3 = x(2) - 1.0;
+    t1 = x(4) - x(3)*x(3);
+    t2 = 1.0 - x(3);
+    t3 = x(4) - 1.0;
+    g(1) = -2.0*(200.0*x(1)*s1 + s2);
+    g(2) = 200.0*s1 + 20.2*s3 + 19.8*t3;
+    g(3) = -2.0*(180.0*x(3)*t1 + t2);
+    g(4) = 180.0*t1 + 20.2*t3 + 19.8*s3;
+  } else if (prob == 18) {
+    /* Chebyquad function. */
+    fvec = array(0.0, n);
+    for (j=1 ; j<=n ; ++j) {
+      t1 = 1.0;
+      t2 = 2.0*x(j) - 1.0;
+      t = 2.0*t2;
+      for (i=1 ; i<=n ; ++i) {
+	fvec(i) += t2;
+	th = t*t2 - t1;
+	t1 = t2;
+	t2 = th;
+      }
+    }
+    d1 = 1.0/double(n);
+    iev = -1;
+    for (i=1 ; i<=n ; ++i) {
+      fvec(i) *= d1;
+      if (iev > 0) fvec(i) += 1.0/(double(i)*double(i) - 1.0);
+      iev = -iev;
+    }
+    for (j=1 ; j<=n ; ++j) {
+      g(j) = 0.0;
+      t1 = 1.0;
+      t2 = 2.0*x(j) - 1.0;
+      t = 2.0*t2;
+      s1 = 0.0;
+      s2 = 2.0;
+      for (i=1 ; i<=n ; ++i) {
+	g(j) = g(j) + fvec(i)*s2;
+	th = 4.0*t2 + t*s2 - s1;
+	s1 = s2;
+	s2 = th;
+	th = t*t2 - t1;
+	t1 = t2;
+	t2 = th;
+      }
+    }
+    d2 = 2.0*d1;
+    for (j=1 ; j<=n ; ++j) g(j) *= d2;
+  }
+  return g;
+}
+
+func minpack1_umipt(n, prob, factor)
+/* DOCUMENT minpack1_umipt(n, prob, factor)
+     Returns  the standard  starting points  for the  functions  defined by
+     subroutine  minpack1_umobj.  The  function  returns a  vector  X of  N
+     elements, X is a multiple  (times FACTOR, default 1.0) of the standard
+     starting point.  For the  seventh function the standard starting point
+     is 0.0,  so in this  case, if FACTOR  is not unity, then  the function
+     returns  X  filled with  FACTOR.   PROB has  the  same  meaning as  in
+     minpack1_umobj.
+
+   SEE ALSO: minpack1_umobj, minpack1_umipt. */
+{
+  if (is_void(factor)) factor = 1.0;
+  x = array(double, n);
+
+  /* Selection of initial point. */
+  if (prob == 1) {
+    /* Helical valley function. */
+    x(1) = -1.0;
+    x(2) = 0.0;
+    x(3) = 0.0;
+  } else if (prob == 2) {
+    /* Biggs exp6 function. */
+    x(1) = 1.0;
+    x(2) = 2.0;
+    x(3) = 1.0;
+    x(4) = 1.0;
+    x(5) = 1.0;
+    x(6) = 1.0;
+  } else if (prob == 3) {
+    /* Gaussian function. */
+    x(1) = 0.4;
+    x(2) = 1.0;
+    x(3) = 0.0;
+  } else if (prob == 4) {
+    /* Powell badly scaled function. */
+    x(1) = 0.0;
+    x(2) = 1.0;
+  } else if (prob == 5) {
+    /* Box 3-dimensional function. */
+    x(1) = 0.0;
+    x(2) = 10.0;
+    x(3) = 20.0;
+  } else if (prob == 6) {
+    /* Variably dimensioned function. */
+    h = 1.0/double(n);
+    for (j=1 ; j<=n ; ++j) x(j) = 1.0 - double(j)*h;
+  } else if (prob == 7) {
+    /* Watson function. */
+    for (j=1 ; j<=n ; ++j) x(j) = 0.0;
+  } else if (prob == 8) {
+    /* Penalty function I. */
+    for (j=1 ; j<=n ; ++j) x(j) = double(j);
+  } else if (prob == 9) {
+    /* Penalty function II. */
+    for (j=1 ; j<=n ; ++j) x(j) = 0.5;
+  } else if (prob == 10) {
+    /* Brown badly scaled function. */
+    x(1) = 1.0;
+    x(2) = 1.0;
+  } else if (prob == 11) {
+    /* Brown and Dennis function. */
+    x(1) = 25.0;
+    x(2) = 5.0;
+    x(3) = -5.0;
+    x(4) = -1.0;
+  } else if (prob == 12) {
+    /* Gulf research and development function. */
+    x(1) = 5.0;
+    x(2) = 2.5;
+    x(3) = 0.15;
+  } else if (prob == 13) {
+    /* Trigonometric function. */
+    h = 1.0/double(n);
+    for (j=1 ; j<=n ; ++j) x(j) = h;
+  } else if (prob == 14) {
+    /* Extended Rosenbrock function. */
+    for (j=1 ; j<=n ; j+=2) {
+      x(j) = -1.2;
+      x(j+1) = 1.0;
+    }
+  } else if (prob == 15) {
+    /* Extended Powell singular function. */
+    for (j=1 ; j<=n ; j+=4) {
+      x(j) = 3.0;
+      x(j+1) = -1.0;
+      x(j+2) = 0.0;
+      x(j+3) = 1.0;
+    }
+  } else if (prob == 16) {
+    /* Beale function. */
+    x(1) = 1.0;
+    x(2) = 1.0;
+  } else if (prob == 17) {
+    /* Wood function. */
+    x(1) = -3.0;
+    x(2) = -1.0;
+    x(3) = -3.0;
+    x(4) = -1.0;
+  } else if (prob == 18) {
+    /* Chebyquad function. */
+    h = 1.0/double(n+1);
+    for (j=1 ; j<=n ; ++j) x(j) = double(j)*h;
+  }
+
+  /* Compute multiple of initial point. */
+  if (factor != 1.0) {
+    if (prob == 7) {
+      for (j=1 ; j<=n ; ++j) x(j) = factor;
+    } else {
+      for (j=1 ; j<=n ; ++j) x(j) *= factor;
+    }
+  }
+  return x;
+}
diff -Nru yorick-optimpack-1.3.2+dfsg/yorick/optimpacklegacy-tests.out yorick-optimpack-1.3.2+dfsg+1.4.0/yorick/optimpacklegacy-tests.out
--- yorick-optimpack-1.3.2+dfsg/yorick/optimpacklegacy-tests.out	1970-01-01 00:00:00.000000000 +0000
+++ yorick-optimpack-1.3.2+dfsg+1.4.0/yorick/optimpacklegacy-tests.out	2017-01-10 22:16:57.000000000 +0000
@@ -0,0 +1,1281 @@
+#
+# Problem 1 (N=3): Helical valley function.
+# Method 0 (NDIR=3): Limited Memory BFGS (VMLM with NDIR=3)
+#
+# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
+# ---------------------------------------------------------------
+     0     1      0.000  +2.500000000000000e+03  1.9e+03  0.0e+00  
+     1     2      0.000  +1.132008103520547e+03  1.1e+03  1.0e+00  
+     2     3      0.000  +3.073911905701987e+02  4.7e+02  7.8e-01  
+     3     4      0.000  +8.534071352331746e+01  2.1e+02  9.3e-01  
+     4     5      0.000  +3.541502648995344e+01  1.1e+02  1.0e+00  
+     5     6      0.000  +1.762519408308565e+01  7.3e+01  1.0e+00  
+     6     7      0.000  +6.010226268823216e+00  1.7e+01  9.0e-01  
+     7     8      0.000  +5.492716897495775e+00  6.3e+00  1.0e+00  
+     8     9      0.000  +5.425503969579507e+00  4.3e+00  1.0e+00  
+     9    10      0.000  +5.265630629847704e+00  7.5e+00  1.0e+00  
+    10    11      0.000  +4.809839791888933e+00  1.9e+01  1.0e+00  
+    11    12      0.000  +3.522455208281464e+00  3.0e+01  1.0e+00  
+    12    14      0.000  +3.068297969073592e+00  2.7e+01  1.3e-01  
+    13    15      0.000  +2.100951192748246e+00  1.5e+01  1.0e+00  
+    14    16      0.000  +1.706672666076662e+00  1.3e+01  1.0e+00  
+    15    17      0.000  +8.286257916242681e-01  6.9e+00  1.0e+00  
+    16    18      4.001  +5.922941003132391e-01  9.6e+00  1.0e+00  
+    17    20      4.001  +5.103420996864492e-01  1.1e+01  4.4e-01  
+    18    21      4.001  +2.916460245825456e-01  7.0e+00  1.0e+00  
+    19    22      4.001  +1.004295671502106e-01  3.3e+00  1.0e+00  
+    20    23      4.001  +4.654709712389724e-02  1.3e+00  8.3e-01  
+    21    24      4.001  +1.427494728803810e-02  2.6e+00  4.6e-01  
+    22    25      4.001  +4.543295602689820e-03  1.0e-00  4.3e-01  
+    23    26      4.001  +1.007118040044901e-03  4.6e-01  9.2e-01  
+    24    27      4.001  +2.061213550356601e-04  1.9e-01  6.1e-01  
+    25    28      4.001  +4.141146958118607e-05  9.1e-02  5.9e-01  
+    26    29      4.001  +9.246362768846678e-06  4.6e-02  5.6e-01  
+    27    30      4.001  +3.194411530932206e-06  3.5e-02  3.1e-01  
+    28    31      4.001  +6.501783574339488e-07  1.4e-02  5.4e-01  
+    29    32      4.001  +1.343722348096534e-07  5.4e-03  5.9e-01  
+    30    33      4.001  +2.750162245743687e-08  2.3e-03  5.9e-01  
+    31    34      4.001  +6.952580275602280e-09  3.8e-04  5.4e-01  
+    32    35      4.001  +1.473890736071037e-09  2.1e-04  4.1e-01  
+    33    36      4.001  +3.751052304854505e-10  2.5e-04  4.4e-01  
+    34    37      4.001  +7.625216557423310e-11  9.0e-05  5.1e-01  
+    35    38      4.001  +1.622952431278697e-11  6.6e-05  5.2e-01  
+    36    39      4.001  +7.337759316133232e-12  3.6e-05  2.9e-01  
+    37    40      4.001  +1.484824633556255e-12  1.6e-05  5.6e-01  
+    38    41      4.001  +4.578352609117974e-13  1.2e-05  4.6e-01  
+    39    42      4.001  +9.211331598248391e-14  4.8e-06  4.1e-01  
+    40    43      4.001  +1.831236718906136e-14  2.5e-06  5.5e-01  
+    41    44      4.001  +5.028878022134398e-15  2.4e-07  5.2e-01  
+# op_vmlmb_next: FATOL test satisfied
+#
+#
+# Problem 2 (N=6): Biggs exp6 function.
+# Method 0 (NDIR=6): Limited Memory BFGS (VMLM with NDIR=6)
+#
+# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
+# ---------------------------------------------------------------
+     0     1      0.000  +7.790700756559702e-01  2.6e+00  0.0e+00  
+     1     3      4.000  +6.063399881248565e-01  1.4e+00  1.4e-01  
+     2     4      4.000  +5.345518690614532e-01  1.2e+00  1.0e+00  
+     3     5      4.000  +3.079086646397058e-01  4.0e-01  1.0e+00  
+     4     6      4.000  +2.937191017970756e-01  1.2e-01  1.0e+00  
+     5     7      4.000  +2.921168291268924e-01  3.4e-02  1.0e+00  
+     6     8      4.000  +2.918462455582488e-01  4.3e-02  1.0e+00  
+     7     9      4.000  +2.907755492762679e-01  9.9e-02  1.0e+00  
+     8    10      4.000  +2.881208307389913e-01  1.7e-01  1.0e+00  
+     9    11      4.000  +2.777833991389049e-01  4.6e-01  1.0e+00  
+    10    13      4.000  +2.612679403981057e-01  6.3e-01  5.2e-01  
+    11    14      4.000  +2.469361666977165e-01  9.9e-01  1.0e+00  
+    12    15      4.000  +2.036078330726717e-01  1.0e-00  1.0e+00  
+    13    16      4.000  +7.767306534374016e-02  3.6e-01  3.7e-01  
+    14    17      4.000  +5.174481985556744e-02  2.1e-01  1.0e+00  
+    15    18      4.000  +4.438442687186699e-02  3.2e-02  1.0e+00  
+    16    19      4.000  +4.327020633870218e-02  2.0e-02  1.0e+00  
+    17    20      4.000  +4.270533262117948e-02  2.0e-02  1.0e+00  
+    18    21      4.000  +3.969619752160380e-02  2.1e-01  1.0e+00  
+    19    22      4.000  +3.608256498897430e-02  2.2e-01  1.0e+00  
+    20    23      8.000  +2.496078630339771e-02  8.7e-03  1.0e+00  
+    21    25      8.000  +2.354604949127677e-02  1.2e-01  2.2e-01  
+    22    26      8.000  +1.888593515049183e-02  1.4e-01  1.0e+00  
+    23    27      8.000  +1.155437130469526e-02  7.9e-02  1.0e+00  
+    24    28      8.000  +8.080802739733741e-03  4.6e-02  1.0e+00  
+    25    30      8.000  +7.156021780018340e-03  1.1e-01  4.9e-01  
+    26    31      8.000  +6.273418884507282e-03  7.0e-02  1.0e+00  
+    27    32      8.000  +5.939819199276478e-03  9.8e-03  1.0e+00  
+    28    33      8.000  +5.908026441632852e-03  1.0e-02  1.0e+00  
+    29    35      8.000  +5.859754857684088e-03  1.0e-02  2.8e-02  
+    30    36      8.000  +5.765713460425574e-03  7.4e-03  1.0e+00  
+    31    37      8.000  +5.675434828171089e-03  7.0e-03  1.0e+00  
+    32    38      8.000  +5.657523454643495e-03  3.2e-03  1.0e+00  
+    33    39      8.000  +5.655833463796146e-03  4.4e-04  1.0e+00  
+    34    40      8.000  +5.655671174917713e-03  2.4e-04  1.0e+00  
+    35    42      8.000  +5.655652521284395e-03  1.2e-04  3.3e-01  
+    36    43      8.000  +5.655650195207963e-03  3.0e-05  1.0e+00  
+    37    44     12.000  +5.655649926013700e-03  6.4e-07  1.0e+00  
+    38    45     12.000  +5.655649925527675e-03  2.3e-07  1.0e+00  
+    39    46     12.000  +5.655649925502423e-03  9.0e-08  1.0e+00  
+# op_vmlmb_next: FRTOL test satisfied
+#
+#
+# Problem 3 (N=3): Gaussian function.
+# Method 0 (NDIR=3): Limited Memory BFGS (VMLM with NDIR=3)
+#
+# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
+# ---------------------------------------------------------------
+     0     1      0.000  +3.888106991166885e-06  7.5e-03  0.0e+00  
+     1     2      0.000  +7.716984735720412e-07  3.3e-03  5.8e-04  
+     2     3      0.000  +1.561242789005403e-07  1.4e-03  5.6e-01  
+     3     4      0.000  +3.476004610942878e-08  5.7e-04  6.0e-01  
+     4     5      0.000  +1.232954447864692e-08  9.3e-05  8.4e-01  
+     5     6      0.000  +1.171122486137217e-08  1.1e-05  1.0e+00  
+     6     8      0.000  +1.163182146077833e-08  1.2e-05  5.0e+00  
+     7     9      0.000  +1.130733360163093e-08  1.6e-05  1.0e+00  
+     8    10      0.000  +1.127985527183232e-08  2.7e-06  1.0e+00  
+     9    11      0.000  +1.127932791925235e-08  4.0e-08  1.0e+00  
+    10    12      0.000  +1.127932769618526e-08  8.6e-12  1.0e+00  
+# op_vmlmb_next: FATOL test satisfied
+#
+#
+# Problem 4 (N=2): Powell badly scaled function.
+# Method 0 (NDIR=2): Limited Memory BFGS (VMLM with NDIR=2)
+#
+# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
+# ---------------------------------------------------------------
+     0     1      0.000  +1.135261717348378e+00  2.0e+04  0.0e+00  
+     1     2      0.000  +2.716142498422306e-01  7.4e+03  6.3e-05  
+     2     3      0.000  +1.351881720546067e-01  2.7e-01  1.0e+00  
+     3    14      0.000  +1.347499857711354e-01  1.7e+02  1.4e+06  
+     4    15      0.000  +1.325667967357710e-01  6.0e+02  1.0e+00  
+     5    16      0.000  +1.268168829890248e-01  1.4e+03  1.0e+00  
+     6    17      0.000  +1.130266725138436e-01  2.2e+03  1.0e+00  
+     7    18      0.000  +7.189847553126569e-02  2.1e+03  1.0e+00  
+     8    20      0.000  +6.626840795010225e-02  7.5e+01  3.3e-03  
+     9    21      0.000  +4.050790583682891e-02  5.5e+02  1.0e+00  
+    10    22      0.000  +2.603122017596488e-02  2.9e+03  1.0e+00  
+    11    23      0.000  +1.344335372038092e-02  1.8e+03  8.0e-01  
+    12    24      0.000  +7.754280961808157e-03  1.8e+03  1.0e+00  
+    13    25      0.000  +6.035962443792143e-03  6.0e+02  1.0e+00  
+    14    26      0.000  +3.520105110849622e-03  2.7e+02  1.0e+00  
+    15    27      0.000  +2.370401920922337e-03  1.3e+03  1.0e+00  
+    16    28      0.000  +1.111838810799019e-03  5.4e+02  8.5e-01  
+    17    30      0.000  +7.562658146984992e-04  4.1e+02  4.8e-01  
+    18    31      0.000  +6.291294727585325e-04  7.2e+02  1.0e+00  
+    19    32      0.000  +4.125929545959699e-04  4.0e+02  1.0e+00  
+    20    33      0.000  +2.786252603932807e-04  2.3e+02  1.0e+00  
+    21    34      0.000  +1.865344312220937e-04  6.5e+01  1.0e+00  
+    22    36      0.000  +1.746213097705067e-04  2.7e+02  1.2e-01  
+    23    37      0.000  +1.311007032893237e-04  3.1e+02  1.0e+00  
+    24    38      0.000  +8.604790308724185e-05  9.6e+01  1.0e+00  
+    25    40      0.000  +6.713643137639769e-05  1.5e+02  3.7e-01  
+    26    41      0.000  +6.009576963699230e-05  3.4e+02  1.0e+00  
+    27    42      0.000  +4.592112785957327e-05  1.3e+02  1.0e+00  
+    28    43      0.000  +3.318733434604557e-05  1.3e+02  1.0e+00  
+    29    45      0.000  +3.153928824477498e-05  7.9e-01  2.0e-04  
+    30    46      0.000  +2.316717042185159e-05  1.3e+02  1.0e+00  
+    31    47      0.000  +1.983842227523587e-05  1.8e+02  1.0e+00  
+    32    48      0.000  +1.370511800174228e-05  1.2e+02  1.0e+00  
+    33    50      0.000  +1.002231977553119e-05  2.0e+01  3.7e-01  
+    34    52      4.001  +9.448845461709604e-06  7.8e+01  3.1e-01  
+    35    53      4.001  +8.796547092034665e-06  8.8e+01  1.0e+00  
+    36    54      4.001  +6.012203046585967e-06  3.7e+00  1.0e+00  
+    37    56      4.001  +5.591031631209653e-06  5.2e+01  2.2e-01  
+    38    57      4.001  +5.042798867261178e-06  8.1e+01  1.0e+00  
+    39    58      4.001  +4.037916381025496e-06  4.9e+01  1.0e+00  
+    40    59      4.001  +3.325226275541043e-06  2.6e+01  1.0e+00  
+    41    61      4.001  +3.145813424606391e-06  5.4e+01  2.7e-01  
+    42    62      4.001  +2.620153892100086e-06  5.5e+01  1.0e+00  
+    43    64      4.001  +2.415748503691216e-06  2.5e+00  2.2e-02  
+    44    65      4.001  +2.007550819175101e-06  3.0e+01  1.0e+00  
+    45    67      4.001  +1.890695485188910e-06  5.1e+01  4.5e-01  
+    46    68      4.001  +1.536361962738215e-06  3.0e+01  1.0e+00  
+    47    69      4.001  +1.311168885938422e-06  2.0e+01  1.0e+00  
+    48    70      4.001  +1.246078119694974e-06  4.5e+01  1.0e+00  
+    49    72      4.001  +9.491335127465187e-07  7.2e+00  3.3e-01  
+    50    74      4.001  +8.891242770948279e-07  2.8e+01  6.9e-02  
+    51    75      4.001  +8.700737460692882e-07  1.9e+01  1.0e+00  
+    52    76      4.001  +7.774251370222714e-07  7.0e+00  1.0e+00  
+    53    78      4.001  +7.054120977646890e-07  1.4e+01  3.9e-01  
+    54    80      4.001  +6.079579263162548e-07  2.2e+01  3.9e-01  
+    55    81      4.001  +4.495947084220561e-07  1.7e+01  1.0e+00  
+    56    83      4.001  +3.956164009642611e-07  6.9e+00  5.9e-02  
+    57    85      4.001  +3.842041614956623e-07  1.6e+01  4.7e-01  
+    58    86      4.001  +3.650291414806386e-07  2.0e+01  1.0e+00  
+    59    87      4.001  +2.977310422144736e-07  1.0e+01  1.0e+00  
+    60    88      4.001  +2.645228220544150e-07  8.7e+00  1.0e+00  
+    61    90      4.001  +2.625753218665754e-07  2.1e+00  1.3e-02  
+    62    92      4.001  +2.351392468128754e-07  7.8e+00  5.3e-01  
+    63    94      4.001  +2.228437274607579e-07  1.5e+01  3.0e-01  
+    64    95      4.001  +1.908884988619849e-07  1.6e+01  1.0e+00  
+    65    97      4.001  +1.775213596206642e-07  1.5e+00  7.7e-02  
+    66    98      4.001  +1.563404116641290e-07  9.7e+00  1.0e+00  
+    67   100      4.001  +1.512029496166810e-07  1.4e+01  4.4e-01  
+    68   101      4.001  +1.307607535470326e-07  9.5e+00  1.0e+00  
+    69   102      4.001  +1.175169650897558e-07  2.0e+00  1.0e+00  
+    70   104      4.001  +1.072392194161219e-07  5.1e+00  2.9e-01  
+    71   106      4.001  +1.037392963035747e-07  9.8e+00  2.9e-01  
+    72   107      4.001  +9.620878417591773e-08  1.0e+01  1.0e+00  
+    73   109      4.001  +9.039151653346654e-08  1.6e+00  8.0e-02  
+    74   110      4.001  +8.006176991138113e-08  8.3e+00  1.0e+00  
+    75   111      4.001  +7.595885339417243e-08  1.0e+01  1.0e+00  
+    76   112      4.001  +6.314410560360231e-08  4.1e-01  1.0e+00  
+    77   114      4.001  +6.008323382664185e-08  5.3e+00  2.6e-01  
+    78   115      4.001  +5.774858820209131e-08  1.1e+01  1.0e+00  
+    79   116      4.001  +5.227214564981060e-08  4.5e+00  1.0e+00  
+    80   117      4.001  +4.671286653797208e-08  7.9e+00  1.0e+00  
+    81   118      4.001  +4.218605795772740e-08  4.0e+00  1.0e+00  
+    82   120      4.001  +3.978787254803439e-08  7.2e+00  5.2e-01  
+    83   121      4.001  +3.475025245891024e-08  4.6e+00  1.0e+00  
+    84   122      4.001  +3.131608455766981e-08  8.5e-01  1.0e+00  
+    85   124      4.001  +2.975290789910577e-08  4.2e+00  1.9e-01  
+    86   125      4.001  +2.844598223236710e-08  8.2e+00  1.0e+00  
+    87   126      4.001  +2.529667836942072e-08  2.4e+00  1.0e+00  
+    88   127      4.001  +2.285266654491062e-08  5.8e+00  1.0e+00  
+    89   128      4.001  +2.110270876321310e-08  3.4e+00  1.0e+00  
+    90   130      4.001  +1.982830112972024e-08  4.6e+00  4.7e-01  
+    91   131      4.001  +1.556088550165383e-08  1.6e-01  1.0e+00  
+    92   133      4.001  +1.509931751153993e-08  2.7e+00  1.1e-01  
+    93   134      4.001  +1.441420778804029e-08  3.7e+00  1.0e+00  
+    94   135      4.001  +1.303715234141585e-08  4.6e+00  1.0e+00  
+    95   137      4.001  +1.183143970298517e-08  1.5e+00  1.6e-01  
+    96   139      4.001  +1.083047880278837e-08  4.3e-01  4.4e-01  
+    97   141      4.001  +1.033931695032363e-08  3.5e+00  1.4e-01  
+    98   142      4.001  +9.955899460561576e-09  2.8e+00  1.0e+00  
+    99   143      4.001  +8.883196616290377e-09  4.3e+00  1.0e+00  
+   100   145      4.001  +7.742742776189192e-09  2.1e+00  2.7e-01  
+   101   147      4.001  +6.834754461132445e-09  9.3e-01  4.0e-01  
+   102   149      4.001  +6.666959323631201e-09  2.3e+00  1.9e-01  
+   103   150      4.001  +6.411180662499273e-09  2.8e+00  1.0e+00  
+   104   151      4.001  +5.435981187381998e-09  2.0e+00  1.0e+00  
+   105   153      4.001  +5.283745805222238e-09  1.1e-01  2.0e-01  
+   106   154      4.001  +4.667635231009192e-09  2.4e+00  1.0e+00  
+   107   155      4.001  +4.374389490301682e-09  2.4e+00  1.0e+00  
+   108   157      8.001  +4.163941820284297e-09  7.6e-02  1.3e-02  
+   109   158      8.001  +3.677160794243351e-09  1.7e+00  1.0e+00  
+   110   160      8.001  +3.556463460936755e-09  2.4e+00  4.1e-01  
+   111   161      8.001  +3.036430367400247e-09  1.7e+00  1.0e+00  
+   112   162      8.001  +2.784362981880398e-09  1.2e+00  1.0e+00  
+   113   164      8.001  +2.406505899582082e-09  6.4e-01  4.2e-01  
+   114   166      8.001  +2.340080591653236e-09  1.5e+00  1.6e-01  
+   115   167      8.001  +2.232707735696947e-09  1.8e+00  1.0e+00  
+   116   168      8.001  +1.807669675248058e-09  8.9e-01  1.0e+00  
+   117   169      8.001  +1.621579861725144e-09  1.5e+00  1.0e+00  
+   118   171      8.001  +1.260526356088865e-09  4.8e-01  3.1e-01  
+   119   173      8.001  +1.158748732953299e-09  1.3e+00  1.3e-01  
+   120   174      8.001  +1.091888811725686e-09  1.0e+00  1.0e+00  
+   121   175      8.001  +9.252174759540841e-10  1.4e+00  1.0e+00  
+   122   177      8.001  +8.177332024184264e-10  5.0e-01  7.1e-02  
+   123   180      8.001  +6.877682728262519e-10  9.4e-01  6.3e-01  
+   124   181      8.001  +6.521162246605309e-10  1.4e+00  1.0e+00  
+   125   182      8.001  +5.245455884270034e-10  5.8e-01  1.0e+00  
+   126   183      8.001  +4.740039908668378e-10  1.4e+00  1.0e+00  
+   127   184      8.001  +3.675734148905452e-10  1.5e-01  1.0e+00  
+   128   186      8.001  +3.278212930002444e-10  7.1e-01  4.5e-01  
+   129   187      8.001  +2.991826277801766e-10  1.1e+00  1.0e+00  
+   130   188      8.001  +2.261615323913900e-10  2.1e-01  1.0e+00  
+   131   190      8.001  +1.996749791891283e-10  6.8e-01  5.4e-01  
+   132   191      8.001  +1.748408381668149e-10  7.5e-01  1.0e+00  
+   133   193      8.001  +1.441186976349858e-10  2.6e-01  3.3e-01  
+   134   195      8.001  +1.168134759399082e-10  1.2e-01  5.0e-01  
+   135   197      8.001  +1.065919364144133e-10  4.5e-01  1.6e-01  
+   136   198      8.001  +9.624408438738366e-11  5.9e-01  1.0e+00  
+   137   199      8.001  +6.522624230099676e-11  2.6e-01  1.0e+00  
+   138   200      8.001  +5.382979150929681e-11  5.4e-01  1.0e+00  
+   139   201      8.001  +2.357595065249005e-11  5.6e-02  9.4e-01  
+   140   203      8.001  +2.194863217396652e-11  2.2e-01  2.0e-01  
+   141   204      8.001  +1.824678260827043e-11  2.6e-01  1.0e+00  
+   142   205      8.001  +1.007427717509816e-11  1.8e-01  1.0e+00  
+   143   207      8.001  +9.240366653486143e-12  1.5e-02  1.2e-01  
+   144   208      8.001  +5.277029415816368e-12  1.3e-01  1.0e+00  
+   145   209      8.001  +4.150258646119530e-12  2.7e-01  1.0e+00  
+   146   210      8.001  +1.419227552276263e-12  3.3e-02  6.6e-01  
+   147   211      8.001  +6.157107277445726e-13  6.3e-02  1.0e+00  
+   148   212      8.001  +2.164773422247019e-13  5.5e-02  1.0e+00  
+   149   213      8.001  +1.645865002459103e-13  2.4e-02  3.0e-02  
+   150   214      8.001  +3.516759308772241e-14  4.5e-03  8.8e-01  
+   151   215      8.001  +1.152075456477990e-14  1.4e-02  7.0e-01  
+# op_vmlmb_next: FATOL test satisfied
+#
+#
+# Problem 5 (N=3): Box 3-dimensional function.
+# Method 0 (NDIR=3): Limited Memory BFGS (VMLM with NDIR=3)
+#
+# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
+# ---------------------------------------------------------------
+     0     1      0.000  +1.031153810609398e+03  1.5e+02  0.0e+00  
+     1     4      0.000  +5.051751883930287e+02  1.4e+02  3.2e+00  
+     2     7      0.000  +4.693698123274796e+02  6.3e+01  9.6e-03  
+     3     8      0.000  +4.196780145077672e+02  7.3e+01  1.0e+00  
+     4     9      0.000  +9.577851908664192e+01  7.3e+01  6.4e-01  
+     5    10      0.000  +2.963077540829067e+01  6.2e+01  8.2e-01  
+     6    11      0.000  +1.472450551152400e+01  1.0e+01  1.3e-01  
+     7    12      0.000  +4.692489499264585e+00  1.1e+01  9.0e-01  
+     8    13      0.000  +2.930070582447900e+00  9.1e+00  1.0e+00  
+     9    14      0.000  +1.626093588037745e+00  5.9e+00  1.0e+00  
+    10    15      0.000  +6.607304557529599e-01  1.5e+00  1.0e+00  
+    11    16      0.000  +2.360905443567035e-01  1.2e+00  1.0e+00  
+    12    17      0.000  +9.771929015861618e-02  7.4e-01  1.0e+00  
+    13    18      4.000  +2.921048390382599e-02  3.1e-01  1.0e+00  
+    14    19      4.000  +7.162028854070950e-03  1.4e-01  1.0e+00  
+    15    20      4.000  +1.918627248183639e-03  3.8e-02  8.5e-01  
+    16    21      4.000  +5.706147462900988e-04  4.1e-02  5.0e-01  
+    17    22      4.000  +1.767122289515497e-04  5.9e-03  6.7e-01  
+    18    23      4.000  +1.388438676986920e-04  1.1e-03  1.0e+00  
+    19    24      4.000  +1.380987151663160e-04  1.5e-03  1.0e+00  
+    20    25      4.000  +1.375596494219131e-04  1.6e-03  1.0e+00  
+    21    26      4.000  +1.348123100471587e-04  2.7e-03  1.0e+00  
+    22    27      4.000  +1.273751593447703e-04  2.4e-03  1.0e+00  
+    23    29      4.000  +1.236844681639359e-04  8.5e-03  3.4e-01  
+    24    30      4.000  +1.111624159031401e-04  6.1e-03  1.0e+00  
+    25    31      4.000  +7.709438714814043e-05  4.2e-03  1.0e+00  
+    26    32      4.000  +3.555022908765118e-05  5.5e-03  1.0e+00  
+    27    33      4.000  +1.388449576270083e-05  1.2e-02  8.4e-01  
+    28    34      4.000  +3.499447500852135e-06  4.8e-03  2.5e-01  
+    29    35      4.000  +7.802810396086031e-07  1.7e-03  7.4e-01  
+    30    36      4.000  +1.797026655239720e-07  4.0e-04  6.9e-01  
+    31    37      4.000  +4.113226590053436e-08  1.4e-04  6.9e-01  
+    32    38      4.000  +1.170488139789506e-08  6.3e-06  5.5e-01  
+    33    39      4.000  +8.860893531384294e-09  2.9e-04  7.0e-01  
+    34    40      4.000  +3.295705185007528e-09  6.7e-05  1.0e+00  
+    35    41      4.000  +1.824061308183375e-09  2.4e-05  1.0e+00  
+    36    42      4.000  +4.894303628176848e-10  4.1e-05  8.8e-01  
+    37    43      4.000  +1.063838077120574e-10  2.6e-05  7.7e-01  
+    38    44      4.000  +2.936005901492016e-11  4.7e-06  4.7e-01  
+    39    45      4.000  +7.520001768792375e-12  1.9e-06  6.8e-01  
+    40    46      4.000  +3.232186206428190e-12  2.7e-06  1.0e+00  
+    41    47      4.000  +2.382259476974284e-12  7.7e-07  1.0e+00  
+    42    48      4.000  +1.627836101802466e-12  7.8e-07  1.0e+00  
+    43    49      4.000  +8.722135008897642e-13  1.8e-06  1.0e+00  
+    44    50      4.000  +3.181054605846769e-13  1.3e-06  1.0e+00  
+    45    51      4.000  +1.819403692094123e-13  5.7e-07  1.0e+00  
+    46    52      4.000  +1.552379827036547e-13  2.8e-07  1.0e+00  
+# op_vmlmb_next: FATOL test satisfied
+#
+#
+# Problem 6 (N=10): Variably dimensioned function.
+# Method 0 (NDIR=10): Limited Memory BFGS (VMLM with NDIR=10)
+#
+# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
+# ---------------------------------------------------------------
+     0     1      0.000  +2.198551162500000e+06  4.5e+06  0.0e+00  
+     1     2      0.000  +5.982233536014224e+05  1.7e+06  5.5e-01  
+     2     3      0.000  +2.077189332476444e+05  7.6e+05  1.0e+00  
+     3     4      4.000  +6.578142669110338e+04  3.2e+05  1.0e+00  
+     4     5      4.000  +2.160249233159776e+04  1.4e+05  1.0e+00  
+     5     6      4.000  +7.004735376311746e+03  6.0e+04  1.0e+00  
+     6     7      4.000  +2.287386781801080e+03  2.6e+04  1.0e+00  
+     7     8      4.000  +7.476983219073760e+02  1.1e+04  1.0e+00  
+     8     9      4.000  +2.458538169695109e+02  4.8e+03  1.0e+00  
+     9    10      4.000  +8.149749297306352e+01  2.1e+03  1.0e+00  
+    10    11      4.000  +2.737280609091122e+01  9.0e+02  1.0e+00  
+    11    12      4.000  +9.362878818503740e+00  3.9e+02  1.0e+00  
+    12    13      4.000  +3.269284473674885e+00  1.7e+02  1.0e+00  
+    13    14      4.000  +1.153504000090763e+00  7.7e+01  1.0e+00  
+    14    15      4.000  +3.936136413645998e-01  3.5e+01  1.0e+00  
+    15    16      4.000  +1.147737756239351e-01  1.5e+01  1.0e+00  
+    16    17      4.000  +2.581587916978744e-02  6.5e+00  9.1e-01  
+    17    18      4.000  +5.303642148696754e-03  2.9e+00  7.0e-01  
+    18    19      4.000  +1.056848632834968e-03  1.3e+00  5.9e-01  
+    19    20      4.000  +2.091314644328269e-04  5.7e-01  5.6e-01  
+    20    21      4.000  +4.132449788388705e-05  2.5e-01  5.6e-01  
+    21    22      4.000  +8.163433357518874e-06  1.1e-01  5.6e-01  
+    22    23      4.000  +1.612552275601864e-06  5.0e-02  5.6e-01  
+    23    24      4.000  +3.185297119742180e-07  2.2e-02  5.6e-01  
+    24    25      4.000  +6.291948312422135e-08  9.9e-03  5.6e-01  
+    25    26      4.000  +1.242854119682474e-08  4.4e-03  5.6e-01  
+    26    27      4.000  +2.455020534958202e-09  1.9e-03  5.6e-01  
+    27    28      4.000  +4.849423299090284e-10  8.7e-04  5.6e-01  
+    28    29      4.000  +9.579107757034683e-11  3.8e-04  5.6e-01  
+    29    30      4.000  +1.892169434557917e-11  1.7e-04  5.6e-01  
+    30    31      4.000  +3.737618638352018e-12  7.6e-05  5.6e-01  
+    31    32      4.000  +7.382950396510434e-13  3.4e-05  5.6e-01  
+    32    33      4.000  +1.458360569885202e-13  1.5e-05  5.6e-01  
+    33    34      4.000  +2.880712217942045e-14  6.7e-06  5.6e-01  
+    34    35      4.000  +5.690295862135377e-15  3.0e-06  5.6e-01  
+# op_vmlmb_next: FATOL test satisfied
+#
+#
+# Problem 7 (N=6): Watson function.
+# Method 0 (NDIR=6): Limited Memory BFGS (VMLM with NDIR=6)
+#
+# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
+# ---------------------------------------------------------------
+     0     1      0.000  +3.000000000000000e+01  1.4e+02  0.0e+00  
+     1     2      0.000  +1.153491761608158e+01  3.6e+01  2.4e-01  
+     2     3      0.000  +8.662294302946657e+00  2.7e+01  1.0e+00  
+     3     4      0.000  +2.159765745956006e+00  1.3e+01  1.0e+00  
+     4     5      0.000  +9.370932269174013e-01  9.6e+00  6.9e-01  
+     5     6      0.000  +6.260360367334762e-01  2.7e+00  1.0e+00  
+     6     7      0.000  +5.588208440197413e-01  2.9e+00  1.0e+00  
+     7     8      0.000  +4.320129246513010e-01  4.0e+00  1.0e+00  
+     8     9      0.000  +1.782329757356047e-01  4.6e+00  1.0e+00  
+     9    10      4.001  +4.357179339744174e-02  1.6e+00  6.4e-01  
+    10    11      4.001  +2.446191487403206e-02  4.8e-01  1.0e+00  
+    11    12      4.001  +2.250413138430174e-02  3.4e-01  1.0e+00  
+    12    13      4.001  +2.111722399878381e-02  5.5e-01  1.0e+00  
+    13    14      4.001  +1.606205485982599e-02  8.0e-01  1.0e+00  
+    14    16      8.001  +1.060663387077928e-02  1.8e-01  5.1e-01  
+    15    17      8.001  +1.023711762982278e-02  2.1e-01  1.0e+00  
+    16    18      8.001  +1.014232386791980e-02  2.5e-02  1.0e+00  
+    17    19      8.001  +1.012808413731048e-02  3.0e-02  1.0e+00  
+    18    20      8.001  +1.011416301337225e-02  1.9e-02  1.0e+00  
+    19    21     12.001  +1.010622490501859e-02  1.7e-02  1.0e+00  
+    20    22     12.001  +1.005354212767259e-02  2.5e-02  1.0e+00  
+    21    23     12.001  +9.914998965299265e-03  4.3e-02  1.0e+00  
+    22    24     12.001  +9.633255378335592e-03  5.2e-02  1.0e+00  
+    23    25     12.001  +9.435981241419105e-03  3.2e-01  1.0e+00  
+    24    26     12.001  +9.074119841420146e-03  9.2e-02  1.0e+00  
+    25    27     16.001  +8.948864483207091e-03  2.6e-02  1.0e+00  
+    26    28     16.001  +8.942033313705005e-03  9.7e-03  1.0e+00  
+    27    29     16.001  +8.940317436619535e-03  7.6e-03  1.0e+00  
+    28    30     16.001  +8.936673299222047e-03  1.6e-02  1.0e+00  
+    29    31     16.001  +8.932411285273037e-03  2.3e-02  1.0e+00  
+    30    32     16.001  +8.923876594747306e-03  2.4e-02  1.0e+00  
+    31    34     20.002  +8.919738995782814e-03  6.0e-02  1.4e-01  
+    32    35     20.002  +8.900791041922290e-03  5.2e-02  1.0e+00  
+    33    36     20.002  +8.821982716914249e-03  5.8e-02  1.0e+00  
+    34    37     20.002  +8.676125612127840e-03  4.9e-02  1.0e+00  
+    35    38     20.002  +8.443320768310978e-03  3.1e-01  1.0e+00  
+    36    39     24.002  +7.962339610876239e-03  1.2e-01  1.0e+00  
+    37    40     24.002  +7.700051635114865e-03  9.5e-02  1.0e+00  
+    38    41     24.002  +7.564775888244103e-03  9.7e-02  1.0e+00  
+    39    43     24.002  +7.490280990021314e-03  2.0e-01  8.1e-02  
+    40    44     24.002  +7.225853155050442e-03  1.1e-01  1.0e+00  
+    41    45     28.002  +7.027986857610604e-03  6.7e-02  1.0e+00  
+    42    46     28.002  +6.898992549696143e-03  1.2e-01  1.0e+00  
+    43    47     28.002  +6.696669267370094e-03  1.1e-01  1.0e+00  
+    44    48     28.002  +6.521394247682940e-03  3.6e-01  1.0e+00  
+    45    49     28.002  +5.900564228855348e-03  1.5e-01  1.0e+00  
+    46    50     28.002  +5.436162501033610e-03  1.2e-01  1.0e+00  
+    47    51     32.002  +5.185527792214816e-03  1.9e-01  1.0e+00  
+    48    52     32.002  +4.977046075759494e-03  1.4e-01  1.0e+00  
+    49    53     32.002  +4.658566016994147e-03  7.2e-02  1.0e+00  
+    50    54     32.002  +4.308711947089532e-03  1.0e-01  1.0e+00  
+    51    55     32.002  +3.919697403900082e-03  1.9e-01  1.0e+00  
+    52    56     32.002  +3.280783714973028e-03  1.9e-01  1.0e+00  
+    53    57     36.003  +2.520432499557056e-03  1.6e-01  1.0e+00  
+    54    59     36.003  +2.457626981592080e-03  1.4e-01  2.8e-02  
+    55    60     36.003  +2.311981662769732e-03  5.2e-02  1.0e+00  
+    56    61     36.003  +2.289345802013666e-03  6.1e-03  1.0e+00  
+    57    62     36.003  +2.288985893595373e-03  2.9e-03  1.0e+00  
+    58    63     40.003  +2.288455672536768e-03  2.7e-03  1.0e+00  
+    59    64     40.003  +2.287793236670549e-03  1.9e-03  1.0e+00  
+    60    65     40.003  +2.287695261121659e-03  1.5e-03  1.0e+00  
+    61    67     40.003  +2.287684367911231e-03  6.3e-04  4.8e-01  
+    62    68     40.003  +2.287676176945362e-03  3.6e-04  1.0e+00  
+    63    70     44.003  +2.287675098559974e-03  2.0e-04  3.4e-01  
+    64    71     44.003  +2.287673953644514e-03  6.5e-05  1.0e+00  
+    65    72     44.003  +2.287673573776456e-03  5.8e-05  1.0e+00  
+    66    73     44.003  +2.287672636686810e-03  1.3e-04  1.0e+00  
+    67    74     44.003  +2.287671819591959e-03  1.5e-04  1.0e+00  
+    68    76     48.003  +2.287671215406123e-03  3.4e-04  3.9e-01  
+    69    77     48.003  +2.287670175158950e-03  7.6e-05  1.0e+00  
+    70    78     48.003  +2.287670069963467e-03  3.0e-05  1.0e+00  
+    71    79     48.003  +2.287670055842873e-03  1.1e-05  1.0e+00  
+    72    80     48.003  +2.287670054951157e-03  7.6e-06  1.0e+00  
+    73    81     52.004  +2.287670054462369e-03  2.6e-06  1.0e+00  
+    74    82     52.004  +2.287670054258627e-03  1.8e-06  1.0e+00  
+    75    83     52.004  +2.287670053768855e-03  4.4e-06  1.0e+00  
+    76    85     52.004  +2.287670053701440e-03  2.1e-06  3.5e-01  
+# op_vmlmb_next: FRTOL test satisfied
+#
+#
+# Problem 8 (N=10): Penalty function I.
+# Method 0 (NDIR=10): Limited Memory BFGS (VMLM with NDIR=10)
+#
+# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
+# ---------------------------------------------------------------
+     0     1      0.000  +1.480325653500000e+05  3.0e+04  0.0e+00  
+     1     2      0.000  +1.200672187926850e+05  2.6e+04  1.0e+00  
+     2     3      0.000  +3.265992616691508e+04  9.7e+03  8.8e-01  
+     3     4      0.000  +1.132290692299289e+04  4.4e+03  1.0e+00  
+     4     5      0.000  +3.577134652544013e+03  1.9e+03  1.0e+00  
+     5     6      0.000  +1.169681852985238e+03  8.0e+02  1.0e+00  
+     6     7      0.000  +3.764229133643723e+02  3.4e+02  1.0e+00  
+     7     8      4.000  +1.213086610658549e+02  1.5e+02  1.0e+00  
+     8     9      4.000  +3.874731549111131e+01  6.3e+01  1.0e+00  
+     9    10      4.000  +1.223737772730658e+01  2.7e+01  1.0e+00  
+    10    11      4.000  +3.782057667252822e+00  1.2e+01  1.0e+00  
+    11    12      4.000  +1.125513580941122e+00  4.9e+00  1.0e+00  
+    12    13      4.000  +3.129446120087767e-01  2.0e+00  1.0e+00  
+    13    14      4.000  +7.756206235205798e-02  8.1e-01  1.0e-00  
+    14    15      4.000  +1.827422007113406e-02  3.3e-01  9.2e-01  
+    15    16      4.000  +4.085118985926949e-03  1.4e-01  8.1e-01  
+    16    17      4.000  +8.877332480334356e-04  6.0e-02  7.2e-01  
+    17    18      4.000  +2.065403882446298e-04  2.4e-02  6.9e-01  
+    18    19      4.000  +7.703710321289555e-05  3.2e-03  9.3e-01  
+    19    20      4.000  +7.446943015394475e-05  1.1e-04  1.0e+00  
+    20    21      4.000  +7.446618591447701e-05  2.9e-05  1.0e+00  
+    21    23      4.000  +7.446415870380601e-05  5.2e-05  5.0e+00  
+    22    24      4.000  +7.445657592228791e-05  1.2e-04  1.0e+00  
+    23    25      4.000  +7.442752521815094e-05  2.8e-04  1.0e+00  
+    24    26      4.000  +7.434003956432855e-05  5.2e-04  1.0e+00  
+    25    29      4.000  +7.349631102481636e-05  6.1e-04  5.9e-01  
+    26    31      4.000  +7.349026117318990e-05  4.7e-04  2.2e-01  
+    27    33      4.000  +7.331713301296246e-05  4.0e-04  5.0e+00  
+    28    35      4.000  +7.310908109664723e-05  5.5e-04  4.7e-01  
+    29    36      4.000  +7.281998859159809e-05  8.1e-04  1.0e+00  
+    30    37      4.000  +7.250779119403938e-05  2.0e-04  1.0e+00  
+    31    39      4.000  +7.230694011645983e-05  2.8e-04  3.9e-01  
+    32    41      4.000  +7.225525250357204e-05  5.3e-04  2.7e-01  
+    33    42      4.000  +7.216099121388021e-05  5.7e-04  1.0e+00  
+    34    43      4.000  +7.193027784341741e-05  4.0e-04  1.0e+00  
+    35    44      4.000  +7.175919696417940e-05  1.9e-04  1.0e+00  
+    36    46      4.000  +7.170723123651528e-05  4.2e-04  2.5e-01  
+    37    47      4.000  +7.158287428953024e-05  7.8e-04  1.0e+00  
+    38    48      4.000  +7.144374877244074e-05  2.2e-04  1.0e+00  
+    39    49      4.000  +7.133466251468262e-05  1.7e-04  1.0e+00  
+    40    51      4.000  +7.131147537304108e-05  3.4e-04  2.7e-01  
+    41    52      4.000  +7.127028433699874e-05  3.7e-04  1.0e+00  
+    42    53      4.000  +7.117077758835362e-05  2.6e-04  1.0e+00  
+    43    54      4.000  +7.110140571775857e-05  9.8e-05  1.0e+00  
+    44    56      4.000  +7.108040834207843e-05  2.5e-04  2.2e-01  
+    45    57      4.000  +7.103394859713061e-05  3.8e-04  1.0e+00  
+    46    58      4.000  +7.098405566611185e-05  1.8e-05  1.0e+00  
+    47    59      4.000  +7.095277805502977e-05  2.3e-04  1.0e+00  
+    48    60      4.000  +7.093698079764311e-05  1.3e-04  1.0e+00  
+    49    62      4.000  +7.092411497593044e-05  1.6e-04  3.6e-01  
+    50    63      4.000  +7.090081388960589e-05  8.4e-05  1.0e+00  
+    51    64      4.000  +7.089092762586513e-05  7.5e-05  1.0e+00  
+    52    65      4.000  +7.088414527104555e-05  8.0e-05  1.0e+00  
+    53    67      4.000  +7.087881487192198e-05  7.0e-06  1.7e-01  
+    54    69      4.000  +7.087808649792271e-05  4.1e-05  4.0e-01  
+    55    70      8.000  +7.087756682229364e-05  3.7e-05  1.0e+00  
+    56    71      8.000  +7.087666490410433e-05  6.3e-06  1.0e+00  
+    57    72      8.000  +7.087654244772589e-05  9.0e-06  1.0e+00  
+    58    73      8.000  +7.087651609138998e-05  1.9e-06  1.0e+00  
+    59    74      8.000  +7.087651467883146e-05  1.2e-07  1.0e+00  
+    60    75      8.000  +7.087651467090616e-05  2.6e-09  1.0e+00  
+# op_vmlmb_next: FATOL test satisfied
+#
+#
+# Problem 9 (N=10): Penalty function II.
+# Method 0 (NDIR=10): Limited Memory BFGS (VMLM with NDIR=10)
+#
+# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
+# ---------------------------------------------------------------
+     0     1      0.000  +1.626527765659671e+02  5.0e+02  0.0e+00  
+     1     2      0.000  +4.478644776655588e+01  1.9e+02  3.6e-01  
+     2     3      0.000  +1.567407090737728e+01  8.6e+01  1.0e+00  
+     3     4      0.000  +4.595268667402950e+00  3.5e+01  1.0e+00  
+     4     5      0.000  +1.269158916418052e+00  1.5e+01  1.0e+00  
+     5     6      0.000  +3.110713197933571e-01  5.8e+00  9.7e-01  
+     6     7      0.000  +7.571688000474813e-02  2.3e+00  9.0e-01  
+     7     8      0.000  +2.213120188520761e-02  6.8e-01  9.4e-01  
+     8     9      0.000  +1.485561199109297e-02  2.3e-01  1.0e+00  
+     9    10      0.000  +1.306075025095904e-02  2.3e-01  1.0e+00  
+    10    11      0.000  +8.330391266572293e-03  2.9e-01  1.0e+00  
+    11    12      0.000  +2.118643374119330e-03  1.6e-01  5.4e-01  
+    12    13      0.000  +1.676859414703804e-03  2.0e-01  1.0e+00  
+    13    14      0.000  +6.085265554844259e-04  7.2e-02  1.0e+00  
+    14    15      0.000  +3.602520091513869e-04  2.9e-02  1.0e+00  
+    15    16      0.000  +3.000429994250958e-04  1.2e-02  1.0e+00  
+    16    17      0.000  +2.942768976757234e-04  1.9e-03  1.0e+00  
+    17    18      0.000  +2.941190006037160e-04  2.6e-03  1.0e+00  
+    18    19      0.000  +2.940276365124544e-04  4.2e-05  1.0e+00  
+    19    20      0.000  +2.940276143217213e-04  7.9e-06  1.0e+00  
+    20    22      0.000  +2.940276088743079e-04  1.3e-05  5.0e+00  
+    21    23      0.000  +2.940275674459129e-04  4.1e-05  1.0e+00  
+    22    24      0.000  +2.940274684490467e-04  8.4e-05  1.0e+00  
+    23    25      0.000  +2.940272019219013e-04  1.6e-04  1.0e+00  
+    24    26      0.000  +2.940265308678704e-04  2.7e-04  1.0e+00  
+    25    27      0.000  +2.940249257417753e-04  4.6e-04  1.0e+00  
+    26    28      0.000  +2.940218267746400e-04  7.0e-04  1.0e+00  
+    27    29      0.000  +2.940167114119969e-04  9.1e-04  1.0e+00  
+    28    30      0.000  +2.940057396280275e-04  1.0e-03  1.0e+00  
+    29    31      0.000  +2.939847652858170e-04  6.7e-04  1.0e+00  
+    30    32      0.000  +2.939671940695009e-04  3.5e-04  1.0e+00  
+    31    34      4.000  +2.939605724251989e-04  7.1e-04  3.6e-01  
+    32    35      4.000  +2.939456480560964e-04  1.3e-03  1.0e+00  
+    33    36      4.000  +2.939328151552932e-04  8.5e-04  1.0e+00  
+    34    37      4.000  +2.939141108236152e-04  2.0e-04  1.0e+00  
+    35    39      4.000  +2.939111211303367e-04  5.4e-04  3.7e-01  
+    36    40      4.000  +2.939053168820111e-04  6.0e-04  1.0e+00  
+    37    41      4.000  +2.938883629324550e-04  6.3e-04  1.0e+00  
+    38    42      4.000  +2.938747221912601e-04  2.5e-05  1.0e+00  
+    39    44      4.000  +2.938682139412850e-04  4.2e-04  2.0e-01  
+    40    46      4.000  +2.938639778872194e-04  7.4e-04  5.2e-01  
+    41    47      4.000  +2.938560543957402e-04  6.0e-04  1.0e+00  
+    42    48      4.000  +2.938431790575485e-04  1.9e-04  1.0e+00  
+    43    50      4.000  +2.938394172992321e-04  5.0e-04  1.9e-01  
+    44    51      4.000  +2.938332461245707e-04  9.1e-04  1.0e+00  
+    45    52      4.000  +2.938232087891656e-04  9.5e-05  1.0e+00  
+    46    53      4.000  +2.938162192572837e-04  3.1e-04  1.0e+00  
+    47    54      4.000  +2.938134286486824e-04  7.5e-04  1.0e+00  
+    48    55      4.000  +2.938046050490839e-04  1.2e-04  1.0e+00  
+    49    56      4.000  +2.937958615389975e-04  2.5e-04  1.0e+00  
+    50    58      4.000  +2.937915280165045e-04  5.2e-04  4.3e-01  
+    51    59      4.000  +2.937829339096076e-04  3.9e-04  1.0e+00  
+    52    60      4.000  +2.937787756979532e-04  1.2e-04  1.0e+00  
+    53    62      4.000  +2.937767478240379e-04  3.5e-04  2.1e-01  
+    54    63      4.000  +2.937740704182577e-04  5.8e-04  1.0e+00  
+    55    64      4.000  +2.937692673453995e-04  3.0e-04  1.0e+00  
+    56    66      4.000  +2.937653648012842e-04  4.2e-04  4.6e-01  
+    57    67      4.000  +2.937586070665360e-04  6.9e-04  1.0e+00  
+    58    69      4.000  +2.937544459124473e-04  8.5e-05  4.5e-01  
+    59    70      4.000  +2.937530885438273e-04  1.3e-04  1.0e+00  
+    60    72      4.000  +2.937500033638618e-04  3.4e-04  4.1e-01  
+    61    73      8.001  +2.937462650101101e-04  4.1e-04  1.0e+00  
+    62    74      8.001  +2.937436103075173e-04  7.7e-05  1.0e+00  
+    63    76      8.001  +2.937411292974525e-04  1.1e-04  4.1e-01  
+    64    78      8.001  +2.937396821963436e-04  3.1e-04  1.7e-01  
+    65    79      8.001  +2.937381391529797e-04  3.8e-04  1.0e+00  
+    66    80      8.001  +2.937365816728961e-04  1.4e-04  1.0e+00  
+    67    81      8.001  +2.937347185972254e-04  2.4e-04  1.0e+00  
+    68    82      8.001  +2.937318532989324e-04  3.7e-04  1.0e+00  
+    69    83      8.001  +2.937287934342775e-04  4.3e-05  1.0e+00  
+    70    85      8.001  +2.937271147643474e-04  2.1e-04  5.1e-01  
+    71    87      8.001  +2.937263798718626e-04  3.0e-04  5.2e-01  
+    72    88      8.001  +2.937246531357029e-04  2.2e-04  1.0e+00  
+    73    89      8.001  +2.937232048142877e-04  1.0e-04  1.0e+00  
+    74    91      8.001  +2.937223578268570e-04  2.2e-04  4.0e-01  
+    75    92      8.001  +2.937201426598879e-04  2.4e-04  1.0e+00  
+    76    93      8.001  +2.937187758592068e-04  1.8e-04  1.0e+00  
+    77    95      8.001  +2.937169668102822e-04  6.6e-05  5.0e-01  
+    78    97      8.001  +2.937167045913685e-04  1.6e-04  1.9e-01  
+    79    98     12.001  +2.937161308786513e-04  1.9e-04  1.0e+00  
+    80    99     12.001  +2.937145418783188e-04  2.1e-04  1.0e+00  
+    81   100     12.001  +2.937126830402479e-04  7.7e-05  1.0e+00  
+    82   102     12.001  +2.937119950899304e-04  1.9e-04  3.4e-01  
+    83   103     12.001  +2.937103197572409e-04  3.0e-04  1.0e+00  
+    84   104     12.001  +2.937081325220577e-04  1.3e-04  1.0e+00  
+    85   106     12.001  +2.937067731152529e-04  1.5e-05  4.2e-01  
+    86   109     12.001  +2.937061298844395e-04  9.7e-05  5.7e-02  
+    87   110     12.001  +2.937057792029250e-04  3.3e-04  1.0e+00  
+    88   111     12.001  +2.937048989862912e-04  1.6e-04  1.0e+00  
+    89   112     12.001  +2.937037498661225e-04  6.0e-05  1.0e+00  
+    90   113     12.001  +2.937020302605030e-04  2.2e-04  1.0e+00  
+    91   114     12.001  +2.937011876780409e-04  2.4e-04  1.0e+00  
+    92   116     12.001  +2.936994036462835e-04  2.7e-04  4.0e-01  
+    93   117     12.001  +2.936932742505855e-04  4.2e-05  1.0e+00  
+    94   119     12.001  +2.936925011344764e-04  2.5e-04  1.2e-01  
+    95   120     12.001  +2.936903903706649e-04  2.4e-04  1.0e+00  
+    96   121     12.001  +2.936864971751230e-04  1.6e-04  1.0e+00  
+    97   122     12.001  +2.936833519272741e-04  2.7e-05  1.0e+00  
+    98   125     12.001  +2.936823989527786e-04  1.3e-04  5.9e-02  
+    99   127     12.001  +2.936814369909003e-04  2.8e-04  5.1e-01  
+   100   128     12.001  +2.936801889576564e-04  2.5e-04  1.0e+00  
+   101   129     12.001  +2.936781670510260e-04  6.2e-06  1.0e+00  
+   102   131     12.001  +2.936773383070480e-04  1.3e-04  2.7e-01  
+   103   133     12.001  +2.936767971224333e-04  2.1e-04  4.8e-01  
+   104   134     12.001  +2.936757371420169e-04  2.0e-04  1.0e+00  
+   105   136     12.001  +2.936755119527722e-04  1.9e-04  1.7e-01  
+   106   137     12.001  +2.936739331071090e-04  6.8e-05  1.0e+00  
+   107   139     16.001  +2.936733609422002e-04  6.7e-05  2.4e-01  
+   108   141     16.001  +2.936731441199923e-04  1.5e-04  4.5e-01  
+   109   142     16.001  +2.936728734176120e-04  1.5e-04  1.0e+00  
+   110   143     16.001  +2.936727646558677e-04  1.2e-04  1.0e+00  
+   111   144     16.001  +2.936720719650833e-04  5.3e-05  1.0e+00  
+   112   146     16.001  +2.936718160655674e-04  5.7e-05  5.0e-01  
+   113   147     16.001  +2.936716335691947e-04  8.9e-05  1.0e+00  
+   114   148     16.001  +2.936713673939239e-04  1.0e-04  1.0e+00  
+   115   149     16.001  +2.936711604644687e-04  1.8e-06  1.0e+00  
+   116   150     16.001  +2.936710464585561e-04  7.8e-05  1.0e+00  
+   117   151     16.001  +2.936709734203265e-04  2.0e-05  1.0e+00  
+   118   152     16.001  +2.936709005854026e-04  2.0e-05  1.0e+00  
+   119   154     16.001  +2.936708447037076e-04  5.4e-05  3.7e-01  
+   120   155     16.001  +2.936707215906627e-04  5.5e-05  1.0e+00  
+   121   156     16.001  +2.936703043174316e-04  1.9e-05  1.0e+00  
+   122   158     16.001  +2.936700146863054e-04  9.4e-05  4.5e-01  
+   123   160     16.001  +2.936693047392297e-04  1.0e-04  5.0e-01  
+   124   161     16.001  +2.936685401469610e-04  1.2e-04  1.0e+00  
+   125   163     16.001  +2.936679641926337e-04  1.8e-05  1.9e-01  
+   126   165     16.001  +2.936674792095312e-04  1.1e-04  3.2e-01  
+   127   166     16.001  +2.936668316559686e-04  2.9e-04  1.0e+00  
+   128   167     16.001  +2.936662100391527e-04  5.3e-05  1.0e+00  
+   129   168     16.001  +2.936656178325533e-04  8.7e-05  1.0e+00  
+   130   170     16.001  +2.936651583330866e-04  1.5e-04  5.0e-01  
+   131   171     16.001  +2.936647742964451e-04  1.4e-04  1.0e+00  
+   132   173     16.001  +2.936646566758439e-04  1.2e-04  2.0e-01  
+   133   174     16.001  +2.936641713973722e-04  7.2e-05  1.0e+00  
+   134   176     16.001  +2.936637890170677e-04  1.2e-04  4.3e-01  
+   135   177     20.001  +2.936630264588969e-04  4.5e-05  1.0e+00  
+   136   179     20.001  +2.936628969739628e-04  1.1e-04  4.5e-01  
+   137   180     20.001  +2.936625655838410e-04  8.3e-05  1.0e+00  
+   138   181     20.001  +2.936624300065082e-04  2.9e-05  1.0e+00  
+   139   182     20.001  +2.936622977829990e-04  7.7e-05  1.0e+00  
+   140   183     20.001  +2.936622477588315e-04  1.0e-05  1.0e+00  
+   141   184     20.001  +2.936622031232782e-04  1.4e-05  1.0e+00  
+   142   185     20.001  +2.936621779293315e-04  4.8e-05  1.0e+00  
+   143   186     20.001  +2.936621567734476e-04  3.0e-06  1.0e+00  
+   144   187     20.001  +2.936621506624571e-04  2.4e-06  1.0e+00  
+   145   188     20.001  +2.936621474513797e-04  7.8e-06  1.0e+00  
+   146   189     20.001  +2.936621458663817e-04  2.2e-06  1.0e+00  
+   147   190     20.001  +2.936621447656716e-04  1.4e-06  1.0e+00  
+   148   191     20.001  +2.936621438322216e-04  3.6e-06  1.0e+00  
+   149   192     20.001  +2.936621407224748e-04  7.2e-06  1.0e+00  
+   150   193     20.001  +2.936621353581356e-04  8.7e-06  1.0e+00  
+   151   194     20.001  +2.936621275310319e-04  7.5e-06  1.0e+00  
+   152   195     20.001  +2.936621223335431e-04  6.9e-06  1.0e+00  
+   153   197     20.001  +2.936621209792176e-04  3.3e-06  2.2e-01  
+   154   198     20.001  +2.936621173468774e-04  7.0e-06  1.0e+00  
+   155   199     20.001  +2.936621156967350e-04  1.2e-05  1.0e+00  
+   156   200     20.001  +2.936621127659403e-04  1.1e-05  1.0e+00  
+   157   201     20.001  +2.936620879068670e-04  1.8e-05  1.0e+00  
+   158   202     20.001  +2.936620341924160e-04  1.5e-06  1.0e+00  
+   159   204     20.001  +2.936619396711716e-04  1.8e-05  4.0e-01  
+   160   206     20.001  +2.936618809583579e-04  4.6e-05  4.9e-01  
+   161   207     20.001  +2.936618437961445e-04  3.1e-05  1.0e+00  
+   162   208     20.001  +2.936618135595330e-04  1.7e-05  1.0e+00  
+   163   209     20.001  +2.936617994124585e-04  1.5e-05  1.0e+00  
+   164   211     20.001  +2.936617977401772e-04  8.7e-06  2.1e-01  
+   165   212     20.001  +2.936617949948577e-04  7.8e-06  1.0e+00  
+   166   213     24.002  +2.936617942029165e-04  4.8e-06  1.0e+00  
+   167   214     24.002  +2.936617936336488e-04  7.0e-07  1.0e+00  
+   168   215     24.002  +2.936617935577645e-04  6.6e-07  1.0e+00  
+# op_vmlmb_next: FATOL test satisfied
+#
+#
+# Problem 10 (N=2): Brown badly scaled function.
+# Method 0 (NDIR=2): Limited Memory BFGS (VMLM with NDIR=2)
+#
+# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
+# ---------------------------------------------------------------
+     0     1      0.000  +9.999980000030000e+11  2.0e+06  0.0e+00  
+     1    10      0.000  +8.405068809937695e+11  1.5e+10  8.7e+04  
+     2    12      0.000  +6.534530905604027e+11  2.6e+10  1.2e-01  
+     3    14      0.000  +5.259989045876316e+11  1.6e+11  2.1e-01  
+     4    16      0.000  +2.692902690480896e+11  8.1e+10  3.7e-01  
+     5    17      0.000  +1.587055937831890e+11  4.5e+11  1.8e-01  
+     6    18      0.000  +5.786251940191312e+10  3.2e+10  9.8e-01  
+     7    19      0.000  +2.014729184788555e+10  1.3e+11  1.0e+00  
+     8    20      0.000  +3.789073790387382e+09  6.5e+10  7.6e-01  
+     9    21      0.000  +7.582658601419518e+08  2.1e+10  4.9e-01  
+    10    22      0.000  +1.532406522092270e+08  1.3e+10  5.1e-01  
+    11    23      0.000  +8.382857608319093e+07  6.5e+09  3.7e-01  
+    12    24      0.000  +1.653294988314359e+07  2.9e+09  5.7e-01  
+    13    25      0.000  +3.263611062004277e+06  1.3e+09  5.5e-01  
+    14    26      0.000  +6.471465292335765e+05  6.7e+08  5.5e-01  
+    15    27      0.000  +2.722789943285238e+05  4.0e+08  5.0e-01  
+    16    28      0.000  +5.377870916293834e+04  1.7e+08  5.3e-01  
+    17    29      0.000  +1.062250565109277e+04  7.8e+07  5.6e-01  
+    18    30      0.000  +2.098255912542021e+03  3.5e+07  5.6e-01  
+    19    31      0.000  +4.150644198176832e+02  1.4e+07  5.6e-01  
+    20    32      0.000  +9.195149511769590e+01  1.2e+07  5.4e-01  
+    21    33      0.000  +7.394055311418897e+01  6.1e+06  1.4e-02  
+    22    34      0.000  +1.460552054965025e+01  2.7e+06  5.6e-01  
+    23    35      0.000  +2.885039269609231e+00  1.2e+06  5.6e-01  
+    24    36      0.000  +5.698841404349454e-01  5.4e+05  5.6e-01  
+    25    37      0.000  +1.125697148814101e-01  2.4e+05  5.6e-01  
+    26    38      0.000  +2.223674412281545e-02  1.1e+05  5.6e-01  
+    27    39      0.000  +4.419596330611485e-03  3.8e+04  5.6e-01  
+    28    40      0.000  +1.226680528641698e-03  5.3e+04  5.2e-01  
+    29    41      0.000  +3.552382989525306e-04  9.7e+03  4.1e-02  
+    30    42      0.000  +7.017052848565110e-05  4.3e+03  5.6e-01  
+    31    43      0.000  +1.386084529266547e-05  1.9e+03  5.6e-01  
+    32    44      0.000  +2.737944677494988e-06  8.5e+02  5.6e-01  
+    33    45      0.000  +5.408290745856043e-07  3.8e+02  5.6e-01  
+    34    46      0.000  +1.069191494379131e-07  1.5e+02  5.6e-01  
+    35    47      0.000  +3.099248909852002e-08  2.6e+02  5.4e-01  
+    36    48      0.000  +8.015714097213813e-09  5.7e+01  7.0e-02  
+    37    49      0.000  +1.583352621921838e-09  2.5e+01  5.6e-01  
+    38    50      0.000  +3.127629493167706e-10  1.1e+01  5.6e-01  
+    39    51      0.000  +6.178050732586073e-11  5.0e+00  5.6e-01  
+    40    52      0.000  +1.220343418206337e-11  2.2e+00  5.6e-01  
+    41    53      0.000  +2.410577466990187e-12  9.9e-01  5.6e-01  
+    42    54      0.000  +4.761860264644440e-13  4.5e-01  5.6e-01  
+    43    55      0.000  +9.529309271044640e-14  1.3e-01  5.5e-01  
+    44    56      0.000  +3.454718805039423e-14  3.0e-01  4.7e-01  
+    45    57      0.000  +7.000760536493319e-15  1.2e-01  2.0e-01  
+# op_vmlmb_next: FATOL test satisfied
+#
+#
+# Problem 11 (N=4): Brown and Dennis function.
+# Method 0 (NDIR=4): Limited Memory BFGS (VMLM with NDIR=4)
+#
+# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
+# ---------------------------------------------------------------
+     0     1      0.000  +7.926693336997432e+06  2.1e+06  0.0e+00  
+     1     2      0.000  +6.049349781006352e+06  1.6e+06  1.0e+00  
+     2     3      0.000  +2.838871733130934e+06  4.3e+05  1.0e+00  
+     3     4      0.000  +2.432298103636766e+06  2.6e+05  1.0e+00  
+     4     5      0.000  +2.100775303409475e+06  3.1e+05  1.0e+00  
+     5     6      0.000  +1.323784908907083e+06  3.3e+05  1.0e+00  
+     6     7      0.000  +5.656591397675695e+05  8.5e+04  1.0e+00  
+     7     8      4.000  +3.430980546283170e+05  4.1e+04  1.0e+00  
+     8     9      4.000  +1.878284295308689e+05  3.3e+04  1.0e+00  
+     9    11      4.000  +1.436998832262278e+05  7.0e+04  4.8e-01  
+    10    12      4.000  +9.738492091554010e+04  2.9e+04  1.0e+00  
+    11    13      4.000  +9.084457699916144e+04  9.6e+03  1.0e+00  
+    12    14      4.000  +8.891237239806094e+04  5.0e+03  1.0e+00  
+    13    15      4.000  +8.705530186352410e+04  6.8e+03  1.0e+00  
+    14    16      4.000  +8.608483951495643e+04  1.3e+03  1.0e+00  
+    15    17      4.000  +8.599075237276051e+04  7.5e+02  1.0e+00  
+    16    18      4.000  +8.590306517851379e+04  9.1e+02  1.0e+00  
+    17    20      4.000  +8.585776884341528e+04  1.4e+03  3.1e-01  
+    18    21      4.000  +8.582231434220298e+04  9.3e+01  1.0e+00  
+    19    22      4.000  +8.582220228898624e+04  4.8e+00  1.0e+00  
+    20    23      4.000  +8.582220180473091e+04  2.0e+00  1.0e+00  
+    21    24      4.000  +8.582220164639555e+04  3.4e-01  1.0e+00  
+    22    25      4.000  +8.582220163995650e+04  2.7e-01  1.0e+00  
+# op_vmlmb_next: FRTOL test satisfied
+#
+#
+# Problem 12 (N=3): Gulf research and development function.
+# Method 0 (NDIR=3): Limited Memory BFGS (VMLM with NDIR=3)
+#
+# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
+# ---------------------------------------------------------------
+     0     1      4.000  +1.211070582556949e+01  4.0e+01  0.0e+00  
+     1     3      4.000  +7.037432998984529e+00  1.5e+01  1.7e-01  
+     2     5      4.000  +6.621351881374275e+00  3.1e-01  5.0e-01  
+     3     6      8.000  +6.621101702040585e+00  2.3e-01  1.0e+00  
+     4     7      8.000  +6.620679188673091e+00  3.3e-01  1.0e+00  
+     5     8      8.000  +6.619037491331203e+00  8.0e-01  1.0e+00  
+     6     9      8.000  +6.615310780340258e+00  1.5e+00  1.0e+00  
+     7    10      8.000  +6.604547336243583e+00  2.7e+00  1.0e+00  
+     8    11      8.000  +6.573884980436160e+00  4.7e+00  1.0e+00  
+     9    12     12.001  +6.499049562962999e+00  7.4e+00  1.0e+00  
+    10    13     12.001  +6.336057520157562e+00  8.7e+00  1.0e+00  
+    11    14     12.001  +5.892999608485755e+00  2.4e+00  1.0e+00  
+    12    15     12.001  +5.662280493431998e+00  1.4e+01  1.0e+00  
+    13    16     12.001  +5.449061619118568e+00  3.9e+00  1.0e+00  
+    14    17     16.001  +5.234241685722618e+00  2.1e+00  1.0e+00  
+    15    18     16.001  +4.865169222646597e+00  1.8e+01  1.0e+00  
+    16    19     16.001  +4.453895249926380e+00  5.9e+00  1.0e+00  
+    17    20     16.001  +3.976830574245754e+00  2.9e+00  1.0e+00  
+    18    22     20.001  +1.779414184967219e-01  5.4e+00  1.7e+00  
+    19    24     20.001  +1.417710645204940e-01  3.9e+00  8.2e-02  
+    20    25     20.001  +2.557537679786676e-02  1.8e+00  7.2e-01  
+    21    26     20.001  +6.611690206271554e-03  6.2e-01  5.2e-01  
+    22    27     24.001  +4.564494341401721e-03  3.3e-02  1.0e+00  
+    23    28     24.001  +4.543334030131170e-03  1.0e-02  1.0e+00  
+    24    29     24.001  +4.539678138594905e-03  1.0e-02  1.0e+00  
+    25    31     24.001  +4.538933737699077e-03  2.0e-03  4.3e-02  
+    26    32     28.002  +4.538084042484109e-03  1.2e-03  1.0e+00  
+    27    37     32.002  +3.469460838544598e-03  3.0e-01  3.4e+02  
+    28    38     32.002  +2.928359037254009e-03  1.6e-01  1.0e+00  
+    29    40     32.002  +2.474054806017020e-03  2.4e-01  2.6e-01  
+    30    41     32.002  +1.565633067221580e-03  2.3e-01  1.0e+00  
+    31    43     36.002  +1.413550255660053e-03  1.2e-01  9.7e-02  
+    32    44     36.002  +9.024611061567671e-04  1.6e-02  1.0e+00  
+    33    46     36.002  +7.003267516821486e-04  1.1e-01  1.8e-01  
+    34    47     36.002  +5.735129820311213e-04  2.3e-01  1.0e+00  
+    35    48     40.002  +3.123330023579667e-04  4.1e-02  1.0e+00  
+    36    49     40.002  +1.947752299522285e-04  3.4e-02  1.0e+00  
+    37    51     40.002  +1.638242201908890e-04  8.3e-02  2.9e-01  
+    38    52     40.002  +1.048439465991671e-04  7.0e-02  1.0e+00  
+    39    53     44.003  +3.709259481404306e-05  2.7e-03  5.5e-01  
+    40    54     44.003  +1.091378850908817e-05  2.3e-02  8.2e-01  
+    41    55     44.003  +2.536658359037260e-06  1.5e-02  7.5e-01  
+    42    56     44.003  +5.748894725508491e-07  4.4e-03  6.2e-01  
+    43    57     44.003  +1.301070142934200e-07  3.2e-03  5.7e-01  
+    44    58     48.003  +8.850638573840128e-08  1.2e-03  1.6e-01  
+    45    59     48.003  +1.929576324643203e-08  4.9e-04  6.2e-01  
+    46    60     48.003  +5.601806973787550e-09  2.1e-04  7.4e-01  
+    47    61     48.003  +2.535490761789031e-09  3.4e-05  1.0e+00  
+    48    62     48.003  +1.322572045394975e-09  7.9e-05  1.0e+00  
+    49    63     52.003  +8.287306876272502e-10  1.5e-04  1.0e+00  
+    50    64     52.003  +3.454513513192700e-10  7.7e-05  1.0e+00  
+    51    65     52.003  +1.279735809853422e-10  6.8e-05  1.0e+00  
+    52    66     52.003  +2.590444871831076e-11  3.7e-05  5.6e-01  
+    53    67     52.003  +5.131187839211650e-12  1.8e-05  5.6e-01  
+    54    68     56.003  +1.096260941388581e-12  4.6e-06  5.5e-01  
+    55    69     56.003  +2.320936116341532e-13  3.7e-06  4.9e-01  
+    56    71     56.003  +1.720714526990411e-13  3.0e-07  3.5e-02  
+    57    72     56.003  +3.399938346550955e-14  1.3e-07  5.6e-01  
+    58    73     60.004  +6.724520326208138e-15  6.0e-08  5.6e-01  
+# op_vmlmb_next: FATOL test satisfied
+#
+#
+# Problem 13 (N=10): Trigonometric function.
+# Method 0 (NDIR=10): Limited Memory BFGS (VMLM with NDIR=10)
+#
+# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
+# ---------------------------------------------------------------
+     0     1      0.000  +7.075759466222607e-03  9.9e-02  0.0e+00  
+     1     2      0.000  +1.847318266210997e-03  2.8e-02  7.9e-02  
+     2     3      0.000  +1.337289272696683e-03  2.6e-02  1.0e+00  
+     3     4      0.000  +9.099932601024449e-04  2.0e-02  1.0e+00  
+     4     5      0.000  +6.559192696755177e-04  1.4e-02  1.0e+00  
+     5     6      0.000  +4.686579245332390e-04  1.5e-02  1.0e+00  
+     6     7      0.000  +2.915051473509156e-04  1.4e-02  1.0e+00  
+     7     8      0.000  +1.433277880070397e-04  1.7e-02  1.7e-01  
+     8     9      0.000  +7.147757750781793e-05  5.4e-03  5.9e-01  
+     9    10      0.000  +5.887928681982255e-05  2.8e-03  1.0e+00  
+    10    11      0.000  +5.263481793491030e-05  2.1e-03  1.0e+00  
+    11    12      0.000  +4.522784407286506e-05  1.8e-03  1.0e+00  
+    12    13      0.000  +4.260697310099406e-05  1.7e-03  1.0e+00  
+    13    14      0.000  +4.033897074809929e-05  1.2e-03  1.0e+00  
+    14    15      0.000  +3.597768894272814e-05  1.6e-03  1.0e+00  
+    15    17      0.000  +3.282850339569031e-05  1.9e-03  4.0e-01  
+    16    19      0.000  +3.030246929870708e-05  1.7e-03  4.7e-01  
+    17    20      0.000  +2.874543857699578e-05  1.2e-03  1.0e+00  
+    18    21      0.000  +2.839516499584868e-05  7.6e-04  1.0e+00  
+    19    22      0.000  +2.805891729461959e-05  3.7e-04  1.0e+00  
+    20    23      0.000  +2.801778561737049e-05  1.4e-04  1.0e+00  
+    21    24      0.000  +2.800096728737016e-05  1.1e-04  1.0e+00  
+    22    25      0.000  +2.796003401543012e-05  9.0e-05  1.0e+00  
+    23    26      0.000  +2.795364460348979e-05  8.1e-05  1.0e+00  
+    24    27      0.000  +2.795145020217185e-05  4.2e-05  1.0e+00  
+    25    28      0.000  +2.795057495098975e-05  4.8e-06  1.0e+00  
+    26    29      0.000  +2.795056448092877e-05  1.7e-06  1.0e+00  
+    27    30      0.000  +2.795056214675631e-05  9.8e-07  1.0e+00  
+    28    31      0.000  +2.795056136433344e-05  7.1e-07  1.0e+00  
+    29    32      0.000  +2.795056130890243e-05  5.4e-07  1.0e+00  
+    30    33      0.000  +2.795056121893572e-05  1.6e-08  1.0e+00  
+    31    34      0.000  +2.795056121878748e-05  3.9e-09  1.0e+00  
+# op_vmlmb_next: FRTOL test satisfied
+#
+#
+# Problem 14 (N=10): Extended Rosenbrock function.
+# Method 0 (NDIR=10): Limited Memory BFGS (VMLM with NDIR=10)
+#
+# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
+# ---------------------------------------------------------------
+     0     1      0.000  +1.210000000000000e+02  5.2e+02  0.0e+00  
+     1     2      0.000  +3.333875559382903e+01  1.7e+02  2.6e-01  
+     2     3      0.000  +2.099690543341773e+01  2.7e+01  1.0e+00  
+     3     4      0.000  +2.064737829082273e+01  4.4e+00  1.0e+00  
+     4     5      4.000  +2.062947719722462e+01  4.0e+00  1.0e+00  
+     5     6      4.000  +2.055056296009381e+01  8.2e+00  1.0e+00  
+     6     7      4.000  +2.036601960781752e+01  1.6e+01  1.0e+00  
+     7    11      4.000  +1.270403994373162e+01  2.9e+01  7.3e+00  
+     8    13      4.000  +1.266492082784074e+01  2.4e+01  1.3e-01  
+     9    15      4.000  +1.160881636531017e+01  2.0e+01  5.0e+00  
+    10    17      4.000  +1.014905429393288e+01  2.3e+01  5.2e-01  
+    11    18      4.000  +8.256388073653257e+00  2.2e+01  1.0e+00  
+    12    19      4.000  +6.515652375585378e+00  7.3e+00  1.0e+00  
+    13    21      4.000  +5.313683620850455e+00  6.8e+00  3.2e-01  
+    14    23      4.000  +5.001446956969033e+00  1.2e+01  2.3e-01  
+    15    24      4.000  +4.582646809321272e+00  1.3e+01  1.0e+00  
+    16    25      4.000  +3.603604585846324e+00  1.2e+01  1.0e+00  
+    17    26      4.000  +2.675900088307497e+00  2.9e+00  1.0e+00  
+    18    28      4.000  +2.296387307115140e+00  8.0e+00  3.1e-01  
+    19    29      4.000  +1.954912440237827e+00  1.7e+01  1.0e+00  
+    20    30      4.000  +1.378522055959003e+00  3.5e+00  1.0e+00  
+    21    31      4.000  +9.484804947450111e-01  8.2e+00  1.0e+00  
+    22    32      4.000  +6.713411428693927e-01  1.1e+01  1.0e+00  
+    23    33      4.000  +3.822925991805740e-01  5.5e+00  1.0e+00  
+    24    35      4.000  +2.191730723230072e-01  4.4e+00  4.7e-01  
+    25    36      4.000  +1.887020522506004e-01  1.1e+01  1.0e+00  
+    26    37      4.000  +1.125336324978479e-01  4.1e+00  1.0e+00  
+    27    38      4.000  +4.747278490703725e-02  1.8e+00  1.0e+00  
+    28    39      4.000  +2.164097573626416e-02  4.3e+00  1.0e+00  
+    29    40      4.000  +5.971361214373413e-03  8.7e-01  8.5e-01  
+    30    41      4.000  +1.514300265908568e-03  9.7e-01  7.8e-01  
+    31    42      4.000  +3.293711779148185e-04  3.4e-01  6.8e-01  
+    32    43      4.000  +6.882146001996125e-05  1.9e-01  6.4e-01  
+    33    44      4.000  +1.402734044478412e-05  7.0e-02  5.9e-01  
+    34    45      4.000  +2.827846239737803e-06  3.8e-02  5.7e-01  
+    35    46      4.000  +5.657367678388773e-07  1.4e-02  5.6e-01  
+    36    47      4.000  +1.126657341335922e-07  7.5e-03  5.5e-01  
+    37    48      4.000  +2.236521035181264e-08  2.9e-03  5.5e-01  
+    38    49      4.000  +4.430894630373603e-09  1.4e-03  5.5e-01  
+    39    50      4.000  +8.766285485792653e-10  6.0e-04  5.5e-01  
+    40    51      4.000  +1.751634425012838e-10  3.2e-04  5.5e-01  
+    41    52      4.000  +4.269613882266779e-11  3.6e-05  5.1e-01  
+    42    53      4.000  +8.563903609021838e-12  3.2e-05  5.0e-01  
+    43    55      4.000  +8.011613923905404e-12  2.8e-06  8.9e-03  
+    44    56      4.000  +1.582541862741472e-12  1.3e-06  5.6e-01  
+    45    57      4.000  +3.126009356473569e-13  5.6e-07  5.6e-01  
+    46    58      4.000  +6.174833942884158e-14  2.5e-07  5.6e-01  
+    47    59      4.000  +1.219720341626072e-14  1.1e-07  5.6e-01  
+# op_vmlmb_next: FATOL test satisfied
+#
+#
+# Problem 15 (N=12): Extended Powell function.
+# Method 0 (NDIR=12): Limited Memory BFGS (VMLM with NDIR=12)
+#
+# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
+# ---------------------------------------------------------------
+     0     1      0.000  +6.450000000000000e+02  7.9e+02  0.0e+00  
+     1     2      0.000  +2.126398786342238e+02  2.7e+02  9.0e-01  
+     2     3      0.000  +1.002223459053673e+02  1.4e+02  1.0e+00  
+     3     4      0.000  +4.372578508635030e+01  4.1e+01  1.0e+00  
+     4     5      0.000  +3.492275772532622e+01  3.1e+01  1.0e+00  
+     5     6      0.000  +2.371218382737346e+01  1.8e+01  1.0e+00  
+     6     7      0.000  +1.840511402191540e+01  1.5e+01  1.0e+00  
+     7     8      0.000  +5.385458666855794e+00  1.4e+01  1.0e+00  
+     8     9      0.000  +1.387075054330895e+00  5.4e+00  7.5e-01  
+     9    10      0.000  +4.338250784945510e-01  5.3e+00  1.0e+00  
+    10    11      4.000  +2.021610832573901e-01  3.7e+00  9.0e-01  
+    11    12      4.000  +8.424287893602030e-02  1.4e+00  1.0e+00  
+    12    13      4.000  +2.416572403566977e-02  6.8e-01  9.8e-01  
+    13    14      4.000  +9.539455035955798e-03  3.4e-01  1.0e+00  
+    14    15      4.000  +4.018557231556538e-03  1.2e-01  1.0e+00  
+    15    16      4.000  +2.359119570961944e-03  6.5e-02  1.0e+00  
+    16    17      4.000  +1.410815508220599e-03  9.5e-02  1.0e+00  
+    17    18      4.000  +6.664117905074039e-04  4.2e-02  1.0e+00  
+    18    19      4.000  +3.278858525866031e-04  2.2e-02  1.0e+00  
+    19    20      4.000  +1.301355227806065e-04  2.9e-02  1.0e+00  
+    20    21      4.000  +5.051539438473153e-05  4.1e-02  9.6e-01  
+    21    22      4.000  +1.933558681673291e-05  1.0e-02  1.0e+00  
+    22    23      4.000  +1.385853063374876e-05  1.9e-03  1.0e+00  
+    23    24      4.000  +1.325733364422288e-05  6.1e-03  1.0e+00  
+    24    25      4.000  +1.042889374455694e-05  1.5e-02  1.0e+00  
+    25    26      4.000  +5.019830828798650e-06  1.6e-02  1.0e+00  
+    26    28      4.000  +4.246579321514016e-06  2.7e-03  3.0e-02  
+    27    29      4.000  +1.264335976216658e-06  6.3e-04  1.0e+00  
+    28    30      4.000  +4.235261754358550e-07  9.7e-05  1.0e+00  
+    29    31      4.000  +1.358585713215724e-07  4.3e-05  1.0e+00  
+    30    32      4.000  +4.490260964925541e-08  3.5e-04  1.0e+00  
+    31    33      4.000  +1.435728201106651e-08  2.0e-04  1.0e+00  
+    32    34      4.000  +4.659469517411141e-09  1.9e-05  1.0e+00  
+    33    35      4.000  +3.197807521383443e-09  5.6e-04  9.5e-01  
+    34    36      4.000  +8.129560805831940e-10  1.5e-04  8.3e-01  
+    35    37      4.000  +2.639089711885569e-10  2.5e-05  1.0e+00  
+    36    38      4.000  +1.238902847308503e-10  3.8e-05  1.0e+00  
+    37    39      4.000  +3.693522871395788e-11  2.6e-05  1.0e+00  
+    38    40      4.000  +1.262527367596187e-11  1.7e-05  9.9e-01  
+    39    41      4.000  +4.121104687115640e-12  6.1e-06  8.0e-01  
+    40    42      4.000  +1.510459349123597e-12  1.4e-06  1.0e+00  
+    41    43      4.000  +5.074496790632610e-13  2.9e-07  1.0e+00  
+    42    44      4.000  +1.788275537869560e-13  1.2e-06  1.0e+00  
+    43    45      4.000  +5.912068107118078e-14  1.1e-06  1.0e+00  
+    44    46      4.000  +2.328813604908046e-14  3.7e-07  1.0e+00  
+# op_vmlmb_next: FATOL test satisfied
+#
+#
+# Problem 16 (N=2): Beale function.
+# Method 0 (NDIR=2): Limited Memory BFGS (VMLM with NDIR=2)
+#
+# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
+# ---------------------------------------------------------------
+     0     1      0.000  +1.420312500000000e+01  2.8e+01  0.0e+00  
+     1     2      0.000  +5.837321962114054e+00  9.0e+00  5.7e-01  
+     2     3      0.000  +3.543247835494009e+00  6.4e+00  1.0e+00  
+     3     4      0.000  +1.309302199158894e+00  2.7e+00  8.3e-01  
+     4     5      0.000  +8.188817853278094e-01  2.2e+00  1.0e+00  
+     5     6      0.000  +2.196594007426552e-01  9.2e-01  6.3e-01  
+     6     7      0.000  +5.892697837805581e-02  3.1e-01  9.0e-01  
+     7     8      0.000  +2.970214723480817e-02  1.1e+00  1.0e+00  
+     8     9      0.000  +7.437526283530453e-03  2.6e-01  6.0e-01  
+     9    10      0.000  +1.762547800263668e-03  5.2e-02  8.1e-01  
+    10    11      0.000  +3.806254994795292e-04  3.8e-02  7.5e-01  
+    11    13      0.000  +3.601037933927141e-04  1.8e-02  1.6e-02  
+    12    14      0.000  +7.333268718739307e-05  6.9e-03  6.4e-01  
+    13    15      0.000  +1.475615358477659e-05  3.5e-03  5.9e-01  
+    14    17      0.000  +1.418392844246689e-05  6.2e-03  1.9e-02  
+    15    18      0.000  +2.813440877948162e-06  2.6e-03  5.7e-01  
+    16    19      0.000  +5.569285817905507e-07  1.1e-03  5.6e-01  
+    17    20      0.000  +2.389901351508039e-07  3.9e-03  5.4e-01  
+    18    21      0.000  +4.719137850755555e-08  1.7e-03  2.6e-01  
+    19    22      0.000  +9.318027774792144e-09  7.6e-04  5.5e-01  
+    20    23      0.000  +1.840271195971691e-09  3.4e-04  5.6e-01  
+    21    24      0.000  +3.634816763291771e-10  1.5e-04  5.6e-01  
+    22    25      0.000  +7.179633292922795e-11  6.7e-05  5.6e-01  
+    23    26      0.000  +1.418177095511089e-11  3.0e-05  5.6e-01  
+    24    27      0.000  +2.801318130710862e-12  1.3e-05  5.6e-01  
+    25    28      0.000  +5.533450993015748e-13  5.9e-06  5.6e-01  
+    26    29      0.000  +1.093025883599040e-13  2.6e-06  5.6e-01  
+    27    30      0.000  +2.159062213224393e-14  1.2e-06  5.6e-01  
+    28    31      0.000  +4.264813197124873e-15  5.2e-07  5.6e-01  
+# op_vmlmb_next: FATOL test satisfied
+#
+#
+# Problem 17 (N=4): Wood function.
+# Method 0 (NDIR=4): Limited Memory BFGS (VMLM with NDIR=4)
+#
+# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
+# ---------------------------------------------------------------
+     0     1      0.000  +1.919200000000000e+04  1.6e+04  0.0e+00  
+     1     2      0.000  +7.427890102322217e+03  7.9e+03  1.0e+00  
+     2     3      0.000  +2.438439115206284e+03  3.3e+03  1.0e+00  
+     3     4      0.000  +8.528820526783926e+02  1.5e+03  1.0e+00  
+     4     5      4.000  +2.768216485716339e+02  6.1e+02  1.0e+00  
+     5     6      4.000  +8.327982562502508e+01  2.4e+02  1.0e+00  
+     6     7      4.000  +3.108746833161832e+01  7.1e+01  1.0e+00  
+     7     8      4.000  +2.380525415568198e+01  2.4e+01  1.0e+00  
+     8     9      4.000  +2.251089219753886e+01  2.6e+01  1.0e+00  
+     9    10      4.000  +1.855299679936986e+01  4.3e+01  1.0e+00  
+    10    12      4.000  +1.160837562431893e+01  4.5e+01  3.8e-01  
+    11    14      4.000  +8.137724551705739e+00  1.9e+01  1.1e-01  
+    12    16      4.000  +7.878690238212614e+00  1.2e+00  3.4e-01  
+    13    17      4.000  +7.877411159067403e+00  8.8e-01  1.0e+00  
+    14    18      4.000  +7.876880489799159e+00  4.4e-02  1.0e+00  
+    15    19      4.000  +7.876879132206481e+00  1.1e-02  1.0e+00  
+    16    20      4.000  +7.876878876272726e+00  4.8e-03  1.0e+00  
+    17    22      4.000  +7.876878490252988e+00  7.0e-03  5.0e+00  
+    18    23      4.000  +7.876876755266399e+00  1.9e-02  1.0e+00  
+    19    24      4.000  +7.876870816217647e+00  3.5e-02  1.0e+00  
+    20    26      4.000  +7.876865204511740e+00  1.3e-01  4.0e-01  
+    21    27      4.000  +7.876844389583843e+00  1.4e-01  1.0e+00  
+    22    28      4.000  +7.876583706646104e+00  3.2e-01  1.0e+00  
+    23    29      4.000  +7.876423129704414e+00  8.5e-01  1.0e+00  
+    24    30      4.000  +7.875060453829682e+00  1.6e+00  1.0e+00  
+    25    31      4.000  +7.872131119796703e+00  3.0e+00  1.0e+00  
+    26    33      4.000  +7.869170139094837e+00  3.3e+00  2.0e-01  
+    27    35      4.000  +7.864052623536911e+00  3.4e+00  3.6e-01  
+    28    36      4.000  +7.855001610484345e+00  2.9e+00  1.0e+00  
+    29    37      4.000  +7.849625111708809e+00  4.1e+00  1.0e+00  
+    30    38      4.000  +7.839170804391435e+00  3.0e+00  1.0e+00  
+    31    39      4.000  +7.824568101062441e+00  2.8e+00  1.0e+00  
+    32    41      4.000  +7.813646935560872e+00  4.1e+00  2.4e-01  
+    33    43      4.000  +7.789494013946371e+00  5.7e+00  2.3e-01  
+    34    44      4.000  +7.722263757787657e+00  7.4e+00  1.0e+00  
+    35    46      4.000  +7.693814493002182e+00  1.2e+01  1.6e-01  
+    36    47      4.000  +7.541393104832614e+00  4.3e+00  1.0e+00  
+    37    48      4.000  +7.434111139448211e+00  5.1e+00  1.0e+00  
+    38    50      4.000  +7.420136912558213e+00  6.7e+00  9.8e-02  
+    39    51      4.000  +7.323032564057124e+00  6.2e+00  1.0e+00  
+    40    53      4.000  +7.216964400808464e+00  1.4e+01  2.7e-01  
+    41    54      4.000  +6.911125334280928e+00  1.1e+01  1.0e+00  
+    42    55      4.000  +6.512566568432114e+00  4.0e+01  1.0e+00  
+    43    56      4.000  +5.720835039047132e+00  7.6e+00  1.0e+00  
+    44    57      4.000  +5.672818396981924e+00  1.6e+01  1.0e+00  
+    45    59      4.000  +5.202278173076890e+00  1.9e+01  2.2e-01  
+    46    62      4.000  +5.061832019786340e+00  2.0e+01  6.4e-02  
+    47    63      4.000  +4.875017742525158e+00  2.0e+01  1.0e+00  
+    48    64      4.000  +4.616628933510177e+00  1.3e+01  1.0e+00  
+    49    65      4.000  +4.405532645759691e+00  1.7e+01  1.0e+00  
+    50    66      4.000  +3.915460121738099e+00  1.8e+01  1.0e+00  
+    51    67      4.000  +3.571117225615803e+00  1.8e+01  1.0e+00  
+    52    69      4.000  +3.342807282681064e+00  6.6e+00  3.0e-01  
+    53    70      4.000  +3.169420327958804e+00  8.2e+00  1.0e+00  
+    54    71      4.000  +3.083714115933907e+00  7.5e+00  1.0e+00  
+    55    72      4.000  +2.842571930210177e+00  6.2e+00  1.0e+00  
+    56    73      4.000  +2.407959483920122e+00  1.8e+01  1.0e+00  
+    57    75      4.000  +2.310997032934655e+00  1.5e+01  2.4e-01  
+    58    77      4.000  +1.874303903557421e+00  9.1e+00  3.9e-01  
+    59    79      4.000  +1.747352207978819e+00  4.5e+00  4.3e-01  
+    60    80      4.000  +1.616702123440979e+00  6.3e+00  1.0e+00  
+    61    81      4.000  +1.551453286562933e+00  1.7e+01  1.0e+00  
+    62    82      4.000  +1.445642573680781e+00  1.1e+01  1.0e+00  
+    63    84      4.000  +1.291548725488739e+00  7.3e+00  5.2e-01  
+    64    85      4.000  +1.146267070283055e+00  1.3e+01  1.0e+00  
+    65    86      4.000  +8.736037619411690e-01  6.2e+00  1.0e+00  
+    66    88      4.000  +7.587510486192135e-01  6.2e+00  4.3e-01  
+    67    89      4.000  +6.272474461111625e-01  2.7e+00  1.0e+00  
+    68    91      4.000  +6.154503738538099e-01  2.9e+00  3.6e-01  
+    69    92      4.000  +6.025386870053662e-01  2.3e+00  1.0e+00  
+    70    93      4.000  +5.569297053304927e-01  2.8e+00  1.0e+00  
+    71    94      4.000  +4.939103897295918e-01  6.0e+00  1.0e+00  
+    72    95      4.000  +3.289194049732398e-01  5.1e+00  1.0e+00  
+    73    97      4.000  +2.689387273180264e-01  8.0e+00  2.0e-01  
+    74    98      4.000  +1.220581321270582e-01  8.6e+00  8.6e-01  
+    75    99      8.001  +6.663309577533551e-02  8.9e+00  4.3e-01  
+    76   100      8.001  +3.637323340490146e-02  1.1e+00  1.0e+00  
+    77   101      8.001  +2.712208655572348e-02  1.5e+00  1.0e+00  
+    78   102      8.001  +1.116522496174569e-02  3.7e+00  7.9e-01  
+    79   103      8.001  +3.900482707955074e-03  2.0e+00  4.8e-01  
+    80   104      8.001  +1.004136803886999e-03  6.9e-01  9.3e-01  
+    81   105      8.001  +2.226638008945489e-04  3.5e-01  7.3e-01  
+    82   106      8.001  +5.106876720624694e-05  7.5e-02  6.0e-01  
+    83   107      8.001  +1.071982128302296e-05  2.6e-02  6.0e-01  
+    84   108      8.001  +4.441881481174797e-06  6.4e-02  5.2e-01  
+    85   109      8.001  +9.368857777996710e-07  2.8e-02  4.1e-01  
+    86   110      8.001  +1.923710022206024e-07  1.3e-02  5.7e-01  
+    87   111      8.001  +4.207762167723878e-08  5.8e-03  6.1e-01  
+    88   112      8.001  +1.181228459744630e-08  2.3e-03  7.0e-01  
+    89   113      8.001  +6.562748229821411e-09  8.5e-04  1.0e+00  
+    90   114      8.001  +5.554256689700290e-09  7.8e-04  1.0e+00  
+    91   115      8.001  +3.484975951958208e-09  1.1e-03  1.0e+00  
+    92   116      8.001  +8.872950699360685e-10  9.9e-04  9.6e-01  
+    93   117      8.001  +1.837384368516011e-10  3.9e-04  4.7e-01  
+    94   118      8.001  +3.863280276302230e-11  1.8e-04  5.7e-01  
+    95   119      8.001  +9.862952976040704e-12  8.1e-05  6.1e-01  
+    96   120      8.001  +3.643236162973744e-12  3.2e-05  6.8e-01  
+    97   121      8.001  +2.484476074089160e-12  8.5e-06  1.0e+00  
+    98   122      8.001  +2.082579068068493e-12  1.4e-05  1.0e+00  
+    99   123      8.001  +7.291374932118642e-13  2.4e-05  1.0e+00  
+   100   124      8.001  +3.315075555077437e-13  9.7e-06  5.1e-01  
+   101   125      8.001  +7.622499994371465e-14  7.5e-06  7.5e-01  
+   102   126      8.001  +4.174888567594510e-14  6.3e-06  1.5e-01  
+# op_vmlmb_next: FATOL test satisfied
+#
+#
+# Problem 18 (N=25): Chebyquad function.
+# Method 0 (NDIR=25): Limited Memory BFGS (VMLM with NDIR=25)
+#
+# ITER  EVAL   CPU (ms)        FUNC               GNORM   STEPLEN
+# ---------------------------------------------------------------
+     0     1      0.000  +1.248791904880204e-02  6.5e-01  0.0e+00  
+     1     3      4.000  +1.049431287352932e-02  5.8e-01  5.7e-03  
+     2     4      8.000  +9.609006926829304e-03  2.8e-01  1.0e+00  
+     3     5      8.000  +9.337302507733160e-03  1.3e-01  1.0e+00  
+     4     6     12.000  +9.170073298832805e-03  1.2e-01  1.0e+00  
+     5     7     12.000  +8.991254191516106e-03  1.1e-01  1.0e+00  
+     6     8     16.001  +8.846941541915740e-03  7.7e-02  1.0e+00  
+     7     9     16.001  +8.801166872704557e-03  9.3e-02  1.0e+00  
+     8    10     20.001  +8.756693487815655e-03  4.5e-02  1.0e+00  
+     9    11     20.001  +8.739152782891746e-03  3.3e-02  1.0e+00  
+    10    12     20.001  +8.714552799449523e-03  3.1e-02  1.0e+00  
+    11    13     24.001  +8.692796444352035e-03  3.2e-02  1.0e+00  
+    12    14     24.001  +8.667777829095081e-03  2.6e-02  1.0e+00  
+    13    15     28.001  +8.654662603946484e-03  4.0e-02  1.0e+00  
+    14    16     28.001  +8.643693770592379e-03  1.7e-02  1.0e+00  
+    15    17     32.002  +8.637815829617758e-03  1.5e-02  1.0e+00  
+    16    18     32.002  +8.633008188826369e-03  1.8e-02  1.0e+00  
+    17    19     36.002  +8.620907535587131e-03  4.2e-02  1.0e+00  
+    18    21     40.002  +8.614998716828056e-03  2.6e-02  4.1e-01  
+    19    22     40.002  +8.610412652519038e-03  1.1e-02  1.0e+00  
+    20    23     40.002  +8.608556239357218e-03  7.1e-03  1.0e+00  
+    21    24     44.002  +8.607605459630636e-03  6.9e-03  1.0e+00  
+    22    25     44.002  +8.602572986472511e-03  1.3e-02  1.0e+00  
+    23    26     48.003  +8.590054454806751e-03  2.8e-02  1.0e+00  
+    24    27     48.003  +8.564183633311328e-03  7.5e-02  1.0e+00  
+    25    28     52.003  +8.532458576242349e-03  9.3e-02  1.0e+00  
+    26    29     52.003  +8.493452768781006e-03  7.0e-02  1.0e+00  
+    27    30     56.003  +8.474787010915145e-03  6.7e-02  1.0e+00  
+    28    31     56.003  +8.458773326847066e-03  4.5e-02  1.0e+00  
+    29    32     60.003  +8.457999627479094e-03  4.1e-02  1.0e+00  
+    30    33     60.003  +8.449532870934518e-03  2.2e-02  1.0e+00  
+    31    34     64.004  +8.447840743807028e-03  2.8e-02  1.0e+00  
+    32    35     64.004  +8.445692845529283e-03  1.1e-02  1.0e+00  
+    33    36     68.004  +8.444165323560711e-03  9.6e-03  1.0e+00  
+    34    37     68.004  +8.443207951672584e-03  1.0e-02  1.0e+00  
+    35    38     68.004  +8.441994339191562e-03  2.0e-02  1.0e+00  
+    36    39     72.004  +8.439832619160158e-03  1.4e-02  1.0e+00  
+    37    40     72.004  +8.437231750924349e-03  1.1e-02  1.0e+00  
+    38    41     76.004  +8.433302937380200e-03  1.2e-02  1.0e+00  
+    39    43     80.005  +8.432489353555114e-03  9.1e-03  3.7e-01  
+    40    44     80.005  +8.432123509481731e-03  4.7e-03  1.0e+00  
+    41    45     84.005  +8.432035588096611e-03  2.3e-03  1.0e+00  
+    42    46     84.005  +8.431999120538823e-03  1.5e-03  1.0e+00  
+    43    47     88.005  +8.431966728031759e-03  1.2e-03  1.0e+00  
+    44    48     88.005  +8.431924365562692e-03  1.6e-03  1.0e+00  
+    45    50     92.005  +8.431891947171172e-03  3.1e-03  4.2e-01  
+    46    51     92.005  +8.431831354671862e-03  2.3e-03  1.0e+00  
+    47    52     96.006  +8.431668636095641e-03  3.3e-03  1.0e+00  
+    48    53     96.006  +8.431437099609954e-03  5.4e-03  1.0e+00  
+    49    54    100.006  +8.431000851063426e-03  5.3e-03  1.0e+00  
+    50    55    100.006  +8.430678732503366e-03  1.6e-02  1.0e+00  
+    51    56    104.006  +8.429876682496911e-03  7.2e-03  1.0e+00  
+    52    57    104.006  +8.428910142166941e-03  6.9e-03  1.0e+00  
+    53    58    108.006  +8.428161202850929e-03  9.8e-03  1.0e+00  
+    54    59    108.006  +8.427149557235504e-03  1.2e-02  1.0e+00  
+    55    60    112.007  +8.426884594329293e-03  1.0e-02  1.0e+00  
+    56    62    116.007  +8.425929204745749e-03  9.6e-03  4.4e-01  
+    57    63    116.007  +8.425078821369147e-03  6.2e-03  1.0e+00  
+    58    65    120.007  +8.424962146289759e-03  6.7e-03  2.7e-01  
+    59    66    124.007  +8.424706166580516e-03  6.3e-03  1.0e+00  
+    60    67    124.007  +8.424483854096705e-03  4.1e-03  1.0e+00  
+    61    68    124.007  +8.424346241895737e-03  2.7e-03  1.0e+00  
+    62    69    128.008  +8.424196521199122e-03  4.1e-03  1.0e+00  
+    63    70    128.008  +8.423947181728741e-03  3.3e-03  1.0e+00  
+    64    72    132.008  +8.423857716916193e-03  3.9e-03  4.8e-01  
+    65    73    136.008  +8.423772029357686e-03  1.3e-03  1.0e+00  
+    66    74    136.008  +8.423740800437915e-03  1.7e-03  1.0e+00  
+    67    75    140.008  +8.423721211048594e-03  2.0e-03  1.0e+00  
+    68    76    140.008  +8.423707802726785e-03  6.8e-04  1.0e+00  
+    69    77    144.009  +8.423705094214971e-03  2.9e-04  1.0e+00  
+    70    78    144.009  +8.423704078604773e-03  2.7e-04  1.0e+00  
+    71    79    148.009  +8.423703211145708e-03  2.3e-04  1.0e+00  
+    72    80    148.009  +8.423702337458264e-03  1.9e-04  1.0e+00  
+    73    81    148.009  +8.423702265665172e-03  4.1e-04  1.0e+00  
+    74    82    152.009  +8.423701658411723e-03  1.6e-04  1.0e+00  
+    75    83    152.009  +8.423701425312869e-03  1.7e-04  1.0e+00  
+    76    84    156.009  +8.423700442240544e-03  3.0e-04  1.0e+00  
+    77    85    156.009  +8.423698956540247e-03  4.1e-04  1.0e+00  
+    78    86    160.010  +8.423696594839578e-03  6.2e-04  1.0e+00  
+    79    87    160.010  +8.423693749784765e-03  5.9e-04  1.0e+00  
+    80    88    164.010  +8.423691373336607e-03  3.1e-04  1.0e+00  
+    81    89    164.010  +8.423689724709164e-03  1.6e-04  1.0e+00  
+    82    91    168.010  +8.423689561087022e-03  2.0e-04  4.0e-01  
+    83    92    172.010  +8.423689406081498e-03  1.2e-04  1.0e+00  
+    84    93    172.010  +8.423689325881282e-03  3.0e-05  1.0e+00  
+    85    94    172.010  +8.423689316751977e-03  2.9e-05  1.0e+00  
+    86    95    176.011  +8.423689305145607e-03  2.4e-05  1.0e+00  
+    87    96    176.011  +8.423689289622477e-03  2.8e-05  1.0e+00  
+    88    97    180.011  +8.423689257662553e-03  3.4e-05  1.0e+00  
+    89    98    180.011  +8.423689218774710e-03  3.7e-05  1.0e+00  
+    90    99    184.011  +8.423689151546083e-03  7.2e-05  1.0e+00  
+    91   100    184.011  +8.423689072351309e-03  6.8e-05  1.0e+00  
+    92   101    188.011  +8.423688995763033e-03  6.2e-05  1.0e+00  
+    93   102    188.011  +8.423688928736774e-03  7.4e-05  1.0e+00  
+    94   103    192.012  +8.423688881914616e-03  4.9e-05  1.0e+00  
+    95   104    192.012  +8.423688840104407e-03  4.0e-05  1.0e+00  
+    96   106    196.012  +8.423688821486053e-03  7.3e-05  4.4e-01  
+    97   107    196.012  +8.423688798581467e-03  3.0e-05  1.0e+00  
+    98   108    200.012  +8.423688787360375e-03  1.9e-05  1.0e+00  
+    99   109    200.012  +8.423688776709048e-03  1.3e-05  1.0e+00  
+   100   111    204.012  +8.423688774926129e-03  2.1e-05  4.6e-01  
+   101   112    208.013  +8.423688773115171e-03  7.6e-06  1.0e+00  
+   102   113    208.013  +8.423688772436546e-03  6.9e-06  1.0e+00  
+   103   114    212.013  +8.423688771155470e-03  1.1e-05  1.0e+00  
+   104   115    212.013  +8.423688769387254e-03  1.4e-05  1.0e+00  
+   105   116    216.013  +8.423688766337282e-03  1.4e-05  1.0e+00  
+   106   118    220.013  +8.423688765114607e-03  1.5e-05  2.8e-01  
+   107   119    220.013  +8.423688763449228e-03  6.4e-06  1.0e+00  
+   108   120    220.013  +8.423688762532369e-03  7.1e-06  1.0e+00  
+   109   121    224.014  +8.423688761837404e-03  9.9e-06  1.0e+00  
+   110   122    224.014  +8.423688760262529e-03  1.3e-05  1.0e+00  
+   111   123    228.014  +8.423688759272251e-03  3.6e-05  1.0e+00  
+   112   124    228.014  +8.423688756130365e-03  1.7e-05  1.0e+00  
+   113   125    232.014  +8.423688753374270e-03  9.2e-06  1.0e+00  
+   114   126    232.014  +8.423688751373724e-03  1.1e-05  1.0e+00  
+   115   127    236.014  +8.423688750014176e-03  7.3e-06  1.0e+00  
+   116   128    236.014  +8.423688749391211e-03  7.7e-06  1.0e+00  
+   117   129    240.015  +8.423688748986261e-03  5.8e-06  1.0e+00  
+# op_vmlmb_next: FRTOL test satisfied
+#