[med-svn] [spades] 02/04: Imported Upstream version 3.8.2+dfsg2
Sascha Steinbiss
satta at debian.org
Tue Jul 19 21:16:14 UTC 2016
This is an automated email from the git hooks/post-receive script.
satta pushed a commit to branch master
in repository spades.
commit edff7965b9ab519dbbc929ecb591ab21cf31d95f
Author: Sascha Steinbiss <satta at debian.org>
Date: Tue Jul 19 17:09:31 2016 +0000
Imported Upstream version 3.8.2+dfsg2
---
ext/include/htrie/ahtable.h | 115 --
ext/include/htrie/common.h | 22 -
ext/include/htrie/hat-trie.h | 74 -
ext/include/nlopt/auglag.h | 50 -
ext/include/nlopt/bobyqa.h | 13 -
ext/include/nlopt/cdirect.h | 80 -
ext/include/nlopt/cobyla.h | 62 -
ext/include/nlopt/crs.h | 47 -
ext/include/nlopt/esch.h | 49 -
ext/include/nlopt/isres.h | 48 -
ext/include/nlopt/mlsl.h | 48 -
ext/include/nlopt/mma.h | 61 -
ext/include/nlopt/neldermead.h | 61 -
ext/include/nlopt/newuoa.h | 14 -
ext/include/nlopt/nlopt-internal.h | 95 --
ext/include/nlopt/nlopt-util.h | 124 --
ext/include/nlopt/nlopt.h | 379 -----
ext/include/nlopt/nlopt.hpp | 596 -------
ext/include/nlopt/praxis.h | 22 -
ext/include/nlopt/redblack.h | 77 -
ext/include/ssw/ssw.h | 188 ---
ext/include/ssw/ssw_cpp.h | 215 ---
ext/src/htrie/CMakeLists.txt | 11 -
ext/src/htrie/ahtable.c | 564 -------
ext/src/htrie/hat-trie.c | 711 --------
ext/src/htrie/misc.c | 46 -
ext/src/htrie/misc.h | 22 -
ext/src/htrie/murmurhash3.c | 77 -
ext/src/htrie/murmurhash3.h | 12 -
ext/src/nlopt/AUTHORS | 6 -
ext/src/nlopt/CMakeLists.txt | 34 -
ext/src/nlopt/COPYING | 20 -
ext/src/nlopt/api/deprecated.c | 171 --
ext/src/nlopt/api/general.c | 134 --
ext/src/nlopt/api/optimize.c | 767 ---------
ext/src/nlopt/api/options.c | 753 ---------
ext/src/nlopt/auglag/README | 25 -
ext/src/nlopt/auglag/auglag.c | 289 ----
ext/src/nlopt/bobyqa/COPYRIGHT | 23 -
ext/src/nlopt/bobyqa/README | 20 -
ext/src/nlopt/bobyqa/README.orig | 60 -
ext/src/nlopt/bobyqa/bobyqa.c | 3269 ------------------------------------
ext/src/nlopt/cdirect/README | 26 -
ext/src/nlopt/cdirect/cdirect.c | 600 -------
ext/src/nlopt/cdirect/hybrid.c | 317 ----
ext/src/nlopt/cobyla/COPYRIGHT | 22 -
ext/src/nlopt/cobyla/README | 42 -
ext/src/nlopt/cobyla/README.orig | 74 -
ext/src/nlopt/cobyla/cobyla.c | 1847 --------------------
ext/src/nlopt/crs/README | 19 -
ext/src/nlopt/crs/crs.c | 270 ---
ext/src/nlopt/esch/COPYRIGHT | 22 -
ext/src/nlopt/esch/README | 27 -
ext/src/nlopt/esch/esch.c | 259 ---
ext/src/nlopt/isres/README | 23 -
ext/src/nlopt/isres/isres.c | 283 ----
ext/src/nlopt/mlsl/README | 22 -
ext/src/nlopt/mlsl/mlsl.c | 435 -----
ext/src/nlopt/mma/README | 32 -
ext/src/nlopt/mma/ccsa_quadratic.c | 550 ------
ext/src/nlopt/mma/mma.c | 398 -----
ext/src/nlopt/neldermead/README | 107 --
ext/src/nlopt/neldermead/nldrmd.c | 306 ----
ext/src/nlopt/neldermead/sbplx.c | 239 ---
ext/src/nlopt/newuoa/COPYRIGHT | 23 -
ext/src/nlopt/newuoa/README | 29 -
ext/src/nlopt/newuoa/README.orig | 40 -
ext/src/nlopt/newuoa/newuoa.c | 2560 ----------------------------
ext/src/nlopt/praxis/README | 15 -
ext/src/nlopt/praxis/praxis.c | 1366 ---------------
ext/src/nlopt/util/mt19937ar.c | 241 ---
ext/src/nlopt/util/qsort_r.c | 110 --
ext/src/nlopt/util/redblack.c | 430 -----
ext/src/nlopt/util/rescale.c | 82 -
ext/src/nlopt/util/soboldata.h | 880 ----------
ext/src/nlopt/util/sobolseq.c | 287 ----
ext/src/nlopt/util/stop.c | 134 --
ext/src/nlopt/util/timer.c | 93 -
ext/src/ssw/CMakeLists.txt | 12 -
ext/src/ssw/ssw.c | 903 ----------
ext/src/ssw/ssw_cpp.cpp | 477 ------
81 files changed, 23056 deletions(-)
diff --git a/ext/include/htrie/ahtable.h b/ext/include/htrie/ahtable.h
deleted file mode 100644
index bdfd9f9..0000000
--- a/ext/include/htrie/ahtable.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * This file is part of hat-trie.
- *
- * Copyright (c) 2011 by Daniel C. Jones <dcjones at cs.washington.edu>
- *
- *
- * This is an implementation of the 'cache-conscious' hash tables described in,
- *
- * Askitis, N., & Zobel, J. (2005). Cache-conscious collision resolution in
- * string hash tables. String Processing and Information Retrieval (pp.
- * 91–102). Springer.
- *
- * http://naskitis.com/naskitis-spire05.pdf
- *
- * Briefly, the idea behind an Array Hash Table is, as opposed to separate
- * chaining with linked lists, to store keys contiguously in one big array,
- * thereby improving the caching behavior, and reducing space requirements.
- *
- * ahtable keeps a fixed number (array) of slots, each of which contains a
- * variable number of key/value pairs. Each key is preceded by its length--
- * one byte for lengths < 128 bytes, and TWO bytes for longer keys. The least
- * significant bit of the first byte indicates, if set, that the size is two
- * bytes. The slot number where a key/value pair goes is determined by finding
- * the murmurhashed integer value of its key, modulus the number of slots.
- * The number of slots expands in a stepwise fashion when the number of
- # key/value pairs reaches an arbitrarily large number.
- *
- * +-------+-------+-------+-------+-------+-------+
- * | 0 | 1 | 2 | 3 | ... | N |
- * +-------+-------+-------+-------+-------+-------+
- * | | | | |
- * v | | v v
- * NULL | | 4html[VALUE] etc.
- * | v
- * | 5space[VALUE]4jury[VALUE]
- * v
- * 6justice[VALUE]3car[VALUE]4star[VALUE]
- *
- */
-
-#ifndef HATTRIE_AHTABLE_H
-#define HATTRIE_AHTABLE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdlib.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include "htrie/common.h"
-
-typedef unsigned char* slot_t;
-
-typedef struct ahtable_t_
-{
- /* these fields are reserved for hattrie to fiddle with */
- uint8_t flag;
- unsigned char c0;
- unsigned char c1;
-
- size_t n; // number of slots
- size_t m; // number of key/value pairs stored
- size_t max_m; // number of stored keys before we resize
-
- size_t* slot_sizes;
- slot_t* slots;
-} ahtable_t;
-
-extern const double ahtable_max_load_factor;
-extern const size_t ahtable_initial_size;
-
-ahtable_t* ahtable_create (void); // Create an empty hash table.
-ahtable_t* ahtable_create_n (size_t n); // Create an empty hash table, with
- // n slots reserved.
-
-void ahtable_free (ahtable_t*); // Free all memory used by a table.
-void ahtable_clear (ahtable_t*); // Remove all entries.
-size_t ahtable_size (const ahtable_t*); // Number of stored keys.
-size_t ahtable_sizeof (const ahtable_t*); // Memory used by the table in bytes.
-
-
-/** Find the given key in the table, inserting it if it does not exist, and
- * returning a pointer to it's value.
- *
- * This pointer is not guaranteed to be valid after additional calls to
- * ahtable_get, ahtable_del, ahtable_clear, or other functions that modify the
- * table.
- */
-value_t* ahtable_get (ahtable_t*, const char* key, size_t len);
-
-
-/* Find a given key in the table, return a NULL pointer if it does not exist. */
-value_t* ahtable_tryget (ahtable_t*, const char* key, size_t len);
-
-
-int ahtable_del(ahtable_t*, const char* key, size_t len);
-
-
-typedef struct ahtable_iter_t_ ahtable_iter_t;
-
-ahtable_iter_t* ahtable_iter_begin (const ahtable_t*, bool sorted);
-void ahtable_iter_next (ahtable_iter_t*);
-bool ahtable_iter_finished (ahtable_iter_t*);
-void ahtable_iter_free (ahtable_iter_t*);
-const char* ahtable_iter_key (ahtable_iter_t*, size_t* len);
-value_t* ahtable_iter_val (ahtable_iter_t*);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/ext/include/htrie/common.h b/ext/include/htrie/common.h
deleted file mode 100644
index 7f0b034..0000000
--- a/ext/include/htrie/common.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * This file is part of hat-trie.
- *
- * Copyright (c) 2011 by Daniel C. Jones <dcjones at cs.washington.edu>
- *
- *
- * Common typedefs, etc.
- *
- */
-
-
-#ifndef HATTRIE_COMMON_H
-#define HATTRIE_COMMON_H
-
-#include <stdint.h>
-
-// an unsigned int that is guaranteed to be the same size as a pointer
-typedef uintptr_t value_t;
-
-#endif
-
-
diff --git a/ext/include/htrie/hat-trie.h b/ext/include/htrie/hat-trie.h
deleted file mode 100644
index 754d4f8..0000000
--- a/ext/include/htrie/hat-trie.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * This file is part of hat-trie
- *
- * Copyright (c) 2011 by Daniel C. Jones <dcjones at cs.washington.edu>
- *
- *
- * This is an implementation of the HAT-trie data structure described in,
- *
- * Askitis, N., & Sinha, R. (2007). HAT-trie: a cache-conscious trie-based data
- * structure for strings. Proceedings of the thirtieth Australasian conference on
- * Computer science-Volume 62 (pp. 97–105). Australian Computer Society, Inc.
- *
- * The HAT-trie is in essence a hybrid data structure, combining tries and hash
- * tables in a clever way to try to get the best of both worlds.
- *
- */
-
-#ifndef HATTRIE_HATTRIE_H
-#define HATTRIE_HATTRIE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "htrie/common.h"
-#include <stdlib.h>
-#include <stdbool.h>
-
-typedef struct hattrie_t_ hattrie_t;
-
-hattrie_t* hattrie_create (void); // Create an empty hat-trie.
-void hattrie_free (hattrie_t*); // Free all memory used by a trie.
-hattrie_t* hattrie_dup (const hattrie_t*); // Duplicate an existing trie.
-void hattrie_clear (hattrie_t*); // Remove all entries.
-size_t hattrie_size (const hattrie_t*); // Number of stored keys.
-size_t hattrie_sizeof (const hattrie_t*); // Memory used in structure in bytes.
-
-
-/** Find the given key in the trie, inserting it if it does not exist, and
- * returning a pointer to it's key.
- *
- * This pointer is not guaranteed to be valid after additional calls to
- * hattrie_get, hattrie_del, hattrie_clear, or other functions that modifies the
- * trie.
- */
-value_t* hattrie_get (hattrie_t*, const char* key, size_t len);
-
-
-/** Find a given key in the table, returning a NULL pointer if it does not
- * exist. */
-value_t* hattrie_tryget (hattrie_t*, const char* key, size_t len);
-
-/** Delete a given key from trie. Returns 0 if successful or -1 if not found.
- */
-int hattrie_del(hattrie_t* T, const char* key, size_t len);
-
-typedef struct hattrie_iter_t_ hattrie_iter_t;
-
-hattrie_iter_t* hattrie_iter_begin (const hattrie_t*, bool sorted);
-void hattrie_iter_next (hattrie_iter_t*);
-bool hattrie_iter_finished (hattrie_iter_t*);
-void hattrie_iter_free (hattrie_iter_t*);
-const char* hattrie_iter_key (hattrie_iter_t*, size_t* len);
-value_t* hattrie_iter_val (hattrie_iter_t*);
-
-/* Return true if two iterators are equal. */
-bool hattrie_iter_equal (const hattrie_iter_t* a,
- const hattrie_iter_t* b);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/ext/include/nlopt/auglag.h b/ext/include/nlopt/auglag.h
deleted file mode 100644
index 88981bf..0000000
--- a/ext/include/nlopt/auglag.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Copyright (c) 2007-2012 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef AUGLAG_H
-#define AUGLAG_H
-
-#include "nlopt.h"
-#include "nlopt-util.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-extern int auglag_verbose;
-
-nlopt_result auglag_minimize(int n, nlopt_func f, void *f_data,
- int m, nlopt_constraint *fc,
- int p, nlopt_constraint *h,
- const double *lb, const double *ub, /* bounds */
- double *x, /* in: initial guess, out: minimizer */
- double *minf,
- nlopt_stopping *stop,
- nlopt_opt sub_opt, int sub_has_fc);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif /* __cplusplus */
-
-#endif
-
diff --git a/ext/include/nlopt/bobyqa.h b/ext/include/nlopt/bobyqa.h
deleted file mode 100644
index 598753a..0000000
--- a/ext/include/nlopt/bobyqa.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef BOBYQA_H
-#define BOBYQA_H 1
-
-#include "nlopt-util.h"
-#include "nlopt.h"
-
-extern nlopt_result bobyqa(int n, int npt, double *x,
- const double *lb, const double *ub,
- const double *dx,
- nlopt_stopping *stop, double *minf,
- nlopt_func f, void *f_data);
-
-#endif /* BOBYQA_H */
diff --git a/ext/include/nlopt/cdirect.h b/ext/include/nlopt/cdirect.h
deleted file mode 100644
index 5a3f942..0000000
--- a/ext/include/nlopt/cdirect.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* Copyright (c) 2007-2012 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef CDIRECT_H
-#define CDIRECT_H
-
-#include "nlopt-util.h"
-#include "nlopt.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-extern nlopt_result cdirect_unscaled(int n, nlopt_func f, void *f_data,
- const double *lb, const double *ub,
- double *x,
- double *minf,
- nlopt_stopping *stop,
- double magic_eps, int which_alg);
-
-extern nlopt_result cdirect(int n, nlopt_func f, void *f_data,
- const double *lb, const double *ub,
- double *x,
- double *minf,
- nlopt_stopping *stop,
- double magic_eps, int which_alg);
-
-extern nlopt_result cdirect_hybrid(int n, nlopt_func f, void *f_data,
- const double *lb, const double *ub,
- double *x,
- double *minf,
- nlopt_stopping *stop,
- nlopt_algorithm local_alg,
- int local_maxeval,
- int randomized_div);
-
-extern nlopt_result cdirect_hybrid_unscaled(int n, nlopt_func f, void *f_data,
- const double *lb, const double *ub,
- double *x,
- double *minf,
- nlopt_stopping *stop,
- nlopt_algorithm local_alg,
- int local_maxeval,
- int randomized_div);
-
-/* internal routines and data structures: */
-extern int cdirect_hyperrect_compare(double *a, double *b);
-typedef struct {
- nlopt_func f;
- void *f_data;
- double *x;
- const double *lb, *ub;
-} cdirect_uf_data;
-extern double cdirect_uf(unsigned n, const double *xu, double *grad, void *d_);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif /* __cplusplus */
-
-#endif /* DIRECT_H */
diff --git a/ext/include/nlopt/cobyla.h b/ext/include/nlopt/cobyla.h
deleted file mode 100644
index fd71ee1..0000000
--- a/ext/include/nlopt/cobyla.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* cobyla : contrained optimization by linear approximation */
-
-/*
- * Copyright (c) 1992, Michael J. D. Powell (M.J.D.Powell at damtp.cam.ac.uk)
- * Copyright (c) 2004, Jean-Sebastien Roy (js at jeannot.org)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
- * This software is a C version of COBYLA2, a contrained optimization by linear
- * approximation package developed by Michael J. D. Powell in Fortran.
- *
- * The original source code can be found at :
- * http://plato.la.asu.edu/topics/problems/nlores.html
- */
-
-/* $Jeannot: cobyla.h,v 1.10 2004/04/18 09:51:37 js Exp $ */
-
-#ifndef _COBYLA_
-#define _COBYLA_
-
-#include "nlopt.h"
-#include "nlopt-util.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-/* NLopt-style interface function */
-nlopt_result cobyla_minimize(unsigned n, nlopt_func f, void *f_data,
- unsigned m, nlopt_constraint *fc,
- unsigned p, nlopt_constraint *h,
- const double *lb, const double *ub, /* bounds */
- double *x, /* in: initial guess, out: minimizer */
- double *minf,
- nlopt_stopping *stop,
- const double *dx);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _COBYLA_ */
diff --git a/ext/include/nlopt/crs.h b/ext/include/nlopt/crs.h
deleted file mode 100644
index 6df9f3d..0000000
--- a/ext/include/nlopt/crs.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Copyright (c) 2007-2012 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef CRS_H
-#define CRS_H
-
-#include "nlopt.h"
-#include "nlopt-util.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-nlopt_result crs_minimize(int n, nlopt_func f, void *f_data,
- const double *lb, const double *ub, /* bounds */
- double *x, /* in: initial guess, out: minimizer */
- double *minf,
- nlopt_stopping *stop,
- int population, /* initial population (0=default) */
- int random); /* random or low-discrepancy seq. */
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif /* __cplusplus */
-
-#endif
-
diff --git a/ext/include/nlopt/esch.h b/ext/include/nlopt/esch.h
deleted file mode 100644
index 8732e31..0000000
--- a/ext/include/nlopt/esch.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* Copyright (c) 2008-2013 Carlos Henrique da Silva Santos
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef ES_POP_H
-#define ES_POP_H 1
-
-#include "nlopt-util.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-nlopt_result chevolutionarystrategy(
- unsigned, /* Number of input parameters */
- nlopt_func, /* Recursive Objective Funtion Call */
- void *, /* Data to Objective Function */
- const double*, /* Lower bound values */
- const double*, /* Upper bound values */
- double*, /* in: initial guess, out: minimizer */
- double*,
- nlopt_stopping*, /* nlopt stop condition */
- unsigned, /* Number of Parents */
- unsigned); /* Number of Offsprings */
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif /* __cplusplus */
-
-#endif /* ES_POP_H */
diff --git a/ext/include/nlopt/isres.h b/ext/include/nlopt/isres.h
deleted file mode 100644
index 258e821..0000000
--- a/ext/include/nlopt/isres.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Copyright (c) 2007-2012 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef ISRES_H
-#define ISRES_H
-
-#include "nlopt.h"
-#include "nlopt-util.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-nlopt_result isres_minimize(int n, nlopt_func f, void *f_data,
- int m, nlopt_constraint *fc, /* fc <= 0 */
- int p, nlopt_constraint *h, /* h == 0 */
- const double *lb, const double *ub, /* bounds */
- double *x, /* in: initial guess, out: minimizer */
- double *minf,
- nlopt_stopping *stop,
- int population); /* init. population */
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif /* __cplusplus */
-
-#endif
-
diff --git a/ext/include/nlopt/mlsl.h b/ext/include/nlopt/mlsl.h
deleted file mode 100644
index 7e46c7f..0000000
--- a/ext/include/nlopt/mlsl.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Copyright (c) 2007-2012 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef MLSL_H
-#define MLSL_H
-
-#include "nlopt.h"
-#include "nlopt-util.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-nlopt_result mlsl_minimize(int n, nlopt_func f, void *f_data,
- const double *lb, const double *ub, /* bounds */
- double *x, /* in: initial guess, out: minimizer */
- double *minf,
- nlopt_stopping *stop,
- nlopt_opt local_opt,
- int Nsamples, /* #samples/iteration (0=default) */
- int lds);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif /* __cplusplus */
-
-#endif
-
diff --git a/ext/include/nlopt/mma.h b/ext/include/nlopt/mma.h
deleted file mode 100644
index a4e6073..0000000
--- a/ext/include/nlopt/mma.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Copyright (c) 2007-2012 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef MMA_H
-#define MMA_H
-
-#include "nlopt.h"
-#include "nlopt-util.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-extern unsigned mma_verbose;
-
-nlopt_result mma_minimize(unsigned n, nlopt_func f, void *f_data,
- unsigned m, nlopt_constraint *fc,
- const double *lb, const double *ub, /* bounds */
- double *x, /* in: initial guess, out: minimizer */
- double *minf,
- nlopt_stopping *stop,
- nlopt_opt dual_opt);
-
-nlopt_result ccsa_quadratic_minimize(
- unsigned n, nlopt_func f, void *f_data,
- unsigned m, nlopt_constraint *fc,
-
- nlopt_precond pre,
-
- const double *lb, const double *ub, /* bounds */
- double *x, /* in: initial guess, out: minimizer */
- double *minf,
- nlopt_stopping *stop,
- nlopt_opt dual_opt);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif /* __cplusplus */
-
-#endif
-
diff --git a/ext/include/nlopt/neldermead.h b/ext/include/nlopt/neldermead.h
deleted file mode 100644
index 453046d..0000000
--- a/ext/include/nlopt/neldermead.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Copyright (c) 2007-2012 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef NELDERMEAD_H
-#define NELDERMEAD_H
-
-#include "nlopt.h"
-#include "nlopt-util.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-nlopt_result nldrmd_minimize(int n, nlopt_func f, void *f_data,
- const double *lb, const double *ub, /* bounds */
- double *x, /* in: initial guess, out: minimizer */
- double *minf,
- const double *xstep, /* initial step sizes */
- nlopt_stopping *stop);
-
-nlopt_result nldrmd_minimize_(int n, nlopt_func f, void *f_data,
- const double *lb, const double *ub, /* bounds */
- double *x,/* in: initial guess, out: minimizer */
- double *minf,
- const double *xstep, /* initial step sizes */
- nlopt_stopping *stop,
- double psi, double *scratch, double *fdiff);
-
-nlopt_result sbplx_minimize(int n, nlopt_func f, void *f_data,
- const double *lb, const double *ub, /* bounds */
- double *x, /* in: initial guess, out: minimizer */
- double *minf,
- const double *xstep0, /* initial step sizes */
- nlopt_stopping *stop);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif /* __cplusplus */
-
-#endif
-
diff --git a/ext/include/nlopt/newuoa.h b/ext/include/nlopt/newuoa.h
deleted file mode 100644
index b270069..0000000
--- a/ext/include/nlopt/newuoa.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef NEWUOA_H
-#define NEWUOA_H 1
-
-#include "nlopt-util.h"
-#include "nlopt.h"
-
-typedef double (*newuoa_func)(int n, const double *x, void *func_data);
-
-extern nlopt_result newuoa(int n, int npt, double *x,
- const double *lb, const double *ub,
- double rhobeg, nlopt_stopping *stop, double *minf,
- newuoa_func calfun, void *calfun_data);
-
-#endif /* NEWUOA_H */
diff --git a/ext/include/nlopt/nlopt-internal.h b/ext/include/nlopt/nlopt-internal.h
deleted file mode 100644
index 841b81d..0000000
--- a/ext/include/nlopt/nlopt-internal.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* Copyright (c) 2007-2012 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef NLOPT_INTERNAL_H
-#define NLOPT_INTERNAL_H
-
-#include "nlopt/nlopt.h"
-#include "nlopt/nlopt-util.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-/*********************************************************************/
-
-struct nlopt_opt_s {
- nlopt_algorithm algorithm; /* the optimization algorithm (immutable) */
- unsigned n; /* the dimension of the problem (immutable) */
-
- nlopt_func f; void *f_data; /* objective function to minimize */
- nlopt_precond pre; /* optional preconditioner for f (NULL if none) */
- int maximize; /* nonzero if we are maximizing, not minimizing */
-
- double *lb, *ub; /* lower and upper bounds (length n) */
-
- unsigned m; /* number of inequality constraints */
- unsigned m_alloc; /* number of inequality constraints allocated */
- nlopt_constraint *fc; /* inequality constraints, length m_alloc */
-
- unsigned p; /* number of equality constraints */
- unsigned p_alloc; /* number of inequality constraints allocated */
- nlopt_constraint *h; /* equality constraints, length p_alloc */
-
- nlopt_munge munge_on_destroy, munge_on_copy; /* hack for wrappers */
-
- /* stopping criteria */
- double stopval; /* stop when f reaches stopval or better */
- double ftol_rel, ftol_abs; /* relative/absolute f tolerances */
- double xtol_rel, *xtol_abs; /* rel/abs x tolerances */
- int maxeval; /* max # evaluations */
- double maxtime; /* max time (seconds) */
-
- int force_stop; /* if nonzero, force a halt the next time we
- try to evaluate the objective during optimization */
- /* when local optimization is used, we need a force_stop in the
- parent object to force a stop in child optimizations */
- struct nlopt_opt_s *force_stop_child;
-
- /* algorithm-specific parameters */
- nlopt_opt local_opt; /* local optimizer */
- unsigned stochastic_population; /* population size for stochastic algs */
- double *dx; /* initial step sizes (length n) for nonderivative algs */
- unsigned vector_storage; /* max subspace dimension (0 for default) */
-
- void *work; /* algorithm-specific workspace during optimization */
-};
-
-/*********************************************************************/
-extern void nlopt_srand_time_default(void); /* init the rand. seed only if unset */
-
-/*********************************************************************/
-/* global defaults set by deprecated API: */
-
-extern nlopt_algorithm nlopt_local_search_alg_deriv;
-extern nlopt_algorithm nlopt_local_search_alg_nonderiv;
-extern int nlopt_local_search_maxeval;
-extern unsigned nlopt_stochastic_population;
-
-/*********************************************************************/
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif /* __cplusplus */
-
-#endif /* NLOPT_INTERNAL_H */
diff --git a/ext/include/nlopt/nlopt-util.h b/ext/include/nlopt/nlopt-util.h
deleted file mode 100644
index 5e40b4b..0000000
--- a/ext/include/nlopt/nlopt-util.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/* Copyright (c) 2007-2012 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef NLOPT_UTIL_H
-#define NLOPT_UTIL_H
-
-#include <stdlib.h>
-#include <math.h>
-
-#include "nlopt/nlopt.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-int nlopt_isinf(double x);
-
-/* re-entrant qsort */
-extern void nlopt_qsort_r(void *base_, size_t nmemb, size_t size, void *thunk,
- int (*compar)(void *, const void *, const void *));
-
-/* seconds timer */
-extern double nlopt_seconds(void);
-extern unsigned long nlopt_time_seed(void);
-
-/* pseudorandom number generation by Mersenne twister algorithm */
-extern void nlopt_init_genrand(unsigned long s);
-extern double nlopt_urand(double a, double b);
-extern int nlopt_iurand(int n);
-extern double nlopt_nrand(double mean, double stddev);
-
-/* Sobol' low-discrepancy-sequence generation */
-typedef struct nlopt_soboldata_s *nlopt_sobol;
-extern nlopt_sobol nlopt_sobol_create(unsigned sdim);
-extern void nlopt_sobol_destroy(nlopt_sobol s);
-extern void nlopt_sobol_next01(nlopt_sobol s, double *x);
-extern void nlopt_sobol_next(nlopt_sobol s, double *x,
- const double *lb, const double *ub);
-extern void nlopt_sobol_skip(nlopt_sobol s, unsigned n, double *x);
-
-/* stopping criteria */
-typedef struct {
- unsigned n;
- double minf_max;
- double ftol_rel;
- double ftol_abs;
- double xtol_rel;
- const double *xtol_abs;
- int nevals, maxeval;
- double maxtime, start;
- int *force_stop;
-} nlopt_stopping;
-extern int nlopt_stop_f(const nlopt_stopping *stop, double f, double oldf);
-extern int nlopt_stop_ftol(const nlopt_stopping *stop, double f, double oldf);
-extern int nlopt_stop_x(const nlopt_stopping *stop,
- const double *x, const double *oldx);
-extern int nlopt_stop_dx(const nlopt_stopping *stop,
- const double *x, const double *dx);
-extern int nlopt_stop_xs(const nlopt_stopping *stop,
- const double *xs, const double *oldxs,
- const double *scale_min, const double *scale_max);
-extern int nlopt_stop_evals(const nlopt_stopping *stop);
-extern int nlopt_stop_time_(double start, double maxtime);
-extern int nlopt_stop_time(const nlopt_stopping *stop);
-extern int nlopt_stop_evalstime(const nlopt_stopping *stop);
-extern int nlopt_stop_forced(const nlopt_stopping *stop);
-
-/* for local optimizations, temporarily setting eval/time limits */
-extern nlopt_result nlopt_optimize_limited(nlopt_opt opt,
- double *x, double *minf,
- int maxevals, double maxtime);
-
-/* data structure for nonlinear inequality or equality constraint
- (f <= 0 or f = 0, respectively). tol (>= 0) is a tolerance
- that is used for stopping criteria -- the point is considered
- "feasible" for purposes of stopping if the constraint is violated
- by at most tol. */
-typedef struct {
- unsigned m; /* dimensional of constraint: mf maps R^n -> R^m */
- nlopt_func f; /* one-dimensional constraint, requires m == 1 */
- nlopt_mfunc mf;
- nlopt_precond pre; /* preconditioner for f (NULL if none or if mf) */
- void *f_data;
- double *tol;
-} nlopt_constraint;
-
-extern unsigned nlopt_count_constraints(unsigned p, const nlopt_constraint *c);
-extern unsigned nlopt_max_constraint_dim(unsigned p, const nlopt_constraint *c);
-extern void nlopt_eval_constraint(double *result, double *grad,
- const nlopt_constraint *c,
- unsigned n, const double *x);
-
-/* rescale.c: */
-double *nlopt_compute_rescaling(unsigned n, const double *dx);
-double *nlopt_new_rescaled(unsigned n, const double *s, const double *x);
-void nlopt_rescale(unsigned n, const double *s, const double *x, double *xs);
-void nlopt_unscale(unsigned n, const double *s, const double *x, double *xs);
-void nlopt_reorder_bounds(unsigned n, double *lb, double *ub);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif /* __cplusplus */
-
-#endif
diff --git a/ext/include/nlopt/nlopt.h b/ext/include/nlopt/nlopt.h
deleted file mode 100644
index 16696c8..0000000
--- a/ext/include/nlopt/nlopt.h
+++ /dev/null
@@ -1,379 +0,0 @@
-/* Copyright (c) 2007-2012 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef NLOPT_H
-#define NLOPT_H
-
-#include <stddef.h> /* for ptrdiff_t and size_t */
-
-/* Change 0 to 1 to use stdcall convention under Win32 */
-#if 0 && (defined(_WIN32) || defined(__WIN32__))
-# if defined(__GNUC__)
-# define NLOPT_STDCALL __attribute__((stdcall))
-# elif defined(_MSC_VER) || defined(_ICC) || defined(_STDCALL_SUPPORTED)
-# define NLOPT_STDCALL __stdcall
-# else
-# define NLOPT_STDCALL
-# endif
-#else
-# define NLOPT_STDCALL
-#endif
-
-/* for Windows compilers, you should add a line
- #define NLOPT_DLL
- when using NLopt from a DLL, in order to do the proper
- Windows importing nonsense. */
-#if defined(NLOPT_DLL) && (defined(_WIN32) || defined(__WIN32__)) && !defined(__LCC__)
-/* annoying Windows syntax for calling functions in a DLL */
-# if defined(NLOPT_DLL_EXPORT)
-# define NLOPT_EXTERN(T) extern __declspec(dllexport) T NLOPT_STDCALL
-# else
-# define NLOPT_EXTERN(T) extern __declspec(dllimport) T NLOPT_STDCALL
-# endif
-#else
-# define NLOPT_EXTERN(T) extern T NLOPT_STDCALL
-#endif
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-typedef double (*nlopt_func)(unsigned n, const double *x,
- double *gradient, /* NULL if not needed */
- void *func_data);
-
-typedef void (*nlopt_mfunc)(unsigned m, double *result,
- unsigned n, const double *x,
- double *gradient, /* NULL if not needed */
- void *func_data);
-
-/* A preconditioner, which preconditions v at x to return vpre.
- (The meaning of "preconditioning" is algorithm-dependent.) */
-typedef void (*nlopt_precond)(unsigned n, const double *x, const double *v,
- double *vpre, void *data);
-
-typedef enum {
- /* Naming conventions:
-
- NLOPT_{G/L}{D/N}_*
- = global/local derivative/no-derivative optimization,
- respectively
-
- *_RAND algorithms involve some randomization.
-
- *_NOSCAL algorithms are *not* scaled to a unit hypercube
- (i.e. they are sensitive to the units of x)
- */
-
- NLOPT_GN_DIRECT = 0,
- NLOPT_GN_DIRECT_L,
- NLOPT_GN_DIRECT_L_RAND,
- NLOPT_GN_DIRECT_NOSCAL,
- NLOPT_GN_DIRECT_L_NOSCAL,
- NLOPT_GN_DIRECT_L_RAND_NOSCAL,
-
- NLOPT_GN_ORIG_DIRECT,
- NLOPT_GN_ORIG_DIRECT_L,
-
- NLOPT_GD_STOGO,
- NLOPT_GD_STOGO_RAND,
-
- NLOPT_LD_LBFGS_NOCEDAL,
-
- NLOPT_LD_LBFGS,
-
- NLOPT_LN_PRAXIS,
-
- NLOPT_LD_VAR1,
- NLOPT_LD_VAR2,
-
- NLOPT_LD_TNEWTON,
- NLOPT_LD_TNEWTON_RESTART,
- NLOPT_LD_TNEWTON_PRECOND,
- NLOPT_LD_TNEWTON_PRECOND_RESTART,
-
- NLOPT_GN_CRS2_LM,
-
- NLOPT_GN_MLSL,
- NLOPT_GD_MLSL,
- NLOPT_GN_MLSL_LDS,
- NLOPT_GD_MLSL_LDS,
-
- NLOPT_LD_MMA,
-
- NLOPT_LN_COBYLA,
-
- NLOPT_LN_NEWUOA,
- NLOPT_LN_NEWUOA_BOUND,
-
- NLOPT_LN_NELDERMEAD,
- NLOPT_LN_SBPLX,
-
- NLOPT_LN_AUGLAG,
- NLOPT_LD_AUGLAG,
- NLOPT_LN_AUGLAG_EQ,
- NLOPT_LD_AUGLAG_EQ,
-
- NLOPT_LN_BOBYQA,
-
- NLOPT_GN_ISRES,
-
- /* new variants that require local_optimizer to be set,
- not with older constants for backwards compatibility */
- NLOPT_AUGLAG,
- NLOPT_AUGLAG_EQ,
- NLOPT_G_MLSL,
- NLOPT_G_MLSL_LDS,
-
- NLOPT_LD_SLSQP,
-
- NLOPT_LD_CCSAQ,
-
- NLOPT_GN_ESCH,
-
- NLOPT_NUM_ALGORITHMS /* not an algorithm, just the number of them */
-} nlopt_algorithm;
-
-NLOPT_EXTERN(const char *) nlopt_algorithm_name(nlopt_algorithm a);
-
-typedef enum {
- NLOPT_FAILURE = -1, /* generic failure code */
- NLOPT_INVALID_ARGS = -2,
- NLOPT_OUT_OF_MEMORY = -3,
- NLOPT_ROUNDOFF_LIMITED = -4,
- NLOPT_FORCED_STOP = -5,
- NLOPT_SUCCESS = 1, /* generic success code */
- NLOPT_STOPVAL_REACHED = 2,
- NLOPT_FTOL_REACHED = 3,
- NLOPT_XTOL_REACHED = 4,
- NLOPT_MAXEVAL_REACHED = 5,
- NLOPT_MAXTIME_REACHED = 6
-} nlopt_result;
-
-#define NLOPT_MINF_MAX_REACHED NLOPT_STOPVAL_REACHED
-
-NLOPT_EXTERN(void) nlopt_srand(unsigned long seed);
-NLOPT_EXTERN(void) nlopt_srand_time(void);
-
-NLOPT_EXTERN(void) nlopt_version(int *major, int *minor, int *bugfix);
-
-/*************************** OBJECT-ORIENTED API **************************/
-/* The style here is that we create an nlopt_opt "object" (an opaque pointer),
- then set various optimization parameters, and then execute the
- algorithm. In this way, we can add more and more optimization parameters
- (including algorithm-specific ones) without breaking backwards
- compatibility, having functions with zillions of parameters, or
- relying non-reentrantly on global variables.*/
-
-struct nlopt_opt_s; /* opaque structure, defined internally */
-typedef struct nlopt_opt_s *nlopt_opt;
-
-/* the only immutable parameters of an optimization are the algorithm and
- the dimension n of the problem, since changing either of these could
- have side-effects on lots of other parameters */
-NLOPT_EXTERN(nlopt_opt) nlopt_create(nlopt_algorithm algorithm, unsigned n);
-NLOPT_EXTERN(void) nlopt_destroy(nlopt_opt opt);
-NLOPT_EXTERN(nlopt_opt) nlopt_copy(const nlopt_opt opt);
-
-NLOPT_EXTERN(nlopt_result) nlopt_optimize(nlopt_opt opt, double *x,
- double *opt_f);
-
-NLOPT_EXTERN(nlopt_result) nlopt_set_min_objective(nlopt_opt opt, nlopt_func f,
- void *f_data);
-NLOPT_EXTERN(nlopt_result) nlopt_set_max_objective(nlopt_opt opt, nlopt_func f,
- void *f_data);
-
-NLOPT_EXTERN(nlopt_result) nlopt_set_precond_min_objective(nlopt_opt opt, nlopt_func f, nlopt_precond pre, void *f_data);
-NLOPT_EXTERN(nlopt_result) nlopt_set_precond_max_objective(nlopt_opt opt, nlopt_func f, nlopt_precond pre, void *f_data);
-
-NLOPT_EXTERN(nlopt_algorithm) nlopt_get_algorithm(const nlopt_opt opt);
-NLOPT_EXTERN(unsigned) nlopt_get_dimension(const nlopt_opt opt);
-
-/* constraints: */
-
-NLOPT_EXTERN(nlopt_result) nlopt_set_lower_bounds(nlopt_opt opt,
- const double *lb);
-NLOPT_EXTERN(nlopt_result) nlopt_set_lower_bounds1(nlopt_opt opt, double lb);
-NLOPT_EXTERN(nlopt_result) nlopt_get_lower_bounds(const nlopt_opt opt,
- double *lb);
-NLOPT_EXTERN(nlopt_result) nlopt_set_upper_bounds(nlopt_opt opt,
- const double *ub);
-NLOPT_EXTERN(nlopt_result) nlopt_set_upper_bounds1(nlopt_opt opt, double ub);
-NLOPT_EXTERN(nlopt_result) nlopt_get_upper_bounds(const nlopt_opt opt,
- double *ub);
-
-NLOPT_EXTERN(nlopt_result) nlopt_remove_inequality_constraints(nlopt_opt opt);
-NLOPT_EXTERN(nlopt_result) nlopt_add_inequality_constraint(nlopt_opt opt,
- nlopt_func fc,
- void *fc_data,
- double tol);
-NLOPT_EXTERN(nlopt_result) nlopt_add_precond_inequality_constraint(
- nlopt_opt opt, nlopt_func fc, nlopt_precond pre, void *fc_data,
- double tol);
-NLOPT_EXTERN(nlopt_result) nlopt_add_inequality_mconstraint(nlopt_opt opt,
- unsigned m,
- nlopt_mfunc fc,
- void *fc_data,
- const double *tol);
-
-NLOPT_EXTERN(nlopt_result) nlopt_remove_equality_constraints(nlopt_opt opt);
-NLOPT_EXTERN(nlopt_result) nlopt_add_equality_constraint(nlopt_opt opt,
- nlopt_func h,
- void *h_data,
- double tol);
-NLOPT_EXTERN(nlopt_result) nlopt_add_precond_equality_constraint(
- nlopt_opt opt, nlopt_func h, nlopt_precond pre, void *h_data,
- double tol);
-NLOPT_EXTERN(nlopt_result) nlopt_add_equality_mconstraint(nlopt_opt opt,
- unsigned m,
- nlopt_mfunc h,
- void *h_data,
- const double *tol);
-
-/* stopping criteria: */
-
-NLOPT_EXTERN(nlopt_result) nlopt_set_stopval(nlopt_opt opt, double stopval);
-NLOPT_EXTERN(double) nlopt_get_stopval(const nlopt_opt opt);
-
-NLOPT_EXTERN(nlopt_result) nlopt_set_ftol_rel(nlopt_opt opt, double tol);
-NLOPT_EXTERN(double) nlopt_get_ftol_rel(const nlopt_opt opt);
-NLOPT_EXTERN(nlopt_result) nlopt_set_ftol_abs(nlopt_opt opt, double tol);
-NLOPT_EXTERN(double) nlopt_get_ftol_abs(const nlopt_opt opt);
-
-NLOPT_EXTERN(nlopt_result) nlopt_set_xtol_rel(nlopt_opt opt, double tol);
-NLOPT_EXTERN(double) nlopt_get_xtol_rel(const nlopt_opt opt);
-NLOPT_EXTERN(nlopt_result) nlopt_set_xtol_abs1(nlopt_opt opt, double tol);
-NLOPT_EXTERN(nlopt_result) nlopt_set_xtol_abs(nlopt_opt opt, const double *tol);
-NLOPT_EXTERN(nlopt_result) nlopt_get_xtol_abs(const nlopt_opt opt,
- double *tol);
-
-NLOPT_EXTERN(nlopt_result) nlopt_set_maxeval(nlopt_opt opt, int maxeval);
-NLOPT_EXTERN(int) nlopt_get_maxeval(const nlopt_opt opt);
-
-NLOPT_EXTERN(nlopt_result) nlopt_set_maxtime(nlopt_opt opt, double maxtime);
-NLOPT_EXTERN(double) nlopt_get_maxtime(const nlopt_opt opt);
-
-NLOPT_EXTERN(nlopt_result) nlopt_force_stop(nlopt_opt opt);
-NLOPT_EXTERN(nlopt_result) nlopt_set_force_stop(nlopt_opt opt, int val);
-NLOPT_EXTERN(int) nlopt_get_force_stop(const nlopt_opt opt);
-
-/* more algorithm-specific parameters */
-
-NLOPT_EXTERN(nlopt_result) nlopt_set_local_optimizer(nlopt_opt opt,
- const nlopt_opt local_opt);
-
-NLOPT_EXTERN(nlopt_result) nlopt_set_population(nlopt_opt opt, unsigned pop);
-NLOPT_EXTERN(unsigned) nlopt_get_population(const nlopt_opt opt);
-
-NLOPT_EXTERN(nlopt_result) nlopt_set_vector_storage(nlopt_opt opt, unsigned dim);
-NLOPT_EXTERN(unsigned) nlopt_get_vector_storage(const nlopt_opt opt);
-
-NLOPT_EXTERN(nlopt_result) nlopt_set_default_initial_step(nlopt_opt opt,
- const double *x);
-NLOPT_EXTERN(nlopt_result) nlopt_set_initial_step(nlopt_opt opt,
- const double *dx);
-NLOPT_EXTERN(nlopt_result) nlopt_set_initial_step1(nlopt_opt opt, double dx);
-NLOPT_EXTERN(nlopt_result) nlopt_get_initial_step(const nlopt_opt opt,
- const double *x, double *dx);
-
-/* the following are functions mainly designed to be used internally
- by the Fortran and SWIG wrappers, allow us to tel nlopt_destroy and
- nlopt_copy to do something to the f_data pointers (e.g. free or
- duplicate them, respectively) */
-typedef void* (*nlopt_munge)(void *p);
-NLOPT_EXTERN(void) nlopt_set_munge(nlopt_opt opt,
- nlopt_munge munge_on_destroy,
- nlopt_munge munge_on_copy);
-typedef void* (*nlopt_munge2)(void *p, void *data);
-NLOPT_EXTERN(void) nlopt_munge_data(nlopt_opt opt,
- nlopt_munge2 munge, void *data);
-
-/*************************** DEPRECATED API **************************/
-/* The new "object-oriented" API is preferred, since it allows us to
- gracefully add new features and algorithm-specific options in a
- re-entrant way, and we can automatically assume reasonable defaults
- for unspecified parameters. */
-
-/* Where possible (e.g. for gcc >= 3.1), enable a compiler warning
- for code that uses a deprecated function */
-#if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__==3 && __GNUC_MINOR__ > 0))
-# define NLOPT_DEPRECATED __attribute__((deprecated))
-#else
-# define NLOPT_DEPRECATED
-#endif
-
-typedef double (*nlopt_func_old)(int n, const double *x,
- double *gradient, /* NULL if not needed */
- void *func_data);
-
-NLOPT_EXTERN(nlopt_result) nlopt_minimize(
- nlopt_algorithm algorithm,
- int n, nlopt_func_old f, void *f_data,
- const double *lb, const double *ub, /* bounds */
- double *x, /* in: initial guess, out: minimizer */
- double *minf, /* out: minimum */
- double minf_max, double ftol_rel, double ftol_abs,
- double xtol_rel, const double *xtol_abs,
- int maxeval, double maxtime) NLOPT_DEPRECATED;
-
-NLOPT_EXTERN(nlopt_result) nlopt_minimize_constrained(
- nlopt_algorithm algorithm,
- int n, nlopt_func_old f, void *f_data,
- int m, nlopt_func_old fc, void *fc_data, ptrdiff_t fc_datum_size,
- const double *lb, const double *ub, /* bounds */
- double *x, /* in: initial guess, out: minimizer */
- double *minf, /* out: minimum */
- double minf_max, double ftol_rel, double ftol_abs,
- double xtol_rel, const double *xtol_abs,
- int maxeval, double maxtime) NLOPT_DEPRECATED;
-
-NLOPT_EXTERN(nlopt_result) nlopt_minimize_econstrained(
- nlopt_algorithm algorithm,
- int n, nlopt_func_old f, void *f_data,
- int m, nlopt_func_old fc, void *fc_data, ptrdiff_t fc_datum_size,
- int p, nlopt_func_old h, void *h_data, ptrdiff_t h_datum_size,
- const double *lb, const double *ub, /* bounds */
- double *x, /* in: initial guess, out: minimizer */
- double *minf, /* out: minimum */
- double minf_max, double ftol_rel, double ftol_abs,
- double xtol_rel, const double *xtol_abs,
- double htol_rel, double htol_abs,
- int maxeval, double maxtime) NLOPT_DEPRECATED;
-
-NLOPT_EXTERN(void) nlopt_get_local_search_algorithm(nlopt_algorithm *deriv,
- nlopt_algorithm *nonderiv,
- int *maxeval) NLOPT_DEPRECATED;
-NLOPT_EXTERN(void) nlopt_set_local_search_algorithm(nlopt_algorithm deriv,
- nlopt_algorithm nonderiv,
- int maxeval) NLOPT_DEPRECATED;
-
-NLOPT_EXTERN(int) nlopt_get_stochastic_population(void) NLOPT_DEPRECATED;
-NLOPT_EXTERN(void) nlopt_set_stochastic_population(int pop) NLOPT_DEPRECATED;
-
-/*********************************************************************/
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif /* __cplusplus */
-
-#endif
diff --git a/ext/include/nlopt/nlopt.hpp b/ext/include/nlopt/nlopt.hpp
deleted file mode 100644
index d9ee9b4..0000000
--- a/ext/include/nlopt/nlopt.hpp
+++ /dev/null
@@ -1,596 +0,0 @@
-/* Copyright (c) 2007-2011 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-// C++ style wrapper around NLopt API
-// nlopt.hpp is AUTOMATICALLY GENERATED from nlopt-in.hpp - edit the latter!
-
-#ifndef NLOPT_HPP
-#define NLOPT_HPP
-
-#include <nlopt/nlopt.h>
-
-#include <vector>
-#include <stdexcept>
-#include <new>
-#include <cstdlib>
-#include <cstring>
-#include <cmath>
-
-// convenience overloading for below (not in nlopt:: since has nlopt_ prefix)
-inline nlopt_result nlopt_get_initial_step(const nlopt_opt opt, double *dx) {
- return nlopt_get_initial_step(opt, (const double *) NULL, dx);
-}
-
-namespace nlopt {
-
- //////////////////////////////////////////////////////////////////////
- // nlopt::* namespace versions of the C enumerated types
- // AUTOMATICALLY GENERATED, DO NOT EDIT
- // GEN_ENUMS_HERE
- enum algorithm {
- GN_DIRECT = 0,
- GN_DIRECT_L,
- GN_DIRECT_L_RAND,
- GN_DIRECT_NOSCAL,
- GN_DIRECT_L_NOSCAL,
- GN_DIRECT_L_RAND_NOSCAL,
- GN_ORIG_DIRECT,
- GN_ORIG_DIRECT_L,
- GD_STOGO,
- GD_STOGO_RAND,
- LD_LBFGS_NOCEDAL,
- LD_LBFGS,
- LN_PRAXIS,
- LD_VAR1,
- LD_VAR2,
- LD_TNEWTON,
- LD_TNEWTON_RESTART,
- LD_TNEWTON_PRECOND,
- LD_TNEWTON_PRECOND_RESTART,
- GN_CRS2_LM,
- GN_MLSL,
- GD_MLSL,
- GN_MLSL_LDS,
- GD_MLSL_LDS,
- LD_MMA,
- LN_COBYLA,
- LN_NEWUOA,
- LN_NEWUOA_BOUND,
- LN_NELDERMEAD,
- LN_SBPLX,
- LN_AUGLAG,
- LD_AUGLAG,
- LN_AUGLAG_EQ,
- LD_AUGLAG_EQ,
- LN_BOBYQA,
- GN_ISRES,
- AUGLAG,
- AUGLAG_EQ,
- G_MLSL,
- G_MLSL_LDS,
- LD_SLSQP,
- LD_CCSAQ,
- GN_ESCH,
- NUM_ALGORITHMS /* not an algorithm, just the number of them */
- };
- enum result {
- FAILURE = -1, /* generic failure code */
- INVALID_ARGS = -2,
- OUT_OF_MEMORY = -3,
- ROUNDOFF_LIMITED = -4,
- FORCED_STOP = -5,
- SUCCESS = 1, /* generic success code */
- STOPVAL_REACHED = 2,
- FTOL_REACHED = 3,
- XTOL_REACHED = 4,
- MAXEVAL_REACHED = 5,
- MAXTIME_REACHED = 6
- };
- // GEN_ENUMS_HERE
- //////////////////////////////////////////////////////////////////////
-
- typedef nlopt_func func; // nlopt::func synoynm
- typedef nlopt_mfunc mfunc; // nlopt::mfunc synoynm
-
- // alternative to nlopt_func that takes std::vector<double>
- // ... unfortunately requires a data copy
- typedef double (*vfunc)(const std::vector<double> &x,
- std::vector<double> &grad, void *data);
-
- //////////////////////////////////////////////////////////////////////
-
- // NLopt-specific exceptions (corresponding to error codes):
- class roundoff_limited : public std::runtime_error {
- public:
- roundoff_limited() : std::runtime_error("nlopt roundoff-limited") {}
- };
-
- class forced_stop : public std::runtime_error {
- public:
- forced_stop() : std::runtime_error("nlopt forced stop") {}
- };
-
- //////////////////////////////////////////////////////////////////////
-
- class opt {
- private:
- nlopt_opt o;
-
- void mythrow(nlopt_result ret) const {
- switch (ret) {
- case NLOPT_FAILURE: throw std::runtime_error("nlopt failure");
- case NLOPT_OUT_OF_MEMORY: throw std::bad_alloc();
- case NLOPT_INVALID_ARGS: throw std::invalid_argument("nlopt invalid argument");
- case NLOPT_ROUNDOFF_LIMITED: throw roundoff_limited();
- case NLOPT_FORCED_STOP: throw forced_stop();
- default: break;
- }
- }
-
- typedef struct {
- opt *o;
- mfunc mf; func f; void *f_data;
- vfunc vf;
- nlopt_munge munge_destroy, munge_copy; // non-NULL for SWIG wrappers
- } myfunc_data;
-
- // free/destroy f_data in nlopt_destroy and nlopt_copy, respectively
- static void *free_myfunc_data(void *p) {
- myfunc_data *d = (myfunc_data *) p;
- if (d) {
- if (d->f_data && d->munge_destroy) d->munge_destroy(d->f_data);
- delete d;
- }
- return NULL;
- }
- static void *dup_myfunc_data(void *p) {
- myfunc_data *d = (myfunc_data *) p;
- if (d) {
- void *f_data;
- if (d->f_data && d->munge_copy) {
- f_data = d->munge_copy(d->f_data);
- if (!f_data) return NULL;
- }
- else
- f_data = d->f_data;
- myfunc_data *dnew = new myfunc_data;
- if (dnew) {
- *dnew = *d;
- dnew->f_data = f_data;
- }
- return (void*) dnew;
- }
- else return NULL;
- }
-
- // nlopt_func wrapper that catches exceptions
- static double myfunc(unsigned n, const double *x, double *grad, void *d_) {
- myfunc_data *d = reinterpret_cast<myfunc_data*>(d_);
- try {
- return d->f(n, x, grad, d->f_data);
- }
- catch (std::bad_alloc&)
- { d->o->forced_stop_reason = NLOPT_OUT_OF_MEMORY; }
- catch (std::invalid_argument&)
- { d->o->forced_stop_reason = NLOPT_INVALID_ARGS; }
- catch (roundoff_limited&)
- { d->o->forced_stop_reason = NLOPT_ROUNDOFF_LIMITED; }
- catch (forced_stop&)
- { d->o->forced_stop_reason = NLOPT_FORCED_STOP; }
- catch (...)
- { d->o->forced_stop_reason = NLOPT_FAILURE; }
- d->o->force_stop(); // stop gracefully, opt::optimize will re-throw
- return HUGE_VAL;
- }
-
- // nlopt_mfunc wrapper that catches exceptions
- static void mymfunc(unsigned m, double *result,
- unsigned n, const double *x, double *grad, void *d_) {
- myfunc_data *d = reinterpret_cast<myfunc_data*>(d_);
- try {
- d->mf(m, result, n, x, grad, d->f_data);
- return;
- }
- catch (std::bad_alloc&)
- { d->o->forced_stop_reason = NLOPT_OUT_OF_MEMORY; }
- catch (std::invalid_argument&)
- { d->o->forced_stop_reason = NLOPT_INVALID_ARGS; }
- catch (roundoff_limited&)
- { d->o->forced_stop_reason = NLOPT_ROUNDOFF_LIMITED; }
- catch (forced_stop&)
- { d->o->forced_stop_reason = NLOPT_FORCED_STOP; }
- catch (...)
- { d->o->forced_stop_reason = NLOPT_FAILURE; }
- d->o->force_stop(); // stop gracefully, opt::optimize will re-throw
- for (unsigned i = 0; i < m; ++i) result[i] = HUGE_VAL;
- }
-
- std::vector<double> xtmp, gradtmp, gradtmp0; // scratch for myvfunc
-
- // nlopt_func wrapper, using std::vector<double>
- static double myvfunc(unsigned n, const double *x, double *grad, void *d_){
- myfunc_data *d = reinterpret_cast<myfunc_data*>(d_);
- try {
- std::vector<double> &xv = d->o->xtmp;
- if (n) std::memcpy(&xv[0], x, n * sizeof(double));
- double val=d->vf(xv, grad ? d->o->gradtmp : d->o->gradtmp0, d->f_data);
- if (grad && n) {
- std::vector<double> &gradv = d->o->gradtmp;
- std::memcpy(grad, &gradv[0], n * sizeof(double));
- }
- return val;
- }
- catch (std::bad_alloc&)
- { d->o->forced_stop_reason = NLOPT_OUT_OF_MEMORY; }
- catch (std::invalid_argument&)
- { d->o->forced_stop_reason = NLOPT_INVALID_ARGS; }
- catch (roundoff_limited&)
- { d->o->forced_stop_reason = NLOPT_ROUNDOFF_LIMITED; }
- catch (forced_stop&)
- { d->o->forced_stop_reason = NLOPT_FORCED_STOP; }
- catch (...)
- { d->o->forced_stop_reason = NLOPT_FAILURE; }
- d->o->force_stop(); // stop gracefully, opt::optimize will re-throw
- return HUGE_VAL;
- }
-
- void alloc_tmp() {
- if (xtmp.size() != nlopt_get_dimension(o)) {
- xtmp = std::vector<double>(nlopt_get_dimension(o));
- gradtmp = std::vector<double>(nlopt_get_dimension(o));
- }
- }
-
- result last_result;
- double last_optf;
- nlopt_result forced_stop_reason;
-
- public:
- // Constructors etc.
- opt() : o(NULL), xtmp(0), gradtmp(0), gradtmp0(0),
- last_result(nlopt::FAILURE), last_optf(HUGE_VAL),
- forced_stop_reason(NLOPT_FORCED_STOP) {}
- ~opt() { nlopt_destroy(o); }
- opt(algorithm a, unsigned n) :
- o(nlopt_create(nlopt_algorithm(a), n)),
- xtmp(0), gradtmp(0), gradtmp0(0),
- last_result(nlopt::FAILURE), last_optf(HUGE_VAL),
- forced_stop_reason(NLOPT_FORCED_STOP) {
- if (!o) throw std::bad_alloc();
- nlopt_set_munge(o, free_myfunc_data, dup_myfunc_data);
- }
- opt(const opt& f) : o(nlopt_copy(f.o)),
- xtmp(f.xtmp), gradtmp(f.gradtmp), gradtmp0(0),
- last_result(f.last_result), last_optf(f.last_optf),
- forced_stop_reason(f.forced_stop_reason) {
- if (f.o && !o) throw std::bad_alloc();
- }
- opt& operator=(opt const& f) {
- if (this == &f) return *this; // self-assignment
- nlopt_destroy(o);
- o = nlopt_copy(f.o);
- if (f.o && !o) throw std::bad_alloc();
- xtmp = f.xtmp; gradtmp = f.gradtmp;
- last_result = f.last_result; last_optf = f.last_optf;
- forced_stop_reason = f.forced_stop_reason;
- return *this;
- }
-
- // Do the optimization:
- result optimize(std::vector<double> &x, double &opt_f) {
- if (o && nlopt_get_dimension(o) != x.size())
- throw std::invalid_argument("dimension mismatch");
- forced_stop_reason = NLOPT_FORCED_STOP;
- nlopt_result ret = nlopt_optimize(o, x.empty() ? NULL : &x[0], &opt_f);
- last_result = result(ret);
- last_optf = opt_f;
- if (ret == NLOPT_FORCED_STOP)
- mythrow(forced_stop_reason);
- mythrow(ret);
- return last_result;
- }
-
- // variant mainly useful for SWIG wrappers:
- std::vector<double> optimize(const std::vector<double> &x0) {
- std::vector<double> x(x0);
- last_result = optimize(x, last_optf);
- return x;
- }
- result last_optimize_result() const { return last_result; }
- double last_optimum_value() const { return last_optf; }
-
- // accessors:
- algorithm get_algorithm() const {
- if (!o) throw std::runtime_error("uninitialized nlopt::opt");
- return algorithm(nlopt_get_algorithm(o));
- }
- const char *get_algorithm_name() const {
- if (!o) throw std::runtime_error("uninitialized nlopt::opt");
- return nlopt_algorithm_name(nlopt_get_algorithm(o));
- }
- unsigned get_dimension() const {
- if (!o) throw std::runtime_error("uninitialized nlopt::opt");
- return nlopt_get_dimension(o);
- }
-
- // Set the objective function
- void set_min_objective(func f, void *f_data) {
- myfunc_data *d = new myfunc_data;
- if (!d) throw std::bad_alloc();
- d->o = this; d->f = f; d->f_data = f_data; d->mf = NULL; d->vf = NULL;
- d->munge_destroy = d->munge_copy = NULL;
- mythrow(nlopt_set_min_objective(o, myfunc, d)); // d freed via o
- }
- void set_min_objective(vfunc vf, void *f_data) {
- myfunc_data *d = new myfunc_data;
- if (!d) throw std::bad_alloc();
- d->o = this; d->f = NULL; d->f_data = f_data; d->mf = NULL; d->vf = vf;
- d->munge_destroy = d->munge_copy = NULL;
- mythrow(nlopt_set_min_objective(o, myvfunc, d)); // d freed via o
- alloc_tmp();
- }
- void set_max_objective(func f, void *f_data) {
- myfunc_data *d = new myfunc_data;
- if (!d) throw std::bad_alloc();
- d->o = this; d->f = f; d->f_data = f_data; d->mf = NULL; d->vf = NULL;
- d->munge_destroy = d->munge_copy = NULL;
- mythrow(nlopt_set_max_objective(o, myfunc, d)); // d freed via o
- }
- void set_max_objective(vfunc vf, void *f_data) {
- myfunc_data *d = new myfunc_data;
- if (!d) throw std::bad_alloc();
- d->o = this; d->f = NULL; d->f_data = f_data; d->mf = NULL; d->vf = vf;
- d->munge_destroy = d->munge_copy = NULL;
- mythrow(nlopt_set_max_objective(o, myvfunc, d)); // d freed via o
- alloc_tmp();
- }
-
- // for internal use in SWIG wrappers -- variant that
- // takes ownership of f_data, with munging for destroy/copy
- void set_min_objective(func f, void *f_data,
- nlopt_munge md, nlopt_munge mc) {
- myfunc_data *d = new myfunc_data;
- if (!d) throw std::bad_alloc();
- d->o = this; d->f = f; d->f_data = f_data; d->mf = NULL; d->vf = NULL;
- d->munge_destroy = md; d->munge_copy = mc;
- mythrow(nlopt_set_min_objective(o, myfunc, d)); // d freed via o
- }
- void set_max_objective(func f, void *f_data,
- nlopt_munge md, nlopt_munge mc) {
- myfunc_data *d = new myfunc_data;
- if (!d) throw std::bad_alloc();
- d->o = this; d->f = f; d->f_data = f_data; d->mf = NULL; d->vf = NULL;
- d->munge_destroy = md; d->munge_copy = mc;
- mythrow(nlopt_set_max_objective(o, myfunc, d)); // d freed via o
- }
-
- // Nonlinear constraints:
-
- void remove_inequality_constraints() {
- nlopt_result ret = nlopt_remove_inequality_constraints(o);
- mythrow(ret);
- }
- void add_inequality_constraint(func f, void *f_data, double tol=0) {
- myfunc_data *d = new myfunc_data;
- if (!d) throw std::bad_alloc();
- d->o = this; d->f = f; d->f_data = f_data; d->mf = NULL; d->vf = NULL;
- d->munge_destroy = d->munge_copy = NULL;
- mythrow(nlopt_add_inequality_constraint(o, myfunc, d, tol));
- }
- void add_inequality_constraint(vfunc vf, void *f_data, double tol=0) {
- myfunc_data *d = new myfunc_data;
- if (!d) throw std::bad_alloc();
- d->o = this; d->f = NULL; d->f_data = f_data; d->mf = NULL; d->vf = vf;
- d->munge_destroy = d->munge_copy = NULL;
- mythrow(nlopt_add_inequality_constraint(o, myvfunc, d, tol));
- alloc_tmp();
- }
- void add_inequality_mconstraint(mfunc mf, void *f_data,
- const std::vector<double> &tol) {
- myfunc_data *d = new myfunc_data;
- if (!d) throw std::bad_alloc();
- d->o = this; d->mf = mf; d->f_data = f_data; d->f = NULL; d->vf = NULL;
- d->munge_destroy = d->munge_copy = NULL;
- mythrow(nlopt_add_inequality_mconstraint(o, tol.size(), mymfunc, d,
- tol.empty() ? NULL : &tol[0]));
- }
-
- void remove_equality_constraints() {
- nlopt_result ret = nlopt_remove_equality_constraints(o);
- mythrow(ret);
- }
- void add_equality_constraint(func f, void *f_data, double tol=0) {
- myfunc_data *d = new myfunc_data;
- if (!d) throw std::bad_alloc();
- d->o = this; d->f = f; d->f_data = f_data; d->mf = NULL; d->vf = NULL;
- d->munge_destroy = d->munge_copy = NULL;
- mythrow(nlopt_add_equality_constraint(o, myfunc, d, tol));
- }
- void add_equality_constraint(vfunc vf, void *f_data, double tol=0) {
- myfunc_data *d = new myfunc_data;
- if (!d) throw std::bad_alloc();
- d->o = this; d->f = NULL; d->f_data = f_data; d->mf = NULL; d->vf = vf;
- d->munge_destroy = d->munge_copy = NULL;
- mythrow(nlopt_add_equality_constraint(o, myvfunc, d, tol));
- alloc_tmp();
- }
- void add_equality_mconstraint(mfunc mf, void *f_data,
- const std::vector<double> &tol) {
- myfunc_data *d = new myfunc_data;
- if (!d) throw std::bad_alloc();
- d->o = this; d->mf = mf; d->f_data = f_data; d->f = NULL; d->vf = NULL;
- d->munge_destroy = d->munge_copy = NULL;
- mythrow(nlopt_add_equality_mconstraint(o, tol.size(), mymfunc, d,
- tol.empty() ? NULL : &tol[0]));
- }
-
- // For internal use in SWIG wrappers (see also above)
- void add_inequality_constraint(func f, void *f_data,
- nlopt_munge md, nlopt_munge mc,
- double tol=0) {
- myfunc_data *d = new myfunc_data;
- if (!d) throw std::bad_alloc();
- d->o = this; d->f = f; d->f_data = f_data; d->mf = NULL; d->vf = NULL;
- d->munge_destroy = md; d->munge_copy = mc;
- mythrow(nlopt_add_inequality_constraint(o, myfunc, d, tol));
- }
- void add_equality_constraint(func f, void *f_data,
- nlopt_munge md, nlopt_munge mc,
- double tol=0) {
- myfunc_data *d = new myfunc_data;
- if (!d) throw std::bad_alloc();
- d->o = this; d->f = f; d->f_data = f_data; d->mf = NULL; d->vf = NULL;
- d->munge_destroy = md; d->munge_copy = mc;
- mythrow(nlopt_add_equality_constraint(o, myfunc, d, tol));
- }
- void add_inequality_mconstraint(mfunc mf, void *f_data,
- nlopt_munge md, nlopt_munge mc,
- const std::vector<double> &tol) {
- myfunc_data *d = new myfunc_data;
- if (!d) throw std::bad_alloc();
- d->o = this; d->mf = mf; d->f_data = f_data; d->f = NULL; d->vf = NULL;
- d->munge_destroy = md; d->munge_copy = mc;
- mythrow(nlopt_add_inequality_mconstraint(o, tol.size(), mymfunc, d,
- tol.empty() ? NULL : &tol[0]));
- }
- void add_equality_mconstraint(mfunc mf, void *f_data,
- nlopt_munge md, nlopt_munge mc,
- const std::vector<double> &tol) {
- myfunc_data *d = new myfunc_data;
- if (!d) throw std::bad_alloc();
- d->o = this; d->mf = mf; d->f_data = f_data; d->f = NULL; d->vf = NULL;
- d->munge_destroy = md; d->munge_copy = mc;
- mythrow(nlopt_add_equality_mconstraint(o, tol.size(), mymfunc, d,
- tol.empty() ? NULL : &tol[0]));
- }
-
-#define NLOPT_GETSET_VEC(name) \
- void set_##name(double val) { \
- mythrow(nlopt_set_##name##1(o, val)); \
- } \
- void get_##name(std::vector<double> &v) const { \
- if (o && nlopt_get_dimension(o) != v.size()) \
- throw std::invalid_argument("dimension mismatch"); \
- mythrow(nlopt_get_##name(o, v.empty() ? NULL : &v[0])); \
- } \
- std::vector<double> get_##name() const { \
- if (!o) throw std::runtime_error("uninitialized nlopt::opt"); \
- std::vector<double> v(nlopt_get_dimension(o)); \
- get_##name(v); \
- return v; \
- } \
- void set_##name(const std::vector<double> &v) { \
- if (o && nlopt_get_dimension(o) != v.size()) \
- throw std::invalid_argument("dimension mismatch"); \
- mythrow(nlopt_set_##name(o, v.empty() ? NULL : &v[0])); \
- }
-
- NLOPT_GETSET_VEC(lower_bounds)
- NLOPT_GETSET_VEC(upper_bounds)
-
- // stopping criteria:
-
-#define NLOPT_GETSET(T, name) \
- T get_##name() const { \
- if (!o) throw std::runtime_error("uninitialized nlopt::opt"); \
- return nlopt_get_##name(o); \
- } \
- void set_##name(T name) { \
- mythrow(nlopt_set_##name(o, name)); \
- }
- NLOPT_GETSET(double, stopval)
- NLOPT_GETSET(double, ftol_rel)
- NLOPT_GETSET(double, ftol_abs)
- NLOPT_GETSET(double, xtol_rel)
- NLOPT_GETSET_VEC(xtol_abs)
- NLOPT_GETSET(int, maxeval)
- NLOPT_GETSET(double, maxtime)
-
- NLOPT_GETSET(int, force_stop)
- void force_stop() { set_force_stop(1); }
-
- // algorithm-specific parameters:
-
- void set_local_optimizer(const opt &lo) {
- nlopt_result ret = nlopt_set_local_optimizer(o, lo.o);
- mythrow(ret);
- }
-
- NLOPT_GETSET(unsigned, population)
- NLOPT_GETSET(unsigned, vector_storage)
- NLOPT_GETSET_VEC(initial_step)
-
- void set_default_initial_step(const std::vector<double> &x) {
- nlopt_result ret
- = nlopt_set_default_initial_step(o, x.empty() ? NULL : &x[0]);
- mythrow(ret);
- }
- void get_initial_step(const std::vector<double> &x, std::vector<double> &dx) const {
- if (o && (nlopt_get_dimension(o) != x.size()
- || nlopt_get_dimension(o) != dx.size()))
- throw std::invalid_argument("dimension mismatch");
- nlopt_result ret = nlopt_get_initial_step(o, x.empty() ? NULL : &x[0],
- dx.empty() ? NULL : &dx[0]);
- mythrow(ret);
- }
- std::vector<double> get_initial_step_(const std::vector<double> &x) const {
- if (!o) throw std::runtime_error("uninitialized nlopt::opt");
- std::vector<double> v(nlopt_get_dimension(o));
- get_initial_step(x, v);
- return v;
- }
- };
-
-#undef NLOPT_GETSET
-#undef NLOPT_GETSET_VEC
-
- //////////////////////////////////////////////////////////////////////
-
- inline void srand(unsigned long seed) { nlopt_srand(seed); }
- inline void srand_time() { nlopt_srand_time(); }
- inline void version(int &major, int &minor, int &bugfix) {
- nlopt_version(&major, &minor, &bugfix);
- }
- inline int version_major() {
- int major, minor, bugfix;
- nlopt_version(&major, &minor, &bugfix);
- return major;
- }
- inline int version_minor() {
- int major, minor, bugfix;
- nlopt_version(&major, &minor, &bugfix);
- return minor;
- }
- inline int version_bugfix() {
- int major, minor, bugfix;
- nlopt_version(&major, &minor, &bugfix);
- return bugfix;
- }
- inline const char *algorithm_name(algorithm a) {
- return nlopt_algorithm_name(nlopt_algorithm(a));
- }
-
- //////////////////////////////////////////////////////////////////////
-
-} // namespace nlopt
-
-#endif /* NLOPT_HPP */
diff --git a/ext/include/nlopt/praxis.h b/ext/include/nlopt/praxis.h
deleted file mode 100644
index 59ad0bd..0000000
--- a/ext/include/nlopt/praxis.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef PRAXIS_H
-#define PRAXIS_H
-
-#include "nlopt-util.h"
-#include "nlopt.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-typedef double (*praxis_func)(int n, const double *x, void *f_data);
-
-nlopt_result praxis_(double t0, double machep, double h0,
- int n, double *x, praxis_func f, void *f_data,
- nlopt_stopping *stop, double *minf);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif /* __cplusplus */
-
-#endif /* PRAXIS_H */
diff --git a/ext/include/nlopt/redblack.h b/ext/include/nlopt/redblack.h
deleted file mode 100644
index 9bb8bd0..0000000
--- a/ext/include/nlopt/redblack.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/* Copyright (c) 2007-2012 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef REDBLACK_H
-#define REDBLACK_H
-
-#include <stddef.h> /* for ptrdiff_t */
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-typedef double *rb_key; /* key type ... double* is convenient for us,
- but of course this could be cast to anything
- desired (although void* would look more generic) */
-
-typedef enum { RED, BLACK } rb_color;
-typedef struct rb_node_s {
- struct rb_node_s *p, *r, *l; /* parent, right, left */
- rb_key k; /* key (and data) */
- rb_color c;
-} rb_node;
-
-typedef int (*rb_compare)(rb_key k1, rb_key k2);
-
-typedef struct {
- rb_compare compare;
- rb_node *root;
- int N; /* number of nodes */
-} rb_tree;
-
-extern void rb_tree_init(rb_tree *t, rb_compare compare);
-extern void rb_tree_destroy(rb_tree *t);
-extern void rb_tree_destroy_with_keys(rb_tree *t);
-extern rb_node *rb_tree_insert(rb_tree *t, rb_key k);
-extern int rb_tree_check(rb_tree *t);
-extern rb_node *rb_tree_find(rb_tree *t, rb_key k);
-extern rb_node *rb_tree_find_le(rb_tree *t, rb_key k);
-extern rb_node *rb_tree_find_lt(rb_tree *t, rb_key k);
-extern rb_node *rb_tree_find_gt(rb_tree *t, rb_key k);
-extern rb_node *rb_tree_resort(rb_tree *t, rb_node *n);
-extern rb_node *rb_tree_min(rb_tree *t);
-extern rb_node *rb_tree_max(rb_tree *t);
-extern rb_node *rb_tree_succ(rb_node *n);
-extern rb_node *rb_tree_pred(rb_node *n);
-extern void rb_tree_shift_keys(rb_tree *t, ptrdiff_t kshift);
-
-/* To change a key, use rb_tree_find+resort. Removing a node
- currently wastes memory unless you change the allocation scheme
- in redblack.c */
-extern rb_node *rb_tree_remove(rb_tree *t, rb_node *n);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif /* __cplusplus */
-
-#endif
diff --git a/ext/include/ssw/ssw.h b/ext/include/ssw/ssw.h
deleted file mode 100755
index 34c9e67..0000000
--- a/ext/include/ssw/ssw.h
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * ssw.h
- *
- * Created by Mengyao Zhao on 6/22/10.
- * Copyright 2010 Boston College. All rights reserved.
- * Version 0.1.4
- * Last revision by Mengyao Zhao on 01/30/13.
- *
- */
-
-#ifndef SSW_H
-#define SSW_H
-
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <emmintrin.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif // __cplusplus
-
-
-/*! @typedef structure of the query profile */
-struct _profile;
-typedef struct _profile s_profile;
-
-/*! @typedef structure of the alignment result
- @field score1 the best alignment score
- @field score2 sub-optimal alignment score
- @field ref_begin1 0-based best alignment beginning position on reference; ref_begin1 = -1 when the best alignment beginning
- position is not available
- @field ref_end1 0-based best alignment ending position on reference
- @field read_begin1 0-based best alignment beginning position on read; read_begin1 = -1 when the best alignment beginning
- position is not available
- @field read_end1 0-based best alignment ending position on read
- @field read_end2 0-based sub-optimal alignment ending position on read
- @field cigar best alignment cigar; stored the same as that in BAM format, high 28 bits: length, low 4 bits: M/I/D (0/1/2);
- cigar = 0 when the best alignment path is not available
- @field cigarLen length of the cigar string; cigarLen = 0 when the best alignment path is not available
-*/
-typedef struct {
- uint16_t score1;
- uint16_t score2;
- int32_t ref_begin1;
- int32_t ref_end1;
- int32_t read_begin1;
- int32_t read_end1;
- int32_t ref_end2;
- uint32_t* cigar;
- int32_t cigarLen;
-} s_align;
-
-/*! @function Create the query profile using the query sequence.
- @param read pointer to the query sequence; the query sequence needs to be numbers
- @param readLen length of the query sequence
- @param mat pointer to the substitution matrix; mat needs to be corresponding to the read sequence
- @param n the square root of the number of elements in mat (mat has n*n elements)
- @param score_size estimated Smith-Waterman score; if your estimated best alignment score is surely < 255 please set 0; if
- your estimated best alignment score >= 255, please set 1; if you don't know, please set 2
- @return pointer to the query profile structure
- @note example for parameter read and mat:
- If the query sequence is: ACGTATC, the sequence that read points to can be: 1234142
- Then if the penalty for match is 2 and for mismatch is -2, the substitution matrix of parameter mat will be:
- //A C G T
- 2 -2 -2 -2 //A
- -2 2 -2 -2 //C
- -2 -2 2 -2 //G
- -2 -2 -2 2 //T
- mat is the pointer to the array {2, -2, -2, -2, -2, 2, -2, -2, -2, -2, 2, -2, -2, -2, -2, 2}
-*/
-s_profile* ssw_init (const int8_t* read, const int32_t readLen, const int8_t* mat, const int32_t n, const int8_t score_size);
-
-/*! @function Release the memory allocated by function ssw_init.
- @param p pointer to the query profile structure
-*/
-void init_destroy (s_profile* p);
-
-// @function ssw alignment.
-/*! @function Do Striped Smith-Waterman alignment.
- @param prof pointer to the query profile structure
- @param ref pointer to the target sequence; the target sequence needs to be numbers and corresponding to the mat parameter of
- function ssw_init
- @param refLen length of the target sequence
- @param weight_gapO the absolute value of gap open penalty
- @param weight_gapE the absolute value of gap extension penalty
- @param flag bitwise FLAG; (from high to low) bit 5: when setted as 1, function ssw_align will return the best alignment
- beginning position; bit 6: when setted as 1, if (ref_end1 - ref_begin1 < filterd && read_end1 - read_begin1
- < filterd), (whatever bit 5 is setted) the function will return the best alignment beginning position and
- cigar; bit 7: when setted as 1, if the best alignment score >= filters, (whatever bit 5 is setted) the function
- will return the best alignment beginning position and cigar; bit 8: when setted as 1, (whatever bit 5, 6 or 7 is
- setted) the function will always return the best alignment beginning position and cigar. When flag == 0, only
- the optimal and sub-optimal scores and the optimal alignment ending position will be returned.
- @param filters score filter: when bit 7 of flag is setted as 1 and bit 8 is setted as 0, filters will be used (Please check the
- decription of the flag parameter for detailed usage.)
- @param filterd distance filter: when bit 6 of flag is setted as 1 and bit 8 is setted as 0, filterd will be used (Please check
- the decription of the flag parameter for detailed usage.)
- @param maskLen The distance between the optimal and suboptimal alignment ending position >= maskLen. We suggest to use
- readLen/2, if you don't have special concerns. Note: maskLen has to be >= 15, otherwise this function will NOT
- return the suboptimal alignment information. Detailed description of maskLen: After locating the optimal
- alignment ending position, the suboptimal alignment score can be heuristically found by checking the second
- largest score in the array that contains the maximal score of each column of the SW matrix. In order to avoid
- picking the scores that belong to the alignments sharing the partial best alignment, SSW C library masks the
- reference loci nearby (mask length = maskLen) the best alignment ending position and locates the second largest
- score from the unmasked elements.
- @return pointer to the alignment result structure
- @note Whatever the parameter flag is setted, this function will at least return the optimal and sub-optimal alignment score,
- and the optimal alignment ending positions on target and query sequences. If both bit 6 and 7 of the flag are setted
- while bit 8 is not, the function will return cigar only when both criteria are fulfilled. All returned positions are
- 0-based coordinate.
-*/
-s_align* ssw_align (const s_profile* prof,
- const int8_t* ref,
- int32_t refLen,
- const uint8_t weight_gapO,
- const uint8_t weight_gapE,
- const uint8_t flag,
- const uint16_t filters,
- const int32_t filterd,
- const int32_t maskLen);
-
-/*! @function Release the memory allocated by function ssw_align.
- @param a pointer to the alignment result structure
-*/
-void align_destroy (s_align* a);
-
-/*! @function Produce CIGAR 32-bit unsigned integer from CIGAR operation and CIGAR length
- @param length length of CIGAR
- @param op_letter CIGAR operation character ('M', 'I', etc)
- @return 32-bit unsigned integer, representing encoded CIGAR operation and length
-*/
-static inline uint32_t to_cigar_int (uint32_t length, char op_letter)
-{
- uint32_t res;
- uint8_t op_code;
-
- switch (op_letter) {
- case 'M': /* alignment match (can be a sequence match or mismatch */
- default:
- op_code = 0;
- break;
- case 'I': /* insertion to the reference */
- op_code = 1;
- break;
- case 'D': /* deletion from the reference */
- op_code = 2;
- break;
- case 'N': /* skipped region from the reference */
- op_code = 3;
- break;
- case 'S': /* soft clipping (clipped sequences present in SEQ) */
- op_code = 4;
- break;
- case 'H': /* hard clipping (clipped sequences NOT present in SEQ) */
- op_code = 5;
- break;
- case 'P': /* padding (silent deletion from padded reference) */
- op_code = 6;
- break;
- case '=': /* sequence match */
- op_code = 7;
- break;
- case 'X': /* sequence mismatch */
- op_code = 8;
- break;
- }
-
- res = (length << 4) | op_code;
- return res;
-}
-
-/*! @function Extract CIGAR operation character from CIGAR 32-bit unsigned integer
- @param cigar_int 32-bit unsigned integer, representing encoded CIGAR operation and length
- @return CIGAR operation character ('M', 'I', etc)
-*/
-char cigar_int_to_op (uint32_t cigar_int);
-
-/*! @function Extract length of a CIGAR operation from CIGAR 32-bit unsigned integer
- @param cigar_int 32-bit unsigned integer, representing encoded CIGAR operation and length
- @return length of CIGAR operation
-*/
-uint32_t cigar_int_to_len (uint32_t cigar_int);
-
-#ifdef __cplusplus
-}
-#endif // __cplusplus
-
-#endif // SSW_H
diff --git a/ext/include/ssw/ssw_cpp.h b/ext/include/ssw/ssw_cpp.h
deleted file mode 100644
index 0af9cf4..0000000
--- a/ext/include/ssw/ssw_cpp.h
+++ /dev/null
@@ -1,215 +0,0 @@
-#ifndef COMPLETE_STRIPED_SMITH_WATERMAN_CPP_H_
-#define COMPLETE_STRIPED_SMITH_WATERMAN_CPP_H_
-
-#include <stdint.h>
-#include <string>
-#include <vector>
-
-namespace StripedSmithWaterman {
-
-struct Alignment {
- uint16_t sw_score; // The best alignment score
- uint16_t sw_score_next_best; // The next best alignment score
- int32_t ref_begin; // Reference begin position of the best alignment
- int32_t ref_end; // Reference end position of the best alignment
- int32_t query_begin; // Query begin position of the best alignment
- int32_t query_end; // Query end position of the best alignment
- int32_t ref_end_next_best; // Reference end position of the next best alignment
- int32_t mismatches; // Number of mismatches of the alignment
- std::string cigar_string; // Cigar string of the best alignment
- std::vector<uint32_t> cigar; // Cigar stored in the BAM format
- // high 28 bits: length
- // low 4 bits: M/I/D/S/X (0/1/2/4/8);
- void Clear() {
- sw_score = 0;
- sw_score_next_best = 0;
- ref_begin = 0;
- ref_end = 0;
- query_begin = 0;
- query_end = 0;
- ref_end_next_best = 0;
- mismatches = 0;
- cigar_string.clear();
- cigar.clear();
- };
-};
-
-struct Filter {
- // NOTE: No matter the filter, those five fields of Alignment will be given anyway.
- // sw_score; sw_score_next_best; ref_end; query_end; ref_end_next_best.
- // NOTE: Only need score of alignments, please set 'report_begin_position'
- // and 'report_cigar' false.
-
- bool report_begin_position; // Give ref_begin and query_begin.
- // If it is not set, ref_begin and query_begin are -1.
- bool report_cigar; // Give cigar_string and cigar.
- // report_begin_position is automatically TRUE.
-
- // When *report_cigar* is true and alignment passes these two filters,
- // cigar_string and cigar will be given.
- uint16_t score_filter; // score >= score_filter
- uint16_t distance_filter; // ((ref_end - ref_begin) < distance_filter) &&
- // ((query_end - read_begin) < distance_filter)
-
- Filter()
- : report_begin_position(true), report_cigar(true), score_filter(0), distance_filter(32767) { };
-
- Filter(const bool &pos, const bool &cigar, const uint16_t &score, const uint16_t &dis)
- : report_begin_position(pos), report_cigar(cigar), score_filter(score), distance_filter(dis) { };
-};
-
-class Aligner {
-public:
- // =========
- // @function Construct an Aligner on default values.
- // The function will build the {A.C,G,T,N} aligner.
- // If you target for other character aligners, then please
- // use the other constructor and pass the corresponding matrix in.
- // =========
- Aligner(void);
-
- // =========
- // @function Construct an Aligner by assigning scores.
- // The function will build the {A.C,G,T,N} aligner.
- // If you target for other character aligners, then please
- // use the other constructor and pass the corresponding matrix in.
- // =========
- Aligner(const uint8_t &match_score,
- const uint8_t &mismatch_penalty,
- const uint8_t &gap_opening_penalty,
- const uint8_t &gap_extending_penalty);
-
- // =========
- // @function Construct an Aligner by the specific matrixs.
- // =========
- Aligner(const int8_t *score_matrix,
- const int &score_matrix_size,
- const int8_t *translation_matrix,
- const int &translation_matrix_size);
-
- ~Aligner(void);
-
- // =========
- // @function Build the reference sequence and thus make
- // Align(const char* query, s_align* alignment) function;
- // otherwise the reference should be given when aligning.
- // [NOTICE] If there exists a sequence, that one will be deleted
- // and replaced.
- // @param seq The reference bases;
- // [NOTICE] It is not necessary null terminated.
- // @param length The length of bases will be be built.
- // @return The length of the built bases.
- // =========
- int SetReferenceSequence(const char *seq, const int &length);
-
- void CleanReferenceSequence(void);
-
- // =========
- // @function Set penalties for opening and extending gaps
- // [NOTICE] The defaults are 3 and 1 respectively.
- // =========
- void SetGapPenalty(const uint8_t &opening, const uint8_t &extending) {
- gap_opening_penalty_ = opening;
- gap_extending_penalty_ = extending;
- };
-
- // =========
- // @function Align the query againt the reference that is set by
- // SetReferenceSequence.
- // @param query The query sequence.
- // @param filter The filter for the alignment.
- // @param alignment The container contains the result.
- // @return True: succeed; false: fail.
- // =========
- bool Align(const char *query, const Filter &filter, Alignment *alignment) const;
-
- // =========
- // @function Align the query againt the reference.
- // [NOTICE] The reference won't replace the reference
- // set by SetReferenceSequence.
- // @param query The query sequence.
- // @param ref The reference sequence.
- // [NOTICE] It is not necessary null terminated.
- // @param ref_len The length of the reference sequence.
- // @param filter The filter for the alignment.
- // @param alignment The container contains the result.
- // @return True: succeed; false: fail.
- // =========
- bool Align(const char *query, const char *ref, const int &ref_len,
- const Filter &filter, Alignment *alignment) const;
-
- // @function Clear up all containers and thus the aligner is disabled.
- // To rebuild the aligner please use Build functions.
- void Clear(void);
-
- // =========
- // @function Rebuild the aligner's ability on default values.
- // [NOTICE] If the aligner is not cleaned, rebuilding will fail.
- // @return True: succeed; false: fail.
- // =========
- bool ReBuild(void);
-
- // =========
- // @function Rebuild the aligner's ability by the specific matrixs.
- // [NOTICE] If the aligner is not cleaned, rebuilding will fail.
- // @return True: succeed; false: fail.
- // =========
- bool ReBuild(
- const uint8_t &match_score,
- const uint8_t &mismatch_penalty,
- const uint8_t &gap_opening_penalty,
- const uint8_t &gap_extending_penalty);
-
- // =========
- // @function Construct an Aligner by the specific matrixs.
- // [NOTICE] If the aligner is not cleaned, rebuilding will fail.
- // @return True: succeed; false: fail.
- // =========
- bool ReBuild(
- const int8_t *score_matrix,
- const int &score_matrix_size,
- const int8_t *translation_matrix,
- const int &translation_matrix_size);
-
-private:
- int8_t *score_matrix_;
- int score_matrix_size_;
- int8_t *translation_matrix_;
-
- uint8_t match_score_; // default: 2
- uint8_t mismatch_penalty_; // default: 2
- uint8_t gap_opening_penalty_; // default: 3
- uint8_t gap_extending_penalty_; // default: 1
-
- int8_t *translated_reference_;
- int32_t reference_length_;
-
- int TranslateBase(const char *bases, const int &length, int8_t *translated) const;
-
- void SetAllDefault(void);
-
- void BuildDefaultMatrix(void);
-
- void ClearMatrices(void);
-
- Aligner &operator=(const Aligner &);
-
- Aligner(const Aligner &);
-}; // class Aligner
-
-
-// ================
-// inline functions
-// ================
-inline void Aligner::CleanReferenceSequence(void) {
- if (reference_length_ == 0) return;
-
- // delete the current buffer
- if (reference_length_ > 1) delete[] translated_reference_;
- else delete translated_reference_;
-
- reference_length_ = 0;
-}
-} // namespace StripedSmithWaterman
-
-#endif // COMPLETE_STRIPED_SMITH_WATERMAN_CPP_H_
diff --git a/ext/src/htrie/CMakeLists.txt b/ext/src/htrie/CMakeLists.txt
deleted file mode 100644
index 4345de8..0000000
--- a/ext/src/htrie/CMakeLists.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-############################################################################
-# Copyright (c) 2015 Saint Petersburg State University
-# All Rights Reserved
-# See file LICENSE for details.
-############################################################################
-
-project(hattrie C)
-
-add_library(hattrie STATIC
- ahtable.c hat-trie.c misc.c murmurhash3.c)
-
diff --git a/ext/src/htrie/ahtable.c b/ext/src/htrie/ahtable.c
deleted file mode 100644
index c84c433..0000000
--- a/ext/src/htrie/ahtable.c
+++ /dev/null
@@ -1,564 +0,0 @@
-/*
- * This file is part of hat-trie.
- *
- * Copyright (c) 2011 by Daniel C. Jones <dcjones at cs.washington.edu>
- *
- * See ahtable.h for description of the Array Hash Table.
- *
- */
-
-#include "htrie/ahtable.h"
-#include "misc.h"
-#include "murmurhash3.h"
-#include <assert.h>
-#include <string.h>
-
-const double ahtable_max_load_factor = 100000.0; /* arbitrary large number => don't resize */
-const size_t ahtable_initial_size = 4096;
-
-static size_t keylen(slot_t s) {
- if (0x1 & *s) {
- return (size_t) (*((uint16_t*) s) >> 1);
- }
- else {
- return (size_t) (*s >> 1);
- }
-}
-
-
-ahtable_t* ahtable_create()
-{
- return ahtable_create_n(ahtable_initial_size);
-}
-
-
-ahtable_t* ahtable_create_n(size_t n)
-{
- ahtable_t* table = malloc_or_die(sizeof(ahtable_t));
- table->flag = 0;
- table->c0 = table->c1 = '\0';
-
- table->n = n;
- table->m = 0;
- table->max_m = (size_t) (ahtable_max_load_factor * (double) table->n);
- table->slots = malloc_or_die(n * sizeof(slot_t));
- memset(table->slots, 0, n * sizeof(slot_t));
-
- table->slot_sizes = malloc_or_die(n * sizeof(size_t));
- memset(table->slot_sizes, 0, n * sizeof(size_t));
-
- return table;
-}
-
-
-void ahtable_free(ahtable_t* table)
-{
- if (table == NULL) return;
- size_t i;
- for (i = 0; i < table->n; ++i) free(table->slots[i]);
- free(table->slots);
- free(table->slot_sizes);
- free(table);
-}
-
-
-size_t ahtable_size(const ahtable_t* table)
-{
- return table->m;
-}
-
-
-size_t ahtable_sizeof(const ahtable_t* table)
-{
- size_t nbytes = sizeof(ahtable_t) +
- table->n * (sizeof(size_t) + sizeof(slot_t));
- size_t i;
- for (i = 0; i < table->n; ++i) {
- nbytes += table->slot_sizes[i];
- }
- return nbytes;
-}
-
-
-void ahtable_clear(ahtable_t* table)
-{
- size_t i;
- for (i = 0; i < table->n; ++i) free(table->slots[i]);
- table->n = ahtable_initial_size;
- table->slots = realloc_or_die(table->slots, table->n * sizeof(slot_t));
- memset(table->slots, 0, table->n * sizeof(slot_t));
-
- table->slot_sizes = realloc_or_die(table->slot_sizes, table->n * sizeof(size_t));
- memset(table->slot_sizes, 0, table->n * sizeof(size_t));
-}
-
-/** Inserts a key with value into slot s, and returns a pointer to the
- * space immediately after.
- */
-static slot_t ins_key(slot_t s, const char* key, size_t len, value_t** val)
-{
- // key length
- if (len < 128) {
- s[0] = (unsigned char) (len << 1);
- s += 1;
- }
- else {
- /* The least significant bit is set to indicate that two bytes are
- * being used to store the key length. */
- *((uint16_t*) s) = ((uint16_t) len << 1) | 0x1;
- s += 2;
- }
-
- // key
- memcpy(s, key, len * sizeof(unsigned char));
- s += len;
-
- // value
- *val = (value_t*) s;
- **val = 0;
- s += sizeof(value_t);
-
- return s;
-}
-
-
-static void ahtable_expand(ahtable_t* table)
-{
- /* Resizing a table is essentially building a brand new one.
- * One little shortcut we can take on the memory allocation front is to
- * figure out how much memory each slot needs in advance.
- */
- assert(table->n > 0);
- size_t new_n = 2 * table->n;
- size_t* slot_sizes = malloc_or_die(new_n * sizeof(size_t));
- memset(slot_sizes, 0, new_n * sizeof(size_t));
-
- const char* key;
- size_t len = 0;
- size_t m = 0;
- ahtable_iter_t* i = ahtable_iter_begin(table, false);
- while (!ahtable_iter_finished(i)) {
- key = ahtable_iter_key(i, &len);
- slot_sizes[hash(key, len) % new_n] +=
- len + sizeof(value_t) + (len >= 128 ? 2 : 1);
-
- ++m;
- ahtable_iter_next(i);
- }
- assert(m == table->m);
- ahtable_iter_free(i);
-
-
- /* allocate slots */
- slot_t* slots = malloc_or_die(new_n * sizeof(slot_t));
- size_t j;
- for (j = 0; j < new_n; ++j) {
- if (slot_sizes[j] > 0) {
- slots[j] = malloc_or_die(slot_sizes[j]);
- }
- else slots[j] = NULL;
- }
-
- /* rehash values. A few shortcuts can be taken here as well, as we know
- * there will be no collisions. Instead of the regular insertion routine,
- * we keep track of the ends of every slot and simply insert keys.
- * */
- slot_t* slots_next = malloc_or_die(new_n * sizeof(slot_t));
- memcpy(slots_next, slots, new_n * sizeof(slot_t));
- size_t h;
- m = 0;
- value_t* u;
- value_t* v;
- i = ahtable_iter_begin(table, false);
- while (!ahtable_iter_finished(i)) {
-
- key = ahtable_iter_key(i, &len);
- h = hash(key, len) % new_n;
-
- slots_next[h] = ins_key(slots_next[h], key, len, &u);
- v = ahtable_iter_val(i);
- *u = *v;
-
- ++m;
- ahtable_iter_next(i);
- }
- assert(m == table->m);
- ahtable_iter_free(i);
-
-
- free(slots_next);
- for (j = 0; j < table->n; ++j) free(table->slots[j]);
-
- free(table->slots);
- table->slots = slots;
-
- free(table->slot_sizes);
- table->slot_sizes = slot_sizes;
-
- table->n = new_n;
- table->max_m = (size_t) (ahtable_max_load_factor * (double) table->n);
-}
-
-
-static value_t* get_key(ahtable_t* table, const char* key, size_t len, bool insert_missing)
-{
- /* if we are at capacity, preemptively resize */
- if (insert_missing && table->m >= table->max_m) {
- ahtable_expand(table);
- }
-
-
- uint32_t i = hash(key, len) % table->n;
- size_t k;
- slot_t s;
- value_t* val;
-
- /* search the array for our key */
- s = table->slots[i];
- while ((size_t) (s - table->slots[i]) < table->slot_sizes[i]) {
- /* get the key length */
- k = keylen(s);
- s += k < 128 ? 1 : 2;
-
- /* skip keys that are longer than ours */
- if (k != len) {
- s += k + sizeof(value_t);
- continue;
- }
-
- /* key found. */
- if (memcmp(s, key, len) == 0) {
- return (value_t*) (s + len);
- }
- /* key not found. */
- else {
- s += k + sizeof(value_t);
- continue;
- }
- }
-
-
- if (insert_missing) {
- /* the key was not found, so we must insert it. */
- size_t new_size = table->slot_sizes[i];
- new_size += 1 + (len >= 128 ? 1 : 0); // key length
- new_size += len * sizeof(unsigned char); // key
- new_size += sizeof(value_t); // value
-
- table->slots[i] = realloc_or_die(table->slots[i], new_size);
-
- ++table->m;
- ins_key(table->slots[i] + table->slot_sizes[i], key, len, &val);
- table->slot_sizes[i] = new_size;
-
- return val;
- }
- else return NULL;
-}
-
-
-value_t* ahtable_get(ahtable_t* table, const char* key, size_t len)
-{
- return get_key(table, key, len, true);
-}
-
-
-value_t* ahtable_tryget(ahtable_t* table, const char* key, size_t len )
-{
- return get_key(table, key, len, false);
-}
-
-
-int ahtable_del(ahtable_t* table, const char* key, size_t len)
-{
- uint32_t i = hash(key, len) % table->n;
- size_t k;
- slot_t s;
-
- /* search the array for our key */
- s = table->slots[i];
- while ((size_t) (s - table->slots[i]) < table->slot_sizes[i]) {
- /* get the key length */
- k = keylen(s);
- s += k < 128 ? 1 : 2;
-
- /* skip keys that are longer than ours */
- if (k != len) {
- s += k + sizeof(value_t);
- continue;
- }
-
- /* key found. */
- if (memcmp(s, key, len) == 0) {
- /* move everything over, resize the array */
- unsigned char* t = s + len + sizeof(value_t);
- s -= k < 128 ? 1 : 2;
- memmove(s, t, table->slot_sizes[i] - (size_t) (t - table->slots[i]));
- table->slot_sizes[i] -= (size_t) (t - s);
- --table->m;
- return 0;
- }
- /* key not found. */
- else {
- s += k + sizeof(value_t);
- continue;
- }
- }
-
- // Key was not found. Do nothing.
- return -1;
-}
-
-
-
-static int cmpkey(const void* a_, const void* b_)
-{
- slot_t a = *(slot_t*) a_;
- slot_t b = *(slot_t*) b_;
-
- size_t ka = keylen(a), kb = keylen(b);
-
- a += ka < 128 ? 1 : 2;
- b += kb < 128 ? 1 : 2;
-
- int c = memcmp(a, b, ka < kb ? ka : kb);
- return c == 0 ? (int) ka - (int) kb : c;
-}
-
-
-/* Sorted/unsorted iterators are kept private and exposed by passing the
-sorted flag to ahtable_iter_begin. */
-
-typedef struct ahtable_sorted_iter_t_
-{
- const ahtable_t* table; // parent
- slot_t* xs; // pointers to keys
- size_t i; // current key
-} ahtable_sorted_iter_t;
-
-
-static ahtable_sorted_iter_t* ahtable_sorted_iter_begin(const ahtable_t* table)
-{
- ahtable_sorted_iter_t* i = malloc_or_die(sizeof(ahtable_sorted_iter_t));
- i->table = table;
- i->xs = malloc_or_die(table->m * sizeof(slot_t));
- i->i = 0;
-
- slot_t s;
- size_t j, k, u;
- for (j = 0, u = 0; j < table->n; ++j) {
- s = table->slots[j];
- while (s < table->slots[j] + table->slot_sizes[j]) {
- i->xs[u++] = s;
- k = keylen(s);
- s += k < 128 ? 1 : 2;
- s += k + sizeof(value_t);
- }
- }
-
- qsort(i->xs, table->m, sizeof(slot_t), cmpkey);
-
- return i;
-}
-
-
-static bool ahtable_sorted_iter_finished(ahtable_sorted_iter_t* i)
-{
- return i->i >= i->table->m;
-}
-
-
-static void ahtable_sorted_iter_next(ahtable_sorted_iter_t* i)
-{
- if (ahtable_sorted_iter_finished(i)) return;
- ++i->i;
-}
-
-
-static void ahtable_sorted_iter_free(ahtable_sorted_iter_t* i)
-{
- if (i == NULL) return;
- free(i->xs);
- free(i);
-}
-
-
-static const char* ahtable_sorted_iter_key(ahtable_sorted_iter_t* i, size_t* len)
-{
- if (ahtable_sorted_iter_finished(i)) return NULL;
-
- slot_t s = i->xs[i->i];
- if (len) *len = keylen(s);
-
- return (const char*) (s + (*len < 128 ? 1 : 2));
-}
-
-
-static value_t* ahtable_sorted_iter_val(ahtable_sorted_iter_t* i)
-{
- if (ahtable_sorted_iter_finished(i)) return NULL;
-
- slot_t s = i->xs[i->i];
- size_t k = keylen(s);
-
- s += k < 128 ? 1 : 2;
- s += k;
-
- return (value_t*) s;
-}
-
-
-typedef struct ahtable_unsorted_iter_t_
-{
- const ahtable_t* table; // parent
- size_t i; // slot index
- slot_t s; // slot position
-} ahtable_unsorted_iter_t;
-
-
-static ahtable_unsorted_iter_t* ahtable_unsorted_iter_begin(const ahtable_t* table)
-{
- ahtable_unsorted_iter_t* i = malloc_or_die(sizeof(ahtable_unsorted_iter_t));
- i->table = table;
-
- for (i->i = 0; i->i < i->table->n; ++i->i) {
- i->s = table->slots[i->i];
- if ((size_t) (i->s - table->slots[i->i]) >= table->slot_sizes[i->i]) continue;
- break;
- }
-
- return i;
-}
-
-
-static bool ahtable_unsorted_iter_finished(ahtable_unsorted_iter_t* i)
-{
- return i->i >= i->table->n;
-}
-
-
-static void ahtable_unsorted_iter_next(ahtable_unsorted_iter_t* i)
-{
- if (ahtable_unsorted_iter_finished(i)) return;
-
- /* get the key length */
- size_t k = keylen(i->s);
- i->s += k < 128 ? 1 : 2;
-
- /* skip to the next key */
- i->s += k + sizeof(value_t);
-
- if ((size_t) (i->s - i->table->slots[i->i]) >= i->table->slot_sizes[i->i]) {
- do {
- ++i->i;
- } while(i->i < i->table->n &&
- i->table->slot_sizes[i->i] == 0);
-
- if (i->i < i->table->n) i->s = i->table->slots[i->i];
- else i->s = NULL;
- }
-}
-
-
-static void ahtable_unsorted_iter_free(ahtable_unsorted_iter_t* i)
-{
- free(i);
-}
-
-
-static const char* ahtable_unsorted_iter_key(ahtable_unsorted_iter_t* i, size_t* len)
-{
- if (ahtable_unsorted_iter_finished(i)) return NULL;
-
- slot_t s = i->s;
- size_t k;
- if (0x1 & *s) {
- k = (size_t) (*((uint16_t*) s)) >> 1;
- s += 2;
- }
- else {
- k = (size_t) (*s >> 1);
- s += 1;
- }
-
- if(len) *len = k;
- return (const char*) s;
-}
-
-
-static value_t* ahtable_unsorted_iter_val(ahtable_unsorted_iter_t* i)
-{
- if (ahtable_unsorted_iter_finished(i)) return NULL;
-
- slot_t s = i->s;
-
- size_t k;
- if (0x1 & *s) {
- k = (size_t) (*((uint16_t*) s)) >> 1;
- s += 2;
- }
- else {
- k = (size_t) (*s >> 1);
- s += 1;
- }
-
- s += k;
- return (value_t*) s;
-}
-
-
-struct ahtable_iter_t_
-{
- bool sorted;
- union {
- ahtable_unsorted_iter_t* unsorted;
- ahtable_sorted_iter_t* sorted;
- } i;
-};
-
-
-ahtable_iter_t* ahtable_iter_begin(const ahtable_t* table, bool sorted) {
- ahtable_iter_t* i = malloc_or_die(sizeof(ahtable_iter_t));
- i->sorted = sorted;
- if (sorted) i->i.sorted = ahtable_sorted_iter_begin(table);
- else i->i.unsorted = ahtable_unsorted_iter_begin(table);
- return i;
-}
-
-
-void ahtable_iter_next(ahtable_iter_t* i)
-{
- if (i->sorted) ahtable_sorted_iter_next(i->i.sorted);
- else ahtable_unsorted_iter_next(i->i.unsorted);
-}
-
-
-bool ahtable_iter_finished(ahtable_iter_t* i)
-{
- if (i->sorted) return ahtable_sorted_iter_finished(i->i.sorted);
- else return ahtable_unsorted_iter_finished(i->i.unsorted);
-}
-
-
-void ahtable_iter_free(ahtable_iter_t* i)
-{
- if (i == NULL) return;
- if (i->sorted) ahtable_sorted_iter_free(i->i.sorted);
- else ahtable_unsorted_iter_free(i->i.unsorted);
- free(i);
-}
-
-
-const char* ahtable_iter_key(ahtable_iter_t* i, size_t* len)
-{
- if (i->sorted) return ahtable_sorted_iter_key(i->i.sorted, len);
- else return ahtable_unsorted_iter_key(i->i.unsorted, len);
-}
-
-
-value_t* ahtable_iter_val(ahtable_iter_t* i)
-{
- if (i->sorted) return ahtable_sorted_iter_val(i->i.sorted);
- else return ahtable_unsorted_iter_val(i->i.unsorted);
-}
-
diff --git a/ext/src/htrie/hat-trie.c b/ext/src/htrie/hat-trie.c
deleted file mode 100644
index 812c0d2..0000000
--- a/ext/src/htrie/hat-trie.c
+++ /dev/null
@@ -1,711 +0,0 @@
-/*
- * This file is part of hat-trie.
- *
- * Copyright (c) 2011 by Daniel C. Jones <dcjones at cs.washington.edu>
- *
- */
-
-#include "htrie/hat-trie.h"
-#include "htrie/ahtable.h"
-#include "misc.h"
-#include <stdint.h>
-#include <assert.h>
-#include <string.h>
-
-#define HT_UNUSED(x) x=x
-
-/* maximum number of keys that may be stored in a bucket before it is burst */
-static const size_t MAX_BUCKET_SIZE = 16384;
-#define NODE_MAXCHAR 0xff // 0x7f for 7-bit ASCII
-#define NODE_CHILDS (NODE_MAXCHAR+1)
-
-static const uint8_t NODE_TYPE_TRIE = 0x1;
-static const uint8_t NODE_TYPE_PURE_BUCKET = 0x2;
-static const uint8_t NODE_TYPE_HYBRID_BUCKET = 0x4;
-static const uint8_t NODE_HAS_VAL = 0x8;
-
-
-struct trie_node_t_;
-
-/* Node's may be trie nodes or buckets. This union allows us to keep
- * non-specific pointer. */
-typedef union node_ptr_
-{
- ahtable_t* b;
- struct trie_node_t_* t;
- uint8_t* flag;
-} node_ptr;
-
-
-typedef struct trie_node_t_
-{
- uint8_t flag;
-
- /* the value for the key that is consumed on a trie node */
- value_t val;
-
- /* Map a character to either a trie_node_t or a ahtable_t. The first byte
- * must be examined to determine which. */
- node_ptr xs[NODE_CHILDS];
-
-} trie_node_t;
-
-struct hattrie_t_
-{
- node_ptr root; // root node
- size_t m; // number of stored keys
-};
-
-
-
-size_t hattrie_size(const hattrie_t* T)
-{
- return T->m;
-}
-
-
-static size_t node_sizeof(node_ptr node)
-{
- if (*node.flag & NODE_TYPE_TRIE) {
- size_t nbytes = sizeof(trie_node_t);
- size_t i;
- nbytes += node_sizeof(node.t->xs[0]);
- for (i = 1; i < NODE_CHILDS; ++i) {
- if (node.t->xs[i].t != node.t->xs[i-1].t) nbytes += node_sizeof(node.t->xs[i]);
- }
- return nbytes;
- }
- else {
- return ahtable_sizeof(node.b);
- }
-}
-
-
-size_t hattrie_sizeof(const hattrie_t* T)
-{
- return sizeof(hattrie_t) + node_sizeof(T->root);
-}
-
-
-/* Create a new trie node with all pointers pointing to the given child (which
- * can be NULL). */
-static trie_node_t* alloc_trie_node(hattrie_t* T, node_ptr child)
-{
- trie_node_t* node = malloc_or_die(sizeof(trie_node_t));
- node->flag = NODE_TYPE_TRIE;
- node->val = 0;
-
- /* pass T to allow custom allocator for trie. */
- HT_UNUSED(T); /* unused now */
-
- size_t i;
- for (i = 0; i < NODE_CHILDS; ++i) node->xs[i] = child;
- return node;
-}
-
-/* iterate trie nodes until string is consumed or bucket is found */
-static node_ptr hattrie_consume(node_ptr *p, const char **k, size_t *l, unsigned brk)
-{
- node_ptr node = p->t->xs[(unsigned char) **k];
- while (*node.flag & NODE_TYPE_TRIE && *l > brk) {
- ++*k;
- --*l;
- *p = node;
- node = node.t->xs[(unsigned char) **k];
- }
-
- /* copy and writeback variables if it's faster */
-
- assert(*p->flag & NODE_TYPE_TRIE);
- return node;
-}
-
-/* use node value and return pointer to it */
-static inline value_t* hattrie_useval(hattrie_t *T, node_ptr n)
-{
- if (!(n.t->flag & NODE_HAS_VAL)) {
- n.t->flag |= NODE_HAS_VAL;
- ++T->m;
- }
- return &n.t->val;
-}
-
-/* clear node value if exists */
-static inline int hattrie_clrval(hattrie_t *T, node_ptr n)
-{
- if (n.t->flag & NODE_HAS_VAL) {
- n.t->flag &= ~NODE_HAS_VAL;
- n.t->val = 0;
- --T->m;
- return 0;
- }
- return -1;
-}
-
-/* find node in trie */
-static node_ptr hattrie_find(hattrie_t* T, const char **key, size_t *len)
-{
- node_ptr parent = T->root;
- assert(*parent.flag & NODE_TYPE_TRIE);
-
- if (*len == 0) return parent;
-
- node_ptr node = hattrie_consume(&parent, key, len, 1);
-
- /* if the trie node consumes value, use it */
- if (*node.flag & NODE_TYPE_TRIE) {
- if (!(node.t->flag & NODE_HAS_VAL)) {
- node.flag = NULL;
- }
- return node;
- }
-
- /* pure bucket holds only key suffixes, skip current char */
- if (*node.flag & NODE_TYPE_PURE_BUCKET) {
- *key += 1;
- *len -= 1;
- }
-
- /* do not scan bucket, it's not needed for this operation */
- return node;
-}
-
-hattrie_t* hattrie_create()
-{
- hattrie_t* T = malloc_or_die(sizeof(hattrie_t));
- T->m = 0;
-
- node_ptr node;
- node.b = ahtable_create();
- node.b->flag = NODE_TYPE_HYBRID_BUCKET;
- node.b->c0 = 0x00;
- node.b->c1 = NODE_MAXCHAR;
- T->root.t = alloc_trie_node(T, node);
-
- return T;
-}
-
-
-static void hattrie_free_node(node_ptr node)
-{
- if (*node.flag & NODE_TYPE_TRIE) {
- size_t i;
- for (i = 0; i < NODE_CHILDS; ++i) {
- if (i > 0 && node.t->xs[i].t == node.t->xs[i - 1].t) continue;
-
- /* XXX: recursion might not be the best choice here. It is possible
- * to build a very deep trie. */
- if (node.t->xs[i].t) hattrie_free_node(node.t->xs[i]);
- }
- free(node.t);
- }
- else {
- ahtable_free(node.b);
- }
-}
-
-
-void hattrie_free(hattrie_t* T)
-{
- hattrie_free_node(T->root);
- free(T);
-}
-
-
-void hattrie_clear(hattrie_t* T)
-{
- hattrie_free_node(T->root);
- node_ptr node;
- node.b = ahtable_create();
- node.b->flag = NODE_TYPE_HYBRID_BUCKET;
- node.b->c0 = 0x00;
- node.b->c1 = 0xff;
- T->root.t = alloc_trie_node(T, node);
-}
-
-
-/* Perform one split operation on the given node with the given parent.
- */
-static void hattrie_split(hattrie_t* T, node_ptr parent, node_ptr node)
-{
- /* only buckets may be split */
- assert(*node.flag & NODE_TYPE_PURE_BUCKET ||
- *node.flag & NODE_TYPE_HYBRID_BUCKET);
-
- assert(*parent.flag & NODE_TYPE_TRIE);
-
- if (*node.flag & NODE_TYPE_PURE_BUCKET) {
- /* turn the pure bucket into a hybrid bucket */
- parent.t->xs[node.b->c0].t = alloc_trie_node(T, node);
-
- /* if the bucket had an empty key, move it to the new trie node */
- value_t* val = ahtable_tryget(node.b, NULL, 0);
- if (val) {
- parent.t->xs[node.b->c0].t->val = *val;
- parent.t->xs[node.b->c0].t->flag |= NODE_HAS_VAL;
- *val = 0;
- ahtable_del(node.b, NULL, 0);
- }
-
- node.b->c0 = 0x00;
- node.b->c1 = NODE_MAXCHAR;
- node.b->flag = NODE_TYPE_HYBRID_BUCKET;
-
- return;
- }
-
- /* This is a hybrid bucket. Perform a proper split. */
-
- /* count the number of occourances of every leading character */
- unsigned int cs[NODE_CHILDS]; // occurance count for leading chars
- memset(cs, 0, NODE_CHILDS * sizeof(unsigned int));
- size_t len;
- const char* key;
-
- ahtable_iter_t* i = ahtable_iter_begin(node.b, false);
- while (!ahtable_iter_finished(i)) {
- key = ahtable_iter_key(i, &len);
- assert(len > 0);
- cs[(unsigned char) key[0]] += 1;
- ahtable_iter_next(i);
- }
- ahtable_iter_free(i);
-
- /* choose a split point */
- unsigned int left_m, right_m, all_m;
- unsigned char j = node.b->c0;
- all_m = ahtable_size(node.b);
- left_m = cs[j];
- right_m = all_m - left_m;
- int d;
-
- while (j + 1 < node.b->c1) {
- d = abs((int) (left_m + cs[j + 1]) - (int) (right_m - cs[j + 1]));
- if (d <= abs(left_m - right_m) && left_m + cs[j + 1] < all_m) {
- j += 1;
- left_m += cs[j];
- right_m -= cs[j];
- }
- else break;
- }
-
- /* now split into two node cooresponding to ranges [0, j] and
- * [j + 1, NODE_MAXCHAR], respectively. */
-
-
- /* create new left and right nodes */
-
- /* TODO: Add a special case if either node is a hybrid bucket containing all
- * the keys. In such a case, do not build a new table, just use the old one.
- * */
- size_t num_slots;
-
-
- for (num_slots = ahtable_initial_size;
- (double) left_m > ahtable_max_load_factor * (double) num_slots;
- num_slots *= 2);
-
- node_ptr left, right;
- left.b = ahtable_create_n(num_slots);
- left.b->c0 = node.b->c0;
- left.b->c1 = j;
- left.b->flag = left.b->c0 == left.b->c1 ?
- NODE_TYPE_PURE_BUCKET : NODE_TYPE_HYBRID_BUCKET;
-
-
- for (num_slots = ahtable_initial_size;
- (double) right_m > ahtable_max_load_factor * (double) num_slots;
- num_slots *= 2);
-
- right.b = ahtable_create_n(num_slots);
- right.b->c0 = j + 1;
- right.b->c1 = node.b->c1;
- right.b->flag = right.b->c0 == right.b->c1 ?
- NODE_TYPE_PURE_BUCKET : NODE_TYPE_HYBRID_BUCKET;
-
-
- /* update the parent's pointer */
-
- unsigned int c;
- for (c = node.b->c0; c <= j; ++c) parent.t->xs[c] = left;
- for (; c <= node.b->c1; ++c) parent.t->xs[c] = right;
-
-
-
- /* distribute keys to the new left or right node */
- value_t* u;
- value_t* v;
- i = ahtable_iter_begin(node.b, false);
- while (!ahtable_iter_finished(i)) {
- key = ahtable_iter_key(i, &len);
- u = ahtable_iter_val(i);
- assert(len > 0);
-
- /* left */
- if ((unsigned char) key[0] <= j) {
- if (*left.flag & NODE_TYPE_PURE_BUCKET) {
- v = ahtable_get(left.b, key + 1, len - 1);
- }
- else {
- v = ahtable_get(left.b, key, len);
- }
- *v = *u;
- }
-
- /* right */
- else {
- if (*right.flag & NODE_TYPE_PURE_BUCKET) {
- v = ahtable_get(right.b, key + 1, len - 1);
- }
- else {
- v = ahtable_get(right.b, key, len);
- }
- *v = *u;
- }
-
- ahtable_iter_next(i);
- }
-
- ahtable_iter_free(i);
- ahtable_free(node.b);
-}
-
-value_t* hattrie_get(hattrie_t* T, const char* key, size_t len)
-{
- node_ptr parent = T->root;
- assert(*parent.flag & NODE_TYPE_TRIE);
-
- if (len == 0) return &parent.t->val;
-
- /* consume all trie nodes, now parent must be trie and child anything */
- node_ptr node = hattrie_consume(&parent, &key, &len, 0);
- assert(*parent.flag & NODE_TYPE_TRIE);
-
- /* if the key has been consumed on a trie node, use its value */
- if (len == 0) {
- if (*node.flag & NODE_TYPE_TRIE) {
- return hattrie_useval(T, node);
- }
- else if (*node.flag & NODE_TYPE_HYBRID_BUCKET) {
- return hattrie_useval(T, parent);
- }
- }
-
-
- /* preemptively split the bucket if it is full */
- while (ahtable_size(node.b) >= MAX_BUCKET_SIZE) {
- hattrie_split(T, parent, node);
-
- /* after the split, the node pointer is invalidated, so we search from
- * the parent again. */
- node = hattrie_consume(&parent, &key, &len, 0);
-
- /* if the key has been consumed on a trie node, use its value */
- if (len == 0) {
- if (*node.flag & NODE_TYPE_TRIE) {
- return hattrie_useval(T, node);
- }
- else if (*node.flag & NODE_TYPE_HYBRID_BUCKET) {
- return hattrie_useval(T, parent);
- }
- }
- }
-
- assert(*node.flag & NODE_TYPE_PURE_BUCKET || *node.flag & NODE_TYPE_HYBRID_BUCKET);
-
- assert(len > 0);
- size_t m_old = node.b->m;
- value_t* val;
- if (*node.flag & NODE_TYPE_PURE_BUCKET) {
- val = ahtable_get(node.b, key + 1, len - 1);
- }
- else {
- val = ahtable_get(node.b, key, len);
- }
- T->m += (node.b->m - m_old);
-
- return val;
-}
-
-
-value_t* hattrie_tryget(hattrie_t* T, const char* key, size_t len)
-{
- /* find node for given key */
- node_ptr node = hattrie_find(T, &key, &len);
- if (node.flag == NULL) {
- return NULL;
- }
-
- /* if the trie node consumes value, use it */
- if (*node.flag & NODE_TYPE_TRIE) {
- return &node.t->val;
- }
-
- return ahtable_tryget(node.b, key, len);
-}
-
-
-int hattrie_del(hattrie_t* T, const char* key, size_t len)
-{
- node_ptr parent = T->root;
- HT_UNUSED(parent);
- assert(*parent.flag & NODE_TYPE_TRIE);
-
- /* find node for deletion */
- node_ptr node = hattrie_find(T, &key, &len);
- if (node.flag == NULL) {
- return -1;
- }
-
- /* if consumed on a trie node, clear the value */
- if (*node.flag & NODE_TYPE_TRIE) {
- return hattrie_clrval(T, node);
- }
-
- /* remove from bucket */
- size_t m_old = ahtable_size(node.b);
- int ret = ahtable_del(node.b, key, len);
- T->m -= (m_old - ahtable_size(node.b));
-
- /* merge empty buckets */
- /*! \todo */
-
- return ret;
-}
-
-
-/* plan for iteration:
- * This is tricky, as we have no parent pointers currently, and I would like to
- * avoid adding them. That means maintaining a stack
- *
- */
-
-typedef struct hattrie_node_stack_t_
-{
- unsigned char c;
- size_t level;
-
- node_ptr node;
- struct hattrie_node_stack_t_* next;
-
-} hattrie_node_stack_t;
-
-
-struct hattrie_iter_t_
-{
- char* key;
- size_t keysize; // space reserved for the key
- size_t level;
-
- /* keep track of keys stored in trie nodes */
- bool has_nil_key;
- value_t nil_val;
-
- const hattrie_t* T;
- bool sorted;
- ahtable_iter_t* i;
- hattrie_node_stack_t* stack;
-};
-
-
-static void hattrie_iter_pushchar(hattrie_iter_t* i, size_t level, char c)
-{
- if (i->keysize < level) {
- i->keysize *= 2;
- i->key = realloc_or_die(i->key, i->keysize * sizeof(char));
- }
-
- if (level > 0) {
- i->key[level - 1] = c;
- }
-
- i->level = level;
-}
-
-
-static void hattrie_iter_nextnode(hattrie_iter_t* i)
-{
- if (i->stack == NULL) return;
-
- /* pop the stack */
- node_ptr node;
- hattrie_node_stack_t* next;
- unsigned char c;
- size_t level;
-
- node = i->stack->node;
- next = i->stack->next;
- c = i->stack->c;
- level = i->stack->level;
-
- free(i->stack);
- i->stack = next;
-
- if (*node.flag & NODE_TYPE_TRIE) {
- hattrie_iter_pushchar(i, level, c);
-
- if(node.t->flag & NODE_HAS_VAL) {
- i->has_nil_key = true;
- i->nil_val = node.t->val;
- }
-
- /* push all child nodes from right to left */
- int j;
- for (j = NODE_MAXCHAR; j >= 0; --j) {
-
- /* skip repeated pointers to hybrid bucket */
- if (j < NODE_MAXCHAR && node.t->xs[j].t == node.t->xs[j + 1].t) continue;
-
- // push stack
- next = i->stack;
- i->stack = malloc_or_die(sizeof(hattrie_node_stack_t));
- i->stack->node = node.t->xs[j];
- i->stack->next = next;
- i->stack->level = level + 1;
- i->stack->c = (unsigned char) j;
- }
- }
- else {
- if (*node.flag & NODE_TYPE_PURE_BUCKET) {
- hattrie_iter_pushchar(i, level, c);
- }
- else {
- i->level = level - 1;
- }
-
- i->i = ahtable_iter_begin(node.b, i->sorted);
- }
-}
-
-
-hattrie_iter_t* hattrie_iter_begin(const hattrie_t* T, bool sorted)
-{
- hattrie_iter_t* i = malloc_or_die(sizeof(hattrie_iter_t));
- i->T = T;
- i->sorted = sorted;
- i->i = NULL;
- i->keysize = 16;
- i->key = malloc_or_die(i->keysize * sizeof(char));
- i->level = 0;
- i->has_nil_key = false;
- i->nil_val = 0;
-
- i->stack = malloc_or_die(sizeof(hattrie_node_stack_t));
- i->stack->next = NULL;
- i->stack->node = T->root;
- i->stack->c = '\0';
- i->stack->level = 0;
-
-
- while (((i->i == NULL || ahtable_iter_finished(i->i)) && !i->has_nil_key) &&
- i->stack != NULL ) {
-
- ahtable_iter_free(i->i);
- i->i = NULL;
- hattrie_iter_nextnode(i);
- }
-
- if (i->i != NULL && ahtable_iter_finished(i->i)) {
- ahtable_iter_free(i->i);
- i->i = NULL;
- }
-
- return i;
-}
-
-
-void hattrie_iter_next(hattrie_iter_t* i)
-{
- if (hattrie_iter_finished(i)) return;
-
- if (i->i != NULL && !ahtable_iter_finished(i->i)) {
- ahtable_iter_next(i->i);
- }
- else if (i->has_nil_key) {
- i->has_nil_key = false;
- i->nil_val = 0;
- hattrie_iter_nextnode(i);
- }
-
- while (((i->i == NULL || ahtable_iter_finished(i->i)) && !i->has_nil_key) &&
- i->stack != NULL ) {
-
- ahtable_iter_free(i->i);
- i->i = NULL;
- hattrie_iter_nextnode(i);
- }
-
- if (i->i != NULL && ahtable_iter_finished(i->i)) {
- ahtable_iter_free(i->i);
- i->i = NULL;
- }
-}
-
-
-bool hattrie_iter_finished(hattrie_iter_t* i)
-{
- return i->stack == NULL && i->i == NULL && !i->has_nil_key;
-}
-
-
-void hattrie_iter_free(hattrie_iter_t* i)
-{
- if (i == NULL) return;
- if (i->i) ahtable_iter_free(i->i);
-
- hattrie_node_stack_t* next;
- while (i->stack) {
- next = i->stack->next;
- free(i->stack);
- i->stack = next;
- }
-
- free(i->key);
- free(i);
-}
-
-
-const char* hattrie_iter_key(hattrie_iter_t* i, size_t* len)
-{
- if (hattrie_iter_finished(i)) return NULL;
-
- size_t sublen;
- const char* subkey;
-
- if (i->has_nil_key) {
- subkey = NULL;
- sublen = 0;
- }
- else subkey = ahtable_iter_key(i->i, &sublen);
-
- if (i->keysize < i->level + sublen + 1) {
- while (i->keysize < i->level + sublen + 1) i->keysize *= 2;
- i->key = realloc_or_die(i->key, i->keysize * sizeof(char));
- }
-
- memcpy(i->key + i->level, subkey, sublen);
- i->key[i->level + sublen] = '\0';
-
- if (len) *len = i->level + sublen;
- return i->key;
-}
-
-
-value_t* hattrie_iter_val(hattrie_iter_t* i)
-{
- if (i->has_nil_key) return &i->nil_val;
-
- if (hattrie_iter_finished(i)) return NULL;
-
- return ahtable_iter_val(i->i);
-}
-
-
-
-bool hattrie_iter_equal(const hattrie_iter_t* a,
- const hattrie_iter_t* b)
-{
- return a->T == b->T &&
- a->sorted == b->sorted &&
- a->i == b->i;
-}
diff --git a/ext/src/htrie/misc.c b/ext/src/htrie/misc.c
deleted file mode 100644
index 0530c34..0000000
--- a/ext/src/htrie/misc.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * This file is part of hat-trie.
- *
- * Copyright (c) 2011 by Daniel C. Jones <dcjones at cs.washington.edu>
- *
- */
-
-#include "misc.h"
-#include <stdlib.h>
-
-
-void* malloc_or_die(size_t n)
-{
- void* p = malloc(n);
- if (p == NULL && n != 0) {
- fprintf(stderr, "Cannot allocate %zu bytes.\n", n);
- exit(EXIT_FAILURE);
- }
- return p;
-}
-
-
-void* realloc_or_die(void* ptr, size_t n)
-{
- void* p = realloc(ptr, n);
- if (p == NULL && n != 0) {
- fprintf(stderr, "Cannot allocate %zu bytes.\n", n);
- exit(EXIT_FAILURE);
- }
- return p;
-}
-
-
-FILE* fopen_or_die(const char* path, const char* mode)
-{
- FILE* f = fopen(path, mode);
- if (f == NULL) {
- fprintf(stderr, "Cannot open file %s with mode %s.\n", path, mode);
- exit(EXIT_FAILURE);
- }
- return f;
-}
-
-
-
-
diff --git a/ext/src/htrie/misc.h b/ext/src/htrie/misc.h
deleted file mode 100644
index 7223b8b..0000000
--- a/ext/src/htrie/misc.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * This file is part of hat-trie.
- *
- * Copyright (c) 2011 by Daniel C. Jones <dcjones at cs.washington.edu>
- *
- * misc :
- * miscelaneous functions.
- *
- */
-
-#ifndef LINESET_MISC_H
-#define LINESET_MISC_H
-
-#include <stdio.h>
-
-void* malloc_or_die(size_t);
-void* realloc_or_die(void*, size_t);
-FILE* fopen_or_die(const char*, const char*);
-
-#endif
-
-
diff --git a/ext/src/htrie/murmurhash3.c b/ext/src/htrie/murmurhash3.c
deleted file mode 100644
index cb24c8f..0000000
--- a/ext/src/htrie/murmurhash3.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/* This is MurmurHash3. The original C++ code was placed in the public domain
- * by its author, Austin Appleby. */
-
-#include "murmurhash3.h"
-
-static inline uint32_t fmix(uint32_t h)
-{
- h ^= h >> 16;
- h *= 0x85ebca6b;
- h ^= h >> 13;
- h *= 0xc2b2ae35;
- h ^= h >> 16;
-
- return h;
-}
-
-
-static inline uint32_t rotl32(uint32_t x, int8_t r)
-{
- return (x << r) | (x >> (32 - r));
-}
-
-
-uint32_t hash(const char* data, size_t len_)
-{
- const int len = (int) len_;
- const int nblocks = len / 4;
-
- uint32_t h1 = 0xc062fb4a;
-
- uint32_t c1 = 0xcc9e2d51;
- uint32_t c2 = 0x1b873593;
-
- //----------
- // body
-
- const uint32_t * blocks = (const uint32_t*) (data + nblocks * 4);
-
- int i;
- for(i = -nblocks; i; i++)
- {
- uint32_t k1 = blocks[i];
-
- k1 *= c1;
- k1 = rotl32(k1, 15);
- k1 *= c2;
-
- h1 ^= k1;
- h1 = rotl32(h1, 13);
- h1 = h1*5+0xe6546b64;
- }
-
- //----------
- // tail
-
- const uint8_t * tail = (const uint8_t*)(data + nblocks*4);
-
- uint32_t k1 = 0;
-
- switch(len & 3)
- {
- case 3: k1 ^= tail[2] << 16;
- case 2: k1 ^= tail[1] << 8;
- case 1: k1 ^= tail[0];
- k1 *= c1; k1 = rotl32(k1,15); k1 *= c2; h1 ^= k1;
- }
-
- //----------
- // finalization
-
- h1 ^= len;
-
- h1 = fmix(h1);
-
- return h1;
-}
-
diff --git a/ext/src/htrie/murmurhash3.h b/ext/src/htrie/murmurhash3.h
deleted file mode 100644
index 9aa2dba..0000000
--- a/ext/src/htrie/murmurhash3.h
+++ /dev/null
@@ -1,12 +0,0 @@
-
-#ifndef MURMURHASH3_H
-#define MURMURHASH3_H
-
-#include <stdlib.h>
-
-#include <stdint.h>
-
-uint32_t hash(const char* data, size_t len);
-
-#endif
-
diff --git a/ext/src/nlopt/AUTHORS b/ext/src/nlopt/AUTHORS
deleted file mode 100644
index 6e2be75..0000000
--- a/ext/src/nlopt/AUTHORS
+++ /dev/null
@@ -1,6 +0,0 @@
-NLopt was written/packaged by:
-
-Steven G. Johnson <stevenj at alum.mit.edu>
-
-See the subdirectories for the authors of the original nonlinear optimization
-libraries utilized by NLopt.
diff --git a/ext/src/nlopt/CMakeLists.txt b/ext/src/nlopt/CMakeLists.txt
deleted file mode 100644
index 8041809..0000000
--- a/ext/src/nlopt/CMakeLists.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-project(nlopt CXX C)
-
-include_directories(${CMAKE_CURRENT_SOURCE_DIR})
-include_directories(${EXT_DIR}/include)
-
-set(NLOPT_SRCS "api/general.c"
- "api/optimize.c"
- "api/options.c"
- "api/deprecated.c"
- "auglag/auglag.c"
- "bobyqa/bobyqa.c"
- "cdirect/cdirect.c"
- "cdirect/hybrid.c"
- "cobyla/cobyla.c"
- "crs/crs.c"
- "esch/esch.c"
- "isres/isres.c"
- "mma/mma.c"
- "mma/ccsa_quadratic.c"
- "mlsl/mlsl.c"
- "neldermead/nldrmd.c"
- "neldermead/sbplx.c"
- "newuoa/newuoa.c"
- "praxis/praxis.c"
- "util/redblack.c"
- "util/rescale.c"
- "util/stop.c"
- "util/timer.c"
- "util/qsort_r.c"
- "util/sobolseq.c"
- "util/mt19937ar.c"
-)
-
-add_library(nlopt STATIC ${NLOPT_SRCS})
diff --git a/ext/src/nlopt/COPYING b/ext/src/nlopt/COPYING
deleted file mode 100644
index 9b8990b..0000000
--- a/ext/src/nlopt/COPYING
+++ /dev/null
@@ -1,20 +0,0 @@
-Copyright (c) 2007-2011 Massachusetts Institute of Technology
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/ext/src/nlopt/api/deprecated.c b/ext/src/nlopt/api/deprecated.c
deleted file mode 100644
index 2969358..0000000
--- a/ext/src/nlopt/api/deprecated.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/* Copyright (c) 2007-2012 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include "nlopt/nlopt.h"
-
-/*************************************************************************/
-
-nlopt_algorithm nlopt_local_search_alg_deriv = NLOPT_LD_MMA;
-nlopt_algorithm nlopt_local_search_alg_nonderiv = NLOPT_LN_COBYLA;
-int nlopt_local_search_maxeval = -1; /* no maximum by default */
-
-void
-NLOPT_STDCALL nlopt_get_local_search_algorithm(nlopt_algorithm *deriv,
- nlopt_algorithm *nonderiv,
- int *maxeval)
-{
- *deriv = nlopt_local_search_alg_deriv;
- *nonderiv = nlopt_local_search_alg_nonderiv;
- *maxeval = nlopt_local_search_maxeval;
-}
-
-void
-NLOPT_STDCALL nlopt_set_local_search_algorithm(nlopt_algorithm deriv,
- nlopt_algorithm nonderiv,
- int maxeval)
-{
- nlopt_local_search_alg_deriv = deriv;
- nlopt_local_search_alg_nonderiv = nonderiv;
- nlopt_local_search_maxeval = maxeval;
-}
-
-/*************************************************************************/
-
-int nlopt_stochastic_population = 0;
-
-int
-NLOPT_STDCALL nlopt_get_stochastic_population(void) {
- return nlopt_stochastic_population; }
-void
-NLOPT_STDCALL nlopt_set_stochastic_population(int pop) {
- nlopt_stochastic_population = pop <= 0 ? 0 : (unsigned) pop; }
-
-/*************************************************************************/
-
-nlopt_result
-NLOPT_STDCALL nlopt_minimize_econstrained(
- nlopt_algorithm algorithm,
- int n, nlopt_func_old f, void *f_data,
- int m, nlopt_func_old fc, void *fc_data_, ptrdiff_t fc_datum_size,
- int p, nlopt_func_old h, void *h_data_, ptrdiff_t h_datum_size,
- const double *lb, const double *ub, /* bounds */
- double *x, /* in: initial guess, out: minimizer */
- double *minf, /* out: minimum */
- double minf_max, double ftol_rel, double ftol_abs,
- double xtol_rel, const double *xtol_abs,
- double htol_rel, double htol_abs,
- int maxeval, double maxtime)
-{
- char *fc_data = (char *) fc_data_;
- char *h_data = (char *) h_data_;
- nlopt_opt opt;
- nlopt_result ret;
- int i;
-
- if (n < 0 || m < 0 || p < 0) return NLOPT_INVALID_ARGS;
-
- opt = nlopt_create(algorithm, (unsigned) n);
- if (!opt) return NLOPT_INVALID_ARGS;
-
- ret = nlopt_set_min_objective(opt, (nlopt_func) f, f_data);
- if (ret != NLOPT_SUCCESS) { nlopt_destroy(opt); return ret; }
-
- for (i = 0; i < m; ++i) {
- ret = nlopt_add_inequality_constraint(opt, (nlopt_func) fc,
- fc_data + i*fc_datum_size,
- 0.0);
- if (ret != NLOPT_SUCCESS) { nlopt_destroy(opt); return ret; }
- }
-
- (void) htol_rel; /* unused */
- for (i = 0; i < p; ++i) {
- ret = nlopt_add_equality_constraint(opt, (nlopt_func) h,
- h_data + i*h_datum_size,
- htol_abs);
- if (ret != NLOPT_SUCCESS) { nlopt_destroy(opt); return ret; }
- }
-
- ret = nlopt_set_lower_bounds(opt, lb);
- if (ret != NLOPT_SUCCESS) { nlopt_destroy(opt); return ret; }
- ret = nlopt_set_upper_bounds(opt, ub);
- if (ret != NLOPT_SUCCESS) { nlopt_destroy(opt); return ret; }
-
- ret = nlopt_set_stopval(opt, minf_max);
- if (ret != NLOPT_SUCCESS) { nlopt_destroy(opt); return ret; }
-
- ret = nlopt_set_ftol_rel(opt, ftol_rel);
- if (ret != NLOPT_SUCCESS) { nlopt_destroy(opt); return ret; }
- ret = nlopt_set_ftol_abs(opt, ftol_abs);
- if (ret != NLOPT_SUCCESS) { nlopt_destroy(opt); return ret; }
-
- ret = nlopt_set_xtol_rel(opt, xtol_rel);
- if (ret != NLOPT_SUCCESS) { nlopt_destroy(opt); return ret; }
- if (xtol_abs) ret = nlopt_set_xtol_abs(opt, xtol_abs);
- if (ret != NLOPT_SUCCESS) { nlopt_destroy(opt); return ret; }
-
- ret = nlopt_set_maxeval(opt, maxeval);
- if (ret != NLOPT_SUCCESS) { nlopt_destroy(opt); return ret; }
-
- ret = nlopt_set_maxtime(opt, maxtime);
- if (ret != NLOPT_SUCCESS) { nlopt_destroy(opt); return ret; }
-
- ret = nlopt_optimize(opt, x, minf);
-
- nlopt_destroy(opt);
- return ret;
-}
-
-nlopt_result
-NLOPT_STDCALL nlopt_minimize_constrained(
- nlopt_algorithm algorithm,
- int n, nlopt_func_old f, void *f_data,
- int m, nlopt_func_old fc, void *fc_data, ptrdiff_t fc_datum_size,
- const double *lb, const double *ub, /* bounds */
- double *x, /* in: initial guess, out: minimizer */
- double *minf, /* out: minimum */
- double minf_max, double ftol_rel, double ftol_abs,
- double xtol_rel, const double *xtol_abs,
- int maxeval, double maxtime)
-{
- return nlopt_minimize_econstrained(
- algorithm, n, f, f_data,
- m, fc, fc_data, fc_datum_size, 0, NULL, NULL, 0,
- lb, ub, x, minf, minf_max, ftol_rel, ftol_abs,
- xtol_rel, xtol_abs, ftol_rel, ftol_abs, maxeval, maxtime);
-}
-
-nlopt_result
-NLOPT_STDCALL nlopt_minimize(
- nlopt_algorithm algorithm,
- int n, nlopt_func_old f, void *f_data,
- const double *lb, const double *ub, /* bounds */
- double *x, /* in: initial guess, out: minimizer */
- double *minf, /* out: minimum */
- double minf_max, double ftol_rel, double ftol_abs,
- double xtol_rel, const double *xtol_abs,
- int maxeval, double maxtime)
-{
- return nlopt_minimize_constrained(
- algorithm, n, f, f_data, 0, NULL, NULL, 0,
- lb, ub, x, minf, minf_max, ftol_rel, ftol_abs,
- xtol_rel, xtol_abs, maxeval, maxtime);
-}
diff --git a/ext/src/nlopt/api/general.c b/ext/src/nlopt/api/general.c
deleted file mode 100644
index 40897d6..0000000
--- a/ext/src/nlopt/api/general.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/* Copyright (c) 2007-2012 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <math.h>
-#include <float.h>
-
-#include "nlopt/nlopt-internal.h"
-
-/*************************************************************************/
-
-int nlopt_isinf(double x) {
- return fabs(x) >= HUGE_VAL * 0.99
- || isinf(x)
- ;
-}
-
-/*************************************************************************/
-void NLOPT_STDCALL nlopt_version(int *major, int *minor, int *bugfix)
-{
- *major = 2;
- *minor = 5;
- *bugfix = 1;
-}
-
-/*************************************************************************/
-
-static const char nlopt_algorithm_names[NLOPT_NUM_ALGORITHMS][256] = {
- "DIRECT (global, no-derivative)",
- "DIRECT-L (global, no-derivative)",
- "Randomized DIRECT-L (global, no-derivative)",
- "Unscaled DIRECT (global, no-derivative)",
- "Unscaled DIRECT-L (global, no-derivative)",
- "Unscaled Randomized DIRECT-L (global, no-derivative)",
- "Original DIRECT version (global, no-derivative)",
- "Original DIRECT-L version (global, no-derivative)",
- "StoGO (global, derivative-based)",
- "StoGO with randomized search (global, derivative-based)",
- "original L-BFGS code by Nocedal et al. (NOT COMPILED)",
- "Limited-memory BFGS (L-BFGS) (local, derivative-based)",
- "Principal-axis, praxis (local, no-derivative)",
- "Limited-memory variable-metric, rank 1 (local, derivative-based)",
- "Limited-memory variable-metric, rank 2 (local, derivative-based)",
- "Truncated Newton (local, derivative-based)",
- "Truncated Newton with restarting (local, derivative-based)",
- "Preconditioned truncated Newton (local, derivative-based)",
- "Preconditioned truncated Newton with restarting (local, derivative-based)",
- "Controlled random search (CRS2) with local mutation (global, no-derivative)",
- "Multi-level single-linkage (MLSL), random (global, no-derivative)",
- "Multi-level single-linkage (MLSL), random (global, derivative)",
- "Multi-level single-linkage (MLSL), quasi-random (global, no-derivative)",
- "Multi-level single-linkage (MLSL), quasi-random (global, derivative)",
- "Method of Moving Asymptotes (MMA) (local, derivative)",
- "COBYLA (Constrained Optimization BY Linear Approximations) (local, no-derivative)",
- "NEWUOA unconstrained optimization via quadratic models (local, no-derivative)",
- "Bound-constrained optimization via NEWUOA-based quadratic models (local, no-derivative)",
- "Nelder-Mead simplex algorithm (local, no-derivative)",
- "Sbplx variant of Nelder-Mead (re-implementation of Rowan's Subplex) (local, no-derivative)",
- "Augmented Lagrangian method (local, no-derivative)",
- "Augmented Lagrangian method (local, derivative)",
- "Augmented Lagrangian method for equality constraints (local, no-derivative)",
- "Augmented Lagrangian method for equality constraints (local, derivative)",
- "BOBYQA bound-constrained optimization via quadratic models (local, no-derivative)",
- "ISRES evolutionary constrained optimization (global, no-derivative)",
- "Augmented Lagrangian method (needs sub-algorithm)",
- "Augmented Lagrangian method for equality constraints (needs sub-algorithm)",
- "Multi-level single-linkage (MLSL), random (global, needs sub-algorithm)",
- "Multi-level single-linkage (MLSL), quasi-random (global, needs sub-algorithm)",
- "Sequential Quadratic Programming (SQP) (local, derivative)",
- "CCSA (Conservative Convex Separable Approximations) with simple quadratic approximations (local, derivative)",
- "ESCH evolutionary strategy"
-};
-
-const char * NLOPT_STDCALL nlopt_algorithm_name(nlopt_algorithm a)
-{
- if (((int) a) < 0 || a >= NLOPT_NUM_ALGORITHMS) return "UNKNOWN";
- return nlopt_algorithm_names[a];
-}
-
-/*************************************************************************/
-/* get thread id, if possible, for use in nlopt_srand_time to ensure that
- different threads have a different default seed even if they are called
- simultaneously */
-
-#if defined(_WIN32) || defined(__WIN32__)
-# include <windows.h>
-# define my_gettid GetCurrentThreadId
-#elif defined(HAVE_GETTID_SYSCALL)
-# include <unistd.h>
-# include <sys/syscall.h>
-# define my_gettid() syscall(SYS_gettid)
-#elif defined(HAVE_GETPID)
-# include <sys/types.h>
-# include <unistd.h>
-# define my_gettid getpid
-#else
-# define my_gettid() (0)
-#endif
-
-/*************************************************************************/
-
-static __thread int nlopt_srand_called = 0;
-void NLOPT_STDCALL nlopt_srand(unsigned long seed) {
- nlopt_srand_called = 1;
- nlopt_init_genrand(seed);
-}
-
-void NLOPT_STDCALL nlopt_srand_time(void) {
- nlopt_srand(nlopt_time_seed() + my_gettid() * 314159);
-}
-
-void nlopt_srand_time_default(void) {
- if (!nlopt_srand_called) nlopt_srand_time();
-}
-
-/*************************************************************************/
diff --git a/ext/src/nlopt/api/optimize.c b/ext/src/nlopt/api/optimize.c
deleted file mode 100644
index cf8c07a..0000000
--- a/ext/src/nlopt/api/optimize.c
+++ /dev/null
@@ -1,767 +0,0 @@
-/* Copyright (c) 2007-2012 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <stdlib.h>
-#include <math.h>
-#include <float.h>
-
-#include "nlopt/nlopt-internal.h"
-
-/*********************************************************************/
-
-#include "nlopt/praxis.h"
-
-#include "nlopt/cdirect.h"
-
-#include "nlopt/crs.h"
-
-#include "nlopt/mlsl.h"
-#include "nlopt/mma.h"
-#include "nlopt/cobyla.h"
-#include "nlopt/newuoa.h"
-#include "nlopt/neldermead.h"
-#include "nlopt/auglag.h"
-#include "nlopt/bobyqa.h"
-#include "nlopt/isres.h"
-#include "nlopt/esch.h"
-
-/*********************************************************************/
-
-static double f_bound(int n, const double *x, void *data_)
-{
- int i;
- nlopt_opt data = (nlopt_opt) data_;
- double f;
-
- /* some methods do not support bound constraints, but support
- discontinuous objectives so we can just return Inf for invalid x */
- for (i = 0; i < n; ++i)
- if (x[i] < data->lb[i] || x[i] > data->ub[i])
- return HUGE_VAL;
-
- f = data->f((unsigned) n, x, NULL, data->f_data);
- return (isnan(f) || nlopt_isinf(f) ? HUGE_VAL : f);
-}
-
-static double f_noderiv(int n, const double *x, void *data_)
-{
- nlopt_opt data = (nlopt_opt) data_;
- return data->f((unsigned) n, x, NULL, data->f_data);
-}
-
-/*********************************************************************/
-
-/* get min(dx) for algorithms requiring a scalar initial step size */
-static nlopt_result initial_step(nlopt_opt opt, const double *x, double *step)
-{
- unsigned freedx = 0, i;
-
- if (!opt->dx) {
- freedx = 1;
- if (nlopt_set_default_initial_step(opt, x) != NLOPT_SUCCESS)
- return NLOPT_OUT_OF_MEMORY;
- }
-
- *step = HUGE_VAL;
- for (i = 0; i < opt->n; ++i)
- if (*step > fabs(opt->dx[i]))
- *step = fabs(opt->dx[i]);
-
- if (freedx) { free(opt->dx); opt->dx = NULL; }
- return NLOPT_SUCCESS;
-}
-
-/*********************************************************************/
-
-/* return true if [lb,ub] is finite in every dimension (n dimensions) */
-static int finite_domain(unsigned n, const double *lb, const double *ub)
-{
- unsigned i;
- for (i = 0; i < n; ++i)
- if (nlopt_isinf(ub[i] - lb[i])) return 0;
- return 1;
-}
-
-/*********************************************************************/
-/* wrapper functions, only for derivative-free methods, that
- eliminate dimensions with lb == ub. (The gradient-based methods
- should handle this case directly, since they operate on much
- larger vectors where I am loathe to make copies unnecessarily.) */
-
-typedef struct {
- nlopt_func f;
- nlopt_mfunc mf;
- void *f_data;
- unsigned n; /* true dimension */
- double *x; /* scratch vector of length n */
- double *grad; /* optional scratch vector of length n */
- const double *lb, *ub; /* bounds, of length n */
-} elimdim_data;
-
-static void *elimdim_makedata(nlopt_func f, nlopt_mfunc mf, void *f_data,
- unsigned n, double *x, const double *lb,
- const double *ub, double *grad)
-{
- elimdim_data *d = (elimdim_data *) malloc(sizeof(elimdim_data));
- if (!d) return NULL;
- d->f = f; d->mf = mf; d->f_data = f_data; d->n = n; d->x = x;
- d->lb = lb; d->ub = ub;
- d->grad = grad;
- return d;
-}
-
-static double elimdim_func(unsigned n0, const double *x0, double *grad, void *d_)
-{
- elimdim_data *d = (elimdim_data *) d_;
- double *x = d->x;
- const double *lb = d->lb, *ub = d->ub;
- double val;
- unsigned n = d->n, i, j;
-
- (void) n0; /* unused */
- for (i = j = 0; i < n; ++i) {
- if (lb[i] == ub[i])
- x[i] = lb[i];
- else /* assert: j < n0 */
- x[i] = x0[j++];
- }
- val = d->f(n, x, grad ? d->grad : NULL, d->f_data);
- if (grad) {
- /* assert: d->grad != NULL */
- for (i = j = 0; i < n; ++i)
- if (lb[i] != ub[i])
- grad[j++] = d->grad[i];
- }
- return val;
-}
-
-
-static void elimdim_mfunc(unsigned m, double *result,
- unsigned n0, const double *x0, double *grad, void *d_)
-{
- elimdim_data *d = (elimdim_data *) d_;
- double *x = d->x;
- const double *lb = d->lb, *ub = d->ub;
- unsigned n = d->n, i, j;
-
- (void) n0; /* unused */
- (void) grad; /* assert: grad == NULL */
- for (i = j = 0; i < n; ++i) {
- if (lb[i] == ub[i])
- x[i] = lb[i];
- else /* assert: j < n0 */
- x[i] = x0[j++];
- }
- d->mf(m, result, n, x, NULL, d->f_data);
-}
-
-/* compute the eliminated dimension: number of dims with lb[i] != ub[i] */
-static unsigned elimdim_dimension(unsigned n, const double *lb, const double *ub)
-{
- unsigned n0 = 0, i;
- for (i = 0; i < n; ++i) n0 += lb[i] != ub[i] ? 1U : 0;
- return n0;
-}
-
-/* modify v to "shrunk" version, with dimensions for lb[i] == ub[i] elim'ed */
-static void elimdim_shrink(unsigned n, double *v,
- const double *lb, const double *ub)
-{
- unsigned i, j;
- if (v)
- for (i = j = 0; i < n; ++i)
- if (lb[i] != ub[i])
- v[j++] = v[i];
-}
-
-/* inverse of elimdim_shrink */
-static void elimdim_expand(unsigned n, double *v,
- const double *lb, const double *ub)
-{
- unsigned i, j;
- if (v && n > 0) {
- j = elimdim_dimension(n, lb, ub) - 1;
- for (i = n - 1; i > 0; --i) {
- if (lb[i] != ub[i])
- v[i] = v[j--];
- else
- v[i] = lb[i];
- }
- if (lb[0] == ub[0])
- v[0] = lb[0];
- }
-}
-
-/* given opt, create a new opt with equal-constraint dimensions eliminated */
-static nlopt_opt elimdim_create(nlopt_opt opt)
-{
- nlopt_opt opt0 = nlopt_copy(opt);
- double *x, *grad = NULL;
- unsigned i;
-
- if (!opt0) return NULL;
- x = (double *) malloc(sizeof(double) * opt->n);
- if (opt->n && !x) { nlopt_destroy(opt0); return NULL; }
-
- if (opt->algorithm == NLOPT_GD_STOGO
- || opt->algorithm == NLOPT_GD_STOGO_RAND) {
- grad = (double *) malloc(sizeof(double) * opt->n);
- if (opt->n && !grad) goto bad;
- }
-
- opt0->n = elimdim_dimension(opt->n, opt->lb, opt->ub);
- elimdim_shrink(opt->n, opt0->lb, opt->lb, opt->ub);
- elimdim_shrink(opt->n, opt0->ub, opt->lb, opt->ub);
- elimdim_shrink(opt->n, opt0->xtol_abs, opt->lb, opt->ub);
- elimdim_shrink(opt->n, opt0->dx, opt->lb, opt->ub);
-
- opt0->munge_on_destroy = opt0->munge_on_copy = NULL;
-
- opt0->f = elimdim_func;
- opt0->f_data = elimdim_makedata(opt->f, NULL, opt->f_data,
- opt->n, x, opt->lb, opt->ub, grad);
- if (!opt0->f_data) goto bad;
-
- for (i = 0; i < opt->m; ++i) {
- opt0->fc[i].f = elimdim_func;
- opt0->fc[i].mf = elimdim_mfunc;
- opt0->fc[i].f_data = elimdim_makedata(opt->fc[i].f, opt->fc[i].mf,
- opt->fc[i].f_data,
- opt->n, x, opt->lb, opt->ub,
- NULL);
- if (!opt0->fc[i].f_data) goto bad;
- }
-
- for (i = 0; i < opt->p; ++i) {
- opt0->h[i].f = elimdim_func;
- opt0->h[i].mf = elimdim_mfunc;
- opt0->h[i].f_data = elimdim_makedata(opt->h[i].f, opt->h[i].mf,
- opt->h[i].f_data,
- opt->n, x, opt->lb, opt->ub,
- NULL);
- if (!opt0->h[i].f_data) goto bad;
- }
-
- return opt0;
-bad:
- free(grad);
- free(x);
- nlopt_destroy(opt0);
- return NULL;
-}
-
-/* like nlopt_destroy, but also frees elimdim_data */
-static void elimdim_destroy(nlopt_opt opt)
-{
- unsigned i;
- if (!opt) return;
-
- free(((elimdim_data*) opt->f_data)->x);
- free(((elimdim_data*) opt->f_data)->grad);
- free(opt->f_data); opt->f_data = NULL;
-
- for (i = 0; i < opt->m; ++i) {
- free(opt->fc[i].f_data);
- opt->fc[i].f_data = NULL;
- }
- for (i = 0; i < opt->p; ++i) {
- free(opt->h[i].f_data);
- opt->h[i].f_data = NULL;
- }
-
- nlopt_destroy(opt);
-}
-
-/* return whether to use elimdim wrapping. */
-static int elimdim_wrapcheck(nlopt_opt opt)
-{
- if (!opt) return 0;
- if (elimdim_dimension(opt->n, opt->lb, opt->ub) == opt->n) return 0;
- switch (opt->algorithm) {
- case NLOPT_GN_DIRECT:
- case NLOPT_GN_DIRECT_L:
- case NLOPT_GN_DIRECT_L_RAND:
- case NLOPT_GN_DIRECT_NOSCAL:
- case NLOPT_GN_DIRECT_L_NOSCAL:
- case NLOPT_GN_DIRECT_L_RAND_NOSCAL:
- case NLOPT_GN_ORIG_DIRECT:
- case NLOPT_GN_ORIG_DIRECT_L:
- case NLOPT_LN_PRAXIS:
- case NLOPT_LN_COBYLA:
- case NLOPT_LN_NEWUOA:
- case NLOPT_LN_NEWUOA_BOUND:
- case NLOPT_LN_BOBYQA:
- case NLOPT_LN_NELDERMEAD:
- case NLOPT_LN_SBPLX:
- case NLOPT_GN_ISRES:
- case NLOPT_GN_ESCH:
- case NLOPT_GD_STOGO:
- case NLOPT_GD_STOGO_RAND:
- return 1;
-
- default: return 0;
- }
-}
-
-/*********************************************************************/
-
-#define POP(defaultpop) (opt->stochastic_population > 0 ? \
- opt->stochastic_population : \
- (nlopt_stochastic_population > 0 ? \
- nlopt_stochastic_population : (defaultpop)))
-
-/* unlike nlopt_optimize() below, only handles minimization case */
-static nlopt_result nlopt_optimize_(nlopt_opt opt, double *x, double *minf)
-{
- const double *lb, *ub;
- nlopt_algorithm algorithm;
- nlopt_func f; void *f_data;
- unsigned n, i;
- int ni;
- nlopt_stopping stop;
-
- if (!opt || !x || !minf || !opt->f
- || opt->maximize) return NLOPT_INVALID_ARGS;
-
- /* reset stopping flag */
- nlopt_set_force_stop(opt, 0);
- opt->force_stop_child = NULL;
-
- /* copy a few params to local vars for convenience */
- n = opt->n;
- ni = (int) n; /* most of the subroutines take "int" arg */
- lb = opt->lb; ub = opt->ub;
- algorithm = opt->algorithm;
- f = opt->f; f_data = opt->f_data;
-
- if (n == 0) { /* trivial case: no degrees of freedom */
- *minf = opt->f(n, x, NULL, opt->f_data);
- return NLOPT_SUCCESS;
- }
-
- *minf = HUGE_VAL;
-
- /* make sure rand generator is inited */
- nlopt_srand_time_default(); /* default is non-deterministic */
-
- /* check bound constraints */
- for (i = 0; i < n; ++i)
- if (lb[i] > ub[i] || x[i] < lb[i] || x[i] > ub[i])
- return NLOPT_INVALID_ARGS;
-
- stop.n = n;
- stop.minf_max = opt->stopval;
- stop.ftol_rel = opt->ftol_rel;
- stop.ftol_abs = opt->ftol_abs;
- stop.xtol_rel = opt->xtol_rel;
- stop.xtol_abs = opt->xtol_abs;
- stop.nevals = 0;
- stop.maxeval = opt->maxeval;
- stop.maxtime = opt->maxtime;
- stop.start = nlopt_seconds();
- stop.force_stop = &(opt->force_stop);
-
- switch (algorithm) {
- case NLOPT_GN_DIRECT:
- case NLOPT_GN_DIRECT_L:
- case NLOPT_GN_DIRECT_L_RAND:
- if (!finite_domain(n, lb, ub)) return NLOPT_INVALID_ARGS;
- return cdirect(ni, f, f_data,
- lb, ub, x, minf, &stop, 0.0,
- (algorithm != NLOPT_GN_DIRECT)
- + 3 * (algorithm == NLOPT_GN_DIRECT_L_RAND
- ? 2 : (algorithm != NLOPT_GN_DIRECT))
- + 9 * (algorithm == NLOPT_GN_DIRECT_L_RAND
- ? 1 : (algorithm != NLOPT_GN_DIRECT)));
-
- case NLOPT_GN_DIRECT_NOSCAL:
- case NLOPT_GN_DIRECT_L_NOSCAL:
- case NLOPT_GN_DIRECT_L_RAND_NOSCAL:
- if (!finite_domain(n, lb, ub)) return NLOPT_INVALID_ARGS;
- return cdirect_unscaled(ni, f, f_data, lb, ub, x, minf,
- &stop, 0.0,
- (algorithm != NLOPT_GN_DIRECT)
- + 3 * (algorithm == NLOPT_GN_DIRECT_L_RAND ? 2 : (algorithm != NLOPT_GN_DIRECT))
- + 9 * (algorithm == NLOPT_GN_DIRECT_L_RAND ? 1 : (algorithm != NLOPT_GN_DIRECT)));
-
- case NLOPT_GD_STOGO:
- case NLOPT_GD_STOGO_RAND:
-#ifdef WITH_CXX
- if (!finite_domain(n, lb, ub)) return NLOPT_INVALID_ARGS;
- if (!stogo_minimize(ni, f, f_data, x, minf, lb, ub, &stop,
- algorithm == NLOPT_GD_STOGO
- ? 0 : (int) POP(2*n)))
- return NLOPT_FAILURE;
- break;
-#else
- return NLOPT_INVALID_ARGS;
-#endif
-
-#if 0
- /* lacking a free/open-source license, we no longer use
- Rowan's code, and instead use by "sbplx" re-implementation */
- case NLOPT_LN_SUBPLEX: {
- int iret, freedx = 0;
- if (!opt->dx) {
- freedx = 1;
- if (nlopt_set_default_initial_step(opt, x) != NLOPT_SUCCESS)
- return NLOPT_OUT_OF_MEMORY;
- }
- iret = nlopt_subplex(f_bound, minf, x, n, opt, &stop, opt->dx);
- if (freedx) { free(opt->dx); opt->dx = NULL; }
- switch (iret) {
- case -2: return NLOPT_INVALID_ARGS;
- case -20: return NLOPT_FORCED_STOP;
- case -10: return NLOPT_MAXTIME_REACHED;
- case -1: return NLOPT_MAXEVAL_REACHED;
- case 0: return NLOPT_XTOL_REACHED;
- case 1: return NLOPT_SUCCESS;
- case 2: return NLOPT_MINF_MAX_REACHED;
- case 20: return NLOPT_FTOL_REACHED;
- case -200: return NLOPT_OUT_OF_MEMORY;
- default: return NLOPT_FAILURE; /* unknown return code */
- }
- break;
- }
-#endif
-
- case NLOPT_LN_PRAXIS: {
- double step;
- if (initial_step(opt, x, &step) != NLOPT_SUCCESS)
- return NLOPT_OUT_OF_MEMORY;
- return praxis_(0.0, DBL_EPSILON,
- step, ni, x, f_bound, opt, &stop, minf);
- }
-
- case NLOPT_GN_CRS2_LM:
- if (!finite_domain(n, lb, ub)) return NLOPT_INVALID_ARGS;
- return crs_minimize(ni, f, f_data, lb, ub, x, minf, &stop,
- (int) POP(0), 0);
-
- case NLOPT_G_MLSL:
- case NLOPT_G_MLSL_LDS:
- case NLOPT_GN_MLSL:
- case NLOPT_GD_MLSL:
- case NLOPT_GN_MLSL_LDS:
- case NLOPT_GD_MLSL_LDS: {
- nlopt_opt local_opt = opt->local_opt;
- nlopt_result ret;
- if (!finite_domain(n, lb, ub)) return NLOPT_INVALID_ARGS;
- if (!local_opt && (algorithm == NLOPT_G_MLSL
- || algorithm == NLOPT_G_MLSL_LDS))
- return NLOPT_INVALID_ARGS;
- if (!local_opt) { /* default */
- nlopt_algorithm local_alg = (algorithm == NLOPT_GN_MLSL ||
- algorithm == NLOPT_GN_MLSL_LDS)
- ? nlopt_local_search_alg_nonderiv
- : nlopt_local_search_alg_deriv;
- /* don't call MLSL recursively! */
- if (local_alg >= NLOPT_GN_MLSL
- && local_alg <= NLOPT_GD_MLSL_LDS)
- local_alg = (algorithm == NLOPT_GN_MLSL ||
- algorithm == NLOPT_GN_MLSL_LDS)
- ? NLOPT_LN_COBYLA : NLOPT_LD_MMA;
- local_opt = nlopt_create(local_alg, n);
- if (!local_opt) return NLOPT_FAILURE;
- nlopt_set_ftol_rel(local_opt, opt->ftol_rel);
- nlopt_set_ftol_abs(local_opt, opt->ftol_abs);
- nlopt_set_xtol_rel(local_opt, opt->xtol_rel);
- nlopt_set_xtol_abs(local_opt, opt->xtol_abs);
- nlopt_set_maxeval(local_opt, nlopt_local_search_maxeval);
- }
- if (opt->dx) nlopt_set_initial_step(local_opt, opt->dx);
- for (i = 0; i < n && stop.xtol_abs[i] > 0; ++i) ;
- if (local_opt->ftol_rel <= 0 && local_opt->ftol_abs <= 0 &&
- local_opt->xtol_rel <= 0 && i < n) {
- /* it is not sensible to call MLSL without *some*
- nonzero tolerance for the local search */
- nlopt_set_ftol_rel(local_opt, 1e-15);
- nlopt_set_xtol_rel(local_opt, 1e-7);
- }
- opt->force_stop_child = local_opt;
- ret = mlsl_minimize(ni, f, f_data, lb, ub, x, minf, &stop,
- local_opt, (int) POP(0),
- algorithm >= NLOPT_GN_MLSL_LDS &&
- algorithm != NLOPT_G_MLSL);
- opt->force_stop_child = NULL;
- if (!opt->local_opt) nlopt_destroy(local_opt);
- return ret;
- }
-
- case NLOPT_LD_MMA: case NLOPT_LD_CCSAQ: {
- nlopt_opt dual_opt;
- nlopt_result ret;
-#define LO(param, def) (opt->local_opt ? opt->local_opt->param : (def))
- dual_opt = nlopt_create(LO(algorithm,
- nlopt_local_search_alg_deriv),
- nlopt_count_constraints(opt->m,
- opt->fc));
- if (!dual_opt) return NLOPT_FAILURE;
- nlopt_set_ftol_rel(dual_opt, LO(ftol_rel, 1e-14));
- nlopt_set_ftol_abs(dual_opt, LO(ftol_abs, 0.0));
- nlopt_set_maxeval(dual_opt, LO(maxeval, 100000));
-#undef LO
-
- if (algorithm == NLOPT_LD_MMA)
- ret = mma_minimize(n, f, f_data, opt->m, opt->fc,
- lb, ub, x, minf, &stop, dual_opt);
- else
- ret = ccsa_quadratic_minimize(
- n, f, f_data, opt->m, opt->fc, opt->pre,
- lb, ub, x, minf, &stop, dual_opt);
- nlopt_destroy(dual_opt);
- return ret;
- }
-
- case NLOPT_LN_COBYLA: {
- nlopt_result ret;
- int freedx = 0;
- if (!opt->dx) {
- freedx = 1;
- if (nlopt_set_default_initial_step(opt, x) != NLOPT_SUCCESS)
- return NLOPT_OUT_OF_MEMORY;
- }
- return cobyla_minimize(n, f, f_data,
- opt->m, opt->fc,
- opt->p, opt->h,
- lb, ub, x, minf, &stop,
- opt->dx);
- if (freedx) { free(opt->dx); opt->dx = NULL; }
- return ret;
- }
-
- case NLOPT_LN_NEWUOA: {
- double step;
- if (initial_step(opt, x, &step) != NLOPT_SUCCESS)
- return NLOPT_OUT_OF_MEMORY;
- return newuoa(ni, 2*n+1, x, 0, 0, step,
- &stop, minf, f_noderiv, opt);
- }
-
- case NLOPT_LN_NEWUOA_BOUND: {
- double step;
- if (initial_step(opt, x, &step) != NLOPT_SUCCESS)
- return NLOPT_OUT_OF_MEMORY;
- return newuoa(ni, 2*n+1, x, lb, ub, step,
- &stop, minf, f_noderiv, opt);
- }
-
- case NLOPT_LN_BOBYQA: {
- nlopt_result ret;
- int freedx = 0;
- if (!opt->dx) {
- freedx = 1;
- if (nlopt_set_default_initial_step(opt, x) != NLOPT_SUCCESS)
- return NLOPT_OUT_OF_MEMORY;
- }
- ret = bobyqa(ni, 2*n+1, x, lb, ub, opt->dx,
- &stop, minf, opt->f, opt->f_data);
- if (freedx) { free(opt->dx); opt->dx = NULL; }
- return ret;
- }
-
- case NLOPT_LN_NELDERMEAD:
- case NLOPT_LN_SBPLX:
- {
- nlopt_result ret;
- int freedx = 0;
- if (!opt->dx) {
- freedx = 1;
- if (nlopt_set_default_initial_step(opt, x) != NLOPT_SUCCESS)
- return NLOPT_OUT_OF_MEMORY;
- }
- if (algorithm == NLOPT_LN_NELDERMEAD)
- ret= nldrmd_minimize(ni,f,f_data,lb,ub,x,minf,opt->dx,&stop);
- else
- ret= sbplx_minimize(ni,f,f_data,lb,ub,x,minf,opt->dx,&stop);
- if (freedx) { free(opt->dx); opt->dx = NULL; }
- return ret;
- }
-
- case NLOPT_AUGLAG:
- case NLOPT_AUGLAG_EQ:
- case NLOPT_LN_AUGLAG:
- case NLOPT_LN_AUGLAG_EQ:
- case NLOPT_LD_AUGLAG:
- case NLOPT_LD_AUGLAG_EQ: {
- nlopt_opt local_opt = opt->local_opt;
- nlopt_result ret;
- if ((algorithm == NLOPT_AUGLAG || algorithm == NLOPT_AUGLAG_EQ)
- && !local_opt)
- return NLOPT_INVALID_ARGS;
- if (!local_opt) { /* default */
- local_opt = nlopt_create(
- algorithm == NLOPT_LN_AUGLAG ||
- algorithm == NLOPT_LN_AUGLAG_EQ
- ? nlopt_local_search_alg_nonderiv
- : nlopt_local_search_alg_deriv, n);
- if (!local_opt) return NLOPT_FAILURE;
- nlopt_set_ftol_rel(local_opt, opt->ftol_rel);
- nlopt_set_ftol_abs(local_opt, opt->ftol_abs);
- nlopt_set_xtol_rel(local_opt, opt->xtol_rel);
- nlopt_set_xtol_abs(local_opt, opt->xtol_abs);
- nlopt_set_maxeval(local_opt, nlopt_local_search_maxeval);
- }
- if (opt->dx) nlopt_set_initial_step(local_opt, opt->dx);
- opt->force_stop_child = local_opt;
- ret = auglag_minimize(ni, f, f_data,
- opt->m, opt->fc,
- opt->p, opt->h,
- lb, ub, x, minf, &stop,
- local_opt,
- algorithm == NLOPT_AUGLAG_EQ
- || algorithm == NLOPT_LN_AUGLAG_EQ
- || algorithm == NLOPT_LD_AUGLAG_EQ);
- opt->force_stop_child = NULL;
- if (!opt->local_opt) nlopt_destroy(local_opt);
- return ret;
- }
-
- case NLOPT_GN_ISRES:
- if (!finite_domain(n, lb, ub)) return NLOPT_INVALID_ARGS;
- return isres_minimize(ni, f, f_data,
- (int) (opt->m), opt->fc,
- (int) (opt->p), opt->h,
- lb, ub, x, minf, &stop,
- (int) POP(0));
-
- case NLOPT_GN_ESCH:
- if (!finite_domain(n, lb, ub)) return NLOPT_INVALID_ARGS;
- return chevolutionarystrategy(n, f, f_data,
- lb, ub, x, minf, &stop,
- (unsigned) POP(0),
- (unsigned) (POP(0)*1.5));
-
- default:
- return NLOPT_INVALID_ARGS;
- }
-
- return NLOPT_SUCCESS; /* never reached */
-}
-
-/*********************************************************************/
-
-typedef struct {
- nlopt_func f;
- nlopt_precond pre;
- void *f_data;
-} f_max_data;
-
-/* wrapper for maximizing: just flip the sign of f and grad */
-static double f_max(unsigned n, const double *x, double *grad, void *data)
-{
- f_max_data *d = (f_max_data *) data;
- double val = d->f(n, x, grad, d->f_data);
- if (grad) {
- unsigned i;
- for (i = 0; i < n; ++i)
- grad[i] = -grad[i];
- }
- return -val;
-}
-
-static void pre_max(unsigned n, const double *x, const double *v,
- double *vpre, void *data)
-{
- f_max_data *d = (f_max_data *) data;
- unsigned i;
- d->pre(n, x, v, vpre, d->f_data);
- for (i = 0; i < n; ++i) vpre[i] = -vpre[i];
-}
-
-nlopt_result
-NLOPT_STDCALL nlopt_optimize(nlopt_opt opt, double *x, double *opt_f)
-{
- nlopt_func f; void *f_data; nlopt_precond pre;
- f_max_data fmd;
- int maximize;
- nlopt_result ret;
-
- if (!opt || !opt_f || !opt->f) return NLOPT_INVALID_ARGS;
- f = opt->f; f_data = opt->f_data; pre = opt->pre;
-
- /* for maximizing, just minimize the f_max wrapper, which
- flips the sign of everything */
- if ((maximize = opt->maximize)) {
- fmd.f = f; fmd.f_data = f_data; fmd.pre = pre;
- opt->f = f_max; opt->f_data = &fmd;
- if (opt->pre) opt->pre = pre_max;
- opt->stopval = -opt->stopval;
- opt->maximize = 0;
- }
-
- { /* possibly eliminate lb == ub dimensions for some algorithms */
- nlopt_opt elim_opt = opt;
- if (elimdim_wrapcheck(opt)) {
- elim_opt = elimdim_create(opt);
- if (!elim_opt) { ret = NLOPT_OUT_OF_MEMORY; goto done; }
- elimdim_shrink(opt->n, x, opt->lb, opt->ub);
- }
-
- ret = nlopt_optimize_(elim_opt, x, opt_f);
-
- if (elim_opt != opt) {
- elimdim_destroy(elim_opt);
- elimdim_expand(opt->n, x, opt->lb, opt->ub);
- }
- }
-
-done:
- if (maximize) { /* restore original signs */
- opt->maximize = maximize;
- opt->stopval = -opt->stopval;
- opt->f = f; opt->f_data = f_data; opt->pre = pre;
- *opt_f = -*opt_f;
- }
-
- return ret;
-}
-
-/*********************************************************************/
-
-nlopt_result nlopt_optimize_limited(nlopt_opt opt, double *x, double *minf,
- int maxeval, double maxtime)
-{
- int save_maxeval;
- double save_maxtime;
- nlopt_result ret;
-
- if (!opt) return NLOPT_INVALID_ARGS;
-
- save_maxeval = nlopt_get_maxeval(opt);
- save_maxtime = nlopt_get_maxtime(opt);
-
- /* override opt limits if maxeval and/or maxtime are more stringent */
- if (save_maxeval <= 0 || (maxeval > 0 && maxeval < save_maxeval))
- nlopt_set_maxeval(opt, maxeval);
- if (save_maxtime <= 0 || (maxtime > 0 && maxtime < save_maxtime))
- nlopt_set_maxtime(opt, maxtime);
-
- ret = nlopt_optimize(opt, x, minf);
-
- nlopt_set_maxeval(opt, save_maxeval);
- nlopt_set_maxtime(opt, save_maxtime);
-
- return ret;
-}
-
-/*********************************************************************/
diff --git a/ext/src/nlopt/api/options.c b/ext/src/nlopt/api/options.c
deleted file mode 100644
index 0369704..0000000
--- a/ext/src/nlopt/api/options.c
+++ /dev/null
@@ -1,753 +0,0 @@
-/* Copyright (c) 2007-2012 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include <string.h>
-#include <float.h>
-
-#include "nlopt/nlopt-internal.h"
-
-/*************************************************************************/
-
-void NLOPT_STDCALL nlopt_destroy(nlopt_opt opt)
-{
- if (opt) {
- unsigned i;
- if (opt->munge_on_destroy) {
- nlopt_munge munge = opt->munge_on_destroy;
- munge(opt->f_data);
- for (i = 0; i < opt->m; ++i)
- munge(opt->fc[i].f_data);
- for (i = 0; i < opt->p; ++i)
- munge(opt->h[i].f_data);
- }
- for (i = 0; i < opt->m; ++i)
- free(opt->fc[i].tol);
- for (i = 0; i < opt->p; ++i)
- free(opt->h[i].tol);
- free(opt->lb); free(opt->ub);
- free(opt->xtol_abs);
- free(opt->fc);
- free(opt->h);
- nlopt_destroy(opt->local_opt);
- free(opt->dx);
- free(opt->work);
- free(opt);
- }
-}
-
-nlopt_opt NLOPT_STDCALL nlopt_create(nlopt_algorithm algorithm, unsigned n)
-{
- nlopt_opt opt;
-
- if (((int) algorithm) < 0 || algorithm >= NLOPT_NUM_ALGORITHMS)
- return NULL;
-
- opt = (nlopt_opt) malloc(sizeof(struct nlopt_opt_s));
- if (opt) {
- opt->algorithm = algorithm;
- opt->n = n;
- opt->f = NULL; opt->f_data = NULL; opt->pre = NULL;
- opt->maximize = 0;
- opt->munge_on_destroy = opt->munge_on_copy = NULL;
-
- opt->lb = opt->ub = NULL;
- opt->m = opt->m_alloc = 0;
- opt->fc = NULL;
- opt->p = opt->p_alloc = 0;
- opt->h = NULL;
-
- opt->stopval = -HUGE_VAL;
- opt->ftol_rel = opt->ftol_abs = 0;
- opt->xtol_rel = 0; opt->xtol_abs = NULL;
- opt->maxeval = 0;
- opt->maxtime = 0;
- opt->force_stop = 0;
- opt->force_stop_child = NULL;
-
- opt->local_opt = NULL;
- opt->stochastic_population = 0;
- opt->vector_storage = 0;
- opt->dx = NULL;
- opt->work = NULL;
-
- if (n > 0) {
- opt->lb = (double *) malloc(sizeof(double) * (n));
- if (!opt->lb) goto oom;
- opt->ub = (double *) malloc(sizeof(double) * (n));
- if (!opt->ub) goto oom;
- opt->xtol_abs = (double *) malloc(sizeof(double) * (n));
- if (!opt->xtol_abs) goto oom;
- nlopt_set_lower_bounds1(opt, -HUGE_VAL);
- nlopt_set_upper_bounds1(opt, +HUGE_VAL);
- nlopt_set_xtol_abs1(opt, 0.0);
- }
- }
-
- return opt;
-
-oom:
- nlopt_destroy(opt);
- return NULL;
-}
-
-nlopt_opt NLOPT_STDCALL nlopt_copy(const nlopt_opt opt)
-{
- nlopt_opt nopt = NULL;
- unsigned i;
- if (opt) {
- nlopt_munge munge;
- nopt = (nlopt_opt) malloc(sizeof(struct nlopt_opt_s));
- *nopt = *opt;
- nopt->lb = nopt->ub = nopt->xtol_abs = NULL;
- nopt->fc = nopt->h = NULL;
- nopt->m_alloc = nopt->p_alloc = 0;
- nopt->local_opt = NULL;
- nopt->dx = NULL;
- nopt->work = NULL;
- opt->force_stop_child = NULL;
-
- munge = nopt->munge_on_copy;
- if (munge && nopt->f_data)
- if (!(nopt->f_data = munge(nopt->f_data))) goto oom;
-
- if (opt->n > 0) {
- nopt->lb = (double *) malloc(sizeof(double) * (opt->n));
- if (!opt->lb) goto oom;
- nopt->ub = (double *) malloc(sizeof(double) * (opt->n));
- if (!opt->ub) goto oom;
- nopt->xtol_abs = (double *) malloc(sizeof(double) * (opt->n));
- if (!opt->xtol_abs) goto oom;
-
- memcpy(nopt->lb, opt->lb, sizeof(double) * (opt->n));
- memcpy(nopt->ub, opt->ub, sizeof(double) * (opt->n));
- memcpy(nopt->xtol_abs, opt->xtol_abs, sizeof(double) * (opt->n));
- }
-
- if (opt->m) {
- nopt->m_alloc = opt->m;
- nopt->fc = (nlopt_constraint *) malloc(sizeof(nlopt_constraint)
- * (opt->m));
- if (!nopt->fc) goto oom;
- memcpy(nopt->fc, opt->fc, sizeof(nlopt_constraint) * (opt->m));
- for (i = 0; i < opt->m; ++i) nopt->fc[i].tol = NULL;
- if (munge)
- for (i = 0; i < opt->m; ++i)
- if (nopt->fc[i].f_data &&
- !(nopt->fc[i].f_data
- = munge(nopt->fc[i].f_data)))
- goto oom;
- for (i = 0; i < opt->m; ++i)
- if (opt->fc[i].tol) {
- nopt->fc[i].tol = (double *) malloc(sizeof(double)
- * nopt->fc[i].m);
- if (!nopt->fc[i].tol) goto oom;
- memcpy(nopt->fc[i].tol, opt->fc[i].tol,
- sizeof(double) * nopt->fc[i].m);
- }
- }
-
- if (opt->p) {
- nopt->p_alloc = opt->p;
- nopt->h = (nlopt_constraint *) malloc(sizeof(nlopt_constraint)
- * (opt->p));
- if (!nopt->h) goto oom;
- memcpy(nopt->h, opt->h, sizeof(nlopt_constraint) * (opt->p));
- for (i = 0; i < opt->p; ++i) nopt->h[i].tol = NULL;
- if (munge)
- for (i = 0; i < opt->p; ++i)
- if (nopt->h[i].f_data &&
- !(nopt->h[i].f_data
- = munge(nopt->h[i].f_data)))
- goto oom;
- for (i = 0; i < opt->p; ++i)
- if (opt->h[i].tol) {
- nopt->h[i].tol = (double *) malloc(sizeof(double)
- * nopt->h[i].m);
- if (!nopt->h[i].tol) goto oom;
- memcpy(nopt->h[i].tol, opt->h[i].tol,
- sizeof(double) * nopt->h[i].m);
- }
- }
-
- if (opt->local_opt) {
- nopt->local_opt = nlopt_copy(opt->local_opt);
- if (!nopt->local_opt) goto oom;
- }
-
- if (opt->dx) {
- nopt->dx = (double *) malloc(sizeof(double) * (opt->n));
- if (!nopt->dx) goto oom;
- memcpy(nopt->dx, opt->dx, sizeof(double) * (opt->n));
- }
- }
- return nopt;
-
-oom:
- nopt->munge_on_destroy = NULL; // better to leak mem than crash
- nlopt_destroy(nopt);
- return NULL;
-}
-
-/*************************************************************************/
-
-nlopt_result NLOPT_STDCALL nlopt_set_precond_min_objective(nlopt_opt opt,
- nlopt_func f,
- nlopt_precond pre,
- void *f_data)
-{
- if (opt) {
- if (opt->munge_on_destroy) opt->munge_on_destroy(opt->f_data);
- opt->f = f; opt->f_data = f_data; opt->pre = pre;
- opt->maximize = 0;
- if (nlopt_isinf(opt->stopval) && opt->stopval > 0)
- opt->stopval = -HUGE_VAL; /* switch default from max to min */
- return NLOPT_SUCCESS;
- }
- return NLOPT_INVALID_ARGS;
-}
-
-nlopt_result NLOPT_STDCALL nlopt_set_min_objective(nlopt_opt opt,
- nlopt_func f, void *f_data)
-{
- return nlopt_set_precond_min_objective(opt, f, NULL, f_data);
-}
-
-nlopt_result NLOPT_STDCALL nlopt_set_precond_max_objective(nlopt_opt opt,
- nlopt_func f,
- nlopt_precond pre,
- void *f_data)
-{
- if (opt) {
- if (opt->munge_on_destroy) opt->munge_on_destroy(opt->f_data);
- opt->f = f; opt->f_data = f_data; opt->pre = pre;
- opt->maximize = 1;
- if (nlopt_isinf(opt->stopval) && opt->stopval < 0)
- opt->stopval = +HUGE_VAL; /* switch default from min to max */
- return NLOPT_SUCCESS;
- }
- return NLOPT_INVALID_ARGS;
-}
-
-nlopt_result NLOPT_STDCALL nlopt_set_max_objective(nlopt_opt opt,
- nlopt_func f, void *f_data)
-{
- return nlopt_set_precond_max_objective(opt, f, NULL, f_data);
-}
-
-/*************************************************************************/
-
-nlopt_result
-NLOPT_STDCALL nlopt_set_lower_bounds(nlopt_opt opt, const double *lb)
-{
- if (opt && (opt->n == 0 || lb)) {
- memcpy(opt->lb, lb, sizeof(double) * (opt->n));
- return NLOPT_SUCCESS;
- }
- return NLOPT_INVALID_ARGS;
-}
-
-nlopt_result
-NLOPT_STDCALL nlopt_set_lower_bounds1(nlopt_opt opt, double lb)
-{
- if (opt) {
- unsigned i;
- for (i = 0; i < opt->n; ++i)
- opt->lb[i] = lb;
- return NLOPT_SUCCESS;
- }
- return NLOPT_INVALID_ARGS;
-}
-
-nlopt_result
-NLOPT_STDCALL nlopt_get_lower_bounds(const nlopt_opt opt, double *lb)
-{
- if (opt && (opt->n == 0 || lb)) {
- memcpy(lb, opt->lb, sizeof(double) * (opt->n));
- return NLOPT_SUCCESS;
- }
- return NLOPT_INVALID_ARGS;
-}
-
-nlopt_result
-NLOPT_STDCALL nlopt_set_upper_bounds(nlopt_opt opt, const double *ub)
-{
- if (opt && (opt->n == 0 || ub)) {
- memcpy(opt->ub, ub, sizeof(double) * (opt->n));
- return NLOPT_SUCCESS;
- }
- return NLOPT_INVALID_ARGS;
-}
-
-nlopt_result
-NLOPT_STDCALL nlopt_set_upper_bounds1(nlopt_opt opt, double ub)
-{
- if (opt) {
- unsigned i;
- for (i = 0; i < opt->n; ++i)
- opt->ub[i] = ub;
- return NLOPT_SUCCESS;
- }
- return NLOPT_INVALID_ARGS;
-}
-
-nlopt_result
-NLOPT_STDCALL nlopt_get_upper_bounds(const nlopt_opt opt, double *ub)
-{
- if (opt && (opt->n == 0 || ub)) {
- memcpy(ub, opt->ub, sizeof(double) * (opt->n));
- return NLOPT_SUCCESS;
- }
- return NLOPT_INVALID_ARGS;
-}
-
-/*************************************************************************/
-
-#define AUGLAG_ALG(a) ((a) == NLOPT_AUGLAG || \
- (a) == NLOPT_AUGLAG_EQ || \
- (a) == NLOPT_LN_AUGLAG || \
- (a) == NLOPT_LN_AUGLAG_EQ || \
- (a) == NLOPT_LD_AUGLAG || \
- (a) == NLOPT_LD_AUGLAG_EQ)
-
-nlopt_result
-NLOPT_STDCALL nlopt_remove_inequality_constraints(nlopt_opt opt)
-{
- unsigned i;
- if (!opt) return NLOPT_INVALID_ARGS;
- if (opt->munge_on_destroy) {
- nlopt_munge munge = opt->munge_on_destroy;
- for (i = 0; i < opt->m; ++i)
- munge(opt->fc[i].f_data);
- }
- for (i = 0; i < opt->m; ++i)
- free(opt->fc[i].tol);
- free(opt->fc);
- opt->fc = NULL;
- opt->m = opt->m_alloc = 0;
- return NLOPT_SUCCESS;
-}
-
-static nlopt_result add_constraint(unsigned *m, unsigned *m_alloc,
- nlopt_constraint **c,
- unsigned fm, nlopt_func fc, nlopt_mfunc mfc,
- nlopt_precond pre,
- void *fc_data,
- const double *tol)
-{
- double *tolcopy;
- unsigned i;
-
- if ((fc && mfc) || (fc && fm != 1) || (!fc && !mfc))
- return NLOPT_INVALID_ARGS;
- if (tol)
- for (i = 0; i < fm; ++i) if (tol[i] < 0) return NLOPT_INVALID_ARGS;
-
- tolcopy = (double *) malloc(sizeof(double) * fm);
- if (fm && !tolcopy) return NLOPT_OUT_OF_MEMORY;
- if (tol)
- memcpy(tolcopy, tol, sizeof(double) * fm);
- else
- for (i = 0; i < fm; ++i) tolcopy[i] = 0;
-
- *m += 1;
- if (*m > *m_alloc) {
- /* allocate by repeated doubling so that
- we end up with O(log m) mallocs rather than O(m). */
- *m_alloc = 2 * (*m);
- *c = (nlopt_constraint *) realloc(*c,
- sizeof(nlopt_constraint)
- * (*m_alloc));
- if (!*c) {
- *m_alloc = *m = 0;
- free(tolcopy);
- return NLOPT_OUT_OF_MEMORY;
- }
- }
-
- (*c)[*m - 1].m = fm;
- (*c)[*m - 1].f = fc;
- (*c)[*m - 1].pre = pre;
- (*c)[*m - 1].mf = mfc;
- (*c)[*m - 1].f_data = fc_data;
- (*c)[*m - 1].tol = tolcopy;
- return NLOPT_SUCCESS;
-}
-
-static int inequality_ok(nlopt_algorithm algorithm) {
- /* nonlinear constraints are only supported with some algorithms */
- return (algorithm == NLOPT_LD_MMA || algorithm == NLOPT_LD_CCSAQ
- || algorithm == NLOPT_LD_SLSQP
- || algorithm == NLOPT_LN_COBYLA
- || AUGLAG_ALG(algorithm)
- || algorithm == NLOPT_GN_ISRES
- || algorithm == NLOPT_GN_ORIG_DIRECT
- || algorithm == NLOPT_GN_ORIG_DIRECT_L);
-}
-
-nlopt_result
-NLOPT_STDCALL nlopt_add_inequality_mconstraint(nlopt_opt opt, unsigned m,
- nlopt_mfunc fc, void *fc_data,
- const double *tol)
-{
- nlopt_result ret;
- if (!m) { /* empty constraints are always ok */
- if (opt && opt->munge_on_destroy) opt->munge_on_destroy(fc_data);
- return NLOPT_SUCCESS;
- }
- if (!opt || !inequality_ok(opt->algorithm)) ret = NLOPT_INVALID_ARGS;
- else ret = add_constraint(&opt->m, &opt->m_alloc, &opt->fc,
- m, NULL, fc, NULL, fc_data, tol);
- if (ret < 0 && opt && opt->munge_on_destroy)
- opt->munge_on_destroy(fc_data);
- return ret;
-}
-
-nlopt_result
-NLOPT_STDCALL nlopt_add_precond_inequality_constraint(nlopt_opt opt,
- nlopt_func fc,
- nlopt_precond pre,
- void *fc_data,
- double tol)
-{
- nlopt_result ret;
- if (!opt || !inequality_ok(opt->algorithm)) ret = NLOPT_INVALID_ARGS;
- else ret = add_constraint(&opt->m, &opt->m_alloc, &opt->fc,
- 1, fc, NULL, pre, fc_data, &tol);
- if (ret < 0 && opt && opt->munge_on_destroy)
- opt->munge_on_destroy(fc_data);
- return ret;
-}
-
-nlopt_result
-NLOPT_STDCALL nlopt_add_inequality_constraint(nlopt_opt opt,
- nlopt_func fc, void *fc_data,
- double tol)
-{
- return nlopt_add_precond_inequality_constraint(opt, fc, NULL, fc_data,
- tol);
-}
-
-nlopt_result
-NLOPT_STDCALL nlopt_remove_equality_constraints(nlopt_opt opt)
-{
- unsigned i;
- if (!opt) return NLOPT_INVALID_ARGS;
- if (opt->munge_on_destroy) {
- nlopt_munge munge = opt->munge_on_destroy;
- for (i = 0; i < opt->p; ++i)
- munge(opt->h[i].f_data);
- }
- for (i = 0; i < opt->p; ++i)
- free(opt->h[i].tol);
- free(opt->h);
- opt->h = NULL;
- opt->p = opt->p_alloc = 0;
- return NLOPT_SUCCESS;
-}
-
-static int equality_ok(nlopt_algorithm algorithm) {
- /* equality constraints (h(x) = 0) only via some algorithms */
- return (AUGLAG_ALG(algorithm)
- || algorithm == NLOPT_LD_SLSQP
- || algorithm == NLOPT_GN_ISRES
- || algorithm == NLOPT_LN_COBYLA);
-}
-
-nlopt_result
-NLOPT_STDCALL nlopt_add_equality_mconstraint(nlopt_opt opt, unsigned m,
- nlopt_mfunc fc, void *fc_data,
- const double *tol)
-{
- nlopt_result ret;
- if (!m) { /* empty constraints are always ok */
- if (opt && opt->munge_on_destroy) opt->munge_on_destroy(fc_data);
- return NLOPT_SUCCESS;
- }
- if (!opt || !equality_ok(opt->algorithm)
- || nlopt_count_constraints(opt->p, opt->h) + m > opt->n)
- ret = NLOPT_INVALID_ARGS;
- else ret = add_constraint(&opt->p, &opt->p_alloc, &opt->h,
- m, NULL, fc, NULL, fc_data, tol);
- if (ret < 0 && opt && opt->munge_on_destroy)
- opt->munge_on_destroy(fc_data);
- return ret;
-}
-
-nlopt_result
-NLOPT_STDCALL nlopt_add_precond_equality_constraint(nlopt_opt opt,
- nlopt_func fc,
- nlopt_precond pre,
- void *fc_data,
- double tol)
-{
- nlopt_result ret;
- if (!opt || !equality_ok(opt->algorithm)
- || nlopt_count_constraints(opt->p, opt->h) + 1 > opt->n)
- ret = NLOPT_INVALID_ARGS;
- else ret = add_constraint(&opt->p, &opt->p_alloc, &opt->h,
- 1, fc, NULL, pre, fc_data, &tol);
- if (ret < 0 && opt && opt->munge_on_destroy)
- opt->munge_on_destroy(fc_data);
- return ret;
-}
-
-nlopt_result
-NLOPT_STDCALL nlopt_add_equality_constraint(nlopt_opt opt,
- nlopt_func fc, void *fc_data,
- double tol)
-{
- return nlopt_add_precond_equality_constraint(opt, fc, NULL, fc_data, tol);
-}
-
-/*************************************************************************/
-
-#define SET(param, T, arg) \
- nlopt_result NLOPT_STDCALL nlopt_set_##param(nlopt_opt opt, T arg) \
- { \
- if (opt) { \
- opt->arg = arg; \
- return NLOPT_SUCCESS; \
- } \
- return NLOPT_INVALID_ARGS; \
- }
-
-
-#define GET(param, T, arg) T NLOPT_STDCALL \
- nlopt_get_##param(const nlopt_opt opt) { \
- return opt->arg; \
- }
-
-#define GETSET(param, T, arg) GET(param, T, arg) SET(param, T, arg)
-
-GETSET(stopval, double, stopval)
-
-GETSET(ftol_rel, double, ftol_rel)
-GETSET(ftol_abs, double, ftol_abs)
-GETSET(xtol_rel, double, xtol_rel)
-
-nlopt_result
-NLOPT_STDCALL nlopt_set_xtol_abs(nlopt_opt opt, const double *xtol_abs)
-{
- if (opt) {
- memcpy(opt->xtol_abs, xtol_abs, opt->n * sizeof(double));
- return NLOPT_SUCCESS;
- }
- return NLOPT_INVALID_ARGS;
-}
-
-nlopt_result
-NLOPT_STDCALL nlopt_set_xtol_abs1(nlopt_opt opt, double xtol_abs)
-{
- if (opt) {
- unsigned i;
- for (i = 0; i < opt->n; ++i)
- opt->xtol_abs[i] = xtol_abs;
- return NLOPT_SUCCESS;
- }
- return NLOPT_INVALID_ARGS;
-}
-
-nlopt_result
-NLOPT_STDCALL nlopt_get_xtol_abs(const nlopt_opt opt, double *xtol_abs)
-{
- memcpy(xtol_abs, opt->xtol_abs, opt->n * sizeof(double));
- return NLOPT_SUCCESS;
-}
-
-GETSET(maxeval, int, maxeval)
-
-GETSET(maxtime, double, maxtime)
-
-/*************************************************************************/
-
-nlopt_result
-NLOPT_STDCALL nlopt_set_force_stop(nlopt_opt opt, int force_stop)
-{
- if (opt) {
- opt->force_stop = force_stop;
- if (opt->force_stop_child)
- return nlopt_set_force_stop(opt->force_stop_child, force_stop);
- return NLOPT_SUCCESS;
- }
- return NLOPT_INVALID_ARGS;
-}
-
-GET(force_stop, int, force_stop)
-nlopt_result NLOPT_STDCALL nlopt_force_stop(nlopt_opt opt) {
- return nlopt_set_force_stop(opt, 1);
-}
-
-/*************************************************************************/
-
-GET(algorithm, nlopt_algorithm, algorithm)
-GET(dimension, unsigned, n)
-
-/*************************************************************************/
-
-nlopt_result
-NLOPT_STDCALL nlopt_set_local_optimizer(nlopt_opt opt,
- const nlopt_opt local_opt)
-{
- if (opt) {
- if (local_opt && local_opt->n != opt->n) return NLOPT_INVALID_ARGS;
- nlopt_destroy(opt->local_opt);
- opt->local_opt = nlopt_copy(local_opt);
- if (local_opt) {
- if (!opt->local_opt) return NLOPT_OUT_OF_MEMORY;
- nlopt_set_lower_bounds(opt->local_opt, opt->lb);
- nlopt_set_upper_bounds(opt->local_opt, opt->ub);
- nlopt_remove_inequality_constraints(opt->local_opt);
- nlopt_remove_equality_constraints(opt->local_opt);
- nlopt_set_min_objective(opt->local_opt, NULL, NULL);
- nlopt_set_munge(opt->local_opt, NULL, NULL);
- opt->local_opt->force_stop = 0;
- }
- return NLOPT_SUCCESS;
- }
- return NLOPT_INVALID_ARGS;
-}
-
-/*************************************************************************/
-
-GETSET(population, unsigned, stochastic_population)
-GETSET(vector_storage, unsigned, vector_storage)
-
-/*************************************************************************/
-
-nlopt_result NLOPT_STDCALL nlopt_set_initial_step1(nlopt_opt opt, double dx)
-{
- unsigned i;
- if (!opt || dx == 0) return NLOPT_INVALID_ARGS;
- if (!opt->dx && opt->n > 0) {
- opt->dx = (double *) malloc(sizeof(double) * (opt->n));
- if (!opt->dx) return NLOPT_OUT_OF_MEMORY;
- }
- for (i = 0; i < opt->n; ++i) opt->dx[i] = dx;
- return NLOPT_SUCCESS;
-}
-
-nlopt_result
-NLOPT_STDCALL nlopt_set_initial_step(nlopt_opt opt, const double *dx)
-{
- unsigned i;
- if (!opt) return NLOPT_INVALID_ARGS;
- if (!dx) {
- free(opt->dx); opt->dx = NULL;
- return NLOPT_SUCCESS;
- }
- for (i = 0; i < opt->n; ++i) if (dx[i] == 0) return NLOPT_INVALID_ARGS;
- if (!opt->dx && nlopt_set_initial_step1(opt, 1) == NLOPT_OUT_OF_MEMORY)
- return NLOPT_OUT_OF_MEMORY;
- memcpy(opt->dx, dx, sizeof(double) * (opt->n));
- return NLOPT_SUCCESS;
-}
-
-nlopt_result
-NLOPT_STDCALL nlopt_get_initial_step(const nlopt_opt opt, const double *x,
- double *dx)
-{
- if (!opt) return NLOPT_INVALID_ARGS;
- if (!opt->n) return NLOPT_SUCCESS;
- if (!opt->dx) {
- nlopt_opt o = (nlopt_opt) opt; /* discard const temporarily */
- nlopt_result ret = nlopt_set_default_initial_step(o, x);
- if (ret != NLOPT_SUCCESS) return ret;
- memcpy(dx, o->dx, sizeof(double) * (opt->n));
- free(o->dx); o->dx = NULL; /* don't save, since x-dependent */
- }
- else
- memcpy(dx, opt->dx, sizeof(double) * (opt->n));
- return NLOPT_SUCCESS;
-}
-
-nlopt_result
-NLOPT_STDCALL nlopt_set_default_initial_step(nlopt_opt opt, const double *x)
-{
- const double *lb, *ub;
- unsigned i;
-
- if (!opt || !x) return NLOPT_INVALID_ARGS;
- lb = opt->lb; ub = opt->ub;
-
- if (!opt->dx && nlopt_set_initial_step1(opt, 1) == NLOPT_OUT_OF_MEMORY)
- return NLOPT_OUT_OF_MEMORY;
-
- /* crude heuristics for initial step size of nonderivative algorithms */
- for (i = 0; i < opt->n; ++i) {
- double step = HUGE_VAL;
-
- if (!nlopt_isinf(ub[i]) && !nlopt_isinf(lb[i])
- && (ub[i] - lb[i]) * 0.25 < step && ub[i] > lb[i])
- step = (ub[i] - lb[i]) * 0.25;
- if (!nlopt_isinf(ub[i])
- && ub[i] - x[i] < step && ub[i] > x[i])
- step = (ub[i] - x[i]) * 0.75;
- if (!nlopt_isinf(lb[i])
- && x[i] - lb[i] < step && x[i] > lb[i])
- step = (x[i] - lb[i]) * 0.75;
-
- if (nlopt_isinf(step)) {
- if (!nlopt_isinf(ub[i])
- && fabs(ub[i] - x[i]) < fabs(step))
- step = (ub[i] - x[i]) * 1.1;
- if (!nlopt_isinf(lb[i])
- && fabs(x[i] - lb[i]) < fabs(step))
- step = (x[i] - lb[i]) * 1.1;
- }
- if (nlopt_isinf(step) || step == 0) {
- step = x[i];
- }
- if (nlopt_isinf(step) || step == 0)
- step = 1;
-
- opt->dx[i] = step;
- }
- return NLOPT_SUCCESS;
-}
-
-/*************************************************************************/
-
-void NLOPT_STDCALL nlopt_set_munge(nlopt_opt opt,
- nlopt_munge munge_on_destroy,
- nlopt_munge munge_on_copy) {
- if (opt) {
- opt->munge_on_destroy = munge_on_destroy;
- opt->munge_on_copy = munge_on_copy;
- }
-}
-
-void NLOPT_STDCALL nlopt_munge_data(nlopt_opt opt,
- nlopt_munge2 munge, void *data) {
- if (opt && munge) {
- unsigned i;
- opt->f_data = munge(opt->f_data, data);
- for (i = 0; i < opt->m; ++i)
- opt->fc[i].f_data = munge(opt->fc[i].f_data, data);
- for (i = 0; i < opt->p; ++i)
- opt->h[i].f_data = munge(opt->h[i].f_data, data);
- }
-}
-
-/*************************************************************************/
diff --git a/ext/src/nlopt/auglag/README b/ext/src/nlopt/auglag/README
deleted file mode 100644
index e1f8c2f..0000000
--- a/ext/src/nlopt/auglag/README
+++ /dev/null
@@ -1,25 +0,0 @@
-This directory contains my implementation of the "augmented Lagrangian"
-method to express constrained optimization problems (including equality
-constraints) in terms of unconstrained optimization problems (or just
-inequality constraints, or just box constraints).
-
-I used the algorithm description (but no source code) from the outline
-in the paper:
-
- E. G. Birgin and J. M. Martinez, "Improving ultimate convergence
- of an augmented Lagrangian method," Optimization Methods and
- Software vol. 23, no. 2, p. 177-195 (2008).
-
- http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.72.6121
-
-(The authors of this paper have their own free-software implementation
-of this idea and its variations, in the TANGO project:
-http://www.ime.usp.br/~egbirgin/tango/ ....I did *not* use any code
-from TANGO here, or even look at the TANGO code. TANGO is GPLed, and
-I'm trying to keep NLopt at most LGPLed.)
-
-The code in this directory is under the same MIT license as the rest
-of my code in NLopt (see ../COPYRIGHT).
-
-Steven G. Johnson
-November 2008
diff --git a/ext/src/nlopt/auglag/auglag.c b/ext/src/nlopt/auglag/auglag.c
deleted file mode 100644
index 53555c8..0000000
--- a/ext/src/nlopt/auglag/auglag.c
+++ /dev/null
@@ -1,289 +0,0 @@
-#include <stdlib.h>
-#include <math.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "nlopt/auglag.h"
-
-int auglag_verbose = 0;
-
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-#define MAX(a,b) ((a) > (b) ? (a) : (b))
-
-/***************************************************************************/
-
-typedef struct {
- nlopt_func f; void *f_data;
- int m, mm; nlopt_constraint *fc;
- int p, pp; nlopt_constraint *h;
- double rho, *lambda, *mu;
- double *restmp, *gradtmp;
- nlopt_stopping *stop;
-} auglag_data;
-
-/* the augmented lagrangian objective function */
-static double auglag(unsigned n, const double *x, double *grad, void *data)
-{
- auglag_data *d = (auglag_data *) data;
- double *gradtmp = grad ? d->gradtmp : NULL;
- double *restmp = d->restmp;
- double rho = d->rho;
- const double *lambda = d->lambda, *mu = d->mu;
- double L;
- int i, ii;
- unsigned j, k;
-
- L = d->f(n, x, grad, d->f_data);
- d->stop->nevals++;
- if (nlopt_stop_forced(d->stop)) return L;
-
- for (ii = i = 0; i < d->p; ++i) {
- nlopt_eval_constraint(restmp, gradtmp, d->h + i, n, x);
- if (nlopt_stop_forced(d->stop)) return L;
- for (k = 0; k < d->h[i].m; ++k) {
- double h = restmp[k] + lambda[ii++] / rho;
- L += 0.5 * rho * h*h;
- if (grad) for (j = 0; j < n; ++j)
- grad[j] += (rho * h) * gradtmp[k*n + j];
- }
- }
-
- for (ii = i = 0; i < d->m; ++i) {
- nlopt_eval_constraint(restmp, gradtmp, d->fc + i, n, x);
- if (nlopt_stop_forced(d->stop)) return L;
- for (k = 0; k < d->fc[i].m; ++k) {
- double fc = restmp[k] + mu[ii++] / rho;
- if (fc > 0) {
- L += 0.5 * rho * fc*fc;
- if (grad) for (j = 0; j < n; ++j)
- grad[j] += (rho * fc) * gradtmp[k*n + j];
- }
- }
- }
-
- return L;
-}
-
-/***************************************************************************/
-
-nlopt_result auglag_minimize(int n, nlopt_func f, void *f_data,
- int m, nlopt_constraint *fc,
- int p, nlopt_constraint *h,
- const double *lb, const double *ub, /* bounds */
- double *x, /* in: initial guess, out: minimizer */
- double *minf,
- nlopt_stopping *stop,
- nlopt_opt sub_opt, int sub_has_fc)
-{
- auglag_data d;
- nlopt_result ret = NLOPT_SUCCESS;
- double ICM = HUGE_VAL, minf_penalty = HUGE_VAL, penalty;
- double *xcur = NULL, fcur;
- int i, ii, k, feasible, minf_feasible = 0;
- int auglag_iters = 0;
- int max_constraint_dim;
-
- /* magic parameters from Birgin & Martinez */
- const double tau = 0.5, gam = 10;
- const double lam_min = -1e20, lam_max = 1e20, mu_max = 1e20;
-
- d.f = f; d.f_data = f_data;
- d.m = m; d.fc = fc;
- d.p = p; d.h = h;
- d.stop = stop;
-
- /* whether we handle inequality constraints via the augmented
- Lagrangian penalty function, or directly in the sub-algorithm */
- if (sub_has_fc)
- d.m = 0;
- else
- m = 0;
-
- max_constraint_dim = MAX(nlopt_max_constraint_dim(d.m, fc),
- nlopt_max_constraint_dim(d.p, h));
-
- d.mm = nlopt_count_constraints(d.m, fc);
- d.pp = nlopt_count_constraints(d.p, h);
-
- ret = nlopt_set_min_objective(sub_opt, auglag, &d); if (ret<0) return ret;
- ret = nlopt_set_lower_bounds(sub_opt, lb); if (ret<0) return ret;
- ret = nlopt_set_upper_bounds(sub_opt, ub); if (ret<0) return ret;
- ret = nlopt_set_stopval(sub_opt,
- d.m==0 && d.p==0 ? stop->minf_max : -HUGE_VAL);
- if (ret<0) return ret;
- ret = nlopt_remove_inequality_constraints(sub_opt); if (ret<0) return ret;
- ret = nlopt_remove_equality_constraints(sub_opt); if (ret<0) return ret;
- for (i = 0; i < m; ++i) {
- if (fc[i].f)
- ret = nlopt_add_inequality_constraint(sub_opt,
- fc[i].f, fc[i].f_data,
- fc[i].tol[0]);
- else
- ret = nlopt_add_inequality_mconstraint(sub_opt, fc[i].m,
- fc[i].mf, fc[i].f_data,
- fc[i].tol);
- if (ret < 0) return ret;
- }
-
- xcur = (double *) malloc(sizeof(double) * (n
- + max_constraint_dim * (1 + n)
- + d.pp + d.mm));
- if (!xcur) return NLOPT_OUT_OF_MEMORY;
- memcpy(xcur, x, sizeof(double) * n);
-
- d.restmp = xcur + n;
- d.gradtmp = d.restmp + max_constraint_dim;
- memset(d.gradtmp, 0, sizeof(double) * (n*max_constraint_dim + d.pp+d.mm));
- d.lambda = d.gradtmp + n * max_constraint_dim;
- d.mu = d.lambda + d.pp;
-
- *minf = HUGE_VAL;
-
- /* starting rho suggested by B & M */
- if (d.p > 0 || d.m > 0) {
- double con2 = 0;
- d.stop->nevals++;
- fcur = f(n, xcur, NULL, f_data);
- if (nlopt_stop_forced(stop)) {
- ret = NLOPT_FORCED_STOP; goto done; }
- penalty = 0;
- feasible = 1;
- for (i = 0; i < d.p; ++i) {
- nlopt_eval_constraint(d.restmp, NULL, d.h + i, n, xcur);
- if (nlopt_stop_forced(stop)) {
- ret = NLOPT_FORCED_STOP; goto done; }
- for (k = 0; k < d.h[i].m; ++k) {
- double hi = d.restmp[k];
- penalty += fabs(hi);
- feasible = feasible && fabs(hi) <= h[i].tol[k];
- con2 += hi * hi;
- }
- }
- for (i = 0; i < d.m; ++i) {
- nlopt_eval_constraint(d.restmp, NULL, d.fc + i, n, xcur);
- if (nlopt_stop_forced(stop)) {
- ret = NLOPT_FORCED_STOP; goto done; }
- for (k = 0; k < d.fc[i].m; ++k) {
- double fci = d.restmp[k];
- penalty += fci > 0 ? fci : 0;
- feasible = feasible && fci <= fc[i].tol[k];
- if (fci > 0) con2 += fci * fci;
- }
- }
- *minf = fcur;
- minf_penalty = penalty;
- minf_feasible = feasible;
- d.rho = MAX(1e-6, MIN(10, 2 * fabs(*minf) / con2));
- }
- else
- d.rho = 1; /* whatever, doesn't matter */
-
- if (auglag_verbose) {
- printf("auglag: initial rho=%g\nauglag initial lambda=", d.rho);
- for (i = 0; i < d.pp; ++i) printf(" %g", d.lambda[i]);
- printf("\nauglag initial mu = ");
- for (i = 0; i < d.mm; ++i) printf(" %g", d.mu[i]);
- printf("\n");
- }
-
- do {
- double prev_ICM = ICM;
-
- ret = nlopt_optimize_limited(sub_opt, xcur, &fcur,
- stop->maxeval - stop->nevals,
- stop->maxtime - (nlopt_seconds()
- - stop->start));
- if (auglag_verbose)
- printf("auglag: subopt return code %d\n", ret);
- if (ret < 0) break;
-
- d.stop->nevals++;
- fcur = f(n, xcur, NULL, f_data);
- if (nlopt_stop_forced(stop)) {
- ret = NLOPT_FORCED_STOP; goto done; }
- if (auglag_verbose)
- printf("auglag: fcur = %g\n", fcur);
-
- ICM = 0;
- penalty = 0;
- feasible = 1;
- for (i = ii = 0; i < d.p; ++i) {
- nlopt_eval_constraint(d.restmp, NULL, d.h + i, n, xcur);
- if (nlopt_stop_forced(stop)) {
- ret = NLOPT_FORCED_STOP; goto done; }
- for (k = 0; k < d.h[i].m; ++k) {
- double hi = d.restmp[k];
- double newlam = d.lambda[ii] + d.rho * hi;
- penalty += fabs(hi);
- feasible = feasible && fabs(hi) <= h[i].tol[k];
- ICM = MAX(ICM, fabs(hi));
- d.lambda[ii++] = MIN(MAX(lam_min, newlam), lam_max);
- }
- }
- for (i = ii = 0; i < d.m; ++i) {
- nlopt_eval_constraint(d.restmp, NULL, d.fc + i, n, xcur);
- if (nlopt_stop_forced(stop)) {
- ret = NLOPT_FORCED_STOP; goto done; }
- for (k = 0; k < d.fc[i].m; ++k) {
- double fci = d.restmp[k];
- double newmu = d.mu[ii] + d.rho * fci;
- penalty += fci > 0 ? fci : 0;
- feasible = feasible && fci <= fc[i].tol[k];
- ICM = MAX(ICM, fabs(MAX(fci, -d.mu[ii] / d.rho)));
- d.mu[ii++] = MIN(MAX(0.0, newmu), mu_max);
- }
- }
- if (ICM > tau * prev_ICM) {
- d.rho *= gam;
- }
-
- auglag_iters++;
-
- if (auglag_verbose) {
- printf("auglag %d: ICM=%g (%sfeasible), rho=%g\nauglag lambda=",
- auglag_iters, ICM, feasible ? "" : "not ", d.rho);
- for (i = 0; i < d.pp; ++i) printf(" %g", d.lambda[i]);
- printf("\nauglag %d: mu = ", auglag_iters);
- for (i = 0; i < d.mm; ++i) printf(" %g", d.mu[i]);
- printf("\n");
- }
-
- if ((feasible && (!minf_feasible || penalty < minf_penalty
- || fcur < *minf)) ||
- (!minf_feasible && penalty < minf_penalty)) {
- ret = NLOPT_SUCCESS;
- if (feasible) {
- if (fcur < stop->minf_max)
- ret = NLOPT_MINF_MAX_REACHED;
- else if (nlopt_stop_ftol(stop, fcur, *minf))
- ret = NLOPT_FTOL_REACHED;
- else if (nlopt_stop_x(stop, xcur, x))
- ret = NLOPT_XTOL_REACHED;
- }
- *minf = fcur;
- minf_penalty = penalty;
- minf_feasible = feasible;
- memcpy(x, xcur, sizeof(double) * n);
- if (ret != NLOPT_SUCCESS) break;
- }
-
- if (nlopt_stop_forced(stop)) {ret = NLOPT_FORCED_STOP; break;}
- if (nlopt_stop_evals(stop)) {ret = NLOPT_MAXEVAL_REACHED; break;}
- if (nlopt_stop_time(stop)) {ret = NLOPT_MAXTIME_REACHED; break;}
-
- /* TODO: use some other stopping criterion on ICM? */
- /* The paper uses ICM <= epsilon and DFM <= epsilon, where
- DFM is a measure of the size of the Lagrangian gradient.
- Besides the fact that these kinds of absolute tolerances
- (non-scale-invariant) are unsatisfying and it is not
- clear how the user should specify it, the ICM <= epsilon
- condition seems not too different from requiring feasibility,
- especially now that the user can provide constraint-specific
- tolerances analogous to epsilon. */
- if (ICM == 0) return NLOPT_FTOL_REACHED;
- } while (1);
-
-done:
- free(xcur);
- return ret;
-}
diff --git a/ext/src/nlopt/bobyqa/COPYRIGHT b/ext/src/nlopt/bobyqa/COPYRIGHT
deleted file mode 100644
index ef653d4..0000000
--- a/ext/src/nlopt/bobyqa/COPYRIGHT
+++ /dev/null
@@ -1,23 +0,0 @@
-/* Copyright (c) 2009 M. J. D. Powell (mjdp at cam.ac.uk)
- * Modifications Copyright (c) 2010 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
diff --git a/ext/src/nlopt/bobyqa/README b/ext/src/nlopt/bobyqa/README
deleted file mode 100644
index c87ce61..0000000
--- a/ext/src/nlopt/bobyqa/README
+++ /dev/null
@@ -1,20 +0,0 @@
-This is the BOBYQA software by M. J. D. Powell, which performs
-derivative-free unconstrained optimization using an iteratively
-constructred quadratic approximation for the objective function. See:
-
- M. J. D. Powell, "The BOBYQA algorithm for bound constrained
- optimization without derivatives," Department of Applied
- Mathematics and Theoretical Physics, Cambridge England,
- technical report NA2009/06 (2009).
-
- http://www.damtp.cam.ac.uk/user/na/NA_papers/NA2009_06.pdf
- http://plato.asu.edu/ftp/other_software/bobyqa.zip
-
-The C translation by S. G. Johnson (2009) includes a few minor
-modifications, mainly to use the NLopt stopping criteria (and to
-take the objective function as an argument rather than a global).
-
-The original Fortran code was released by Powell with "no restrictions
-or charges", and the C translation by S. G. Johnson is released in a
-similar spirit under the MIT License (see the COPYRIGHT file in this
-directory).
diff --git a/ext/src/nlopt/bobyqa/README.orig b/ext/src/nlopt/bobyqa/README.orig
deleted file mode 100644
index 8a81d98..0000000
--- a/ext/src/nlopt/bobyqa/README.orig
+++ /dev/null
@@ -1,60 +0,0 @@
-===========================================================================
-On 8/13/09 added the paper on BOBYQA
-===========================================================================
-
-For simplicity, the Makefi;e has been replaced by a one-line compile
-script "comp" which needs to be adjusted if the compiler name is not
-f77. All Fortran files are in bobyla.f. Compiling and running bobyqa
-should produce results similar to those in RESULTS.
- Hans Mittelmann, Jan 2009
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- The Fortran version of BOBYQA is attached. Its purpose is to seek
-the least value of a function F of several variables, when derivatives
-are not available, where F is specified by the user through a subroutine
-called CALFUN. The name BOBYQA denotes Bound Approximation BY Quadratic
-Approximation, the constraints being lower and upper bounds on every
-variable, which can be set to huge values for unconstrained variables.
-The algorithm is intended to change the variables to values that are close
-to a local minimum of F. The user, however, should assume responsibility for
-finding out if the calculations are satisfactory, by considering carefully
-the values of F that occur. The BOBYQA software has been developed from the
-method of the paper "The NEWUOA software for unconstrained minimization
-without derivatives", in Large-Scale Nonlinear Optimization, editors G. Di
-Pillo and M. Roma, Springer (2006), pages 255-297. A report that describes
-the details of the development is going to be written soon.
-
- The attachments in sequence are a suitable Makefile, followed by a main
-program and a CALFUN routine for the "Invdist2" problem, in order to provide
-an example for testing. Then BOBYQA and its six auxiliary routines, namely
-BOBYQB, ALTMOV, PRELIM, RESCUE, TRSBOX and UPDATE, are given. Finally, the
-computed output that the author obtained for the Invdist2 problems is listed.
-
- In addition to providing CALFUN, an initial vector of variables and
-the lower and upper bounds, the user has to set the values of the parameters
-RHOBEG, RHOEND and NPT. After scaling the individual variables if necessary,
-so that the magnitudes of their expected changes are similar, RHOBEG is the
-initial steplength for changes to the variables, a reasonable choice being
-the mesh size of a coarse grid search. Further, RHOEND should be suitable for
-a search on a very fine grid. Typically, the software calculates a vector
-of variables that is within distance 10*RHOEND of a local minimum. Another
-consideration is that every trial vector of variables is forced to satisfy
-the lower and upper bounds, but there has to be room to make a search in all
-directions. Therefore an error return occurs if the difference between the
-bounds on any variable is less than 2*RHOBEG. The parameter NPT specifies
-the number of interpolation conditions on each quadratic model, the value
-NPT=2*N+1 being recommended for a start, where N is the number of variables.
-It is often worthwhile to try other choices too, but much larger values tend
-to be inefficient, because the amount of routine work of each iteration is
-of magnitude NPT**2, and because the achievement of adequate accuracy in some
-matrix calculations becomes more difficult. Some excellent numerical results
-have been found in the case NPT=N+6 even with more than 100 variables.
-
- The way of calling BOBYQA should be clear from the Invdist2 examples
-and from the comments near the beginning of SUBROUTINE BOBYQA. There are no
-restrictions on or charges for the use of the software. I hope that the time
-and effort I have spent on developing the package will be helpful to much
-research and to many applications.
-
-January 5th, 2009 M.J.D. Powell (mjdp at cam.ac.uk)
-
diff --git a/ext/src/nlopt/bobyqa/bobyqa.c b/ext/src/nlopt/bobyqa/bobyqa.c
deleted file mode 100644
index b325feb..0000000
--- a/ext/src/nlopt/bobyqa/bobyqa.c
+++ /dev/null
@@ -1,3269 +0,0 @@
-/* BOBYQA derivative-free optimization code by M. J. D. Powell.
- Original Fortran code by Powell (2009). Converted via v2c,
- cleaned up, and incorporated into NLopt by S. G. Johnson (2009).
- See README. */
-
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "nlopt/bobyqa.h"
-
-typedef double (*bobyqa_func)(int n, const double *x, void *func_data);
-
-#define MIN2(a,b) ((a) <= (b) ? (a) : (b))
-#define MAX2(a,b) ((a) >= (b) ? (a) : (b))
-#define IABS(x) ((x) < 0 ? -(x) : (x))
-
-static void update_(int *n, int *npt, double *bmat,
- double *zmat, int *ndim, double *vlag, double *beta,
- double *denom, int *knew, double *w)
-{
- /* System generated locals */
- int bmat_dim1, bmat_offset, zmat_dim1, zmat_offset, i__1, i__2;
- double d__1, d__2, d__3;
-
- /* Local variables */
- int i__, j, k, jl, jp;
- double one, tau, temp;
- int nptm;
- double zero, alpha, tempa, tempb, ztest;
-
-
-/* The arrays BMAT and ZMAT are updated, as required by the new position */
-/* of the interpolation point that has the index KNEW. The vector VLAG has */
-/* N+NPT components, set on entry to the first NPT and last N components */
-/* of the product Hw in equation (4.11) of the Powell (2006) paper on */
-/* NEWUOA. Further, BETA is set on entry to the value of the parameter */
-/* with that name, and DENOM is set to the denominator of the updating */
-/* formula. Elements of ZMAT may be treated as zero if their moduli are */
-/* at most ZTEST. The first NDIM elements of W are used for working space. */
-
-/* Set some constants. */
-
- /* Parameter adjustments */
- zmat_dim1 = *npt;
- zmat_offset = 1 + zmat_dim1;
- zmat -= zmat_offset;
- bmat_dim1 = *ndim;
- bmat_offset = 1 + bmat_dim1;
- bmat -= bmat_offset;
- --vlag;
- --w;
-
- /* Function Body */
- one = 1.;
- zero = 0.;
- nptm = *npt - *n - 1;
- ztest = zero;
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
- i__2 = nptm;
- for (j = 1; j <= i__2; ++j) {
-/* L10: */
-/* Computing MAX */
- d__2 = ztest, d__3 = (d__1 = zmat[k + j * zmat_dim1], fabs(d__1));
- ztest = MAX2(d__2,d__3);
- }
- }
- ztest *= 1e-20;
-
-/* Apply the rotations that put zeros in the KNEW-th row of ZMAT. */
-
- jl = 1;
- i__2 = nptm;
- for (j = 2; j <= i__2; ++j) {
- if ((d__1 = zmat[*knew + j * zmat_dim1], fabs(d__1)) > ztest) {
-/* Computing 2nd power */
- d__1 = zmat[*knew + zmat_dim1];
-/* Computing 2nd power */
- d__2 = zmat[*knew + j * zmat_dim1];
- temp = sqrt(d__1 * d__1 + d__2 * d__2);
- tempa = zmat[*knew + zmat_dim1] / temp;
- tempb = zmat[*knew + j * zmat_dim1] / temp;
- i__1 = *npt;
- for (i__ = 1; i__ <= i__1; ++i__) {
- temp = tempa * zmat[i__ + zmat_dim1] + tempb * zmat[i__ + j *
- zmat_dim1];
- zmat[i__ + j * zmat_dim1] = tempa * zmat[i__ + j * zmat_dim1]
- - tempb * zmat[i__ + zmat_dim1];
-/* L20: */
- zmat[i__ + zmat_dim1] = temp;
- }
- }
- zmat[*knew + j * zmat_dim1] = zero;
-/* L30: */
- }
-
-/* Put the first NPT components of the KNEW-th column of HLAG into W, */
-/* and calculate the parameters of the updating formula. */
-
- i__2 = *npt;
- for (i__ = 1; i__ <= i__2; ++i__) {
- w[i__] = zmat[*knew + zmat_dim1] * zmat[i__ + zmat_dim1];
-/* L40: */
- }
- alpha = w[*knew];
- tau = vlag[*knew];
- vlag[*knew] -= one;
-
-/* Complete the updating of ZMAT. */
-
- temp = sqrt(*denom);
- tempb = zmat[*knew + zmat_dim1] / temp;
- tempa = tau / temp;
- i__2 = *npt;
- for (i__ = 1; i__ <= i__2; ++i__) {
-/* L50: */
- zmat[i__ + zmat_dim1] = tempa * zmat[i__ + zmat_dim1] - tempb * vlag[
- i__];
- }
-
-/* Finally, update the matrix BMAT. */
-
- i__2 = *n;
- for (j = 1; j <= i__2; ++j) {
- jp = *npt + j;
- w[jp] = bmat[*knew + j * bmat_dim1];
- tempa = (alpha * vlag[jp] - tau * w[jp]) / *denom;
- tempb = (-(*beta) * w[jp] - tau * vlag[jp]) / *denom;
- i__1 = jp;
- for (i__ = 1; i__ <= i__1; ++i__) {
- bmat[i__ + j * bmat_dim1] = bmat[i__ + j * bmat_dim1] + tempa *
- vlag[i__] + tempb * w[i__];
- if (i__ > *npt) {
- bmat[jp + (i__ - *npt) * bmat_dim1] = bmat[i__ + j *
- bmat_dim1];
- }
-/* L60: */
- }
- }
-} /* update_ */
-
-static nlopt_result rescue_(int *n, int *npt, const double *xl, const double *xu,
- /* int *maxfun */
- nlopt_stopping *stop,
- bobyqa_func calfun, void *calfun_data,
- double *xbase, double *xpt, double *fval, double *xopt, double *gopt,
- double *hq, double *pq, double *bmat, double *zmat,
- int *ndim, double *sl, double *su, /* int *nf, */
- double *delta, int *kopt, double *vlag, double *
- ptsaux, double *ptsid, double *w)
-{
- /* System generated locals */
- int xpt_dim1, xpt_offset, bmat_dim1, bmat_offset, zmat_dim1,
- zmat_offset, i__1, i__2, i__3;
- double d__1, d__2, d__3, d__4;
-
- /* Local variables */
- double f;
- int i__, j, k, ih, jp, ip, iq, np, iw;
- double xp, xq, den;
- int ihp;
- double one;
- int ihq, jpn, kpt;
- double sum, diff, half, beta;
- int kold;
- double winc;
- int nrem, knew;
- double temp, bsum;
- int nptm;
- double zero, hdiag, fbase, sfrac, denom, vquad, sumpq;
- double dsqmin, distsq, vlmxsq;
-
-
-/* The arguments N, NPT, XL, XU, MAXFUN, XBASE, XPT, FVAL, XOPT, */
-/* GOPT, HQ, PQ, BMAT, ZMAT, NDIM, SL and SU have the same meanings as */
-/* the corresponding arguments of BOBYQB on the entry to RESCUE. */
-/* NF is maintained as the number of calls of CALFUN so far, except that */
-/* NF is set to -1 if the value of MAXFUN prevents further progress. */
-/* KOPT is maintained so that FVAL(KOPT) is the least calculated function */
-/* value. Its correct value must be given on entry. It is updated if a */
-/* new least function value is found, but the corresponding changes to */
-/* XOPT and GOPT have to be made later by the calling program. */
-/* DELTA is the current trust region radius. */
-/* VLAG is a working space vector that will be used for the values of the */
-/* provisional Lagrange functions at each of the interpolation points. */
-/* They are part of a product that requires VLAG to be of length NDIM. */
-/* PTSAUX is also a working space array. For J=1,2,...,N, PTSAUX(1,J) and */
-/* PTSAUX(2,J) specify the two positions of provisional interpolation */
-/* points when a nonzero step is taken along e_J (the J-th coordinate */
-/* direction) through XBASE+XOPT, as specified below. Usually these */
-/* steps have length DELTA, but other lengths are chosen if necessary */
-/* in order to satisfy the given bounds on the variables. */
-/* PTSID is also a working space array. It has NPT components that denote */
-/* provisional new positions of the original interpolation points, in */
-/* case changes are needed to restore the linear independence of the */
-/* interpolation conditions. The K-th point is a candidate for change */
-/* if and only if PTSID(K) is nonzero. In this case let p and q be the */
-/* int parts of PTSID(K) and (PTSID(K)-p) multiplied by N+1. If p */
-/* and q are both positive, the step from XBASE+XOPT to the new K-th */
-/* interpolation point is PTSAUX(1,p)*e_p + PTSAUX(1,q)*e_q. Otherwise */
-/* the step is PTSAUX(1,p)*e_p or PTSAUX(2,q)*e_q in the cases q=0 or */
-/* p=0, respectively. */
-/* The first NDIM+NPT elements of the array W are used for working space. */
-/* The final elements of BMAT and ZMAT are set in a well-conditioned way */
-/* to the values that are appropriate for the new interpolation points. */
-/* The elements of GOPT, HQ and PQ are also revised to the values that are */
-/* appropriate to the final quadratic model. */
-
-/* Set some constants. */
-
- /* Parameter adjustments */
- zmat_dim1 = *npt;
- zmat_offset = 1 + zmat_dim1;
- zmat -= zmat_offset;
- xpt_dim1 = *npt;
- xpt_offset = 1 + xpt_dim1;
- xpt -= xpt_offset;
- --xl;
- --xu;
- --xbase;
- --fval;
- --xopt;
- --gopt;
- --hq;
- --pq;
- bmat_dim1 = *ndim;
- bmat_offset = 1 + bmat_dim1;
- bmat -= bmat_offset;
- --sl;
- --su;
- --vlag;
- ptsaux -= 3;
- --ptsid;
- --w;
-
- /* Function Body */
- half = .5;
- one = 1.;
- zero = 0.;
- np = *n + 1;
- sfrac = half / (double) np;
- nptm = *npt - np;
-
-/* Shift the interpolation points so that XOPT becomes the origin, and set */
-/* the elements of ZMAT to zero. The value of SUMPQ is required in the */
-/* updating of HQ below. The squares of the distances from XOPT to the */
-/* other interpolation points are set at the end of W. Increments of WINC */
-/* may be added later to these squares to balance the consideration of */
-/* the choice of point that is going to become current. */
-
- sumpq = zero;
- winc = zero;
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
- distsq = zero;
- i__2 = *n;
- for (j = 1; j <= i__2; ++j) {
- xpt[k + j * xpt_dim1] -= xopt[j];
-/* L10: */
-/* Computing 2nd power */
- d__1 = xpt[k + j * xpt_dim1];
- distsq += d__1 * d__1;
- }
- sumpq += pq[k];
- w[*ndim + k] = distsq;
- winc = MAX2(winc,distsq);
- i__2 = nptm;
- for (j = 1; j <= i__2; ++j) {
-/* L20: */
- zmat[k + j * zmat_dim1] = zero;
- }
- }
-
-/* Update HQ so that HQ and PQ define the second derivatives of the model */
-/* after XBASE has been shifted to the trust region centre. */
-
- ih = 0;
- i__2 = *n;
- for (j = 1; j <= i__2; ++j) {
- w[j] = half * sumpq * xopt[j];
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
-/* L30: */
- w[j] += pq[k] * xpt[k + j * xpt_dim1];
- }
- i__1 = j;
- for (i__ = 1; i__ <= i__1; ++i__) {
- ++ih;
-/* L40: */
- hq[ih] = hq[ih] + w[i__] * xopt[j] + w[j] * xopt[i__];
- }
- }
-
-/* Shift XBASE, SL, SU and XOPT. Set the elements of BMAT to zero, and */
-/* also set the elements of PTSAUX. */
-
- i__1 = *n;
- for (j = 1; j <= i__1; ++j) {
- xbase[j] += xopt[j];
- sl[j] -= xopt[j];
- su[j] -= xopt[j];
- xopt[j] = zero;
-/* Computing MIN */
- d__1 = *delta, d__2 = su[j];
- ptsaux[(j << 1) + 1] = MIN2(d__1,d__2);
-/* Computing MAX */
- d__1 = -(*delta), d__2 = sl[j];
- ptsaux[(j << 1) + 2] = MAX2(d__1,d__2);
- if (ptsaux[(j << 1) + 1] + ptsaux[(j << 1) + 2] < zero) {
- temp = ptsaux[(j << 1) + 1];
- ptsaux[(j << 1) + 1] = ptsaux[(j << 1) + 2];
- ptsaux[(j << 1) + 2] = temp;
- }
- if ((d__2 = ptsaux[(j << 1) + 2], fabs(d__2)) < half * (d__1 = ptsaux[(
- j << 1) + 1], fabs(d__1))) {
- ptsaux[(j << 1) + 2] = half * ptsaux[(j << 1) + 1];
- }
- i__2 = *ndim;
- for (i__ = 1; i__ <= i__2; ++i__) {
-/* L50: */
- bmat[i__ + j * bmat_dim1] = zero;
- }
- }
- fbase = fval[*kopt];
-
-/* Set the identifiers of the artificial interpolation points that are */
-/* along a coordinate direction from XOPT, and set the corresponding */
-/* nonzero elements of BMAT and ZMAT. */
-
- ptsid[1] = sfrac;
- i__2 = *n;
- for (j = 1; j <= i__2; ++j) {
- jp = j + 1;
- jpn = jp + *n;
- ptsid[jp] = (double) j + sfrac;
- if (jpn <= *npt) {
- ptsid[jpn] = (double) j / (double) np + sfrac;
- temp = one / (ptsaux[(j << 1) + 1] - ptsaux[(j << 1) + 2]);
- bmat[jp + j * bmat_dim1] = -temp + one / ptsaux[(j << 1) + 1];
- bmat[jpn + j * bmat_dim1] = temp + one / ptsaux[(j << 1) + 2];
- bmat[j * bmat_dim1 + 1] = -bmat[jp + j * bmat_dim1] - bmat[jpn +
- j * bmat_dim1];
- zmat[j * zmat_dim1 + 1] = sqrt(2.) / (d__1 = ptsaux[(j << 1) + 1]
- * ptsaux[(j << 1) + 2], fabs(d__1));
- zmat[jp + j * zmat_dim1] = zmat[j * zmat_dim1 + 1] * ptsaux[(j <<
- 1) + 2] * temp;
- zmat[jpn + j * zmat_dim1] = -zmat[j * zmat_dim1 + 1] * ptsaux[(j
- << 1) + 1] * temp;
- } else {
- bmat[j * bmat_dim1 + 1] = -one / ptsaux[(j << 1) + 1];
- bmat[jp + j * bmat_dim1] = one / ptsaux[(j << 1) + 1];
-/* Computing 2nd power */
- d__1 = ptsaux[(j << 1) + 1];
- bmat[j + *npt + j * bmat_dim1] = -half * (d__1 * d__1);
- }
-/* L60: */
- }
-
-/* Set any remaining identifiers with their nonzero elements of ZMAT. */
-
- if (*npt >= *n + np) {
- i__2 = *npt;
- for (k = np << 1; k <= i__2; ++k) {
- iw = (int) (((double) (k - np) - half) / (double) (*n)
- );
- ip = k - np - iw * *n;
- iq = ip + iw;
- if (iq > *n) {
- iq -= *n;
- }
- ptsid[k] = (double) ip + (double) iq / (double) np +
- sfrac;
- temp = one / (ptsaux[(ip << 1) + 1] * ptsaux[(iq << 1) + 1]);
- zmat[(k - np) * zmat_dim1 + 1] = temp;
- zmat[ip + 1 + (k - np) * zmat_dim1] = -temp;
- zmat[iq + 1 + (k - np) * zmat_dim1] = -temp;
-/* L70: */
- zmat[k + (k - np) * zmat_dim1] = temp;
- }
- }
- nrem = *npt;
- kold = 1;
- knew = *kopt;
-
-/* Reorder the provisional points in the way that exchanges PTSID(KOLD) */
-/* with PTSID(KNEW). */
-
-L80:
- i__2 = *n;
- for (j = 1; j <= i__2; ++j) {
- temp = bmat[kold + j * bmat_dim1];
- bmat[kold + j * bmat_dim1] = bmat[knew + j * bmat_dim1];
-/* L90: */
- bmat[knew + j * bmat_dim1] = temp;
- }
- i__2 = nptm;
- for (j = 1; j <= i__2; ++j) {
- temp = zmat[kold + j * zmat_dim1];
- zmat[kold + j * zmat_dim1] = zmat[knew + j * zmat_dim1];
-/* L100: */
- zmat[knew + j * zmat_dim1] = temp;
- }
- ptsid[kold] = ptsid[knew];
- ptsid[knew] = zero;
- w[*ndim + knew] = zero;
- --nrem;
- if (knew != *kopt) {
- temp = vlag[kold];
- vlag[kold] = vlag[knew];
- vlag[knew] = temp;
-
-/* Update the BMAT and ZMAT matrices so that the status of the KNEW-th */
-/* interpolation point can be changed from provisional to original. The */
-/* branch to label 350 occurs if all the original points are reinstated. */
-/* The nonnegative values of W(NDIM+K) are required in the search below. */
-
- update_(n, npt, &bmat[bmat_offset], &zmat[zmat_offset], ndim, &vlag[1]
- , &beta, &denom, &knew, &w[1]);
- if (nrem == 0) {
- goto L350;
- }
- i__2 = *npt;
- for (k = 1; k <= i__2; ++k) {
-/* L110: */
- w[*ndim + k] = (d__1 = w[*ndim + k], fabs(d__1));
- }
- }
-
-/* Pick the index KNEW of an original interpolation point that has not */
-/* yet replaced one of the provisional interpolation points, giving */
-/* attention to the closeness to XOPT and to previous tries with KNEW. */
-
-L120:
- dsqmin = zero;
- i__2 = *npt;
- for (k = 1; k <= i__2; ++k) {
- if (w[*ndim + k] > zero) {
- if (dsqmin == zero || w[*ndim + k] < dsqmin) {
- knew = k;
- dsqmin = w[*ndim + k];
- }
- }
-/* L130: */
- }
- if (dsqmin == zero) {
- goto L260;
- }
-
-/* Form the W-vector of the chosen original interpolation point. */
-
- i__2 = *n;
- for (j = 1; j <= i__2; ++j) {
-/* L140: */
- w[*npt + j] = xpt[knew + j * xpt_dim1];
- }
- i__2 = *npt;
- for (k = 1; k <= i__2; ++k) {
- sum = zero;
- if (k == *kopt) {
- } else if (ptsid[k] == zero) {
- i__1 = *n;
- for (j = 1; j <= i__1; ++j) {
-/* L150: */
- sum += w[*npt + j] * xpt[k + j * xpt_dim1];
- }
- } else {
- ip = (int) ptsid[k];
- if (ip > 0) {
- sum = w[*npt + ip] * ptsaux[(ip << 1) + 1];
- }
- iq = (int) ((double) np * ptsid[k] - (double) (ip *
- np));
- if (iq > 0) {
- iw = 1;
- if (ip == 0) {
- iw = 2;
- }
- sum += w[*npt + iq] * ptsaux[iw + (iq << 1)];
- }
- }
-/* L160: */
- w[k] = half * sum * sum;
- }
-
-/* Calculate VLAG and BETA for the required updating of the H matrix if */
-/* XPT(KNEW,.) is reinstated in the set of interpolation points. */
-
- i__2 = *npt;
- for (k = 1; k <= i__2; ++k) {
- sum = zero;
- i__1 = *n;
- for (j = 1; j <= i__1; ++j) {
-/* L170: */
- sum += bmat[k + j * bmat_dim1] * w[*npt + j];
- }
-/* L180: */
- vlag[k] = sum;
- }
- beta = zero;
- i__2 = nptm;
- for (j = 1; j <= i__2; ++j) {
- sum = zero;
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
-/* L190: */
- sum += zmat[k + j * zmat_dim1] * w[k];
- }
- beta -= sum * sum;
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
-/* L200: */
- vlag[k] += sum * zmat[k + j * zmat_dim1];
- }
- }
- bsum = zero;
- distsq = zero;
- i__1 = *n;
- for (j = 1; j <= i__1; ++j) {
- sum = zero;
- i__2 = *npt;
- for (k = 1; k <= i__2; ++k) {
-/* L210: */
- sum += bmat[k + j * bmat_dim1] * w[k];
- }
- jp = j + *npt;
- bsum += sum * w[jp];
- i__2 = *ndim;
- for (ip = *npt + 1; ip <= i__2; ++ip) {
-/* L220: */
- sum += bmat[ip + j * bmat_dim1] * w[ip];
- }
- bsum += sum * w[jp];
- vlag[jp] = sum;
-/* L230: */
-/* Computing 2nd power */
- d__1 = xpt[knew + j * xpt_dim1];
- distsq += d__1 * d__1;
- }
- beta = half * distsq * distsq + beta - bsum;
- vlag[*kopt] += one;
-
-/* KOLD is set to the index of the provisional interpolation point that is */
-/* going to be deleted to make way for the KNEW-th original interpolation */
-/* point. The choice of KOLD is governed by the avoidance of a small value */
-/* of the denominator in the updating calculation of UPDATE. */
-
- denom = zero;
- vlmxsq = zero;
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
- if (ptsid[k] != zero) {
- hdiag = zero;
- i__2 = nptm;
- for (j = 1; j <= i__2; ++j) {
-/* L240: */
-/* Computing 2nd power */
- d__1 = zmat[k + j * zmat_dim1];
- hdiag += d__1 * d__1;
- }
-/* Computing 2nd power */
- d__1 = vlag[k];
- den = beta * hdiag + d__1 * d__1;
- if (den > denom) {
- kold = k;
- denom = den;
- }
- }
-/* L250: */
-/* Computing MAX */
-/* Computing 2nd power */
- d__3 = vlag[k];
- d__1 = vlmxsq, d__2 = d__3 * d__3;
- vlmxsq = MAX2(d__1,d__2);
- }
- if (denom <= vlmxsq * .01) {
- w[*ndim + knew] = -w[*ndim + knew] - winc;
- goto L120;
- }
- goto L80;
-
-/* When label 260 is reached, all the final positions of the interpolation */
-/* points have been chosen although any changes have not been included yet */
-/* in XPT. Also the final BMAT and ZMAT matrices are complete, but, apart */
-/* from the shift of XBASE, the updating of the quadratic model remains to */
-/* be done. The following cycle through the new interpolation points begins */
-/* by putting the new point in XPT(KPT,.) and by setting PQ(KPT) to zero, */
-/* except that a RETURN occurs if MAXFUN prohibits another value of F. */
-
-L260:
- i__1 = *npt;
- for (kpt = 1; kpt <= i__1; ++kpt) {
- if (ptsid[kpt] == zero) {
- goto L340;
- }
-
- if (nlopt_stop_forced(stop)) return NLOPT_FORCED_STOP;
- else if (nlopt_stop_evals(stop)) return NLOPT_MAXEVAL_REACHED;
- else if (nlopt_stop_time(stop)) return NLOPT_MAXTIME_REACHED;
-
- ih = 0;
- i__2 = *n;
- for (j = 1; j <= i__2; ++j) {
- w[j] = xpt[kpt + j * xpt_dim1];
- xpt[kpt + j * xpt_dim1] = zero;
- temp = pq[kpt] * w[j];
- i__3 = j;
- for (i__ = 1; i__ <= i__3; ++i__) {
- ++ih;
-/* L270: */
- hq[ih] += temp * w[i__];
- }
- }
- pq[kpt] = zero;
- ip = (int) ptsid[kpt];
- iq = (int) ((double) np * ptsid[kpt] - (double) (ip * np))
- ;
- if (ip > 0) {
- xp = ptsaux[(ip << 1) + 1];
- xpt[kpt + ip * xpt_dim1] = xp;
- }
- if (iq > 0) {
- xq = ptsaux[(iq << 1) + 1];
- if (ip == 0) {
- xq = ptsaux[(iq << 1) + 2];
- }
- xpt[kpt + iq * xpt_dim1] = xq;
- }
-
-/* Set VQUAD to the value of the current model at the new point. */
-
- vquad = fbase;
- if (ip > 0) {
- ihp = (ip + ip * ip) / 2;
- vquad += xp * (gopt[ip] + half * xp * hq[ihp]);
- }
- if (iq > 0) {
- ihq = (iq + iq * iq) / 2;
- vquad += xq * (gopt[iq] + half * xq * hq[ihq]);
- if (ip > 0) {
- iw = MAX2(ihp,ihq) - (i__3 = ip - iq, IABS(i__3));
- vquad += xp * xq * hq[iw];
- }
- }
- i__3 = *npt;
- for (k = 1; k <= i__3; ++k) {
- temp = zero;
- if (ip > 0) {
- temp += xp * xpt[k + ip * xpt_dim1];
- }
- if (iq > 0) {
- temp += xq * xpt[k + iq * xpt_dim1];
- }
-/* L280: */
- vquad += half * pq[k] * temp * temp;
- }
-
-/* Calculate F at the new interpolation point, and set DIFF to the factor */
-/* that is going to multiply the KPT-th Lagrange function when the model */
-/* is updated to provide interpolation to the new function value. */
-
- i__3 = *n;
- for (i__ = 1; i__ <= i__3; ++i__) {
-/* Computing MIN */
-/* Computing MAX */
- d__3 = xl[i__], d__4 = xbase[i__] + xpt[kpt + i__ * xpt_dim1];
- d__1 = MAX2(d__3,d__4), d__2 = xu[i__];
- w[i__] = MIN2(d__1,d__2);
- if (xpt[kpt + i__ * xpt_dim1] == sl[i__]) {
- w[i__] = xl[i__];
- }
- if (xpt[kpt + i__ * xpt_dim1] == su[i__]) {
- w[i__] = xu[i__];
- }
-/* L290: */
- }
-
- stop->nevals++;
- f = calfun(*n, &w[1], calfun_data);
- fval[kpt] = f;
- if (f < fval[*kopt]) {
- *kopt = kpt;
- }
- if (nlopt_stop_forced(stop)) return NLOPT_FORCED_STOP;
- else if (f < stop->minf_max) return NLOPT_MINF_MAX_REACHED;
- else if (nlopt_stop_evals(stop)) return NLOPT_MAXEVAL_REACHED;
- else if (nlopt_stop_time(stop)) return NLOPT_MAXTIME_REACHED;
-
- diff = f - vquad;
-
-/* Update the quadratic model. The RETURN from the subroutine occurs when */
-/* all the new interpolation points are included in the model. */
-
- i__3 = *n;
- for (i__ = 1; i__ <= i__3; ++i__) {
-/* L310: */
- gopt[i__] += diff * bmat[kpt + i__ * bmat_dim1];
- }
- i__3 = *npt;
- for (k = 1; k <= i__3; ++k) {
- sum = zero;
- i__2 = nptm;
- for (j = 1; j <= i__2; ++j) {
-/* L320: */
- sum += zmat[k + j * zmat_dim1] * zmat[kpt + j * zmat_dim1];
- }
- temp = diff * sum;
- if (ptsid[k] == zero) {
- pq[k] += temp;
- } else {
- ip = (int) ptsid[k];
- iq = (int) ((double) np * ptsid[k] - (double) (ip
- * np));
- ihq = (iq * iq + iq) / 2;
- if (ip == 0) {
-/* Computing 2nd power */
- d__1 = ptsaux[(iq << 1) + 2];
- hq[ihq] += temp * (d__1 * d__1);
- } else {
- ihp = (ip * ip + ip) / 2;
-/* Computing 2nd power */
- d__1 = ptsaux[(ip << 1) + 1];
- hq[ihp] += temp * (d__1 * d__1);
- if (iq > 0) {
-/* Computing 2nd power */
- d__1 = ptsaux[(iq << 1) + 1];
- hq[ihq] += temp * (d__1 * d__1);
- iw = MAX2(ihp,ihq) - (i__2 = iq - ip, IABS(i__2));
- hq[iw] += temp * ptsaux[(ip << 1) + 1] * ptsaux[(iq <<
- 1) + 1];
- }
- }
- }
-/* L330: */
- }
- ptsid[kpt] = zero;
-L340:
- ;
- }
-L350:
- return NLOPT_SUCCESS;
-} /* rescue_ */
-
-static void altmov_(int *n, int *npt, double *xpt,
- double *xopt, double *bmat, double *zmat, int *ndim,
- double *sl, double *su, int *kopt, int *knew,
- double *adelt, double *xnew, double *xalt, double *
- alpha, double *cauchy, double *glag, double *hcol,
- double *w)
-{
- /* System generated locals */
- int xpt_dim1, xpt_offset, bmat_dim1, bmat_offset, zmat_dim1,
- zmat_offset, i__1, i__2;
- double d__1, d__2, d__3, d__4;
-
- /* Local variables */
- int i__, j, k;
- double ha, gw, one, diff, half;
- int ilbd, isbd;
- double slbd;
- int iubd;
- double vlag, subd, temp;
- int ksav;
- double step, zero, curv;
- int iflag;
- double scale, csave, tempa, tempb, tempd, const__, sumin, ggfree;
- int ibdsav;
- double dderiv, bigstp, predsq, presav, distsq, stpsav, wfixsq, wsqsav;
-
-
-/* The arguments N, NPT, XPT, XOPT, BMAT, ZMAT, NDIM, SL and SU all have */
-/* the same meanings as the corresponding arguments of BOBYQB. */
-/* KOPT is the index of the optimal interpolation point. */
-/* KNEW is the index of the interpolation point that is going to be moved. */
-/* ADELT is the current trust region bound. */
-/* XNEW will be set to a suitable new position for the interpolation point */
-/* XPT(KNEW,.). Specifically, it satisfies the SL, SU and trust region */
-/* bounds and it should provide a large denominator in the next call of */
-/* UPDATE. The step XNEW-XOPT from XOPT is restricted to moves along the */
-/* straight lines through XOPT and another interpolation point. */
-/* XALT also provides a large value of the modulus of the KNEW-th Lagrange */
-/* function subject to the constraints that have been mentioned, its main */
-/* difference from XNEW being that XALT-XOPT is a constrained version of */
-/* the Cauchy step within the trust region. An exception is that XALT is */
-/* not calculated if all components of GLAG (see below) are zero. */
-/* ALPHA will be set to the KNEW-th diagonal element of the H matrix. */
-/* CAUCHY will be set to the square of the KNEW-th Lagrange function at */
-/* the step XALT-XOPT from XOPT for the vector XALT that is returned, */
-/* except that CAUCHY is set to zero if XALT is not calculated. */
-/* GLAG is a working space vector of length N for the gradient of the */
-/* KNEW-th Lagrange function at XOPT. */
-/* HCOL is a working space vector of length NPT for the second derivative */
-/* coefficients of the KNEW-th Lagrange function. */
-/* W is a working space vector of length 2N that is going to hold the */
-/* constrained Cauchy step from XOPT of the Lagrange function, followed */
-/* by the downhill version of XALT when the uphill step is calculated. */
-
-/* Set the first NPT components of W to the leading elements of the */
-/* KNEW-th column of the H matrix. */
-
- /* Parameter adjustments */
- zmat_dim1 = *npt;
- zmat_offset = 1 + zmat_dim1;
- zmat -= zmat_offset;
- xpt_dim1 = *npt;
- xpt_offset = 1 + xpt_dim1;
- xpt -= xpt_offset;
- --xopt;
- bmat_dim1 = *ndim;
- bmat_offset = 1 + bmat_dim1;
- bmat -= bmat_offset;
- --sl;
- --su;
- --xnew;
- --xalt;
- --glag;
- --hcol;
- --w;
-
- /* Function Body */
- half = .5;
- one = 1.;
- zero = 0.;
- const__ = one + sqrt(2.);
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
-/* L10: */
- hcol[k] = zero;
- }
- i__1 = *npt - *n - 1;
- for (j = 1; j <= i__1; ++j) {
- temp = zmat[*knew + j * zmat_dim1];
- i__2 = *npt;
- for (k = 1; k <= i__2; ++k) {
-/* L20: */
- hcol[k] += temp * zmat[k + j * zmat_dim1];
- }
- }
- *alpha = hcol[*knew];
- ha = half * *alpha;
-
-/* Calculate the gradient of the KNEW-th Lagrange function at XOPT. */
-
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
-/* L30: */
- glag[i__] = bmat[*knew + i__ * bmat_dim1];
- }
- i__2 = *npt;
- for (k = 1; k <= i__2; ++k) {
- temp = zero;
- i__1 = *n;
- for (j = 1; j <= i__1; ++j) {
-/* L40: */
- temp += xpt[k + j * xpt_dim1] * xopt[j];
- }
- temp = hcol[k] * temp;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
-/* L50: */
- glag[i__] += temp * xpt[k + i__ * xpt_dim1];
- }
- }
-
-/* Search for a large denominator along the straight lines through XOPT */
-/* and another interpolation point. SLBD and SUBD will be lower and upper */
-/* bounds on the step along each of these lines in turn. PREDSQ will be */
-/* set to the square of the predicted denominator for each line. PRESAV */
-/* will be set to the largest admissible value of PREDSQ that occurs. */
-
- presav = zero;
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
- if (k == *kopt) {
- goto L80;
- }
- dderiv = zero;
- distsq = zero;
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
- temp = xpt[k + i__ * xpt_dim1] - xopt[i__];
- dderiv += glag[i__] * temp;
-/* L60: */
- distsq += temp * temp;
- }
- subd = *adelt / sqrt(distsq);
- slbd = -subd;
- ilbd = 0;
- iubd = 0;
- sumin = MIN2(one,subd);
-
-/* Revise SLBD and SUBD if necessary because of the bounds in SL and SU. */
-
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
- temp = xpt[k + i__ * xpt_dim1] - xopt[i__];
- if (temp > zero) {
- if (slbd * temp < sl[i__] - xopt[i__]) {
- slbd = (sl[i__] - xopt[i__]) / temp;
- ilbd = -i__;
- }
- if (subd * temp > su[i__] - xopt[i__]) {
-/* Computing MAX */
- d__1 = sumin, d__2 = (su[i__] - xopt[i__]) / temp;
- subd = MAX2(d__1,d__2);
- iubd = i__;
- }
- } else if (temp < zero) {
- if (slbd * temp > su[i__] - xopt[i__]) {
- slbd = (su[i__] - xopt[i__]) / temp;
- ilbd = i__;
- }
- if (subd * temp < sl[i__] - xopt[i__]) {
-/* Computing MAX */
- d__1 = sumin, d__2 = (sl[i__] - xopt[i__]) / temp;
- subd = MAX2(d__1,d__2);
- iubd = -i__;
- }
- }
-/* L70: */
- }
-
-/* Seek a large modulus of the KNEW-th Lagrange function when the index */
-/* of the other interpolation point on the line through XOPT is KNEW. */
-
- if (k == *knew) {
- diff = dderiv - one;
- step = slbd;
- vlag = slbd * (dderiv - slbd * diff);
- isbd = ilbd;
- temp = subd * (dderiv - subd * diff);
- if (fabs(temp) > fabs(vlag)) {
- step = subd;
- vlag = temp;
- isbd = iubd;
- }
- tempd = half * dderiv;
- tempa = tempd - diff * slbd;
- tempb = tempd - diff * subd;
- if (tempa * tempb < zero) {
- temp = tempd * tempd / diff;
- if (fabs(temp) > fabs(vlag)) {
- step = tempd / diff;
- vlag = temp;
- isbd = 0;
- }
- }
-
-/* Search along each of the other lines through XOPT and another point. */
-
- } else {
- step = slbd;
- vlag = slbd * (one - slbd);
- isbd = ilbd;
- temp = subd * (one - subd);
- if (fabs(temp) > fabs(vlag)) {
- step = subd;
- vlag = temp;
- isbd = iubd;
- }
- if (subd > half) {
- if (fabs(vlag) < .25) {
- step = half;
- vlag = .25;
- isbd = 0;
- }
- }
- vlag *= dderiv;
- }
-
-/* Calculate PREDSQ for the current line search and maintain PRESAV. */
-
- temp = step * (one - step) * distsq;
- predsq = vlag * vlag * (vlag * vlag + ha * temp * temp);
- if (predsq > presav) {
- presav = predsq;
- ksav = k;
- stpsav = step;
- ibdsav = isbd;
- }
-L80:
- ;
- }
-
-/* Construct XNEW in a way that satisfies the bound constraints exactly. */
-
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- temp = xopt[i__] + stpsav * (xpt[ksav + i__ * xpt_dim1] - xopt[i__]);
-/* L90: */
-/* Computing MAX */
-/* Computing MIN */
- d__3 = su[i__];
- d__1 = sl[i__], d__2 = MIN2(d__3,temp);
- xnew[i__] = MAX2(d__1,d__2);
- }
- if (ibdsav < 0) {
- xnew[-ibdsav] = sl[-ibdsav];
- }
- if (ibdsav > 0) {
- xnew[ibdsav] = su[ibdsav];
- }
-
-/* Prepare for the iterative method that assembles the constrained Cauchy */
-/* step in W. The sum of squares of the fixed components of W is formed in */
-/* WFIXSQ, and the free components of W are set to BIGSTP. */
-
- bigstp = *adelt + *adelt;
- iflag = 0;
-L100:
- wfixsq = zero;
- ggfree = zero;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- w[i__] = zero;
-/* Computing MIN */
- d__1 = xopt[i__] - sl[i__], d__2 = glag[i__];
- tempa = MIN2(d__1,d__2);
-/* Computing MAX */
- d__1 = xopt[i__] - su[i__], d__2 = glag[i__];
- tempb = MAX2(d__1,d__2);
- if (tempa > zero || tempb < zero) {
- w[i__] = bigstp;
-/* Computing 2nd power */
- d__1 = glag[i__];
- ggfree += d__1 * d__1;
- }
-/* L110: */
- }
- if (ggfree == zero) {
- *cauchy = zero;
- goto L200;
- }
-
-/* Investigate whether more components of W can be fixed. */
-
-L120:
- temp = *adelt * *adelt - wfixsq;
- if (temp > zero) {
- wsqsav = wfixsq;
- step = sqrt(temp / ggfree);
- ggfree = zero;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- if (w[i__] == bigstp) {
- temp = xopt[i__] - step * glag[i__];
- if (temp <= sl[i__]) {
- w[i__] = sl[i__] - xopt[i__];
-/* Computing 2nd power */
- d__1 = w[i__];
- wfixsq += d__1 * d__1;
- } else if (temp >= su[i__]) {
- w[i__] = su[i__] - xopt[i__];
-/* Computing 2nd power */
- d__1 = w[i__];
- wfixsq += d__1 * d__1;
- } else {
-/* Computing 2nd power */
- d__1 = glag[i__];
- ggfree += d__1 * d__1;
- }
- }
-/* L130: */
- }
- if (wfixsq > wsqsav && ggfree > zero) {
- goto L120;
- }
- }
-
-/* Set the remaining free components of W and all components of XALT, */
-/* except that W may be scaled later. */
-
- gw = zero;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- if (w[i__] == bigstp) {
- w[i__] = -step * glag[i__];
-/* Computing MAX */
-/* Computing MIN */
- d__3 = su[i__], d__4 = xopt[i__] + w[i__];
- d__1 = sl[i__], d__2 = MIN2(d__3,d__4);
- xalt[i__] = MAX2(d__1,d__2);
- } else if (w[i__] == zero) {
- xalt[i__] = xopt[i__];
- } else if (glag[i__] > zero) {
- xalt[i__] = sl[i__];
- } else {
- xalt[i__] = su[i__];
- }
-/* L140: */
- gw += glag[i__] * w[i__];
- }
-
-/* Set CURV to the curvature of the KNEW-th Lagrange function along W. */
-/* Scale W by a factor less than one if that can reduce the modulus of */
-/* the Lagrange function at XOPT+W. Set CAUCHY to the final value of */
-/* the square of this function. */
-
- curv = zero;
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
- temp = zero;
- i__2 = *n;
- for (j = 1; j <= i__2; ++j) {
-/* L150: */
- temp += xpt[k + j * xpt_dim1] * w[j];
- }
-/* L160: */
- curv += hcol[k] * temp * temp;
- }
- if (iflag == 1) {
- curv = -curv;
- }
- if (curv > -gw && curv < -const__ * gw) {
- scale = -gw / curv;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- temp = xopt[i__] + scale * w[i__];
-/* L170: */
-/* Computing MAX */
-/* Computing MIN */
- d__3 = su[i__];
- d__1 = sl[i__], d__2 = MIN2(d__3,temp);
- xalt[i__] = MAX2(d__1,d__2);
- }
-/* Computing 2nd power */
- d__1 = half * gw * scale;
- *cauchy = d__1 * d__1;
- } else {
-/* Computing 2nd power */
- d__1 = gw + half * curv;
- *cauchy = d__1 * d__1;
- }
-
-/* If IFLAG is zero, then XALT is calculated as before after reversing */
-/* the sign of GLAG. Thus two XALT vectors become available. The one that */
-/* is chosen is the one that gives the larger value of CAUCHY. */
-
- if (iflag == 0) {
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- glag[i__] = -glag[i__];
-/* L180: */
- w[*n + i__] = xalt[i__];
- }
- csave = *cauchy;
- iflag = 1;
- goto L100;
- }
- if (csave > *cauchy) {
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
-/* L190: */
- xalt[i__] = w[*n + i__];
- }
- *cauchy = csave;
- }
-L200:
- return;
-} /* altmov_ */
-
-static void trsbox_(int *n, int *npt, double *xpt,
- double *xopt, double *gopt, double *hq, double *pq,
- double *sl, double *su, double *delta, double *xnew,
- double *d__, double *gnew, double *xbdi, double *s,
- double *hs, double *hred, double *dsq, double *crvmin)
-{
- /* System generated locals */
- int xpt_dim1, xpt_offset, i__1, i__2;
- double d__1, d__2, d__3, d__4;
-
- /* Local variables */
- int i__, j, k, ih;
- double ds;
- int iu;
- double dhd, dhs, cth, one, shs, sth, ssq, half, beta, sdec, blen;
- int iact, nact;
- double angt, qred;
- int isav;
- double temp, zero, xsav, xsum, angbd, dredg, sredg;
- int iterc;
- double resid, delsq, ggsav, tempa, tempb, ratio, sqstp, redmax,
- dredsq, redsav, onemin, gredsq, rednew;
- int itcsav;
- double rdprev, rdnext, stplen, stepsq;
- int itermax;
-
-
-/* The arguments N, NPT, XPT, XOPT, GOPT, HQ, PQ, SL and SU have the same */
-/* meanings as the corresponding arguments of BOBYQB. */
-/* DELTA is the trust region radius for the present calculation, which */
-/* seeks a small value of the quadratic model within distance DELTA of */
-/* XOPT subject to the bounds on the variables. */
-/* XNEW will be set to a new vector of variables that is approximately */
-/* the one that minimizes the quadratic model within the trust region */
-/* subject to the SL and SU constraints on the variables. It satisfies */
-/* as equations the bounds that become active during the calculation. */
-/* D is the calculated trial step from XOPT, generated iteratively from an */
-/* initial value of zero. Thus XNEW is XOPT+D after the final iteration. */
-/* GNEW holds the gradient of the quadratic model at XOPT+D. It is updated */
-/* when D is updated. */
-/* XBDI is a working space vector. For I=1,2,...,N, the element XBDI(I) is */
-/* set to -1.0, 0.0, or 1.0, the value being nonzero if and only if the */
-/* I-th variable has become fixed at a bound, the bound being SL(I) or */
-/* SU(I) in the case XBDI(I)=-1.0 or XBDI(I)=1.0, respectively. This */
-/* information is accumulated during the construction of XNEW. */
-/* The arrays S, HS and HRED are also used for working space. They hold the */
-/* current search direction, and the changes in the gradient of Q along S */
-/* and the reduced D, respectively, where the reduced D is the same as D, */
-/* except that the components of the fixed variables are zero. */
-/* DSQ will be set to the square of the length of XNEW-XOPT. */
-/* CRVMIN is set to zero if D reaches the trust region boundary. Otherwise */
-/* it is set to the least curvature of H that occurs in the conjugate */
-/* gradient searches that are not restricted by any constraints. The */
-/* value CRVMIN=-1.0D0 is set, however, if all of these searches are */
-/* constrained. */
-
-/* A version of the truncated conjugate gradient is applied. If a line */
-/* search is restricted by a constraint, then the procedure is restarted, */
-/* the values of the variables that are at their bounds being fixed. If */
-/* the trust region boundary is reached, then further changes may be made */
-/* to D, each one being in the two dimensional space that is spanned */
-/* by the current D and the gradient of Q at XOPT+D, staying on the trust */
-/* region boundary. Termination occurs when the reduction in Q seems to */
-/* be close to the greatest reduction that can be achieved. */
-
-/* Set some constants. */
-
- /* Parameter adjustments */
- xpt_dim1 = *npt;
- xpt_offset = 1 + xpt_dim1;
- xpt -= xpt_offset;
- --xopt;
- --gopt;
- --hq;
- --pq;
- --sl;
- --su;
- --xnew;
- --d__;
- --gnew;
- --xbdi;
- --s;
- --hs;
- --hred;
-
- /* Function Body */
- half = .5;
- one = 1.;
- onemin = -1.;
- zero = 0.;
-
-/* The sign of GOPT(I) gives the sign of the change to the I-th variable */
-/* that will reduce Q from its value at XOPT. Thus XBDI(I) shows whether */
-/* or not to fix the I-th variable at one of its bounds initially, with */
-/* NACT being set to the number of fixed variables. D and GNEW are also */
-/* set for the first iteration. DELSQ is the upper bound on the sum of */
-/* squares of the free variables. QRED is the reduction in Q so far. */
-
- iterc = 0;
- nact = 0;
- sqstp = zero;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- xbdi[i__] = zero;
- if (xopt[i__] <= sl[i__]) {
- if (gopt[i__] >= zero) {
- xbdi[i__] = onemin;
- }
- } else if (xopt[i__] >= su[i__]) {
- if (gopt[i__] <= zero) {
- xbdi[i__] = one;
- }
- }
- if (xbdi[i__] != zero) {
- ++nact;
- }
- d__[i__] = zero;
-/* L10: */
- gnew[i__] = gopt[i__];
- }
- delsq = *delta * *delta;
- qred = zero;
- *crvmin = onemin;
-
-/* Set the next search direction of the conjugate gradient method. It is */
-/* the steepest descent direction initially and when the iterations are */
-/* restarted because a variable has just been fixed by a bound, and of */
-/* course the components of the fixed variables are zero. ITERMAX is an */
-/* upper bound on the indices of the conjugate gradient iterations. */
-
-L20:
- beta = zero;
-L30:
- stepsq = zero;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- if (xbdi[i__] != zero) {
- s[i__] = zero;
- } else if (beta == zero) {
- s[i__] = -gnew[i__];
- } else {
- s[i__] = beta * s[i__] - gnew[i__];
- }
-/* L40: */
-/* Computing 2nd power */
- d__1 = s[i__];
- stepsq += d__1 * d__1;
- }
- if (stepsq == zero) {
- goto L190;
- }
- if (beta == zero) {
- gredsq = stepsq;
- itermax = iterc + *n - nact;
- }
- if (gredsq * delsq <= qred * 1e-4 * qred) {
- goto L190;
- }
-
-/* Multiply the search direction by the second derivative matrix of Q and */
-/* calculate some scalars for the choice of steplength. Then set BLEN to */
-/* the length of the the step to the trust region boundary and STPLEN to */
-/* the steplength, ignoring the simple bounds. */
-
- goto L210;
-L50:
- resid = delsq;
- ds = zero;
- shs = zero;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- if (xbdi[i__] == zero) {
-/* Computing 2nd power */
- d__1 = d__[i__];
- resid -= d__1 * d__1;
- ds += s[i__] * d__[i__];
- shs += s[i__] * hs[i__];
- }
-/* L60: */
- }
- if (resid <= zero) {
- goto L90;
- }
- temp = sqrt(stepsq * resid + ds * ds);
- if (ds < zero) {
- blen = (temp - ds) / stepsq;
- } else {
- blen = resid / (temp + ds);
- }
- stplen = blen;
- if (shs > zero) {
-/* Computing MIN */
- d__1 = blen, d__2 = gredsq / shs;
- stplen = MIN2(d__1,d__2);
- }
-
-/* Reduce STPLEN if necessary in order to preserve the simple bounds, */
-/* letting IACT be the index of the new constrained variable. */
-
- iact = 0;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- if (s[i__] != zero) {
- xsum = xopt[i__] + d__[i__];
- if (s[i__] > zero) {
- temp = (su[i__] - xsum) / s[i__];
- } else {
- temp = (sl[i__] - xsum) / s[i__];
- }
- if (temp < stplen) {
- stplen = temp;
- iact = i__;
- }
- }
-/* L70: */
- }
-
-/* Update CRVMIN, GNEW and D. Set SDEC to the decrease that occurs in Q. */
-
- sdec = zero;
- if (stplen > zero) {
- ++iterc;
- temp = shs / stepsq;
- if (iact == 0 && temp > zero) {
- *crvmin = MIN2(*crvmin,temp);
- if (*crvmin == onemin) {
- *crvmin = temp;
- }
- }
- ggsav = gredsq;
- gredsq = zero;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- gnew[i__] += stplen * hs[i__];
- if (xbdi[i__] == zero) {
-/* Computing 2nd power */
- d__1 = gnew[i__];
- gredsq += d__1 * d__1;
- }
-/* L80: */
- d__[i__] += stplen * s[i__];
- }
-/* Computing MAX */
- d__1 = stplen * (ggsav - half * stplen * shs);
- sdec = MAX2(d__1,zero);
- qred += sdec;
- }
-
-/* Restart the conjugate gradient method if it has hit a new bound. */
-
- if (iact > 0) {
- ++nact;
- xbdi[iact] = one;
- if (s[iact] < zero) {
- xbdi[iact] = onemin;
- }
-/* Computing 2nd power */
- d__1 = d__[iact];
- delsq -= d__1 * d__1;
- if (delsq <= zero) {
- goto L90;
- }
- goto L20;
- }
-
-/* If STPLEN is less than BLEN, then either apply another conjugate */
-/* gradient iteration or RETURN. */
-
- if (stplen < blen) {
- if (iterc == itermax) {
- goto L190;
- }
- if (sdec <= qred * .01) {
- goto L190;
- }
- beta = gredsq / ggsav;
- goto L30;
- }
-L90:
- *crvmin = zero;
-
-/* Prepare for the alternative iteration by calculating some scalars */
-/* and by multiplying the reduced D by the second derivative matrix of */
-/* Q, where S holds the reduced D in the call of GGMULT. */
-
-L100:
- if (nact >= *n - 1) {
- goto L190;
- }
- dredsq = zero;
- dredg = zero;
- gredsq = zero;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- if (xbdi[i__] == zero) {
-/* Computing 2nd power */
- d__1 = d__[i__];
- dredsq += d__1 * d__1;
- dredg += d__[i__] * gnew[i__];
-/* Computing 2nd power */
- d__1 = gnew[i__];
- gredsq += d__1 * d__1;
- s[i__] = d__[i__];
- } else {
- s[i__] = zero;
- }
-/* L110: */
- }
- itcsav = iterc;
- goto L210;
-
-/* Let the search direction S be a linear combination of the reduced D */
-/* and the reduced G that is orthogonal to the reduced D. */
-
-L120:
- ++iterc;
- temp = gredsq * dredsq - dredg * dredg;
- if (temp <= qred * 1e-4 * qred) {
- goto L190;
- }
- temp = sqrt(temp);
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- if (xbdi[i__] == zero) {
- s[i__] = (dredg * d__[i__] - dredsq * gnew[i__]) / temp;
- } else {
- s[i__] = zero;
- }
-/* L130: */
- }
- sredg = -temp;
-
-/* By considering the simple bounds on the variables, calculate an upper */
-/* bound on the tangent of half the angle of the alternative iteration, */
-/* namely ANGBD, except that, if already a free variable has reached a */
-/* bound, there is a branch back to label 100 after fixing that variable. */
-
- angbd = one;
- iact = 0;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- if (xbdi[i__] == zero) {
- tempa = xopt[i__] + d__[i__] - sl[i__];
- tempb = su[i__] - xopt[i__] - d__[i__];
- if (tempa <= zero) {
- ++nact;
- xbdi[i__] = onemin;
- goto L100;
- } else if (tempb <= zero) {
- ++nact;
- xbdi[i__] = one;
- goto L100;
- }
- ratio = one;
-/* Computing 2nd power */
- d__1 = d__[i__];
-/* Computing 2nd power */
- d__2 = s[i__];
- ssq = d__1 * d__1 + d__2 * d__2;
-/* Computing 2nd power */
- d__1 = xopt[i__] - sl[i__];
- temp = ssq - d__1 * d__1;
- if (temp > zero) {
- temp = sqrt(temp) - s[i__];
- if (angbd * temp > tempa) {
- angbd = tempa / temp;
- iact = i__;
- xsav = onemin;
- }
- }
-/* Computing 2nd power */
- d__1 = su[i__] - xopt[i__];
- temp = ssq - d__1 * d__1;
- if (temp > zero) {
- temp = sqrt(temp) + s[i__];
- if (angbd * temp > tempb) {
- angbd = tempb / temp;
- iact = i__;
- xsav = one;
- }
- }
- }
-/* L140: */
- }
-
-/* Calculate HHD and some curvatures for the alternative iteration. */
-
- goto L210;
-L150:
- shs = zero;
- dhs = zero;
- dhd = zero;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- if (xbdi[i__] == zero) {
- shs += s[i__] * hs[i__];
- dhs += d__[i__] * hs[i__];
- dhd += d__[i__] * hred[i__];
- }
-/* L160: */
- }
-
-/* Seek the greatest reduction in Q for a range of equally spaced values */
-/* of ANGT in [0,ANGBD], where ANGT is the tangent of half the angle of */
-/* the alternative iteration. */
-
- redmax = zero;
- isav = 0;
- redsav = zero;
- iu = (int) (angbd * 17. + 3.1);
- i__1 = iu;
- for (i__ = 1; i__ <= i__1; ++i__) {
- angt = angbd * (double) i__ / (double) iu;
- sth = (angt + angt) / (one + angt * angt);
- temp = shs + angt * (angt * dhd - dhs - dhs);
- rednew = sth * (angt * dredg - sredg - half * sth * temp);
- if (rednew > redmax) {
- redmax = rednew;
- isav = i__;
- rdprev = redsav;
- } else if (i__ == isav + 1) {
- rdnext = rednew;
- }
-/* L170: */
- redsav = rednew;
- }
-
-/* Return if the reduction is zero. Otherwise, set the sine and cosine */
-/* of the angle of the alternative iteration, and calculate SDEC. */
-
- if (isav == 0) {
- goto L190;
- }
- if (isav < iu) {
- temp = (rdnext - rdprev) / (redmax + redmax - rdprev - rdnext);
- angt = angbd * ((double) isav + half * temp) / (double) iu;
- }
- cth = (one - angt * angt) / (one + angt * angt);
- sth = (angt + angt) / (one + angt * angt);
- temp = shs + angt * (angt * dhd - dhs - dhs);
- sdec = sth * (angt * dredg - sredg - half * sth * temp);
- if (sdec <= zero) {
- goto L190;
- }
-
-/* Update GNEW, D and HRED. If the angle of the alternative iteration */
-/* is restricted by a bound on a free variable, that variable is fixed */
-/* at the bound. */
-
- dredg = zero;
- gredsq = zero;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- gnew[i__] = gnew[i__] + (cth - one) * hred[i__] + sth * hs[i__];
- if (xbdi[i__] == zero) {
- d__[i__] = cth * d__[i__] + sth * s[i__];
- dredg += d__[i__] * gnew[i__];
-/* Computing 2nd power */
- d__1 = gnew[i__];
- gredsq += d__1 * d__1;
- }
-/* L180: */
- hred[i__] = cth * hred[i__] + sth * hs[i__];
- }
- qred += sdec;
- if (iact > 0 && isav == iu) {
- ++nact;
- xbdi[iact] = xsav;
- goto L100;
- }
-
-/* If SDEC is sufficiently small, then RETURN after setting XNEW to */
-/* XOPT+D, giving careful attention to the bounds. */
-
- if (sdec > qred * .01) {
- goto L120;
- }
-L190:
- *dsq = zero;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
-/* Computing MAX */
-/* Computing MIN */
- d__3 = xopt[i__] + d__[i__], d__4 = su[i__];
- d__1 = MIN2(d__3,d__4), d__2 = sl[i__];
- xnew[i__] = MAX2(d__1,d__2);
- if (xbdi[i__] == onemin) {
- xnew[i__] = sl[i__];
- }
- if (xbdi[i__] == one) {
- xnew[i__] = su[i__];
- }
- d__[i__] = xnew[i__] - xopt[i__];
-/* L200: */
-/* Computing 2nd power */
- d__1 = d__[i__];
- *dsq += d__1 * d__1;
- }
- return;
-/* The following instructions multiply the current S-vector by the second */
-/* derivative matrix of the quadratic model, putting the product in HS. */
-/* They are reached from three different parts of the software above and */
-/* they can be regarded as an external subroutine. */
-
-L210:
- ih = 0;
- i__1 = *n;
- for (j = 1; j <= i__1; ++j) {
- hs[j] = zero;
- i__2 = j;
- for (i__ = 1; i__ <= i__2; ++i__) {
- ++ih;
- if (i__ < j) {
- hs[j] += hq[ih] * s[i__];
- }
-/* L220: */
- hs[i__] += hq[ih] * s[j];
- }
- }
- i__2 = *npt;
- for (k = 1; k <= i__2; ++k) {
- if (pq[k] != zero) {
- temp = zero;
- i__1 = *n;
- for (j = 1; j <= i__1; ++j) {
-/* L230: */
- temp += xpt[k + j * xpt_dim1] * s[j];
- }
- temp *= pq[k];
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
-/* L240: */
- hs[i__] += temp * xpt[k + i__ * xpt_dim1];
- }
- }
-/* L250: */
- }
- if (*crvmin != zero) {
- goto L50;
- }
- if (iterc > itcsav) {
- goto L150;
- }
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
-/* L260: */
- hred[i__] = hs[i__];
- }
- goto L120;
-} /* trsbox_ */
-
-static nlopt_result prelim_(int *n, int *npt, double *x,
- const double *xl, const double *xu, double *rhobeg,
- nlopt_stopping *stop,
- bobyqa_func calfun, void *calfun_data,
- double *xbase, double *xpt, double *fval,
- double *gopt, double *hq, double *pq, double *bmat,
- double *zmat, int *ndim, double *sl, double *su,
- int *kopt)
-{
- /* System generated locals */
- int xpt_dim1, xpt_offset, bmat_dim1, bmat_offset, zmat_dim1,
- zmat_offset, i__1, i__2;
- double d__1, d__2, d__3, d__4;
-
- /* Local variables */
- double f;
- int i__, j, k, ih, np, nfm;
- double one;
- int nfx, ipt, jpt;
- double two, fbeg, diff, half, temp, zero, recip, stepa, stepb;
- int itemp;
- double rhosq;
-
- int nf;
-
-/* The arguments N, NPT, X, XL, XU, RHOBEG, and MAXFUN are the */
-/* same as the corresponding arguments in SUBROUTINE BOBYQA. */
-/* The arguments XBASE, XPT, FVAL, HQ, PQ, BMAT, ZMAT, NDIM, SL and SU */
-/* are the same as the corresponding arguments in BOBYQB, the elements */
-/* of SL and SU being set in BOBYQA. */
-/* GOPT is usually the gradient of the quadratic model at XOPT+XBASE, but */
-/* it is set by PRELIM to the gradient of the quadratic model at XBASE. */
-/* If XOPT is nonzero, BOBYQB will change it to its usual value later. */
-/* NF is maintaned as the number of calls of CALFUN so far. */
-/* KOPT will be such that the least calculated value of F so far is at */
-/* the point XPT(KOPT,.)+XBASE in the space of the variables. */
-
-/* SUBROUTINE PRELIM sets the elements of XBASE, XPT, FVAL, GOPT, HQ, PQ, */
-/* BMAT and ZMAT for the first iteration, and it maintains the values of */
-/* NF and KOPT. The vector X is also changed by PRELIM. */
-
-/* Set some constants. */
-
- /* Parameter adjustments */
- zmat_dim1 = *npt;
- zmat_offset = 1 + zmat_dim1;
- zmat -= zmat_offset;
- xpt_dim1 = *npt;
- xpt_offset = 1 + xpt_dim1;
- xpt -= xpt_offset;
- --x;
- --xl;
- --xu;
- --xbase;
- --fval;
- --gopt;
- --hq;
- --pq;
- bmat_dim1 = *ndim;
- bmat_offset = 1 + bmat_dim1;
- bmat -= bmat_offset;
- --sl;
- --su;
-
- /* Function Body */
- half = .5;
- one = 1.;
- two = 2.;
- zero = 0.;
- rhosq = *rhobeg * *rhobeg;
- recip = one / rhosq;
- np = *n + 1;
-
-/* Set XBASE to the initial vector of variables, and set the initial */
-/* elements of XPT, BMAT, HQ, PQ and ZMAT to zero. */
-
- i__1 = *n;
- for (j = 1; j <= i__1; ++j) {
- xbase[j] = x[j];
- i__2 = *npt;
- for (k = 1; k <= i__2; ++k) {
-/* L10: */
- xpt[k + j * xpt_dim1] = zero;
- }
- i__2 = *ndim;
- for (i__ = 1; i__ <= i__2; ++i__) {
-/* L20: */
- bmat[i__ + j * bmat_dim1] = zero;
- }
- }
- i__2 = *n * np / 2;
- for (ih = 1; ih <= i__2; ++ih) {
-/* L30: */
- hq[ih] = zero;
- }
- i__2 = *npt;
- for (k = 1; k <= i__2; ++k) {
- pq[k] = zero;
- i__1 = *npt - np;
- for (j = 1; j <= i__1; ++j) {
-/* L40: */
- zmat[k + j * zmat_dim1] = zero;
- }
- }
-
-/* Begin the initialization procedure. NF becomes one more than the number */
-/* of function values so far. The coordinates of the displacement of the */
-/* next initial interpolation point from XBASE are set in XPT(NF+1,.). */
-
- nf = 0;
-L50:
- nfm = nf;
- nfx = nf - *n;
- ++(nf);
- if (nfm <= *n << 1) {
- if (nfm >= 1 && nfm <= *n) {
- stepa = *rhobeg;
- if (su[nfm] == zero) {
- stepa = -stepa;
- }
- xpt[nf + nfm * xpt_dim1] = stepa;
- } else if (nfm > *n) {
- stepa = xpt[nf - *n + nfx * xpt_dim1];
- stepb = -(*rhobeg);
- if (sl[nfx] == zero) {
-/* Computing MIN */
- d__1 = two * *rhobeg, d__2 = su[nfx];
- stepb = MIN2(d__1,d__2);
- }
- if (su[nfx] == zero) {
-/* Computing MAX */
- d__1 = -two * *rhobeg, d__2 = sl[nfx];
- stepb = MAX2(d__1,d__2);
- }
- xpt[nf + nfx * xpt_dim1] = stepb;
- }
- } else {
- itemp = (nfm - np) / *n;
- jpt = nfm - itemp * *n - *n;
- ipt = jpt + itemp;
- if (ipt > *n) {
- itemp = jpt;
- jpt = ipt - *n;
- ipt = itemp;
- }
- xpt[nf + ipt * xpt_dim1] = xpt[ipt + 1 + ipt * xpt_dim1];
- xpt[nf + jpt * xpt_dim1] = xpt[jpt + 1 + jpt * xpt_dim1];
- }
-
-/* Calculate the next value of F. The least function value so far and */
-/* its index are required. */
-
- i__1 = *n;
- for (j = 1; j <= i__1; ++j) {
-/* Computing MIN */
-/* Computing MAX */
- d__3 = xl[j], d__4 = xbase[j] + xpt[nf + j * xpt_dim1];
- d__1 = MAX2(d__3,d__4), d__2 = xu[j];
- x[j] = MIN2(d__1,d__2);
- if (xpt[nf + j * xpt_dim1] == sl[j]) {
- x[j] = xl[j];
- }
- if (xpt[nf + j * xpt_dim1] == su[j]) {
- x[j] = xu[j];
- }
-/* L60: */
- }
- stop->nevals++;
- f = calfun(*n, &x[1], calfun_data);
- fval[nf] = f;
- if (nf == 1) {
- fbeg = f;
- *kopt = 1;
- } else if (f < fval[*kopt]) {
- *kopt = nf;
- }
-
-/* Set the nonzero initial elements of BMAT and the quadratic model in the */
-/* cases when NF is at most 2*N+1. If NF exceeds N+1, then the positions */
-/* of the NF-th and (NF-N)-th interpolation points may be switched, in */
-/* order that the function value at the first of them contributes to the */
-/* off-diagonal second derivative terms of the initial quadratic model. */
-
- if (nf <= (*n << 1) + 1) {
- if (nf >= 2 && nf <= *n + 1) {
- gopt[nfm] = (f - fbeg) / stepa;
- if (*npt < nf + *n) {
- bmat[nfm * bmat_dim1 + 1] = -one / stepa;
- bmat[nf + nfm * bmat_dim1] = one / stepa;
- bmat[*npt + nfm + nfm * bmat_dim1] = -half * rhosq;
- }
- } else if (nf >= *n + 2) {
- ih = nfx * (nfx + 1) / 2;
- temp = (f - fbeg) / stepb;
- diff = stepb - stepa;
- hq[ih] = two * (temp - gopt[nfx]) / diff;
- gopt[nfx] = (gopt[nfx] * stepb - temp * stepa) / diff;
- if (stepa * stepb < zero) {
- if (f < fval[nf - *n]) {
- fval[nf] = fval[nf - *n];
- fval[nf - *n] = f;
- if (*kopt == nf) {
- *kopt = nf - *n;
- }
- xpt[nf - *n + nfx * xpt_dim1] = stepb;
- xpt[nf + nfx * xpt_dim1] = stepa;
- }
- }
- bmat[nfx * bmat_dim1 + 1] = -(stepa + stepb) / (stepa * stepb);
- bmat[nf + nfx * bmat_dim1] = -half / xpt[nf - *n + nfx *
- xpt_dim1];
- bmat[nf - *n + nfx * bmat_dim1] = -bmat[nfx * bmat_dim1 + 1] -
- bmat[nf + nfx * bmat_dim1];
- zmat[nfx * zmat_dim1 + 1] = sqrt(two) / (stepa * stepb);
- zmat[nf + nfx * zmat_dim1] = sqrt(half) / rhosq;
- zmat[nf - *n + nfx * zmat_dim1] = -zmat[nfx * zmat_dim1 + 1] -
- zmat[nf + nfx * zmat_dim1];
- }
-
-/* Set the off-diagonal second derivatives of the Lagrange functions and */
-/* the initial quadratic model. */
-
- } else {
- ih = ipt * (ipt - 1) / 2 + jpt;
- zmat[nfx * zmat_dim1 + 1] = recip;
- zmat[nf + nfx * zmat_dim1] = recip;
- zmat[ipt + 1 + nfx * zmat_dim1] = -recip;
- zmat[jpt + 1 + nfx * zmat_dim1] = -recip;
- temp = xpt[nf + ipt * xpt_dim1] * xpt[nf + jpt * xpt_dim1];
- hq[ih] = (fbeg - fval[ipt + 1] - fval[jpt + 1] + f) / temp;
- }
- if (nlopt_stop_forced(stop)) return NLOPT_FORCED_STOP;
- else if (f < stop->minf_max) return NLOPT_MINF_MAX_REACHED;
- else if (nlopt_stop_evals(stop)) return NLOPT_MAXEVAL_REACHED;
- else if (nlopt_stop_time(stop)) return NLOPT_MAXTIME_REACHED;
- if (nf < *npt) {
- goto L50;
- }
- return NLOPT_SUCCESS;
-} /* prelim_ */
-
-static nlopt_result bobyqb_(int *n, int *npt, double *x,
- const double *xl, const double *xu, double *rhobeg, double *
- rhoend,
- nlopt_stopping *stop,
- bobyqa_func calfun, void *calfun_data,
- double *minf,
- double *xbase,
- double *xpt, double *fval, double *xopt, double *gopt,
- double *hq, double *pq, double *bmat, double *zmat,
- int *ndim, double *sl, double *su, double *xnew,
- double *xalt, double *d__, double *vlag, double *w)
-{
- /* System generated locals */
- int xpt_dim1, xpt_offset, bmat_dim1, bmat_offset, zmat_dim1,
- zmat_offset, i__1, i__2, i__3;
- double d__1, d__2, d__3, d__4;
-
- /* Local variables */
- double f;
- int i__, j, k, ih, jj, nh, ip, jp;
- double dx;
- int np;
- double den, one, ten, dsq, rho, sum, two, diff, half, beta, gisq;
- int knew;
- double temp, suma, sumb, bsum, fopt;
- int kopt, nptm;
- double zero, curv;
- int ksav;
- double gqsq, dist, sumw, sumz, diffa, diffb, diffc, hdiag;
- int kbase;
- double alpha, delta, adelt, denom, fsave, bdtol, delsq;
- int nresc, nfsav;
- double ratio, dnorm, vquad, pqold, tenth;
- int itest;
- double sumpq, scaden;
- double errbig, cauchy, fracsq, biglsq, densav;
- double bdtest;
- double crvmin, frhosq;
- double distsq;
- int ntrits;
- double xoptsq;
-
- nlopt_result rc = NLOPT_SUCCESS, rc2;
-
-/* The arguments N, NPT, X, XL, XU, RHOBEG, RHOEND, and MAXFUN */
-/* are identical to the corresponding arguments in SUBROUTINE BOBYQA. */
-/* XBASE holds a shift of origin that should reduce the contributions */
-/* from rounding errors to values of the model and Lagrange functions. */
-/* XPT is a two-dimensional array that holds the coordinates of the */
-/* interpolation points relative to XBASE. */
-/* FVAL holds the values of F at the interpolation points. */
-/* XOPT is set to the displacement from XBASE of the trust region centre. */
-/* GOPT holds the gradient of the quadratic model at XBASE+XOPT. */
-/* HQ holds the explicit second derivatives of the quadratic model. */
-/* PQ contains the parameters of the implicit second derivatives of the */
-/* quadratic model. */
-/* BMAT holds the last N columns of H. */
-/* ZMAT holds the factorization of the leading NPT by NPT submatrix of H, */
-/* this factorization being ZMAT times ZMAT^T, which provides both the */
-/* correct rank and positive semi-definiteness. */
-/* NDIM is the first dimension of BMAT and has the value NPT+N. */
-/* SL and SU hold the differences XL-XBASE and XU-XBASE, respectively. */
-/* All the components of every XOPT are going to satisfy the bounds */
-/* SL(I) .LEQ. XOPT(I) .LEQ. SU(I), with appropriate equalities when */
-/* XOPT is on a constraint boundary. */
-/* XNEW is chosen by SUBROUTINE TRSBOX or ALTMOV. Usually XBASE+XNEW is the */
-/* vector of variables for the next call of CALFUN. XNEW also satisfies */
-/* the SL and SU constraints in the way that has just been mentioned. */
-/* XALT is an alternative to XNEW, chosen by ALTMOV, that may replace XNEW */
-/* in order to increase the denominator in the updating of UPDATE. */
-/* D is reserved for a trial step from XOPT, which is usually XNEW-XOPT. */
-/* VLAG contains the values of the Lagrange functions at a new point X. */
-/* They are part of a product that requires VLAG to be of length NDIM. */
-/* W is a one-dimensional array that is used for working space. Its length */
-/* must be at least 3*NDIM = 3*(NPT+N). */
-
-/* Set some constants. */
-
- /* Parameter adjustments */
- zmat_dim1 = *npt;
- zmat_offset = 1 + zmat_dim1;
- zmat -= zmat_offset;
- xpt_dim1 = *npt;
- xpt_offset = 1 + xpt_dim1;
- xpt -= xpt_offset;
- --x;
- --xl;
- --xu;
- --xbase;
- --fval;
- --xopt;
- --gopt;
- --hq;
- --pq;
- bmat_dim1 = *ndim;
- bmat_offset = 1 + bmat_dim1;
- bmat -= bmat_offset;
- --sl;
- --su;
- --xnew;
- --xalt;
- --d__;
- --vlag;
- --w;
-
- /* Function Body */
- half = .5;
- one = 1.;
- ten = 10.;
- tenth = .1;
- two = 2.;
- zero = 0.;
- np = *n + 1;
- nptm = *npt - np;
- nh = *n * np / 2;
-
-/* The call of PRELIM sets the elements of XBASE, XPT, FVAL, GOPT, HQ, PQ, */
-/* BMAT and ZMAT for the first iteration, with the corresponding values of */
-/* of NF and KOPT, which are the number of calls of CALFUN so far and the */
-/* index of the interpolation point at the trust region centre. Then the */
-/* initial XOPT is set too. The branch to label 720 occurs if MAXFUN is */
-/* less than NPT. GOPT will be updated if KOPT is different from KBASE. */
-
- rc2 = prelim_(n, npt, &x[1], &xl[1], &xu[1], rhobeg,
- stop, calfun, calfun_data,
- &xbase[1], &xpt[xpt_offset], &fval[1], &gopt[1], &hq[1], &pq[1], &bmat[
- bmat_offset], &zmat[zmat_offset], ndim, &sl[1], &su[1], &kopt);
- xoptsq = zero;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- xopt[i__] = xpt[kopt + i__ * xpt_dim1];
-/* L10: */
-/* Computing 2nd power */
- d__1 = xopt[i__];
- xoptsq += d__1 * d__1;
- }
- fsave = fval[1];
- if (rc2 != NLOPT_SUCCESS) {
- rc = rc2;
- goto L720;
- }
- kbase = 1;
-
-/* Complete the settings that are required for the iterative procedure. */
-
- rho = *rhobeg;
- delta = rho;
- nresc = stop->nevals;
- ntrits = 0;
- diffa = zero;
- diffb = zero;
- itest = 0;
- nfsav = stop->nevals;
-
-/* Update GOPT if necessary before the first iteration and after each */
-/* call of RESCUE that makes a call of CALFUN. */
-
-L20:
- if (kopt != kbase) {
- ih = 0;
- i__1 = *n;
- for (j = 1; j <= i__1; ++j) {
- i__2 = j;
- for (i__ = 1; i__ <= i__2; ++i__) {
- ++ih;
- if (i__ < j) {
- gopt[j] += hq[ih] * xopt[i__];
- }
-/* L30: */
- gopt[i__] += hq[ih] * xopt[j];
- }
- }
- if (stop->nevals > *npt) {
- i__2 = *npt;
- for (k = 1; k <= i__2; ++k) {
- temp = zero;
- i__1 = *n;
- for (j = 1; j <= i__1; ++j) {
-/* L40: */
- temp += xpt[k + j * xpt_dim1] * xopt[j];
- }
- temp = pq[k] * temp;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
-/* L50: */
- gopt[i__] += temp * xpt[k + i__ * xpt_dim1];
- }
- }
- }
- }
-
-/* Generate the next point in the trust region that provides a small value */
-/* of the quadratic model subject to the constraints on the variables. */
-/* The int NTRITS is set to the number "trust region" iterations that */
-/* have occurred since the last "alternative" iteration. If the length */
-/* of XNEW-XOPT is less than HALF*RHO, however, then there is a branch to */
-/* label 650 or 680 with NTRITS=-1, instead of calculating F at XNEW. */
-
-L60:
- trsbox_(n, npt, &xpt[xpt_offset], &xopt[1], &gopt[1], &hq[1], &pq[1], &sl[
- 1], &su[1], &delta, &xnew[1], &d__[1], &w[1], &w[np], &w[np + *n],
- &w[np + (*n << 1)], &w[np + *n * 3], &dsq, &crvmin);
-/* Computing MIN */
- d__1 = delta, d__2 = sqrt(dsq);
- dnorm = MIN2(d__1,d__2);
- if (dnorm < half * rho) {
- ntrits = -1;
-/* Computing 2nd power */
- d__1 = ten * rho;
- distsq = d__1 * d__1;
- if (stop->nevals <= nfsav + 2) {
- goto L650;
- }
-
-/* The following choice between labels 650 and 680 depends on whether or */
-/* not our work with the current RHO seems to be complete. Either RHO is */
-/* decreased or termination occurs if the errors in the quadratic model at */
-/* the last three interpolation points compare favourably with predictions */
-/* of likely improvements to the model within distance HALF*RHO of XOPT. */
-
-/* Computing MAX */
- d__1 = MAX2(diffa,diffb);
- errbig = MAX2(d__1,diffc);
- frhosq = rho * .125 * rho;
- if (crvmin > zero && errbig > frhosq * crvmin) {
- goto L650;
- }
- bdtol = errbig / rho;
- i__1 = *n;
- for (j = 1; j <= i__1; ++j) {
- bdtest = bdtol;
- if (xnew[j] == sl[j]) {
- bdtest = w[j];
- }
- if (xnew[j] == su[j]) {
- bdtest = -w[j];
- }
- if (bdtest < bdtol) {
- curv = hq[(j + j * j) / 2];
- i__2 = *npt;
- for (k = 1; k <= i__2; ++k) {
-/* L70: */
-/* Computing 2nd power */
- d__1 = xpt[k + j * xpt_dim1];
- curv += pq[k] * (d__1 * d__1);
- }
- bdtest += half * curv * rho;
- if (bdtest < bdtol) {
- goto L650;
- }
- }
-/* L80: */
- }
- goto L680;
- }
- ++ntrits;
-
-/* Severe cancellation is likely to occur if XOPT is too far from XBASE. */
-/* If the following test holds, then XBASE is shifted so that XOPT becomes */
-/* zero. The appropriate changes are made to BMAT and to the second */
-/* derivatives of the current model, beginning with the changes to BMAT */
-/* that do not depend on ZMAT. VLAG is used temporarily for working space. */
-
-L90:
- if (dsq <= xoptsq * .001) {
- fracsq = xoptsq * .25;
- sumpq = zero;
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
- sumpq += pq[k];
- sum = -half * xoptsq;
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
-/* L100: */
- sum += xpt[k + i__ * xpt_dim1] * xopt[i__];
- }
- w[*npt + k] = sum;
- temp = fracsq - half * sum;
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
- w[i__] = bmat[k + i__ * bmat_dim1];
- vlag[i__] = sum * xpt[k + i__ * xpt_dim1] + temp * xopt[i__];
- ip = *npt + i__;
- i__3 = i__;
- for (j = 1; j <= i__3; ++j) {
-/* L110: */
- bmat[ip + j * bmat_dim1] = bmat[ip + j * bmat_dim1] + w[
- i__] * vlag[j] + vlag[i__] * w[j];
- }
- }
- }
-
-/* Then the revisions of BMAT that depend on ZMAT are calculated. */
-
- i__3 = nptm;
- for (jj = 1; jj <= i__3; ++jj) {
- sumz = zero;
- sumw = zero;
- i__2 = *npt;
- for (k = 1; k <= i__2; ++k) {
- sumz += zmat[k + jj * zmat_dim1];
- vlag[k] = w[*npt + k] * zmat[k + jj * zmat_dim1];
-/* L120: */
- sumw += vlag[k];
- }
- i__2 = *n;
- for (j = 1; j <= i__2; ++j) {
- sum = (fracsq * sumz - half * sumw) * xopt[j];
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
-/* L130: */
- sum += vlag[k] * xpt[k + j * xpt_dim1];
- }
- w[j] = sum;
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
-/* L140: */
- bmat[k + j * bmat_dim1] += sum * zmat[k + jj * zmat_dim1];
- }
- }
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- ip = i__ + *npt;
- temp = w[i__];
- i__2 = i__;
- for (j = 1; j <= i__2; ++j) {
-/* L150: */
- bmat[ip + j * bmat_dim1] += temp * w[j];
- }
- }
- }
-
-/* The following instructions complete the shift, including the changes */
-/* to the second derivative parameters of the quadratic model. */
-
- ih = 0;
- i__2 = *n;
- for (j = 1; j <= i__2; ++j) {
- w[j] = -half * sumpq * xopt[j];
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
- w[j] += pq[k] * xpt[k + j * xpt_dim1];
-/* L160: */
- xpt[k + j * xpt_dim1] -= xopt[j];
- }
- i__1 = j;
- for (i__ = 1; i__ <= i__1; ++i__) {
- ++ih;
- hq[ih] = hq[ih] + w[i__] * xopt[j] + xopt[i__] * w[j];
-/* L170: */
- bmat[*npt + i__ + j * bmat_dim1] = bmat[*npt + j + i__ *
- bmat_dim1];
- }
- }
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- xbase[i__] += xopt[i__];
- xnew[i__] -= xopt[i__];
- sl[i__] -= xopt[i__];
- su[i__] -= xopt[i__];
-/* L180: */
- xopt[i__] = zero;
- }
- xoptsq = zero;
- }
- if (ntrits == 0) {
- goto L210;
- }
- goto L230;
-
-/* XBASE is also moved to XOPT by a call of RESCUE. This calculation is */
-/* more expensive than the previous shift, because new matrices BMAT and */
-/* ZMAT are generated from scratch, which may include the replacement of */
-/* interpolation points whose positions seem to be causing near linear */
-/* dependence in the interpolation conditions. Therefore RESCUE is called */
-/* only if rounding errors have reduced by at least a factor of two the */
-/* denominator of the formula for updating the H matrix. It provides a */
-/* useful safeguard, but is not invoked in most applications of BOBYQA. */
-
-L190:
- nfsav = stop->nevals;
- kbase = kopt;
- rc2 = rescue_(n, npt, &xl[1], &xu[1],
- stop, calfun, calfun_data,
- &xbase[1], &xpt[xpt_offset], &fval[1], &xopt[1], &gopt[1],
- &hq[1], &pq[1], &bmat[bmat_offset], &zmat[zmat_offset], ndim,
- &sl[1], &su[1], &delta, &kopt, &vlag[1],
- &w[1], &w[*n + np], &w[*ndim + np]);
-
-/* XOPT is updated now in case the branch below to label 720 is taken. */
-/* Any updating of GOPT occurs after the branch below to label 20, which */
-/* leads to a trust region iteration as does the branch to label 60. */
-
- xoptsq = zero;
- if (kopt != kbase) {
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- xopt[i__] = xpt[kopt + i__ * xpt_dim1];
-/* L200: */
-/* Computing 2nd power */
- d__1 = xopt[i__];
- xoptsq += d__1 * d__1;
- }
- }
- if (rc2 != NLOPT_SUCCESS) {
- rc = rc2;
- goto L720;
- }
- nresc = stop->nevals;
- if (nfsav < stop->nevals) {
- nfsav = stop->nevals;
- goto L20;
- }
- if (ntrits > 0) {
- goto L60;
- }
-
-/* Pick two alternative vectors of variables, relative to XBASE, that */
-/* are suitable as new positions of the KNEW-th interpolation point. */
-/* Firstly, XNEW is set to the point on a line through XOPT and another */
-/* interpolation point that minimizes the predicted value of the next */
-/* denominator, subject to ||XNEW - XOPT|| .LEQ. ADELT and to the SL */
-/* and SU bounds. Secondly, XALT is set to the best feasible point on */
-/* a constrained version of the Cauchy step of the KNEW-th Lagrange */
-/* function, the corresponding value of the square of this function */
-/* being returned in CAUCHY. The choice between these alternatives is */
-/* going to be made when the denominator is calculated. */
-
-L210:
- altmov_(n, npt, &xpt[xpt_offset], &xopt[1], &bmat[bmat_offset], &zmat[
- zmat_offset], ndim, &sl[1], &su[1], &kopt, &knew, &adelt, &xnew[1]
- , &xalt[1], &alpha, &cauchy, &w[1], &w[np], &w[*ndim + 1]);
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
-/* L220: */
- d__[i__] = xnew[i__] - xopt[i__];
- }
-
-/* Calculate VLAG and BETA for the current choice of D. The scalar */
-/* product of D with XPT(K,.) is going to be held in W(NPT+K) for */
-/* use when VQUAD is calculated. */
-
-L230:
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
- suma = zero;
- sumb = zero;
- sum = zero;
- i__2 = *n;
- for (j = 1; j <= i__2; ++j) {
- suma += xpt[k + j * xpt_dim1] * d__[j];
- sumb += xpt[k + j * xpt_dim1] * xopt[j];
-/* L240: */
- sum += bmat[k + j * bmat_dim1] * d__[j];
- }
- w[k] = suma * (half * suma + sumb);
- vlag[k] = sum;
-/* L250: */
- w[*npt + k] = suma;
- }
- beta = zero;
- i__1 = nptm;
- for (jj = 1; jj <= i__1; ++jj) {
- sum = zero;
- i__2 = *npt;
- for (k = 1; k <= i__2; ++k) {
-/* L260: */
- sum += zmat[k + jj * zmat_dim1] * w[k];
- }
- beta -= sum * sum;
- i__2 = *npt;
- for (k = 1; k <= i__2; ++k) {
-/* L270: */
- vlag[k] += sum * zmat[k + jj * zmat_dim1];
- }
- }
- dsq = zero;
- bsum = zero;
- dx = zero;
- i__2 = *n;
- for (j = 1; j <= i__2; ++j) {
-/* Computing 2nd power */
- d__1 = d__[j];
- dsq += d__1 * d__1;
- sum = zero;
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
-/* L280: */
- sum += w[k] * bmat[k + j * bmat_dim1];
- }
- bsum += sum * d__[j];
- jp = *npt + j;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
-/* L290: */
- sum += bmat[jp + i__ * bmat_dim1] * d__[i__];
- }
- vlag[jp] = sum;
- bsum += sum * d__[j];
-/* L300: */
- dx += d__[j] * xopt[j];
- }
- beta = dx * dx + dsq * (xoptsq + dx + dx + half * dsq) + beta - bsum;
- vlag[kopt] += one;
-
-/* If NTRITS is zero, the denominator may be increased by replacing */
-/* the step D of ALTMOV by a Cauchy step. Then RESCUE may be called if */
-/* rounding errors have damaged the chosen denominator. */
-
- if (ntrits == 0) {
-/* Computing 2nd power */
- d__1 = vlag[knew];
- denom = d__1 * d__1 + alpha * beta;
- if (denom < cauchy && cauchy > zero) {
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
- xnew[i__] = xalt[i__];
-/* L310: */
- d__[i__] = xnew[i__] - xopt[i__];
- }
- cauchy = zero;
- goto L230;
- }
-/* Computing 2nd power */
- d__1 = vlag[knew];
- if (denom <= half * (d__1 * d__1)) {
- if (stop->nevals > nresc) {
- goto L190;
- }
- /* Return from BOBYQA because of much cancellation in a
- denominator. */
- rc = NLOPT_ROUNDOFF_LIMITED;
- goto L720;
- }
-
-/* Alternatively, if NTRITS is positive, then set KNEW to the index of */
-/* the next interpolation point to be deleted to make room for a trust */
-/* region step. Again RESCUE may be called if rounding errors have damaged */
-/* the chosen denominator, which is the reason for attempting to select */
-/* KNEW before calculating the next value of the objective function. */
-
- } else {
- delsq = delta * delta;
- scaden = zero;
- biglsq = zero;
- knew = 0;
- i__2 = *npt;
- for (k = 1; k <= i__2; ++k) {
- if (k == kopt) {
- goto L350;
- }
- hdiag = zero;
- i__1 = nptm;
- for (jj = 1; jj <= i__1; ++jj) {
-/* L330: */
-/* Computing 2nd power */
- d__1 = zmat[k + jj * zmat_dim1];
- hdiag += d__1 * d__1;
- }
-/* Computing 2nd power */
- d__1 = vlag[k];
- den = beta * hdiag + d__1 * d__1;
- distsq = zero;
- i__1 = *n;
- for (j = 1; j <= i__1; ++j) {
-/* L340: */
-/* Computing 2nd power */
- d__1 = xpt[k + j * xpt_dim1] - xopt[j];
- distsq += d__1 * d__1;
- }
-/* Computing MAX */
-/* Computing 2nd power */
- d__3 = distsq / delsq;
- d__1 = one, d__2 = d__3 * d__3;
- temp = MAX2(d__1,d__2);
- if (temp * den > scaden) {
- scaden = temp * den;
- knew = k;
- denom = den;
- }
-/* Computing MAX */
-/* Computing 2nd power */
- d__3 = vlag[k];
- d__1 = biglsq, d__2 = temp * (d__3 * d__3);
- biglsq = MAX2(d__1,d__2);
-L350:
- ;
- }
- if (scaden <= half * biglsq) {
- if (stop->nevals > nresc) {
- goto L190;
- }
- /* Return from BOBYQA because of much cancellation in a
- denominator. */
- rc = NLOPT_ROUNDOFF_LIMITED;
- goto L720;
- }
- }
-
-/* Put the variables for the next calculation of the objective function */
-/* in XNEW, with any adjustments for the bounds. */
-
-
-/* Calculate the value of the objective function at XBASE+XNEW, unless */
-/* the limit on the number of calculations of F has been reached. */
-
-L360:
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
-/* Computing MIN */
-/* Computing MAX */
- d__3 = xl[i__], d__4 = xbase[i__] + xnew[i__];
- d__1 = MAX2(d__3,d__4), d__2 = xu[i__];
- x[i__] = MIN2(d__1,d__2);
- if (xnew[i__] == sl[i__]) {
- x[i__] = xl[i__];
- }
- if (xnew[i__] == su[i__]) {
- x[i__] = xu[i__];
- }
-/* L380: */
- }
-
- if (nlopt_stop_forced(stop)) rc = NLOPT_FORCED_STOP;
- else if (nlopt_stop_evals(stop)) rc = NLOPT_MAXEVAL_REACHED;
- else if (nlopt_stop_time(stop)) rc = NLOPT_MAXTIME_REACHED;
- if (rc != NLOPT_SUCCESS) goto L720;
-
- stop->nevals++;
- f = calfun(*n, &x[1], calfun_data);
- if (ntrits == -1) {
- fsave = f;
- rc = NLOPT_XTOL_REACHED;
- if (fsave < fval[kopt]) { *minf = f; return rc; }
- goto L720;
- }
-
- if (f < stop->minf_max) {
- *minf = f;
- return NLOPT_MINF_MAX_REACHED;
- }
-
-/* Use the quadratic model to predict the change in F due to the step D, */
-/* and set DIFF to the error of this prediction. */
-
- fopt = fval[kopt];
- vquad = zero;
- ih = 0;
- i__2 = *n;
- for (j = 1; j <= i__2; ++j) {
- vquad += d__[j] * gopt[j];
- i__1 = j;
- for (i__ = 1; i__ <= i__1; ++i__) {
- ++ih;
- temp = d__[i__] * d__[j];
- if (i__ == j) {
- temp = half * temp;
- }
-/* L410: */
- vquad += hq[ih] * temp;
- }
- }
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
-/* L420: */
-/* Computing 2nd power */
- d__1 = w[*npt + k];
- vquad += half * pq[k] * (d__1 * d__1);
- }
- diff = f - fopt - vquad;
- diffc = diffb;
- diffb = diffa;
- diffa = fabs(diff);
- if (dnorm > rho) {
- nfsav = stop->nevals;
- }
-
-/* Pick the next value of DELTA after a trust region step. */
-
- if (ntrits > 0) {
- if (vquad >= zero) {
- /* Return from BOBYQA because a trust region step has failed
- to reduce Q. */
- rc = NLOPT_ROUNDOFF_LIMITED; /* or FTOL_REACHED? */
- goto L720;
- }
- ratio = (f - fopt) / vquad;
- if (ratio <= tenth) {
-/* Computing MIN */
- d__1 = half * delta;
- delta = MIN2(d__1,dnorm);
- } else if (ratio <= .7) {
-/* Computing MAX */
- d__1 = half * delta;
- delta = MAX2(d__1,dnorm);
- } else {
-/* Computing MAX */
- d__1 = half * delta, d__2 = dnorm + dnorm;
- delta = MAX2(d__1,d__2);
- }
- if (delta <= rho * 1.5) {
- delta = rho;
- }
-
-/* Recalculate KNEW and DENOM if the new F is less than FOPT. */
-
- if (f < fopt) {
- ksav = knew;
- densav = denom;
- delsq = delta * delta;
- scaden = zero;
- biglsq = zero;
- knew = 0;
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
- hdiag = zero;
- i__2 = nptm;
- for (jj = 1; jj <= i__2; ++jj) {
-/* L440: */
-/* Computing 2nd power */
- d__1 = zmat[k + jj * zmat_dim1];
- hdiag += d__1 * d__1;
- }
-/* Computing 2nd power */
- d__1 = vlag[k];
- den = beta * hdiag + d__1 * d__1;
- distsq = zero;
- i__2 = *n;
- for (j = 1; j <= i__2; ++j) {
-/* L450: */
-/* Computing 2nd power */
- d__1 = xpt[k + j * xpt_dim1] - xnew[j];
- distsq += d__1 * d__1;
- }
-/* Computing MAX */
-/* Computing 2nd power */
- d__3 = distsq / delsq;
- d__1 = one, d__2 = d__3 * d__3;
- temp = MAX2(d__1,d__2);
- if (temp * den > scaden) {
- scaden = temp * den;
- knew = k;
- denom = den;
- }
-/* L460: */
-/* Computing MAX */
-/* Computing 2nd power */
- d__3 = vlag[k];
- d__1 = biglsq, d__2 = temp * (d__3 * d__3);
- biglsq = MAX2(d__1,d__2);
- }
- if (scaden <= half * biglsq) {
- knew = ksav;
- denom = densav;
- }
- }
- }
-
-/* Update BMAT and ZMAT, so that the KNEW-th interpolation point can be */
-/* moved. Also update the second derivative terms of the model. */
-
- update_(n, npt, &bmat[bmat_offset], &zmat[zmat_offset], ndim, &vlag[1], &
- beta, &denom, &knew, &w[1]);
- ih = 0;
- pqold = pq[knew];
- pq[knew] = zero;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- temp = pqold * xpt[knew + i__ * xpt_dim1];
- i__2 = i__;
- for (j = 1; j <= i__2; ++j) {
- ++ih;
-/* L470: */
- hq[ih] += temp * xpt[knew + j * xpt_dim1];
- }
- }
- i__2 = nptm;
- for (jj = 1; jj <= i__2; ++jj) {
- temp = diff * zmat[knew + jj * zmat_dim1];
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
-/* L480: */
- pq[k] += temp * zmat[k + jj * zmat_dim1];
- }
- }
-
-/* Include the new interpolation point, and make the changes to GOPT at */
-/* the old XOPT that are caused by the updating of the quadratic model. */
-
- fval[knew] = f;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- xpt[knew + i__ * xpt_dim1] = xnew[i__];
-/* L490: */
- w[i__] = bmat[knew + i__ * bmat_dim1];
- }
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
- suma = zero;
- i__2 = nptm;
- for (jj = 1; jj <= i__2; ++jj) {
-/* L500: */
- suma += zmat[knew + jj * zmat_dim1] * zmat[k + jj * zmat_dim1];
- }
- if (nlopt_isinf(suma)) {
- /* SGJ: detect singularity here (happend if we run
- for too many iterations) ... is there another way to recover? */
- rc = NLOPT_ROUNDOFF_LIMITED;
- goto L720;
- }
- sumb = zero;
- i__2 = *n;
- for (j = 1; j <= i__2; ++j) {
-/* L510: */
- sumb += xpt[k + j * xpt_dim1] * xopt[j];
- }
- temp = suma * sumb;
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
-/* L520: */
- w[i__] += temp * xpt[k + i__ * xpt_dim1];
- }
- }
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
-/* L530: */
- gopt[i__] += diff * w[i__];
- }
-
-/* Update XOPT, GOPT and KOPT if the new calculated F is less than FOPT. */
-
- if (f < fopt) {
- kopt = knew;
- xoptsq = zero;
- ih = 0;
- i__2 = *n;
- for (j = 1; j <= i__2; ++j) {
- xopt[j] = xnew[j];
-/* Computing 2nd power */
- d__1 = xopt[j];
- xoptsq += d__1 * d__1;
- i__1 = j;
- for (i__ = 1; i__ <= i__1; ++i__) {
- ++ih;
- if (i__ < j) {
- gopt[j] += hq[ih] * d__[i__];
- }
-/* L540: */
- gopt[i__] += hq[ih] * d__[j];
- }
- }
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
- temp = zero;
- i__2 = *n;
- for (j = 1; j <= i__2; ++j) {
-/* L550: */
- temp += xpt[k + j * xpt_dim1] * d__[j];
- }
- temp = pq[k] * temp;
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
-/* L560: */
- gopt[i__] += temp * xpt[k + i__ * xpt_dim1];
- }
- }
- if (nlopt_stop_ftol(stop, f, fopt)) {
- rc = NLOPT_FTOL_REACHED;
- goto L720;
- }
- }
-
-/* Calculate the parameters of the least Frobenius norm interpolant to */
-/* the current data, the gradient of this interpolant at XOPT being put */
-/* into VLAG(NPT+I), I=1,2,...,N. */
-
- if (ntrits > 0) {
- i__2 = *npt;
- for (k = 1; k <= i__2; ++k) {
- vlag[k] = fval[k] - fval[kopt];
-/* L570: */
- w[k] = zero;
- }
- i__2 = nptm;
- for (j = 1; j <= i__2; ++j) {
- sum = zero;
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
-/* L580: */
- sum += zmat[k + j * zmat_dim1] * vlag[k];
- }
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
-/* L590: */
- w[k] += sum * zmat[k + j * zmat_dim1];
- }
- }
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
- sum = zero;
- i__2 = *n;
- for (j = 1; j <= i__2; ++j) {
-/* L600: */
- sum += xpt[k + j * xpt_dim1] * xopt[j];
- }
- w[k + *npt] = w[k];
-/* L610: */
- w[k] = sum * w[k];
- }
- gqsq = zero;
- gisq = zero;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- sum = zero;
- i__2 = *npt;
- for (k = 1; k <= i__2; ++k) {
-/* L620: */
- sum = sum + bmat[k + i__ * bmat_dim1] * vlag[k] + xpt[k + i__
- * xpt_dim1] * w[k];
- }
- if (xopt[i__] == sl[i__]) {
-/* Computing MIN */
- d__2 = zero, d__3 = gopt[i__];
-/* Computing 2nd power */
- d__1 = MIN2(d__2,d__3);
- gqsq += d__1 * d__1;
-/* Computing 2nd power */
- d__1 = MIN2(zero,sum);
- gisq += d__1 * d__1;
- } else if (xopt[i__] == su[i__]) {
-/* Computing MAX */
- d__2 = zero, d__3 = gopt[i__];
-/* Computing 2nd power */
- d__1 = MAX2(d__2,d__3);
- gqsq += d__1 * d__1;
-/* Computing 2nd power */
- d__1 = MAX2(zero,sum);
- gisq += d__1 * d__1;
- } else {
-/* Computing 2nd power */
- d__1 = gopt[i__];
- gqsq += d__1 * d__1;
- gisq += sum * sum;
- }
-/* L630: */
- vlag[*npt + i__] = sum;
- }
-
-/* Test whether to replace the new quadratic model by the least Frobenius */
-/* norm interpolant, making the replacement if the test is satisfied. */
-
- ++itest;
- if (gqsq < ten * gisq) {
- itest = 0;
- }
- if (itest >= 3) {
- i__1 = MAX2(*npt,nh);
- for (i__ = 1; i__ <= i__1; ++i__) {
- if (i__ <= *n) {
- gopt[i__] = vlag[*npt + i__];
- }
- if (i__ <= *npt) {
- pq[i__] = w[*npt + i__];
- }
- if (i__ <= nh) {
- hq[i__] = zero;
- }
- itest = 0;
-/* L640: */
- }
- }
- }
-
-/* If a trust region step has provided a sufficient decrease in F, then */
-/* branch for another trust region calculation. The case NTRITS=0 occurs */
-/* when the new interpolation point was reached by an alternative step. */
-
- if (ntrits == 0) {
- goto L60;
- }
- if (f <= fopt + tenth * vquad) {
- goto L60;
- }
-
-/* Alternatively, find out if the interpolation points are close enough */
-/* to the best point so far. */
-
-/* Computing MAX */
-/* Computing 2nd power */
- d__3 = two * delta;
-/* Computing 2nd power */
- d__4 = ten * rho;
- d__1 = d__3 * d__3, d__2 = d__4 * d__4;
- distsq = MAX2(d__1,d__2);
-L650:
- knew = 0;
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
- sum = zero;
- i__2 = *n;
- for (j = 1; j <= i__2; ++j) {
-/* L660: */
-/* Computing 2nd power */
- d__1 = xpt[k + j * xpt_dim1] - xopt[j];
- sum += d__1 * d__1;
- }
- if (sum > distsq) {
- knew = k;
- distsq = sum;
- }
-/* L670: */
- }
-
-/* If KNEW is positive, then ALTMOV finds alternative new positions for */
-/* the KNEW-th interpolation point within distance ADELT of XOPT. It is */
-/* reached via label 90. Otherwise, there is a branch to label 60 for */
-/* another trust region iteration, unless the calculations with the */
-/* current RHO are complete. */
-
- if (knew > 0) {
- dist = sqrt(distsq);
- if (ntrits == -1) {
-/* Computing MIN */
- d__1 = tenth * delta, d__2 = half * dist;
- delta = MIN2(d__1,d__2);
- if (delta <= rho * 1.5) {
- delta = rho;
- }
- }
- ntrits = 0;
-/* Computing MAX */
-/* Computing MIN */
- d__2 = tenth * dist;
- d__1 = MIN2(d__2,delta);
- adelt = MAX2(d__1,rho);
- dsq = adelt * adelt;
- goto L90;
- }
- if (ntrits == -1) {
- goto L680;
- }
- if (ratio > zero) {
- goto L60;
- }
- if (MAX2(delta,dnorm) > rho) {
- goto L60;
- }
-
-/* The calculations with the current value of RHO are complete. Pick the */
-/* next values of RHO and DELTA. */
-
-L680:
- if (rho > *rhoend) {
- delta = half * rho;
- ratio = rho / *rhoend;
- if (ratio <= 16.) {
- rho = *rhoend;
- } else if (ratio <= 250.) {
- rho = sqrt(ratio) * *rhoend;
- } else {
- rho = tenth * rho;
- }
- delta = MAX2(delta,rho);
- ntrits = 0;
- nfsav = stop->nevals;
- goto L60;
- }
-
-/* Return from the calculation, after another Newton-Raphson step, if */
-/* it is too short to have been tried before. */
-
- if (ntrits == -1) {
- goto L360;
- }
-L720:
- /* originally: if (fval[kopt] <= fsave) -- changed by SGJ, since
- this seems like a slight optimization to not update x[]
- unnecessarily, at the expense of possibly not returning the
- best x[] found so far if the algorithm is stopped suddenly
- (e.g. runs out of time) ... it seems safer to execute this
- unconditionally, and the efficiency loss seems negligible. */
- {
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
-/* Computing MIN */
-/* Computing MAX */
- d__3 = xl[i__], d__4 = xbase[i__] + xopt[i__];
- d__1 = MAX2(d__3,d__4), d__2 = xu[i__];
- x[i__] = MIN2(d__1,d__2);
- if (xopt[i__] == sl[i__]) {
- x[i__] = xl[i__];
- }
- if (xopt[i__] == su[i__]) {
- x[i__] = xu[i__];
- }
-/* L730: */
- }
- f = fval[kopt];
- }
- *minf = f;
- return rc;
-} /* bobyqb_ */
-
-/**************************************************************************/
-
-#define U(n) ((unsigned) (n))
-
-typedef struct {
- double *s, *xs;
- nlopt_func f; void *f_data;
-} rescale_fun_data;
-
-static double rescale_fun(int n, const double *x, void *d_)
-{
- rescale_fun_data *d = (rescale_fun_data*) d_;
- nlopt_unscale(U(n), d->s, x, d->xs);
- return d->f(U(n), d->xs, NULL, d->f_data);
-}
-
-nlopt_result bobyqa(int n, int npt, double *x,
- const double *xl, const double *xu,
- const double *dx,
- nlopt_stopping *stop, double *minf,
- nlopt_func f, void *f_data)
-{
- /* System generated locals */
- int i__1;
- double d__1, d__2;
-
- /* Local variables */
- int j, id, np, iw, igo, ihq, ixb, ixa, ifv, isl, jsl, ipq, ivl, ixn,
- ixo, ixp, isu, jsu, ndim;
- double temp, zero;
- int ibmat, izmat;
-
- double rhobeg, rhoend;
- double *w0 = NULL, *w;
- nlopt_result ret;
- double *s = NULL, *sxl = NULL, *sxu = NULL, *xs = NULL;
- rescale_fun_data calfun_data;
-
- /* SGJ 2010: rescale parameters to make the initial step sizes dx
- equal in all directions */
- s = nlopt_compute_rescaling(U(n), dx);
- if (!s) return NLOPT_OUT_OF_MEMORY;
-
- /* this statement must go before goto done, so that --x occurs */
- nlopt_rescale(U(n), s, x, x); --x;
-
- xs = (double *) malloc(sizeof(double) * (U(n)));
-
- sxl = nlopt_new_rescaled(U(n), s, xl);
- if (!sxl) { ret = NLOPT_OUT_OF_MEMORY; goto done; }
- xl = sxl;
- sxu = nlopt_new_rescaled(U(n), s, xu);
- if (!sxu) { ret = NLOPT_OUT_OF_MEMORY; goto done; }
- xu = sxu;
- nlopt_reorder_bounds(n, sxl, sxu);
-
- rhobeg = fabs(dx[0] / s[0]); /* equals all other dx[i] after rescaling */
-
- calfun_data.s = s;
- calfun_data.xs = xs;
- calfun_data.f = f;
- calfun_data.f_data = f_data;
-
- /* SGJ, 2009: compute rhoend from NLopt stop info */
- rhoend = stop->xtol_rel * (rhobeg);
- for (j = 0; j < n; ++j)
- if (rhoend < stop->xtol_abs[j] / fabs(s[j]))
- rhoend = stop->xtol_abs[j] / fabs(s[j]);
-
-
-/* This subroutine seeks the least value of a function of many variables, */
-/* by applying a trust region method that forms quadratic models by */
-/* interpolation. There is usually some freedom in the interpolation */
-/* conditions, which is taken up by minimizing the Frobenius norm of */
-/* the change to the second derivative of the model, beginning with the */
-/* zero matrix. The values of the variables are constrained by upper and */
-/* lower bounds. The arguments of the subroutine are as follows. */
-
-/* N must be set to the number of variables and must be at least two. */
-/* NPT is the number of interpolation conditions. Its value must be in */
-/* the interval [N+2,(N+1)(N+2)/2]. Choices that exceed 2*N+1 are not */
-/* recommended. */
-/* Initial values of the variables must be set in X(1),X(2),...,X(N). They */
-/* will be changed to the values that give the least calculated F. */
-/* For I=1,2,...,N, XL(I) and XU(I) must provide the lower and upper */
-/* bounds, respectively, on X(I). The construction of quadratic models */
-/* requires XL(I) to be strictly less than XU(I) for each I. Further, */
-/* the contribution to a model from changes to the I-th variable is */
-/* damaged severely by rounding errors if XU(I)-XL(I) is too small. */
-/* RHOBEG and RHOEND must be set to the initial and final values of a trust */
-/* region radius, so both must be positive with RHOEND no greater than */
-/* RHOBEG. Typically, RHOBEG should be about one tenth of the greatest */
-/* expected change to a variable, while RHOEND should indicate the */
-/* accuracy that is required in the final values of the variables. An */
-/* error return occurs if any of the differences XU(I)-XL(I), I=1,...,N, */
-/* is less than 2*RHOBEG. */
-/* MAXFUN must be set to an upper bound on the number of calls of CALFUN. */
-/* The array W will be used for working space. Its length must be at least */
-/* (NPT+5)*(NPT+N)+3*N*(N+5)/2. */
-
-/* SUBROUTINE CALFUN (N,X,F) has to be provided by the user. It must set */
-/* F to the value of the objective function for the current values of the */
-/* variables X(1),X(2),...,X(N), which are generated automatically in a */
-/* way that satisfies the bounds given in XL and XU. */
-
-/* Return if the value of NPT is unacceptable. */
-
- /* Parameter adjustments */
- --xu;
- --xl;
-
- /* Function Body */
- np = n + 1;
- if (npt < n + 2 || npt > (n + 2) * np / 2) {
- /* Return from BOBYQA because NPT is not in the required interval */
- ret = NLOPT_INVALID_ARGS;
- goto done;
- }
-
-/* Partition the working space array, so that different parts of it can */
-/* be treated separately during the calculation of BOBYQB. The partition */
-/* requires the first (NPT+2)*(NPT+N)+3*N*(N+5)/2 elements of W plus the */
-/* space that is taken by the last array in the argument list of BOBYQB. */
-
- ndim = npt + n;
- ixb = 1;
- ixp = ixb + n;
- ifv = ixp + n * npt;
- ixo = ifv + npt;
- igo = ixo + n;
- ihq = igo + n;
- ipq = ihq + n * np / 2;
- ibmat = ipq + npt;
- izmat = ibmat + ndim * n;
- isl = izmat + npt * (npt - np);
- isu = isl + n;
- ixn = isu + n;
- ixa = ixn + n;
- id = ixa + n;
- ivl = id + n;
- iw = ivl + ndim;
-
- w0 = (double *) malloc(sizeof(double) * U((npt+5)*(npt+n)+3*n*(n+5)/2));
- if (!w0) { ret = NLOPT_OUT_OF_MEMORY; goto done; }
- w = w0 - 1;
-
-/* Return if there is insufficient space between the bounds. Modify the */
-/* initial X if necessary in order to avoid conflicts between the bounds */
-/* and the construction of the first quadratic model. The lower and upper */
-/* bounds on moves from the updated X are set now, in the ISL and ISU */
-/* partitions of W, in order to provide useful and exact information about */
-/* components of X that become within distance RHOBEG from their bounds. */
-
- zero = 0.;
- i__1 = n;
- for (j = 1; j <= i__1; ++j) {
- temp = xu[j] - xl[j];
- if (temp < rhobeg + rhobeg) {
- /* Return from BOBYQA because one of the differences
- XU(I)-XL(I)s is less than 2*RHOBEG. */
- ret = NLOPT_INVALID_ARGS;
- goto done;
- }
- jsl = isl + j - 1;
- jsu = jsl + n;
- w[jsl] = xl[j] - x[j];
- w[jsu] = xu[j] - x[j];
- if (w[jsl] >= -(rhobeg)) {
- if (w[jsl] >= zero) {
- x[j] = xl[j];
- w[jsl] = zero;
- w[jsu] = temp;
- } else {
- x[j] = xl[j] + rhobeg;
- w[jsl] = -(rhobeg);
-/* Computing MAX */
- d__1 = xu[j] - x[j];
- w[jsu] = MAX2(d__1,rhobeg);
- }
- } else if (w[jsu] <= rhobeg) {
- if (w[jsu] <= zero) {
- x[j] = xu[j];
- w[jsl] = -temp;
- w[jsu] = zero;
- } else {
- x[j] = xu[j] - rhobeg;
-/* Computing MIN */
- d__1 = xl[j] - x[j], d__2 = -(rhobeg);
- w[jsl] = MIN2(d__1,d__2);
- w[jsu] = rhobeg;
- }
- }
-/* L30: */
- }
-
-/* Make the call of BOBYQB. */
-
- ret = bobyqb_(&n, &npt, &x[1], &xl[1], &xu[1], &rhobeg, &rhoend,
- stop, rescale_fun, &calfun_data, minf,
- &w[ixb], &w[ixp], &w[ifv], &w[ixo], &w[igo], &w[ihq], &w[ipq],
- &w[ibmat], &w[izmat], &ndim, &w[isl], &w[isu], &w[ixn], &w[ixa],
- &w[id], &w[ivl], &w[iw]);
-
-done:
- free(w0);
- free(sxl);
- free(sxu);
- free(xs);
- ++x; nlopt_unscale(U(n), s, x, x);
- free(s);
- return ret;
-} /* bobyqa_ */
-
diff --git a/ext/src/nlopt/cdirect/README b/ext/src/nlopt/cdirect/README
deleted file mode 100644
index 0685c93..0000000
--- a/ext/src/nlopt/cdirect/README
+++ /dev/null
@@ -1,26 +0,0 @@
-From-scratch re-implementation of the DIRECT and DIRECT-L algorithms
-described in:
-
- D. R. Jones, C. D. Perttunen, and B. E. Stuckmann,
- "Lipschitzian optimization without the lipschitz constant,"
- J. Optimization Theory and Applications, vol. 79, p. 157 (1993).
-
- J. M. Gablonsky and C. T. Kelley, "A locally-biased form
- of the DIRECT algorithm," J. Global Optimization 21 (1),
- p. 27-37 (2001).
-
-I re-implemented the algorithms for a couple of reasons. First,
-because I was interested in the algorithms and wanted to play with
-them by trying some variations (originally, because I wanted to
-experiment with a hybrid approach combining DIRECT with local search
-algorithms, see hybrid.c). Second, I wanted to remove some arbitrary
-restrictions in the original Fortran code, e.g. a fixed upper bound on
-the number of function evaluations. Third, because it was fun to
-code. As far as I can tell, my version converges in about the same
-number of iterations as Gablonsky's code (with occasional slight
-differences due to minor differences in how I break ties, etc.).
-
-The code in this directory is under the same MIT license as the rest
-of my code in NLopt (see ../COPYRIGHT).
-
-Steven G. Johnson
diff --git a/ext/src/nlopt/cdirect/cdirect.c b/ext/src/nlopt/cdirect/cdirect.c
deleted file mode 100644
index caba6b6..0000000
--- a/ext/src/nlopt/cdirect/cdirect.c
+++ /dev/null
@@ -1,600 +0,0 @@
-/* Copyright (c) 2007-2012 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "nlopt/nlopt-util.h"
-#include "nlopt/nlopt.h"
-#include "nlopt/cdirect.h"
-#include "nlopt/redblack.h"
-
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-#define MAX(a,b) ((a) > (b) ? (a) : (b))
-
-/***************************************************************************/
-/* basic data structure:
- *
- * a hyper-rectangle is stored as an array of length L = 2n+3, where [1]
- * is the value (f) of the function at the center, [0] is the "size"
- * measure (d) of the rectangle, [3..n+2] are the coordinates of the
- * center (c), [n+3..2n+2] are the widths of the sides (w), and [2]
- * is an "age" measure for tie-breaking purposes.
- *
- * we store the hyper-rectangles in a red-black tree, sorted by (d,f)
- * in lexographic order, to allow us to perform quick convex-hull
- * calculations (in the future, we might make this data structure
- * more sophisticated based on the dynamic convex-hull literature).
- *
- * n > 0 always, of course.
- */
-
-/* parameters of the search algorithm and various information that
- needs to be passed around */
-typedef struct {
- int n; /* dimension */
- int L; /* size of each rectangle (2n+3) */
- double magic_eps; /* Jones' epsilon parameter (1e-4 is recommended) */
- int which_diam; /* which measure of hyper-rectangle diam to use:
- 0 = Jones, 1 = Gablonsky */
- int which_div; /* which way to divide rects:
- 0: orig. Jones (divide all longest sides)
- 1: Gablonsky (cubes divide all, rects longest)
- 2: Jones Encyc. Opt.: pick random longest side */
- int which_opt; /* which rects are considered "potentially optimal"
- 0: Jones (all pts on cvx hull, even equal pts)
- 1: Gablonsky DIRECT-L (pick one pt, if equal pts)
- 2: ~ 1, but pick points randomly if equal pts
- ... 2 seems to suck compared to just picking oldest pt */
-
- const double *lb, *ub;
- nlopt_stopping *stop; /* stopping criteria */
- nlopt_func f; void *f_data;
- double *work; /* workspace, of length >= 2*n */
- int *iwork; /* workspace, length >= n */
- double minf, *xmin; /* minimum so far */
-
- /* red-black tree of hyperrects, sorted by (d,f,age) in
- lexographical order */
- rb_tree rtree;
- int age; /* age for next new rect */
- double **hull; /* array to store convex hull */
- int hull_len; /* allocated length of hull array */
-} params;
-
-/***************************************************************************/
-
-/* Evaluate the "diameter" (d) of a rectangle of widths w[n]
-
- We round the result to single precision, which should be plenty for
- the use we put the diameter to (rect sorting), to allow our
- performance hack in convex_hull to work (in the Jones and Gablonsky
- DIRECT algorithms, all of the rects fall into a few diameter
- values, and we don't want rounding error to spoil this) */
-static double rect_diameter(int n, const double *w, const params *p)
-{
- int i;
- if (p->which_diam == 0) { /* Jones measure */
- double sum = 0;
- for (i = 0; i < n; ++i)
- sum += w[i] * w[i];
- /* distance from center to a vertex */
- return ((float) (sqrt(sum) * 0.5));
- }
- else { /* Gablonsky measure */
- double maxw = 0;
- for (i = 0; i < n; ++i)
- if (w[i] > maxw)
- maxw = w[i];
- /* half-width of longest side */
- return ((float) (maxw * 0.5));
- }
-}
-
-#define ALLOC_RECT(rect, L) if (!(rect = (double*) malloc(sizeof(double)*(L)))) return NLOPT_OUT_OF_MEMORY
-
-static int sort_fv_compare(void *fv_, const void *a_, const void *b_)
-{
- const double *fv = (const double *) fv_;
- int a = *((const int *) a_), b = *((const int *) b_);
- double fa = MIN(fv[2*a], fv[2*a+1]);
- double fb = MIN(fv[2*b], fv[2*b+1]);
- if (fa < fb)
- return -1;
- else if (fa > fb)
- return +1;
- else
- return 0;
-}
-static void sort_fv(int n, double *fv, int *isort)
-{
- int i;
- for (i = 0; i < n; ++i) isort[i] = i;
- nlopt_qsort_r(isort, (unsigned) n, sizeof(int), fv, sort_fv_compare);
-}
-
-static double function_eval(const double *x, params *p) {
- double f = p->f(p->n, x, NULL, p->f_data);
- if (f < p->minf) {
- p->minf = f;
- memcpy(p->xmin, x, sizeof(double) * p->n);
- }
- p->stop->nevals++;
- return f;
-}
-#define FUNCTION_EVAL(fv,x,p,freeonerr) fv = function_eval(x, p); if (nlopt_stop_forced((p)->stop)) { free(freeonerr); return NLOPT_FORCED_STOP; } else if (p->minf < p->stop->minf_max) { free(freeonerr); return NLOPT_MINF_MAX_REACHED; } else if (nlopt_stop_evals((p)->stop)) { free(freeonerr); return NLOPT_MAXEVAL_REACHED; } else if (nlopt_stop_time((p)->stop)) { free(freeonerr); return NLOPT_MAXTIME_REACHED; }
-
-#define THIRD (0.3333333333333333333333)
-
-#define EQUAL_SIDE_TOL 5e-2 /* tolerance to equate side sizes */
-
-/* divide rectangle idiv in the list p->rects */
-static nlopt_result divide_rect(double *rdiv, params *p)
-{
- int i;
- const int n = p->n;
- const int L = p->L;
- double *c = rdiv + 3; /* center of rect to divide */
- double *w = c + n; /* widths of rect to divide */
- double wmax = w[0];
- int imax = 0, nlongest = 0;
- rb_node *node;
-
- for (i = 1; i < n; ++i)
- if (w[i] > wmax)
- wmax = w[imax = i];
- for (i = 0; i < n; ++i)
- if (wmax - w[i] <= wmax * EQUAL_SIDE_TOL)
- ++nlongest;
- if (p->which_div == 1 || (p->which_div == 0 && nlongest == n)) {
- /* trisect all longest sides, in increasing order of the average
- function value along that direction */
- double *fv = p->work;
- int *isort = p->iwork;
- for (i = 0; i < n; ++i) {
- if (wmax - w[i] <= wmax * EQUAL_SIDE_TOL) {
- double csave = c[i];
- c[i] = csave - w[i] * THIRD;
- FUNCTION_EVAL(fv[2*i], c, p, 0);
- c[i] = csave + w[i] * THIRD;
- FUNCTION_EVAL(fv[2*i+1], c, p, 0);
- c[i] = csave;
- }
- else {
- fv[2*i] = fv[2*i+1] = HUGE_VAL;
- }
- }
- sort_fv(n, fv, isort);
- if (!(node = rb_tree_find(&p->rtree, rdiv)))
- return NLOPT_FAILURE;
- for (i = 0; i < nlongest; ++i) {
- int k;
- w[isort[i]] *= THIRD;
- rdiv[0] = rect_diameter(n, w, p);
- rdiv[2] = p->age++;
- node = rb_tree_resort(&p->rtree, node);
- for (k = 0; k <= 1; ++k) {
- double *rnew;
- ALLOC_RECT(rnew, L);
- memcpy(rnew, rdiv, sizeof(double) * L);
- rnew[3 + isort[i]] += w[isort[i]] * (2*k-1);
- rnew[1] = fv[2*isort[i]+k];
- rnew[2] = p->age++;
- if (!rb_tree_insert(&p->rtree, rnew)) {
- free(rnew);
- return NLOPT_OUT_OF_MEMORY;
- }
- }
- }
- }
- else {
- int k;
- if (nlongest > 1 && p->which_div == 2) {
- /* randomly choose longest side */
- i = nlopt_iurand(nlongest);
- for (k = 0; k < n; ++k)
- if (wmax - w[k] <= wmax * EQUAL_SIDE_TOL) {
- if (!i) { i = k; break; }
- --i;
- }
- }
- else
- i = imax; /* trisect longest side */
- if (!(node = rb_tree_find(&p->rtree, rdiv)))
- return NLOPT_FAILURE;
- w[i] *= THIRD;
- rdiv[0] = rect_diameter(n, w, p);
- rdiv[2] = p->age++;
- node = rb_tree_resort(&p->rtree, node);
- for (k = 0; k <= 1; ++k) {
- double *rnew;
- ALLOC_RECT(rnew, L);
- memcpy(rnew, rdiv, sizeof(double) * L);
- rnew[3 + i] += w[i] * (2*k-1);
- FUNCTION_EVAL(rnew[1], rnew + 3, p, rnew);
- rnew[2] = p->age++;
- if (!rb_tree_insert(&p->rtree, rnew)) {
- free(rnew);
- return NLOPT_OUT_OF_MEMORY;
- }
- }
- }
- return NLOPT_SUCCESS;
-}
-
-/***************************************************************************/
-/* Convex hull algorithm, used later to find the potentially optimal
- points. What we really have in DIRECT is a "dynamic convex hull"
- problem, since we are dynamically adding/removing points and
- updating the hull, but I haven't implemented any of the fancy
- algorithms for this problem yet. */
-
-/* Find the lower convex hull of a set of points (x,y) stored in a rb-tree
- of pointers to {x,y} arrays sorted in lexographic order by (x,y).
-
- Unlike standard convex hulls, we allow redundant points on the hull,
- and even allow duplicate points if allow_dups is nonzero.
-
- The return value is the number of points in the hull, with pointers
- stored in hull[i] (should be an array of length >= t->N).
-*/
-static int convex_hull(rb_tree *t, double **hull, int allow_dups)
-{
- int nhull = 0;
- double minslope;
- double xmin, xmax, yminmin, ymaxmin;
- rb_node *n, *nmax;
-
- /* Monotone chain algorithm [Andrew, 1979]. */
-
- n = rb_tree_min(t);
- if (!n) return 0;
- nmax = rb_tree_max(t);
-
- xmin = n->k[0];
- yminmin = n->k[1];
- xmax = nmax->k[0];
-
- if (allow_dups)
- do { /* include any duplicate points at (xmin,yminmin) */
- hull[nhull++] = n->k;
- n = rb_tree_succ(n);
- } while (n && n->k[0] == xmin && n->k[1] == yminmin);
- else
- hull[nhull++] = n->k;
-
- if (xmin == xmax) return nhull;
-
- /* set nmax = min mode with x == xmax */
-#if 0
- while (nmax->k[0] == xmax)
- nmax = rb_tree_pred(nmax); /* non-NULL since xmin != xmax */
- nmax = rb_tree_succ(nmax);
-#else
- /* performance hack (see also below) */
- {
- double kshift[2];
- kshift[0] = xmax * (1 - 1e-13);
- kshift[1] = -HUGE_VAL;
- nmax = rb_tree_find_gt(t, kshift); /* non-NULL since xmin != xmax */
- }
-#endif
-
- ymaxmin = nmax->k[1];
- minslope = (ymaxmin - yminmin) / (xmax - xmin);
-
- /* set n = first node with x != xmin */
-#if 0
- while (n->k[0] == xmin)
- n = rb_tree_succ(n); /* non-NULL since xmin != xmax */
-#else
- /* performance hack (see also below) */
- {
- double kshift[2];
- kshift[0] = xmin * (1 + 1e-13);
- kshift[1] = -HUGE_VAL;
- n = rb_tree_find_gt(t, kshift); /* non-NULL since xmin != xmax */
- }
-#endif
-
- for (; n != nmax; n = rb_tree_succ(n)) {
- double *k = n->k;
- if (k[1] > yminmin + (k[0] - xmin) * minslope)
- continue;
-
- /* performance hack: most of the points in DIRECT lie along
- vertical lines at a few x values, and we can exploit this */
- if (nhull && k[0] == hull[nhull - 1][0]) { /* x == previous x */
- if (k[1] > hull[nhull - 1][1]) {
- double kshift[2];
- /* because of the round to float in rect_diameter, above,
- it shouldn't be possible for two diameters (x values)
- to have a fractional difference < 1e-13. Note
- that k[0] > 0 always in DIRECT */
- kshift[0] = k[0] * (1 + 1e-13);
- kshift[1] = -HUGE_VAL;
- n = rb_tree_pred(rb_tree_find_gt(t, kshift));
- continue;
- }
- else { /* equal y values, add to hull */
- if (allow_dups)
- hull[nhull++] = k;
- continue;
- }
- }
-
- /* remove points until we are making a "left turn" to k */
- while (nhull > 1) {
- double *t1 = hull[nhull - 1], *t2;
-
- /* because we allow equal points in our hull, we have
- to modify the standard convex-hull algorithm slightly:
- we need to look backwards in the hull list until we
- find a point t2 != t1 */
- int it2 = nhull - 2;
- do {
- t2 = hull[it2--];
- } while (it2 >= 0 && t2[0] == t1[0] && t2[1] == t1[1]);
- if (it2 < 0) break;
-
- /* cross product (t1-t2) x (k-t2) > 0 for a left turn: */
- if ((t1[0]-t2[0]) * (k[1]-t2[1])
- - (t1[1]-t2[1]) * (k[0]-t2[0]) >= 0)
- break;
- --nhull;
- }
- hull[nhull++] = k;
- }
-
- if (allow_dups)
- do { /* include any duplicate points at (xmax,ymaxmin) */
- hull[nhull++] = nmax->k;
- nmax = rb_tree_succ(nmax);
- } while (nmax && nmax->k[0] == xmax && nmax->k[1] == ymaxmin);
- else
- hull[nhull++] = nmax->k;
-
- return nhull;
-}
-
-/***************************************************************************/
-
-static int small(double *w, params *p)
-{
- int i;
- for (i = 0; i < p->n; ++i)
- if (w[i] > p->stop->xtol_abs[i] &&
- w[i] > (p->ub[i] - p->lb[i]) * p->stop->xtol_rel)
- return 0;
- return 1;
-}
-
-static nlopt_result divide_good_rects(params *p)
-{
- const int n = p->n;
- double **hull;
- int nhull, i, xtol_reached = 1, divided_some = 0;
- double magic_eps = p->magic_eps;
-
- if (p->hull_len < p->rtree.N) {
- p->hull_len += p->rtree.N;
- p->hull = (double **) realloc(p->hull, sizeof(double*)*p->hull_len);
- if (!p->hull) return NLOPT_OUT_OF_MEMORY;
- }
- nhull = convex_hull(&p->rtree, hull = p->hull, p->which_opt != 1);
- divisions:
- for (i = 0; i < nhull; ++i) {
- double K1 = -HUGE_VAL, K2 = -HUGE_VAL, K;
- int im, ip;
-
- /* find unequal points before (im) and after (ip) to get slope */
- for (im = i-1; im >= 0 && hull[im][0] == hull[i][0]; --im) ;
- for (ip = i+1; ip < nhull && hull[ip][0] == hull[i][0]; ++ip) ;
-
- if (im >= 0)
- K1 = (hull[i][1] - hull[im][1]) / (hull[i][0] - hull[im][0]);
- if (ip < nhull)
- K2 = (hull[i][1] - hull[ip][1]) / (hull[i][0] - hull[ip][0]);
- K = MAX(K1, K2);
- if (hull[i][1] - K * hull[i][0]
- <= p->minf - magic_eps * fabs(p->minf) || ip == nhull) {
- /* "potentially optimal" rectangle, so subdivide */
- nlopt_result ret = divide_rect(hull[i], p);
- divided_some = 1;
- if (ret != NLOPT_SUCCESS) return ret;
- xtol_reached = xtol_reached && small(hull[i] + 3+n, p);
- }
-
- /* for the DIRECT-L variant, we only divide one rectangle out
- of all points with equal diameter and function values
- ... note that for p->which_opt == 1, i == ip-1 should be a no-op
- anyway, since we set allow_dups=0 in convex_hull above */
- if (p->which_opt == 1)
- i = ip - 1; /* skip to next unequal point for next iteration */
- else if (p->which_opt == 2) /* like DIRECT-L but randomized */
- i += nlopt_iurand(ip - i); /* possibly do another equal pt */
- }
- if (!divided_some) {
- if (magic_eps != 0) {
- magic_eps = 0;
- goto divisions; /* try again */
- }
- else { /* WTF? divide largest rectangle with smallest f */
- /* (note that this code actually gets called from time
- to time, and the heuristic here seems to work well,
- but I don't recall this situation being discussed in
- the references?) */
- rb_node *max = rb_tree_max(&p->rtree);
- rb_node *pred = max;
- double wmax = max->k[0];
- do { /* note: this loop is O(N) worst-case time */
- max = pred;
- pred = rb_tree_pred(max);
- } while (pred && pred->k[0] == wmax);
- return divide_rect(max->k, p);
- }
- }
- return xtol_reached ? NLOPT_XTOL_REACHED : NLOPT_SUCCESS;
-}
-
-/***************************************************************************/
-
-/* lexographic sort order (d,f,age) of hyper-rects, for red-black tree */
-int cdirect_hyperrect_compare(double *a, double *b)
-{
- if (a[0] < b[0]) return -1;
- if (a[0] > b[0]) return +1;
- if (a[1] < b[1]) return -1;
- if (a[1] > b[1]) return +1;
- if (a[2] < b[2]) return -1;
- if (a[2] > b[2]) return +1;
- return (int) (a - b); /* tie-breaker, shouldn't be needed */
-}
-
-/***************************************************************************/
-
-nlopt_result cdirect_unscaled(int n, nlopt_func f, void *f_data,
- const double *lb, const double *ub,
- double *x,
- double *minf,
- nlopt_stopping *stop,
- double magic_eps, int which_alg)
-{
- params p;
- int i;
- double *rnew;
- nlopt_result ret = NLOPT_OUT_OF_MEMORY;
-
- p.magic_eps = magic_eps;
- p.which_diam = which_alg % 3;
- p.which_div = (which_alg / 3) % 3;
- p.which_opt = (which_alg / (3*3)) % 3;
- p.lb = lb; p.ub = ub;
- p.stop = stop;
- p.n = n;
- p.L = 2*n+3;
- p.f = f;
- p.f_data = f_data;
- p.xmin = x;
- p.minf = HUGE_VAL;
- p.work = 0;
- p.iwork = 0;
- p.hull = 0;
- p.age = 0;
-
- rb_tree_init(&p.rtree, cdirect_hyperrect_compare);
-
- p.work = (double *) malloc(sizeof(double) * (2*n));
- if (!p.work) goto done;
- p.iwork = (int *) malloc(sizeof(int) * n);
- if (!p.iwork) goto done;
- p.hull_len = 128; /* start with a reasonable number */
- p.hull = (double **) malloc(sizeof(double *) * p.hull_len);
- if (!p.hull) goto done;
-
- if (!(rnew = (double *) malloc(sizeof(double) * p.L))) goto done;
- for (i = 0; i < n; ++i) {
- rnew[3+i] = 0.5 * (lb[i] + ub[i]);
- rnew[3+n+i] = ub[i] - lb[i];
- }
- rnew[0] = rect_diameter(n, rnew+3+n, &p);
- rnew[1] = function_eval(rnew+3, &p);
- rnew[2] = p.age++;
- if (!rb_tree_insert(&p.rtree, rnew)) {
- free(rnew);
- goto done;
- }
-
- ret = divide_rect(rnew, &p);
- if (ret != NLOPT_SUCCESS) goto done;
-
- while (1) {
- double minf0 = p.minf;
- ret = divide_good_rects(&p);
- if (ret != NLOPT_SUCCESS) goto done;
- if (p.minf < minf0 && nlopt_stop_f(p.stop, p.minf, minf0)) {
- ret = NLOPT_FTOL_REACHED;
- goto done;
- }
- }
-
- done:
- rb_tree_destroy_with_keys(&p.rtree);
- free(p.hull);
- free(p.iwork);
- free(p.work);
-
- *minf = p.minf;
- return ret;
-}
-
-/* in the conventional DIRECT-type algorithm, we first rescale our
- coordinates to a unit hypercube ... we do this simply by
- wrapping cdirect() around cdirect_unscaled(). */
-
-double cdirect_uf(unsigned n, const double *xu, double *grad, void *d_)
-{
- cdirect_uf_data *d = (cdirect_uf_data *) d_;
- double f;
- unsigned i;
- for (i = 0; i < n; ++i)
- d->x[i] = d->lb[i] + xu[i] * (d->ub[i] - d->lb[i]);
- f = d->f(n, d->x, grad, d->f_data);
- if (grad)
- for (i = 0; i < n; ++i)
- grad[i] *= d->ub[i] - d->lb[i];
- return f;
-}
-
-nlopt_result cdirect(int n, nlopt_func f, void *f_data,
- const double *lb, const double *ub,
- double *x,
- double *minf,
- nlopt_stopping *stop,
- double magic_eps, int which_alg)
-{
- cdirect_uf_data d;
- nlopt_result ret;
- const double *xtol_abs_save;
- int i;
-
- d.f = f; d.f_data = f_data; d.lb = lb; d.ub = ub;
- d.x = (double *) malloc(sizeof(double) * n*4);
- if (!d.x) return NLOPT_OUT_OF_MEMORY;
-
- for (i = 0; i < n; ++i) {
- x[i] = (x[i] - lb[i]) / (ub[i] - lb[i]);
- d.x[n+i] = 0;
- d.x[2*n+i] = 1;
- d.x[3*n+i] = stop->xtol_abs[i] / (ub[i] - lb[i]);
- }
- xtol_abs_save = stop->xtol_abs;
- stop->xtol_abs = d.x + 3*n;
- ret = cdirect_unscaled(n, cdirect_uf, &d, d.x+n, d.x+2*n, x, minf, stop,
- magic_eps, which_alg);
- stop->xtol_abs = xtol_abs_save;
- for (i = 0; i < n; ++i)
- x[i] = lb[i]+ x[i] * (ub[i] - lb[i]);
- free(d.x);
- return ret;
-}
diff --git a/ext/src/nlopt/cdirect/hybrid.c b/ext/src/nlopt/cdirect/hybrid.c
deleted file mode 100644
index 841697b..0000000
--- a/ext/src/nlopt/cdirect/hybrid.c
+++ /dev/null
@@ -1,317 +0,0 @@
-/* Copyright (c) 2007-2012 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "nlopt/nlopt-util.h"
-#include "nlopt/nlopt.h"
-#include "nlopt/cdirect.h"
-#include "nlopt/redblack.h"
-
-/* Hybrid algorithm, inspired by DIRECT, that uses another local
- * optimization algorithm within each rectangle, and then looks
- * in the largest remaining rectangle (breaking ties by minimum
- * function value and then by age.
- *
- * Each hyperrect is represented by an array of length 3*n+3 consisting
- * of (d, -f, -a, x, c, w), where d=diameter, f=f(x), a=age, x=local optimum
- * c=center, w=widths.
- */
-
-typedef struct {
- int n; /* dimension */
- int L; /* 3*n+3 */
- const double *lb, *ub;
- nlopt_stopping *stop; /* stopping criteria */
- nlopt_func f; void *f_data;
- double minf, *xmin; /* min so far */
- rb_tree rtree; /* red-black tree of rects, sorted by (d,-f,-a) */
- int age; /* age for next new rect */
- double *work; /* workspace of length >= 2*n */
-
- nlopt_algorithm local_alg; /* local search algorithm */
- int local_maxeval; /* max # local iterations (0 if unlimited) */
-
- int randomized_div; /* 1 to use randomized division algorithm */
-} params;
-
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-
-#define THIRD (0.3333333333333333333333) /* 1/3 */
-
-/************************************************************************/
-
-static double fcount(int n, const double *x, double *grad, void *p_)
-{
- params *p = (params *) p_;
- p->stop->nevals++;
- return p->f(n, x, grad, p->f_data);
-}
-
-static nlopt_result optimize_rect(double *r, params *p)
-{
- int i, n = p->n;
- double *lb = p->work, *ub = lb + n;
- double *x = r + 3, *c = x + n, *w = c + n;
- double t = nlopt_seconds();
- double minf;
- nlopt_stopping *stop = p->stop;
- nlopt_result ret;
-
- if (stop->maxeval > 0 &&
- stop->nevals >= stop->maxeval) return NLOPT_MAXEVAL_REACHED;
- if (stop->maxtime > 0 &&
- t - stop->start >= stop->maxtime) return NLOPT_MAXTIME_REACHED;
-
- for (i = 0; i < n; ++i) {
- lb[i] = c[i] - 0.5 * w[i];
- ub[i] = c[i] + 0.5 * w[i];
- }
- ret = nlopt_minimize(p->local_alg, n, fcount, p,
- lb, ub, x, &minf,
- stop->minf_max, stop->ftol_rel, stop->ftol_abs,
- stop->xtol_rel, stop->xtol_abs,
- p->local_maxeval > 0 ?
- MIN(p->local_maxeval,
- stop->maxeval - stop->nevals)
- : stop->maxeval - stop->nevals,
- stop->maxtime - (t - stop->start));
- r[1] = -minf;
- if (ret > 0) {
- if (minf < p->minf) {
- p->minf = minf;
- memcpy(p->xmin, x, sizeof(double) * n);
- if (ret == NLOPT_MINF_MAX_REACHED) return ret;
- }
- return NLOPT_SUCCESS;
- }
- return ret;
-}
-
-/* given a hyperrect r, randomize the starting guess within the middle
- third of the box (don't guess too close to edges) */
-static void randomize_x(int n, double *r)
-{
- double *x = r + 3, *c = x + n, *w = c + n;
- int i;
- for (i = 0; i < n; ++i)
- x[i] = nlopt_urand(c[i] - w[i]*(0.5*THIRD),
- c[i] + w[i]*(0.5*THIRD));
-}
-
-/************************************************************************/
-
-static double longest(int n, const double *w)
-{
- double wmax = w[n-1];
- for (n = n-2; n >= 0; n--) if (w[n] > wmax) wmax = w[n];
- return wmax;
-}
-
-#define EQUAL_SIDE_TOL 5e-2 /* tolerance to equate side sizes */
-
-static nlopt_result divide_largest(params *p)
-{
- int L = p->L;
- int n = p->n;
- rb_node *node = rb_tree_max(&p->rtree); /* just using it as a heap */
- double minf_start = p->minf;
- double *r = node->k, *rnew = NULL;
- double *x = r + 3, *c = x + n, *w = c + n;
- const double *lb = p->lb, *ub = p->ub;
- int i, idiv;
- double wmax;
- nlopt_result ret;
-
- /* printf("rect:, %d, %g, %g, %g, %g\n", p->stop->nevals, c[0], c[1], w[0], w[1]); */
-
- /* check xtol */
- for (i = 0; i < n; ++i)
- if (w[i] > p->stop->xtol_rel * (ub[i] - lb[i])
- && w[i] > p->stop->xtol_abs[i])
- break;
- if (i == n) return NLOPT_XTOL_REACHED;
-
- if (p->randomized_div) { /* randomly pick among ~largest sides */
- int nlongest = 0;
- wmax = longest(n, w);
- for (i = 0; i < n; ++i)
- if (wmax - w[i] < EQUAL_SIDE_TOL * wmax) ++nlongest;
- i = 1 + nlopt_iurand(nlongest);
- for (idiv = 0; idiv < n; ++idiv) {
- if (wmax - w[idiv] < EQUAL_SIDE_TOL * wmax) --i;
- if (!i) break;
- }
- }
- else { /* just pick first largest side */
- wmax = w[idiv = 0];
- for (i = 1; i < n; ++i) if (w[i] > wmax) wmax = w[idiv = i];
- }
-
- if (fabs(x[idiv] - c[idiv]) > (0.5 * THIRD) * w[idiv]) { /* bisect */
- double deltac = (x[idiv] > c[idiv] ? 0.25 : -0.25) * w[idiv];
- w[idiv] *= 0.5;
- c[idiv] += deltac;
- r[0] = longest(n, w); /* new diameter */
- /* r[1] unchanged since still contains local optimum x */
- r[2] = p->age--;
- node = rb_tree_resort(&p->rtree, node);
-
- rnew = (double *) malloc(sizeof(double) * L);
- if (!rnew) return NLOPT_OUT_OF_MEMORY;
- memcpy(rnew, r, sizeof(double) * L);
- rnew[2] = p->age--;
- rnew[3+n+idiv] -= deltac*2;
- if (p->randomized_div)
- randomize_x(n, rnew);
- else
- memcpy(rnew+3, rnew+3+n, sizeof(double) * n); /* x = c */
- ret = optimize_rect(rnew, p);
- if (ret != NLOPT_SUCCESS) { free(rnew); return ret; }
- if (!rb_tree_insert(&p->rtree, rnew)) {
- free(rnew); return NLOPT_OUT_OF_MEMORY;
- }
- }
- else { /* trisect */
- w[idiv] *= THIRD;
- r[0] = longest(n, w);
- /* r[1] unchanged since still contains local optimum x */
- r[2] = p->age--;
- node = rb_tree_resort(&p->rtree, node);
-
- for (i = -1; i <= +1; i += 2) {
- rnew = (double *) malloc(sizeof(double) * L);
- if (!rnew) return NLOPT_OUT_OF_MEMORY;
- memcpy(rnew, r, sizeof(double) * L);
- rnew[2] = p->age--;
- rnew[3+n+idiv] += w[i] * i;
- if (p->randomized_div)
- randomize_x(n, rnew);
- else
- memcpy(rnew+3, rnew+3+n, sizeof(double) * n); /* x = c */
- ret = optimize_rect(rnew, p);
- if (ret != NLOPT_SUCCESS) { free(rnew); return ret; }
- if (!rb_tree_insert(&p->rtree, rnew)) {
- free(rnew); return NLOPT_OUT_OF_MEMORY;
- }
- }
- }
- if (p->minf < minf_start && nlopt_stop_f(p->stop, p->minf, minf_start))
- return NLOPT_FTOL_REACHED;
- return NLOPT_SUCCESS;
-}
-
-/************************************************************************/
-
-nlopt_result cdirect_hybrid_unscaled(int n, nlopt_func f, void *f_data,
- const double *lb, const double *ub,
- double *x,
- double *minf,
- nlopt_stopping *stop,
- nlopt_algorithm local_alg,
- int local_maxeval,
- int randomized_div)
-{
- params p;
- int i;
- double *rnew;
- nlopt_result ret = NLOPT_OUT_OF_MEMORY;
-
- p.n = n;
- p.L = 3*n+3;
- p.lb = lb; p.ub = ub;
- p.stop = stop;
- p.f = f;
- p.f_data = f_data;
- p.minf = HUGE_VAL;
- p.xmin = x;
- p.age = 0;
- p.work = 0;
- p.local_alg = local_alg;
- p.local_maxeval = local_maxeval;
- p.randomized_div = randomized_div;
-
- rb_tree_init(&p.rtree, cdirect_hyperrect_compare);
- p.work = (double *) malloc(sizeof(double) * (2*n));
- if (!p.work) goto done;
-
- if (!(rnew = (double *) malloc(sizeof(double) * p.L))) goto done;
- for (i = 0; i < n; ++i) {
- rnew[3+i] = rnew[3+n+i] = 0.5 * (lb[i] + ub[i]);
- rnew[3+2*n+i] = ub[i] - lb[i];
- }
- rnew[0] = longest(n, rnew+2*n);
- rnew[2] = p.age--;
- ret = optimize_rect(rnew, &p);
- if (ret != NLOPT_SUCCESS) { free(rnew); goto done; }
- if (!rb_tree_insert(&p.rtree, rnew)) { free(rnew); goto done; }
-
- do {
- ret = divide_largest(&p);
- } while (ret == NLOPT_SUCCESS);
-
- done:
- rb_tree_destroy_with_keys(&p.rtree);
- free(p.work);
-
- *minf = p.minf;
- return ret;
-}
-
-/* rescaled to unit hypercube so that all x[i] are weighted equally */
-nlopt_result cdirect_hybrid(int n, nlopt_func f, void *f_data,
- const double *lb, const double *ub,
- double *x,
- double *minf,
- nlopt_stopping *stop,
- nlopt_algorithm local_alg,
- int local_maxeval,
- int randomized_div)
-{
- cdirect_uf_data d;
- nlopt_result ret;
- const double *xtol_abs_save;
- int i;
-
- d.f = f; d.f_data = f_data; d.lb = lb; d.ub = ub;
- d.x = (double *) malloc(sizeof(double) * n*4);
- if (!d.x) return NLOPT_OUT_OF_MEMORY;
-
- for (i = 0; i < n; ++i) {
- x[i] = (x[i] - lb[i]) / (ub[i] - lb[i]);
- d.x[n+i] = 0;
- d.x[2*n+i] = 1;
- d.x[3*n+i] = stop->xtol_abs[i] / (ub[i] - lb[i]);
- }
- xtol_abs_save = stop->xtol_abs;
- stop->xtol_abs = d.x + 3*n;
- ret = cdirect_hybrid_unscaled(n, cdirect_uf, &d, d.x+n, d.x+2*n,
- x, minf, stop, local_alg, local_maxeval,
- randomized_div);
- stop->xtol_abs = xtol_abs_save;
- for (i = 0; i < n; ++i)
- x[i] = lb[i]+ x[i] * (ub[i] - lb[i]);
- free(d.x);
- return ret;
-}
diff --git a/ext/src/nlopt/cobyla/COPYRIGHT b/ext/src/nlopt/cobyla/COPYRIGHT
deleted file mode 100644
index f5e0d95..0000000
--- a/ext/src/nlopt/cobyla/COPYRIGHT
+++ /dev/null
@@ -1,22 +0,0 @@
-Copyright (c) 1992, Michael J. D. Powell (M.J.D.Powell at damtp.cam.ac.uk)
-Copyright (c) 2004, Jean-Sebastien Roy (js at jeannot.org)
-Copyright (c) 2008, Steven G. Johnson (stevenj at alum.mit.edu)
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/ext/src/nlopt/cobyla/README b/ext/src/nlopt/cobyla/README
deleted file mode 100644
index eb19f17..0000000
--- a/ext/src/nlopt/cobyla/README
+++ /dev/null
@@ -1,42 +0,0 @@
-This code implements COBYLA (Constrained Optimization BY Linear
-Approximations) algorithm derivative free optimization with nonlinear
-inequality constraints by M. J. D. Powell, described by:
-
- M. J. D. Powell, "A direct search optimization method that
- models the objective and constraint functions by linear
- interpolation," in Advances in Optimization and Numerical
- Analysis, eds. S. Gomez and J.-P. Hennart (Kluwer Academic:
- Dordrecht, 1994), p. 51-67.
-
-and reviewed in:
-
- M. J. D. Powell, "Direct search algorithms for optimization
- calculations," Acta Numerica 7, 287-336 (1998).
-
-It constructs successive linear approximations of the objective
-function and constraints via a simplex of n+1 points (in n
-dimensions), and optimizes these approximations in a trust region at
-each step.
-
-The original code itself was written in Fortran by Powell, and
-apparently released without restrictions (like several of his other
-programs), and was converted to C in 2004 by Jean-Sebastien Roy
-(js at jeannot.org) for the SciPy project. The C version was released
-under the attached license (basically the MIT license) at:
- http://www.jeannot.org/~js/code/index.en.html#COBYLA
-
-It was incorporated into NLopt in 2008 by S. G. Johnson, and kept under
-the same MIT license. In incorporating it into NLopt, SGJ adapted it
-to include the NLopt stopping conditions (the original code provided
-an x tolerance and a maximum number of function evaluations only).
-
-The original COBYLA did not have explicit support for bound
-constraints; these are included as linear constraints along with any
-other nonlinear constraints. This is mostly fine---linear constraints
-are handled exactly by COBYLA's linear approximations. However,
-occasionally COBYLA takes a "simplex" step, either to create the
-initial simplex or to fix a degenerate simplex, and these steps could
-violate the bound constraints. SGJ modified COBYLA to explicitly
-honor the bound constraints in these cases, so that the
-objective/constraints are never evaluated outside of the bound
-constraints, without slowing convergence.
diff --git a/ext/src/nlopt/cobyla/README.orig b/ext/src/nlopt/cobyla/README.orig
deleted file mode 100644
index 09ead81..0000000
--- a/ext/src/nlopt/cobyla/README.orig
+++ /dev/null
@@ -1,74 +0,0 @@
-# COBYLA : constrained optimization by linear approximation
-# Version 1.1
-# Copyright (c) 1992, Michael J. D. Powell (M.J.D.Powell at damtp.cam.ac.uk)
-# Copyright (c) 2004, J.S. Roy (js at jeannot.org)
-# See the LICENSE file for copyright information.
-# $Jeannot: README,v 1.7 2004/04/18 14:04:20 js Exp $
-
-This software is a C version of COBYLA2, a contrained optimization by linear
-approximation package developed by Michael J. D. Powell in Fortran.
-
-The original source code can be found at :
-http://plato.la.asu.edu/topics/problems/nlores.html
-
-Reference article for the method: Powell, J.M.D. (1992), "A Direct Search
-Optimization Method that Models the Objective and Constraint Functions by Linear
-Interpolation", DAMTP/NA5, Cambridge, England.
-
-This package was initially built by J.S. Roy to ease integration into SciPy.
-See: http://www.scipy.org/
-Many thanks to Michael J. D. Powell for allowing this to happen !
-
-This software, a derivative free non-linear optimizer, aims at minimizing the
-value of a nonlinear function subject to nonlinear constraints. It requires to
-be able to evaluate the function and the value of the constraints.
-
-COBYLA will try to make all the values of the constraints positive.
-So if you want to input a constraint j such as variable x[i] <= MAX, set:
- constraint[j] = MAX - x[i]
-
-See the comments in cobyla.c for more details.
-
-This software has been converted from the Fortran into C and provides the
-following modifications :
-- reentrancy, no global variables or functions ;
-- ability to pass a pointer to the function to be optimized (to provide
- access to constants) ;
-- ability to end the minimization at any time ;
-And other small changes.
-
-The last version (and other software) is avalaible at the URL :
-http://www.jeannot.org/~js/code/index.en.html
-
-A Python interface module is also provided.
-
-Contents :
-- cobyla.c : Source
-- cobyla.h : Header, and API documentation
-- LICENSE : License and copyright information
-- HISTORY : Release history
-- README : This file
-- example.c : A simple example
-- Makefile : Make file used to build the examples
-- moduleCobyla.c : the source of the python module
-- cobyla.py : the python module wrapper
-- example.py : an example for the python module
-- setup.py : the python installer
-
-Use is described in cobyla.h. For more information, see the example.
-The example can be built and executed by doing :
- make test
-
-You may need to adjust the Makefile before building cobyla.
-
-To install the module in the current directory, use:
- python setup.py build_ext --inplace
-To test it, execute:
- python cobyla.py
-To install it globaly, use:
- python setup.py install
-
-If you make use of this software, or if you make modifications to it (for a
-specific platform for example), you are encouraged to contact the author of
-this Fortran to C conversion at the following email : js at jeannot.org
-Thanks !
diff --git a/ext/src/nlopt/cobyla/cobyla.c b/ext/src/nlopt/cobyla/cobyla.c
deleted file mode 100644
index 4578121..0000000
--- a/ext/src/nlopt/cobyla/cobyla.c
+++ /dev/null
@@ -1,1847 +0,0 @@
-/* cobyla : contrained optimization by linear approximation */
-
-/*
- * Copyright (c) 1992, Michael J. D. Powell (M.J.D.Powell at damtp.cam.ac.uk)
- * Copyright (c) 2004, Jean-Sebastien Roy (js at jeannot.org)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
- * This software is a C version of COBYLA2, a contrained optimization by linear
- * approximation package developed by Michael J. D. Powell in Fortran.
- *
- * The original source code can be found at :
- * http://plato.la.asu.edu/topics/problems/nlores.html
- */
-
-static char const rcsid[] =
- "@(#) $Jeannot: cobyla.c,v 1.11 2004/04/18 09:51:36 js Exp $";
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <math.h>
-
-#include "nlopt/cobyla.h"
-
-/* SGJ, 2008: modified COBYLA code to take explicit account of bound
- constraints. Since bound constraints are linear, these should
- already be handled exactly when COBYLA optimizes it linear model.
- However, they were not handled properly when COBYLA created its
- initial simplex, or when COBYLA updated unacceptable simplices.
- Since NLopt guarantees that the objective will not be evaluated
- outside the bound constraints, this required us to handle such
- points by putting a slope discontinuity into the objective &
- constraints (below), which slows convergence considerably for
- smooth functions. Instead, handling them explicitly prevents this
- problem */
-#define ENFORCE_BOUNDS 1
-
-#define MIN2(a,b) ((a) <= (b) ? (a) : (b))
-#define MAX2(a,b) ((a) >= (b) ? (a) : (b))
-
-#define U(n) ((unsigned) (n))
-
-/**************************************************************************/
-/* SGJ, 2008: NLopt-style interface function: */
-
-typedef struct {
- nlopt_func f;
- void *f_data;
- unsigned m_orig;
- nlopt_constraint *fc;
- unsigned p;
- nlopt_constraint *h;
- double *xtmp;
- double *lb, *ub;
- double *con_tol, *scale;
- nlopt_stopping *stop;
-} func_wrap_state;
-
-static int func_wrap(int ni, int mi, double *x, double *f, double *con,
- func_wrap_state *s)
-{
- unsigned n = U(ni);
- unsigned i, j, k;
- double *xtmp = s->xtmp;
- const double *lb = s->lb, *ub = s->ub;
-
- (void) mi; /* unused */
-
- /* in nlopt, we guarante that the function is never evaluated outside
- the lb and ub bounds, so we need force this with xtmp ... note
- that this leads to discontinuity in the first derivative, which
- slows convergence if we don't enable the ENFORCE_BOUNDS feature
- above. */
- for (j = 0; j < n; ++j) {
- if (x[j] < lb[j]) xtmp[j] = lb[j];
- else if (x[j] > ub[j]) xtmp[j] = ub[j];
- else xtmp[j] = x[j];
- }
- nlopt_unscale(n, s->scale, xtmp, xtmp);
-
- *f = s->f(n, xtmp, NULL, s->f_data);
- if (nlopt_stop_forced(s->stop)) return 1;
- i = 0;
- for (j = 0; j < s->m_orig; ++j) {
- nlopt_eval_constraint(con + i, NULL, s->fc+j, n, xtmp);
- if (nlopt_stop_forced(s->stop)) return 1;
- for (k = 0; k < s->fc[j].m; ++k)
- con[i + k] = -con[i + k];
- i += s->fc[j].m;
- }
- for (j = 0; j < s->p; ++j) {
- nlopt_eval_constraint(con + i, NULL, s->h+j, n, xtmp);
- if (nlopt_stop_forced(s->stop)) return 1;
- for (k = 0; k < s->h[j].m; ++k)
- con[(i + s->h[j].m) + k] = -con[i + k];
- i += 2 * s->h[j].m;
- }
- for (j = 0; j < n; ++j) {
- if (!nlopt_isinf(lb[j]))
- con[i++] = x[j] - lb[j];
- if (!nlopt_isinf(ub[j]))
- con[i++] = ub[j] - x[j];
- }
- return 0;
-}
-
-/*
- * Verbosity level
- */
-typedef enum {
- COBYLA_MSG_NONE = 0, /* No messages */
- COBYLA_MSG_EXIT = 1, /* Exit reasons */
- COBYLA_MSG_ITER = 2, /* Rho and Sigma changes */
- COBYLA_MSG_INFO = 3 /* Informational messages */
-} cobyla_message;
-
-/*
- * A function as required by cobyla
- * state is a void pointer provided to the function at each call
- *
- * n : the number of variables
- * m : the number of constraints
- * x : on input, then vector of variables (should not be modified)
- * f : on output, the value of the function
- * con : on output, the value of the constraints (vector of size m)
- * state : on input, the value of the state variable as provided to cobyla
- *
- * COBYLA will try to make all the values of the constraints positive.
- * So if you want to input a constraint j such as x[i] <= MAX, set:
- * con[j] = MAX - x[i]
- * The function must returns 0 if no error occurs or 1 to immediately end the
- * minimization.
- *
- */
-typedef int cobyla_function(int n, int m, double *x, double *f, double *con,
- func_wrap_state *state);
-
-/*
- * cobyla : minimize a function subject to constraints
- *
- * n : number of variables (>=0)
- * m : number of constraints (>=0)
- * x : on input, initial estimate ; on output, the solution
- * minf : on output, minimum objective function
- * rhobeg : a reasonable initial change to the variables
- * stop : the NLopt stopping criteria
- * lb, ub : lower and upper bounds on x
- * message : see the cobyla_message enum
- * calcfc : the function to minimize (see cobyla_function)
- * state : used by function (see cobyla_function)
- *
- * The cobyla function returns the usual nlopt_result codes.
- *
- */
-extern nlopt_result cobyla(int n, int m, double *x, double *minf, double rhobeg, double rhoend, nlopt_stopping *stop, const double *lb, const double *ub,
- int message, cobyla_function *calcfc, func_wrap_state *state);
-
-nlopt_result cobyla_minimize(unsigned n, nlopt_func f, void *f_data,
- unsigned m, nlopt_constraint *fc,
- unsigned p, nlopt_constraint *h,
- const double *lb, const double *ub, /* bounds */
- double *x, /* in: initial guess, out: minimizer */
- double *minf,
- nlopt_stopping *stop,
- const double *dx)
-{
- unsigned i, j;
- func_wrap_state s;
- nlopt_result ret;
- double rhobeg, rhoend;
-
- s.f = f; s.f_data = f_data;
- s.m_orig = m;
- s.fc = fc;
- s.p = p;
- s.h = h;
- s.stop = stop;
- s.lb = s.ub = s.xtmp = s.con_tol = s.scale = NULL;
-
- s.scale = nlopt_compute_rescaling(n, dx);
- if (!s.scale) { ret = NLOPT_OUT_OF_MEMORY; goto done; }
-
- s.lb = nlopt_new_rescaled(n, s.scale, lb);
- if (!s.lb) { ret = NLOPT_OUT_OF_MEMORY; goto done; }
- s.ub = nlopt_new_rescaled(n, s.scale, ub);
- if (!s.ub) { ret = NLOPT_OUT_OF_MEMORY; goto done; }
- nlopt_reorder_bounds(n, s.lb, s.ub);
-
- s.xtmp = (double *) malloc(sizeof(double) * n);
- if (!s.xtmp) { ret = NLOPT_OUT_OF_MEMORY; goto done; }
-
- /* SGJ, 2008: compute rhoend from NLopt stop info */
- rhobeg = fabs(dx[0] / s.scale[0]);
- rhoend = stop->xtol_rel * (rhobeg);
- for (j = 0; j < n; ++j)
- if (rhoend < stop->xtol_abs[j] / fabs(s.scale[j]))
- rhoend = stop->xtol_abs[j] / fabs(s.scale[j]);
-
- /* each equality constraint gives two inequality constraints */
- m = nlopt_count_constraints(m, fc) + 2 * nlopt_count_constraints(p, h);
-
- /* add constraints for lower/upper bounds (if any) */
- for (j = 0; j < n; ++j) {
- if (!nlopt_isinf(lb[j]))
- ++m;
- if (!nlopt_isinf(ub[j]))
- ++m;
- }
-
- s.con_tol = (double *) malloc(sizeof(double) * m);
- if (m && !s.con_tol) { ret = NLOPT_OUT_OF_MEMORY; goto done; }
-
- for (j = 0; j < m; ++j) s.con_tol[j] = 0;
- for (j = i = 0; i < s.m_orig; ++i) {
- unsigned ji = j, jnext = j + fc[i].m;
- for (; j < jnext; ++j) s.con_tol[j] = fc[i].tol[j - ji];
- }
- for (i = 0; i < s.p; ++i) {
- unsigned ji = j, jnext = j + h[i].m;
- for (; j < jnext; ++j) s.con_tol[j] = h[i].tol[j - ji];
- ji = j; jnext = j + h[i].m;
- for (; j < jnext; ++j) s.con_tol[j] = h[i].tol[j - ji];
- }
-
- nlopt_rescale(n, s.scale, x, x);
- ret = cobyla((int) n, (int) m, x, minf, rhobeg, rhoend,
- stop, s.lb, s.ub, COBYLA_MSG_NONE,
- func_wrap, &s);
- nlopt_unscale(n, s.scale, x, x);
-
- /* make sure e.g. rounding errors didn't push us slightly out of bounds */
- for (j = 0; j < n; ++j) {
- if (x[j] < lb[j]) x[j] = lb[j];
- if (x[j] > ub[j]) x[j] = ub[j];
- }
-
-done:
- free(s.con_tol);
- free(s.xtmp);
- free(s.ub);
- free(s.lb);
- free(s.scale);
- return ret;
-}
-
-/**************************************************************************/
-
-/* SGJ, 2010: I find that it seems to increase robustness of the algorithm
- if, on "simplex" steps (which are intended to improve the linear
- independence of the simplex, not improve the objective), we multiply
- the steps by pseudorandom numbers in [0,1). Intuitively, pseudorandom
- steps are likely to avoid any accidental dependency in the simplex
- vertices. However, since I still want COBYLA to be a deterministic
- algorithm, and I don't care all that much about the quality of the
- randomness here, I implement a simple linear congruential generator
- rather than use nlopt_urand, and set the initial seed deterministically. */
-
-#include <stdint.h>
-
-/* a simple linear congruential generator */
-
-static uint32_t lcg_rand(uint32_t *seed)
-{
- return (*seed = *seed * 1103515245 + 12345);
-}
-
-static double lcg_urand(uint32_t *seed, double a, double b)
-{
- return a + lcg_rand(seed) * (b - a) / ((uint32_t) -1);
-}
-
-/**************************************************************************/
-
-static nlopt_result cobylb(int *n, int *m, int *mpp, double *x, double *minf, double *rhobeg, double rhoend,
- nlopt_stopping *stop, const double *lb, const double *ub, int *iprint, double *con, double *sim,
- double *simi, double *datmat, double *a, double *vsig, double *veta,
- double *sigbar, double *dx, double *w, int *iact, cobyla_function *calcfc,
- func_wrap_state *state);
-static nlopt_result trstlp(int *n, int *m, double *a, double *b, double *rho,
- double *dx, int *ifull, int *iact, double *z__, double *zdota, double *vmultc,
- double *sdirn, double *dxnew, double *vmultd);
-
-/* ------------------------------------------------------------------------ */
-
-nlopt_result cobyla(int n, int m, double *x, double *minf, double rhobeg, double rhoend, nlopt_stopping *stop, const double *lb, const double *ub, int iprint,
- cobyla_function *calcfc, func_wrap_state *state)
-{
- int icon, isim, isigb, idatm, iveta, isimi, ivsig, iwork, ia, idx, mpp;
- int *iact;
- double *w;
- nlopt_result rc;
-
-/*
- * This subroutine minimizes an objective function F(X) subject to M
- * inequality constraints on X, where X is a vector of variables that has
- * N components. The algorithm employs linear approximations to the
- * objective and constraint functions, the approximations being formed by
- * linear interpolation at N+1 points in the space of the variables.
- * We regard these interpolation points as vertices of a simplex. The
- * parameter RHO controls the size of the simplex and it is reduced
- * automatically from RHOBEG to RHOEND. For each RHO the subroutine tries
- * to achieve a good vector of variables for the current size, and then
- * RHO is reduced until the value RHOEND is reached. Therefore RHOBEG and
- * RHOEND should be set to reasonable initial changes to and the required
- * accuracy in the variables respectively, but this accuracy should be
- * viewed as a subject for experimentation because it is not guaranteed.
- * The subroutine has an advantage over many of its competitors, however,
- * which is that it treats each constraint individually when calculating
- * a change to the variables, instead of lumping the constraints together
- * into a single penalty function. The name of the subroutine is derived
- * from the phrase Constrained Optimization BY Linear Approximations.
- *
- * The user must set the values of N, M, RHOBEG and RHOEND, and must
- * provide an initial vector of variables in X. Further, the value of
- * IPRINT should be set to 0, 1, 2 or 3, which controls the amount of
- * printing during the calculation. Specifically, there is no output if
- * IPRINT=0 and there is output only at the end of the calculation if
- * IPRINT=1. Otherwise each new value of RHO and SIGMA is printed.
- * Further, the vector of variables and some function information are
- * given either when RHO is reduced or when each new value of F(X) is
- * computed in the cases IPRINT=2 or IPRINT=3 respectively. Here SIGMA
- * is a penalty parameter, it being assumed that a change to X is an
- * improvement if it reduces the merit function
- * F(X)+SIGMA*MAX(0.0,-C1(X),-C2(X),...,-CM(X)),
- * where C1,C2,...,CM denote the constraint functions that should become
- * nonnegative eventually, at least to the precision of RHOEND. In the
- * printed output the displayed term that is multiplied by SIGMA is
- * called MAXCV, which stands for 'MAXimum Constraint Violation'. The
- * argument MAXFUN is an int variable that must be set by the user to a
- * limit on the number of calls of CALCFC, the purpose of this routine being
- * given below. The value of MAXFUN will be altered to the number of calls
- * of CALCFC that are made. The arguments W and IACT provide real and
- * int arrays that are used as working space. Their lengths must be at
- * least N*(3*N+2*M+11)+4*M+6 and M+1 respectively.
- *
- * In order to define the objective and constraint functions, we require
- * a subroutine that has the name and arguments
- * SUBROUTINE CALCFC (N,M,X,F,CON)
- * DIMENSION X(*),CON(*) .
- * The values of N and M are fixed and have been defined already, while
- * X is now the current vector of variables. The subroutine should return
- * the objective and constraint functions at X in F and CON(1),CON(2),
- * ...,CON(M). Note that we are trying to adjust X so that F(X) is as
- * small as possible subject to the constraint functions being nonnegative.
- *
- * Partition the working space array W to provide the storage that is needed
- * for the main calculation.
- */
-
- stop->nevals = 0;
-
- if (n == 0)
- {
- if (iprint>=1) fprintf(stderr, "cobyla: N==0.\n");
- return NLOPT_SUCCESS;
- }
-
- if (n < 0 || m < 0)
- {
- if (iprint>=1) fprintf(stderr, "cobyla: N<0 or M<0.\n");
- return NLOPT_INVALID_ARGS;
- }
-
- /* workspace allocation */
- w = (double*) malloc(U(n*(3*n+2*m+11)+4*m+6)*sizeof(*w));
- if (w == NULL)
- {
- if (iprint>=1) fprintf(stderr, "cobyla: memory allocation error.\n");
- return NLOPT_OUT_OF_MEMORY;
- }
- iact = (int*)malloc(U(m+1)*sizeof(*iact));
- if (iact == NULL)
- {
- if (iprint>=1) fprintf(stderr, "cobyla: memory allocation error.\n");
- free(w);
- return NLOPT_OUT_OF_MEMORY;
- }
-
- /* Parameter adjustments */
- --iact;
- --w;
- --x;
- --lb; --ub;
-
- /* Function Body */
- mpp = m + 2;
- icon = 1;
- isim = icon + mpp;
- isimi = isim + n * n + n;
- idatm = isimi + n * n;
- ia = idatm + n * mpp + mpp;
- ivsig = ia + m * n + n;
- iveta = ivsig + n;
- isigb = iveta + n;
- idx = isigb + n;
- iwork = idx + n;
- rc = cobylb(&n, &m, &mpp, &x[1], minf, &rhobeg, rhoend, stop, &lb[1], &ub[1], &iprint,
- &w[icon], &w[isim], &w[isimi], &w[idatm], &w[ia], &w[ivsig], &w[iveta],
- &w[isigb], &w[idx], &w[iwork], &iact[1], calcfc, state);
-
- /* Parameter adjustments (reverse) */
- ++iact;
- ++w;
-
- free(w);
- free(iact);
-
- return rc;
-} /* cobyla */
-
-/* ------------------------------------------------------------------------- */
-static nlopt_result cobylb(int *n, int *m, int *mpp,
- double *x, double *minf, double *rhobeg, double rhoend,
- nlopt_stopping *stop, const double *lb, const double *ub,
- int *iprint, double *con, double *sim, double *simi,
- double *datmat, double *a, double *vsig, double *veta,
- double *sigbar, double *dx, double *w, int *iact, cobyla_function *calcfc,
- func_wrap_state *state)
-{
- /* System generated locals */
- int sim_dim1, sim_offset, simi_dim1, simi_offset, datmat_dim1,
- datmat_offset, a_dim1, a_offset, i__1, i__2, i__3;
- double d__1, d__2;
-
- /* Local variables */
- double alpha, delta, denom, tempa, barmu;
- double beta, cmin = 0.0, cmax = 0.0;
- double cvmaxm, dxsign, prerem = 0.0;
- double edgmax, pareta, prerec = 0.0, phimin, parsig = 0.0;
- double gamma_;
- double phi, rho, sum = 0.0;
- double ratio, vmold, parmu, error, vmnew;
- double resmax, cvmaxp;
- double resnew, trured;
- double temp, wsig, f;
- double weta;
- int i__, j, k, l;
- int idxnew;
- int iflag = 0;
- int iptemp;
- int isdirn, izdota;
- int ivmc;
- int ivmd;
- int mp, np, iz, ibrnch;
- int nbest, ifull, iptem, jdrop;
- nlopt_result rc = NLOPT_SUCCESS;
- uint32_t seed = (uint32_t) (*n + *m); /* arbitrary deterministic LCG seed */
- int feasible;
-
- /* SGJ, 2008: added code to keep track of minimum feasible function val */
- *minf = HUGE_VAL;
-
-/* Set the initial values of some parameters. The last column of SIM holds */
-/* the optimal vertex of the current simplex, and the preceding N columns */
-/* hold the displacements from the optimal vertex to the other vertices. */
-/* Further, SIMI holds the inverse of the matrix that is contained in the */
-/* first N columns of SIM. */
-
- /* Parameter adjustments */
- a_dim1 = *n;
- a_offset = 1 + a_dim1 * 1;
- a -= a_offset;
- simi_dim1 = *n;
- simi_offset = 1 + simi_dim1 * 1;
- simi -= simi_offset;
- sim_dim1 = *n;
- sim_offset = 1 + sim_dim1 * 1;
- sim -= sim_offset;
- datmat_dim1 = *mpp;
- datmat_offset = 1 + datmat_dim1 * 1;
- datmat -= datmat_offset;
- --x;
- --con;
- --vsig;
- --veta;
- --sigbar;
- --dx;
- --w;
- --iact;
- --lb; --ub;
-
- /* Function Body */
- iptem = MIN2(*n,4);
- iptemp = iptem + 1;
- np = *n + 1;
- mp = *m + 1;
- alpha = .25;
- beta = 2.1;
- gamma_ = .5;
- delta = 1.1;
- rho = *rhobeg;
- parmu = 0.;
- if (*iprint >= 2) {
- fprintf(stderr,
- "cobyla: the initial value of RHO is %12.6E and PARMU is set to zero.\n",
- rho);
- }
- temp = 1. / rho;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- double rhocur;
- sim[i__ + np * sim_dim1] = x[i__];
- i__2 = *n;
- for (j = 1; j <= i__2; ++j) {
- sim[i__ + j * sim_dim1] = 0.;
- simi[i__ + j * simi_dim1] = 0.;
- }
- rhocur = rho;
-#if ENFORCE_BOUNDS
- /* SGJ: make sure step rhocur stays inside [lb,ub] */
- if (x[i__] + rhocur > ub[i__]) {
- if (x[i__] - rhocur >= lb[i__])
- rhocur = -rhocur;
- else if (ub[i__] - x[i__] > x[i__] - lb[i__])
- rhocur = 0.5 * (ub[i__] - x[i__]);
- else
- rhocur = 0.5 * (x[i__] - lb[i__]);
- }
-#endif
- sim[i__ + i__ * sim_dim1] = rhocur;
- simi[i__ + i__ * simi_dim1] = 1.0 / rhocur;
- }
- jdrop = np;
- ibrnch = 0;
-
-/* Make the next call of the user-supplied subroutine CALCFC. These */
-/* instructions are also used for calling CALCFC during the iterations of */
-/* the algorithm. */
-
- /* SGJ comment: why the hell couldn't he just use a damn subroutine?
- #*&!%*@ Fortran-66 spaghetti code */
-
-L40:
- if (nlopt_stop_forced(stop)) rc = NLOPT_FORCED_STOP;
- else if (stop->nevals > 0) {
- if (nlopt_stop_evals(stop)) rc = NLOPT_MAXEVAL_REACHED;
- else if (nlopt_stop_time(stop)) rc = NLOPT_MAXTIME_REACHED;
- }
- if (rc != NLOPT_SUCCESS) goto L600;
-
- stop->nevals++;
- if (calcfc(*n, *m, &x[1], &f, &con[1], state))
- {
- if (*iprint >= 1) {
- fprintf(stderr, "cobyla: user requested end of minimization.\n");
- }
- rc = NLOPT_FORCED_STOP;
- goto L600;
- }
-
- resmax = 0.;
- feasible = 1; /* SGJ, 2010 */
- if (*m > 0) {
- i__1 = *m;
- for (k = 1; k <= i__1; ++k) {
- d__1 = resmax, d__2 = -con[k];
- resmax = MAX2(d__1,d__2);
- if (d__2 > state->con_tol[k-1])
- feasible = 0; /* SGJ, 2010 */
- }
- }
-
- /* SGJ, 2008: check for minf_max reached by feasible point */
- if (f < stop->minf_max && feasible) {
- rc = NLOPT_MINF_MAX_REACHED;
- goto L620; /* not L600 because we want to use current x, f, resmax */
- }
-
- if (stop->nevals == *iprint - 1 || *iprint == 3) {
- fprintf(stderr, "cobyla: NFVALS = %4d, F =%13.6E, MAXCV =%13.6E\n",
- stop->nevals, f, resmax);
- i__1 = iptem;
- fprintf(stderr, "cobyla: X =");
- for (i__ = 1; i__ <= i__1; ++i__) {
- if (i__>1) fprintf(stderr, " ");
- fprintf(stderr, "%13.6E", x[i__]);
- }
- if (iptem < *n) {
- i__1 = *n;
- for (i__ = iptemp; i__ <= i__1; ++i__) {
- if (!((i__-1) % 4)) fprintf(stderr, "\ncobyla: ");
- fprintf(stderr, "%15.6E", x[i__]);
- }
- }
- fprintf(stderr, "\n");
- }
- con[mp] = f;
- con[*mpp] = resmax;
- if (ibrnch == 1) {
- goto L440;
- }
-
-/* Set the recently calculated function values in a column of DATMAT. This */
-/* array has a column for each vertex of the current simplex, the entries of */
-/* each column being the values of the constraint functions (if any) */
-/* followed by the objective function and the greatest constraint violation */
-/* at the vertex. */
-
- i__1 = *mpp;
- for (k = 1; k <= i__1; ++k) {
- datmat[k + jdrop * datmat_dim1] = con[k];
- }
- if (stop->nevals > np) {
- goto L130;
- }
-
-/* Exchange the new vertex of the initial simplex with the optimal vertex if */
-/* necessary. Then, if the initial simplex is not complete, pick its next */
-/* vertex and calculate the function values there. */
-
- if (jdrop <= *n) {
- if (datmat[mp + np * datmat_dim1] <= f) {
- x[jdrop] = sim[jdrop + np * sim_dim1];
- } else { /* improvement in function val */
- double rhocur = x[jdrop] - sim[jdrop + np * sim_dim1];
- /* SGJ: use rhocur instead of rho. In original code, rhocur == rho
- always, but I want to change this to ensure that simplex points
- fall within [lb,ub]. */
- sim[jdrop + np * sim_dim1] = x[jdrop];
- i__1 = *mpp;
- for (k = 1; k <= i__1; ++k) {
- datmat[k + jdrop * datmat_dim1] = datmat[k + np * datmat_dim1]
- ;
- datmat[k + np * datmat_dim1] = con[k];
- }
- i__1 = jdrop;
- for (k = 1; k <= i__1; ++k) {
- sim[jdrop + k * sim_dim1] = -rhocur;
- temp = 0.f;
- i__2 = jdrop;
- for (i__ = k; i__ <= i__2; ++i__) {
- temp -= simi[i__ + k * simi_dim1];
- }
- simi[jdrop + k * simi_dim1] = temp;
- }
- }
- }
- if (stop->nevals <= *n) { /* evaluating initial simplex */
- jdrop = stop->nevals;
- /* SGJ: was += rho, but using sim[jdrop,jdrop] enforces consistency
- if we change the stepsize above to stay in [lb,ub]. */
- x[jdrop] += sim[jdrop + jdrop * sim_dim1];
- goto L40;
- }
-L130:
- ibrnch = 1;
-
-/* Identify the optimal vertex of the current simplex. */
-
-L140:
- phimin = datmat[mp + np * datmat_dim1] + parmu * datmat[*mpp + np *
- datmat_dim1];
- nbest = np;
- i__1 = *n;
- for (j = 1; j <= i__1; ++j) {
- temp = datmat[mp + j * datmat_dim1] + parmu * datmat[*mpp + j *
- datmat_dim1];
- if (temp < phimin) {
- nbest = j;
- phimin = temp;
- } else if (temp == phimin && parmu == 0.) {
- if (datmat[*mpp + j * datmat_dim1] < datmat[*mpp + nbest *
- datmat_dim1]) {
- nbest = j;
- }
- }
- }
-
-/* Switch the best vertex into pole position if it is not there already, */
-/* and also update SIM, SIMI and DATMAT. */
-
- if (nbest <= *n) {
- i__1 = *mpp;
- for (i__ = 1; i__ <= i__1; ++i__) {
- temp = datmat[i__ + np * datmat_dim1];
- datmat[i__ + np * datmat_dim1] = datmat[i__ + nbest * datmat_dim1]
- ;
- datmat[i__ + nbest * datmat_dim1] = temp;
- }
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- temp = sim[i__ + nbest * sim_dim1];
- sim[i__ + nbest * sim_dim1] = 0.;
- sim[i__ + np * sim_dim1] += temp;
- tempa = 0.;
- i__2 = *n;
- for (k = 1; k <= i__2; ++k) {
- sim[i__ + k * sim_dim1] -= temp;
- tempa -= simi[k + i__ * simi_dim1];
- }
- simi[nbest + i__ * simi_dim1] = tempa;
- }
- }
-
-/* Make an error return if SIGI is a poor approximation to the inverse of */
-/* the leading N by N submatrix of SIG. */
-
- error = 0.;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- i__2 = *n;
- for (j = 1; j <= i__2; ++j) {
- temp = 0.;
- if (i__ == j) {
- temp += -1.;
- }
- i__3 = *n;
- for (k = 1; k <= i__3; ++k) if (sim[k + j * sim_dim1] != 0) {
- temp += simi[i__ + k * simi_dim1] * sim[k + j * sim_dim1];
- }
- d__1 = error, d__2 = fabs(temp);
- error = MAX2(d__1,d__2);
- }
- }
- if (error > .1) {
- if (*iprint >= 1) {
- fprintf(stderr, "cobyla: rounding errors are becoming damaging.\n");
- }
- rc = NLOPT_ROUNDOFF_LIMITED;
- goto L600;
- }
-
-/* Calculate the coefficients of the linear approximations to the objective */
-/* and constraint functions, placing minus the objective function gradient */
-/* after the constraint gradients in the array A. The vector W is used for */
-/* working space. */
-
- i__2 = mp;
- for (k = 1; k <= i__2; ++k) {
- con[k] = -datmat[k + np * datmat_dim1];
- i__1 = *n;
- for (j = 1; j <= i__1; ++j) {
- w[j] = datmat[k + j * datmat_dim1] + con[k];
- }
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- temp = 0.;
- i__3 = *n;
- for (j = 1; j <= i__3; ++j) {
- temp += w[j] * simi[j + i__ * simi_dim1];
- }
- if (k == mp) {
- temp = -temp;
- }
- a[i__ + k * a_dim1] = temp;
- }
- }
-
-/* Calculate the values of sigma and eta, and set IFLAG=0 if the current */
-/* simplex is not acceptable. */
-
- iflag = 1;
- parsig = alpha * rho;
- pareta = beta * rho;
- i__1 = *n;
- for (j = 1; j <= i__1; ++j) {
- wsig = 0.;
- weta = 0.;
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
- d__1 = simi[j + i__ * simi_dim1];
- wsig += d__1 * d__1;
- d__1 = sim[i__ + j * sim_dim1];
- weta += d__1 * d__1;
- }
- vsig[j] = 1. / sqrt(wsig);
- veta[j] = sqrt(weta);
- if (vsig[j] < parsig || veta[j] > pareta) {
- iflag = 0;
- }
- }
-
-/* If a new vertex is needed to improve acceptability, then decide which */
-/* vertex to drop from the simplex. */
-
- if (ibrnch == 1 || iflag == 1) {
- goto L370;
- }
- jdrop = 0;
- temp = pareta;
- i__1 = *n;
- for (j = 1; j <= i__1; ++j) {
- if (veta[j] > temp) {
- jdrop = j;
- temp = veta[j];
- }
- }
- if (jdrop == 0) {
- i__1 = *n;
- for (j = 1; j <= i__1; ++j) {
- if (vsig[j] < temp) {
- jdrop = j;
- temp = vsig[j];
- }
- }
- }
-
-/* Calculate the step to the new vertex and its sign. */
-
- temp = gamma_ * rho * vsig[jdrop];
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- dx[i__] = temp * simi[jdrop + i__ * simi_dim1];
- }
- cvmaxp = 0.;
- cvmaxm = 0.;
- i__1 = mp;
- for (k = 1; k <= i__1; ++k) {
- sum = 0.;
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
- sum += a[i__ + k * a_dim1] * dx[i__];
- }
- if (k < mp) {
- temp = datmat[k + np * datmat_dim1];
- d__1 = cvmaxp, d__2 = -sum - temp;
- cvmaxp = MAX2(d__1,d__2);
- d__1 = cvmaxm, d__2 = sum - temp;
- cvmaxm = MAX2(d__1,d__2);
- }
- }
- dxsign = 1.;
- if (parmu * (cvmaxp - cvmaxm) > sum + sum) {
- dxsign = -1.;
- }
-
-/* Update the elements of SIM and SIMI, and set the next X. */
-
- temp = 0.;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- /* SGJ, 2010: pseudo-randomize simplex steps (see LCG comments above) */
- dx[i__] = dxsign * dx[i__] * lcg_urand(&seed, 0.01, 1);
- /* SGJ: make sure dx step says in [lb,ub] */
-#if ENFORCE_BOUNDS
- {
- double xi = sim[i__ + np * sim_dim1];
- fixdx:
- if (xi + dx[i__] > ub[i__])
- dx[i__] = -dx[i__];
- if (xi + dx[i__] < lb[i__]) {
- if (xi - dx[i__] <= ub[i__])
- dx[i__] = -dx[i__];
- else { /* try again with halved step */
- dx[i__] *= 0.5;
- goto fixdx;
- }
- }
- }
-#endif
- sim[i__ + jdrop * sim_dim1] = dx[i__];
- temp += simi[jdrop + i__ * simi_dim1] * dx[i__];
- }
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- simi[jdrop + i__ * simi_dim1] /= temp;
- }
- i__1 = *n;
- for (j = 1; j <= i__1; ++j) {
- if (j != jdrop) {
- temp = 0.;
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
- temp += simi[j + i__ * simi_dim1] * dx[i__];
- }
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
- simi[j + i__ * simi_dim1] -= temp * simi[jdrop + i__ *
- simi_dim1];
- }
- }
- x[j] = sim[j + np * sim_dim1] + dx[j];
- }
- goto L40;
-
-/* Calculate DX=x(*)-x(0). Branch if the length of DX is less than 0.5*RHO. */
-
-L370:
- iz = 1;
- izdota = iz + *n * *n;
- ivmc = izdota + *n;
- isdirn = ivmc + mp;
- idxnew = isdirn + *n;
- ivmd = idxnew + *n;
- rc = trstlp(n, m, &a[a_offset], &con[1], &rho, &dx[1], &ifull, &iact[1], &w[
- iz], &w[izdota], &w[ivmc], &w[isdirn], &w[idxnew], &w[ivmd]);
- if (rc != NLOPT_SUCCESS) goto L600;
-#if ENFORCE_BOUNDS
- /* SGJ: since the bound constraints are linear, we should never get
- a dx that lies outside the [lb,ub] constraints here, but we'll
- enforce this anyway just to be paranoid */
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- double xi = sim[i__ + np * sim_dim1];
- if (xi + dx[i__] > ub[i__]) dx[i__] = ub[i__] - xi;
- if (xi + dx[i__] < lb[i__]) dx[i__] = xi - lb[i__];
- }
-#endif
- if (ifull == 0) {
- temp = 0.;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- d__1 = dx[i__];
- temp += d__1 * d__1;
- }
- if (temp < rho * .25 * rho) {
- ibrnch = 1;
- goto L550;
- }
- }
-
-/* Predict the change to F and the new maximum constraint violation if the */
-/* variables are altered from x(0) to x(0)+DX. */
-
- resnew = 0.;
- con[mp] = 0.;
- i__1 = mp;
- for (k = 1; k <= i__1; ++k) {
- sum = con[k];
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
- sum -= a[i__ + k * a_dim1] * dx[i__];
- }
- if (k < mp) {
- resnew = MAX2(resnew,sum);
- }
- }
-
-/* Increase PARMU if necessary and branch back if this change alters the */
-/* optimal vertex. Otherwise PREREM and PREREC will be set to the predicted */
-/* reductions in the merit function and the maximum constraint violation */
-/* respectively. */
-
- barmu = 0.;
- prerec = datmat[*mpp + np * datmat_dim1] - resnew;
- if (prerec > 0.) {
- barmu = sum / prerec;
- }
- if (parmu < barmu * 1.5) {
- parmu = barmu * 2.;
- if (*iprint >= 2) {
- fprintf(stderr, "cobyla: increase in PARMU to %12.6E\n", parmu);
- }
- phi = datmat[mp + np * datmat_dim1] + parmu * datmat[*mpp + np *
- datmat_dim1];
- i__1 = *n;
- for (j = 1; j <= i__1; ++j) {
- temp = datmat[mp + j * datmat_dim1] + parmu * datmat[*mpp + j *
- datmat_dim1];
- if (temp < phi) {
- goto L140;
- }
- if (temp == phi && parmu == 0.f) {
- if (datmat[*mpp + j * datmat_dim1] < datmat[*mpp + np *
- datmat_dim1]) {
- goto L140;
- }
- }
- }
- }
- prerem = parmu * prerec - sum;
-
-/* Calculate the constraint and objective functions at x(*). Then find the */
-/* actual reduction in the merit function. */
-
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- x[i__] = sim[i__ + np * sim_dim1] + dx[i__];
- }
- ibrnch = 1;
- goto L40;
-L440:
- vmold = datmat[mp + np * datmat_dim1] + parmu * datmat[*mpp + np *
- datmat_dim1];
- vmnew = f + parmu * resmax;
- trured = vmold - vmnew;
- if (parmu == 0. && f == datmat[mp + np * datmat_dim1]) {
- prerem = prerec;
- trured = datmat[*mpp + np * datmat_dim1] - resmax;
- }
-
-/* Begin the operations that decide whether x(*) should replace one of the */
-/* vertices of the current simplex, the change being mandatory if TRURED is */
-/* positive. Firstly, JDROP is set to the index of the vertex that is to be */
-/* replaced. */
-
- ratio = 0.;
- if (trured <= 0.f) {
- ratio = 1.f;
- }
- jdrop = 0;
- i__1 = *n;
- for (j = 1; j <= i__1; ++j) {
- temp = 0.;
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
- temp += simi[j + i__ * simi_dim1] * dx[i__];
- }
- temp = fabs(temp);
- if (temp > ratio) {
- jdrop = j;
- ratio = temp;
- }
- sigbar[j] = temp * vsig[j];
- }
-
-/* Calculate the value of ell. */
-
- edgmax = delta * rho;
- l = 0;
- i__1 = *n;
- for (j = 1; j <= i__1; ++j) {
- if (sigbar[j] >= parsig || sigbar[j] >= vsig[j]) {
- temp = veta[j];
- if (trured > 0.) {
- temp = 0.;
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
- d__1 = dx[i__] - sim[i__ + j * sim_dim1];
- temp += d__1 * d__1;
- }
- temp = sqrt(temp);
- }
- if (temp > edgmax) {
- l = j;
- edgmax = temp;
- }
- }
- }
- if (l > 0) {
- jdrop = l;
- }
- if (jdrop == 0) {
- goto L550;
- }
-
-/* Revise the simplex by updating the elements of SIM, SIMI and DATMAT. */
-
- temp = 0.;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- sim[i__ + jdrop * sim_dim1] = dx[i__];
- temp += simi[jdrop + i__ * simi_dim1] * dx[i__];
- }
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- simi[jdrop + i__ * simi_dim1] /= temp;
- }
- i__1 = *n;
- for (j = 1; j <= i__1; ++j) {
- if (j != jdrop) {
- temp = 0.;
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
- temp += simi[j + i__ * simi_dim1] * dx[i__];
- }
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
- simi[j + i__ * simi_dim1] -= temp * simi[jdrop + i__ *
- simi_dim1];
- }
- }
- }
- i__1 = *mpp;
- for (k = 1; k <= i__1; ++k) {
- datmat[k + jdrop * datmat_dim1] = con[k];
- }
-
-/* Branch back for further iterations with the current RHO. */
-
- if (trured > 0. && trured >= prerem * .1) {
- /* SGJ, 2010: following a suggestion in the SAS manual (which
- mentions a similar modification to COBYLA, although they didn't
- publish their source code), increase rho if predicted reduction
- is sufficiently close to the actual reduction. Otherwise,
- COBLYA seems to easily get stuck making very small steps.
- Also require iflag != 0 (i.e., acceptable simplex), again
- following SAS suggestion (otherwise I get convergence failure
- in some cases.) */
- if (trured >= prerem * 0.9 && trured <= prerem * 1.1 && iflag) {
- rho *= 2.0;
- }
- goto L140;
- }
-L550:
- if (iflag == 0) {
- ibrnch = 0;
- goto L140;
- }
-
- /* SGJ, 2008: convergence tests for function vals; note that current
- best val is stored in datmat[mp + np * datmat_dim1], or in f if
- ifull == 1, and previous best is in *minf. This seems like a
- sensible place to put the convergence test, as it is the same
- place that Powell checks the x tolerance (rho > rhoend). */
- {
- double fbest = ifull == 1 ? f : datmat[mp + np * datmat_dim1];
- if (fbest < *minf && nlopt_stop_ftol(stop, fbest, *minf)) {
- rc = NLOPT_FTOL_REACHED;
- goto L600;
- }
- *minf = fbest;
- }
-
-/* Otherwise reduce RHO if it is not at its least value and reset PARMU. */
-
- if (rho > rhoend) {
- rho *= .5;
- if (rho <= rhoend * 1.5) {
- rho = rhoend;
- }
- if (parmu > 0.) {
- denom = 0.;
- i__1 = mp;
- for (k = 1; k <= i__1; ++k) {
- cmin = datmat[k + np * datmat_dim1];
- cmax = cmin;
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
- d__1 = cmin, d__2 = datmat[k + i__ * datmat_dim1];
- cmin = MIN2(d__1,d__2);
- d__1 = cmax, d__2 = datmat[k + i__ * datmat_dim1];
- cmax = MAX2(d__1,d__2);
- }
- if (k <= *m && cmin < cmax * .5) {
- temp = MAX2(cmax,0.) - cmin;
- if (denom <= 0.) {
- denom = temp;
- } else {
- denom = MIN2(denom,temp);
- }
- }
- }
- if (denom == 0.) {
- parmu = 0.;
- } else if (cmax - cmin < parmu * denom) {
- parmu = (cmax - cmin) / denom;
- }
- }
- if (*iprint >= 2) {
- fprintf(stderr, "cobyla: reduction in RHO to %12.6E and PARMU =%13.6E\n",
- rho, parmu);
- }
- if (*iprint == 2) {
- fprintf(stderr, "cobyla: NFVALS = %4d, F =%13.6E, MAXCV =%13.6E\n",
- stop->nevals, datmat[mp + np * datmat_dim1], datmat[*mpp + np * datmat_dim1]);
-
- fprintf(stderr, "cobyla: X =");
- i__1 = iptem;
- for (i__ = 1; i__ <= i__1; ++i__) {
- if (i__>1) fprintf(stderr, " ");
- fprintf(stderr, "%13.6E", sim[i__ + np * sim_dim1]);
- }
- if (iptem < *n) {
- i__1 = *n;
- for (i__ = iptemp; i__ <= i__1; ++i__) {
- if (!((i__-1) % 4)) fprintf(stderr, "\ncobyla: ");
- fprintf(stderr, "%15.6E", x[i__]);
- }
- }
- fprintf(stderr, "\n");
- }
- goto L140;
- }
- else /* rho <= rhoend */
- rc = rhoend > 0 ? NLOPT_XTOL_REACHED : NLOPT_ROUNDOFF_LIMITED;
-
-/* Return the best calculated values of the variables. */
-
- if (*iprint >= 1) {
- fprintf(stderr, "cobyla: normal return.\n");
- }
- if (ifull == 1) {
- goto L620;
- }
-L600:
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- x[i__] = sim[i__ + np * sim_dim1];
- }
- f = datmat[mp + np * datmat_dim1];
- resmax = datmat[*mpp + np * datmat_dim1];
-L620:
- *minf = f;
- if (*iprint >= 1) {
- fprintf(stderr, "cobyla: NFVALS = %4d, F =%13.6E, MAXCV =%13.6E\n",
- stop->nevals, f, resmax);
- i__1 = iptem;
- fprintf(stderr, "cobyla: X =");
- for (i__ = 1; i__ <= i__1; ++i__) {
- if (i__>1) fprintf(stderr, " ");
- fprintf(stderr, "%13.6E", x[i__]);
- }
- if (iptem < *n) {
- i__1 = *n;
- for (i__ = iptemp; i__ <= i__1; ++i__) {
- if (!((i__-1) % 4)) fprintf(stderr, "\ncobyla: ");
- fprintf(stderr, "%15.6E", x[i__]);
- }
- }
- fprintf(stderr, "\n");
- }
- return rc;
-} /* cobylb */
-
-/* ------------------------------------------------------------------------- */
-static nlopt_result trstlp(int *n, int *m, double *a,
- double *b, double *rho, double *dx, int *ifull,
- int *iact, double *z__, double *zdota, double *vmultc,
- double *sdirn, double *dxnew, double *vmultd)
-{
- /* System generated locals */
- int a_dim1, a_offset, z_dim1, z_offset, i__1, i__2;
- double d__1, d__2;
-
- /* Local variables */
- double alpha, tempa;
- double beta;
- double optnew, stpful, sum, tot, acca, accb;
- double ratio, vsave, zdotv, zdotw, dd;
- double sd;
- double sp, ss, resold = 0.0, zdvabs, zdwabs, sumabs, resmax, optold;
- double spabs;
- double temp, step;
- int icount;
- int iout, i__, j, k;
- int isave;
- int kk;
- int kl, kp, kw;
- int nact, icon = 0, mcon;
- int nactx = 0;
-
-
-/* This subroutine calculates an N-component vector DX by applying the */
-/* following two stages. In the first stage, DX is set to the shortest */
-/* vector that minimizes the greatest violation of the constraints */
-/* A(1,K)*DX(1)+A(2,K)*DX(2)+...+A(N,K)*DX(N) .GE. B(K), K=2,3,...,M, */
-/* subject to the Euclidean length of DX being at most RHO. If its length is */
-/* strictly less than RHO, then we use the resultant freedom in DX to */
-/* minimize the objective function */
-/* -A(1,M+1)*DX(1)-A(2,M+1)*DX(2)-...-A(N,M+1)*DX(N) */
-/* subject to no increase in any greatest constraint violation. This */
-/* notation allows the gradient of the objective function to be regarded as */
-/* the gradient of a constraint. Therefore the two stages are distinguished */
-/* by MCON .EQ. M and MCON .GT. M respectively. It is possible that a */
-/* degeneracy may prevent DX from attaining the target length RHO. Then the */
-/* value IFULL=0 would be set, but usually IFULL=1 on return. */
-
-/* In general NACT is the number of constraints in the active set and */
-/* IACT(1),...,IACT(NACT) are their indices, while the remainder of IACT */
-/* contains a permutation of the remaining constraint indices. Further, Z is */
-/* an orthogonal matrix whose first NACT columns can be regarded as the */
-/* result of Gram-Schmidt applied to the active constraint gradients. For */
-/* J=1,2,...,NACT, the number ZDOTA(J) is the scalar product of the J-th */
-/* column of Z with the gradient of the J-th active constraint. DX is the */
-/* current vector of variables and here the residuals of the active */
-/* constraints should be zero. Further, the active constraints have */
-/* nonnegative Lagrange multipliers that are held at the beginning of */
-/* VMULTC. The remainder of this vector holds the residuals of the inactive */
-/* constraints at DX, the ordering of the components of VMULTC being in */
-/* agreement with the permutation of the indices of the constraints that is */
-/* in IACT. All these residuals are nonnegative, which is achieved by the */
-/* shift RESMAX that makes the least residual zero. */
-
-/* Initialize Z and some other variables. The value of RESMAX will be */
-/* appropriate to DX=0, while ICON will be the index of a most violated */
-/* constraint if RESMAX is positive. Usually during the first stage the */
-/* vector SDIRN gives a search direction that reduces all the active */
-/* constraint violations by one simultaneously. */
-
- /* Parameter adjustments */
- z_dim1 = *n;
- z_offset = 1 + z_dim1 * 1;
- z__ -= z_offset;
- a_dim1 = *n;
- a_offset = 1 + a_dim1 * 1;
- a -= a_offset;
- --b;
- --dx;
- --iact;
- --zdota;
- --vmultc;
- --sdirn;
- --dxnew;
- --vmultd;
-
- /* Function Body */
- *ifull = 1;
- mcon = *m;
- nact = 0;
- resmax = 0.;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- i__2 = *n;
- for (j = 1; j <= i__2; ++j) {
- z__[i__ + j * z_dim1] = 0.;
- }
- z__[i__ + i__ * z_dim1] = 1.;
- dx[i__] = 0.;
- }
- if (*m >= 1) {
- i__1 = *m;
- for (k = 1; k <= i__1; ++k) {
- if (b[k] > resmax) {
- resmax = b[k];
- icon = k;
- }
- }
- i__1 = *m;
- for (k = 1; k <= i__1; ++k) {
- iact[k] = k;
- vmultc[k] = resmax - b[k];
- }
- }
- if (resmax == 0.) {
- goto L480;
- }
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- sdirn[i__] = 0.;
- }
-
-/* End the current stage of the calculation if 3 consecutive iterations */
-/* have either failed to reduce the best calculated value of the objective */
-/* function or to increase the number of active constraints since the best */
-/* value was calculated. This strategy prevents cycling, but there is a */
-/* remote possibility that it will cause premature termination. */
-
-L60:
- optold = 0.;
- icount = 0;
-L70:
- if (mcon == *m) {
- optnew = resmax;
- } else {
- optnew = 0.;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- optnew -= dx[i__] * a[i__ + mcon * a_dim1];
- }
- }
- if (icount == 0 || optnew < optold) {
- optold = optnew;
- nactx = nact;
- icount = 3;
- } else if (nact > nactx) {
- nactx = nact;
- icount = 3;
- } else {
- --icount;
- if (icount == 0) {
- goto L490;
- }
- }
-
-/* If ICON exceeds NACT, then we add the constraint with index IACT(ICON) to */
-/* the active set. Apply Givens rotations so that the last N-NACT-1 columns */
-/* of Z are orthogonal to the gradient of the new constraint, a scalar */
-/* product being set to zero if its nonzero value could be due to computer */
-/* rounding errors. The array DXNEW is used for working space. */
-
- if (icon <= nact) {
- goto L260;
- }
- kk = iact[icon];
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- dxnew[i__] = a[i__ + kk * a_dim1];
- }
- tot = 0.;
- k = *n;
-L100:
- if (k > nact) {
- sp = 0.;
- spabs = 0.;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- temp = z__[i__ + k * z_dim1] * dxnew[i__];
- sp += temp;
- spabs += fabs(temp);
- }
- acca = spabs + fabs(sp) * .1;
- accb = spabs + fabs(sp) * .2;
- if (spabs >= acca || acca >= accb) {
- sp = 0.;
- }
- if (tot == 0.) {
- tot = sp;
- } else {
- kp = k + 1;
- temp = sqrt(sp * sp + tot * tot);
- alpha = sp / temp;
- beta = tot / temp;
- tot = temp;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- temp = alpha * z__[i__ + k * z_dim1] + beta * z__[i__ + kp *
- z_dim1];
- z__[i__ + kp * z_dim1] = alpha * z__[i__ + kp * z_dim1] -
- beta * z__[i__ + k * z_dim1];
- z__[i__ + k * z_dim1] = temp;
- }
- }
- --k;
- goto L100;
- }
-
-/* Add the new constraint if this can be done without a deletion from the */
-/* active set. */
-
- if (tot != 0.) {
- ++nact;
- zdota[nact] = tot;
- vmultc[icon] = vmultc[nact];
- vmultc[nact] = 0.;
- goto L210;
- }
-
-/* The next instruction is reached if a deletion has to be made from the */
-/* active set in order to make room for the new active constraint, because */
-/* the new constraint gradient is a linear combination of the gradients of */
-/* the old active constraints. Set the elements of VMULTD to the multipliers */
-/* of the linear combination. Further, set IOUT to the index of the */
-/* constraint to be deleted, but branch if no suitable index can be found. */
-
- ratio = -1.;
- k = nact;
-L130:
- zdotv = 0.;
- zdvabs = 0.;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- temp = z__[i__ + k * z_dim1] * dxnew[i__];
- zdotv += temp;
- zdvabs += fabs(temp);
- }
- acca = zdvabs + fabs(zdotv) * .1;
- accb = zdvabs + fabs(zdotv) * .2;
- if (zdvabs < acca && acca < accb) {
- temp = zdotv / zdota[k];
- if (temp > 0. && iact[k] <= *m) {
- tempa = vmultc[k] / temp;
- if (ratio < 0. || tempa < ratio) {
- ratio = tempa;
- iout = k;
- }
- }
- if (k >= 2) {
- kw = iact[k];
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- dxnew[i__] -= temp * a[i__ + kw * a_dim1];
- }
- }
- vmultd[k] = temp;
- } else {
- vmultd[k] = 0.;
- }
- --k;
- if (k > 0) {
- goto L130;
- }
- if (ratio < 0.) {
- goto L490;
- }
-
-/* Revise the Lagrange multipliers and reorder the active constraints so */
-/* that the one to be replaced is at the end of the list. Also calculate the */
-/* new value of ZDOTA(NACT) and branch if it is not acceptable. */
-
- i__1 = nact;
- for (k = 1; k <= i__1; ++k) {
- d__1 = 0., d__2 = vmultc[k] - ratio * vmultd[k];
- vmultc[k] = MAX2(d__1,d__2);
- }
- if (icon < nact) {
- isave = iact[icon];
- vsave = vmultc[icon];
- k = icon;
-L170:
- kp = k + 1;
- kw = iact[kp];
- sp = 0.;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- sp += z__[i__ + k * z_dim1] * a[i__ + kw * a_dim1];
- }
- d__1 = zdota[kp];
- temp = sqrt(sp * sp + d__1 * d__1);
- alpha = zdota[kp] / temp;
- beta = sp / temp;
- zdota[kp] = alpha * zdota[k];
- zdota[k] = temp;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- temp = alpha * z__[i__ + kp * z_dim1] + beta * z__[i__ + k *
- z_dim1];
- z__[i__ + kp * z_dim1] = alpha * z__[i__ + k * z_dim1] - beta *
- z__[i__ + kp * z_dim1];
- z__[i__ + k * z_dim1] = temp;
- }
- iact[k] = kw;
- vmultc[k] = vmultc[kp];
- k = kp;
- if (k < nact) {
- goto L170;
- }
- iact[k] = isave;
- vmultc[k] = vsave;
- }
- temp = 0.;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- temp += z__[i__ + nact * z_dim1] * a[i__ + kk * a_dim1];
- }
- if (temp == 0.) {
- goto L490;
- }
- zdota[nact] = temp;
- vmultc[icon] = 0.;
- vmultc[nact] = ratio;
-
-/* Update IACT and ensure that the objective function continues to be */
-/* treated as the last active constraint when MCON>M. */
-
-L210:
- iact[icon] = iact[nact];
- iact[nact] = kk;
- if (mcon > *m && kk != mcon) {
- k = nact - 1;
- sp = 0.;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- sp += z__[i__ + k * z_dim1] * a[i__ + kk * a_dim1];
- }
- d__1 = zdota[nact];
- temp = sqrt(sp * sp + d__1 * d__1);
- alpha = zdota[nact] / temp;
- beta = sp / temp;
- zdota[nact] = alpha * zdota[k];
- zdota[k] = temp;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- temp = alpha * z__[i__ + nact * z_dim1] + beta * z__[i__ + k *
- z_dim1];
- z__[i__ + nact * z_dim1] = alpha * z__[i__ + k * z_dim1] - beta *
- z__[i__ + nact * z_dim1];
- z__[i__ + k * z_dim1] = temp;
- }
- iact[nact] = iact[k];
- iact[k] = kk;
- temp = vmultc[k];
- vmultc[k] = vmultc[nact];
- vmultc[nact] = temp;
- }
-
-/* If stage one is in progress, then set SDIRN to the direction of the next */
-/* change to the current vector of variables. */
-
- if (mcon > *m) {
- goto L320;
- }
- kk = iact[nact];
- temp = 0.;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- temp += sdirn[i__] * a[i__ + kk * a_dim1];
- }
- temp += -1.;
- temp /= zdota[nact];
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- sdirn[i__] -= temp * z__[i__ + nact * z_dim1];
- }
- goto L340;
-
-/* Delete the constraint that has the index IACT(ICON) from the active set. */
-
-L260:
- if (icon < nact) {
- isave = iact[icon];
- vsave = vmultc[icon];
- k = icon;
-L270:
- kp = k + 1;
- kk = iact[kp];
- sp = 0.;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- sp += z__[i__ + k * z_dim1] * a[i__ + kk * a_dim1];
- }
- d__1 = zdota[kp];
- temp = sqrt(sp * sp + d__1 * d__1);
- alpha = zdota[kp] / temp;
- beta = sp / temp;
- zdota[kp] = alpha * zdota[k];
- zdota[k] = temp;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- temp = alpha * z__[i__ + kp * z_dim1] + beta * z__[i__ + k *
- z_dim1];
- z__[i__ + kp * z_dim1] = alpha * z__[i__ + k * z_dim1] - beta *
- z__[i__ + kp * z_dim1];
- z__[i__ + k * z_dim1] = temp;
- }
- iact[k] = kk;
- vmultc[k] = vmultc[kp];
- k = kp;
- if (k < nact) {
- goto L270;
- }
- iact[k] = isave;
- vmultc[k] = vsave;
- }
- --nact;
-
-/* If stage one is in progress, then set SDIRN to the direction of the next */
-/* change to the current vector of variables. */
-
- if (mcon > *m) {
- goto L320;
- }
- temp = 0.;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- temp += sdirn[i__] * z__[i__ + (nact + 1) * z_dim1];
- }
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- sdirn[i__] -= temp * z__[i__ + (nact + 1) * z_dim1];
- }
- goto L340;
-
-/* Pick the next search direction of stage two. */
-
-L320:
- temp = 1. / zdota[nact];
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- sdirn[i__] = temp * z__[i__ + nact * z_dim1];
- }
-
-/* Calculate the step to the boundary of the trust region or take the step */
-/* that reduces RESMAX to zero. The two statements below that include the */
-/* factor 1.0E-6 prevent some harmless underflows that occurred in a test */
-/* calculation. Further, we skip the step if it could be zero within a */
-/* reasonable tolerance for computer rounding errors. */
-
-L340:
- dd = *rho * *rho;
- sd = 0.;
- ss = 0.;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- if ((d__1 = dx[i__], fabs(d__1)) >= *rho * 1e-6f) {
- d__2 = dx[i__];
- dd -= d__2 * d__2;
- }
- sd += dx[i__] * sdirn[i__];
- d__1 = sdirn[i__];
- ss += d__1 * d__1;
- }
- if (dd <= 0.) {
- goto L490;
- }
- temp = sqrt(ss * dd);
- if (fabs(sd) >= temp * 1e-6f) {
- temp = sqrt(ss * dd + sd * sd);
- }
- stpful = dd / (temp + sd);
- step = stpful;
- if (mcon == *m) {
- acca = step + resmax * .1;
- accb = step + resmax * .2;
- if (step >= acca || acca >= accb) {
- goto L480;
- }
- step = MIN2(step,resmax);
- }
-
- /* SGJ, 2010: check for error here */
- if (nlopt_isinf(step)) return NLOPT_ROUNDOFF_LIMITED;
-
-/* Set DXNEW to the new variables if STEP is the steplength, and reduce */
-/* RESMAX to the corresponding maximum residual if stage one is being done. */
-/* Because DXNEW will be changed during the calculation of some Lagrange */
-/* multipliers, it will be restored to the following value later. */
-
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- dxnew[i__] = dx[i__] + step * sdirn[i__];
- }
- if (mcon == *m) {
- resold = resmax;
- resmax = 0.;
- i__1 = nact;
- for (k = 1; k <= i__1; ++k) {
- kk = iact[k];
- temp = b[kk];
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
- temp -= a[i__ + kk * a_dim1] * dxnew[i__];
- }
- resmax = MAX2(resmax,temp);
- }
- }
-
-/* Set VMULTD to the VMULTC vector that would occur if DX became DXNEW. A */
-/* device is included to force VMULTD(K)=0.0 if deviations from this value */
-/* can be attributed to computer rounding errors. First calculate the new */
-/* Lagrange multipliers. */
-
- k = nact;
-L390:
- zdotw = 0.;
- zdwabs = 0.;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- temp = z__[i__ + k * z_dim1] * dxnew[i__];
- zdotw += temp;
- zdwabs += fabs(temp);
- }
- acca = zdwabs + fabs(zdotw) * .1;
- accb = zdwabs + fabs(zdotw) * .2;
- if (zdwabs >= acca || acca >= accb) {
- zdotw = 0.;
- }
- vmultd[k] = zdotw / zdota[k];
- if (k >= 2) {
- kk = iact[k];
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- dxnew[i__] -= vmultd[k] * a[i__ + kk * a_dim1];
- }
- --k;
- goto L390;
- }
- if (mcon > *m) {
- d__1 = 0., d__2 = vmultd[nact];
- vmultd[nact] = MAX2(d__1,d__2);
- }
-
-/* Complete VMULTC by finding the new constraint residuals. */
-
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- dxnew[i__] = dx[i__] + step * sdirn[i__];
- }
- if (mcon > nact) {
- kl = nact + 1;
- i__1 = mcon;
- for (k = kl; k <= i__1; ++k) {
- kk = iact[k];
- sum = resmax - b[kk];
- sumabs = resmax + (d__1 = b[kk], fabs(d__1));
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
- temp = a[i__ + kk * a_dim1] * dxnew[i__];
- sum += temp;
- sumabs += fabs(temp);
- }
- acca = sumabs + fabs(sum) * .1f;
- accb = sumabs + fabs(sum) * .2f;
- if (sumabs >= acca || acca >= accb) {
- sum = 0.f;
- }
- vmultd[k] = sum;
- }
- }
-
-/* Calculate the fraction of the step from DX to DXNEW that will be taken. */
-
- ratio = 1.;
- icon = 0;
- i__1 = mcon;
- for (k = 1; k <= i__1; ++k) {
- if (vmultd[k] < 0.) {
- temp = vmultc[k] / (vmultc[k] - vmultd[k]);
- if (temp < ratio) {
- ratio = temp;
- icon = k;
- }
- }
- }
-
-/* Update DX, VMULTC and RESMAX. */
-
- temp = 1. - ratio;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- dx[i__] = temp * dx[i__] + ratio * dxnew[i__];
- }
- i__1 = mcon;
- for (k = 1; k <= i__1; ++k) {
- d__1 = 0., d__2 = temp * vmultc[k] + ratio * vmultd[k];
- vmultc[k] = MAX2(d__1,d__2);
- }
- if (mcon == *m) {
- resmax = resold + ratio * (resmax - resold);
- }
-
-/* If the full step is not acceptable then begin another iteration. */
-/* Otherwise switch to stage two or end the calculation. */
-
- if (icon > 0) {
- goto L70;
- }
- if (step == stpful) {
- goto L500;
- }
-L480:
- mcon = *m + 1;
- icon = mcon;
- iact[mcon] = mcon;
- vmultc[mcon] = 0.;
- goto L60;
-
-/* We employ any freedom that may be available to reduce the objective */
-/* function before returning a DX whose length is less than RHO. */
-
-L490:
- if (mcon == *m) {
- goto L480;
- }
- *ifull = 0;
-L500:
- return NLOPT_SUCCESS;
-} /* trstlp */
diff --git a/ext/src/nlopt/crs/README b/ext/src/nlopt/crs/README
deleted file mode 100644
index beaad8b..0000000
--- a/ext/src/nlopt/crs/README
+++ /dev/null
@@ -1,19 +0,0 @@
-This is my implementation of the "controlled random search" (CRS2) algorithm
-with the "local mutation" modification, as defined by:
-
- P. Kaelo and M. M. Ali, "Some variants of the controlled random
- search algorithm for global optimization," J. Optim. Theory Appl.
- 130 (2), 253-264 (2006).
-
-The original CRS2 algorithm was described by:
-
- W. L. Price, "A controlled random search procedure for global
- optimization," in Towards Global Optimization 2, p. 71-84
- edited by L. C. W. Dixon and G. P. Szego (North-Holland Press,
- Amsterdam, 1978).
-
-It is under the same MIT license as the rest of my code in NLopt (see
-../COPYRIGHT).
-
-Steven G. Johnson
-September 2007
diff --git a/ext/src/nlopt/crs/crs.c b/ext/src/nlopt/crs/crs.c
deleted file mode 100644
index e472789..0000000
--- a/ext/src/nlopt/crs/crs.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/* Copyright (c) 2007-2012 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "nlopt/crs.h"
-#include "nlopt/redblack.h"
-
-/* Controlled Random Search 2 (CRS2) with "local mutation", as defined
- by:
- P. Kaelo and M. M. Ali, "Some variants of the controlled random
- search algorithm for global optimization," J. Optim. Theory Appl.
- 130 (2), 253-264 (2006).
-*/
-
-typedef struct {
- int n; /* # dimensions */
- const double *lb, *ub;
- nlopt_stopping *stop; /* stopping criteria */
- nlopt_func f; void *f_data;
-
- int N; /* # points in population */
- double *ps; /* population array N x (n+1) of tuples [f(x), x] */
- double *p; /* single point array (length n+1), for temp use */
- rb_tree t; /* red-black tree of population, sorted by f(x) */
- nlopt_sobol s; /* sobol data for LDS point generation, or NULL
- to use pseudo-random numbers */
-} crs_data;
-
-/* sort order in red-black tree: keys [f(x), x] are sorted by f(x) */
-static int crs_compare(double *k1, double *k2)
-{
- if (*k1 < *k2) return -1;
- if (*k1 > *k2) return +1;
- return k1 - k2; /* tie-breaker */
-}
-
-/* set x to a random trial value, as defined by CRS:
- x = 2G - x_n,
- where x_0 ... x_n are distinct points in the population
- with x_0 the current best point and the other points are random,
- and G is the centroid of x_0...x_{n-1} */
-static void random_trial(crs_data *d, double *x, rb_node *best)
-{
- int n = d->n, n1 = n+1, i, k, i0, jn;
- double *ps = d->ps, *xi;
-
- /* initialize x to x_0 = best point */
- memcpy(x, best->k + 1, sizeof(double) * n);
- i0 = (best->k - ps) / n1;
-
- jn = nlopt_iurand(n); /* which of remaining n points is "x_n",
- i.e. which to reflect through ...
- this is necessary since we generate
- the remaining points in order, so
- just picking the last point would not
- be very random */
-
- /* use "method A" from
-
- Jeffrey Scott Vitter, "An efficient algorithm for
- sequential random sampling," ACM Trans. Math. Soft. 13 (1),
- 58--67 (1987).
-
- to randomly pick n distinct points out of the remaining N-1 (not
- including i0!). (The same as "method S" in Knuth vol. 2.)
- This method requires O(N) time, which is fine in our case
- (there are better methods if n << N). */
- {
- int Nleft = d->N - 1, nleft = n;
- int Nfree = Nleft - nleft;
- i = 0; i += i == i0;
- while (nleft > 1) {
- double q = ((double) Nfree) / Nleft;
- double v = nlopt_urand(0., 1.);
- while (q > v) {
- ++i; i += i == i0;
- --Nfree; --Nleft;
- q = (q * Nfree) / Nleft;
- }
- xi = ps + n1 * i + 1;
- if (jn-- == 0) /* point to reflect through */
- for (k = 0; k < n; ++k) x[k] -= xi[k] * (0.5*n);
- else /* point to include in centroid */
- for (k = 0; k < n; ++k) x[k] += xi[k];
- ++i; i += i == i0;
- --Nleft; --nleft;
- }
- i += nlopt_iurand(Nleft); i += i == i0;
- xi = ps + n1 * i + 1;
- if (jn-- == 0) /* point to reflect through */
- for (k = 0; k < n; ++k) x[k] -= xi[k] * (0.5*n);
- else /* point to include in centroid */
- for (k = 0; k < n; ++k) x[k] += xi[k];
- }
- for (k = 0; k < n; ++k) {
- x[k] *= 2.0 / n; /* renormalize */
- if (x[k] > d->ub[k]) x[k] = d->ub[k];
- else if (x[k] < d->lb[k]) x[k] = d->lb[k];
- }
-}
-
-#define NUM_MUTATION 1 /* # "local mutation" steps to try if trial fails */
-
-static nlopt_result crs_trial(crs_data *d)
-{
- rb_node *best = rb_tree_min(&d->t);
- rb_node *worst = rb_tree_max(&d->t);
- int mutation = NUM_MUTATION;
- int i, n = d->n;
- random_trial(d, d->p + 1, best);
- do {
- d->p[0] = d->f(n, d->p + 1, NULL, d->f_data);
- d->stop->nevals++;
- if (nlopt_stop_forced(d->stop)) return NLOPT_FORCED_STOP;
- if (d->p[0] < worst->k[0]) break;
- if (nlopt_stop_evals(d->stop)) return NLOPT_MAXEVAL_REACHED;
- if (nlopt_stop_time(d->stop)) return NLOPT_MAXTIME_REACHED;
- if (mutation) {
- for (i = 0; i < n; ++i) {
- double w = nlopt_urand(0.,1.);
- d->p[1+i] = best->k[1+i] * (1 + w) - w * d->p[1+i];
- if (d->p[1+i] > d->ub[i]) d->p[1+i] = d->ub[i];
- else if (d->p[1+i] < d->lb[i]) d->p[1+i] = d->lb[i];
- }
- mutation--;
- }
- else {
- random_trial(d, d->p + 1, best);
- mutation = NUM_MUTATION;
- }
- } while (1);
- memcpy(worst->k, d->p, sizeof(double) * (n+1));
- rb_tree_resort(&d->t, worst);
- return NLOPT_SUCCESS;
-}
-
-static void crs_destroy(crs_data *d)
-{
- nlopt_sobol_destroy(d->s);
- rb_tree_destroy(&d->t);
- free(d->ps);
-}
-
-static nlopt_result crs_init(crs_data *d, int n, const double *x,
- const double *lb, const double *ub,
- nlopt_stopping *stop, nlopt_func f, void *f_data,
- int population, int lds)
-{
- int i;
-
- if (!population) {
- /* TODO: how should we set the default population size?
- the Kaelo and Ali paper suggests 10*(n+1), but should
- we add more random points if maxeval is large, or... ? */
- d->N = 10 * (n + 1); /* heuristic initial population size */
- }
- else
- d->N = population;
- if (d->N < n + 1) /* population must be big enough for a simplex */
- return NLOPT_INVALID_ARGS;
-
- d->n = n;
- d->stop = stop;
- d->f = f; d->f_data = f_data;
- d->ub = ub; d->lb = lb;
- d->ps = (double *) malloc(sizeof(double) * (n + 1) * (d->N + 1));
- if (!d->ps) return NLOPT_OUT_OF_MEMORY;
- d->p = d->ps + d->N * (n+1);
- rb_tree_init(&d->t, crs_compare);
-
- /* we can either use pseudorandom points, as in the original CRS
- algorithm, or use a low-discrepancy Sobol' sequence ... I tried
- the latter, however, and it doesn't seem to help, probably
- because we are only generating a small number of random points
- to start with */
- d->s = lds ? nlopt_sobol_create((unsigned) n) : NULL;
- nlopt_sobol_skip(d->s, (unsigned) d->N, d->ps + 1);
-
- /* generate initial points randomly, plus starting guess x */
- memcpy(d->ps + 1, x, sizeof(double) * n);
- d->ps[0] = f(n, x, NULL, f_data);
- stop->nevals++;
- if (!rb_tree_insert(&d->t, d->ps)) return NLOPT_OUT_OF_MEMORY;
- if (d->ps[0] < stop->minf_max) return NLOPT_MINF_MAX_REACHED;
- if (nlopt_stop_evals(stop)) return NLOPT_MAXEVAL_REACHED;
- if (nlopt_stop_time(stop)) return NLOPT_MAXTIME_REACHED;
- for (i = 1; i < d->N; ++i) {
- double *k = d->ps + i*(n+1);
- if (d->s)
- nlopt_sobol_next(d->s, k + 1, lb, ub);
- else {
- int j;
- for (j = 0; j < n; ++j)
- k[1 + j] = nlopt_urand(lb[j], ub[j]);
- }
- k[0] = f(n, k + 1, NULL, f_data);
- stop->nevals++;
- if (!rb_tree_insert(&d->t, k)) return NLOPT_OUT_OF_MEMORY;
- if (k[0] < stop->minf_max) return NLOPT_MINF_MAX_REACHED;
- if (nlopt_stop_evals(stop)) return NLOPT_MAXEVAL_REACHED;
- if (nlopt_stop_time(stop)) return NLOPT_MAXTIME_REACHED;
- }
-
- return NLOPT_SUCCESS;;
-}
-
-nlopt_result crs_minimize(int n, nlopt_func f, void *f_data,
- const double *lb, const double *ub, /* bounds */
- double *x, /* in: initial guess, out: minimizer */
- double *minf,
- nlopt_stopping *stop,
- int population, /* initial population (0=default) */
- int lds) /* random or low-discrepancy seq. (lds) */
-{
- nlopt_result ret;
- crs_data d;
- rb_node *best;
-
- ret = crs_init(&d, n, x, lb, ub, stop, f, f_data, population, lds);
- if (ret < 0) return ret;
-
- best = rb_tree_min(&d.t);
- *minf = best->k[0];
- memcpy(x, best->k + 1, sizeof(double) * n);
-
- while (ret == NLOPT_SUCCESS) {
- if (NLOPT_SUCCESS == (ret = crs_trial(&d))) {
- best = rb_tree_min(&d.t);
- if (best->k[0] < *minf) {
- if (best->k[0] < stop->minf_max)
- ret = NLOPT_MINF_MAX_REACHED;
- else if (nlopt_stop_f(stop, best->k[0], *minf))
- ret = NLOPT_FTOL_REACHED;
- else if (nlopt_stop_x(stop, best->k + 1, x))
- ret = NLOPT_XTOL_REACHED;
- *minf = best->k[0];
- memcpy(x, best->k + 1, sizeof(double) * n);
- }
- if (ret != NLOPT_SUCCESS) {
- if (nlopt_stop_evals(stop))
- ret = NLOPT_MAXEVAL_REACHED;
- else if (nlopt_stop_time(stop))
- ret = NLOPT_MAXTIME_REACHED;
- }
- }
- }
- crs_destroy(&d);
- return ret;
-}
diff --git a/ext/src/nlopt/esch/COPYRIGHT b/ext/src/nlopt/esch/COPYRIGHT
deleted file mode 100644
index e00ee0d..0000000
--- a/ext/src/nlopt/esch/COPYRIGHT
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Copyright (c) 2008-2013 Carlos Henrique da Silva Santos
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
diff --git a/ext/src/nlopt/esch/README b/ext/src/nlopt/esch/README
deleted file mode 100644
index 8ea4ec6..0000000
--- a/ext/src/nlopt/esch/README
+++ /dev/null
@@ -1,27 +0,0 @@
-This is Carlos Henrique da Silva Santos's implementation of
-a modified version of the Evolutionary Algorithm described in
-the following paper and Ph.D. thesis:
-
- C. H. da Silva Santos, M. S. Gonçalves, and H. E. Hernandez-Figueroa,
- "Designing Novel Photonic Devices by Bio-Inspired Computing,"
- IEEE Photonics Technology Letters 22(15), pp. 1177-1179 (2010).
-
- C. H. da Silva Santos, "Parallel and Bio-Inspired Computing
- Applied to Analyze Microwave and Photonic Metamaterial Strucutures,"
- University of Campinas, (2010)
- http://www.bibliotecadigital.unicamp.br/document/?code=000767537&opt=4&lg=en_US
-
-The algorithms are adapted from ideas described in:
-
- H.-G. Beyer and H.-P. Schwefel. Evolution Strategies: A Comprehensive Introduction. Journal Natural Computing, 1(1):3–52, 2002.
-
- Ingo Rechenberg (1971): Evolutionsstrategie – Optimierung technischer Systeme nach Prinzipien der biologischen Evolution (PhD thesis). Reprinted by Fromman-Holzboog (1973).
-
-It is distributed under the "MIT license" given in the attached
-COPYRIGHT file (similar to the rest of NLopt), and was
-supportedfinancially by the São Paulo Science Foundation (FAPESP -
-Fundação de Amparo à Pesquisa do Estado de São Paulo) under the grant
-2012/14553-9.
-
-Carlos Henrique da Silva Santos
-January 2013
diff --git a/ext/src/nlopt/esch/esch.c b/ext/src/nlopt/esch/esch.c
deleted file mode 100644
index 02f5842..0000000
--- a/ext/src/nlopt/esch/esch.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/* Copyright (c) 2008-2013 Carlos Henrique da Silva Santos
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include "nlopt/esch.h"
-
-// ---------------------------------------------------------------------------
-// Cauchy random number distribution
-static double randcauchy(const double params[7]) {
- /* double min, double max, double mi, double t, double band */
- double na_unif, cauchy_mit, limit_inf, limit_sup;
- double valor;
- double min = params[1], max = params[2], mi = params[3],
- t = params[4], band = params[5];
- limit_inf = mi - (band/2);
- limit_sup = mi + (band/2);
- do {
- na_unif = nlopt_urand(0,1); // ran2(0,1);
- cauchy_mit = t*tan((na_unif-(1/2))*M_PI) + mi;
- } while ( (cauchy_mit<limit_inf) || (cauchy_mit>limit_sup) );
-
- if (cauchy_mit < 0)
- cauchy_mit = -cauchy_mit;
- else
- cauchy_mit = cauchy_mit + (band/2);
- valor = (cauchy_mit*100/band)/100;
- valor = min+(max-min)*valor;
- return valor;
-}
-
-// ---------------------------------------------------------------------------
-
-// main Individual representation type
-typedef struct IndividualStructure {
- double * parameters;
- double fitness;
-} Individual;
-
-static int CompareIndividuals(void *unused, const void *a_, const void *b_) {
- (void) unused;
- const Individual *a = (const Individual *) a_;
- const Individual *b = (const Individual *) b_;
- return a->fitness < b->fitness ? -1 : (a->fitness > b->fitness ? +1 : 0);
-}
-
-nlopt_result chevolutionarystrategy(
- unsigned nparameters, /* Number of input parameters */
- nlopt_func f, /* Recursive Objective Funtion Call */
- void * data_f, /* Data to Objective Function */
- const double* lb, /* Lower bound values */
- const double* ub, /* Upper bound values */
- double* x, /*in: initial guess, out: minimizer */
- double* minf,
- nlopt_stopping* stop, /* nlopt stop condition */
- unsigned np, /* Number of Parents */
- unsigned no) { /* Number of Offsprings */
-
- // variables from nlopt
- nlopt_result ret = NLOPT_SUCCESS;
- double vetor[8];
- unsigned i, id, item;
- int parent1, parent2;
- unsigned crosspoint; // crossover parameteres
- int contmutation, totalmutation; // mutation parameters
- int idoffmutation, paramoffmutation; // mutation parameters
- Individual * esparents; // Parents population
- Individual * esoffsprings; // Offsprings population
- Individual * estotal;// copy containing Parents and Offsprings pops
- /* It is interesting to maintain the parents and offsprings
- * populations stablished and sorted; when the final iterations
- * is achieved, they are ranked and updated. */
-
- // -------------------------------
- // controling the population size
- // -------------------------------
- if (!np) np = 40;
- if (!no) no = 60;
- if ((np < 1)||(no<1)) return NLOPT_INVALID_ARGS;
- esparents = (Individual*) malloc(sizeof(Individual) * np);
- esoffsprings = (Individual*) malloc(sizeof(Individual) * no);
- estotal = (Individual*) malloc(sizeof(Individual) * (np+no));
- if ((!esparents)||(!esoffsprings)||(!estotal)) {
- free(esparents); free(esoffsprings); free(estotal);
- return NLOPT_OUT_OF_MEMORY;
- }
- for (id=0; id < np; id++) esparents[id].parameters = NULL;
- for (id=0; id < no; id++) esoffsprings[id].parameters = NULL;
- // From here the population is initialized
- /* we don't handle unbounded search regions;
- this check is unnecessary since it is performed in nlopt_optimize.
- for (j = 0; j < nparameters; ++j)
- if (nlopt_isinf(low[j]) || nlopt_isinf(up[j]))
- return NLOPT_INVALID_ARGS;
- */
- // main vector of parameters to randcauchy
- vetor[0] = 4; // ignored
- vetor[3] = 0;
- vetor[4] = 1;
- vetor[5] = 10;
- vetor[6] = 1;
- vetor[7] = 0; // ignored
- // ------------------------------------
- // Initializing parents population
- // ------------------------------------
- for (id=0; id < np; id++) {
- esparents[id].parameters =
- (double*) malloc(sizeof(double) * nparameters);
- if (!esparents[id].parameters) {
- ret = NLOPT_OUT_OF_MEMORY;
- goto done;
- }
- for (item=0; item<nparameters; item++) {
- vetor[1] = lb[item];
- vetor[2] = ub[item];
- vetor[7]=vetor[7]+1;
- esparents[id].parameters[item] = randcauchy(vetor);
- }
- }
- memcpy(esparents[0].parameters, x, nparameters * sizeof(double));
-
- // ------------------------------------
- // Initializing offsprings population
- // ------------------------------------
- for (id=0; id < no; id++) {
- esoffsprings[id].parameters =
- (double*) malloc(sizeof(double) * nparameters);
- if (!esoffsprings[id].parameters) {
- ret = NLOPT_OUT_OF_MEMORY;
- goto done;
- }
- for (item=0; item<nparameters; item++) {
- vetor[1] = lb[item];
- vetor[2] = ub[item];
- vetor[7]=vetor[7]+1;
- esoffsprings[id].parameters[item] = randcauchy(vetor);
- }
- }
- // ------------------------------------
- // Parents fitness evaluation
- // ------------------------------------
- for (id=0; id < np; id++) {
- esparents[id].fitness =
- f(nparameters, esparents[id].parameters, NULL, data_f);
- estotal[id].fitness = esparents[id].fitness;
- stop->nevals++;
- if (*minf > esparents[id].fitness) {
- *minf = esparents[id].fitness;
- memcpy(x, esparents[id].parameters,
- nparameters * sizeof(double));
- }
- if (nlopt_stop_forced(stop)) ret = NLOPT_FORCED_STOP;
- else if (*minf < stop->minf_max) ret = NLOPT_MINF_MAX_REACHED;
- else if (nlopt_stop_evals(stop)) ret = NLOPT_MAXEVAL_REACHED;
- else if (nlopt_stop_time(stop)) ret = NLOPT_MAXTIME_REACHED;
- if (ret != NLOPT_SUCCESS) goto done;
- }
- // ------------------------------------
- // Main Loop - Generations
- // ------------------------------------
- while (1) {
- // ------------------------------------
- // Crossover
- // ------------------------------------
- for (id=0; id < no; id++)
- {
- parent1 = nlopt_iurand((int) np);
- parent2 = nlopt_iurand((int) np);
- crosspoint = (unsigned) nlopt_iurand((int) nparameters);
- for (item=0; item < crosspoint; item++)
- esoffsprings[id].parameters[item]
- = esparents[parent1].parameters[item];
- for (item=crosspoint; item < nparameters; item++)
- esoffsprings[id].parameters[item]
- = esparents[parent2].parameters[item];
- }
- // ------------------------------------
- // Gaussian Mutation
- // ------------------------------------
- totalmutation = (int) ((no * nparameters) / 10);
- if (totalmutation < 1) totalmutation = 1;
- for (contmutation=0; contmutation < totalmutation;
- contmutation++) {
- idoffmutation = nlopt_iurand((int) no);
- paramoffmutation = nlopt_iurand((int) nparameters);
- vetor[1] = lb[paramoffmutation];
- vetor[2] = ub[paramoffmutation];
- vetor[7] = vetor[7]+contmutation;
- esoffsprings[idoffmutation].parameters[paramoffmutation]
- = randcauchy(vetor);
- }
- // ------------------------------------
- // Offsprings fitness evaluation
- // ------------------------------------
- for (id=0; id < no; id++){
- //esoffsprings[id].fitness = (double)fitness(esoffsprings[id].parameters, nparameters,fittype);
- esoffsprings[id].fitness = f(nparameters, esoffsprings[id].parameters, NULL, data_f);
- estotal[id+np].fitness = esoffsprings[id].fitness;
- stop->nevals++;
- if (*minf > esoffsprings[id].fitness) {
- *minf = esoffsprings[id].fitness;
- memcpy(x, esoffsprings[id].parameters,
- nparameters * sizeof(double));
- }
- if (nlopt_stop_forced(stop)) ret = NLOPT_FORCED_STOP;
- else if (*minf < stop->minf_max)
- ret = NLOPT_MINF_MAX_REACHED;
- else if (nlopt_stop_evals(stop)) ret = NLOPT_MAXEVAL_REACHED;
- else if (nlopt_stop_time(stop)) ret = NLOPT_MAXTIME_REACHED;
- if (ret != NLOPT_SUCCESS) goto done;
- }
- // ------------------------------------
- // Individual selection
- // ------------------------------------
- // all the individuals are copied to one vector to easily identify best solutions
- for (i=0; i < np; i++)
- estotal[i] = esparents[i];
- for (i=0; i < no; i++)
- estotal[np+i] = esoffsprings[i];
- // Sorting
- nlopt_qsort_r(estotal, no+np, sizeof(Individual), NULL,
- CompareIndividuals);
- // copy after sorting:
- for (i=0; i < no+np; i++) {
- if (i<np)
- esparents[i] = estotal[i];
- else
- esoffsprings[i-np] = estotal[i];
- }
- } // generations loop
-
-done:
- for (id=0; id < np; id++) free(esparents[id].parameters);
- for (id=0; id < no; id++) free(esoffsprings[id].parameters);
-
- if (esparents) free(esparents);
- if (esoffsprings) free(esoffsprings);
- if (estotal) free(estotal);
- return ret;
-}
diff --git a/ext/src/nlopt/isres/README b/ext/src/nlopt/isres/README
deleted file mode 100644
index c396213..0000000
--- a/ext/src/nlopt/isres/README
+++ /dev/null
@@ -1,23 +0,0 @@
-This is my implementation of the "Improved Stochastic Ranking
-Evolution Strategy" (ISRES) algorithm for nonlinearly-constrained
-global optimization, based on the method described in:
-
- Thomas Philip Runarsson and Xin Yao, "Search biases in constrained
- evolutionary optimization," IEEE Trans. on Systems, Man, and Cybernetics
- Part C: Applications and Reviews, vol. 35 (no. 2), pp. 233-243 (2005).
-
-It is a refinement of an earlier method described in:
-
- Thomas P. Runarsson and Xin Yao, "Stochastic ranking for constrained
- evolutionary optimization," IEEE Trans. Evolutionary Computation,
- vol. 4 (no. 3), pp. 284-294 (2000).
-
-This is an independent implementation by S. G. Johnson (2009) based
-on the papers above. Runarsson also has his own Matlab implemention
-available from his web page: http://www3.hi.is/~tpr
-
-It is under the same MIT license as the rest of my code in NLopt (see
-../COPYRIGHT).
-
-Steven G. Johnson
-November 2009
diff --git a/ext/src/nlopt/isres/isres.c b/ext/src/nlopt/isres/isres.c
deleted file mode 100644
index f3d3183..0000000
--- a/ext/src/nlopt/isres/isres.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/* Copyright (c) 2010 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <stdlib.h>
-#include <math.h>
-#include <string.h>
-
-#include "nlopt/isres.h"
-
-/* Improved Stochastic Ranking Evolution Strategy (ISRES) algorithm
- for nonlinearly-constrained global optimization, based on
- the method described in:
-
- Thomas Philip Runarsson and Xin Yao, "Search biases in constrained
- evolutionary optimization," IEEE Trans. on Systems, Man, and Cybernetics
- Part C: Applications and Reviews, vol. 35 (no. 2), pp. 233-243 (2005).
-
- It is a refinement of an earlier method described in:
-
- Thomas P. Runarsson and Xin Yao, "Stochastic ranking for constrained
- evolutionary optimization," IEEE Trans. Evolutionary Computation,
- vol. 4 (no. 3), pp. 284-294 (2000).
-
- This is an independent implementation by S. G. Johnson (2009) based
- on the papers above. Runarsson also has his own Matlab implemention
- available from his web page: http://www3.hi.is/~tpr
-*/
-
-static int key_compare(void *keys_, const void *a_, const void *b_)
-{
- const double *keys = (const double *) keys_;
- const int *a = (const int *) a_;
- const int *b = (const int *) b_;
- return keys[*a] < keys[*b] ? -1 : (keys[*a] > keys[*b] ? +1 : 0);
-}
-
-static unsigned imax2(unsigned a, unsigned b) { return (a > b ? a : b); }
-
-nlopt_result isres_minimize(int n, nlopt_func f, void *f_data,
- int m, nlopt_constraint *fc, /* fc <= 0 */
- int p, nlopt_constraint *h, /* h == 0 */
- const double *lb, const double *ub, /* bounds */
- double *x, /* in: initial guess, out: minimizer */
- double *minf,
- nlopt_stopping *stop,
- int population) /* pop. size (= 0 for default) */
-{
- const double ALPHA = 0.2; /* smoothing factor from paper */
- const double GAMMA = 0.85; /* step-reduction factor from paper */
- const double PHI = 1.0; /* expected rate of convergence, from paper */
- const double PF = 0.45; /* fitness probability, from paper */
- const double SURVIVOR = 1.0/7.0; /* survivor fraction, from paper */
- int survivors;
- nlopt_result ret = NLOPT_SUCCESS;
- double *sigmas = 0, *xs; /* population-by-n arrays (row-major) */
- double *fval; /* population array of function vals */
- double *penalty; /* population array of penalty vals */
- double *x0;
- int *irank = 0;
- int k, i, j, c;
- int mp = m + p;
- double minf_penalty = HUGE_VAL, minf_gpenalty = HUGE_VAL;
- double taup, tau;
- double *results = 0; /* scratch space for mconstraint results */
- unsigned ires;
-
- *minf = HUGE_VAL;
-
- if (!population) population = 20 * (n + 1);
- if (population < 1) return NLOPT_INVALID_ARGS;
- survivors = ceil(population * SURVIVOR);
-
- taup = PHI / sqrt(2*n);
- tau = PHI / sqrt(2*sqrt(n));
-
- /* we don't handle unbounded search regions */
- for (j = 0; j < n; ++j) if (nlopt_isinf(lb[j]) || nlopt_isinf(ub[j]))
- return NLOPT_INVALID_ARGS;
-
- ires = imax2(nlopt_max_constraint_dim(m, fc),
- nlopt_max_constraint_dim(p, h));
- results = (double *) malloc(ires * sizeof(double));
- if (ires > 0 && !results) return NLOPT_OUT_OF_MEMORY;
-
- sigmas = (double*) malloc(sizeof(double) * (population*n*2
- + population
- + population
- + n));
- if (!sigmas) { free(results); return NLOPT_OUT_OF_MEMORY; }
- xs = sigmas + population*n;
- fval = xs + population*n;
- penalty = fval + population;
- x0 = penalty + population;
-
- irank = (int*) malloc(sizeof(int) * population);
- if (!irank) { ret = NLOPT_OUT_OF_MEMORY; goto done; }
-
- for (k = 0; k < population; ++k) {
- for (j = 0; j < n; ++j) {
- sigmas[k*n+j] = (ub[j] - lb[j]) / sqrt(n);
- xs[k*n+j] = nlopt_urand(lb[j], ub[j]);
- }
- }
- memcpy(xs, x, sizeof(double) * n); /* use input x for xs_0 */
-
- while (1) { /* each loop body = one generation */
- int all_feasible = 1;
-
- /* evaluate f and constraint violations for whole population */
- for (k = 0; k < population; ++k) {
- int feasible = 1;
- double gpenalty;
- stop->nevals++;
- fval[k] = f(n, xs + k*n, NULL, f_data);
- if (nlopt_stop_forced(stop)) {
- ret = NLOPT_FORCED_STOP; goto done; }
- penalty[k] = 0;
- for (c = 0; c < m; ++c) { /* inequality constraints */
- nlopt_eval_constraint(results, NULL,
- fc + c, n, xs + k*n);
- if (nlopt_stop_forced(stop)) {
- ret = NLOPT_FORCED_STOP; goto done; }
- for (ires = 0; ires < fc[c].m; ++ires) {
- double gval = results[ires];
- if (gval > fc[c].tol[ires]) feasible = 0;
- if (gval < 0) gval = 0;
- penalty[k] += gval*gval;
- }
- }
- gpenalty = penalty[k];
- for (c = m; c < mp; ++c) { /* equality constraints */
- nlopt_eval_constraint(results, NULL,
- h + (c-m), n, xs + k*n);
- if (nlopt_stop_forced(stop)) {
- ret = NLOPT_FORCED_STOP; goto done; }
- for (ires = 0; ires < h[c-m].m; ++ires) {
- double hval = results[ires];
- if (fabs(hval) > h[c-m].tol[ires]) feasible = 0;
- penalty[k] += hval*hval;
- }
- }
- if (penalty[k] > 0) all_feasible = 0;
-
- /* convergence criteria (FIXME: improve?) */
-
- /* FIXME: with equality constraints, how do
- we decide which solution is the "best" so far?
- ... need some total order on the solutions? */
-
- if ((penalty[k] <= minf_penalty || feasible)
- && (fval[k] <= *minf || minf_gpenalty > 0)
- && ((feasible ? 0 : penalty[k]) != minf_penalty
- || fval[k] != *minf)) {
- if (fval[k] < stop->minf_max && feasible)
- ret = NLOPT_MINF_MAX_REACHED;
- else if (!nlopt_isinf(*minf)) {
- if (nlopt_stop_f(stop, fval[k], *minf)
- && nlopt_stop_f(stop, feasible ? 0 : penalty[k],
- minf_penalty))
- ret = NLOPT_FTOL_REACHED;
- else if (nlopt_stop_x(stop, xs+k*n, x))
- ret = NLOPT_XTOL_REACHED;
- }
- memcpy(x, xs+k*n, sizeof(double)*n);
- *minf = fval[k];
- minf_penalty = feasible ? 0 : penalty[k];
- minf_gpenalty = feasible ? 0 : gpenalty;
- if (ret != NLOPT_SUCCESS) goto done;
- }
-
- if (nlopt_stop_forced(stop)) ret = NLOPT_FORCED_STOP;
- else if (nlopt_stop_evals(stop)) ret = NLOPT_MAXEVAL_REACHED;
- else if (nlopt_stop_time(stop)) ret = NLOPT_MAXTIME_REACHED;
- if (ret != NLOPT_SUCCESS) goto done;
- }
-
- /* "selection" step: rank the population */
- for (k = 0; k < population; ++k) irank[k] = k;
- if (all_feasible) /* special case: rank by objective function */
- nlopt_qsort_r(irank, population, sizeof(int), fval,key_compare);
- else {
- /* Runarsson & Yao's stochastic ranking of the population */
- for (i = 0; i < population; ++i) {
- int swapped = 0;
- for (j = 0; j < population-1; ++j) {
- double u = nlopt_urand(0,1);
- if (u < PF || (penalty[irank[j]] == 0
- && penalty[irank[j+1]] == 0)) {
- if (fval[irank[j]] > fval[irank[j+1]]) {
- int irankj = irank[j];
- irank[j] = irank[j+1];
- irank[j+1] = irankj;
- swapped = 1;
- }
- }
- else if (penalty[irank[j]] > penalty[irank[j+1]]) {
- int irankj = irank[j];
- irank[j] = irank[j+1];
- irank[j+1] = irankj;
- swapped = 1;
- }
- }
- if (!swapped) break;
- }
- }
-
- /* evolve the population:
- differential evolution for the best survivors,
- and standard mutation of the best survivors for the rest: */
- for (k = survivors; k < population; ++k) { /* standard mutation */
- double taup_rand = taup * nlopt_nrand(0,1);
- int rk = irank[k], ri;
- i = k % survivors;
- ri = irank[i];
- for (j = 0; j < n; ++j) {
- double sigmamax = (ub[j] - lb[j]) / sqrt(n);
- sigmas[rk*n+j] = sigmas[ri*n+j]
- * exp(taup_rand + tau*nlopt_nrand(0,1));
- if (sigmas[rk*n+j] > sigmamax)
- sigmas[rk*n+j] = sigmamax;
- do {
- xs[rk*n+j] = xs[ri*n+j]
- + sigmas[rk*n+j] * nlopt_nrand(0,1);
- } while (xs[rk*n+j] < lb[j] || xs[rk*n+j] > ub[j]);
- sigmas[rk*n+j] = sigmas[ri*n+j] + ALPHA*(sigmas[rk*n+j]
- - sigmas[ri*n+j]);
- }
- }
- memcpy(x0, xs, n * sizeof(double));
- for (k = 0; k < survivors; ++k) { /* differential variation */
- double taup_rand = taup * nlopt_nrand(0,1);
- int rk = irank[k];
- for (j = 0; j < n; ++j) {
- double xi = xs[rk*n+j];
- if (k+1 < survivors)
- xs[rk*n+j] += GAMMA * (x0[j] - xs[(k+1)*n+j]);
- if (k+1 == survivors
- || xs[rk*n+j] < lb[j] || xs[rk*n+j] > ub[j]) {
- /* standard mutation for last survivor and
- for any survivor components that are now
- outside the bounds */
- double sigmamax = (ub[j] - lb[j]) / sqrt(n);
- double sigi = sigmas[rk*n+j];
- sigmas[rk*n+j] *= exp(taup_rand
- + tau*nlopt_nrand(0,1));
- if (sigmas[rk*n+j] > sigmamax)
- sigmas[rk*n+j] = sigmamax;
- do {
- xs[rk*n+j] = xi
- + sigmas[rk*n+j] * nlopt_nrand(0,1);
- } while (xs[rk*n+j] < lb[j] || xs[rk*n+j] > ub[j]);
- sigmas[rk*n+j] = sigi
- + ALPHA * (sigmas[rk*n+j] - sigi);
- }
- }
- }
- }
-
-done:
- if (irank) free(irank);
- if (sigmas) free(sigmas);
- if (results) free(results);
- return ret;
-}
diff --git a/ext/src/nlopt/mlsl/README b/ext/src/nlopt/mlsl/README
deleted file mode 100644
index 18852b0..0000000
--- a/ext/src/nlopt/mlsl/README
+++ /dev/null
@@ -1,22 +0,0 @@
-This is my implementation of the "Multi-Level Single-Linkage" (MLSL)
-algorithm for global optimization by random local optimizations (a
-multistart algorithm with "clustering" to avoid repeated detection of
-the same local minimum), modified to optionally use a Sobol'
-low-discrepancy sequence (LDS) instead of pseudorandom numbers. See:
-
- A. H. G. Rinnooy Kan and G. T. Timmer, "Stochastic global optimization
- methods," Mathematical Programming, vol. 39, p. 27-78 (1987).
- [ actually 2 papers -- part I: clustering methods (p. 27), then
- part II: multilevel methods (p. 57) ]
-
-and also:
-
- Sergei Kucherenko and Yury Sytsko, "Application of deterministic
- low-discrepancy sequences in global optimization," Computational
- Optimization and Applications, vol. 30, p. 297-318 (2005).
-
-It is under the same MIT license as the rest of my code in NLopt (see
-../COPYRIGHT).
-
-Steven G. Johnson
-September 2007
diff --git a/ext/src/nlopt/mlsl/mlsl.c b/ext/src/nlopt/mlsl/mlsl.c
deleted file mode 100644
index 8edefbd..0000000
--- a/ext/src/nlopt/mlsl/mlsl.c
+++ /dev/null
@@ -1,435 +0,0 @@
-/* Copyright (c) 2007-2012 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/* Multi-Level Single-Linkage (MLSL) algorithm for
- global optimization by random local optimizations (a multistart algorithm
- with "clustering" to avoid repeated detection of the same local minimum),
- modified to optionally use a Sobol' low-discrepancy sequence (LDS) instead
- of pseudorandom numbers. See:
-
- A. H. G. Rinnooy Kan and G. T. Timmer, "Stochastic global optimization
- methods," Mathematical Programming, vol. 39, p. 27-78 (1987).
- [ actually 2 papers -- part I: clustering methods (p. 27), then
- part II: multilevel methods (p. 57) ]
-
- and also:
-
- Sergei Kucherenko and Yury Sytsko, "Application of deterministic
- low-discrepancy sequences in global optimization," Computational
- Optimization and Applications, vol. 30, p. 297-318 (2005).
-
- Compared to the above papers, I made a couple other modifications
- to the algorithm besides the use of a LDS.
-
- 1) first, the original algorithm suggests discarding points
- within a *fixed* distance of the boundaries or of previous
- local minima; I changed this to a distance that decreases with,
- iteration, proportional to the same threshold radius used
- for clustering. (In the case of the boundaries, I make
- the proportionality constant rather small as well.)
-
- 2) Kan and Timmer suggest using fancy "spiral-search" algorithms
- to quickly locate nearest-neighbor points, reducing the
- overall time for N sample points from O(N^2) to O(N log N)
- However, recent papers seem to show that such schemes (kd trees,
- etcetera) become inefficient for high-dimensional spaces (d > 20),
- and finding a better approach seems to be an open question. Therefore,
- since I am mainly interested in MLSL for high-dimensional problems
- (in low dimensions we have DIRECT etc.), I punted on this question
- for now. In practice, O(N^2) (which does not count the #points
- evaluated in local searches) does not seem too bad if the objective
- function is expensive.
-
-*/
-
-#include <stdlib.h>
-#include <math.h>
-#include <string.h>
-
-#include "nlopt/redblack.h"
-#include "nlopt/mlsl.h"
-
-/* data structure for each random/quasirandom point in the population */
-typedef struct {
- double f; /* function value at x */
- int minimized; /* if we have already minimized starting from x */
- double closest_pt_d; /* distance^2 to closest pt with smaller f */
- double closest_lm_d; /* distance^2 to closest lm with smaller f*/
- double x[1]; /* array of length n (K&R struct hack) */
-} pt;
-
-/* all of the data used by the various mlsl routines...it's
- not clear in hindsight that we need to put all of this in a data
- structure since most of the work occurs in a single routine,
- but it doesn't hurt us */
-typedef struct {
- int n; /* # dimensions */
- const double *lb, *ub;
- nlopt_stopping *stop; /* stopping criteria */
- nlopt_func f; void *f_data;
-
- rb_tree pts; /* tree of points (k == pt), sorted by f */
- rb_tree lms; /* tree of local minimizers, sorted by function value
- (k = array of length d+1, [0] = f, [1..d] = x) */
-
- nlopt_sobol s; /* sobol data for LDS point generation, or NULL
- to use pseudo-random numbers */
-
- double R_prefactor, dlm, dbound, gamma; /* parameters of MLSL */
- int N; /* number of pts to add per iteration */
-} mlsl_data;
-
-/* comparison routines to sort the red-black trees by function value */
-static int pt_compare(rb_key p1_, rb_key p2_)
-{
- pt *p1 = (pt *) p1_;
- pt *p2 = (pt *) p2_;
- if (p1->f < p2->f) return -1;
- if (p1->f > p2->f) return +1;
- return 0;
-}
-static int lm_compare(double *k1, double *k2)
-{
- if (*k1 < *k2) return -1;
- if (*k1 > *k2) return +1;
- return 0;
-}
-
-/* Euclidean distance |x1 - x2|^2 */
-static double distance2(int n, const double *x1, const double *x2)
-{
- int i;
- double d = 0.;
- for (i = 0; i < n; ++i) {
- double dx = x1[i] - x2[i];
- d += dx * dx;
- }
- return d;
-}
-
-/* find the closest pt to p with a smaller function value;
- this function is called when p is first added to our tree */
-static void find_closest_pt(int n, rb_tree *pts, pt *p)
-{
- rb_node *node = rb_tree_find_lt(pts, (rb_key) p);
- double closest_d = HUGE_VAL;
- while (node) {
- double d = distance2(n, p->x, ((pt *) node->k)->x);
- if (d < closest_d) closest_d = d;
- node = rb_tree_pred(node);
- }
- p->closest_pt_d = closest_d;
-}
-
-/* find the closest local minimizer (lm) to p with a smaller function value;
- this function is called when p is first added to our tree */
-static void find_closest_lm(int n, rb_tree *lms, pt *p)
-{
- rb_node *node = rb_tree_find_lt(lms, &p->f);
- double closest_d = HUGE_VAL;
- while (node) {
- double d = distance2(n, p->x, node->k+1);
- if (d < closest_d) closest_d = d;
- node = rb_tree_pred(node);
- }
- p->closest_lm_d = closest_d;
-}
-
-/* given newpt, which presumably has just been added to our
- tree, update all pts with a greater function value in case
- newpt is closer to them than their previous closest_pt ...
- we can ignore already-minimized points since we never do
- local minimization from the same point twice */
-static void pts_update_newpt(int n, rb_tree *pts, pt *newpt)
-{
- rb_node *node = rb_tree_find_gt(pts, (rb_key) newpt);
- while (node) {
- pt *p = (pt *) node->k;
- if (!p->minimized) {
- double d = distance2(n, newpt->x, p->x);
- if (d < p->closest_pt_d) p->closest_pt_d = d;
- }
- node = rb_tree_succ(node);
- }
-}
-
-/* given newlm, which presumably has just been added to our
- tree, update all pts with a greater function value in case
- newlm is closer to them than their previous closest_lm ...
- we can ignore already-minimized points since we never do
- local minimization from the same point twice */
-static void pts_update_newlm(int n, rb_tree *pts, double *newlm)
-{
- pt tmp_pt;
- rb_node *node;
- tmp_pt.f = newlm[0];
- node = rb_tree_find_gt(pts, (rb_key) &tmp_pt);
- while (node) {
- pt *p = (pt *) node->k;
- if (!p->minimized) {
- double d = distance2(n, newlm+1, p->x);
- if (d < p->closest_lm_d) p->closest_lm_d = d;
- }
- node = rb_tree_succ(node);
- }
-}
-
-static int is_potential_minimizer(mlsl_data *mlsl, pt *p,
- double dpt_min,
- double dlm_min,
- double dbound_min)
-{
- int i, n = mlsl->n;
- const double *lb = mlsl->lb;
- const double *ub = mlsl->ub;
- const double *x = p->x;
-
- if (p->minimized)
- return 0;
-
- if (p->closest_pt_d <= dpt_min*dpt_min)
- return 0;
-
- if (p->closest_lm_d <= dlm_min*dlm_min)
- return 0;
-
- for (i = 0; i < n; ++i)
- if ((x[i] - lb[i] <= dbound_min || ub[i] - x[i] <= dbound_min)
- && ub[i] - lb[i] > dbound_min)
- return 0;
-
- return 1;
-}
-
-#define K2PI (6.2831853071795864769252867665590057683943388)
-
-/* compute Gamma(1 + n/2)^{1/n} ... this is a constant factor
- used in MLSL as part of the minimum-distance cutoff*/
-static double gam(int n)
-{
- /* use Stirling's approximation:
- Gamma(1 + z) ~ sqrt(2*pi*z) * z^z / exp(z)
- ... this is more than accurate enough for our purposes
- (error in gam < 15% for d=1, < 4% for d=2, < 2% for d=3, ...)
- and avoids overflow problems because we can combine it with
- the ^{1/n} exponent */
- double z = n/2;
- return sqrt(pow(K2PI * z, 1.0/n) * z) * exp(-0.5);
-}
-
-static pt *alloc_pt(int n)
-{
- pt *p = (pt *) malloc(sizeof(pt) + (n-1) * sizeof(double));
- if (p) {
- p->minimized = 0;
- p->closest_pt_d = HUGE_VAL;
- p->closest_lm_d = HUGE_VAL;
- }
- return p;
-}
-
-/* wrapper around objective function that increments evaluation count */
-static double fcount(unsigned n, const double *x, double *grad, void *p_)
-{
- mlsl_data *p = (mlsl_data *) p_;
- p->stop->nevals++;
- return p->f(n, x, grad, p->f_data);
-}
-
-static void get_minf(mlsl_data *d, double *minf, double *x)
-{
- rb_node *node = rb_tree_min(&d->pts);
- if (node) {
- *minf = ((pt *) node->k)->f;
- memcpy(x, ((pt *) node->k)->x, sizeof(double) * d->n);
- }
- node = rb_tree_min(&d->lms);
- if (node && node->k[0] < *minf) {
- *minf = node->k[0];
- memcpy(x, node->k + 1, sizeof(double) * d->n);
- }
-}
-
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-
-#define MLSL_SIGMA 2. /* MLSL sigma parameter, using value from the papers */
-#define MLSL_GAMMA 0.3 /* MLSL gamma parameter (FIXME: what should it be?) */
-
-nlopt_result mlsl_minimize(int n, nlopt_func f, void *f_data,
- const double *lb, const double *ub, /* bounds */
- double *x, /* in: initial guess, out: minimizer */
- double *minf,
- nlopt_stopping *stop,
- nlopt_opt local_opt,
- int Nsamples, /* #samples/iteration (0=default) */
- int lds) /* random or low-discrepancy seq. (lds) */
-{
- nlopt_result ret = NLOPT_SUCCESS;
- mlsl_data d;
- int i;
- pt *p;
-
- if (!Nsamples)
- d.N = 4; /* FIXME: what is good number of samples per iteration? */
- else
- d.N = Nsamples;
- if (d.N < 1) return NLOPT_INVALID_ARGS;
-
- d.n = n;
- d.lb = lb; d.ub = ub;
- d.stop = stop;
- d.f = f; d.f_data = f_data;
- rb_tree_init(&d.pts, pt_compare);
- rb_tree_init(&d.lms, lm_compare);
- d.s = lds ? nlopt_sobol_create((unsigned) n) : NULL;
-
- nlopt_set_min_objective(local_opt, fcount, &d);
- nlopt_set_lower_bounds(local_opt, lb);
- nlopt_set_upper_bounds(local_opt, ub);
- nlopt_set_stopval(local_opt, stop->minf_max);
-
- d.gamma = MLSL_GAMMA;
-
- d.R_prefactor = sqrt(2./K2PI) * pow(gam(n) * MLSL_SIGMA, 1.0/n);
- for (i = 0; i < n; ++i)
- d.R_prefactor *= pow(ub[i] - lb[i], 1.0/n);
-
- /* MLSL also suggests setting some minimum distance from points
- to previous local minimiza and to the boundaries; I don't know
- how to choose this as a fixed number, so I set it proportional
- to R; see also the comments at top. dlm and dbound are the
- proportionality constants. */
- d.dlm = 1.0; /* min distance/R to local minima (FIXME: good value?) */
- d.dbound = 1e-6; /* min distance/R to ub/lb boundaries (good value?) */
-
-
- p = alloc_pt(n);
- if (!p) { ret = NLOPT_OUT_OF_MEMORY; goto done; }
-
- /* FIXME: how many sobol points to skip, if any? */
- nlopt_sobol_skip(d.s, (unsigned) (10*n+d.N), p->x);
-
- memcpy(p->x, x, n * sizeof(double));
- p->f = f(n, x, NULL, f_data);
- stop->nevals++;
- if (!rb_tree_insert(&d.pts, (rb_key) p)) {
- free(p); ret = NLOPT_OUT_OF_MEMORY;
- }
- if (nlopt_stop_forced(stop)) ret = NLOPT_FORCED_STOP;
- else if (nlopt_stop_evals(stop)) ret = NLOPT_MAXEVAL_REACHED;
- else if (nlopt_stop_time(stop)) ret = NLOPT_MAXTIME_REACHED;
- else if (p->f < stop->minf_max) ret = NLOPT_MINF_MAX_REACHED;
-
- while (ret == NLOPT_SUCCESS) {
- rb_node *node;
- double R;
-
- get_minf(&d, minf, x);
-
- /* sampling phase: add random/quasi-random points */
- for (i = 0; i < d.N && ret == NLOPT_SUCCESS; ++i) {
- p = alloc_pt(n);
- if (!p) { ret = NLOPT_OUT_OF_MEMORY; goto done; }
- if (d.s) nlopt_sobol_next(d.s, p->x, lb, ub);
- else { /* use random points instead of LDS */
- int j;
- for (j = 0; j < n; ++j) p->x[j] = nlopt_urand(lb[j],ub[j]);
- }
- p->f = f(n, p->x, NULL, f_data);
- stop->nevals++;
- if (!rb_tree_insert(&d.pts, (rb_key) p)) {
- free(p); ret = NLOPT_OUT_OF_MEMORY;
- }
- if (nlopt_stop_forced(stop)) ret = NLOPT_FORCED_STOP;
- else if (nlopt_stop_evals(stop)) ret = NLOPT_MAXEVAL_REACHED;
- else if (nlopt_stop_time(stop)) ret = NLOPT_MAXTIME_REACHED;
- else if (p->f < stop->minf_max) ret = NLOPT_MINF_MAX_REACHED;
- else {
- find_closest_pt(n, &d.pts, p);
- find_closest_lm(n, &d.lms, p);
- pts_update_newpt(n, &d.pts, p);
- }
- }
-
- /* distance threshhold parameter R in MLSL */
- R = d.R_prefactor
- * pow(log((double) d.pts.N) / d.pts.N, 1.0 / n);
-
- /* local search phase: do local opt. for promising points */
- node = rb_tree_min(&d.pts);
- for (i = (int) (ceil(d.gamma * d.pts.N) + 0.5);
- node && i > 0 && ret == NLOPT_SUCCESS; --i) {
- p = (pt *) node->k;
- if (is_potential_minimizer(&d, p,
- R, d.dlm*R, d.dbound*R)) {
- nlopt_result lret;
- double *lm;
- double t = nlopt_seconds();
-
- if (nlopt_stop_forced(stop)) {
- ret = NLOPT_FORCED_STOP; break;
- }
- if (nlopt_stop_evals(stop)) {
- ret = NLOPT_MAXEVAL_REACHED; break;
- }
- if (stop->maxtime > 0 &&
- t - stop->start >= stop->maxtime) {
- ret = NLOPT_MAXTIME_REACHED; break;
- }
- lm = (double *) malloc(sizeof(double) * (n+1));
- if (!lm) { ret = NLOPT_OUT_OF_MEMORY; goto done; }
- memcpy(lm+1, p->x, sizeof(double) * n);
- lret = nlopt_optimize_limited(local_opt, lm+1, lm,
- stop->maxeval - stop->nevals,
- stop->maxtime -
- (t - stop->start));
- p->minimized = 1;
- if (lret < 0) { free(lm); ret = lret; goto done; }
- if (!rb_tree_insert(&d.lms, lm)) {
- free(lm); ret = NLOPT_OUT_OF_MEMORY;
- }
- else if (nlopt_stop_forced(stop)) ret = NLOPT_FORCED_STOP;
- else if (*lm < stop->minf_max)
- ret = NLOPT_MINF_MAX_REACHED;
- else if (nlopt_stop_evals(stop))
- ret = NLOPT_MAXEVAL_REACHED;
- else if (nlopt_stop_time(stop))
- ret = NLOPT_MAXTIME_REACHED;
- else
- pts_update_newlm(n, &d.pts, lm);
- }
-
- /* TODO: additional stopping criteria based
- e.g. on improvement in function values, etc? */
-
- node = rb_tree_succ(node);
- }
- }
-
- get_minf(&d, minf, x);
-
- done:
- nlopt_sobol_destroy(d.s);
- rb_tree_destroy_with_keys(&d.lms);
- rb_tree_destroy_with_keys(&d.pts);
- return ret;
-}
diff --git a/ext/src/nlopt/mma/README b/ext/src/nlopt/mma/README
deleted file mode 100644
index cb87086..0000000
--- a/ext/src/nlopt/mma/README
+++ /dev/null
@@ -1,32 +0,0 @@
-Implementation of the globally-convergent method-of-moving-asymptotes (MMA)
-algorithm for gradient-based local optimization, as described in:
-
- Krister Svanberg, "A class of globally convergent optimization
- methods based on conservative convex separable approximations,"
- SIAM J. Optim. 12 (2), p. 555-573 (2002).
-
-In fact, this algorithm is much more general than most of the other
-algorithms in NLopt, in that it handles an arbitrary set of nonlinear
-(differentiable) constraints as well, in a very efficient manner.
-I've implemented the full nonlinear-constrained MMA algorithm, and it
-is exported under the nlopt_minimize_constrained API.
-
-I also implemented another CCSA algorithm from the same paper: instead of
-constructing local MMA approximations, it constructs simple quadratic
-approximations (or rather, affine approximations plus a quadratic penalty
-term to stay conservative). This is the ccsa_quadratic code. It seems
-to have similar convergence rates to MMA for most problems, which is not
-surprising as they are both essentially similar. However, for the quadratic
-variant I implemented the possibility of preconditioning: including a
-user-supplied Hessian approximation in the local model. It is easy to
-incorporate this into the proof in Svanberg's paper, and to show that
-global convergence is still guaranteed as long as the user's "Hessian"
-is positive semidefinite, and it practice it can greatly improve convergence
-if the preconditioner is a good approximation for (at least for the
-largest eigenvectors) the real Hessian.
-
-It is under the same MIT license as the rest of my code in NLopt (see
-../COPYRIGHT).
-
-Steven G. Johnson
-July 2008 - July 2012
diff --git a/ext/src/nlopt/mma/ccsa_quadratic.c b/ext/src/nlopt/mma/ccsa_quadratic.c
deleted file mode 100644
index 7c10b79..0000000
--- a/ext/src/nlopt/mma/ccsa_quadratic.c
+++ /dev/null
@@ -1,550 +0,0 @@
-/* Copyright (c) 2007-2012 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/* In this file we implement Svanberg's CCSA algorithm with the
- simple linear approximation + quadratic penalty function.
-
- We also allow the user to specify an optional "preconditioner": an
- approximate Hessian (which must be symmetric & positive
- semidefinite) that can be added into the approximation. [X. Liang
- and I went through the convergence proof in Svanberg's paper
- and it does not seem to be modified by such preconditioning, as
- long as the preconditioner eigenvalues are bounded above for all x.]
-
- For the non-preconditioned case the trust-region subproblem is
- separable and can be solved by a dual method. For the preconditioned
- case the subproblem is still convex but in general is non-separable
- so we solve by calling the same algorithm recursively, under the
- assumption that the subproblem objective is cheap to evaluate.
-*/
-
-#include <stdlib.h>
-#include <math.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "nlopt/mma.h"
-#include "nlopt/nlopt-util.h"
-
-unsigned ccsa_verbose = 0; /* > 0 for verbose output */
-
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-#define MAX(a,b) ((a) > (b) ? (a) : (b))
-
-/* magic minimum value for rho in CCSA ... the 2002 paper says it should
- be a "fixed, strictly positive `small' number, e.g. 1e-5"
- ... grrr, I hate these magic numbers, which seem like they
- should depend on the objective function in some way ... in particular,
- note that rho is dimensionful (= dimensions of objective function) */
-#define CCSA_RHOMIN 1e-5
-
-/***********************************************************************/
-/* function for CCSA's dual solution of the approximate problem */
-
-typedef struct {
- int count; /* evaluation count, incremented each call */
- unsigned n; /* must be set on input to dimension of x */
- const double *x, *lb, *ub, *sigma, *dfdx; /* arrays of length n */
- const double *dfcdx; /* m-by-n array of fc gradients */
- double fval, rho; /* must be set on input */
- const double *fcval, *rhoc; /* arrays of length m */
- double *xcur; /* array of length n, output each time */
- double gval, wval, *gcval; /* output each time (array length m) */
- nlopt_precond pre; void *pre_data;
- nlopt_precond *prec; void **prec_data; /* length = # constraints */
- double *scratch; /* length = 2*n */
-} dual_data;
-
-static double sqr(double x) { return x * x; }
-
-static double dual_func(unsigned m, const double *y, double *grad, void *d_)
-{
- dual_data *d = (dual_data *) d_;
- unsigned n = d->n;
- const double *x = d->x, *lb = d->lb, *ub = d->ub, *sigma = d->sigma,
- *dfdx = d->dfdx;
- const double *dfcdx = d->dfcdx;
- double rho = d->rho, fval = d->fval;
- const double *rhoc = d->rhoc, *fcval = d->fcval;
- double *xcur = d->xcur;
- double *gcval = d->gcval;
- unsigned i, j;
- double val;
-
- d->count++;
-
- val = d->gval = fval;
- d->wval = 0;
- for (i = 0; i < m; ++i)
- val += y[i] * (gcval[i] = fcval[i]);
-
- for (j = 0; j < n; ++j) {
- double u, v, dx, sigma2, dx2, dx2sig;
-
- /* first, compute xcur[j] = x+dx for y. Because this objective is
- separable, we can minimize over x analytically, and the minimum
- dx is given by the solution of a linear equation
- u dx + v sigma^2 = 0, i.e. dx = -sigma^2 v/u
- where u and v are defined by the sums below. However,
- we also have to check that |dx| <= sigma and that
- lb <= x+dx <= ub. */
-
- if (sigma[j] == 0) { /* special case for lb[i] == ub[i] dims, dx=0 */
- xcur[j] = x[j];
- continue;
- }
-
- u = rho;
- v = dfdx[j];
- for (i = 0; i < m; ++i) {
- u += rhoc[i] * y[i];
- v += dfcdx[i*n + j] * y[i];
- }
- dx = -(sigma2 = sqr(sigma[j])) * v/u;
-
- /* if dx is out of bounds, we are guaranteed by convexity
- that the minimum is at the bound on the side of dx */
- if (fabs(dx) > sigma[j]) dx = copysign(sigma[j], dx);
- xcur[j] = x[j] + dx;
- if (xcur[j] > ub[j]) xcur[j] = ub[j];
- else if (xcur[j] < lb[j]) xcur[j] = lb[j];
- dx = xcur[j] - x[j];
-
- /* function value: */
- dx2 = dx * dx;
- val += v * dx + 0.5 * u * dx2 / sigma2;
-
- /* update gval, wval, gcval (approximant functions) */
- d->gval += dfdx[j] * dx + rho * (dx2sig = 0.5*dx2/sigma2);
- d->wval += dx2sig;
- for (i = 0; i < m; ++i)
- gcval[i] += dfcdx[i*n+j] * dx + rhoc[i] * dx2sig;
- }
-
- /* gradient is easy to compute: since we are at a minimum x (dval/dx=0),
- we only need the partial derivative with respect to y, and
- we negate because we are maximizing: */
- if (grad) for (i = 0; i < m; ++i) grad[i] = -gcval[i];
- return -val;
-}
-
-/***********************************************************************/
-
-/* compute g(x - x0) and its gradient */
-static double gfunc(unsigned n, double f, const double *dfdx,
- double rho, const double *sigma,
- const double *x0,
- nlopt_precond pre, void *pre_data, double *scratch,
- const double *x, double *grad)
-{
- double *dx = scratch, *Hdx = scratch + n;
- double val = f;
- unsigned j;
-
- for (j = 0; j < n; ++j) {
- double sigma2inv = 1.0 / sqr(sigma[j]);
- dx[j] = x[j] - x0[j];
- val += dfdx[j] * dx[j] + (0.5*rho) * sqr(dx[j]) * sigma2inv;
- if (grad) grad[j] = dfdx[j] + rho * dx[j] * sigma2inv;
- }
-
- if (pre) {
- pre(n, x0, dx, Hdx, pre_data);
- for (j = 0; j < n; ++j)
- val += 0.5 * dx[j] * Hdx[j];
- if (grad)
- for (j = 0; j < n; ++j)
- grad[j] += Hdx[j];
- }
-
- return val;
-}
-
-static double g0(unsigned n, const double *x, double *grad, void *d_)
-{
- dual_data *d = (dual_data *) d_;
- d->count++;
- return gfunc(n, d->fval, d->dfdx, d->rho, d->sigma,
- d->x,
- d->pre, d->pre_data, d->scratch,
- x, grad);
-}
-
-
-static void gi(unsigned m, double *result,
- unsigned n, const double *x, double *grad, void *d_)
-{
- dual_data *d = (dual_data *) d_;
- unsigned i;
- for (i = 0; i < m; ++i)
- result[i] = gfunc(n, d->fcval[i], d->dfcdx + i*n, d->rhoc[i],
- d->sigma,
- d->x,
- d->prec ? d->prec[i] : NULL,
- d->prec_data ? d->prec_data[i] : NULL,
- d->scratch,
- x, grad);
-}
-
-
-/***********************************************************************/
-
-nlopt_result ccsa_quadratic_minimize(
- unsigned n, nlopt_func f, void *f_data,
- unsigned m, nlopt_constraint *fc,
-
- nlopt_precond pre,
-
- const double *lb, const double *ub, /* bounds */
- double *x, /* in: initial guess, out: minimizer */
- double *minf,
- nlopt_stopping *stop,
- nlopt_opt dual_opt)
-{
- nlopt_result ret = NLOPT_SUCCESS;
- double *xcur, rho, *sigma, *dfdx, *dfdx_cur, *xprev, *xprevprev, fcur;
- double *dfcdx, *dfcdx_cur;
- double *fcval, *fcval_cur, *rhoc, *gcval, *y, *dual_lb, *dual_ub;
- double *pre_lb, *pre_ub;
- unsigned i, ifc, j, k = 0;
- dual_data dd;
- int feasible;
- double infeasibility;
- unsigned mfc;
- unsigned no_precond;
- nlopt_opt pre_opt = NULL;
-
- m = nlopt_count_constraints(mfc = m, fc);
- if (nlopt_get_dimension(dual_opt) != m) return NLOPT_INVALID_ARGS;
- sigma = (double *) malloc(sizeof(double) * (6*n + 2*m*n + m*7));
- if (!sigma) return NLOPT_OUT_OF_MEMORY;
- dfdx = sigma + n;
- dfdx_cur = dfdx + n;
- xcur = dfdx_cur + n;
- xprev = xcur + n;
- xprevprev = xprev + n;
- fcval = xprevprev + n;
- fcval_cur = fcval + m;
- rhoc = fcval_cur + m;
- gcval = rhoc + m;
- dual_lb = gcval + m;
- dual_ub = dual_lb + m;
- y = dual_ub + m;
- dfcdx = y + m;
- dfcdx_cur = dfcdx + m*n;
-
- dd.n = n;
- dd.x = x;
- dd.lb = lb;
- dd.ub = ub;
- dd.sigma = sigma;
- dd.dfdx = dfdx;
- dd.dfcdx = dfcdx;
- dd.fcval = fcval;
- dd.rhoc = rhoc;
- dd.xcur = xcur;
- dd.gcval = gcval;
- dd.pre = pre; dd.pre_data = f_data;
- dd.prec = NULL; dd.prec_data = NULL;
- dd.scratch = NULL;
-
- if (m) {
- dd.prec = (nlopt_precond *) malloc(sizeof(nlopt_precond) * m);
- dd.prec_data = (void **) malloc(sizeof(void *) * m);
- if (!dd.prec || !dd.prec_data) {
- ret = NLOPT_OUT_OF_MEMORY;
- goto done;
- }
- for (i = ifc = 0; ifc < mfc; ++ifc) {
- unsigned inext = i + fc[ifc].m;
- for (; i < inext; ++i) {
- dd.prec[i] = fc[ifc].pre;
- dd.prec_data[i] = fc[ifc].f_data;
- }
- }
- }
-
- no_precond = pre == NULL;
- if (dd.prec)
- for (i = 0; i < m; ++i)
- no_precond = no_precond && dd.prec[i] == NULL;
-
- if (!no_precond) {
- dd.scratch = (double*) malloc(sizeof(double) * (4*n));
- if (!dd.scratch) {
- free(sigma);
- return NLOPT_OUT_OF_MEMORY;
- }
- pre_lb = dd.scratch + 2*n;
- pre_ub = pre_lb + n;
-
- pre_opt = nlopt_create(nlopt_get_algorithm(dual_opt), n);
- if (!pre_opt) { ret = NLOPT_FAILURE; goto done; }
- ret = nlopt_set_min_objective(pre_opt, g0, &dd);
- if (ret < 0) goto done;
- ret = nlopt_add_inequality_mconstraint(pre_opt, m, gi, &dd, NULL);
- if (ret < 0) goto done;
- ret = nlopt_set_ftol_rel(pre_opt, nlopt_get_ftol_rel(dual_opt));
- if (ret < 0) goto done;
- ret = nlopt_set_ftol_abs(pre_opt, nlopt_get_ftol_abs(dual_opt));
- if (ret < 0) goto done;
- ret = nlopt_set_maxeval(pre_opt, nlopt_get_maxeval(dual_opt));
- if (ret < 0) goto done;
- }
-
- for (j = 0; j < n; ++j) {
- if (nlopt_isinf(ub[j]) || nlopt_isinf(lb[j]))
- sigma[j] = 1.0; /* arbitrary default */
- else
- sigma[j] = 0.5 * (ub[j] - lb[j]);
- }
- rho = 1.0;
- for (i = 0; i < m; ++i) {
- rhoc[i] = 1.0;
- dual_lb[i] = y[i] = 0.0;
- dual_ub[i] = HUGE_VAL;
- }
-
- dd.fval = fcur = *minf = f(n, x, dfdx, f_data);
- stop->nevals++;
- memcpy(xcur, x, sizeof(double) * n);
- if (nlopt_stop_forced(stop)) { ret = NLOPT_FORCED_STOP; goto done; }
-
- feasible = 1; infeasibility = 0;
- for (i = ifc = 0; ifc < mfc; ++ifc) {
- nlopt_eval_constraint(fcval + i, dfcdx + i*n,
- fc + ifc, n, x);
- i += fc[ifc].m;
- if (nlopt_stop_forced(stop)) { ret = NLOPT_FORCED_STOP; goto done; }
- }
- for (i = 0; i < m; ++i) {
- feasible = feasible && fcval[i] <= 0;
- if (fcval[i] > infeasibility) infeasibility = fcval[i];
- }
- /* For non-feasible initial points, set a finite (large)
- upper-bound on the dual variables. What this means is that,
- if no feasible solution is found from the dual problem, it
- will minimize the dual objective with the unfeasible
- constraint weighted by 1e40 -- basically, minimizing the
- unfeasible constraint until it becomes feasible or until we at
- least obtain a step towards a feasible point.
-
- Svanberg suggested a different approach in his 1987 paper, basically
- introducing additional penalty variables for unfeasible constraints,
- but this is easier to implement and at least as efficient. */
- if (!feasible)
- for (i = 0; i < m; ++i) dual_ub[i] = 1e40;
-
- nlopt_set_min_objective(dual_opt, dual_func, &dd);
- nlopt_set_lower_bounds(dual_opt, dual_lb);
- nlopt_set_upper_bounds(dual_opt, dual_ub);
- nlopt_set_stopval(dual_opt, -HUGE_VAL);
- nlopt_remove_inequality_constraints(dual_opt);
- nlopt_remove_equality_constraints(dual_opt);
-
- while (1) { /* outer iterations */
- double fprev = fcur;
- if (nlopt_stop_forced(stop)) ret = NLOPT_FORCED_STOP;
- else if (nlopt_stop_evals(stop)) ret = NLOPT_MAXEVAL_REACHED;
- else if (nlopt_stop_time(stop)) ret = NLOPT_MAXTIME_REACHED;
- else if (feasible && *minf < stop->minf_max)
- ret = NLOPT_MINF_MAX_REACHED;
- if (ret != NLOPT_SUCCESS) goto done;
- if (++k > 1) memcpy(xprevprev, xprev, sizeof(double) * n);
- memcpy(xprev, xcur, sizeof(double) * n);
-
- while (1) { /* inner iterations */
- double min_dual, infeasibility_cur;
- int feasible_cur, inner_done;
- unsigned save_verbose;
- nlopt_result reti;
-
- if (no_precond) {
- /* solve dual problem */
- dd.rho = rho; dd.count = 0;
- save_verbose = ccsa_verbose;
- ccsa_verbose = 0; /* no recursive verbosity */
- reti = nlopt_optimize_limited(dual_opt, y, &min_dual,
- 0,
- stop->maxtime
- - (nlopt_seconds()
- - stop->start));
- ccsa_verbose = save_verbose;
- if (reti < 0 || reti == NLOPT_MAXTIME_REACHED) {
- ret = reti;
- goto done;
- }
-
- dual_func(m, y, NULL, &dd); /* evaluate final xcur etc. */
- }
- else {
- double pre_min;
- for (j = 0; j < n; ++j) {
- pre_lb[j] = MAX(lb[j], x[j] - sigma[j]);
- pre_ub[j] = MIN(ub[j], x[j] + sigma[j]);
- xcur[j] = x[j];
- }
- nlopt_set_lower_bounds(pre_opt, pre_lb);
- nlopt_set_upper_bounds(pre_opt, pre_ub);
-
- dd.rho = rho; dd.count = 0;
- save_verbose = ccsa_verbose;
- ccsa_verbose = 0; /* no recursive verbosity */
- reti = nlopt_optimize_limited(pre_opt, xcur, &pre_min,
- 0, stop->maxtime
- - (nlopt_seconds()
- - stop->start));
- ccsa_verbose = save_verbose;
- if (reti < 0 || reti == NLOPT_MAXTIME_REACHED) {
- ret = reti;
- goto done;
- }
-
- /* evaluate final xcur etc */
- dd.gval = g0(n, xcur, NULL, &dd);
- gi(m, dd.gcval, n, xcur, NULL, &dd);
- }
-
- if (ccsa_verbose) {
- printf("CCSA dual converged in %d iters to g=%g:\n",
- dd.count, dd.gval);
- for (i = 0; i < MIN(ccsa_verbose, m); ++i)
- printf(" CCSA y[%d]=%g, gc[%d]=%g\n",
- i, y[i], i, dd.gcval[i]);
- }
-
- fcur = f(n, xcur, dfdx_cur, f_data);
- stop->nevals++;
- if (nlopt_stop_forced(stop)) {
- ret = NLOPT_FORCED_STOP; goto done; }
- feasible_cur = 1; infeasibility_cur = 0;
- inner_done = dd.gval >= fcur;
- for (i = ifc = 0; ifc < mfc; ++ifc) {
- nlopt_eval_constraint(fcval_cur + i, dfcdx_cur + i*n,
- fc + ifc, n, xcur);
- i += fc[ifc].m;
- if (nlopt_stop_forced(stop)) {
- ret = NLOPT_FORCED_STOP; goto done; }
- }
- for (i = ifc = 0; ifc < mfc; ++ifc) {
- unsigned i0 = i, inext = i + fc[ifc].m;
- for (; i < inext; ++i) {
- feasible_cur = feasible_cur
- && fcval_cur[i] <= fc[ifc].tol[i-i0];
- inner_done = inner_done &&
- (dd.gcval[i] >= fcval_cur[i]);
- if (fcval_cur[i] > infeasibility_cur)
- infeasibility_cur = fcval_cur[i];
- }
- }
-
- if ((fcur < *minf && (inner_done || feasible_cur || !feasible))
- || (!feasible && infeasibility_cur < infeasibility)) {
- if (ccsa_verbose && !feasible_cur)
- printf("CCSA - using infeasible point?\n");
- dd.fval = *minf = fcur;
- infeasibility = infeasibility_cur;
- memcpy(fcval, fcval_cur, sizeof(double)*m);
- memcpy(x, xcur, sizeof(double)*n);
- memcpy(dfdx, dfdx_cur, sizeof(double)*n);
- memcpy(dfcdx, dfcdx_cur, sizeof(double)*n*m);
-
- /* once we have reached a feasible solution, the
- algorithm should never make the solution infeasible
- again (if inner_done), although the constraints may
- be violated slightly by rounding errors etc. so we
- must be a little careful about checking feasibility */
- if (infeasibility_cur == 0) {
- if (!feasible) { /* reset upper bounds to infin. */
- for (i = 0; i < m; ++i) dual_ub[i] = HUGE_VAL;
- nlopt_set_upper_bounds(dual_opt, dual_ub);
- }
- feasible = 1;
- }
-
- }
- if (nlopt_stop_forced(stop)) ret = NLOPT_FORCED_STOP;
- else if (nlopt_stop_evals(stop)) ret = NLOPT_MAXEVAL_REACHED;
- else if (nlopt_stop_time(stop)) ret = NLOPT_MAXTIME_REACHED;
- else if (feasible && *minf < stop->minf_max)
- ret = NLOPT_MINF_MAX_REACHED;
- if (ret != NLOPT_SUCCESS) goto done;
-
- if (inner_done) break;
-
- if (fcur > dd.gval)
- rho = MIN(10*rho, 1.1 * (rho + (fcur-dd.gval) / dd.wval));
- for (i = 0; i < m; ++i)
- if (fcval_cur[i] > dd.gcval[i])
- rhoc[i] =
- MIN(10*rhoc[i],
- 1.1 * (rhoc[i] + (fcval_cur[i]-dd.gcval[i])
- / dd.wval));
-
- if (ccsa_verbose)
- printf("CCSA inner iteration: rho -> %g\n", rho);
- for (i = 0; i < MIN(ccsa_verbose, m); ++i)
- printf(" CCSA rhoc[%d] -> %g\n", i,rhoc[i]);
- }
-
- if (nlopt_stop_ftol(stop, fcur, fprev))
- ret = NLOPT_FTOL_REACHED;
- if (nlopt_stop_x(stop, xcur, xprev))
- ret = NLOPT_XTOL_REACHED;
- if (ret != NLOPT_SUCCESS) goto done;
-
- /* update rho and sigma for iteration k+1 */
- rho = MAX(0.1 * rho, CCSA_RHOMIN);
- if (ccsa_verbose)
- printf("CCSA outer iteration: rho -> %g\n", rho);
- for (i = 0; i < m; ++i)
- rhoc[i] = MAX(0.1 * rhoc[i], CCSA_RHOMIN);
- for (i = 0; i < MIN(ccsa_verbose, m); ++i)
- printf(" CCSA rhoc[%d] -> %g\n", i, rhoc[i]);
- if (k > 1) {
- for (j = 0; j < n; ++j) {
- double dx2 = (xcur[j]-xprev[j]) * (xprev[j]-xprevprev[j]);
- double gam = dx2 < 0 ? 0.7 : (dx2 > 0 ? 1.2 : 1);
- sigma[j] *= gam;
- if (!nlopt_isinf(ub[j]) && !nlopt_isinf(lb[j])) {
- sigma[j] = MIN(sigma[j], 10*(ub[j]-lb[j]));
- /* use a smaller lower bound than Svanberg's
- 0.01*(ub-lb), which seems unnecessarily large */
- sigma[j] = MAX(sigma[j], 1e-8*(ub[j]-lb[j]));
- }
- }
- for (j = 0; j < MIN(ccsa_verbose, n); ++j)
- printf(" CCSA sigma[%d] -> %g\n",
- j, sigma[j]);
- }
- }
-
- done:
- nlopt_destroy(pre_opt);
- if (dd.scratch) free(dd.scratch);
- if (m) {
- free(dd.prec_data);
- free(dd.prec);
- }
- free(sigma);
- return ret;
-}
diff --git a/ext/src/nlopt/mma/mma.c b/ext/src/nlopt/mma/mma.c
deleted file mode 100644
index 6a57c4d..0000000
--- a/ext/src/nlopt/mma/mma.c
+++ /dev/null
@@ -1,398 +0,0 @@
-/* Copyright (c) 2007-2012 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <stdlib.h>
-#include <math.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "nlopt/mma.h"
-#include "nlopt/nlopt-util.h"
-
-unsigned mma_verbose = 0; /* > 0 for verbose output */
-
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-#define MAX(a,b) ((a) > (b) ? (a) : (b))
-
-/* magic minimum value for rho in MMA ... the 2002 paper says it should
- be a "fixed, strictly positive `small' number, e.g. 1e-5"
- ... grrr, I hate these magic numbers, which seem like they
- should depend on the objective function in some way ... in particular,
- note that rho is dimensionful (= dimensions of objective function) */
-#define MMA_RHOMIN 1e-5
-
-/***********************************************************************/
-/* function for MMA's dual solution of the approximate problem */
-
-typedef struct {
- int count; /* evaluation count, incremented each call */
- unsigned n; /* must be set on input to dimension of x */
- const double *x, *lb, *ub, *sigma, *dfdx; /* arrays of length n */
- const double *dfcdx; /* m-by-n array of fc gradients */
- double fval, rho; /* must be set on input */
- const double *fcval, *rhoc; /* arrays of length m */
- double *xcur; /* array of length n, output each time */
- double gval, wval, *gcval; /* output each time (array length m) */
-} dual_data;
-
-static double sqr(double x) { return x * x; }
-
-static double dual_func(unsigned m, const double *y, double *grad, void *d_)
-{
- dual_data *d = (dual_data *) d_;
- unsigned n = d->n;
- const double *x = d->x, *lb = d->lb, *ub = d->ub, *sigma = d->sigma,
- *dfdx = d->dfdx;
- const double *dfcdx = d->dfcdx;
- double rho = d->rho, fval = d->fval;
- const double *rhoc = d->rhoc, *fcval = d->fcval;
- double *xcur = d->xcur;
- double *gcval = d->gcval;
- unsigned i, j;
- double val;
-
- d->count++;
-
- val = d->gval = fval;
- d->wval = 0;
- for (i = 0; i < m; ++i)
- val += y[i] * (gcval[i] = isnan(fcval[i]) ? 0 : fcval[i]);
-
- for (j = 0; j < n; ++j) {
- double u, v, dx, denominv, c, sigma2, dx2;
-
- /* first, compute xcur[j] for y. Because this objective is
- separable, we can minimize over x analytically, and the minimum
- dx is given by the solution of a quadratic equation:
- u dx^2 + 2 v sigma^2 dx + u sigma^2 = 0
- where u and v are defined by the sums below. Because of
- the definitions, it is guaranteed that |u/v| <= sigma,
- and it follows that the only dx solution with |dx| <= sigma
- is given by:
- (v/u) sigma^2 (-1 + sqrt(1 - (u / v sigma)^2))
- = (u/v) / (-1 - sqrt(1 - (u / v sigma)^2))
- (which goes to zero as u -> 0). The latter expression
- is less susceptible to roundoff error. */
-
- if (sigma[j] == 0) { /* special case for lb[i] == ub[i] dims, dx=0 */
- xcur[j] = x[j];
- continue;
- }
-
- u = dfdx[j];
- v = fabs(dfdx[j]) * sigma[j] + 0.5 * rho;
- for (i = 0; i < m; ++i) if (!isnan(fcval[i])) {
- u += dfcdx[i*n + j] * y[i];
- v += (fabs(dfcdx[i*n + j]) * sigma[j] + 0.5 * rhoc[i]) * y[i];
- }
- u *= (sigma2 = sqr(sigma[j]));
- dx = (u/v) / (-1 - sqrt(fabs(1 - sqr(u/(v*sigma[j])))));
- xcur[j] = x[j] + dx;
- if (xcur[j] > ub[j]) xcur[j] = ub[j];
- else if (xcur[j] < lb[j]) xcur[j] = lb[j];
- if (xcur[j] > x[j]+0.9*sigma[j]) xcur[j] = x[j]+0.9*sigma[j];
- else if (xcur[j] < x[j]-0.9*sigma[j]) xcur[j] = x[j]-0.9*sigma[j];
- dx = xcur[j] - x[j];
-
- /* function value: */
- dx2 = dx * dx;
- denominv = 1.0 / (sigma2 - dx2);
- val += (u * dx + v * dx2) * denominv;
-
- /* update gval, wval, gcval (approximant functions) */
- c = sigma2 * dx;
- d->gval += (dfdx[j] * c + (fabs(dfdx[j])*sigma[j] + 0.5*rho) * dx2)
- * denominv;
- d->wval += 0.5 * dx2 * denominv;
- for (i = 0; i < m; ++i) if (!isnan(fcval[i]))
- gcval[i] += (dfcdx[i*n+j] * c + (fabs(dfcdx[i*n+j])*sigma[j]
- + 0.5*rhoc[i]) * dx2)
- * denominv;
- }
-
- /* gradient is easy to compute: since we are at a minimum x (dval/dx=0),
- we only need the partial derivative with respect to y, and
- we negate because we are maximizing: */
- if (grad) for (i = 0; i < m; ++i) grad[i] = -gcval[i];
- return -val;
-}
-
-/***********************************************************************/
-
-/* note that we implement a hidden feature not in the standard
- nlopt_minimize_constrained interface: whenever the constraint
- function returns NaN, that constraint becomes inactive. */
-
-nlopt_result mma_minimize(unsigned n, nlopt_func f, void *f_data,
- unsigned m, nlopt_constraint *fc,
- const double *lb, const double *ub, /* bounds */
- double *x, /* in: initial guess, out: minimizer */
- double *minf,
- nlopt_stopping *stop,
- nlopt_opt dual_opt)
-{
- nlopt_result ret = NLOPT_SUCCESS;
- double *xcur, rho, *sigma, *dfdx, *dfdx_cur, *xprev, *xprevprev, fcur;
- double *dfcdx, *dfcdx_cur;
- double *fcval, *fcval_cur, *rhoc, *gcval, *y, *dual_lb, *dual_ub;
- unsigned i, ifc, j, k = 0;
- dual_data dd;
- int feasible;
- double infeasibility;
- unsigned mfc;
-
- m = nlopt_count_constraints(mfc = m, fc);
- if (nlopt_get_dimension(dual_opt) != m) return NLOPT_INVALID_ARGS;
- sigma = (double *) malloc(sizeof(double) * (6*n + 2*m*n + m*7));
- if (!sigma) return NLOPT_OUT_OF_MEMORY;
- dfdx = sigma + n;
- dfdx_cur = dfdx + n;
- xcur = dfdx_cur + n;
- xprev = xcur + n;
- xprevprev = xprev + n;
- fcval = xprevprev + n;
- fcval_cur = fcval + m;
- rhoc = fcval_cur + m;
- gcval = rhoc + m;
- dual_lb = gcval + m;
- dual_ub = dual_lb + m;
- y = dual_ub + m;
- dfcdx = y + m;
- dfcdx_cur = dfcdx + m*n;
-
- dd.n = n;
- dd.x = x;
- dd.lb = lb;
- dd.ub = ub;
- dd.sigma = sigma;
- dd.dfdx = dfdx;
- dd.dfcdx = dfcdx;
- dd.fcval = fcval;
- dd.rhoc = rhoc;
- dd.xcur = xcur;
- dd.gcval = gcval;
-
- for (j = 0; j < n; ++j) {
- if (nlopt_isinf(ub[j]) || nlopt_isinf(lb[j]))
- sigma[j] = 1.0; /* arbitrary default */
- else
- sigma[j] = 0.5 * (ub[j] - lb[j]);
- }
- rho = 1.0;
- for (i = 0; i < m; ++i) {
- rhoc[i] = 1.0;
- dual_lb[i] = y[i] = 0.0;
- dual_ub[i] = HUGE_VAL;
- }
-
- dd.fval = fcur = *minf = f(n, x, dfdx, f_data);
- stop->nevals++;
- memcpy(xcur, x, sizeof(double) * n);
- if (nlopt_stop_forced(stop)) { ret = NLOPT_FORCED_STOP; goto done; }
-
- feasible = 1; infeasibility = 0;
- for (i = ifc = 0; ifc < mfc; ++ifc) {
- nlopt_eval_constraint(fcval + i, dfcdx + i*n,
- fc + ifc, n, x);
- i += fc[ifc].m;
- if (nlopt_stop_forced(stop)) { ret = NLOPT_FORCED_STOP; goto done; }
- }
- for (i = 0; i < m; ++i) {
- feasible = feasible && (fcval[i] <= 0 || isnan(fcval[i]));
- if (fcval[i] > infeasibility) infeasibility = fcval[i];
- }
- /* For non-feasible initial points, set a finite (large)
- upper-bound on the dual variables. What this means is that,
- if no feasible solution is found from the dual problem, it
- will minimize the dual objective with the unfeasible
- constraint weighted by 1e40 -- basically, minimizing the
- unfeasible constraint until it becomes feasible or until we at
- least obtain a step towards a feasible point.
-
- Svanberg suggested a different approach in his 1987 paper, basically
- introducing additional penalty variables for unfeasible constraints,
- but this is easier to implement and at least as efficient. */
- if (!feasible)
- for (i = 0; i < m; ++i) dual_ub[i] = 1e40;
-
- nlopt_set_min_objective(dual_opt, dual_func, &dd);
- nlopt_set_lower_bounds(dual_opt, dual_lb);
- nlopt_set_upper_bounds(dual_opt, dual_ub);
- nlopt_set_stopval(dual_opt, -HUGE_VAL);
- nlopt_remove_inequality_constraints(dual_opt);
- nlopt_remove_equality_constraints(dual_opt);
-
- while (1) { /* outer iterations */
- double fprev = fcur;
- if (nlopt_stop_forced(stop)) ret = NLOPT_FORCED_STOP;
- else if (nlopt_stop_evals(stop)) ret = NLOPT_MAXEVAL_REACHED;
- else if (nlopt_stop_time(stop)) ret = NLOPT_MAXTIME_REACHED;
- else if (feasible && *minf < stop->minf_max)
- ret = NLOPT_MINF_MAX_REACHED;
- if (ret != NLOPT_SUCCESS) goto done;
- if (++k > 1) memcpy(xprevprev, xprev, sizeof(double) * n);
- memcpy(xprev, xcur, sizeof(double) * n);
-
- while (1) { /* inner iterations */
- double min_dual, infeasibility_cur;
- int feasible_cur, inner_done;
- unsigned save_verbose;
- int new_infeasible_constraint;
- nlopt_result reti;
-
- /* solve dual problem */
- dd.rho = rho; dd.count = 0;
- save_verbose = mma_verbose;
- mma_verbose = 0; /* no recursive verbosity */
- reti = nlopt_optimize_limited(dual_opt, y, &min_dual,
- 0,
- stop->maxtime - (nlopt_seconds()
- - stop->start));
- mma_verbose = save_verbose;
- if (reti < 0 || reti == NLOPT_MAXTIME_REACHED) {
- ret = reti;
- goto done;
- }
-
- dual_func(m, y, NULL, &dd); /* evaluate final xcur etc. */
- if (mma_verbose) {
- printf("MMA dual converged in %d iterations to g=%g:\n",
- dd.count, dd.gval);
- for (i = 0; i < MIN(mma_verbose, m); ++i)
- printf(" MMA y[%d]=%g, gc[%d]=%g\n",
- i, y[i], i, dd.gcval[i]);
- }
-
- fcur = f(n, xcur, dfdx_cur, f_data);
- stop->nevals++;
- if (nlopt_stop_forced(stop)) {
- ret = NLOPT_FORCED_STOP; goto done; }
- feasible_cur = 1; infeasibility_cur = 0;
- new_infeasible_constraint = 0;
- inner_done = dd.gval >= fcur;
- for (i = ifc = 0; ifc < mfc; ++ifc) {
- nlopt_eval_constraint(fcval_cur + i, dfcdx_cur + i*n,
- fc + ifc, n, xcur);
- i += fc[ifc].m;
- if (nlopt_stop_forced(stop)) {
- ret = NLOPT_FORCED_STOP; goto done; }
- }
- for (i = ifc = 0; ifc < mfc; ++ifc) {
- unsigned i0 = i, inext = i + fc[ifc].m;
- for (; i < inext; ++i)
- if (!isnan(fcval_cur[i])) {
- feasible_cur = feasible_cur
- && (fcval_cur[i] <= fc[ifc].tol[i-i0]);
- if (!isnan(fcval[i]))
- inner_done = inner_done &&
- (dd.gcval[i] >= fcval_cur[i]);
- else if (fcval_cur[i] > 0)
- new_infeasible_constraint = 1;
- if (fcval_cur[i] > infeasibility_cur)
- infeasibility_cur = fcval_cur[i];
- }
- }
-
- if ((fcur < *minf && (inner_done || feasible_cur || !feasible))
- || (!feasible && infeasibility_cur < infeasibility)) {
- if (mma_verbose && !feasible_cur)
- printf("MMA - using infeasible point?\n");
- dd.fval = *minf = fcur;
- infeasibility = infeasibility_cur;
- memcpy(fcval, fcval_cur, sizeof(double)*m);
- memcpy(x, xcur, sizeof(double)*n);
- memcpy(dfdx, dfdx_cur, sizeof(double)*n);
- memcpy(dfcdx, dfcdx_cur, sizeof(double)*n*m);
-
- /* once we have reached a feasible solution, the
- algorithm should never make the solution infeasible
- again (if inner_done), although the constraints may
- be violated slightly by rounding errors etc. so we
- must be a little careful about checking feasibility */
- if (infeasibility_cur == 0) {
- if (!feasible) { /* reset upper bounds to infin. */
- for (i = 0; i < m; ++i) dual_ub[i] = HUGE_VAL;
- nlopt_set_upper_bounds(dual_opt, dual_ub);
- }
- feasible = 1;
- }
- else if (new_infeasible_constraint) feasible = 0;
-
- }
- if (nlopt_stop_forced(stop)) ret = NLOPT_FORCED_STOP;
- else if (nlopt_stop_evals(stop)) ret = NLOPT_MAXEVAL_REACHED;
- else if (nlopt_stop_time(stop)) ret = NLOPT_MAXTIME_REACHED;
- else if (feasible && *minf < stop->minf_max)
- ret = NLOPT_MINF_MAX_REACHED;
- if (ret != NLOPT_SUCCESS) goto done;
-
- if (inner_done) break;
-
- if (fcur > dd.gval)
- rho = MIN(10*rho, 1.1 * (rho + (fcur-dd.gval) / dd.wval));
- for (i = 0; i < m; ++i)
- if (!isnan(fcval_cur[i]) && fcval_cur[i] > dd.gcval[i])
- rhoc[i] =
- MIN(10*rhoc[i],
- 1.1 * (rhoc[i] + (fcval_cur[i]-dd.gcval[i])
- / dd.wval));
-
- if (mma_verbose)
- printf("MMA inner iteration: rho -> %g\n", rho);
- for (i = 0; i < MIN(mma_verbose, m); ++i)
- printf(" MMA rhoc[%d] -> %g\n", i,rhoc[i]);
- }
-
- if (nlopt_stop_ftol(stop, fcur, fprev))
- ret = NLOPT_FTOL_REACHED;
- if (nlopt_stop_x(stop, xcur, xprev))
- ret = NLOPT_XTOL_REACHED;
- if (ret != NLOPT_SUCCESS) goto done;
-
- /* update rho and sigma for iteration k+1 */
- rho = MAX(0.1 * rho, MMA_RHOMIN);
- if (mma_verbose)
- printf("MMA outer iteration: rho -> %g\n", rho);
- for (i = 0; i < m; ++i)
- rhoc[i] = MAX(0.1 * rhoc[i], MMA_RHOMIN);
- for (i = 0; i < MIN(mma_verbose, m); ++i)
- printf(" MMA rhoc[%d] -> %g\n", i, rhoc[i]);
- if (k > 1) {
- for (j = 0; j < n; ++j) {
- double dx2 = (xcur[j]-xprev[j]) * (xprev[j]-xprevprev[j]);
- double gam = dx2 < 0 ? 0.7 : (dx2 > 0 ? 1.2 : 1);
- sigma[j] *= gam;
- if (!nlopt_isinf(ub[j]) && !nlopt_isinf(lb[j])) {
- sigma[j] = MIN(sigma[j], 10*(ub[j]-lb[j]));
- sigma[j] = MAX(sigma[j], 0.01*(ub[j]-lb[j]));
- }
- }
- for (j = 0; j < MIN(mma_verbose, n); ++j)
- printf(" MMA sigma[%d] -> %g\n",
- j, sigma[j]);
- }
- }
-
- done:
- free(sigma);
- return ret;
-}
diff --git a/ext/src/nlopt/neldermead/README b/ext/src/nlopt/neldermead/README
deleted file mode 100644
index 1d02088..0000000
--- a/ext/src/nlopt/neldermead/README
+++ /dev/null
@@ -1,107 +0,0 @@
-This directory contains Nelder-Mead and variations thereof.
-
-Currently, I have implemented two algorithms, described below.
-
-The code in this directory is under the same MIT license as the rest
-of my code in NLopt (see ../COPYRIGHT).
-
-Steven G. Johnson
-November 2008
-
------------------------------------------------------------------------
-
-First, (almost) the original Nelder-Mead simplex algorithm
-(NLOPT_LN_NELDERMEAD), as described in:
-
- J. A. Nelder and R. Mead, "A simplex method for function
- minimization," The Computer Journal 7, p. 308-313 (1965).
-
-This method is simple and has demonstrated enduring popularity,
-despite the later discovery that it fails to converge at all for some
-functions. Anecdotal evidence suggests that it often performs well
-even for noisy and/or discontinuous objective functions. I would tend
-to recommend the Subplex method (below) instead, however.
-
-The main variation is that I implemented explicit support for bound
-constraints, using essentially the method described in:
-
- J. A. Richardson and J. L. Kuester, "The complex method for
- constrained optimization," Commun. ACM 16(8), 487-489 (1973).
-
- implementing the method described by:
-
- M. J. Box, "A new method of constrained optimization and a
- comparison with other methods," Computer J. 8 (1), 42-52 (1965).
-
-Whenever a new point would lie outside the bound constraints, Box
-advocates moving it "just inside" the constraints. I couldn't see any
-advantage to using a fixed distance inside the constraints, especially
-if the optimum is on the constraint, so instead I move the point
-exactly onto the constraint in that case.
-
-The danger with implementing bound constraints in this way (or by
-Box's method) is that you may collapse the simplex into a
-lower-dimensional subspace. I'm not aware of a better way, however.
-In any case, this collapse of the simplex is ameliorated by
-restarting, such as when Nelder-Mead is used within the Subplex
-algorithm below.
-
------------------------------------------------------------------------
-
-Second, I re-implemented Tom Rowan's "Subplex" algorithm. As Rowan
-expressed a preference that other implementations of his algorithm use
-a different name, I called my implementation "Sbplx" (NLOPT_LN_SBPLX).
-Subplex (a variant of Nelder-Mead that uses Nelder-Mead on a sequence
-of subspaces) is claimed to be much more efficient and robust than the
-original Nelder-Mead, while retaining the latter's facility with
-discontinuous objectives, and in my experience these claims seem to be
-true. (However, I'm not aware of any proof that Subplex is globally
-convergent, and may fail for some objectives like Nelder-Mead; YMMV.)
-
-I used the description of Rowan's algorithm in his PhD thesis:
-
- T. Rowan, "Functional Stability Analysis of Numerical Algorithms",
- Ph.D. thesis, Department of Computer Sciences, University of Texas
- at Austin, 1990.
-
-I would have preferred to use Rowan's original implementation, posted
-by him on Netlib:
-
- http://www.netlib.org/opt/subplex.tgz
-
-Unfortunately, the legality of redistributing or modifying this code
-is unclear. Rowan didn't include any license statement at all with
-the original code, which makes it technically illegal to redistribute.
-I contacted Rowan about getting a clear open-source/free-software
-license for it, and he was very agreeable, but he said he had to think
-about the specific license choice and would get back to me.
-Unfortunately, a year later I still haven't heard from him, and his
-old email address no longer seems to work, so I don't know how to
-contact him for permission.
-
-Since the algorithm is not too complicated, however, I just rewrote
-it. There seem to be slight differences between the behavior of my
-implementation and his (probably due to different choices of initial
-subspace and other slight variations, where his paper was ambiguous),
-but the number of iterations to converge on my test problems seems to
-be quite close (within 10% for most problems).
-
-The only major difference between my implementation and Rowan's, as
-far as I can tell, is that I implemented explicit support for bound
-constraints (via the method in the Box paper as described above).
-This seems to be a big improvement in the case where the optimum lies
-against one of the constraints.
-
------------------------------------------------------------------------
-
-Future possibilities:
-
- C. J. Price, I. D. Coope, and D. Byatt, "A convergent variant
- of the Nelder-Mead algorithm," J. Optim. Theory Appl. 113 (1),
- p. 5-19 (2002).
-
- A. Burmen, J. Puhan, and T. Tuma, "Grid restrained Nelder-Mead
- algorithm," Computational Optim. Appl. 34(3), 359-375 (2006).
-
-Both of these are provably convergent variations of Nelder-Mead; the
-latter authors claim that theirs is superior.
diff --git a/ext/src/nlopt/neldermead/nldrmd.c b/ext/src/nlopt/neldermead/nldrmd.c
deleted file mode 100644
index 643471e..0000000
--- a/ext/src/nlopt/neldermead/nldrmd.c
+++ /dev/null
@@ -1,306 +0,0 @@
-/* Copyright (c) 2007-2012 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "nlopt/neldermead.h"
-#include "nlopt/redblack.h"
-
-/* Nelder-Mead simplex algorithm, used as a subroutine for the Rowan's
- subplex algorithm. Modified to handle bound constraints ala
- Richardson and Kuester (1973), as mentioned below. */
-
-/* heuristic "strategy" constants: */
-static const double alpha = 1, beta = 0.5, gamm = 2, delta = 0.5;
-
-/* sort order in red-black tree: keys [f(x), x] are sorted by f(x) */
-static int simplex_compare(double *k1, double *k2)
-{
- if (*k1 < *k2) return -1;
- if (*k1 > *k2) return +1;
- return k1 - k2; /* tie-breaker */
-}
-
-/* return 1 if a and b are approximately equal relative to floating-point
- precision, 0 otherwise */
-static int close(double a, double b)
-{
- return (fabs(a - b) <= 1e-13 * (fabs(a) + fabs(b)));
-}
-
-/* Perform the reflection xnew = c + scale * (c - xold),
- returning 0 if xnew == c or xnew == xold (coincident points), 1 otherwise.
-
- The reflected point xnew is "pinned" to the lower and upper bounds
- (lb and ub), as suggested by J. A. Richardson and J. L. Kuester,
- "The complex method for constrained optimization," Commun. ACM
- 16(8), 487-489 (1973). This is probably a suboptimal way to handle
- bound constraints, but I don't know a better way. The main danger
- with this is that the simplex might collapse into a
- lower-dimensional hyperplane; this danger can be ameliorated by
- restarting (as in subplex), however. */
-static int reflectpt(int n, double *xnew,
- const double *c, double scale, const double *xold,
- const double *lb, const double *ub)
-{
- int equalc = 1, equalold = 1, i;
- for (i = 0; i < n; ++i) {
- double newx = c[i] + scale * (c[i] - xold[i]);
- if (newx < lb[i]) newx = lb[i];
- if (newx > ub[i]) newx = ub[i];
- equalc = equalc && close(newx, c[i]);
- equalold = equalold && close(newx, xold[i]);
- xnew[i] = newx;
- }
- return !(equalc || equalold);
-}
-
-#define CHECK_EVAL(xc,fc) \
- stop->nevals++; \
- if (nlopt_stop_forced(stop)) { ret=NLOPT_FORCED_STOP; goto done; } \
- if ((fc) <= *minf) { \
- *minf = (fc); memcpy(x, (xc), n * sizeof(double)); \
- if (*minf < stop->minf_max) { ret=NLOPT_MINF_MAX_REACHED; goto done; } \
- } \
- if (nlopt_stop_evals(stop)) { ret=NLOPT_MAXEVAL_REACHED; goto done; } \
- if (nlopt_stop_time(stop)) { ret=NLOPT_MAXTIME_REACHED; goto done; }
-
-/* Internal version of nldrmd_minimize, intended to be used as
- a subroutine for the subplex method. Three differences compared
- to nldrmd_minimize:
-
- *minf should contain the value of f(x) (so that we don't have to
- re-evaluate f at the starting x).
-
- if psi > 0, then it *replaces* xtol and ftol in stop with the condition
- that the simplex diameter |xl - xh| must be reduced by a factor of psi
- ... this is for when nldrmd is used within the subplex method; for
- ordinary termination tests, set psi = 0.
-
- scratch should contain an array of length >= (n+1)*(n+1) + 2*n,
- used as scratch workspace.
-
- On output, *fdiff will contain the difference between the high
- and low function values of the last simplex. */
-nlopt_result nldrmd_minimize_(int n, nlopt_func f, void *f_data,
- const double *lb, const double *ub, /* bounds */
- double *x, /* in: initial guess, out: minimizer */
- double *minf,
- const double *xstep, /* initial step sizes */
- nlopt_stopping *stop,
- double psi, double *scratch,
- double *fdiff)
-{
- double *pts; /* (n+1) x (n+1) array of n+1 points plus function val [0] */
- double *c; /* centroid * n */
- double *xcur; /* current point */
- rb_tree t; /* red-black tree of simplex, sorted by f(x) */
- int i, j;
- double ninv = 1.0 / n;
- nlopt_result ret = NLOPT_SUCCESS;
- double init_diam = 0;
-
- pts = scratch;
- c = scratch + (n+1)*(n+1);
- xcur = c + n;
-
- rb_tree_init(&t, simplex_compare);
-
- *fdiff = HUGE_VAL;
-
- /* initialize the simplex based on the starting xstep */
- memcpy(pts+1, x, sizeof(double)*n);
- pts[0] = *minf;
- if (*minf < stop->minf_max) { ret=NLOPT_MINF_MAX_REACHED; goto done; }
- for (i = 0; i < n; ++i) {
- double *pt = pts + (i+1)*(n+1);
- memcpy(pt+1, x, sizeof(double)*n);
- pt[1+i] += xstep[i];
- if (pt[1+i] > ub[i]) {
- if (ub[i] - x[i] > fabs(xstep[i]) * 0.1)
- pt[1+i] = ub[i];
- else /* ub is too close to pt, go in other direction */
- pt[1+i] = x[i] - fabs(xstep[i]);
- }
- if (pt[1+i] < lb[i]) {
- if (x[i] - lb[i] > fabs(xstep[i]) * 0.1)
- pt[1+i] = lb[i];
- else {/* lb is too close to pt, go in other direction */
- pt[1+i] = x[i] + fabs(xstep[i]);
- if (pt[1+i] > ub[i]) /* go towards further of lb, ub */
- pt[1+i] = 0.5 * ((ub[i] - x[i] > x[i] - lb[i] ?
- ub[i] : lb[i]) + x[i]);
- }
- }
- if (close(pt[1+i], x[i])) { ret=NLOPT_FAILURE; goto done; }
- pt[0] = f(n, pt+1, NULL, f_data);
- CHECK_EVAL(pt+1, pt[0]);
- }
-
- restart:
- for (i = 0; i < n + 1; ++i)
- if (!rb_tree_insert(&t, pts + i*(n+1))) {
- ret = NLOPT_OUT_OF_MEMORY;
- goto done;
- }
-
- while (1) {
- rb_node *low = rb_tree_min(&t);
- rb_node *high = rb_tree_max(&t);
- double fl = low->k[0], *xl = low->k + 1;
- double fh = high->k[0], *xh = high->k + 1;
- double fr;
-
- *fdiff = fh - fl;
-
- if (init_diam == 0) /* initialize diam. for psi convergence test */
- for (i = 0; i < n; ++i) init_diam += fabs(xl[i] - xh[i]);
-
- if (psi <= 0 && nlopt_stop_ftol(stop, fl, fh)) {
- ret = NLOPT_FTOL_REACHED;
- goto done;
- }
-
- /* compute centroid ... if we cared about the perfomance of this,
- we could do it iteratively by updating the centroid on
- each step, but then we would have to be more careful about
- accumulation of rounding errors... anyway n is unlikely to
- be very large for Nelder-Mead in practical cases */
- memset(c, 0, sizeof(double)*n);
- for (i = 0; i < n + 1; ++i) {
- double *xi = pts + i*(n+1) + 1;
- if (xi != xh)
- for (j = 0; j < n; ++j)
- c[j] += xi[j];
- }
- for (i = 0; i < n; ++i) c[i] *= ninv;
-
- /* x convergence check: find xcur = max radius from centroid */
- memset(xcur, 0, sizeof(double)*n);
- for (i = 0; i < n + 1; ++i) {
- double *xi = pts + i*(n+1) + 1;
- for (j = 0; j < n; ++j) {
- double dx = fabs(xi[j] - c[j]);
- if (dx > xcur[j]) xcur[j] = dx;
- }
- }
- for (i = 0; i < n; ++i) xcur[i] += c[i];
- if (psi > 0) {
- double diam = 0;
- for (i = 0; i < n; ++i) diam += fabs(xl[i] - xh[i]);
- if (diam < psi * init_diam) {
- ret = NLOPT_XTOL_REACHED;
- goto done;
- }
- }
- else if (nlopt_stop_x(stop, c, xcur)) {
- ret = NLOPT_XTOL_REACHED;
- goto done;
- }
-
- /* reflection */
- if (!reflectpt(n, xcur, c, alpha, xh, lb, ub)) {
- ret=NLOPT_XTOL_REACHED; goto done;
- }
- fr = f(n, xcur, NULL, f_data);
- CHECK_EVAL(xcur, fr);
-
- if (fr < fl) { /* new best point, expand simplex */
- if (!reflectpt(n, xh, c, gamm, xh, lb, ub)) {
- ret=NLOPT_XTOL_REACHED; goto done;
- }
- fh = f(n, xh, NULL, f_data);
- CHECK_EVAL(xh, fh);
- if (fh >= fr) { /* expanding didn't improve */
- fh = fr;
- memcpy(xh, xcur, sizeof(double)*n);
- }
- }
- else if (fr < rb_tree_pred(high)->k[0]) { /* accept new point */
- memcpy(xh, xcur, sizeof(double)*n);
- fh = fr;
- }
- else { /* new worst point, contract */
- double fc;
- if (!reflectpt(n,xcur,c, fh <= fr ? -beta : beta, xh, lb,ub)) {
- ret=NLOPT_XTOL_REACHED; goto done;
- }
- fc = f(n, xcur, NULL, f_data);
- CHECK_EVAL(xcur, fc);
- if (fc < fr && fc < fh) { /* successful contraction */
- memcpy(xh, xcur, sizeof(double)*n);
- fh = fc;
- }
- else { /* failed contraction, shrink simplex */
- rb_tree_destroy(&t);
- rb_tree_init(&t, simplex_compare);
- for (i = 0; i < n+1; ++i) {
- double *pt = pts + i * (n+1);
- if (pt+1 != xl) {
- if (!reflectpt(n,pt+1, xl,-delta,pt+1, lb,ub)) {
- ret = NLOPT_XTOL_REACHED;
- goto done;
- }
- pt[0] = f(n, pt+1, NULL, f_data);
- CHECK_EVAL(pt+1, pt[0]);
- }
- }
- goto restart;
- }
- }
-
- high->k[0] = fh;
- rb_tree_resort(&t, high);
- }
-
-done:
- rb_tree_destroy(&t);
- return ret;
-}
-
-nlopt_result nldrmd_minimize(int n, nlopt_func f, void *f_data,
- const double *lb, const double *ub, /* bounds */
- double *x, /* in: initial guess, out: minimizer */
- double *minf,
- const double *xstep, /* initial step sizes */
- nlopt_stopping *stop)
-{
- nlopt_result ret;
- double *scratch, fdiff;
-
- *minf = f(n, x, NULL, f_data);
- stop->nevals++;
- if (nlopt_stop_forced(stop)) return NLOPT_FORCED_STOP;
- if (*minf < stop->minf_max) return NLOPT_MINF_MAX_REACHED;
- if (nlopt_stop_evals(stop)) return NLOPT_MAXEVAL_REACHED;
- if (nlopt_stop_time(stop)) return NLOPT_MAXTIME_REACHED;
-
- scratch = (double*) malloc(sizeof(double) * ((n+1)*(n+1) + 2*n));
- if (!scratch) return NLOPT_OUT_OF_MEMORY;
-
- ret = nldrmd_minimize_(n, f, f_data, lb, ub, x, minf, xstep, stop,
- 0.0, scratch, &fdiff);
- free(scratch);
- return ret;
-}
diff --git a/ext/src/nlopt/neldermead/sbplx.c b/ext/src/nlopt/neldermead/sbplx.c
deleted file mode 100644
index 6b8371e..0000000
--- a/ext/src/nlopt/neldermead/sbplx.c
+++ /dev/null
@@ -1,239 +0,0 @@
-/* Copyright (c) 2007-2012 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <math.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "nlopt/neldermead.h"
-
-/* subplex strategy constants: */
-static const double psi = 0.25, omega = 0.1;
-static const int nsmin = 2, nsmax = 5;
-
-int sbplx_verbose = 0; /* for debugging */
-
-/* qsort_r comparison function for sorting indices into delta-x array */
-static int p_compare(void *dx_, const void *i_, const void *j_)
-{
- const double *dx = (const double *) dx_;
- int i = *((const int *) i_), j = *((const int *) j_);
- double dxi = fabs(dx[i]), dxj = fabs(dx[j]);
- return (dxi > dxj ? -1 : (dxi < dxj ? +1 : 0));
-}
-
-typedef struct {
- const int *p; /* subspace index permutation */
- int is; /* starting index for this subspace */
- int n; /* dimension of underlying space */
- double *x; /* current x vector */
- nlopt_func f; void *f_data; /* the "actual" underlying function */
-} subspace_data;
-
-/* wrapper around objective function for subspace optimization */
-static double subspace_func(unsigned ns, const double *xs, double *grad, void *data)
-{
- subspace_data *d = (subspace_data *) data;
- int i, is = d->is;
- const int *p = d->p;
- double *x = d->x;
-
- (void) grad; /* should always be NULL here */
- for (i = is; i < is + ((int) ns); ++i) x[p[i]] = xs[i-is];
- return d->f(d->n, x, NULL, d->f_data);
-}
-
-nlopt_result sbplx_minimize(int n, nlopt_func f, void *f_data,
- const double *lb, const double *ub, /* bounds */
- double *x, /* in: initial guess, out: minimizer */
- double *minf,
- const double *xstep0, /* initial step sizes */
- nlopt_stopping *stop)
-{
- nlopt_result ret = NLOPT_SUCCESS;
- double *xstep, *xprev, *dx, *xs, *lbs, *ubs, *xsstep, *scratch;
- int *p; /* permuted indices of x sorted by decreasing magnitude |dx| */
- int i;
- subspace_data sd;
- double fprev;
-
- *minf = f(n, x, NULL, f_data);
- stop->nevals++;
- if (nlopt_stop_forced(stop)) return NLOPT_FORCED_STOP;
- if (*minf < stop->minf_max) return NLOPT_MINF_MAX_REACHED;
- if (nlopt_stop_evals(stop)) return NLOPT_MAXEVAL_REACHED;
- if (nlopt_stop_time(stop)) return NLOPT_MAXTIME_REACHED;
-
- xstep = (double*)malloc(sizeof(double) * (n*3 + nsmax*4
- + (nsmax+1)*(nsmax+1)+2*nsmax));
- if (!xstep) return NLOPT_OUT_OF_MEMORY;
- xprev = xstep + n; dx = xprev + n;
- xs = dx + n; xsstep = xs + nsmax;
- lbs = xsstep + nsmax; ubs = lbs + nsmax;
- scratch = ubs + nsmax;
- p = (int *) malloc(sizeof(int) * n);
- if (!p) { free(xstep); return NLOPT_OUT_OF_MEMORY; }
-
- memcpy(xstep, xstep0, n * sizeof(double));
- memset(dx, 0, n * sizeof(double));
-
- sd.p = p;
- sd.n = n;
- sd.x = x;
- sd.f = f;
- sd.f_data = f_data;
-
- while (1) {
- double normi = 0;
- double normdx = 0;
- int ns, nsubs = 0;
- int nevals = stop->nevals;
- double fdiff, fdiff_max = 0;
-
- memcpy(xprev, x, n * sizeof(double));
- fprev = *minf;
-
- /* sort indices into the progress vector dx by decreasing
- order of magnitude |dx| */
- for (i = 0; i < n; ++i) p[i] = i;
- nlopt_qsort_r(p, (size_t) n, sizeof(int), dx, p_compare);
-
- /* find the subspaces, and perform nelder-mead on each one */
- for (i = 0; i < n; ++i) normdx += fabs(dx[i]); /* L1 norm */
- for (i = 0; i + nsmin < n; i += ns) {
- /* find subspace starting at index i */
- int k, nk;
- double ns_goodness = -HUGE_VAL, norm = normi;
- nk = i+nsmax > n ? n : i+nsmax; /* max k for this subspace */
- for (k = i; k < i+nsmin-1; ++k) norm += fabs(dx[p[k]]);
- ns = nsmin;
- for (k = i+nsmin-1; k < nk; ++k) {
- double goodness;
- norm += fabs(dx[p[k]]);
- /* remaining subspaces must be big enough to partition */
- if (n-(k+1) < nsmin) continue;
- /* maximize figure of merit defined by Rowan thesis:
- look for sudden drops in average |dx| */
- if (k+1 < n)
- goodness = norm/(k+1) - (normdx-norm)/(n-(k+1));
- else
- goodness = normdx/n;
- if (goodness > ns_goodness) {
- ns_goodness = goodness;
- ns = (k+1)-i;
- }
- }
- for (k = i; k < i+ns; ++k) normi += fabs(dx[p[k]]);
- /* do nelder-mead on subspace of dimension ns starting w/i */
- sd.is = i;
- for (k = i; k < i+ns; ++k) {
- xs[k-i] = x[p[k]];
- xsstep[k-i] = xstep[p[k]];
- lbs[k-i] = lb[p[k]];
- ubs[k-i] = ub[p[k]];
- }
- ++nsubs;
- nevals = stop->nevals;
- ret = nldrmd_minimize_(ns, subspace_func, &sd, lbs,ubs,xs, minf,
- xsstep, stop, psi, scratch, &fdiff);
- if (fdiff > fdiff_max) fdiff_max = fdiff;
- if (sbplx_verbose)
- printf("%d NM iterations for (%d,%d) subspace\n",
- stop->nevals - nevals, sd.is, ns);
- for (k = i; k < i+ns; ++k) x[p[k]] = xs[k-i];
- if (ret == NLOPT_FAILURE) { ret=NLOPT_XTOL_REACHED; goto done; }
- if (ret != NLOPT_XTOL_REACHED) goto done;
- }
- /* nelder-mead on last subspace */
- ns = n - i;
- sd.is = i;
- for (; i < n; ++i) {
- xs[i-sd.is] = x[p[i]];
- xsstep[i-sd.is] = xstep[p[i]];
- lbs[i-sd.is] = lb[p[i]];
- ubs[i-sd.is] = ub[p[i]];
- }
- ++nsubs;
- nevals = stop->nevals;
- ret = nldrmd_minimize_(ns, subspace_func, &sd, lbs,ubs,xs, minf,
- xsstep, stop, psi, scratch, &fdiff);
- if (fdiff > fdiff_max) fdiff_max = fdiff;
- if (sbplx_verbose)
- printf("sbplx: %d NM iterations for (%d,%d) subspace\n",
- stop->nevals - nevals, sd.is, ns);
- for (i = sd.is; i < n; ++i) x[p[i]] = xs[i-sd.is];
- if (ret == NLOPT_FAILURE) { ret=NLOPT_XTOL_REACHED; goto done; }
- if (ret != NLOPT_XTOL_REACHED) goto done;
-
- /* termination tests: */
- if (nlopt_stop_ftol(stop, *minf, *minf + fdiff_max)) {
- ret = NLOPT_FTOL_REACHED;
- goto done;
- }
- if (nlopt_stop_x(stop, x, xprev)) {
- int j;
- /* as explained in Rowan's thesis, it is important
- to check |xstep| as well as |x-xprev|, since if
- the step size is too large (in early iterations),
- the inner Nelder-Mead may not make much progress */
- for (j = 0; j < n; ++j)
- if (fabs(xstep[j]) * psi > stop->xtol_abs[j]
- && fabs(xstep[j]) * psi > stop->xtol_rel * fabs(x[j]))
- break;
- if (j == n) {
- ret = NLOPT_XTOL_REACHED;
- goto done;
- }
- }
-
- /* compute change in optimal point */
- for (i = 0; i < n; ++i) dx[i] = x[i] - xprev[i];
-
- /* setting stepsizes */
- {
- double scale;
- if (nsubs == 1)
- scale = psi;
- else {
- double stepnorm = 0, dxnorm = 0;
- for (i = 0; i < n; ++i) {
- stepnorm += fabs(xstep[i]);
- dxnorm += fabs(dx[i]);
- }
- scale = dxnorm / stepnorm;
- if (scale < omega) scale = omega;
- if (scale > 1/omega) scale = 1/omega;
- }
- if (sbplx_verbose)
- printf("sbplx: stepsize scale factor = %g\n", scale);
- for (i = 0; i < n; ++i)
- xstep[i] = (dx[i] == 0) ? -(xstep[i] * scale)
- : copysign(xstep[i] * scale, dx[i]);
- }
- }
-
- done:
- free(p);
- free(xstep);
- return ret;
-}
diff --git a/ext/src/nlopt/newuoa/COPYRIGHT b/ext/src/nlopt/newuoa/COPYRIGHT
deleted file mode 100644
index af4e0b8..0000000
--- a/ext/src/nlopt/newuoa/COPYRIGHT
+++ /dev/null
@@ -1,23 +0,0 @@
-/* Copyright (c) 2004 M. J. D. Powell (mjdp at cam.ac.uk)
- * Copyright (c) 2007-2011 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
diff --git a/ext/src/nlopt/newuoa/README b/ext/src/nlopt/newuoa/README
deleted file mode 100644
index 8055e8c..0000000
--- a/ext/src/nlopt/newuoa/README
+++ /dev/null
@@ -1,29 +0,0 @@
-This is the NEWUOA software by M. J. D. Powell, which performs
-derivative-free unconstrained optimization using an iteratively
-constructred quadratic approximation for the objective function. See:
-
- M. J. D. Powell, "The NEWUOA software for unconstrained
- optimization without derivatives," Proc. 40th Workshop
- on Large Scale Nonlinear Optimization (Erice, Italy, 2004).
-
-The C translation by S. G. Johnson (2008) includes a few minor
-modifications, mainly to use the NLopt stopping criteria (and to
-take the objective function as an argument rather than a global).
-
-The C translation also includes a variant (NEWUOA_BOUND, when the lb
-and ub parameters to newuoa are non-NULL) that is substantially
-modified in order to support bound constraints on the input variables.
-In the original NEWUOA algorithm, Powell solved the quadratic
-subproblems (in routines TRSAPP and BIGLAG) in a spherical trust
-region via a truncated conjugate-gradient algorithm. In the new
-variant, we use the MMA algorithm for these subproblems to solve them
-with both bound constraints and a spherical trust region. In principle,
-we should also change the BIGDEN subroutine in a similar way (since
-BIGDEN also approximately solves a trust-region subproblem), but instead
-I just truncated its result to the bounds (which probably gives suboptimal
-convergence, but BIGDEN is called only very rarely in practice).
-
-The original Fortran code was released by Powell with "no restrictions
-or charges", and the C translation by S. G. Johnson is released in a
-similar spirit under the MIT License (see the COPYRIGHT file in this
-directory).
diff --git a/ext/src/nlopt/newuoa/README.orig b/ext/src/nlopt/newuoa/README.orig
deleted file mode 100644
index 23f7354..0000000
--- a/ext/src/nlopt/newuoa/README.orig
+++ /dev/null
@@ -1,40 +0,0 @@
- This is the Fortran version of NEWUOA. Its purpose is to seek
-the least value of a function F of several variables, when derivatives
-are not available, where F is specified by the user through a subroutine
-called CALFUN. The algorithm is intended to change the variables to values
-that are close to a local minimum of F. The user, however, should assume
-responsibility for finding out if the calculations are satisfactory, by
-considering carefully the values of F that occur. The method is described
-in the report "The NEWUOA software for unconstrained optimization without
-derivatives", which is available on the web at www.damtp.cam.ac.uk, where
-you have to click on Numerical Analysis and then on Reports, the number
-of the report being NA2004/08. Let N be the number of variables. The main
-new feature of the method is that quadratic models are updated using only
-about NPT=2N+1 interpolation conditions, the remaining freedom being taken
-up by minimizing the Frobenius norm of the change to the second derivative
-matrix of the model.
-
- The new software was developed from UOBYQA, which also forms quadratic
-models from interpolation conditions. That method requires NPT=(N+1)(N+2)/2
-conditions, however, because they have to define all the parameters of the
-model. The least Frobenius norm updating procedure with NPT=2N+1 is usually
-much more efficient when N is large, because the work of each iteration is
-much less than before, and in some experiments the number of calculations
-of the objective function seems to be only of magnitude N.
-
- The attachments in sequence are a suitable Makefile, followed by a main
-program and a CALFUN routine for the Chebyquad problems, in order to provide
-an example for testing. Then NEWUOA and its five auxiliary routines, namely
-NEWUOB, BIGDEN, BIGLAG, TRSAPP and UPDATE, are given. Finally, the computed
-output that the author obtained for the Chebyquad problems is listed.
-
- The way of calling NEWUOA should be clear from the Chebyquad example
-and from the comments of that subroutine. It is hoped that the software will
-be helpful to much future research and to many applications. There are no
-restrictions on or charges for its use. If you wish to refer to it, please
-cite the DAMTP report that is mentioned above, which has been submitted for
-publication in the proceedings of the 40th Workshop on Large Scale Nonlinear
-Optimization (Erice, Italy, 2004).
-
-December 16th, 2004 M.J.D. Powell (mjdp at cam.ac.uk)
-
diff --git a/ext/src/nlopt/newuoa/newuoa.c b/ext/src/nlopt/newuoa/newuoa.c
deleted file mode 100644
index 71b5bc6..0000000
--- a/ext/src/nlopt/newuoa/newuoa.c
+++ /dev/null
@@ -1,2560 +0,0 @@
-/* Copyright (c) 2004 M. J. D. Powell (mjdp at cam.ac.uk)
- * Copyright (c) 2007-2012 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/* NEWUOA derivative-free optimization algorithm by M. J. D. Powell.
- Original Fortran code by Powell (2004). Converted via f2c, cleaned up,
- and incorporated into NLopt by S. G. Johnson (2008). See README. */
-
-#include <math.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "nlopt/newuoa.h"
-
-#define MIN2(a,b) ((a) <= (b) ? (a) : (b))
-#define MAX2(a,b) ((a) >= (b) ? (a) : (b))
-
-/*************************************************************************/
-/* trsapp.f */
-
-typedef struct {
- int npt;
- double *xpt, *pq, *hq, *gq, *xopt;
- double *hd;
- int iter;
-} quad_model_data;
-
-static double quad_model(int n, const double *x, double *grad, void *data)
-{
- quad_model_data *d = (quad_model_data *) data;
- const double *xpt = d->xpt, *pq = d->pq, *hq = d->hq, *gq = d->gq, *xopt = d->xopt;
- double *hd = d->hd;
- int npt = d->npt;
- int i, j, k;
- double val = 0;
-
- /* first, set hd to be Hessian matrix times x */
- memset(hd, 0, sizeof(double) * n);
- /* implicit Hessian terms (a sum of outer products of xpt vectors) */
- for (k = 0; k < npt; ++k) {
- double temp = 0;
- for (j = 0; j < n; ++j)
- temp += xpt[k + j * npt] * (xopt[j] + x[j]);
- temp *= pq[k];
- for (i = 0; i < n; ++i)
- hd[i] += temp * xpt[k + i * npt];
- }
- /* explicit Hessian terms (stored as compressed lower triangle hq) */
- k = 0;
- for (j = 0; j < n; ++j) {
- for (i = 0; i < j; ++i) {
- hd[j] += hq[k] * (xopt[i] + x[i]);
- hd[i] += hq[k] * (xopt[j] + x[j]);
- ++k;
- }
- hd[j] += hq[k++] * (xopt[j] + x[j]);
- }
-
- for (i = 0; i < n; ++i) {
- val += (gq[i] + 0.5 * hd[i]) * (xopt[i] + x[i]);
- if (grad) grad[i] = gq[i] + hd[i];
- }
- d->iter++;
- return val;
-}
-
-/* constraint function to enforce |x|^2 <= rho*rho */
-static double rho_constraint(int n, const double *x, double *grad, void *data)
-{
- double rho = *((double *) data);
- double val = - rho*rho;
- int i;
- for (i = 0; i < n; ++i)
- val += x[i] * x[i];
- if (grad) for (i = 0; i < n; ++i) grad[i] = 2*x[i];
- return val;
-}
-
-static nlopt_result trsapp_(int *n, int *npt, double *xopt,
- double *xpt, double *gq, double *hq, double *pq,
- double *delta, double *step, double *d__, double *g,
- double *hd, double *hs, double *crvmin,
- const double *xbase, const double *lb, const double *ub)
-{
- /* System generated locals */
- int xpt_dim1, xpt_offset, i__1, i__2;
- double d__1, d__2;
-
- /* Local variables */
- int i__, j, k;
- double dd, cf, dg, gg;
- int ih;
- double ds, sg;
- int iu;
- double ss, dhd, dhs, cth, sgk, shs, sth, qadd, half, qbeg, qred, qmin,
- temp, qsav, qnew, zero, ggbeg, alpha, angle, reduc;
- int iterc;
- double ggsav, delsq, tempa, tempb;
- int isave;
- double bstep, ratio, twopi;
- int itersw;
- double angtest;
- int itermax;
-
-
-/* N is the number of variables of a quadratic objective function, Q say. */
-/* The arguments NPT, XOPT, XPT, GQ, HQ and PQ have their usual meanings, */
-/* in order to define the current quadratic model Q. */
-/* DELTA is the trust region radius, and has to be positive. */
-/* STEP will be set to the calculated trial step. */
-/* The arrays D, G, HD and HS will be used for working space. */
-/* CRVMIN will be set to the least curvature of H along the conjugate */
-/* directions that occur, except that it is set to zero if STEP goes */
-/* all the way to the trust region boundary. */
-
-/* The calculation of STEP begins with the truncated conjugate gradient */
-/* method. If the boundary of the trust region is reached, then further */
-/* changes to STEP may be made, each one being in the 2D space spanned */
-/* by the current STEP and the corresponding gradient of Q. Thus STEP */
-/* should provide a substantial reduction to Q within the trust region. */
-
-/* Initialization, which includes setting HD to H times XOPT. */
-
- /* Parameter adjustments */
- xpt_dim1 = *npt;
- xpt_offset = 1 + xpt_dim1;
- xpt -= xpt_offset;
- --xopt;
- --gq;
- --hq;
- --pq;
- --step;
- --d__;
- --g;
- --hd;
- --hs;
-
- if (lb && ub) {
- double *slb, *sub, *xtol, minf, crv;
- nlopt_result ret;
- quad_model_data qmd;
- qmd.npt = *npt;
- qmd.xpt = &xpt[1 + 1 * xpt_dim1];
- qmd.pq = &pq[1];
- qmd.hq = &hq[1];
- qmd.gq = &gq[1];
- qmd.xopt = &xopt[1];
- qmd.hd = &hd[1];
- qmd.iter = 0;
- slb = &g[1];
- sub = &hs[1];
- xtol = &d__[1];
- for (j = 0; j < *n; ++j) {
- slb[j] = -(sub[j] = *delta);
- if (slb[j] < lb[j] - xbase[j] - xopt[j+1])
- slb[j] = lb[j] - xbase[j] - xopt[j+1];
- if (sub[j] > ub[j] - xbase[j] - xopt[j+1])
- sub[j] = ub[j] - xbase[j] - xopt[j+1];
- if (slb[j] > 0) slb[j] = 0;
- if (sub[j] < 0) sub[j] = 0;
- xtol[j] = 1e-7 * *delta; /* absolute x tolerance */
- }
- memset(&step[1], 0, sizeof(double) * *n);
- ret = nlopt_minimize_constrained(NLOPT_LD_MMA, *n, quad_model, &qmd,
- 1, rho_constraint, delta, sizeof(double),
- slb, sub, &step[1], &minf, -HUGE_VAL,
- 0., 0., 0., xtol, 1000, 0.);
- if (rho_constraint(*n, &step[1], 0, delta) > -1e-6*(*delta)*(*delta))
- crv = 0;
- else {
- for (j = 1; j <= *n; ++j) d__[j] = step[j] - xopt[j];
- quad_model(*n, &d__[1], &g[1], &qmd);
- crv = gg = 0;
- for (j = 1; j <= *n; ++j) {
- crv += step[j] * (g[j] - gq[j]);
- gg += step[j] * step[j];
- }
- if (gg <= 1e-16 * crv)
- crv = 1e16;
- else
- crv = crv / gg;
- }
- *crvmin = crv;
- return ret;
- }
-
- /* Function Body */
- half = .5;
- zero = 0.;
- twopi = atan(1.) * 8.;
- delsq = *delta * *delta;
- iterc = 0;
- itermax = *n;
- itersw = itermax;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
-/* L10: */
- d__[i__] = xopt[i__];
- }
- goto L170;
-
-/* Prepare for the first line search. */
-
-L20:
- qred = zero;
- dd = zero;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- step[i__] = zero;
- hs[i__] = zero;
- g[i__] = gq[i__] + hd[i__];
- d__[i__] = -g[i__];
-/* L30: */
-/* Computing 2nd power */
- d__1 = d__[i__];
- dd += d__1 * d__1;
- }
- *crvmin = zero;
- if (dd == zero) {
- goto L160;
- }
- ds = zero;
- ss = zero;
- gg = dd;
- ggbeg = gg;
-
-/* Calculate the step to the trust region boundary and the product HD. */
-
-L40:
- ++iterc;
- temp = delsq - ss;
- bstep = temp / (ds + sqrt(ds * ds + dd * temp));
- goto L170;
-L50:
- dhd = zero;
- i__1 = *n;
- for (j = 1; j <= i__1; ++j) {
-/* L60: */
- dhd += d__[j] * hd[j];
- }
-
-/* Update CRVMIN and set the step-length ALPHA. */
-
- alpha = bstep;
- if (dhd > zero) {
- temp = dhd / dd;
- if (iterc == 1) {
- *crvmin = temp;
- }
- *crvmin = MIN2(*crvmin,temp);
-/* Computing MIN */
- d__1 = alpha, d__2 = gg / dhd;
- alpha = MIN2(d__1,d__2);
- }
- qadd = alpha * (gg - half * alpha * dhd);
- qred += qadd;
-
-/* Update STEP and HS. */
-
- ggsav = gg;
- gg = zero;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- step[i__] += alpha * d__[i__];
- hs[i__] += alpha * hd[i__];
-/* L70: */
-/* Computing 2nd power */
- d__1 = g[i__] + hs[i__];
- gg += d__1 * d__1;
- }
-
-/* Begin another conjugate direction iteration if required. */
-
- if (alpha < bstep) {
- if (qadd <= qred * .01) {
- goto L160;
- }
- if (gg <= ggbeg * 1e-4) {
- goto L160;
- }
- if (iterc == itermax) {
- goto L160;
- }
- temp = gg / ggsav;
- dd = zero;
- ds = zero;
- ss = zero;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- d__[i__] = temp * d__[i__] - g[i__] - hs[i__];
-/* Computing 2nd power */
- d__1 = d__[i__];
- dd += d__1 * d__1;
- ds += d__[i__] * step[i__];
-/* L80: */
-/* Computing 2nd power */
- d__1 = step[i__];
- ss += d__1 * d__1;
- }
- if (ds <= zero) {
- goto L160;
- }
- if (ss < delsq) {
- goto L40;
- }
- }
- *crvmin = zero;
- itersw = iterc;
-
-/* Test whether an alternative iteration is required. */
-
-L90:
- if (gg <= ggbeg * 1e-4) {
- goto L160;
- }
- sg = zero;
- shs = zero;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- sg += step[i__] * g[i__];
-/* L100: */
- shs += step[i__] * hs[i__];
- }
- sgk = sg + shs;
- angtest = sgk / sqrt(gg * delsq);
- if (angtest <= -.99) {
- goto L160;
- }
-
-/* Begin the alternative iteration by calculating D and HD and some */
-/* scalar products. */
-
- ++iterc;
- temp = sqrt(delsq * gg - sgk * sgk);
- tempa = delsq / temp;
- tempb = sgk / temp;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
-/* L110: */
- d__[i__] = tempa * (g[i__] + hs[i__]) - tempb * step[i__];
- }
- goto L170;
-L120:
- dg = zero;
- dhd = zero;
- dhs = zero;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- dg += d__[i__] * g[i__];
- dhd += hd[i__] * d__[i__];
-/* L130: */
- dhs += hd[i__] * step[i__];
- }
-
-/* Seek the value of the angle that minimizes Q. */
-
- cf = half * (shs - dhd);
- qbeg = sg + cf;
- qsav = qbeg;
- qmin = qbeg;
- isave = 0;
- iu = 49;
- temp = twopi / (double) (iu + 1);
- i__1 = iu;
- for (i__ = 1; i__ <= i__1; ++i__) {
- angle = (double) i__ * temp;
- cth = cos(angle);
- sth = sin(angle);
- qnew = (sg + cf * cth) * cth + (dg + dhs * cth) * sth;
- if (qnew < qmin) {
- qmin = qnew;
- isave = i__;
- tempa = qsav;
- } else if (i__ == isave + 1) {
- tempb = qnew;
- }
-/* L140: */
- qsav = qnew;
- }
- if ((double) isave == zero) {
- tempa = qnew;
- }
- if (isave == iu) {
- tempb = qbeg;
- }
- angle = zero;
- if (tempa != tempb) {
- tempa -= qmin;
- tempb -= qmin;
- angle = half * (tempa - tempb) / (tempa + tempb);
- }
- angle = temp * ((double) isave + angle);
-
-/* Calculate the new STEP and HS. Then test for convergence. */
-
- cth = cos(angle);
- sth = sin(angle);
- reduc = qbeg - (sg + cf * cth) * cth - (dg + dhs * cth) * sth;
- gg = zero;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- step[i__] = cth * step[i__] + sth * d__[i__];
- hs[i__] = cth * hs[i__] + sth * hd[i__];
-/* L150: */
-/* Computing 2nd power */
- d__1 = g[i__] + hs[i__];
- gg += d__1 * d__1;
- }
- qred += reduc;
- ratio = reduc / qred;
- if (iterc < itermax && ratio > .01) {
- goto L90;
- }
-L160:
- return NLOPT_SUCCESS;
-
-/* The following instructions act as a subroutine for setting the vector */
-/* HD to the vector D multiplied by the second derivative matrix of Q. */
-/* They are called from three different places, which are distinguished */
-/* by the value of ITERC. */
-
-L170:
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
-/* L180: */
- hd[i__] = zero;
- }
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
- temp = zero;
- i__2 = *n;
- for (j = 1; j <= i__2; ++j) {
-/* L190: */
- temp += xpt[k + j * xpt_dim1] * d__[j];
- }
- temp *= pq[k];
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
-/* L200: */
- hd[i__] += temp * xpt[k + i__ * xpt_dim1];
- }
- }
- ih = 0;
- i__2 = *n;
- for (j = 1; j <= i__2; ++j) {
- i__1 = j;
- for (i__ = 1; i__ <= i__1; ++i__) {
- ++ih;
- if (i__ < j) {
- hd[j] += hq[ih] * d__[i__];
- }
-/* L210: */
- hd[i__] += hq[ih] * d__[j];
- }
- }
- if (iterc == 0) {
- goto L20;
- }
- if (iterc <= itersw) {
- goto L50;
- }
- goto L120;
-} /* trsapp_ */
-
-
-/*************************************************************************/
-/* bigden.f */
-
-static nlopt_result bigden_(int *n, int *npt, double *xopt,
- double *xpt, double *bmat, double *zmat, int *idz,
- int *ndim, int *kopt, int *knew, double *d__,
- double *w, double *vlag, double *beta, double *s,
- double *wvec, double *prod,
- const double *xbase, const double *lb, const double *ub)
-{
- /* System generated locals */
- int xpt_dim1, xpt_offset, bmat_dim1, bmat_offset, zmat_dim1,
- zmat_offset, wvec_dim1, wvec_offset, prod_dim1, prod_offset, i__1,
- i__2;
- double d__1;
-
- /* Local variables */
- int i__, j, k;
- double dd;
- int jc;
- double ds;
- int ip, iu, nw;
- double ss, den[9], one, par[9], tau, sum, two, diff, half, temp;
- int ksav;
- double step;
- int nptm;
- double zero, alpha, angle, denex[9];
- int iterc;
- double tempa, tempb, tempc;
- int isave;
- double ssden, dtest, quart, xoptd, twopi, xopts, denold, denmax,
- densav, dstemp, sumold, sstemp, xoptsq;
-
-
-/* N is the number of variables. */
-/* NPT is the number of interpolation equations. */
-/* XOPT is the best interpolation point so far. */
-/* XPT contains the coordinates of the current interpolation points. */
-/* BMAT provides the last N columns of H. */
-/* ZMAT and IDZ give a factorization of the first NPT by NPT submatrix of H. */
-/* NDIM is the first dimension of BMAT and has the value NPT+N. */
-/* KOPT is the index of the optimal interpolation point. */
-/* KNEW is the index of the interpolation point that is going to be moved. */
-/* D will be set to the step from XOPT to the new point, and on entry it */
-/* should be the D that was calculated by the last call of BIGLAG. The */
-/* length of the initial D provides a trust region bound on the final D. */
-/* W will be set to Wcheck for the final choice of D. */
-/* VLAG will be set to Theta*Wcheck+e_b for the final choice of D. */
-/* BETA will be set to the value that will occur in the updating formula */
-/* when the KNEW-th interpolation point is moved to its new position. */
-/* S, WVEC, PROD and the private arrays DEN, DENEX and PAR will be used */
-/* for working space. */
-
-/* D is calculated in a way that should provide a denominator with a large */
-/* modulus in the updating formula when the KNEW-th interpolation point is */
-/* shifted to the new position XOPT+D. */
-
-/* Set some constants. */
-
- /* Parameter adjustments */
- zmat_dim1 = *npt;
- zmat_offset = 1 + zmat_dim1;
- zmat -= zmat_offset;
- xpt_dim1 = *npt;
- xpt_offset = 1 + xpt_dim1;
- xpt -= xpt_offset;
- --xopt;
- prod_dim1 = *ndim;
- prod_offset = 1 + prod_dim1;
- prod -= prod_offset;
- wvec_dim1 = *ndim;
- wvec_offset = 1 + wvec_dim1;
- wvec -= wvec_offset;
- bmat_dim1 = *ndim;
- bmat_offset = 1 + bmat_dim1;
- bmat -= bmat_offset;
- --d__;
- --w;
- --vlag;
- --s;
-
- /* Function Body */
- half = .5;
- one = 1.;
- quart = .25;
- two = 2.;
- zero = 0.;
- twopi = atan(one) * 8.;
- nptm = *npt - *n - 1;
-
-/* Store the first NPT elements of the KNEW-th column of H in W(N+1) */
-/* to W(N+NPT). */
-
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
-/* L10: */
- w[*n + k] = zero;
- }
- i__1 = nptm;
- for (j = 1; j <= i__1; ++j) {
- temp = zmat[*knew + j * zmat_dim1];
- if (j < *idz) {
- temp = -temp;
- }
- i__2 = *npt;
- for (k = 1; k <= i__2; ++k) {
-/* L20: */
- w[*n + k] += temp * zmat[k + j * zmat_dim1];
- }
- }
- alpha = w[*n + *knew];
-
-/* The initial search direction D is taken from the last call of BIGLAG, */
-/* and the initial S is set below, usually to the direction from X_OPT */
-/* to X_KNEW, but a different direction to an interpolation point may */
-/* be chosen, in order to prevent S from being nearly parallel to D. */
-
- dd = zero;
- ds = zero;
- ss = zero;
- xoptsq = zero;
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
-/* Computing 2nd power */
- d__1 = d__[i__];
- dd += d__1 * d__1;
- s[i__] = xpt[*knew + i__ * xpt_dim1] - xopt[i__];
- ds += d__[i__] * s[i__];
-/* Computing 2nd power */
- d__1 = s[i__];
- ss += d__1 * d__1;
-/* L30: */
-/* Computing 2nd power */
- d__1 = xopt[i__];
- xoptsq += d__1 * d__1;
- }
- if (ds * ds > dd * .99 * ss) {
- ksav = *knew;
- dtest = ds * ds / ss;
- i__2 = *npt;
- for (k = 1; k <= i__2; ++k) {
- if (k != *kopt) {
- dstemp = zero;
- sstemp = zero;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- diff = xpt[k + i__ * xpt_dim1] - xopt[i__];
- dstemp += d__[i__] * diff;
-/* L40: */
- sstemp += diff * diff;
- }
- if (sstemp == 0) return NLOPT_ROUNDOFF_LIMITED;
- if (dstemp * dstemp / sstemp < dtest) {
- ksav = k;
- dtest = dstemp * dstemp / sstemp;
- ds = dstemp;
- ss = sstemp;
- }
- }
-/* L50: */
- }
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
-/* L60: */
- s[i__] = xpt[ksav + i__ * xpt_dim1] - xopt[i__];
- }
- }
- ssden = dd * ss - ds * ds;
- iterc = 0;
- densav = zero;
-
-/* Begin the iteration by overwriting S with a vector that has the */
-/* required length and direction. */
-
-L70:
- ++iterc;
- if (ssden < 0) return NLOPT_ROUNDOFF_LIMITED;
- temp = one / sqrt(ssden);
- xoptd = zero;
- xopts = zero;
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
- s[i__] = temp * (dd * s[i__] - ds * d__[i__]);
- xoptd += xopt[i__] * d__[i__];
-/* L80: */
- if (nlopt_isinf(s[i__])) return NLOPT_ROUNDOFF_LIMITED;
- xopts += xopt[i__] * s[i__];
- }
-
-/* Set the coefficients of the first two terms of BETA. */
-
- tempa = half * xoptd * xoptd;
- tempb = half * xopts * xopts;
- den[0] = dd * (xoptsq + half * dd) + tempa + tempb;
- den[1] = two * xoptd * dd;
- den[2] = two * xopts * dd;
- den[3] = tempa - tempb;
- den[4] = xoptd * xopts;
- for (i__ = 6; i__ <= 9; ++i__) {
-/* L90: */
- den[i__ - 1] = zero;
- }
-
-/* Put the coefficients of Wcheck in WVEC. */
-
- i__2 = *npt;
- for (k = 1; k <= i__2; ++k) {
- tempa = zero;
- tempb = zero;
- tempc = zero;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- tempa += xpt[k + i__ * xpt_dim1] * d__[i__];
- tempb += xpt[k + i__ * xpt_dim1] * s[i__];
-/* L100: */
- tempc += xpt[k + i__ * xpt_dim1] * xopt[i__];
- }
- wvec[k + wvec_dim1] = quart * (tempa * tempa + tempb * tempb);
- wvec[k + (wvec_dim1 << 1)] = tempa * tempc;
- wvec[k + wvec_dim1 * 3] = tempb * tempc;
- wvec[k + (wvec_dim1 << 2)] = quart * (tempa * tempa - tempb * tempb);
-/* L110: */
- wvec[k + wvec_dim1 * 5] = half * tempa * tempb;
- }
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
- ip = i__ + *npt;
- wvec[ip + wvec_dim1] = zero;
- wvec[ip + (wvec_dim1 << 1)] = d__[i__];
- wvec[ip + wvec_dim1 * 3] = s[i__];
- wvec[ip + (wvec_dim1 << 2)] = zero;
-/* L120: */
- wvec[ip + wvec_dim1 * 5] = zero;
- }
-
-/* Put the coefficents of THETA*Wcheck in PROD. */
-
- for (jc = 1; jc <= 5; ++jc) {
- nw = *npt;
- if (jc == 2 || jc == 3) {
- nw = *ndim;
- }
- i__2 = *npt;
- for (k = 1; k <= i__2; ++k) {
-/* L130: */
- prod[k + jc * prod_dim1] = zero;
- }
- i__2 = nptm;
- for (j = 1; j <= i__2; ++j) {
- sum = zero;
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
-/* L140: */
- sum += zmat[k + j * zmat_dim1] * wvec[k + jc * wvec_dim1];
- }
- if (j < *idz) {
- sum = -sum;
- }
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
-/* L150: */
- prod[k + jc * prod_dim1] += sum * zmat[k + j * zmat_dim1];
- }
- }
- if (nw == *ndim) {
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
- sum = zero;
- i__2 = *n;
- for (j = 1; j <= i__2; ++j) {
-/* L160: */
- sum += bmat[k + j * bmat_dim1] * wvec[*npt + j + jc *
- wvec_dim1];
- }
-/* L170: */
- prod[k + jc * prod_dim1] += sum;
- }
- }
- i__1 = *n;
- for (j = 1; j <= i__1; ++j) {
- sum = zero;
- i__2 = nw;
- for (i__ = 1; i__ <= i__2; ++i__) {
-/* L180: */
- sum += bmat[i__ + j * bmat_dim1] * wvec[i__ + jc * wvec_dim1];
- }
-/* L190: */
- prod[*npt + j + jc * prod_dim1] = sum;
- }
- }
-
-/* Include in DEN the part of BETA that depends on THETA. */
-
- i__1 = *ndim;
- for (k = 1; k <= i__1; ++k) {
- sum = zero;
- for (i__ = 1; i__ <= 5; ++i__) {
- par[i__ - 1] = half * prod[k + i__ * prod_dim1] * wvec[k + i__ *
- wvec_dim1];
-/* L200: */
- sum += par[i__ - 1];
- }
- den[0] = den[0] - par[0] - sum;
- tempa = prod[k + prod_dim1] * wvec[k + (wvec_dim1 << 1)] + prod[k + (
- prod_dim1 << 1)] * wvec[k + wvec_dim1];
- tempb = prod[k + (prod_dim1 << 1)] * wvec[k + (wvec_dim1 << 2)] +
- prod[k + (prod_dim1 << 2)] * wvec[k + (wvec_dim1 << 1)];
- tempc = prod[k + prod_dim1 * 3] * wvec[k + wvec_dim1 * 5] + prod[k +
- prod_dim1 * 5] * wvec[k + wvec_dim1 * 3];
- den[1] = den[1] - tempa - half * (tempb + tempc);
- den[5] -= half * (tempb - tempc);
- tempa = prod[k + prod_dim1] * wvec[k + wvec_dim1 * 3] + prod[k +
- prod_dim1 * 3] * wvec[k + wvec_dim1];
- tempb = prod[k + (prod_dim1 << 1)] * wvec[k + wvec_dim1 * 5] + prod[k
- + prod_dim1 * 5] * wvec[k + (wvec_dim1 << 1)];
- tempc = prod[k + prod_dim1 * 3] * wvec[k + (wvec_dim1 << 2)] + prod[k
- + (prod_dim1 << 2)] * wvec[k + wvec_dim1 * 3];
- den[2] = den[2] - tempa - half * (tempb - tempc);
- den[6] -= half * (tempb + tempc);
- tempa = prod[k + prod_dim1] * wvec[k + (wvec_dim1 << 2)] + prod[k + (
- prod_dim1 << 2)] * wvec[k + wvec_dim1];
- den[3] = den[3] - tempa - par[1] + par[2];
- tempa = prod[k + prod_dim1] * wvec[k + wvec_dim1 * 5] + prod[k +
- prod_dim1 * 5] * wvec[k + wvec_dim1];
- tempb = prod[k + (prod_dim1 << 1)] * wvec[k + wvec_dim1 * 3] + prod[k
- + prod_dim1 * 3] * wvec[k + (wvec_dim1 << 1)];
- den[4] = den[4] - tempa - half * tempb;
- den[7] = den[7] - par[3] + par[4];
- tempa = prod[k + (prod_dim1 << 2)] * wvec[k + wvec_dim1 * 5] + prod[k
- + prod_dim1 * 5] * wvec[k + (wvec_dim1 << 2)];
-/* L210: */
- den[8] -= half * tempa;
- }
-
-/* Extend DEN so that it holds all the coefficients of DENOM. */
-
- sum = zero;
- for (i__ = 1; i__ <= 5; ++i__) {
-/* Computing 2nd power */
- d__1 = prod[*knew + i__ * prod_dim1];
- par[i__ - 1] = half * (d__1 * d__1);
-/* L220: */
- sum += par[i__ - 1];
- }
- denex[0] = alpha * den[0] + par[0] + sum;
- tempa = two * prod[*knew + prod_dim1] * prod[*knew + (prod_dim1 << 1)];
- tempb = prod[*knew + (prod_dim1 << 1)] * prod[*knew + (prod_dim1 << 2)];
- tempc = prod[*knew + prod_dim1 * 3] * prod[*knew + prod_dim1 * 5];
- denex[1] = alpha * den[1] + tempa + tempb + tempc;
- denex[5] = alpha * den[5] + tempb - tempc;
- tempa = two * prod[*knew + prod_dim1] * prod[*knew + prod_dim1 * 3];
- tempb = prod[*knew + (prod_dim1 << 1)] * prod[*knew + prod_dim1 * 5];
- tempc = prod[*knew + prod_dim1 * 3] * prod[*knew + (prod_dim1 << 2)];
- denex[2] = alpha * den[2] + tempa + tempb - tempc;
- denex[6] = alpha * den[6] + tempb + tempc;
- tempa = two * prod[*knew + prod_dim1] * prod[*knew + (prod_dim1 << 2)];
- denex[3] = alpha * den[3] + tempa + par[1] - par[2];
- tempa = two * prod[*knew + prod_dim1] * prod[*knew + prod_dim1 * 5];
- denex[4] = alpha * den[4] + tempa + prod[*knew + (prod_dim1 << 1)] * prod[
- *knew + prod_dim1 * 3];
- denex[7] = alpha * den[7] + par[3] - par[4];
- denex[8] = alpha * den[8] + prod[*knew + (prod_dim1 << 2)] * prod[*knew +
- prod_dim1 * 5];
-
-/* Seek the value of the angle that maximizes the modulus of DENOM. */
-
- sum = denex[0] + denex[1] + denex[3] + denex[5] + denex[7];
- denold = sum;
- denmax = sum;
- isave = 0;
- iu = 49;
- temp = twopi / (double) (iu + 1);
- par[0] = one;
- i__1 = iu;
- for (i__ = 1; i__ <= i__1; ++i__) {
- angle = (double) i__ * temp;
- par[1] = cos(angle);
- par[2] = sin(angle);
- for (j = 4; j <= 8; j += 2) {
- par[j - 1] = par[1] * par[j - 3] - par[2] * par[j - 2];
-/* L230: */
- par[j] = par[1] * par[j - 2] + par[2] * par[j - 3];
- }
- sumold = sum;
- sum = zero;
- for (j = 1; j <= 9; ++j) {
-/* L240: */
- sum += denex[j - 1] * par[j - 1];
- }
- if (fabs(sum) > fabs(denmax)) {
- denmax = sum;
- isave = i__;
- tempa = sumold;
- } else if (i__ == isave + 1) {
- tempb = sum;
- }
-/* L250: */
- }
- if (isave == 0) {
- tempa = sum;
- }
- if (isave == iu) {
- tempb = denold;
- }
- step = zero;
- if (tempa != tempb) {
- tempa -= denmax;
- tempb -= denmax;
- step = half * (tempa - tempb) / (tempa + tempb);
- }
- angle = temp * ((double) isave + step);
-
-/* Calculate the new parameters of the denominator, the new VLAG vector */
-/* and the new D. Then test for convergence. */
-
- par[1] = cos(angle);
- par[2] = sin(angle);
- for (j = 4; j <= 8; j += 2) {
- par[j - 1] = par[1] * par[j - 3] - par[2] * par[j - 2];
-/* L260: */
- par[j] = par[1] * par[j - 2] + par[2] * par[j - 3];
- }
- *beta = zero;
- denmax = zero;
- for (j = 1; j <= 9; ++j) {
- *beta += den[j - 1] * par[j - 1];
-/* L270: */
- denmax += denex[j - 1] * par[j - 1];
- }
- i__1 = *ndim;
- for (k = 1; k <= i__1; ++k) {
- vlag[k] = zero;
- for (j = 1; j <= 5; ++j) {
-/* L280: */
- vlag[k] += prod[k + j * prod_dim1] * par[j - 1];
- }
- }
- tau = vlag[*knew];
- dd = zero;
- tempa = zero;
- tempb = zero;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- d__[i__] = par[1] * d__[i__] + par[2] * s[i__];
- w[i__] = xopt[i__] + d__[i__];
-/* Computing 2nd power */
- d__1 = d__[i__];
- dd += d__1 * d__1;
- tempa += d__[i__] * w[i__];
-/* L290: */
- tempb += w[i__] * w[i__];
- }
- if (iterc >= *n) {
- goto L340;
- }
- if (iterc > 1) {
- densav = MAX2(densav,denold);
- }
- if (fabs(denmax) <= fabs(densav) * 1.1) {
- goto L340;
- }
- densav = denmax;
-
-/* Set S to half the gradient of the denominator with respect to D. */
-/* Then branch for the next iteration. */
-
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- temp = tempa * xopt[i__] + tempb * d__[i__] - vlag[*npt + i__];
-/* L300: */
- s[i__] = tau * bmat[*knew + i__ * bmat_dim1] + alpha * temp;
- }
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
- sum = zero;
- i__2 = *n;
- for (j = 1; j <= i__2; ++j) {
-/* L310: */
- sum += xpt[k + j * xpt_dim1] * w[j];
- }
- if (nlopt_isinf(tau * w[*n + k]) ||
- nlopt_isinf(alpha * vlag[k])) return NLOPT_ROUNDOFF_LIMITED;
- temp = (tau * w[*n + k] - alpha * vlag[k]) * sum;
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
-/* L320: */
- s[i__] += temp * xpt[k + i__ * xpt_dim1];
- }
- }
- ss = zero;
- ds = zero;
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
-/* Computing 2nd power */
- d__1 = s[i__];
- ss += d__1 * d__1;
-/* L330: */
- ds += d__[i__] * s[i__];
- }
- ssden = dd * ss - ds * ds;
- if (ssden >= dd * 1e-8 * ss) {
- goto L70;
- }
-
-/* Set the vector W before the RETURN from the subroutine. */
-
-L340:
- /* SGJ, 2008: crude hack: truncate d to [lb,ub] bounds if given */
- if (lb && ub) {
- for (k = 1; k <= *n; ++k) {
- if (d__[k] > ub[k-1] - xbase[k-1] - xopt[k])
- d__[k] = ub[k-1] - xbase[k-1] - xopt[k];
- else if (d__[k] < lb[k-1] - xbase[k-1] - xopt[k])
- d__[k] = lb[k-1] - xbase[k-1] - xopt[k];
- }
- }
-
- i__2 = *ndim;
- for (k = 1; k <= i__2; ++k) {
- w[k] = zero;
- for (j = 1; j <= 5; ++j) {
-/* L350: */
- w[k] += wvec[k + j * wvec_dim1] * par[j - 1];
- }
- }
- vlag[*kopt] += one;
- return NLOPT_SUCCESS;
-} /* bigden_ */
-
-/*************************************************************************/
-/* biglag.f */
-
-typedef struct {
- int npt, ndim, iter;
- double *hcol, *xpt, *bmat, *xopt;
- int flipsign;
-} lag_data;
-
-/* the Lagrange function, whose absolute value biglag maximizes */
-static double lag(int n, const double *dx, double *grad, void *data)
-{
- lag_data *d = (lag_data *) data;
- int i, j, npt = d->npt, ndim = d->ndim;
- const double *hcol = d->hcol, *xpt = d->xpt, *bmat = d->bmat, *xopt = d->xopt;
- double val = 0;
- for (j = 0; j < n; ++j) {
- val += bmat[j * ndim] * (xopt[j] + dx[j]);
- if (grad) grad[j] = bmat[j * ndim];
- }
- for (i = 0; i < npt; ++i) {
- double dot = 0;
- for (j = 0; j < n; ++j)
- dot += xpt[i + j * npt] * (xopt[j] + dx[j]);
- val += 0.5 * hcol[i] * (dot * dot);
- dot *= hcol[i];
- if (grad) for (j = 0; j < n; ++j)
- grad[j] += dot * xpt[i + j * npt];
- }
- if (d->flipsign) {
- val = -val;
- if (grad) for (j = 0; j < n; ++j) grad[j] = -grad[j];
- }
- d->iter++;
- return val;
-}
-
-static nlopt_result biglag_(int *n, int *npt, double *xopt,
- double *xpt, double *bmat, double *zmat, int *idz,
- int *ndim, int *knew, double *delta, double *d__,
- double *alpha, double *hcol, double *gc, double *gd,
- double *s, double *w,
- const double *xbase, const double *lb, const double *ub)
-{
- /* System generated locals */
- int xpt_dim1, xpt_offset, bmat_dim1, bmat_offset, zmat_dim1,
- zmat_offset, i__1, i__2;
- double d__1;
-
- /* Local variables */
- int i__, j, k;
- double dd, gg;
- int iu;
- double sp, ss, cf1, cf2, cf3, cf4, cf5, dhd, cth, one, tau, sth, sum,
- half, temp, step;
- int nptm;
- double zero, angle, scale, denom;
- int iterc, isave;
- double delsq, tempa, tempb, twopi, taubeg, tauold, taumax;
-
-
-/* N is the number of variables. */
-/* NPT is the number of interpolation equations. */
-/* XOPT is the best interpolation point so far. */
-/* XPT contains the coordinates of the current interpolation points. */
-/* BMAT provides the last N columns of H. */
-/* ZMAT and IDZ give a factorization of the first NPT by NPT submatrix of H. */
-/* NDIM is the first dimension of BMAT and has the value NPT+N. */
-/* KNEW is the index of the interpolation point that is going to be moved. */
-/* DELTA is the current trust region bound. */
-/* D will be set to the step from XOPT to the new point. */
-/* ALPHA will be set to the KNEW-th diagonal element of the H matrix. */
-/* HCOL, GC, GD, S and W will be used for working space. */
-
-/* The step D is calculated in a way that attempts to maximize the modulus */
-/* of LFUNC(XOPT+D), subject to the bound ||D|| .LE. DELTA, where LFUNC is */
-/* the KNEW-th Lagrange function. */
-
-/* Set some constants. */
-
- /* Parameter adjustments */
- zmat_dim1 = *npt;
- zmat_offset = 1 + zmat_dim1;
- zmat -= zmat_offset;
- xpt_dim1 = *npt;
- xpt_offset = 1 + xpt_dim1;
- xpt -= xpt_offset;
- --xopt;
- bmat_dim1 = *ndim;
- bmat_offset = 1 + bmat_dim1;
- bmat -= bmat_offset;
- --d__;
- --hcol;
- --gc;
- --gd;
- --s;
- --w;
-
- /* Function Body */
- half = .5;
- one = 1.;
- zero = 0.;
- twopi = atan(one) * 8.;
- delsq = *delta * *delta;
- nptm = *npt - *n - 1;
-
-/* Set the first NPT components of HCOL to the leading elements of the */
-/* KNEW-th column of H. */
-
- iterc = 0;
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
-/* L10: */
- hcol[k] = zero;
- }
- i__1 = nptm;
- for (j = 1; j <= i__1; ++j) {
- temp = zmat[*knew + j * zmat_dim1];
- if (j < *idz) {
- temp = -temp;
- }
- i__2 = *npt;
- for (k = 1; k <= i__2; ++k) {
-/* L20: */
- hcol[k] += temp * zmat[k + j * zmat_dim1];
- if (nlopt_isinf(hcol[k])) return NLOPT_ROUNDOFF_LIMITED;
- }
- }
- *alpha = hcol[*knew];
-
-/* Set the unscaled initial direction D. Form the gradient of LFUNC at */
-/* XOPT, and multiply D by the second derivative matrix of LFUNC. */
-
- dd = zero;
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
- d__[i__] = xpt[*knew + i__ * xpt_dim1] - xopt[i__];
- gc[i__] = bmat[*knew + i__ * bmat_dim1];
- gd[i__] = zero;
-/* L30: */
-/* Computing 2nd power */
- d__1 = d__[i__];
- dd += d__1 * d__1;
- }
- i__2 = *npt;
- for (k = 1; k <= i__2; ++k) {
- temp = zero;
- sum = zero;
- i__1 = *n;
- for (j = 1; j <= i__1; ++j) {
- temp += xpt[k + j * xpt_dim1] * xopt[j];
-/* L40: */
- sum += xpt[k + j * xpt_dim1] * d__[j];
- }
- temp = hcol[k] * temp;
- sum = hcol[k] * sum;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- gc[i__] += temp * xpt[k + i__ * xpt_dim1];
-/* L50: */
- gd[i__] += sum * xpt[k + i__ * xpt_dim1];
- }
- }
-
-/* Scale D and GD, with a sign change if required. Set S to another */
-/* vector in the initial two dimensional subspace. */
-
- gg = zero;
- sp = zero;
- dhd = zero;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
-/* Computing 2nd power */
- d__1 = gc[i__];
- gg += d__1 * d__1;
- sp += d__[i__] * gc[i__];
-/* L60: */
- dhd += d__[i__] * gd[i__];
- }
- scale = *delta / sqrt(dd);
- if (sp * dhd < zero) {
- scale = -scale;
- }
- temp = zero;
- if (sp * sp > dd * .99 * gg) {
- temp = one;
- }
- tau = scale * (fabs(sp) + half * scale * fabs(dhd));
- if (gg * delsq < tau * .01 * tau) {
- temp = one;
- }
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- d__[i__] = scale * d__[i__];
- gd[i__] = scale * gd[i__];
-/* L70: */
- s[i__] = gc[i__] + temp * gd[i__];
- }
-
- if (lb && ub) {
- double minf, *dlb, *dub, *xtol;
- lag_data ld;
- ld.npt = *npt;
- ld.ndim = *ndim;
- ld.iter = 0;
- ld.hcol = &hcol[1];
- ld.xpt = &xpt[1 + 1 * xpt_dim1];
- ld.bmat = &bmat[*knew + 1 * bmat_dim1];
- ld.xopt = &xopt[1];
- ld.flipsign = 0;
- dlb = &gc[1]; dub = &gd[1]; xtol = &s[1];
- /* make sure rounding errors don't push initial |d| > delta */
- for (j = 1; j <= *n; ++j) d__[j] *= 0.99999;
- for (j = 0; j < *n; ++j) {
- dlb[j] = -(dub[j] = *delta);
- if (dlb[j] < lb[j] - xbase[j] - xopt[j+1])
- dlb[j] = lb[j] - xbase[j] - xopt[j+1];
- if (dub[j] > ub[j] - xbase[j] - xopt[j+1])
- dub[j] = ub[j] - xbase[j] - xopt[j+1];
- if (dlb[j] > 0) dlb[j] = 0;
- if (dub[j] < 0) dub[j] = 0;
- if (d__[j+1] < dlb[j]) d__[j+1] = dlb[j];
- else if (d__[j+1] > dub[j]) d__[j+1] = dub[j];
- xtol[j] = 1e-5 * *delta;
- }
- ld.flipsign = lag(*n, &d__[1], 0, &ld) > 0; /* maximize if > 0 */
- return nlopt_minimize_constrained(NLOPT_LD_MMA, *n, lag, &ld,
- 1, rho_constraint, delta, sizeof(double),
- dlb, dub, &d__[1], &minf, -HUGE_VAL,
- 0., 0., 0., xtol, 1000, 0.);
- }
-
-/* Begin the iteration by overwriting S with a vector that has the */
-/* required length and direction, except that termination occurs if */
-/* the given D and S are nearly parallel. */
-
-L80:
- ++iterc;
- dd = zero;
- sp = zero;
- ss = zero;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
-/* Computing 2nd power */
- d__1 = d__[i__];
- dd += d__1 * d__1;
- sp += d__[i__] * s[i__];
-/* L90: */
-/* Computing 2nd power */
- d__1 = s[i__];
- ss += d__1 * d__1;
- }
- temp = dd * ss - sp * sp;
- if (temp <= dd * 1e-8 * ss) {
- goto L160;
- }
- denom = sqrt(temp);
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- s[i__] = (dd * s[i__] - sp * d__[i__]) / denom;
-/* L100: */
- w[i__] = zero;
- }
-
-/* Calculate the coefficients of the objective function on the circle, */
-/* beginning with the multiplication of S by the second derivative matrix. */
-
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
- sum = zero;
- i__2 = *n;
- for (j = 1; j <= i__2; ++j) {
-/* L110: */
- sum += xpt[k + j * xpt_dim1] * s[j];
- }
- sum = hcol[k] * sum;
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
-/* L120: */
- w[i__] += sum * xpt[k + i__ * xpt_dim1];
- }
- }
- cf1 = zero;
- cf2 = zero;
- cf3 = zero;
- cf4 = zero;
- cf5 = zero;
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
- cf1 += s[i__] * w[i__];
- cf2 += d__[i__] * gc[i__];
- cf3 += s[i__] * gc[i__];
- cf4 += d__[i__] * gd[i__];
-/* L130: */
- cf5 += s[i__] * gd[i__];
- }
- cf1 = half * cf1;
- cf4 = half * cf4 - cf1;
-
-/* Seek the value of the angle that maximizes the modulus of TAU. */
-
- taubeg = cf1 + cf2 + cf4;
- taumax = taubeg;
- tauold = taubeg;
- isave = 0;
- iu = 49;
- temp = twopi / (double) (iu + 1);
- i__2 = iu;
- for (i__ = 1; i__ <= i__2; ++i__) {
- angle = (double) i__ * temp;
- cth = cos(angle);
- sth = sin(angle);
- tau = cf1 + (cf2 + cf4 * cth) * cth + (cf3 + cf5 * cth) * sth;
- if (fabs(tau) > fabs(taumax)) {
- taumax = tau;
- isave = i__;
- tempa = tauold;
- } else if (i__ == isave + 1) {
- tempb = tau;
- }
-/* L140: */
- tauold = tau;
- }
- if (isave == 0) {
- tempa = tau;
- }
- if (isave == iu) {
- tempb = taubeg;
- }
- step = zero;
- if (tempa != tempb) {
- tempa -= taumax;
- tempb -= taumax;
- step = half * (tempa - tempb) / (tempa + tempb);
- }
- angle = temp * ((double) isave + step);
-
-/* Calculate the new D and GD. Then test for convergence. */
-
- cth = cos(angle);
- sth = sin(angle);
- tau = cf1 + (cf2 + cf4 * cth) * cth + (cf3 + cf5 * cth) * sth;
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
- d__[i__] = cth * d__[i__] + sth * s[i__];
- gd[i__] = cth * gd[i__] + sth * w[i__];
-/* L150: */
- s[i__] = gc[i__] + gd[i__];
- }
- if (fabs(tau) <= fabs(taubeg) * 1.1) {
- goto L160;
- }
- if (iterc < *n) {
- goto L80;
- }
-L160:
- return NLOPT_SUCCESS;
-} /* biglag_ */
-
-
-
-/*************************************************************************/
-/* update.f */
-
-static void update_(int *n, int *npt, double *bmat,
- double *zmat, int *idz, int *ndim, double *vlag,
- double *beta, int *knew, double *w)
-{
- /* System generated locals */
- int bmat_dim1, bmat_offset, zmat_dim1, zmat_offset, i__1, i__2;
- double d__1, d__2;
-
- /* Local variables */
- int i__, j, ja, jb, jl, jp;
- double one, tau, temp;
- int nptm;
- double zero;
- int iflag;
- double scala, scalb_, alpha, denom, tempa, tempb, tausq;
-
-
-/* The arrays BMAT and ZMAT with IDZ are updated, in order to shift the */
-/* interpolation point that has index KNEW. On entry, VLAG contains the */
-/* components of the vector Theta*Wcheck+e_b of the updating formula */
-/* (6.11), and BETA holds the value of the parameter that has this name. */
-/* The vector W is used for working space. */
-
-/* Set some constants. */
-
- /* Parameter adjustments */
- zmat_dim1 = *npt;
- zmat_offset = 1 + zmat_dim1;
- zmat -= zmat_offset;
- bmat_dim1 = *ndim;
- bmat_offset = 1 + bmat_dim1;
- bmat -= bmat_offset;
- --vlag;
- --w;
-
- /* Function Body */
- one = 1.;
- zero = 0.;
- nptm = *npt - *n - 1;
-
-/* Apply the rotations that put zeros in the KNEW-th row of ZMAT. */
-
- jl = 1;
- i__1 = nptm;
- for (j = 2; j <= i__1; ++j) {
- if (j == *idz) {
- jl = *idz;
- } else if (zmat[*knew + j * zmat_dim1] != zero) {
-/* Computing 2nd power */
- d__1 = zmat[*knew + jl * zmat_dim1];
-/* Computing 2nd power */
- d__2 = zmat[*knew + j * zmat_dim1];
- temp = sqrt(d__1 * d__1 + d__2 * d__2);
- tempa = zmat[*knew + jl * zmat_dim1] / temp;
- tempb = zmat[*knew + j * zmat_dim1] / temp;
- i__2 = *npt;
- for (i__ = 1; i__ <= i__2; ++i__) {
- temp = tempa * zmat[i__ + jl * zmat_dim1] + tempb * zmat[i__
- + j * zmat_dim1];
- zmat[i__ + j * zmat_dim1] = tempa * zmat[i__ + j * zmat_dim1]
- - tempb * zmat[i__ + jl * zmat_dim1];
-/* L10: */
- zmat[i__ + jl * zmat_dim1] = temp;
- }
- zmat[*knew + j * zmat_dim1] = zero;
- }
-/* L20: */
- }
-
-/* Put the first NPT components of the KNEW-th column of HLAG into W, */
-/* and calculate the parameters of the updating formula. */
-
- tempa = zmat[*knew + zmat_dim1];
- if (*idz >= 2) {
- tempa = -tempa;
- }
- if (jl > 1) {
- tempb = zmat[*knew + jl * zmat_dim1];
- }
- i__1 = *npt;
- for (i__ = 1; i__ <= i__1; ++i__) {
- w[i__] = tempa * zmat[i__ + zmat_dim1];
- if (jl > 1) {
- w[i__] += tempb * zmat[i__ + jl * zmat_dim1];
- }
-/* L30: */
- }
- alpha = w[*knew];
- tau = vlag[*knew];
- tausq = tau * tau;
- denom = alpha * *beta + tausq;
- vlag[*knew] -= one;
-
-/* Complete the updating of ZMAT when there is only one nonzero element */
-/* in the KNEW-th row of the new matrix ZMAT, but, if IFLAG is set to one, */
-/* then the first column of ZMAT will be exchanged with another one later. */
-
- iflag = 0;
- if (jl == 1) {
- temp = sqrt((fabs(denom)));
- tempb = tempa / temp;
- tempa = tau / temp;
- i__1 = *npt;
- for (i__ = 1; i__ <= i__1; ++i__) {
-/* L40: */
- zmat[i__ + zmat_dim1] = tempa * zmat[i__ + zmat_dim1] - tempb *
- vlag[i__];
- }
- if (*idz == 1 && temp < zero) {
- *idz = 2;
- }
- if (*idz >= 2 && temp >= zero) {
- iflag = 1;
- }
- } else {
-
-/* Complete the updating of ZMAT in the alternative case. */
-
- ja = 1;
- if (*beta >= zero) {
- ja = jl;
- }
- jb = jl + 1 - ja;
- temp = zmat[*knew + jb * zmat_dim1] / denom;
- tempa = temp * *beta;
- tempb = temp * tau;
- temp = zmat[*knew + ja * zmat_dim1];
- scala = one / sqrt(fabs(*beta) * temp * temp + tausq);
- scalb_ = scala * sqrt((fabs(denom)));
- i__1 = *npt;
- for (i__ = 1; i__ <= i__1; ++i__) {
- zmat[i__ + ja * zmat_dim1] = scala * (tau * zmat[i__ + ja *
- zmat_dim1] - temp * vlag[i__]);
-/* L50: */
- zmat[i__ + jb * zmat_dim1] = scalb_ * (zmat[i__ + jb * zmat_dim1]
- - tempa * w[i__] - tempb * vlag[i__]);
- }
- if (denom <= zero) {
- if (*beta < zero) {
- ++(*idz);
- }
- if (*beta >= zero) {
- iflag = 1;
- }
- }
- }
-
-/* IDZ is reduced in the following case, and usually the first column */
-/* of ZMAT is exchanged with a later one. */
-
- if (iflag == 1) {
- --(*idz);
- i__1 = *npt;
- for (i__ = 1; i__ <= i__1; ++i__) {
- temp = zmat[i__ + zmat_dim1];
- zmat[i__ + zmat_dim1] = zmat[i__ + *idz * zmat_dim1];
-/* L60: */
- zmat[i__ + *idz * zmat_dim1] = temp;
- }
- }
-
-/* Finally, update the matrix BMAT. */
-
- i__1 = *n;
- for (j = 1; j <= i__1; ++j) {
- jp = *npt + j;
- w[jp] = bmat[*knew + j * bmat_dim1];
- tempa = (alpha * vlag[jp] - tau * w[jp]) / denom;
- tempb = (-(*beta) * w[jp] - tau * vlag[jp]) / denom;
- i__2 = jp;
- for (i__ = 1; i__ <= i__2; ++i__) {
- bmat[i__ + j * bmat_dim1] = bmat[i__ + j * bmat_dim1] + tempa *
- vlag[i__] + tempb * w[i__];
- if (i__ > *npt) {
- bmat[jp + (i__ - *npt) * bmat_dim1] = bmat[i__ + j *
- bmat_dim1];
- }
-/* L70: */
- }
- }
- return;
-} /* update_ */
-
-
-/*************************************************************************/
-/* newuob.f */
-
-static nlopt_result newuob_(int *n, int *npt, double *x,
- double *rhobeg,
- const double *lb, const double *ub,
- nlopt_stopping *stop, double *minf,
- newuoa_func calfun, void *calfun_data,
- double *xbase, double *xopt, double *xnew,
- double *xpt, double *fval, double *gq, double *hq,
- double *pq, double *bmat, double *zmat, int *ndim,
- double *d__, double *vlag, double *w)
-{
- /* System generated locals */
- int xpt_dim1, xpt_offset, bmat_dim1, bmat_offset, zmat_dim1,
- zmat_offset, i__1, i__2, i__3;
- double d__1, d__2, d__3;
-
- /* Local variables */
- double f;
- int i__, j, k, ih, nf, nh, ip, jp;
- double dx;
- int np, nfm;
- double one;
- int idz;
- double dsq, rho;
- int ipt, jpt;
- double sum, fbeg, diff, half, beta;
- int nfmm;
- double gisq;
- int knew;
- double temp, suma, sumb, fopt = HUGE_VAL, bsum, gqsq;
- int kopt, nptm;
- double zero, xipt, xjpt, sumz, diffa, diffb, diffc, hdiag, alpha,
- delta, recip, reciq, fsave;
- int ksave, nfsav, itemp;
- double dnorm, ratio, dstep, tenth, vquad;
- int ktemp;
- double tempq;
- int itest;
- double rhosq;
- double detrat, crvmin;
- double distsq;
- double xoptsq;
- double rhoend;
- nlopt_result rc = NLOPT_SUCCESS, rc2;
-
-/* SGJ, 2008: compute rhoend from NLopt stop info */
- rhoend = stop->xtol_rel * (*rhobeg);
- for (j = 0; j < *n; ++j)
- if (rhoend < stop->xtol_abs[j])
- rhoend = stop->xtol_abs[j];
-
-/* The arguments N, NPT, X, RHOBEG, RHOEND, IPRINT and MAXFUN are identical */
-/* to the corresponding arguments in SUBROUTINE NEWUOA. */
-/* XBASE will hold a shift of origin that should reduce the contributions */
-/* from rounding errors to values of the model and Lagrange functions. */
-/* XOPT will be set to the displacement from XBASE of the vector of */
-/* variables that provides the least calculated F so far. */
-/* XNEW will be set to the displacement from XBASE of the vector of */
-/* variables for the current calculation of F. */
-/* XPT will contain the interpolation point coordinates relative to XBASE. */
-/* FVAL will hold the values of F at the interpolation points. */
-/* GQ will hold the gradient of the quadratic model at XBASE. */
-/* HQ will hold the explicit second derivatives of the quadratic model. */
-/* PQ will contain the parameters of the implicit second derivatives of */
-/* the quadratic model. */
-/* BMAT will hold the last N columns of H. */
-/* ZMAT will hold the factorization of the leading NPT by NPT submatrix of */
-/* H, this factorization being ZMAT times Diag(DZ) times ZMAT^T, where */
-/* the elements of DZ are plus or minus one, as specified by IDZ. */
-/* NDIM is the first dimension of BMAT and has the value NPT+N. */
-/* D is reserved for trial steps from XOPT. */
-/* VLAG will contain the values of the Lagrange functions at a new point X. */
-/* They are part of a product that requires VLAG to be of length NDIM. */
-/* The array W will be used for working space. Its length must be at least */
-/* 10*NDIM = 10*(NPT+N). */
-
-/* Set some constants. */
-
- /* Parameter adjustments */
- zmat_dim1 = *npt;
- zmat_offset = 1 + zmat_dim1;
- zmat -= zmat_offset;
- xpt_dim1 = *npt;
- xpt_offset = 1 + xpt_dim1;
- xpt -= xpt_offset;
- --x;
- --xbase;
- --xopt;
- --xnew;
- --fval;
- --gq;
- --hq;
- --pq;
- bmat_dim1 = *ndim;
- bmat_offset = 1 + bmat_dim1;
- bmat -= bmat_offset;
- --d__;
- --vlag;
- --w;
-
- /* Function Body */
- half = .5;
- one = 1.;
- tenth = .1;
- zero = 0.;
- np = *n + 1;
- nh = *n * np / 2;
- nptm = *npt - np;
-
-/* Set the initial elements of XPT, BMAT, HQ, PQ and ZMAT to zero. */
-
- i__1 = *n;
- for (j = 1; j <= i__1; ++j) {
- xbase[j] = x[j];
- i__2 = *npt;
- for (k = 1; k <= i__2; ++k) {
-/* L10: */
- xpt[k + j * xpt_dim1] = zero;
- }
- i__2 = *ndim;
- for (i__ = 1; i__ <= i__2; ++i__) {
-/* L20: */
- bmat[i__ + j * bmat_dim1] = zero;
- }
- }
- i__2 = nh;
- for (ih = 1; ih <= i__2; ++ih) {
-/* L30: */
- hq[ih] = zero;
- }
- i__2 = *npt;
- for (k = 1; k <= i__2; ++k) {
- pq[k] = zero;
- i__1 = nptm;
- for (j = 1; j <= i__1; ++j) {
-/* L40: */
- zmat[k + j * zmat_dim1] = zero;
- }
- }
-
-/* Begin the initialization procedure. NF becomes one more than the number */
-/* of function values so far. The coordinates of the displacement of the */
-/* next initial interpolation point from XBASE are set in XPT(NF,.). */
-
- rhosq = *rhobeg * *rhobeg;
- recip = one / rhosq;
- reciq = sqrt(half) / rhosq;
- nf = 0;
-L50:
- nfm = nf;
- nfmm = nf - *n;
- ++nf;
- if (nfm <= *n << 1) {
- if (nfm >= 1 && nfm <= *n) {
- xpt[nf + nfm * xpt_dim1] = *rhobeg;
- } else if (nfm > *n) {
- xpt[nf + nfmm * xpt_dim1] = -(*rhobeg);
- }
- } else {
- itemp = (nfmm - 1) / *n;
- jpt = nfm - itemp * *n - *n;
- ipt = jpt + itemp;
- if (ipt > *n) {
- itemp = jpt;
- jpt = ipt - *n;
- ipt = itemp;
- }
- xipt = *rhobeg;
- if (fval[ipt + np] < fval[ipt + 1]) {
- xipt = -xipt;
- }
- xjpt = *rhobeg;
- if (fval[jpt + np] < fval[jpt + 1]) {
- xjpt = -xjpt;
- }
- xpt[nf + ipt * xpt_dim1] = xipt;
- xpt[nf + jpt * xpt_dim1] = xjpt;
- }
-
-/* Calculate the next value of F, label 70 being reached immediately */
-/* after this calculation. The least function value so far and its index */
-/* are required. */
-
- i__1 = *n;
- for (j = 1; j <= i__1; ++j) {
-/* L60: */
- x[j] = xpt[nf + j * xpt_dim1] + xbase[j];
- }
- if (lb && ub) { /* SGJ, 2008: make sure we are within bounds */
- for (j = 1; j <= i__1; ++j) {
- if (x[j] < lb[j-1]) x[j] = lb[j-1];
- else if (x[j] > ub[j-1]) x[j] = ub[j-1];
- }
- }
- goto L310;
-L70:
- fval[nf] = f;
- if (nf == 1) {
- fbeg = f;
- fopt = f;
- kopt = 1;
- } else if (f < fopt) {
- fopt = f;
- kopt = nf;
- }
-
-/* Set the nonzero initial elements of BMAT and the quadratic model in */
-/* the cases when NF is at most 2*N+1. */
-
- if (nfm <= *n << 1) {
- if (nfm >= 1 && nfm <= *n) {
- gq[nfm] = (f - fbeg) / *rhobeg;
- if (*npt < nf + *n) {
- bmat[nfm * bmat_dim1 + 1] = -one / *rhobeg;
- bmat[nf + nfm * bmat_dim1] = one / *rhobeg;
- bmat[*npt + nfm + nfm * bmat_dim1] = -half * rhosq;
- }
- } else if (nfm > *n) {
- bmat[nf - *n + nfmm * bmat_dim1] = half / *rhobeg;
- bmat[nf + nfmm * bmat_dim1] = -half / *rhobeg;
- zmat[nfmm * zmat_dim1 + 1] = -reciq - reciq;
- zmat[nf - *n + nfmm * zmat_dim1] = reciq;
- zmat[nf + nfmm * zmat_dim1] = reciq;
- ih = nfmm * (nfmm + 1) / 2;
- temp = (fbeg - f) / *rhobeg;
- hq[ih] = (gq[nfmm] - temp) / *rhobeg;
- gq[nfmm] = half * (gq[nfmm] + temp);
- }
-
-/* Set the off-diagonal second derivatives of the Lagrange functions and */
-/* the initial quadratic model. */
-
- } else {
- ih = ipt * (ipt - 1) / 2 + jpt;
- if (xipt < zero) {
- ipt += *n;
- }
- if (xjpt < zero) {
- jpt += *n;
- }
- zmat[nfmm * zmat_dim1 + 1] = recip;
- zmat[nf + nfmm * zmat_dim1] = recip;
- zmat[ipt + 1 + nfmm * zmat_dim1] = -recip;
- zmat[jpt + 1 + nfmm * zmat_dim1] = -recip;
- hq[ih] = (fbeg - fval[ipt + 1] - fval[jpt + 1] + f) / (xipt * xjpt);
- }
- if (nf < *npt) {
- goto L50;
- }
-
-/* Begin the iterative procedure, because the initial model is complete. */
-
- rho = *rhobeg;
- delta = rho;
- idz = 1;
- diffa = zero;
- diffb = zero;
- itest = 0;
- xoptsq = zero;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- xopt[i__] = xpt[kopt + i__ * xpt_dim1];
-/* L80: */
-/* Computing 2nd power */
- d__1 = xopt[i__];
- xoptsq += d__1 * d__1;
- }
-L90:
- nfsav = nf;
-
-/* Generate the next trust region step and test its length. Set KNEW */
-/* to -1 if the purpose of the next F will be to improve the model. */
-
-L100:
- knew = 0;
- rc2 = trsapp_(n, npt, &xopt[1], &xpt[xpt_offset], &gq[1], &hq[1], &pq[1], &
- delta, &d__[1], &w[1], &w[np], &w[np + *n], &w[np + (*n << 1)], &
- crvmin, &xbase[1], lb, ub);
- if (rc2 < 0) { rc = rc2; goto L530; }
- dsq = zero;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
-/* L110: */
-/* Computing 2nd power */
- d__1 = d__[i__];
- dsq += d__1 * d__1;
- }
-/* Computing MIN */
- d__1 = delta, d__2 = sqrt(dsq);
- dnorm = MIN2(d__1,d__2);
- if (dnorm < half * rho) {
- knew = -1;
- delta = tenth * delta;
- ratio = -1.;
- if (delta <= rho * 1.5) {
- delta = rho;
- }
- if (nf <= nfsav + 2) {
- goto L460;
- }
- temp = crvmin * .125 * rho * rho;
-/* Computing MAX */
- d__1 = MAX2(diffa,diffb);
- if (temp <= MAX2(d__1,diffc)) {
- goto L460;
- }
- goto L490;
- }
-
-/* Shift XBASE if XOPT may be too far from XBASE. First make the changes */
-/* to BMAT that do not depend on ZMAT. */
-
-L120:
- if (dsq <= xoptsq * .001) {
- tempq = xoptsq * .25;
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
- sum = zero;
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
-/* L130: */
- sum += xpt[k + i__ * xpt_dim1] * xopt[i__];
- }
- temp = pq[k] * sum;
- sum -= half * xoptsq;
- w[*npt + k] = sum;
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
- gq[i__] += temp * xpt[k + i__ * xpt_dim1];
- xpt[k + i__ * xpt_dim1] -= half * xopt[i__];
- vlag[i__] = bmat[k + i__ * bmat_dim1];
- w[i__] = sum * xpt[k + i__ * xpt_dim1] + tempq * xopt[i__];
- ip = *npt + i__;
- i__3 = i__;
- for (j = 1; j <= i__3; ++j) {
-/* L140: */
- bmat[ip + j * bmat_dim1] = bmat[ip + j * bmat_dim1] +
- vlag[i__] * w[j] + w[i__] * vlag[j];
- }
- }
- }
-
-/* Then the revisions of BMAT that depend on ZMAT are calculated. */
-
- i__3 = nptm;
- for (k = 1; k <= i__3; ++k) {
- sumz = zero;
- i__2 = *npt;
- for (i__ = 1; i__ <= i__2; ++i__) {
- sumz += zmat[i__ + k * zmat_dim1];
-/* L150: */
- w[i__] = w[*npt + i__] * zmat[i__ + k * zmat_dim1];
- }
- i__2 = *n;
- for (j = 1; j <= i__2; ++j) {
- sum = tempq * sumz * xopt[j];
- i__1 = *npt;
- for (i__ = 1; i__ <= i__1; ++i__) {
-/* L160: */
- sum += w[i__] * xpt[i__ + j * xpt_dim1];
- }
- vlag[j] = sum;
- if (k < idz) {
- sum = -sum;
- }
- i__1 = *npt;
- for (i__ = 1; i__ <= i__1; ++i__) {
-/* L170: */
- bmat[i__ + j * bmat_dim1] += sum * zmat[i__ + k *
- zmat_dim1];
- }
- }
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- ip = i__ + *npt;
- temp = vlag[i__];
- if (k < idz) {
- temp = -temp;
- }
- i__2 = i__;
- for (j = 1; j <= i__2; ++j) {
-/* L180: */
- bmat[ip + j * bmat_dim1] += temp * vlag[j];
- }
- }
- }
-
-/* The following instructions complete the shift of XBASE, including */
-/* the changes to the parameters of the quadratic model. */
-
- ih = 0;
- i__2 = *n;
- for (j = 1; j <= i__2; ++j) {
- w[j] = zero;
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
- w[j] += pq[k] * xpt[k + j * xpt_dim1];
-/* L190: */
- xpt[k + j * xpt_dim1] -= half * xopt[j];
- }
- i__1 = j;
- for (i__ = 1; i__ <= i__1; ++i__) {
- ++ih;
- if (i__ < j) {
- gq[j] += hq[ih] * xopt[i__];
- }
- gq[i__] += hq[ih] * xopt[j];
- hq[ih] = hq[ih] + w[i__] * xopt[j] + xopt[i__] * w[j];
-/* L200: */
- bmat[*npt + i__ + j * bmat_dim1] = bmat[*npt + j + i__ *
- bmat_dim1];
- }
- }
- i__1 = *n;
- for (j = 1; j <= i__1; ++j) {
- xbase[j] += xopt[j];
-/* L210: */
- xopt[j] = zero;
- }
- xoptsq = zero;
- }
-
-/* Pick the model step if KNEW is positive. A different choice of D */
-/* may be made later, if the choice of D by BIGLAG causes substantial */
-/* cancellation in DENOM. */
-
- if (knew > 0) {
- rc2 =
- biglag_(n, npt, &xopt[1], &xpt[xpt_offset], &bmat[bmat_offset], &zmat[
- zmat_offset], &idz, ndim, &knew, &dstep, &d__[1], &alpha, &
- vlag[1], &vlag[*npt + 1], &w[1], &w[np], &w[np + *n],
- &xbase[1], lb, ub);
- if (rc2 < 0) { rc = rc2; goto L530; }
- }
-
-/* Calculate VLAG and BETA for the current choice of D. The first NPT */
-/* components of W_check will be held in W. */
-
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
- suma = zero;
- sumb = zero;
- sum = zero;
- i__2 = *n;
- for (j = 1; j <= i__2; ++j) {
- suma += xpt[k + j * xpt_dim1] * d__[j];
- sumb += xpt[k + j * xpt_dim1] * xopt[j];
-/* L220: */
- sum += bmat[k + j * bmat_dim1] * d__[j];
- }
- w[k] = suma * (half * suma + sumb);
-/* L230: */
- vlag[k] = sum;
- }
- beta = zero;
- i__1 = nptm;
- for (k = 1; k <= i__1; ++k) {
- sum = zero;
- i__2 = *npt;
- for (i__ = 1; i__ <= i__2; ++i__) {
-/* L240: */
- sum += zmat[i__ + k * zmat_dim1] * w[i__];
- }
- if (k < idz) {
- beta += sum * sum;
- sum = -sum;
- } else {
- beta -= sum * sum;
- }
- i__2 = *npt;
- for (i__ = 1; i__ <= i__2; ++i__) {
-/* L250: */
- vlag[i__] += sum * zmat[i__ + k * zmat_dim1];
- }
- }
- bsum = zero;
- dx = zero;
- i__2 = *n;
- for (j = 1; j <= i__2; ++j) {
- sum = zero;
- i__1 = *npt;
- for (i__ = 1; i__ <= i__1; ++i__) {
-/* L260: */
- sum += w[i__] * bmat[i__ + j * bmat_dim1];
- }
- bsum += sum * d__[j];
- jp = *npt + j;
- i__1 = *n;
- for (k = 1; k <= i__1; ++k) {
-/* L270: */
- sum += bmat[jp + k * bmat_dim1] * d__[k];
- }
- vlag[jp] = sum;
- bsum += sum * d__[j];
-/* L280: */
- dx += d__[j] * xopt[j];
- }
- beta = dx * dx + dsq * (xoptsq + dx + dx + half * dsq) + beta - bsum;
- vlag[kopt] += one;
-
-/* If KNEW is positive and if the cancellation in DENOM is unacceptable, */
-/* then BIGDEN calculates an alternative model step, XNEW being used for */
-/* working space. */
-
- if (knew > 0) {
-/* Computing 2nd power */
- d__1 = vlag[knew];
- if (d__1 == 0) { rc = NLOPT_ROUNDOFF_LIMITED; goto L530; }
- temp = one + alpha * beta / (d__1 * d__1);
- if (fabs(temp) <= .8) {
- rc2 =
- bigden_(n, npt, &xopt[1], &xpt[xpt_offset], &bmat[bmat_offset], &
- zmat[zmat_offset], &idz, ndim, &kopt, &knew, &d__[1], &w[
- 1], &vlag[1], &beta, &xnew[1], &w[*ndim + 1], &w[*ndim *
- 6 + 1], &xbase[1], lb, ub);
- if (rc2 < 0) { rc = rc2; goto L530; }
- }
- }
-
-/* Calculate the next value of the objective function. */
-
-L290:
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
- xnew[i__] = xopt[i__] + d__[i__];
-/* L300: */
- x[i__] = xbase[i__] + xnew[i__];
- }
- if (lb && ub) { /* SGJ, 2008: make sure we are within bounds,
- since roundoff errors can push us slightly outside */
- for (j = 1; j <= i__1; ++j) {
- if (x[j] < lb[j-1]) x[j] = lb[j-1];
- else if (x[j] > ub[j-1]) x[j] = ub[j-1];
- }
- }
- ++nf;
-L310:
- if (nlopt_stop_forced(stop)) rc = NLOPT_FORCED_STOP;
- else if (stop->nevals > 0) {
- if (nlopt_stop_evals(stop)) rc = NLOPT_MAXEVAL_REACHED;
- else if (nlopt_stop_time(stop)) rc = NLOPT_MAXTIME_REACHED;
- }
- if (rc != NLOPT_SUCCESS) goto L530;
-
- stop->nevals++;
- f = calfun(*n, &x[1], calfun_data);
- if (f < stop->minf_max) {
- rc = NLOPT_MINF_MAX_REACHED;
- goto L530;
- }
-
- if (nf <= *npt) {
- goto L70;
- }
- if (knew == -1) {
- goto L530;
- }
-
-/* Use the quadratic model to predict the change in F due to the step D, */
-/* and set DIFF to the error of this prediction. */
-
- vquad = zero;
- ih = 0;
- i__2 = *n;
- for (j = 1; j <= i__2; ++j) {
- vquad += d__[j] * gq[j];
- i__1 = j;
- for (i__ = 1; i__ <= i__1; ++i__) {
- ++ih;
- temp = d__[i__] * xnew[j] + d__[j] * xopt[i__];
- if (i__ == j) {
- temp = half * temp;
- }
-/* L340: */
- vquad += temp * hq[ih];
- }
- }
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
-/* L350: */
- vquad += pq[k] * w[k];
- }
- diff = f - fopt - vquad;
- diffc = diffb;
- diffb = diffa;
- diffa = fabs(diff);
- if (dnorm > rho) {
- nfsav = nf;
- }
-
-/* Update FOPT and XOPT if the new F is the least value of the objective */
-/* function so far. The branch when KNEW is positive occurs if D is not */
-/* a trust region step. */
-
- fsave = fopt;
- if (f < fopt) {
- fopt = f;
- xoptsq = zero;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- xopt[i__] = xnew[i__];
-/* L360: */
-/* Computing 2nd power */
- d__1 = xopt[i__];
- xoptsq += d__1 * d__1;
- }
- if (nlopt_stop_ftol(stop, fopt, fsave)) {
- rc = NLOPT_FTOL_REACHED;
- goto L530;
- }
-
- }
- ksave = knew;
- if (knew > 0) {
- goto L410;
- }
-
-/* Pick the next value of DELTA after a trust region step. */
-
- if (vquad >= zero) {
- goto L530;
- }
- ratio = (f - fsave) / vquad;
- if (ratio <= tenth) {
- delta = half * dnorm;
- } else if (ratio <= .7) {
-/* Computing MAX */
- d__1 = half * delta;
- delta = MAX2(d__1,dnorm);
- } else {
-/* Computing MAX */
- d__1 = half * delta, d__2 = dnorm + dnorm;
- delta = MAX2(d__1,d__2);
- }
- if (delta <= rho * 1.5) {
- delta = rho;
- }
-
-/* Set KNEW to the index of the next interpolation point to be deleted. */
-
-/* Computing MAX */
- d__2 = tenth * delta;
-/* Computing 2nd power */
- d__1 = MAX2(d__2,rho);
- rhosq = d__1 * d__1;
- ktemp = 0;
- detrat = zero;
- if (f >= fsave) {
- ktemp = kopt;
- detrat = one;
- }
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
- hdiag = zero;
- i__2 = nptm;
- for (j = 1; j <= i__2; ++j) {
- temp = one;
- if (j < idz) {
- temp = -one;
- }
-/* L380: */
-/* Computing 2nd power */
- d__1 = zmat[k + j * zmat_dim1];
- hdiag += temp * (d__1 * d__1);
- }
-/* Computing 2nd power */
- d__2 = vlag[k];
- temp = (d__1 = beta * hdiag + d__2 * d__2, fabs(d__1));
- distsq = zero;
- i__2 = *n;
- for (j = 1; j <= i__2; ++j) {
-/* L390: */
-/* Computing 2nd power */
- d__1 = xpt[k + j * xpt_dim1] - xopt[j];
- distsq += d__1 * d__1;
- }
- if (distsq > rhosq) {
-/* Computing 3rd power */
- d__1 = distsq / rhosq;
- temp *= d__1 * (d__1 * d__1);
- }
- if (temp > detrat && k != ktemp) {
- detrat = temp;
- knew = k;
- }
-/* L400: */
- }
- if (knew == 0) {
- goto L460;
- }
-
-/* Update BMAT, ZMAT and IDZ, so that the KNEW-th interpolation point */
-/* can be moved. Begin the updating of the quadratic model, starting */
-/* with the explicit second derivative term. */
-
-L410:
- update_(n, npt, &bmat[bmat_offset], &zmat[zmat_offset], &idz, ndim, &vlag[
- 1], &beta, &knew, &w[1]);
- fval[knew] = f;
- ih = 0;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- temp = pq[knew] * xpt[knew + i__ * xpt_dim1];
- i__2 = i__;
- for (j = 1; j <= i__2; ++j) {
- ++ih;
-/* L420: */
- hq[ih] += temp * xpt[knew + j * xpt_dim1];
- }
- }
- pq[knew] = zero;
-
-/* Update the other second derivative parameters, and then the gradient */
-/* vector of the model. Also include the new interpolation point. */
-
- i__2 = nptm;
- for (j = 1; j <= i__2; ++j) {
- temp = diff * zmat[knew + j * zmat_dim1];
- if (j < idz) {
- temp = -temp;
- }
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
-/* L440: */
- pq[k] += temp * zmat[k + j * zmat_dim1];
- }
- }
- gqsq = zero;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- gq[i__] += diff * bmat[knew + i__ * bmat_dim1];
-/* Computing 2nd power */
- d__1 = gq[i__];
- gqsq += d__1 * d__1;
-/* L450: */
- xpt[knew + i__ * xpt_dim1] = xnew[i__];
- }
-
-/* If a trust region step makes a small change to the objective function, */
-/* then calculate the gradient of the least Frobenius norm interpolant at */
-/* XBASE, and store it in W, using VLAG for a vector of right hand sides. */
-
- if (ksave == 0 && delta == rho) {
- if (fabs(ratio) > .01) {
- itest = 0;
- } else {
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
-/* L700: */
- vlag[k] = fval[k] - fval[kopt];
- }
- gisq = zero;
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- sum = zero;
- i__2 = *npt;
- for (k = 1; k <= i__2; ++k) {
-/* L710: */
- sum += bmat[k + i__ * bmat_dim1] * vlag[k];
- }
- gisq += sum * sum;
-/* L720: */
- w[i__] = sum;
- }
-
-/* Test whether to replace the new quadratic model by the least Frobenius */
-/* norm interpolant, making the replacement if the test is satisfied. */
-
- ++itest;
- if (gqsq < gisq * 100.) {
- itest = 0;
- }
- if (itest >= 3) {
- i__1 = *n;
- for (i__ = 1; i__ <= i__1; ++i__) {
-/* L730: */
- gq[i__] = w[i__];
- }
- i__1 = nh;
- for (ih = 1; ih <= i__1; ++ih) {
-/* L740: */
- hq[ih] = zero;
- }
- i__1 = nptm;
- for (j = 1; j <= i__1; ++j) {
- w[j] = zero;
- i__2 = *npt;
- for (k = 1; k <= i__2; ++k) {
-/* L750: */
- w[j] += vlag[k] * zmat[k + j * zmat_dim1];
- }
-/* L760: */
- if (j < idz) {
- w[j] = -w[j];
- }
- }
- i__1 = *npt;
- for (k = 1; k <= i__1; ++k) {
- pq[k] = zero;
- i__2 = nptm;
- for (j = 1; j <= i__2; ++j) {
-/* L770: */
- pq[k] += zmat[k + j * zmat_dim1] * w[j];
- }
- }
- itest = 0;
- }
- }
- }
- if (f < fsave) {
- kopt = knew;
- }
-
-/* If a trust region step has provided a sufficient decrease in F, then */
-/* branch for another trust region calculation. The case KSAVE>0 occurs */
-/* when the new function value was calculated by a model step. */
-
- if (f <= fsave + tenth * vquad) {
- goto L100;
- }
- if (ksave > 0) {
- goto L100;
- }
-
-/* Alternatively, find out if the interpolation points are close enough */
-/* to the best point so far. */
-
- knew = 0;
-L460:
- distsq = delta * 4. * delta;
- i__2 = *npt;
- for (k = 1; k <= i__2; ++k) {
- sum = zero;
- i__1 = *n;
- for (j = 1; j <= i__1; ++j) {
-/* L470: */
-/* Computing 2nd power */
- d__1 = xpt[k + j * xpt_dim1] - xopt[j];
- sum += d__1 * d__1;
- }
- if (sum > distsq) {
- knew = k;
- distsq = sum;
- }
-/* L480: */
- }
-
-/* If KNEW is positive, then set DSTEP, and branch back for the next */
-/* iteration, which will generate a "model step". */
-
- if (knew > 0) {
-/* Computing MAX */
-/* Computing MIN */
- d__2 = tenth * sqrt(distsq), d__3 = half * delta;
- d__1 = MIN2(d__2,d__3);
- dstep = MAX2(d__1,rho);
- dsq = dstep * dstep;
- goto L120;
- }
- if (ratio > zero) {
- goto L100;
- }
- if (MAX2(delta,dnorm) > rho) {
- goto L100;
- }
-
-/* The calculations with the current value of RHO are complete. Pick the */
-/* next values of RHO and DELTA. */
-
-L490:
- if (rho > rhoend) {
- delta = half * rho;
- ratio = rho / rhoend;
- if (ratio <= 16.) {
- rho = rhoend;
- } else if (ratio <= 250.) {
- rho = sqrt(ratio) * rhoend;
- } else {
- rho = tenth * rho;
- }
- delta = MAX2(delta,rho);
- goto L90;
- }
-
-/* Return from the calculation, after another Newton-Raphson step, if */
-/* it is too short to have been tried before. */
-
- if (knew == -1) {
- goto L290;
- }
- rc = NLOPT_XTOL_REACHED;
-L530:
- if (fopt <= f) {
- i__2 = *n;
- for (i__ = 1; i__ <= i__2; ++i__) {
-/* L540: */
- x[i__] = xbase[i__] + xopt[i__];
- }
- f = fopt;
- }
- *minf = f;
- return rc;
-} /* newuob_ */
-
-/*************************************************************************/
-/* newuoa.f */
-
-nlopt_result newuoa(int n, int npt, double *x,
- const double *lb, const double *ub,
- double rhobeg, nlopt_stopping *stop, double *minf,
- newuoa_func calfun, void *calfun_data)
-{
- /* Local variables */
- int id, np, iw, igq, ihq, ixb, ifv, ipq, ivl, ixn, ixo, ixp, ndim,
- nptm, ibmat, izmat;
- nlopt_result ret;
- double *w;
-
-/* This subroutine seeks the least value of a function of many variables, */
-/* by a trust region method that forms quadratic models by interpolation. */
-/* There can be some freedom in the interpolation conditions, which is */
-/* taken up by minimizing the Frobenius norm of the change to the second */
-/* derivative of the quadratic model, beginning with a zero matrix. The */
-/* arguments of the subroutine are as follows. */
-
-/* N must be set to the number of variables and must be at least two. */
-/* NPT is the number of interpolation conditions. Its value must be in the */
-/* interval [N+2,(N+1)(N+2)/2]. */
-/* Initial values of the variables must be set in X(1),X(2),...,X(N). They */
-/* will be changed to the values that give the least calculated F. */
-/* RHOBEG and RHOEND must be set to the initial and final values of a trust */
-/* region radius, so both must be positive with RHOEND<=RHOBEG. Typically */
-/* RHOBEG should be about one tenth of the greatest expected change to a */
-/* variable, and RHOEND should indicate the accuracy that is required in */
-/* the final values of the variables. */
-/* The value of IPRINT should be set to 0, 1, 2 or 3, which controls the */
-/* amount of printing. Specifically, there is no output if IPRINT=0 and */
-/* there is output only at the return if IPRINT=1. Otherwise, each new */
-/* value of RHO is printed, with the best vector of variables so far and */
-/* the corresponding value of the objective function. Further, each new */
-/* value of F with its variables are output if IPRINT=3. */
-/* MAXFUN must be set to an upper bound on the number of calls of CALFUN. */
-/* The array W will be used for working space. Its length must be at least */
-/* (NPT+13)*(NPT+N)+3*N*(N+3)/2. */
-
-/* SUBROUTINE CALFUN (N,X,F) must be provided by the user. It must set F to */
-/* the value of the objective function for the variables X(1),X(2),...,X(N). */
-
-/* Partition the working space array, so that different parts of it can be */
-/* treated separately by the subroutine that performs the main calculation. */
-
- /* Parameter adjustments */
- --x;
-
- /* Function Body */
- np = n + 1;
- nptm = npt - np;
- if (n < 2 || npt < n + 2 || npt > (n + 2) * np / 2) {
- return NLOPT_INVALID_ARGS;
- }
- ndim = npt + n;
- ixb = 1;
- ixo = ixb + n;
- ixn = ixo + n;
- ixp = ixn + n;
- ifv = ixp + n * npt;
- igq = ifv + npt;
- ihq = igq + n;
- ipq = ihq + n * np / 2;
- ibmat = ipq + npt;
- izmat = ibmat + ndim * n;
- id = izmat + npt * nptm;
- ivl = id + n;
- iw = ivl + ndim;
-
- w = (double *) malloc(sizeof(double) * ((npt+13)*(npt+n) + 3*(n*(n+3))/2));
- if (!w) return NLOPT_OUT_OF_MEMORY;
- --w;
-
-/* The above settings provide a partition of W for subroutine NEWUOB. */
-/* The partition requires the first NPT*(NPT+N)+5*N*(N+3)/2 elements of */
-/* W plus the space that is needed by the last array of NEWUOB. */
-
- ret = newuob_(&n, &npt, &x[1], &rhobeg,
- lb, ub, stop, minf, calfun, calfun_data,
- &w[ixb], &w[ixo], &w[ixn], &w[ixp], &w[ifv],
- &w[igq], &w[ihq], &w[ipq], &w[ibmat], &w[izmat],
- &ndim, &w[id], &w[ivl], &w[iw]);
-
- ++w;
- free(w);
- return ret;
-} /* newuoa_ */
-
-/*************************************************************************/
-/*************************************************************************/
diff --git a/ext/src/nlopt/praxis/README b/ext/src/nlopt/praxis/README
deleted file mode 100644
index c51dd42..0000000
--- a/ext/src/nlopt/praxis/README
+++ /dev/null
@@ -1,15 +0,0 @@
-praxis gradient-free local optimization via the "principal-axis method",
-downloaded from Netlib:
-
- http://netlib.org/opt/praxis
-
-The original Fortran code was written by Richard Brent and made
-available by the Stanford Linear Accelerator Center, dated 3/1/73.
-Since this code contains no copyright statements and is dated prior to
-1977, under US copyright law it is in the public domain (not copyrighted).
-
-Converted to C via f2c and cleaned up by Steven G. Johnson
-(stevenj at alum.mit.edu). C version is licensed under the MIT license
-(which is in the same spirit as public domain, but disclaims warranty
-and is clearer legally).
-
diff --git a/ext/src/nlopt/praxis/praxis.c b/ext/src/nlopt/praxis/praxis.c
deleted file mode 100644
index bea8e0b..0000000
--- a/ext/src/nlopt/praxis/praxis.c
+++ /dev/null
@@ -1,1366 +0,0 @@
-/* See README */
-
-#include <stdlib.h>
-#include <math.h>
-#include <string.h>
-#include "nlopt/nlopt-util.h"
-#include "nlopt/praxis.h"
-
-/* Common Block Declarations */
-
-struct global_s {
- double fx, ldt, dmin__;
- int nf, nl;
-};
-
-struct q_s {
- double *v; /* size n x n */
- double *q0, *q1, *t_flin; /* size n */
- double qa, qb, qc, qd0, qd1, qf1;
-
- double fbest, *xbest; /* size n */
- nlopt_stopping *stop;
-};
-
-/* Table of constant values */
-
-static int pow_ii(int x, int n) /* compute x^n, n >= 0 */
-{
- int p = 1;
- while (n > 0) {
- if (n & 1) { n--; p *= x; }
- else { n >>= 1; x *= x; }
- }
- return p;
-}
-
-static void minfit_(int m, int n, double machep,
- double *tol, double *ab, double *q, double *ework);
-static nlopt_result min_(int n, int j, int nits, double *d2, double *x1, double *f1, int fk, praxis_func f, void *f_data, double *x, double *t_old, double machep, double *h__, struct global_s *global_1, struct q_s *q_1);
-static double flin_(int n, int j, double *l, praxis_func f, void *f_data, double *x, int *nf, struct q_s *q_1, nlopt_result *ret);
-static void sort_(int m, int n, double *d__, double *v);
-static void quad_(int n, praxis_func f, void *f_data, double *x,
- double *t_old, double machep, double *h__, struct global_s *global_1, struct q_s *q_1);
-
-nlopt_result praxis_(double t0, double machep, double h0,
- int n, double *x, praxis_func f, void *f_data,
- nlopt_stopping *stop, double *minf)
-{
- /* System generated locals */
- int i__1, i__2, i__3;
- nlopt_result ret = NLOPT_SUCCESS;
- double d__1;
-
- /* Global */
- struct global_s global_1;
- struct q_s q_1;
-
- /* Local variables */
- double *d__, *y, *z__, *e_minfit, *prev_xbest; /* size n */
- double prev_fbest;
- double h__;
- int i__, j, k;
- double s, t_old, f1;
- int k2;
- double m2, m4, t2_old, df, dn;
- int kl, ii;
- double sf;
- int kt;
- double sl;
- int im1, km1;
- double dni, lds;
- int ktm;
- double scbd;
- int illc;
- int klmk;
- double ldfac, large, small, value;
- double vlarge;
- double vsmall;
- double *work;
-
-/* LAST MODIFIED 3/1/73 */
-/* Modified August 2007 by S. G. Johnson:
- after conversion to C via f2c and some manual cleanup,
- eliminating write statements, I additionally:
- - modified the routine to use NLopt stop criteria
- - allocate arrays dynamically to allow n > 20
- - return the NLopt return code, where the min.
- function value is now given by the parameter minf
-*/
-/* PRAXIS RETURNS THE MINIMUM OF THE FUNCTION F(N,X) OF N VARIABLES */
-/* USING THE PRINCIPAL AXIS METHOD. THE GRADIENT OF THE FUNCTION IS */
-/* NOT REQUIRED. */
-
-/* FOR A DESCRIPTION OF THE ALGORITHM, SEE CHAPTER SEVEN OF */
-/* "ALGORITHMS FOR FINDING ZEROS AND EXTREMA OF FUNCTIONS WITHOUT */
-/* CALCULATING DERIVATIVES" BY RICHARD P BRENT. */
-
-/* THE PARAMETERS ARE: */
-/* T0 IS A TOLERANCE. PRAXIS ATTEMPTS TO RETURN PRAXIS=F(X) */
-/* SUCH THAT IF X0 IS THE TRUE LOCAL MINIMUM NEAR X, THEN */
-/* NORM(X-X0) < T0 + SQUAREROOT(MACHEP)*NORM(X). */
-/* MACHEP IS THE MACHINE PRECISION, THE SMALLEST NUMBER SUCH THAT */
-/* 1 + MACHEP > 1. MACHEP SHOULD BE 16.**-13 (ABOUT */
-/* 2.22D-16) FOR REAL*8 ARITHMETIC ON THE IBM 360. */
-/* H0 IS THE MAXIMUM STEP SIZE. H0 SHOULD BE SET TO ABOUT THE */
-/* MAXIMUM DISTANCE FROM THE INITIAL GUESS TO THE MINIMUM. */
-/* (IF H0 IS SET TOO LARGE OR TOO SMALL, THE INITIAL RATE OF */
-/* CONVERGENCE MAY BE SLOW.) */
-/* N (AT LEAST TWO) IS THE NUMBER OF VARIABLES UPON WHICH */
-/* THE FUNCTION DEPENDS. */
-/* X IS AN ARRAY CONTAINING ON ENTRY A GUESS OF THE POINT OF */
-/* MINIMUM, ON RETURN THE ESTIMATED POINT OF MINIMUM. */
-/* F(N,X) IS THE FUNCTION TO BE MINIMIZED. F SHOULD BE A REAL*8 */
-/* FUNCTION DECLARED EXTERNAL IN THE CALLING PROGRAM. */
-/* THE APPROXIMATING QUADRATIC FORM IS */
-/* Q(X') = F(N,X) + (1/2) * (X'-X)-TRANSPOSE * A * (X'-X) */
-/* WHERE X IS THE BEST ESTIMATE OF THE MINIMUM AND A IS */
-/* INVERSE(V-TRANSPOSE) * D * INVERSE(V) */
-/* (V(*,*) IS THE MATRIX OF SEARCH DIRECTIONS; D(*) IS THE ARRAY */
-/* OF SECOND DIFFERENCES). IF F HAS CONTINUOUS SECOND DERIVATIVES */
-/* NEAR X0, A WILL TEND TO THE HESSIAN OF F AT X0 AS X APPROACHES X0. */
-
-/* IT IS ASSUMED THAT ON FLOATING-POINT UNDERFLOW THE RESULT IS SET */
-/* TO ZERO. */
-/* THE USER SHOULD OBSERVE THE COMMENT ON HEURISTIC NUMBERS AFTER */
-/* THE INITIALIZATION OF MACHINE DEPENDENT NUMBERS. */
-
-
-/* .....IF N>20 OR IF N<20 AND YOU NEED MORE SPACE, CHANGE '20' TO THE */
-/* LARGEST VALUE OF N IN THE NEXT CARD, IN THE CARD 'IDIM=20', AND */
-/* IN THE DIMENSION STATEMENTS IN SUBROUTINES MINFIT,MIN,FLIN,QUAD. */
- /* ...changed by S. G. Johnson, 2007, to use malloc */
-
-/* .....INITIALIZATION..... */
-/* MACHINE DEPENDENT NUMBERS: */
-
- /* Parameter adjustments */
- --x;
-
- /* Function Body */
- small = machep * machep;
- vsmall = small * small;
- large = 1. / small;
- vlarge = 1. / vsmall;
- m2 = sqrt(machep);
- m4 = sqrt(m2);
-
- /* new: dynamic allocation of temporary arrays */
- work = (double *) malloc(sizeof(double) * (n*n + n*9));
- if (!work) return NLOPT_OUT_OF_MEMORY;
- q_1.v = work;
- q_1.q0 = q_1.v + n*n;
- q_1.q1 = q_1.q0 + n;
- q_1.t_flin = q_1.q1 + n;
- q_1.xbest = q_1.t_flin + n;
- d__ = q_1.xbest + n;
- y = d__ + n;
- z__ = y + n;
- e_minfit = y + n;
- prev_xbest = e_minfit + n;
-
-/* HEURISTIC NUMBERS: */
-/* IF THE AXES MAY BE BADLY SCALED (WHICH IS TO BE AVOIDED IF */
-/* POSSIBLE), THEN SET SCBD=10. OTHERWISE SET SCBD=1. */
-/* IF THE PROBLEM IS KNOWN TO BE ILL-CONDITIONED, SET ILLC=TRUE. */
-/* OTHERWISE SET ILLC=FALSE. */
-/* KTM IS THE NUMBER OF ITERATIONS WITHOUT IMPROVEMENT BEFORE THE */
-/* ALGORITHM TERMINATES. KTM=4 IS VERY CAUTIOUS; USUALLY KTM=1 */
-/* IS SATISFACTORY. */
-
- scbd = 1.;
- illc = 0 /* false */;
- ktm = 1;
-
- ldfac = .01;
- if (illc) {
- ldfac = .1;
- }
- kt = 0;
- global_1.nl = 0;
- global_1.nf = 1;
- prev_fbest = q_1.fbest = global_1.fx = f(n, &x[1], f_data);
- memcpy(q_1.xbest, &x[1], n*sizeof(double));
- memcpy(prev_xbest, &x[1], n*sizeof(double));
- stop->nevals++;
- q_1.stop = stop;
- q_1.qf1 = global_1.fx;
- if (t0 > 0)
- t_old = small + t0;
- else {
- t_old = 0;
- for (i__ = 0; i__ < n; ++i__)
- if (stop->xtol_abs[i__] > t_old)
- t_old = stop->xtol_abs[i__];
- t_old += small;
- }
- t2_old = t_old;
- global_1.dmin__ = small;
- h__ = h0;
- if (h__ < t_old * 100) {
- h__ = t_old * 100;
- }
- global_1.ldt = h__;
-/* .....THE FIRST SET OF SEARCH DIRECTIONS V IS THE IDENTITY MATRIX..... */
- i__1 = n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- i__2 = n;
- for (j = 1; j <= i__2; ++j) {
-/* L10: */
- q_1.v[i__ + j * n - (n+1)] = 0.;
- }
-/* L20: */
- q_1.v[i__ + i__ * n - (n+1)] = 1.;
- }
- d__[0] = 0.;
- q_1.qd0 = 0.;
- i__1 = n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- q_1.q0[i__ - 1] = x[i__];
-/* L30: */
- q_1.q1[i__ - 1] = x[i__];
- }
-
-/* .....THE MAIN LOOP STARTS HERE..... */
-L40:
- sf = d__[0];
- d__[0] = 0.;
- s = 0.;
-
-/* .....MINIMIZE ALONG THE FIRST DIRECTION V(*,1). */
-/* FX MUST BE PASSED TO MIN BY VALUE. */
- value = global_1.fx;
- ret = min_(n, 1, 2, d__, &s, &value, 0, f,f_data, &x[1],
- &t_old, machep, &h__, &global_1, &q_1);
- if (ret != NLOPT_SUCCESS) goto done;
- if (s > 0.) {
- goto L50;
- }
- i__1 = n;
- for (i__ = 1; i__ <= i__1; ++i__) {
-/* L45: */
- q_1.v[i__ - 1] = -q_1.v[i__ - 1];
- }
-L50:
- if (sf > d__[0] * .9 && sf * .9 < d__[0]) {
- goto L70;
- }
- i__1 = n;
- for (i__ = 2; i__ <= i__1; ++i__) {
-/* L60: */
- d__[i__ - 1] = 0.;
- }
-
-/* .....THE INNER LOOP STARTS HERE..... */
-L70:
- i__1 = n;
- for (k = 2; k <= i__1; ++k) {
- i__2 = n;
- for (i__ = 1; i__ <= i__2; ++i__) {
-/* L75: */
- y[i__ - 1] = x[i__];
- }
- sf = global_1.fx;
- if (kt > 0) {
- illc = 1 /* true */;
- }
-L80:
- kl = k;
- df = 0.;
-
-/* .....A RANDOM STEP FOLLOWS (TO AVOID RESOLUTION VALLEYS). */
-/* PRAXIS ASSUMES THAT RANDOM RETURNS A RANDOM NUMBER UNIFORMLY */
-/* DISTRIBUTED IN (0,1). */
-
- if (! illc) {
- goto L95;
- }
- i__2 = n;
- for (i__ = 1; i__ <= i__2; ++i__) {
- s = (global_1.ldt * .1 + t2_old * pow_ii(10, kt))
- * nlopt_urand(-.5,.5);
- /* was: (random_(n) - .5); */
- z__[i__ - 1] = s;
- i__3 = n;
- for (j = 1; j <= i__3; ++j) {
-/* L85: */
- x[j] += s * q_1.v[j + i__ * n - (n+1)];
- }
-/* L90: */
- }
- global_1.fx = (*f)(n, &x[1], f_data);
- ++global_1.nf;
-
-/* .....MINIMIZE ALONG THE "NON-CONJUGATE" DIRECTIONS V(*,K),...,V(*,N) */
-
-L95:
- i__2 = n;
- for (k2 = k; k2 <= i__2; ++k2) {
- sl = global_1.fx;
- s = 0.;
- value = global_1.fx;
- ret = min_(n, k2, 2, &d__[k2 - 1], &s, &value, 0, f,f_data, &
- x[1], &t_old, machep, &h__, &global_1, &q_1);
- if (ret != NLOPT_SUCCESS) goto done;
- if (illc) {
- goto L97;
- }
- s = sl - global_1.fx;
- goto L99;
-L97:
-/* Computing 2nd power */
- d__1 = s + z__[k2 - 1];
- s = d__[k2 - 1] * (d__1 * d__1);
-L99:
- if (df > s) {
- goto L105;
- }
- df = s;
- kl = k2;
-L105:
- ;
- }
- if (illc || df >= (d__1 = machep * 100 * global_1.fx, fabs(d__1))) {
- goto L110;
- }
-
-/* .....IF THERE WAS NOT MUCH IMPROVEMENT ON THE FIRST TRY, SET */
-/* ILLC=TRUE AND START THE INNER LOOP AGAIN..... */
-
- illc = 1 /* true */;
- goto L80;
-L110:
-
-/* .....MINIMIZE ALONG THE "CONJUGATE" DIRECTIONS V(*,1),...,V(*,K-1) */
-
- km1 = k - 1;
- i__2 = km1;
- for (k2 = 1; k2 <= i__2; ++k2) {
- s = 0.;
- value = global_1.fx;
- ret = min_(n, k2, 2, &d__[k2 - 1], &s, &value, 0, f,f_data, &
- x[1], &t_old, machep, &h__, &global_1, &q_1);
- if (ret != NLOPT_SUCCESS) goto done;
-/* L120: */
- }
- f1 = global_1.fx;
- global_1.fx = sf;
- lds = 0.;
- i__2 = n;
- for (i__ = 1; i__ <= i__2; ++i__) {
- sl = x[i__];
- x[i__] = y[i__ - 1];
- sl -= y[i__ - 1];
- y[i__ - 1] = sl;
-/* L130: */
- lds += sl * sl;
- }
- lds = sqrt(lds);
- if (lds <= small) {
- goto L160;
- }
-
-/* .....DISCARD DIRECTION V(*,KL). */
-/* IF NO RANDOM STEP WAS TAKEN, V(*,KL) IS THE "NON-CONJUGATE" */
-/* DIRECTION ALONG WHICH THE GREATEST IMPROVEMENT WAS MADE..... */
-
- klmk = kl - k;
- if (klmk < 1) {
- goto L141;
- }
- i__2 = klmk;
- for (ii = 1; ii <= i__2; ++ii) {
- i__ = kl - ii;
- i__3 = n;
- for (j = 1; j <= i__3; ++j) {
-/* L135: */
- q_1.v[j + (i__ + 1) * n - (n+1)] = q_1.v[j + i__ * n - (n+1)];
- }
-/* L140: */
- d__[i__] = d__[i__ - 1];
- }
-L141:
- d__[k - 1] = 0.;
- i__2 = n;
- for (i__ = 1; i__ <= i__2; ++i__) {
-/* L145: */
- q_1.v[i__ + k * n - (n+1)] = y[i__ - 1] / lds;
- }
-
-/* .....MINIMIZE ALONG THE NEW "CONJUGATE" DIRECTION V(*,K), WHICH IS */
-/* THE NORMALIZED VECTOR: (NEW X) - (0LD X)..... */
-
- value = f1;
- ret = min_(n, k, 4, &d__[k - 1], &lds, &value, 1, f,f_data, &x[1],
- &t_old, machep, &h__, &global_1, &q_1);
- if (ret != NLOPT_SUCCESS) goto done;
- if (lds > 0.) {
- goto L160;
- }
- lds = -lds;
- i__2 = n;
- for (i__ = 1; i__ <= i__2; ++i__) {
-/* L150: */
- q_1.v[i__ + k * n - (n+1)] = -q_1.v[i__ + k * n - (n+1)];
- }
-L160:
- global_1.ldt = ldfac * global_1.ldt;
- if (global_1.ldt < lds) {
- global_1.ldt = lds;
- }
- t2_old = 0.;
- i__2 = n;
- for (i__ = 1; i__ <= i__2; ++i__) {
-/* L165: */
-/* Computing 2nd power */
- d__1 = x[i__];
- t2_old += d__1 * d__1;
- }
- t2_old = m2 * sqrt(t2_old) + t_old;
-
-/* .....SEE WHETHER THE LENGTH OF THE STEP TAKEN SINCE STARTING THE */
-/* INNER LOOP EXCEEDS HALF THE TOLERANCE..... */
-
- if (global_1.ldt > t2_old * .5f
- && !nlopt_stop_f(stop, q_1.fbest, prev_fbest)
- && !nlopt_stop_x(stop, q_1.xbest, prev_xbest)) {
- kt = -1;
- }
- ++kt;
- if (kt > ktm) {
- if (nlopt_stop_f(stop, q_1.fbest, prev_fbest))
- ret = NLOPT_FTOL_REACHED;
- else if (nlopt_stop_x(stop, q_1.xbest, prev_xbest))
- ret = NLOPT_XTOL_REACHED;
- goto done;
- }
- prev_fbest = q_1.fbest;
- memcpy(prev_xbest, q_1.xbest, n * sizeof(double));
-/* L170: */
- }
-/* .....THE INNER LOOP ENDS HERE. */
-
-/* TRY QUADRATIC EXTRAPOLATION IN CASE WE ARE IN A CURVED VALLEY. */
-
-/* L171: */
- quad_(n, f,f_data, &x[1], &t_old, machep, &h__, &global_1, &q_1);
- dn = 0.;
- i__1 = n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- d__[i__ - 1] = 1. / sqrt(d__[i__ - 1]);
- if (dn < d__[i__ - 1]) {
- dn = d__[i__ - 1];
- }
-/* L175: */
- }
- i__1 = n;
- for (j = 1; j <= i__1; ++j) {
- s = d__[j - 1] / dn;
- i__2 = n;
- for (i__ = 1; i__ <= i__2; ++i__) {
-/* L180: */
- q_1.v[i__ + j * n - (n+1)] = s * q_1.v[i__ + j * n - (n+1)];
- }
- }
-
-/* .....SCALE THE AXES TO TRY TO REDUCE THE CONDITION NUMBER..... */
-
- if (scbd <= 1.) {
- goto L200;
- }
- s = vlarge;
- i__2 = n;
- for (i__ = 1; i__ <= i__2; ++i__) {
- sl = 0.;
- i__1 = n;
- for (j = 1; j <= i__1; ++j) {
-/* L182: */
- sl += q_1.v[i__ + j * n - (n+1)] * q_1.v[i__ + j * n - (n+1)];
- }
- z__[i__ - 1] = sqrt(sl);
- if (z__[i__ - 1] < m4) {
- z__[i__ - 1] = m4;
- }
- if (s > z__[i__ - 1]) {
- s = z__[i__ - 1];
- }
-/* L185: */
- }
- i__2 = n;
- for (i__ = 1; i__ <= i__2; ++i__) {
- sl = s / z__[i__ - 1];
- z__[i__ - 1] = 1. / sl;
- if (z__[i__ - 1] <= scbd) {
- goto L189;
- }
- sl = 1. / scbd;
- z__[i__ - 1] = scbd;
-L189:
- i__1 = n;
- for (j = 1; j <= i__1; ++j) {
-/* L190: */
- q_1.v[i__ + j * n - (n+1)] = sl * q_1.v[i__ + j * n - (n+1)];
- }
-/* L195: */
- }
-
-/* .....CALCULATE A NEW SET OF ORTHOGONAL DIRECTIONS BEFORE REPEATING */
-/* THE MAIN LOOP. */
-/* FIRST TRANSPOSE V FOR MINFIT: */
-
-L200:
- i__2 = n;
- for (i__ = 2; i__ <= i__2; ++i__) {
- im1 = i__ - 1;
- i__1 = im1;
- for (j = 1; j <= i__1; ++j) {
- s = q_1.v[i__ + j * n - (n+1)];
- q_1.v[i__ + j * n - (n+1)] = q_1.v[j + i__ * n - (n+1)];
-/* L210: */
- q_1.v[j + i__ * n - (n+1)] = s;
- }
-/* L220: */
- }
-
-/* .....CALL MINFIT TO FIND THE SINGULAR VALUE DECOMPOSITION OF V. */
-/* THIS GIVES THE PRINCIPAL VALUES AND PRINCIPAL DIRECTIONS OF THE */
-/* APPROXIMATING QUADRATIC FORM WITHOUT SQUARING THE CONDITION */
-/* NUMBER..... */
-
- minfit_(n, n, machep, &vsmall, q_1.v, d__, e_minfit);
-
-/* .....UNSCALE THE AXES..... */
-
- if (scbd <= 1.) {
- goto L250;
- }
- i__2 = n;
- for (i__ = 1; i__ <= i__2; ++i__) {
- s = z__[i__ - 1];
- i__1 = n;
- for (j = 1; j <= i__1; ++j) {
-/* L225: */
- q_1.v[i__ + j * n - (n+1)] = s * q_1.v[i__ + j * n - (n+1)];
- }
-/* L230: */
- }
- i__2 = n;
- for (i__ = 1; i__ <= i__2; ++i__) {
- s = 0.;
- i__1 = n;
- for (j = 1; j <= i__1; ++j) {
-/* L235: */
-/* Computing 2nd power */
- d__1 = q_1.v[j + i__ * n - (n+1)];
- s += d__1 * d__1;
- }
- s = sqrt(s);
- d__[i__ - 1] = s * d__[i__ - 1];
- s = 1 / s;
- i__1 = n;
- for (j = 1; j <= i__1; ++j) {
-/* L240: */
- q_1.v[j + i__ * n - (n+1)] = s * q_1.v[j + i__ * n - (n+1)];
- }
-/* L245: */
- }
-
-L250:
- i__2 = n;
- for (i__ = 1; i__ <= i__2; ++i__) {
- dni = dn * d__[i__ - 1];
- if (dni > large) {
- goto L265;
- }
- if (dni < small) {
- goto L260;
- }
- d__[i__ - 1] = 1 / (dni * dni);
- goto L270;
-L260:
- d__[i__ - 1] = vlarge;
- goto L270;
-L265:
- d__[i__ - 1] = vsmall;
-L270:
- ;
- }
-
-/* .....SORT THE EIGENVALUES AND EIGENVECTORS..... */
-
- sort_(n, n, d__, q_1.v);
- global_1.dmin__ = d__[n - 1];
- if (global_1.dmin__ < small) {
- global_1.dmin__ = small;
- }
- illc = 0 /* false */;
- if (m2 * d__[0] > global_1.dmin__) {
- illc = 1 /* true */;
- }
-
-/* .....THE MAIN LOOP ENDS HERE..... */
-
- goto L40;
-
-/* .....RETURN..... */
-
-done:
- if (ret != NLOPT_OUT_OF_MEMORY) {
- *minf = q_1.fbest;
- memcpy(&x[1], q_1.xbest, n * sizeof(double));
- }
- free(work);
- return ret;
-} /* praxis_ */
-
-static void minfit_(int m, int n, double machep,
- double *tol, double *ab, double *q, double *ework)
-{
- /* System generated locals */
- int ab_dim1, ab_offset, i__1, i__2, i__3;
- double d__1, d__2;
-
- /* Local variables */
- double *e; /* size n */
- double c__, f, g, h__;
- int i__, j, k, l;
- double s, x, y, z__;
- int l2, ii, kk, kt, ll2, lp1;
- double eps, temp;
-
- e = ework;
-
-/* ...AN IMPROVED VERSION OF MINFIT (SEE GOLUB AND REINSCH, 1969) */
-/* RESTRICTED TO M=N,P=0. */
-/* THE SINGULAR VALUES OF THE ARRAY AB ARE RETURNED IN Q AND AB IS */
-/* OVERWRITTEN WITH THE ORTHOGONAL MATRIX V SUCH THAT U.DIAG(Q) = AB.V, */
-/* WHERE U IS ANOTHER ORTHOGONAL MATRIX. */
-/* ...HOUSEHOLDER'S REDUCTION TO BIDIAGONAL FORM... */
- /* Parameter adjustments */
- --q;
- ab_dim1 = m;
- ab_offset = 1 + ab_dim1;
- ab -= ab_offset;
-
- /* Function Body */
- if (n == 1) {
- goto L200;
- }
- eps = machep;
- g = 0.;
- x = 0.;
- i__1 = n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- e[i__ - 1] = g;
- s = 0.;
- l = i__ + 1;
- i__2 = n;
- for (j = i__; j <= i__2; ++j) {
-/* L1: */
-/* Computing 2nd power */
- d__1 = ab[j + i__ * ab_dim1];
- s += d__1 * d__1;
- }
- g = 0.;
- if (s < *tol) {
- goto L4;
- }
- f = ab[i__ + i__ * ab_dim1];
- g = sqrt(s);
- if (f >= 0.) {
- g = -g;
- }
- h__ = f * g - s;
- ab[i__ + i__ * ab_dim1] = f - g;
- if (l > n) {
- goto L4;
- }
- i__2 = n;
- for (j = l; j <= i__2; ++j) {
- f = 0.;
- i__3 = n;
- for (k = i__; k <= i__3; ++k) {
-/* L2: */
- f += ab[k + i__ * ab_dim1] * ab[k + j * ab_dim1];
- }
- f /= h__;
- i__3 = n;
- for (k = i__; k <= i__3; ++k) {
-/* L3: */
- ab[k + j * ab_dim1] += f * ab[k + i__ * ab_dim1];
- }
- }
-L4:
- q[i__] = g;
- s = 0.;
- if (i__ == n) {
- goto L6;
- }
- i__3 = n;
- for (j = l; j <= i__3; ++j) {
-/* L5: */
- s += ab[i__ + j * ab_dim1] * ab[i__ + j * ab_dim1];
- }
-L6:
- g = 0.;
- if (s < *tol) {
- goto L10;
- }
- if (i__ == n) {
- goto L16;
- }
- f = ab[i__ + (i__ + 1) * ab_dim1];
-L16:
- g = sqrt(s);
- if (f >= 0.) {
- g = -g;
- }
- h__ = f * g - s;
- if (i__ == n) {
- goto L10;
- }
- ab[i__ + (i__ + 1) * ab_dim1] = f - g;
- i__3 = n;
- for (j = l; j <= i__3; ++j) {
-/* L7: */
- e[j - 1] = ab[i__ + j * ab_dim1] / h__;
- }
- i__3 = n;
- for (j = l; j <= i__3; ++j) {
- s = 0.;
- i__2 = n;
- for (k = l; k <= i__2; ++k) {
-/* L8: */
- s += ab[j + k * ab_dim1] * ab[i__ + k * ab_dim1];
- }
- i__2 = n;
- for (k = l; k <= i__2; ++k) {
-/* L9: */
- ab[j + k * ab_dim1] += s * e[k - 1];
- }
- }
-L10:
- y = (d__1 = q[i__], fabs(d__1)) + (d__2 = e[i__ - 1], fabs(d__2));
-/* L11: */
- if (y > x) {
- x = y;
- }
- }
-/* ...ACCUMULATION OF RIGHT-HAND TRANSFORMATIONS... */
- ab[n + n * ab_dim1] = 1.;
- g = e[n - 1];
- l = n;
- i__1 = n;
- for (ii = 2; ii <= i__1; ++ii) {
- i__ = n - ii + 1;
- if (g == 0.) {
- goto L23;
- }
- h__ = ab[i__ + (i__ + 1) * ab_dim1] * g;
- i__2 = n;
- for (j = l; j <= i__2; ++j) {
-/* L20: */
- ab[j + i__ * ab_dim1] = ab[i__ + j * ab_dim1] / h__;
- }
- i__2 = n;
- for (j = l; j <= i__2; ++j) {
- s = 0.;
- i__3 = n;
- for (k = l; k <= i__3; ++k) {
-/* L21: */
- s += ab[i__ + k * ab_dim1] * ab[k + j * ab_dim1];
- }
- i__3 = n;
- for (k = l; k <= i__3; ++k) {
-/* L22: */
- ab[k + j * ab_dim1] += s * ab[k + i__ * ab_dim1];
- }
- }
-L23:
- i__3 = n;
- for (j = l; j <= i__3; ++j) {
- ab[i__ + j * ab_dim1] = 0.;
-/* L24: */
- ab[j + i__ * ab_dim1] = 0.;
- }
- ab[i__ + i__ * ab_dim1] = 1.;
- g = e[i__ - 1];
-/* L25: */
- l = i__;
- }
-/* ...DIAGONALIZATION OF THE BIDIAGONAL FORM... */
-/* L100: */
- eps *= x;
- i__1 = n;
- for (kk = 1; kk <= i__1; ++kk) {
- k = n - kk + 1;
- kt = 0;
-L101:
- ++kt;
- if (kt <= 30) {
- goto L102;
- }
- e[k - 1] = 0.;
- /* fprintf(stderr, "QR failed\n"); */
-L102:
- i__3 = k;
- for (ll2 = 1; ll2 <= i__3; ++ll2) {
- l2 = k - ll2 + 1;
- l = l2;
- if ((d__1 = e[l - 1], fabs(d__1)) <= eps) {
- goto L120;
- }
- if (l == 1) {
- goto L103;
- }
- if ((d__1 = q[l - 1], fabs(d__1)) <= eps) {
- goto L110;
- }
-L103:
- ;
- }
-/* ...CANCELLATION OF E(L) IF L>1... */
-L110:
- c__ = 0.;
- s = 1.;
- i__3 = k;
- for (i__ = l; i__ <= i__3; ++i__) {
- f = s * e[i__ - 1];
- e[i__ - 1] = c__ * e[i__ - 1];
- if (fabs(f) <= eps) {
- goto L120;
- }
- g = q[i__];
-/* ...Q(I) = H = DSQRT(G*G + F*F)... */
- if (fabs(f) < fabs(g)) {
- goto L113;
- }
- if (f != 0.) {
- goto L112;
- } else {
- goto L111;
- }
-L111:
- h__ = 0.;
- goto L114;
-L112:
-/* Computing 2nd power */
- d__1 = g / f;
- h__ = fabs(f) * sqrt(d__1 * d__1 + 1);
- goto L114;
-L113:
-/* Computing 2nd power */
- d__1 = f / g;
- h__ = fabs(g) * sqrt(d__1 * d__1 + 1);
-L114:
- q[i__] = h__;
- if (h__ != 0.) {
- goto L115;
- }
- g = 1.;
- h__ = 1.;
-L115:
- c__ = g / h__;
-/* L116: */
- s = -f / h__;
- }
-/* ...TEST FOR CONVERGENCE... */
-L120:
- z__ = q[k];
- if (l == k) {
- goto L140;
- }
-/* ...SHIFT FROM BOTTOM 2*2 MINOR... */
- x = q[l];
- y = q[k - 1];
- g = e[k - 2];
- h__ = e[k - 1];
- f = ((y - z__) * (y + z__) + (g - h__) * (g + h__)) / (h__ * 2 * y);
- g = sqrt(f * f + 1.);
- temp = f - g;
- if (f >= 0.) {
- temp = f + g;
- }
- f = ((x - z__) * (x + z__) + h__ * (y / temp - h__)) / x;
-/* ...NEXT QR TRANSFORMATION... */
- c__ = 1.;
- s = 1.;
- lp1 = l + 1;
- if (lp1 > k) {
- goto L133;
- }
- i__3 = k;
- for (i__ = lp1; i__ <= i__3; ++i__) {
- g = e[i__ - 1];
- y = q[i__];
- h__ = s * g;
- g *= c__;
- if (fabs(f) < fabs(h__)) {
- goto L123;
- }
- if (f != 0.) {
- goto L122;
- } else {
- goto L121;
- }
-L121:
- z__ = 0.;
- goto L124;
-L122:
-/* Computing 2nd power */
- d__1 = h__ / f;
- z__ = fabs(f) * sqrt(d__1 * d__1 + 1);
- goto L124;
-L123:
-/* Computing 2nd power */
- d__1 = f / h__;
- z__ = fabs(h__) * sqrt(d__1 * d__1 + 1);
-L124:
- e[i__ - 2] = z__;
- if (z__ != 0.) {
- goto L125;
- }
- f = 1.;
- z__ = 1.;
-L125:
- c__ = f / z__;
- s = h__ / z__;
- f = x * c__ + g * s;
- g = -x * s + g * c__;
- h__ = y * s;
- y *= c__;
- i__2 = n;
- for (j = 1; j <= i__2; ++j) {
- x = ab[j + (i__ - 1) * ab_dim1];
- z__ = ab[j + i__ * ab_dim1];
- ab[j + (i__ - 1) * ab_dim1] = x * c__ + z__ * s;
-/* L126: */
- ab[j + i__ * ab_dim1] = -x * s + z__ * c__;
- }
- if (fabs(f) < fabs(h__)) {
- goto L129;
- }
- if (f != 0.) {
- goto L128;
- } else {
- goto L127;
- }
-L127:
- z__ = 0.;
- goto L130;
-L128:
-/* Computing 2nd power */
- d__1 = h__ / f;
- z__ = fabs(f) * sqrt(d__1 * d__1 + 1);
- goto L130;
-L129:
-/* Computing 2nd power */
- d__1 = f / h__;
- z__ = fabs(h__) * sqrt(d__1 * d__1 + 1);
-L130:
- q[i__ - 1] = z__;
- if (z__ != 0.) {
- goto L131;
- }
- f = 1.;
- z__ = 1.;
-L131:
- c__ = f / z__;
- s = h__ / z__;
- f = c__ * g + s * y;
-/* L132: */
- x = -s * g + c__ * y;
- }
-L133:
- e[l - 1] = 0.;
- e[k - 1] = f;
- q[k] = x;
- goto L101;
-/* ...CONVERGENCE: Q(K) IS MADE NON-NEGATIVE... */
-L140:
- if (z__ >= 0.) {
- goto L150;
- }
- q[k] = -z__;
- i__3 = n;
- for (j = 1; j <= i__3; ++j) {
-/* L141: */
- ab[j + k * ab_dim1] = -ab[j + k * ab_dim1];
- }
-L150:
- ;
- }
- return;
-L200:
- q[1] = ab[ab_dim1 + 1];
- ab[ab_dim1 + 1] = 1.;
-} /* minfit_ */
-
-static nlopt_result min_(int n, int j, int nits, double *
- d2, double *x1, double *f1, int fk, praxis_func f, void *f_data, double *
- x, double *t_old, double machep, double *h__, struct global_s *global_1, struct q_s *q_1)
-{
- /* System generated locals */
- int i__1;
- double d__1, d__2;
-
- /* Local variables */
- int i__, k;
- double s, d1, f0, f2, m2, m4, t2, x2, fm;
- int dz;
- double xm, sf1, sx1;
- double temp, small;
- nlopt_result ret = NLOPT_SUCCESS;
-
-/* ...THE SUBROUTINE MIN MINIMIZES F FROM X IN THE DIRECTION V(*,J) UNLESS */
-/* J IS LESS THAN 1, WHEN A QUADRATIC SEARCH IS MADE IN THE PLANE */
-/* DEFINED BY Q0,Q1,X. */
-/* D2 IS EITHER ZERO OR AN APPROXIMATION TO HALF F". */
-/* ON ENTRY, X1 IS AN ESTIMATE OF THE DISTANCE FROM X TO THE MINIMUM */
-/* ALONG V(*,J) (OR, IF J=0, A CURVE). ON RETURN, X1 IS THE DISTANCE */
-/* FOUND. */
-/* IF FK=.TRUE., THEN F1 IS FLIN(X1). OTHERWISE X1 AND F1 ARE IGNORED */
-/* ON ENTRY UNLESS FINAL FX IS GREATER THAN F1. */
-/* NITS CONTROLS THE NUMBER OF TIMES AN ATTEMPT WILL BE MADE TO HALVE */
-/* THE INTERVAL. */
- /* Parameter adjustments */
- --x;
-
- /* Function Body */
-/* Computing 2nd power */
- d__1 = machep;
- small = d__1 * d__1;
- m2 = sqrt(machep);
- m4 = sqrt(m2);
- sf1 = *f1;
- sx1 = *x1;
- k = 0;
- xm = 0.;
- fm = global_1->fx;
- f0 = global_1->fx;
- dz = *d2 < machep;
-/* ...FIND THE STEP SIZE... */
- s = 0.;
- i__1 = n;
- for (i__ = 1; i__ <= i__1; ++i__) {
-/* L1: */
-/* Computing 2nd power */
- d__1 = x[i__];
- s += d__1 * d__1;
- }
- s = sqrt(s);
- temp = *d2;
- if (dz) {
- temp = global_1->dmin__;
- }
- t2 = m4 * sqrt(fabs(global_1->fx) / temp + s * global_1->ldt) + m2 *
- global_1->ldt;
- s = m4 * s + *t_old;
- if (dz && t2 > s) {
- t2 = s;
- }
- t2 = t2 > small ? t2 : small;
-/* Computing MIN */
- d__1 = t2, d__2 = *h__ * .01;
- t2 = d__1 < d__2 ? d__1 : d__2;
- if (! (fk) || *f1 > fm) {
- goto L2;
- }
- xm = *x1;
- fm = *f1;
-L2:
- if (fk && fabs(*x1) >= t2) {
- goto L3;
- }
- temp = 1.;
- if (*x1 < 0.) {
- temp = -1.;
- }
- *x1 = temp * t2;
- *f1 = flin_(n, j, x1, f,f_data, &x[1], &global_1->nf, q_1, &ret);
- if (ret != NLOPT_SUCCESS) return ret;
-L3:
- if (*f1 > fm) {
- goto L4;
- }
- xm = *x1;
- fm = *f1;
-L4:
- if (! dz) {
- goto L6;
- }
-/* ...EVALUATE FLIN AT ANOTHER POINT AND ESTIMATE THE SECOND DERIVATIVE... */
- x2 = -(*x1);
- if (f0 >= *f1) {
- x2 = *x1 * 2.;
- }
- f2 = flin_(n, j, &x2, f,f_data, &x[1], &global_1->nf, q_1, &ret);
- if (ret != NLOPT_SUCCESS) return ret;
- if (f2 > fm) {
- goto L5;
- }
- xm = x2;
- fm = f2;
-L5:
- *d2 = (x2 * (*f1 - f0) - *x1 * (f2 - f0)) / (*x1 * x2 * (*x1 - x2));
-/* ...ESTIMATE THE FIRST DERIVATIVE AT 0... */
-L6:
- d1 = (*f1 - f0) / *x1 - *x1 * *d2;
- dz = 1 /* true */;
-/* ...PREDICT THE MINIMUM... */
- if (*d2 > small) {
- goto L7;
- }
- x2 = *h__;
- if (d1 >= 0.) {
- x2 = -x2;
- }
- goto L8;
-L7:
- x2 = d1 * -.5 / *d2;
-L8:
- if (fabs(x2) <= *h__) {
- goto L11;
- }
- if (x2 <= 0.) {
- goto L9;
- } else {
- goto L10;
- }
-L9:
- x2 = -(*h__);
- goto L11;
-L10:
- x2 = *h__;
-/* ...EVALUATE F AT THE PREDICTED MINIMUM... */
-L11:
- f2 = flin_(n, j, &x2, f,f_data, &x[1], &global_1->nf, q_1, &ret);
- if (ret != NLOPT_SUCCESS) return ret;
- if (k >= nits || f2 <= f0) {
- goto L12;
- }
-/* ...NO SUCCESS, SO TRY AGAIN... */
- ++k;
- if (f0 < *f1 && *x1 * x2 > 0.) {
- goto L4;
- }
- x2 *= .5;
- goto L11;
-/* ...INCREMENT THE ONE-DIMENSIONAL SEARCH COUNTER... */
-L12:
- ++global_1->nl;
- if (f2 <= fm) {
- goto L13;
- }
- x2 = xm;
- goto L14;
-L13:
- fm = f2;
-/* ...GET A NEW ESTIMATE OF THE SECOND DERIVATIVE... */
-L14:
- if ((d__1 = x2 * (x2 - *x1), fabs(d__1)) <= small) {
- goto L15;
- }
- *d2 = (x2 * (*f1 - f0) - *x1 * (fm - f0)) / (*x1 * x2 * (*x1 - x2));
- goto L16;
-L15:
- if (k > 0) {
- *d2 = 0.;
- }
-L16:
- if (*d2 <= small) {
- *d2 = small;
- }
- *x1 = x2;
- global_1->fx = fm;
- if (sf1 >= global_1->fx) {
- goto L17;
- }
- global_1->fx = sf1;
- *x1 = sx1;
-/* ...UPDATE X FOR LINEAR BUT NOT PARABOLIC SEARCH... */
-L17:
- if (j == 0) {
- return NLOPT_SUCCESS;
- }
- i__1 = n;
- for (i__ = 1; i__ <= i__1; ++i__) {
-/* L18: */
- x[i__] += *x1 * q_1->v[i__ + j * n - (n+1)];
- }
- return NLOPT_SUCCESS;
-} /* min_ */
-
-static double flin_(int n, int j, double *l, praxis_func f, void *f_data, double *x,
- int *nf, struct q_s *q_1, nlopt_result *ret)
-{
- /* System generated locals */
- int i__1;
- double ret_val;
-
- /* Local variables */
- nlopt_stopping *stop = q_1->stop;
- int i__;
- double *t; /* size n */
-
- t = q_1->t_flin;
-
-/* ...FLIN IS THE FUNCTION OF ONE REAL VARIABLE L THAT IS MINIMIZED */
-/* BY THE SUBROUTINE MIN... */
- /* Parameter adjustments */
- --x;
-
- /* Function Body */
- if (j == 0) {
- goto L2;
- }
-/* ...THE SEARCH IS LINEAR... */
- i__1 = n;
- for (i__ = 1; i__ <= i__1; ++i__) {
-/* L1: */
- t[i__ - 1] = x[i__] + *l * q_1->v[i__ + j * n - (n+1)];
- }
- goto L4;
-/* ...THE SEARCH IS ALONG A PARABOLIC SPACE CURVE... */
-L2:
- q_1->qa = *l * (*l - q_1->qd1) / (q_1->qd0 * (q_1->qd0 + q_1->qd1));
- q_1->qb = (*l + q_1->qd0) * (q_1->qd1 - *l) / (q_1->qd0 * q_1->qd1);
- q_1->qc = *l * (*l + q_1->qd0) / (q_1->qd1 * (q_1->qd0 + q_1->qd1));
- i__1 = n;
- for (i__ = 1; i__ <= i__1; ++i__) {
-/* L3: */
- t[i__ - 1] = q_1->qa * q_1->q0[i__ - 1] + q_1->qb * x[i__] + q_1->qc *
- q_1->q1[i__ - 1];
- }
-/* ...THE FUNCTION EVALUATION COUNTER NF IS INCREMENTED... */
-L4:
- ++(*nf);
- ret_val = f(n, t, f_data);
- stop->nevals++;
- if (ret_val < q_1->fbest) {
- q_1->fbest = ret_val;
- memcpy(q_1->xbest, t, n * sizeof(double));
- }
- if (nlopt_stop_forced(stop)) *ret = NLOPT_FORCED_STOP;
- else if (nlopt_stop_evals(stop)) *ret = NLOPT_MAXEVAL_REACHED;
- else if (nlopt_stop_time(stop)) *ret = NLOPT_MAXTIME_REACHED;
- else if (ret_val <= stop->minf_max) *ret = NLOPT_MINF_MAX_REACHED;
- return ret_val;
-} /* flin_ */
-
-static void sort_(int m, int n, double *d__, double *v)
-{
- /* System generated locals */
- int v_dim1, v_offset, i__1, i__2;
-
- /* Local variables */
- int i__, j, k;
- double s;
- int ip1, nm1;
-
-/* ...SORTS THE ELEMENTS OF D(N) INTO DESCENDING ORDER AND MOVES THE */
-/* CORRESPONDING COLUMNS OF V(N,N). */
-/* M IS THE ROW DIMENSION OF V AS DECLARED IN THE CALLING PROGRAM. */
- /* Parameter adjustments */
- v_dim1 = m;
- v_offset = 1 + v_dim1;
- v -= v_offset;
- --d__;
-
- /* Function Body */
- if (n == 1) {
- return;
- }
- nm1 = n - 1;
- i__1 = nm1;
- for (i__ = 1; i__ <= i__1; ++i__) {
- k = i__;
- s = d__[i__];
- ip1 = i__ + 1;
- i__2 = n;
- for (j = ip1; j <= i__2; ++j) {
- if (d__[j] <= s) {
- goto L1;
- }
- k = j;
- s = d__[j];
-L1:
- ;
- }
- if (k <= i__) {
- goto L3;
- }
- d__[k] = d__[i__];
- d__[i__] = s;
- i__2 = n;
- for (j = 1; j <= i__2; ++j) {
- s = v[j + i__ * v_dim1];
- v[j + i__ * v_dim1] = v[j + k * v_dim1];
-/* L2: */
- v[j + k * v_dim1] = s;
- }
-L3:
- ;
- }
-} /* sort_ */
-
-static void quad_(int n, praxis_func f, void *f_data, double *x, double *t_old,
- double machep, double *h__, struct global_s *global_1, struct q_s *q_1)
-{
- /* System generated locals */
- int i__1;
- double d__1;
-
- /* Local variables */
- int i__;
- double l, s;
- double value;
-
-/* ...QUAD LOOKS FOR THE MINIMUM OF F ALONG A CURVE DEFINED BY Q0,Q1,X... */
- /* Parameter adjustments */
- --x;
-
- /* Function Body */
- s = global_1->fx;
- global_1->fx = q_1->qf1;
- q_1->qf1 = s;
- q_1->qd1 = 0.;
- i__1 = n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- s = x[i__];
- l = q_1->q1[i__ - 1];
- x[i__] = l;
- q_1->q1[i__ - 1] = s;
-/* L1: */
-/* Computing 2nd power */
- d__1 = s - l;
- q_1->qd1 += d__1 * d__1;
- }
- q_1->qd1 = sqrt(q_1->qd1);
- l = q_1->qd1;
- s = 0.;
- if (q_1->qd0 <= 0. || q_1->qd1 <= 0. || global_1->nl < n * 3 * n) {
- goto L2;
- }
- value = q_1->qf1;
- min_(n, 0, 2, &s, &l, &value, 1, f,f_data, &x[1], t_old, machep,
- h__, global_1, q_1);
- q_1->qa = l * (l - q_1->qd1) / (q_1->qd0 * (q_1->qd0 + q_1->qd1));
- q_1->qb = (l + q_1->qd0) * (q_1->qd1 - l) / (q_1->qd0 * q_1->qd1);
- q_1->qc = l * (l + q_1->qd0) / (q_1->qd1 * (q_1->qd0 + q_1->qd1));
- goto L3;
-L2:
- global_1->fx = q_1->qf1;
- q_1->qa = 0.;
- q_1->qb = q_1->qa;
- q_1->qc = 1.;
-L3:
- q_1->qd0 = q_1->qd1;
- i__1 = n;
- for (i__ = 1; i__ <= i__1; ++i__) {
- s = q_1->q0[i__ - 1];
- q_1->q0[i__ - 1] = x[i__];
-/* L4: */
- x[i__] = q_1->qa * s + q_1->qb * x[i__] + q_1->qc * q_1->q1[i__ - 1];
- }
-} /* quad_ */
diff --git a/ext/src/nlopt/util/mt19937ar.c b/ext/src/nlopt/util/mt19937ar.c
deleted file mode 100644
index 561a1e5..0000000
--- a/ext/src/nlopt/util/mt19937ar.c
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- A C-program for MT19937, with initialization improved 2002/1/26.
- Coded by Takuji Nishimura and Makoto Matsumoto.
-
- Before using, initialize the state by using init_genrand(seed)
- or init_by_array(init_key, key_length).
-
- Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
- All rights reserved.
-
- Modified 2007 by Steven G. Johnson for use with NLopt (to avoid
- namespace pollution, use uint32_t instead of unsigned long,
- and add the urand function). Modified 2009 to add normal-distributed
- random numbers.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. The names of its contributors may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
- Any feedback is very welcome.
- http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
- email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
-*/
-
-#include "nlopt/nlopt-util.h"
-
-#include <stdint.h>
-
-/* Period parameters */
-#define N 624
-#define M 397
-#define MATRIX_A 0x9908b0dfUL /* constant vector a */
-#define UPPER_MASK 0x80000000UL /* most significant w-r bits */
-#define LOWER_MASK 0x7fffffffUL /* least significant r bits */
-
-/* SGJ 2010: make RNG thread-safe by declaring the RNG state as thread-local
- storage, at least for GCC, MSVC, and Intel C++ */
-
-static __thread uint32_t mt[N]; /* the array for the state vector */
-static __thread int mti=N+1; /* mti==N+1 means mt[N] is not initialized */
-
-/* initializes mt[N] with a seed */
-void nlopt_init_genrand(unsigned long s)
-{
- mt[0]= s & 0xffffffffUL;
- for (mti=1; mti<N; mti++) {
- mt[mti] =
- (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
- /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
- /* In the previous versions, MSBs of the seed affect */
- /* only MSBs of the array mt[]. */
- /* 2002/01/09 modified by Makoto Matsumoto */
- mt[mti] &= 0xffffffffUL;
- /* for >32 bit machines */
- }
-}
-
-/* generates a random number on [0,0xffffffff]-interval */
-static uint32_t nlopt_genrand_int32(void)
-{
- uint32_t y;
- static uint32_t mag01[2]={0x0UL, MATRIX_A};
- /* mag01[x] = x * MATRIX_A for x=0,1 */
-
- if (mti >= N) { /* generate N words at one time */
- int kk;
-
- if (mti == N+1) /* if init_genrand() has not been called, */
- nlopt_init_genrand(5489UL); /* a default initial seed is used */
-
- for (kk=0;kk<N-M;kk++) {
- y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
- mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];
- }
- for (;kk<N-1;kk++) {
- y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
- mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
- }
- y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
- mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
-
- mti = 0;
- }
-
- y = mt[mti++];
-
- /* Tempering */
- y ^= (y >> 11);
- y ^= (y << 7) & 0x9d2c5680UL;
- y ^= (y << 15) & 0xefc60000UL;
- y ^= (y >> 18);
-
- return y;
-}
-
-#if 0 /* not used in NLopt */
-
-/* initialize by an array with array-length */
-/* init_key is the array for initializing keys */
-/* key_length is its length */
-/* slight change for C++, 2004/2/26 */
-static void nlopt_init_by_array(uint32_t init_key[], int key_length)
-{
- int i, j, k;
- nlopt_init_genrand(19650218UL);
- i=1; j=0;
- k = (N>key_length ? N : key_length);
- for (; k; k--) {
- mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL))
- + init_key[j] + j; /* non linear */
- mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
- i++; j++;
- if (i>=N) { mt[0] = mt[N-1]; i=1; }
- if (j>=key_length) j=0;
- }
- for (k=N-1; k; k--) {
- mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL))
- - i; /* non linear */
- mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
- i++;
- if (i>=N) { mt[0] = mt[N-1]; i=1; }
- }
-
- mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */
-}
-
-/* generates a random number on [0,0x7fffffff]-interval */
-static long nlopt_genrand_int31(void)
-{
- return (long)(nlopt_genrand_int32()>>1);
-}
-
-/* generates a random number on [0,1]-real-interval */
-static double nlopt_genrand_real1(void)
-{
- return nlopt_genrand_int32()*(1.0/4294967295.0);
- /* divided by 2^32-1 */
-}
-
-/* generates a random number on [0,1)-real-interval */
-static double nlopt_genrand_real2(void)
-{
- return nlopt_genrand_int32()*(1.0/4294967296.0);
- /* divided by 2^32 */
-}
-
-/* generates a random number on (0,1)-real-interval */
-static double nlopt_genrand_real3(void)
-{
- return (((double)nlopt_genrand_int32()) + 0.5)*(1.0/4294967296.0);
- /* divided by 2^32 */
-}
-
-#endif
-
-/* generates a random number on [0,1) with 53-bit resolution*/
-static double nlopt_genrand_res53(void)
-{
- uint32_t a=nlopt_genrand_int32()>>5, b=nlopt_genrand_int32()>>6;
- return(a*67108864.0+b)*(1.0/9007199254740992.0);
-}
-/* These real versions are due to Isaku Wada, 2002/01/09 added */
-
-/* generate uniform random number in [a,b) with 53-bit resolution,
- added by SGJ */
-double nlopt_urand(double a, double b)
-{
- return(a + (b - a) * nlopt_genrand_res53());
-}
-
-/* generate a uniform random number in [0,n), added by SGJ */
-int nlopt_iurand(int n)
-{
- return(nlopt_genrand_int32() % n);
-}
-
-/* normal-distributed random numbers with the given mean and std. deviation,
- added by SGJ */
-double nlopt_nrand(double mean, double stddev)
-{
- // Box-Muller algorithm to generate Gaussian from uniform
- // see Knuth vol II algorithm P, sec. 3.4.1
- double v1, v2, s;
- do {
- v1 = nlopt_urand(-1, 1);
- v2 = nlopt_urand(-1, 1);
- s = v1*v1 + v2*v2;
- } while (s >= 1.0);
- if (s == 0) {
- return mean;
- }
- else {
- return mean + v1 * sqrt(-2 * log(s) / s) * stddev;
- }
-}
-
-#if 0
-#include <stdio.h>
-int main(void)
-{
- int i;
- uint32_t init[4]={0x123, 0x234, 0x345, 0x456}, length=4;
- init_by_array(init, length);
- printf("1000 outputs of nlopt_genrand_int32()\n");
- for (i=0; i<1000; i++) {
- printf("%10lu ", nlopt_genrand_int32());
- if (i%5==4) printf("\n");
- }
- printf("\n1000 outputs of genrand_real2()\n");
- for (i=0; i<1000; i++) {
- printf("%10.8f ", genrand_real2());
- if (i%5==4) printf("\n");
- }
- return 0;
-}
-#endif
diff --git a/ext/src/nlopt/util/qsort_r.c b/ext/src/nlopt/util/qsort_r.c
deleted file mode 100644
index d80b98b..0000000
--- a/ext/src/nlopt/util/qsort_r.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/* Copyright (c) 2007-2012 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include "nlopt/nlopt-util.h"
-
-/* Simple replacement for the BSD qsort_r function (re-entrant sorting),
- if it is not available.
-
- (glibc 2.8 included a qsort_r function as well, but totally
- *%&$#-ed things up by gratuitously changing the argument order, in
- such a way as to allow code using the BSD ordering to compile but
- die a flaming death at runtime. Damn them all to Hell, I'll just
- use my own implementation.)
-
- (Actually, with glibc 2.3.6 on my Intel Core Duo, my implementation
- below seems to be significantly faster than qsort. Go figure.)
-*/
-
-#ifndef HAVE_QSORT_R_damn_it_use_my_own
-/* swap size bytes between a_ and b_ */
-static void swap(void *a_, void *b_, size_t size)
-{
- if (a_ == b_) return;
- {
- size_t i, nlong = size / sizeof(long);
- long *a = (long *) a_, *b = (long *) b_;
- for (i = 0; i < nlong; ++i) {
- long c = a[i];
- a[i] = b[i];
- b[i] = c;
- }
- a_ = (void*) (a + nlong);
- b_ = (void*) (b + nlong);
- }
- {
- size_t i;
- char *a = (char *) a_, *b = (char *) b_;
- size = size % sizeof(long);
- for (i = 0; i < size; ++i) {
- char c = a[i];
- a[i] = b[i];
- b[i] = c;
- }
- }
-}
-#endif /* HAVE_QSORT_R */
-
-void nlopt_qsort_r(void *base_, size_t nmemb, size_t size, void *thunk,
- int (*compar)(void *, const void *, const void *))
-{
-#ifdef HAVE_QSORT_R_damn_it_use_my_own
- /* Even if we could detect glibc vs. BSD by appropriate
- macrology, there is no way to make the calls compatible
- without writing a wrapper for the compar function...screw
- this. */
- qsort_r(base_, nmemb, size, thunk, compar);
-#else
- char *base = (char *) base_;
- if (nmemb < 10) { /* use O(nmemb^2) algorithm for small enough nmemb */
- size_t i, j;
- for (i = 0; i+1 < nmemb; ++i)
- for (j = i+1; j < nmemb; ++j)
- if (compar(thunk, base+i*size, base+j*size) > 0)
- swap(base+i*size, base+j*size, size);
- }
- else {
- size_t i, pivot, npart;
- /* pick median of first/middle/last elements as pivot */
- {
- const char *a = base, *b = base + (nmemb/2)*size,
- *c = base + (nmemb-1)*size;
- pivot = compar(thunk,a,b) < 0
- ? (compar(thunk,b,c) < 0 ? nmemb/2 :
- (compar(thunk,a,c) < 0 ? nmemb-1 : 0))
- : (compar(thunk,a,c) < 0 ? 0 :
- (compar(thunk,b,c) < 0 ? nmemb-1 : nmemb/2));
- }
- /* partition array */
- swap(base + pivot*size, base + (nmemb-1) * size, size);
- pivot = (nmemb - 1) * size;
- for (i = npart = 0; i < nmemb-1; ++i)
- if (compar(thunk, base+i*size, base+pivot) <= 0)
- swap(base+i*size, base+(npart++)*size, size);
- swap(base+npart*size, base+pivot, size);
- /* recursive sort of two partitions */
- nlopt_qsort_r(base, npart, size, thunk, compar);
- npart++; /* don't need to sort pivot */
- nlopt_qsort_r(base+npart*size, nmemb-npart, size, thunk, compar);
- }
-#endif /* !HAVE_QSORT_R */
-}
diff --git a/ext/src/nlopt/util/redblack.c b/ext/src/nlopt/util/redblack.c
deleted file mode 100644
index c26eab0..0000000
--- a/ext/src/nlopt/util/redblack.c
+++ /dev/null
@@ -1,430 +0,0 @@
-/* Copyright (c) 2007-2012 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/* simple implementation of red-black trees optimized for use with DIRECT */
-
-#include <stddef.h>
-#include <stdlib.h>
-#include "nlopt/redblack.h"
-
-/* it is convenient to use an explicit node for NULL nodes ... we need
- to be careful never to change this node indirectly via one of our
- pointers! */
-rb_node nil = {&nil, &nil, &nil, 0, BLACK};
-#define NIL (&nil)
-
-void rb_tree_init(rb_tree *t, rb_compare compare) {
- t->compare = compare;
- t->root = NIL;
- t->N = 0;
-}
-
-static void destroy(rb_node *n)
-{
- if (n != NIL) {
- destroy(n->l); destroy(n->r);
- free(n);
- }
-}
-
-void rb_tree_destroy(rb_tree *t)
-{
- destroy(t->root);
- t->root = NIL;
-}
-
-void rb_tree_destroy_with_keys(rb_tree *t)
-{
- rb_node *n = rb_tree_min(t);
- while (n) {
- free(n->k); n->k = NULL;
- n = rb_tree_succ(n);
- }
- rb_tree_destroy(t);
-}
-
-static void rotate_left(rb_node *p, rb_tree *t)
-{
- rb_node *n = p->r; /* must be non-NIL */
- p->r = n->l;
- n->l = p;
- if (p->p != NIL) {
- if (p == p->p->l) p->p->l = n;
- else p->p->r = n;
- }
- else
- t->root = n;
- n->p = p->p;
- p->p = n;
- if (p->r != NIL) p->r->p = p;
-}
-
-static void rotate_right(rb_node *p, rb_tree *t)
-{
- rb_node *n = p->l; /* must be non-NIL */
- p->l = n->r;
- n->r = p;
- if (p->p != NIL) {
- if (p == p->p->l) p->p->l = n;
- else p->p->r = n;
- }
- else
- t->root = n;
- n->p = p->p;
- p->p = n;
- if (p->l != NIL) p->l->p = p;
-}
-
-static void insert_node(rb_tree *t, rb_node *n)
-{
- rb_compare compare = t->compare;
- rb_key k = n->k;
- rb_node *p = t->root;
- n->c = RED;
- n->p = n->l = n->r = NIL;
- t->N++;
- if (p == NIL) {
- t->root = n;
- n->c = BLACK;
- return;
- }
- /* insert (RED) node into tree */
- while (1) {
- if (compare(k, p->k) <= 0) { /* k <= p->k */
- if (p->l != NIL)
- p = p->l;
- else {
- p->l = n;
- n->p = p;
- break;
- }
- }
- else {
- if (p->r != NIL)
- p = p->r;
- else {
- p->r = n;
- n->p = p;
- break;
- }
- }
- }
- fixtree:
- if (n->p->c == RED) { /* red cannot have red child */
- rb_node *u = p == p->p->l ? p->p->r : p->p->l;
- if (u != NIL && u->c == RED) {
- p->c = u->c = BLACK;
- n = p->p;
- if ((p = n->p) != NIL) {
- n->c = RED;
- goto fixtree;
- }
- }
- else {
- if (n == p->r && p == p->p->l) {
- rotate_left(p, t);
- p = n; n = n->l;
- }
- else if (n == p->l && p == p->p->r) {
- rotate_right(p, t);
- p = n; n = n->r;
- }
- p->c = BLACK;
- p->p->c = RED;
- if (n == p->l && p == p->p->l)
- rotate_right(p->p, t);
- else if (n == p->r && p == p->p->r)
- rotate_left(p->p, t);
- }
-
- }
-}
-
-rb_node *rb_tree_insert(rb_tree *t, rb_key k)
-{
- rb_node *n = (rb_node *) malloc(sizeof(rb_node));
- if (!n) return NULL;
- n->k = k;
- insert_node(t, n);
- return n;
-}
-
-static int check_node(rb_node *n, int *nblack, rb_tree *t)
-{
- int nbl, nbr;
- rb_compare compare = t->compare;
- if (n == NIL) { *nblack = 0; return 1; }
- if (n->r != NIL && n->r->p != n) return 0;
- if (n->r != NIL && compare(n->r->k, n->k) < 0)
- return 0;
- if (n->l != NIL && n->l->p != n) return 0;
- if (n->l != NIL && compare(n->l->k, n->k) > 0)
- return 0;
- if (n->c == RED) {
- if (n->r != NIL && n->r->c == RED) return 0;
- if (n->l != NIL && n->l->c == RED) return 0;
- }
- if (!(check_node(n->r, &nbl, t) && check_node(n->l, &nbr, t)))
- return 0;
- if (nbl != nbr) return 0;
- *nblack = nbl + (n->c == BLACK);
- return 1;
-}
-int rb_tree_check(rb_tree *t)
-{
- int nblack;
- if (nil.c != BLACK) return 0;
- if (nil.p != NIL || nil.r != NIL || nil.l != NIL) return 0;
- if (t->root == NIL) return 1;
- if (t->root->c != BLACK) return 0;
- return check_node(t->root, &nblack, t);
-}
-
-rb_node *rb_tree_find(rb_tree *t, rb_key k)
-{
- rb_compare compare = t->compare;
- rb_node *p = t->root;
- while (p != NIL) {
- int comp = compare(k, p->k);
- if (!comp) return p;
- p = comp <= 0 ? p->l : p->r;
- }
- return NULL;
-}
-
-/* find greatest point in subtree p that is <= k */
-static rb_node *find_le(rb_node *p, rb_key k, rb_tree *t)
-{
- rb_compare compare = t->compare;
- while (p != NIL) {
- if (compare(p->k, k) <= 0) { /* p->k <= k */
- rb_node *r = find_le(p->r, k, t);
- if (r) return r;
- else return p;
- }
- else /* p->k > k */
- p = p->l;
- }
- return NULL; /* k < everything in subtree */
-}
-
-/* find greatest point in t <= k */
-rb_node *rb_tree_find_le(rb_tree *t, rb_key k)
-{
- return find_le(t->root, k, t);
-}
-
-/* find greatest point in subtree p that is < k */
-static rb_node *find_lt(rb_node *p, rb_key k, rb_tree *t)
-{
- rb_compare compare = t->compare;
- while (p != NIL) {
- if (compare(p->k, k) < 0) { /* p->k < k */
- rb_node *r = find_lt(p->r, k, t);
- if (r) return r;
- else return p;
- }
- else /* p->k >= k */
- p = p->l;
- }
- return NULL; /* k <= everything in subtree */
-}
-
-/* find greatest point in t < k */
-rb_node *rb_tree_find_lt(rb_tree *t, rb_key k)
-{
- return find_lt(t->root, k, t);
-}
-
-/* find least point in subtree p that is > k */
-static rb_node *find_gt(rb_node *p, rb_key k, rb_tree *t)
-{
- rb_compare compare = t->compare;
- while (p != NIL) {
- if (compare(p->k, k) > 0) { /* p->k > k */
- rb_node *l = find_gt(p->l, k, t);
- if (l) return l;
- else return p;
- }
- else /* p->k <= k */
- p = p->r;
- }
- return NULL; /* k >= everything in subtree */
-}
-
-/* find least point in t > k */
-rb_node *rb_tree_find_gt(rb_tree *t, rb_key k)
-{
- return find_gt(t->root, k, t);
-}
-
-rb_node *rb_tree_min(rb_tree *t)
-{
- rb_node *n = t->root;
- while (n != NIL && n->l != NIL)
- n = n->l;
- return(n == NIL ? NULL : n);
-}
-
-rb_node *rb_tree_max(rb_tree *t)
-{
- rb_node *n = t->root;
- while (n != NIL && n->r != NIL)
- n = n->r;
- return(n == NIL ? NULL : n);
-}
-
-rb_node *rb_tree_succ(rb_node *n)
-{
- if (!n) return NULL;
- if (n->r == NIL) {
- rb_node *prev;
- do {
- prev = n;
- n = n->p;
- } while (prev == n->r && n != NIL);
- return n == NIL ? NULL : n;
- }
- else {
- n = n->r;
- while (n->l != NIL)
- n = n->l;
- return n;
- }
-}
-
-rb_node *rb_tree_pred(rb_node *n)
-{
- if (!n) return NULL;
- if (n->l == NIL) {
- rb_node *prev;
- do {
- prev = n;
- n = n->p;
- } while (prev == n->l && n != NIL);
- return n == NIL ? NULL : n;
- }
- else {
- n = n->l;
- while (n->r != NIL)
- n = n->r;
- return n;
- }
-}
-
-rb_node *rb_tree_remove(rb_tree *t, rb_node *n)
-{
- rb_key k = n->k;
- rb_node *m, *mp;
- if (n->l != NIL && n->r != NIL) {
- rb_node *lmax = n->l;
- while (lmax->r != NIL) lmax = lmax->r;
- n->k = lmax->k;
- n = lmax;
- }
- m = n->l != NIL ? n->l : n->r;
- if (n->p != NIL) {
- if (n->p->r == n) n->p->r = m;
- else n->p->l = m;
- }
- else
- t->root = m;
- mp = n->p;
- if (m != NIL) m->p = mp;
- if (n->c == BLACK) {
- if (m->c == RED)
- m->c = BLACK;
- else {
- deleteblack:
- if (mp != NIL) {
- rb_node *s = m == mp->l ? mp->r : mp->l;
- if (s->c == RED) {
- mp->c = RED;
- s->c = BLACK;
- if (m == mp->l) rotate_left(mp, t);
- else rotate_right(mp, t);
- s = m == mp->l ? mp->r : mp->l;
- }
- if (mp->c == BLACK && s->c == BLACK
- && s->l->c == BLACK && s->r->c == BLACK) {
- if (s != NIL) s->c = RED;
- m = mp; mp = m->p;
- goto deleteblack;
- }
- else if (mp->c == RED && s->c == BLACK &&
- s->l->c == BLACK && s->r->c == BLACK) {
- if (s != NIL) s->c = RED;
- mp->c = BLACK;
- }
- else {
- if (m == mp->l && s->c == BLACK &&
- s->l->c == RED && s->r->c == BLACK) {
- s->c = RED;
- s->l->c = BLACK;
- rotate_right(s, t);
- s = m == mp->l ? mp->r : mp->l;
- }
- else if (m == mp->r && s->c == BLACK &&
- s->r->c == RED && s->l->c == BLACK) {
- s->c = RED;
- s->r->c = BLACK;
- rotate_left(s, t);
- s = m == mp->l ? mp->r : mp->l;
- }
- s->c = mp->c;
- mp->c = BLACK;
- if (m == mp->l) {
- s->r->c = BLACK;
- rotate_left(mp, t);
- }
- else {
- s->l->c = BLACK;
- rotate_right(mp, t);
- }
- }
- }
- }
- }
- t->N--;
- n->k = k; /* n may have changed during remove */
- return n; /* the node that was deleted may be different from initial n */
-}
-
-rb_node *rb_tree_resort(rb_tree *t, rb_node *n)
-{
- n = rb_tree_remove(t, n);
- insert_node(t, n);
- return n;
-}
-
-/* shift all key pointers by kshift ... this is useful when the keys
- are pointers into another array, that has been resized with realloc */
-static void shift_keys(rb_node *n, ptrdiff_t kshift) /* assumes n != NIL */
-{
- n->k += kshift;
- if (n->l != NIL) shift_keys(n->l, kshift);
- if (n->r != NIL) shift_keys(n->r, kshift);
-}
-void rb_tree_shift_keys(rb_tree *t, ptrdiff_t kshift)
-{
- if (t->root != NIL) shift_keys(t->root, kshift);
-}
diff --git a/ext/src/nlopt/util/rescale.c b/ext/src/nlopt/util/rescale.c
deleted file mode 100644
index aa376dd..0000000
--- a/ext/src/nlopt/util/rescale.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Copyright (c) 2007-2012 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <stdlib.h>
-#include "nlopt/nlopt-util.h"
-
-/* Return a new array of length n (> 0) that gives a rescaling factor
- for each dimension, or NULL if out of memory, with dx being the
- array of nonzero initial steps in each dimension. */
-double *nlopt_compute_rescaling(unsigned n, const double *dx)
-{
- double *s = (double *) malloc(sizeof(double) * n);
- unsigned i;
-
- if (!s) return NULL;
- for (i = 0; i < n; ++i) s[i] = 1.0; /* default: no rescaling */
- if (n == 1) return s;
-
- for (i = 1; i < n && dx[i] == dx[i-1]; ++i) ;
- if (i < n) { /* unequal initial steps, rescale to make equal to dx[0] */
- for (i = 1; i < n; ++i)
- s[i] = dx[i] / dx[0];
- }
- return s;
-}
-
-void nlopt_rescale(unsigned n, const double *s, const double *x, double *xs)
-{
- unsigned i;
- if (!s) { for (i = 0; i < n;++i) xs[i] = x[i]; }
- else { for (i = 0; i < n;++i) xs[i] = x[i] / s[i]; }
-}
-
-void nlopt_unscale(unsigned n, const double *s, const double *x, double *xs)
-{
- unsigned i;
- if (!s) { for (i = 0; i < n;++i) xs[i] = x[i]; }
- else { for (i = 0; i < n;++i) xs[i] = x[i] * s[i]; }
-}
-
-/* return a new array of length n equal to the original array
- x divided by the scale factors s, or NULL on a memory error */
-double *nlopt_new_rescaled(unsigned n, const double *s, const double *x)
-{
- double *xs = (double *) malloc(sizeof(double) * n);
- if (!xs) return NULL;
- nlopt_rescale(n, s, x, xs);
- return xs;
-}
-
-/* since rescaling can flip the signs of the x components and the bounds,
- we may have to re-order the bounds in order to ensure that they
- remain in the correct order */
-void nlopt_reorder_bounds(unsigned n, double *lb, double *ub)
-{
- unsigned i;
- for (i = 0; i < n; ++i)
- if (lb[i] > ub[i]) {
- double t = lb[i];
- lb[i] = ub[i];
- ub[i] = t;
- }
-}
diff --git a/ext/src/nlopt/util/soboldata.h b/ext/src/nlopt/util/soboldata.h
deleted file mode 100644
index 19efa5b..0000000
--- a/ext/src/nlopt/util/soboldata.h
+++ /dev/null
@@ -1,880 +0,0 @@
-/* Copyright (c) 2007 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef SOBOLSEQ_H
-#define SOBOLSEQ_H
-
-/* Data on the primitive binary polynomials (a) and the corresponding
- starting values m, for Sobol sequences in up to 1111 dimensions,
- taken from:
- P. Bratley and B. L. Fox, Algorithm 659, ACM Trans.
- Math. Soft. 14 (1), 88-100 (1988),
- as modified by:
- S. Joe and F. Y. Kuo, ACM Trans. Math. Soft 29 (1), 49-57 (2003). */
-
-#define MAXDIM 1111
-#define MAXDEG 12
-
-/* successive primitive binary-coefficient polynomials p(z)
- = a_0 + a_1 z + a_2 z^2 + ... a_31 z^31, where a_i is the
- i-th bit of sobol_a[j] for the j-th polynomial. */
-static const uint32_t sobol_a[MAXDIM-1] = {
- 3,7,11,13,19,25,37,59,47,61,55,41,67,97,91,
- 109,103,115,131,193,137,145,143,241,157,185,167,229,171,213,
- 191,253,203,211,239,247,285,369,299,301,333,351,355,357,361,
- 391,397,425,451,463,487,501,529,539,545,557,563,601,607,617,
- 623,631,637,647,661,675,677,687,695,701,719,721,731,757,761,
- 787,789,799,803,817,827,847,859,865,875,877,883,895,901,911,
- 949,953,967,971,973,981,985,995,1001,1019,1033,1051,1063,
- 1069,1125,1135,1153,1163,1221,1239,1255,1267,1279,1293,1305,
- 1315,1329,1341,1347,1367,1387,1413,1423,1431,1441,1479,1509,
- 1527,1531,1555,1557,1573,1591,1603,1615,1627,1657,1663,1673,
- 1717,1729,1747,1759,1789,1815,1821,1825,1849,1863,1869,1877,
- 1881,1891,1917,1933,1939,1969,2011,2035,2041,2053,2071,2091,
- 2093,2119,2147,2149,2161,2171,2189,2197,2207,2217,2225,2255,
- 2257,2273,2279,2283,2293,2317,2323,2341,2345,2363,2365,2373,
- 2377,2385,2395,2419,2421,2431,2435,2447,2475,2477,2489,2503,
- 2521,2533,2551,2561,2567,2579,2581,2601,2633,2657,2669,
- 2681,2687,2693,2705,2717,2727,2731,2739,
- 2741,2773,2783,2793,2799,2801,2811,2819,2825,2833,2867,2879,
- 2881,2891,2905,2911,2917,2927,2941,2951,2955,2963,2965,2991,
- 2999,3005,3017,3035,3037,3047,3053,3083,3085,3097,3103,3159,
- 3169,3179,3187,3205,3209,3223,3227,3229,3251,3263,3271,3277,
- 3283,3285,3299,3305,3319,3331,3343,3357,3367,3373,3393,3399,
- 3413,3417,3427,3439,3441,3475,3487,3497,3515,3517,3529,3543,
- 3547,3553,3559,3573,3589,3613,3617,3623,3627,3635,3641,3655,
- 3659,3669,3679,3697,3707,3709,3713,3731,3743,3747,3771,3791,
- 3805,3827,3833,3851,3865,3889,3895,3933,3947,3949,3957,3971,
- 3985,3991,3995,4007,4013,4021,4045,4051,4069,4073,4179,4201,
- 4219,4221,4249,4305,4331,4359,4383,4387,4411,4431,4439,4449,
- 4459,4485,4531,4569,4575,4621,4663,4669,4711,4723,4735,4793,
- 4801,4811,4879,4893,4897,4921,4927,4941,4977,5017,5027,5033,
- 5127,5169,5175,5199,5213,5223,5237,5287,5293,5331,5391,5405,
- 5453,5523,5573,5591,5597,5611,5641,5703,5717,5721,5797,5821,
- 5909,5913,
- 5955,5957,6005,6025,6061,6067,6079,6081,
- 6231,6237,6289,6295,6329,6383,6427,6453,6465,6501,6523,6539,
- 6577,6589,6601,6607,6631,6683,6699,6707,6761,6795,6865,6881,
- 6901,6923,6931,6943,6999,7057,7079,7103,7105,7123,7173,7185,
- 7191,7207,7245,7303,7327,7333,7355,7365,7369,7375,7411,7431,
- 7459,7491,7505,7515,7541,7557,7561,7701,7705,7727,7749,7761,
- 7783,7795,7823,7907,7953,7963,7975,8049,8089,8123,8125,8137,
- 8219,8231,8245,8275,8293,8303,8331,8333,8351,8357,8367,8379,
- 8381,8387,8393,8417,8435,8461,8469,8489,8495,8507,8515,8551,
- 8555,8569,8585,8599,8605,8639,8641,8647,8653,8671,8675,8689,
- 8699,8729,8741,8759,8765,8771,8795,8797,8825,8831,8841,8855,
- 8859,8883,8895,8909,8943,8951,8955,8965,8999,9003,9031,9045,
- 9049,9071,9073,9085,9095,9101,9109,9123,9129,9137,9143,9147,
- 9185,9197,9209,9227,9235,9247,9253,9257,9277,9297,9303,9313,
- 9325,9343,9347,9371,9373,9397,9407,9409,9415,9419,9443,9481,
- 9495,9501,9505,9517,9529,9555,9557,9571,9585,9591,9607,9611,
- 9621,9625,
- 9631,9647,9661,9669,9679,9687,9707,9731,
- 9733,9745,9773,9791,9803,9811,9817,9833,9847,9851,9863,9875,
- 9881,9905,9911,9917,9923,9963,9973,10003,10025,10043,10063,
- 10071,10077,10091,10099,10105,10115,10129,10145,10169,10183,
- 10187,10207,10223,10225,10247,10265,10271,10275,10289,10299,
- 10301,10309,10343,10357,10373,10411,10413,10431,10445,10453,
- 10463,10467,10473,10491,10505,10511,10513,10523,10539,10549,
- 10559,10561,10571,10581,10615,10621,10625,10643,10655,10671,
- 10679,10685,10691,10711,10739,10741,10755,10767,10781,10785,
- 10803,10805,10829,10857,10863,10865,10875,10877,10917,10921,
- 10929,10949,10967,10971,10987,10995,11009,11029,11043,11045,
- 11055,11063,11075,11081,11117,11135,11141,11159,11163,11181,
- 11187,11225,11237,11261,11279,11297,11307,11309,11327,11329,
- 11341,11377,11403,11405,11413,11427,11439,11453,11461,11473,
- 11479,11489,11495,11499,11533,11545,11561,11567,11575,11579,
- 11589,11611,11623,11637,11657,11663,11687,11691,11701,11747,
- 11761,11773,11783,11795,11797,11817,11849,11855,11867,11869,
- 11873,11883,11919,
- 11921,11927,11933,11947,11955,11961,
- 11999,12027,12029,12037,12041,12049,12055,12095,12097,12107,
- 12109,12121,12127,12133,12137,12181,12197,12207,12209,12239,
- 12253,12263,12269,12277,12287,12295,12309,12313,12335,12361,
- 12367,12391,12409,12415,12433,12449,12469,12479,12481,12499,
- 12505,12517,12527,12549,12559,12597,12615,12621,12639,12643,
- 12657,12667,12707,12713,12727,12741,12745,12763,12769,12779,
- 12781,12787,12799,12809,12815,12829,12839,12857,12875,12883,
- 12889,12901,12929,12947,12953,12959,12969,12983,12987,12995,
- 13015,13019,13031,13063,13077,13103,13137,13149,13173,13207,
- 13211,13227,13241,13249,13255,13269,13283,13285,13303,13307,
- 13321,13339,13351,13377,13389,13407,13417,13431,13435,13447,
- 13459,13465,13477,13501,13513,13531,13543,13561,13581,13599,
- 13605,13617,13623,13637,13647,13661,13677,13683,13695,13725,
- 13729,13753,13773,13781,13785,13795,13801,13807,13825,13835,
- 13855,13861,13871,13883,13897,13905,13915,13939,13941,13969,
- 13979,13981,13997,14027,14035,14037,14051,14063,14085,14095,
- 14107,14113,14125,14137,14145,
- 14151,14163,14193,14199,14219,14229,
- 14233,14243,14277,14287,14289,14295,14301,14305,14323,14339,
- 14341,14359,14365,14375,14387,14411,14425,14441,14449,14499,
- 14513,14523,14537,14543,14561,14579,14585,14593,14599,14603,
- 14611,14641,14671,14695,14701,14723,14725,14743,14753,14759,
- 14765,14795,14797,14803,14831,14839,14845,14855,14889,14895,
- 14909,14929,14941,14945,14951,14963,14965,14985,15033,15039,
- 15053,15059,15061,15071,15077,15081,15099,15121,15147,15149,
- 15157,15167,15187,15193,15203,15205,15215,15217,15223,15243,
- 15257,15269,15273,15287,15291,15313,15335,15347,15359,15373,
- 15379,15381,15391,15395,15397,15419,15439,15453,15469,15491,
- 15503,15517,15527,15531,15545,15559,15593,15611,15613,15619,
- 15639,15643,15649,15661,15667,15669,15681,15693,15717,15721,
- 15741,15745,15765,15793,15799,15811,15825,15835,15847,15851,
- 15865,15877,15881,15887,15899,15915,15935,15937,15955,15973,
- 15977,16011,16035,16061,16069,16087,16093,16097,16121,16141,
- 16153,16159,16165,16183,16189,16195,16197,16201,16209,16215,
- 16225,16259,16265,16273,16299,
- 16309,16355,16375,16381,
-};
-
-/* starting direction #'s m[i] = sobol_minit[i][j] for i=0..d of the
- * degree-d primitive polynomial sobol_a[j]. */
-static const uint32_t sobol_minit[MAXDEG+1][MAXDIM-1] = {
- /* [0][*] */
- { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 [...]
- /* [1][*] */
- { 0,
- 1,3,1,3,1,3,3,1,3,1,3,1,3,1,1,3,1,3,1,3,
- 1,3,3,1,1,1,3,1,3,1,3,3,1,3,1,1,1,3,1,3,1,1,1,3,3,1,3,3,1,1,
- 3,3,1,3,3,3,1,3,1,3,1,1,3,3,1,1,1,1,3,1,1,3,1,1,1,3,3,1,3,3,
- 1,3,3,3,1,3,3,3,1,3,3,1,3,3,3,1,3,1,3,1,1,3,3,1,3,3,1,1,1,3,
- 3,1,3,3,1,3,1,1,3,3,3,1,1,1,3,1,1,3,1,1,3,3,1,3,1,3,3,3,3,1,
- 1,1,3,3,1,1,3,1,1,1,1,1,1,3,1,3,1,1,1,3,1,3,1,3,3,3,1,1,3,3,
- 1,3,1,3,1,1,3,1,3,1,3,1,3,1,1,1,3,3,1,3,3,1,3,1,1,1,3,1,3,1,
- 1,3,1,1,3,3,1,1,3,3,3,1,3,3,3,1,3,1,3,1,1,1,3,1,1,1,3,1,1,1,
- 1,1,3,3,3,1,1,1,1,3,3,3,1,3,3,1,1,1,1,3,1,1,3,1,3,3,1,1,3,3,
- 1,1,1,1,3,1,3,3,1,3,3,1,1,1,3,3,3,1,3,3,1,3,3,1,3,1,3,3,3,1,
- 3,1,1,3,1,3,1,1,1,3,3,3,1,1,3,1,3,1,1,1,1,1,1,3,1,1,3,1,3,3,
- 1,1,1,1,3,1,3,1,3,1,1,1,1,3,3,1,1,1,1,1,3,3,3,1,1,3,3,3,3,3,
- 1,3,3,1,3,3,3,3,1,1,1,1,1,1,3,1,1,3,1,1,1,3,1,1,1,3,3,3,1,3,
- 1,1,3,3,3,1,3,3,1,3,1,3,3,1,3,3,3,1,1,
- 3,3,1,3,1,3,1,1,1,3,3,3,3,1,3,1,1,3,1,
- 3,1,1,1,3,1,3,1,3,1,3,3,3,3,3,3,3,3,1,3,3,3,3,3,1,3,1,3,3,3,
- 1,3,1,3,1,3,3,1,3,3,3,3,3,3,3,3,3,1,1,1,1,1,1,3,3,1,1,3,3,1,
- 1,1,3,3,1,1,3,3,3,3,1,1,3,1,3,3,1,3,3,1,1,1,3,3,3,1,1,3,3,3,
- 3,3,1,1,1,3,1,3,3,1,3,3,3,3,1,1,3,1,1,3,1,3,1,3,1,3,3,1,1,3,
- 3,1,3,3,1,3,3,1,1,3,1,3,3,1,1,3,1,3,1,3,1,1,3,3,1,1,1,3,3,1,
- 3,1,1,3,3,1,1,3,1,3,1,1,1,1,1,3,1,1,1,1,3,1,3,1,1,3,3,1,1,3,
- 1,3,1,3,3,3,1,3,3,3,1,1,3,3,3,1,1,1,1,3,1,3,1,3,1,1,3,3,1,1,
- 1,3,3,1,3,1,3,1,1,1,1,1,1,3,1,3,3,1,3,3,3,1,3,1,1,3,3,1,1,3,
- 3,1,1,1,3,1,3,3,1,1,3,1,1,3,1,3,1,1,1,3,3,3,3,1,1,3,3,1,1,1,
- 1,3,1,1,3,3,3,1,1,3,3,1,3,3,1,1,3,3,3,3,3,3,3,1,3,3,1,3,1,3,
- 1,1,3,3,1,1,1,3,1,3,3,1,3,3,1,3,1,1,3,3,3,1,1,1,3,1,1,1,3,3,
- 3,1,3,3,1,3,1,1,3,3,3,1,3,3,1,1,1,3,1,3,3,3,3,3,3,3,3,1,3,3,
- 1,3,1,1,3,3,3,1,3,3,3,3,3,1,3,3,3,1,1,1,
- 3,3,1,3,3,1,3,1,3,1,3,1,3,3,3,3,3,3,
- 1,1,3,1,3,1,1,1,1,1,3,1,1,1,3,1,3,1,1,3,3,3,1,3,1,3,1,1,3,1,
- 3,3,1,3,1,3,3,1,3,3,1,3,3,3,3,3,3,1,3,1,1,3,3,3,1,1,3,3,3,3,
- 3,3,3,1,3,3,3,3,1,3,1,3,3,3,1,3,1,3,1,1,1,3,3,1,3,1,1,3,3,1,
- 3,1,1,1,1,3,1,3,1,1,3,1,3,1,3,3,3,3,3,3,1,3,3,3,3,1,3,3,1,3,
- 3,3,3,3,1,1,1,1,3,3,3,1,3,3,1,1,3,3,1,1,3,3,1,3,1,1,3,1,3,3,
- 3,3,3,1,3,1,1,3,3,3,3,1,3,1,1,3,3,3,3,3,3,1,1,3,1,3,1,1,3,1,
- 1,1,1,3,3,1,1,3,1,1,1,3,1,3,1,1,3,3,1,3,1,1,3,3,3,3,3,1,3,1,
- 1,1,3,1,1,1,3,1,1,3,1,3,3,3,3,3,1,1,1,3,3,3,3,1,3,3,3,3,1,1,
- 3,3,3,1,3,1,1,3,3,1,3,3,1,1,1,1,1,3,1,1,3,3,1,1,1,3,1,1,3,3,
- 1,3,3,3,3,3,3,3,3,1,1,3,3,1,1,3,1,3,3,3,3,3,1},
- /* [2][*] */
- { 0,0,
- 7,5,1,3,3,7,5,5,7,7,1,3,3,7,5,1,1,5,3,7,
- 1,7,5,1,3,7,7,1,1,1,5,7,7,5,1,3,3,7,5,5,5,3,3,3,1,1,5,1,1,5,
- 3,3,3,3,1,3,7,5,7,3,7,1,3,3,5,1,3,5,5,7,7,7,1,1,3,3,1,1,5,1,
- 5,7,5,1,7,5,3,3,1,5,7,1,7,5,1,7,3,1,7,1,7,3,3,5,7,3,3,5,1,3,
- 3,1,3,5,1,3,3,3,7,1,1,7,3,1,3,7,5,5,7,5,5,3,1,3,3,3,1,3,3,7,
- 3,3,1,7,5,1,7,7,5,7,5,1,3,1,7,3,7,3,5,7,3,1,3,3,3,1,5,7,3,3,
- 7,7,7,5,3,1,7,1,3,7,5,3,3,3,7,1,1,3,1,5,7,1,3,5,3,5,3,3,7,5,
- 5,3,3,1,3,7,7,7,1,5,7,1,3,1,1,7,1,3,1,7,1,5,3,5,3,1,1,5,5,3,
- 3,5,7,1,5,3,7,7,3,5,3,3,1,7,3,1,3,5,7,1,3,7,1,5,1,3,1,5,3,1,
- 7,1,5,5,5,3,7,1,1,7,3,1,1,7,5,7,5,7,7,3,7,1,3,7,7,3,5,1,1,7,
- 1,5,5,5,1,5,1,7,5,5,7,1,1,7,1,7,7,1,1,3,3,3,7,7,5,3,7,3,1,3,
- 7,5,3,3,5,7,1,1,5,5,7,7,1,1,1,1,5,5,5,7,5,7,1,1,3,5,1,3,3,7,
- 3,7,5,3,5,3,1,7,1,7,7,1,1,7,7,7,5,5,1,1,7,5,5,7,5,1,1,5,5,5,
- 5,5,5,1,3,1,5,7,3,3,5,7,3,7,1,7,7,1,3,
- 5,1,5,5,3,7,3,7,7,5,7,5,7,1,1,5,3,5,1,
- 5,3,7,1,5,7,7,3,5,1,3,5,1,5,3,3,3,7,3,5,1,3,7,7,3,7,5,3,3,1,
- 7,5,1,1,3,7,1,7,1,7,3,7,3,5,7,3,5,3,1,1,1,5,7,7,3,3,1,1,1,5,
- 5,7,3,1,1,3,3,7,3,3,5,1,3,7,3,3,7,3,5,7,5,7,7,3,3,5,1,3,5,3,
- 1,3,5,1,1,3,7,7,1,5,1,3,7,3,7,3,5,1,7,1,1,3,5,3,7,1,5,5,1,1,
- 3,1,3,3,7,1,7,3,1,7,3,1,7,3,5,3,5,7,3,3,3,5,1,7,7,1,3,1,3,7,
- 7,1,3,7,3,1,5,3,1,1,1,5,3,3,7,1,5,3,5,1,3,1,3,1,5,7,7,1,1,5,
- 3,1,5,1,1,7,7,3,5,5,1,7,1,5,1,1,3,1,5,7,5,7,7,1,5,1,1,3,5,1,
- 5,5,3,1,3,1,5,5,3,3,3,3,1,1,3,1,3,5,5,7,5,5,7,5,7,1,3,7,7,3,
- 5,5,7,5,5,3,3,3,1,7,1,5,5,5,3,3,5,1,3,1,3,3,3,7,1,7,7,3,7,1,
- 1,5,7,1,7,1,7,7,1,3,7,5,1,3,5,5,5,1,1,7,1,7,1,7,7,3,1,1,5,1,
- 5,1,5,3,5,5,5,5,5,3,3,7,3,3,5,5,3,7,1,5,7,5,1,5,5,3,5,5,7,5,
- 3,5,5,5,1,5,5,5,5,1,3,5,3,1,7,5,5,7,1,5,3,3,1,5,3,7,1,7,5,1,
- 1,3,1,1,7,1,5,5,3,7,3,7,5,3,1,1,3,1,3,5,
- 5,7,5,3,7,7,7,3,7,3,7,1,3,1,7,7,1,7,
- 3,7,3,7,3,7,3,5,1,1,7,3,1,5,5,7,1,5,5,5,7,1,5,5,1,5,5,3,1,3,
- 1,7,3,1,3,5,7,7,7,1,1,7,3,1,5,5,5,1,1,1,1,1,5,3,5,1,3,5,3,1,
- 1,1,1,3,7,3,7,5,7,1,5,5,7,5,3,3,7,5,3,1,1,3,1,3,1,1,3,7,1,7,
- 1,1,5,1,7,5,3,7,3,5,3,1,1,5,5,1,7,7,3,7,3,7,1,5,1,5,3,7,3,5,
- 7,7,7,3,3,1,1,5,5,3,7,1,1,1,3,5,3,1,1,3,3,7,5,1,1,3,7,1,5,7,
- 3,7,5,5,7,3,5,3,1,5,3,1,1,7,5,1,7,3,7,5,1,7,1,7,7,1,1,7,1,5,
- 5,1,1,7,5,7,1,5,3,5,3,3,7,1,5,1,1,5,5,3,3,7,5,5,1,1,1,3,1,5,
- 7,7,1,7,5,7,3,7,3,1,3,7,3,1,5,5,3,5,1,3,5,5,5,1,1,7,7,1,5,5,
- 1,3,5,1,5,3,5,3,3,7,5,7,3,7,3,1,3,7,7,3,3,1,1,3,3,3,3,3,5,5,
- 3,3,3,1,3,5,7,7,1,5,7,3,7,1,1,3,5,7,5,3,3,3},
- /* [3][*] */
- { 0,0,0,0,
- 1,7,9,13,11,1,3,7,9,5,13,13,11,3,15,5,3,
- 15,7,9,13,9,1,11,7,5,15,1,15,11,5,11,1,7,9,7,7,1,15,15,15,13,
- 3,3,15,5,9,7,13,3,7,5,11,9,1,9,1,5,7,13,9,9,1,7,3,5,1,11,11,
- 13,7,7,9,9,1,1,3,9,15,1,5,13,1,9,9,9,9,9,13,11,3,5,11,11,13,
- 5,3,15,1,11,11,7,13,15,11,13,9,11,15,15,13,3,15,7,9,11,13,11,
- 9,9,5,13,9,1,13,7,7,7,7,7,5,9,7,13,11,9,11,15,3,13,11,1,11,3,
- 3,9,11,1,7,1,15,15,3,1,9,1,7,13,11,3,13,11,7,3,3,5,13,11,5,
- 11,1,3,9,7,15,7,5,13,7,9,13,15,13,9,7,15,7,9,5,11,11,13,13,9,
- 3,5,13,9,11,15,11,7,1,7,13,3,13,3,13,9,15,7,13,13,3,13,15,15,
- 11,9,13,9,15,1,1,15,11,11,7,1,11,13,9,13,3,5,11,13,9,9,13,1,
- 11,15,13,3,13,7,15,1,15,3,3,11,7,13,7,7,9,7,5,15,9,5,5,7,15,
- 13,15,5,15,5,3,1,11,7,1,5,7,9,3,11,1,15,1,3,15,11,13,5,13,1,
- 7,1,15,7,5,1,1,15,13,11,11,13,5,11,7,9,7,1,5,3,9,5,5,11,5,1,
- 7,1,11,7,9,13,15,13,3,1,11,13,15,1,1,11,9,13,3,13,11,15,13,9,
- 9,9,5,5,5,5,1,15,5,9,
- 11,7,15,5,3,13,5,3,11,5,1,11,13,9,11,
- 3,7,13,15,1,7,11,1,13,1,15,1,9,7,3,9,11,1,9,13,13,3,11,7,9,1,
- 7,15,9,1,5,13,5,11,3,9,15,11,13,5,1,7,7,5,13,7,7,9,5,11,11,1,
- 1,15,3,13,9,13,9,9,11,5,5,13,15,3,9,15,3,11,11,15,15,3,11,15,
- 15,3,1,3,1,3,3,1,3,13,1,11,5,15,7,15,9,1,7,1,9,11,15,1,13,9,
- 13,11,7,3,7,3,13,7,9,7,7,3,3,9,9,7,5,11,13,13,7,7,15,9,5,5,3,
- 3,13,3,9,3,1,11,1,3,11,15,11,11,11,9,13,7,9,15,9,11,1,3,3,9,
- 7,15,13,13,7,15,9,13,9,15,13,15,9,13,1,11,7,11,3,13,5,1,7,15,
- 3,13,7,13,13,11,3,5,3,13,11,9,9,3,11,11,7,9,13,11,7,15,13,7,
- 5,3,1,5,15,15,3,11,1,7,3,15,11,5,5,3,5,5,1,15,5,1,5,3,7,5,11,
- 3,13,9,13,15,5,3,5,9,5,3,11,1,13,9,15,3,5,11,9,1,3,15,9,9,9,
- 11,7,5,13,1,15,3,13,9,13,5,1,5,1,13,13,7,7,1,9,5,11,9,11,13,
- 3,15,15,13,15,7,5,7,9,7,9,9,9,11,9,3,11,15,13,13,5,9,15,1,1,
- 9,5,13,3,13,15,3,1,3,11,13,1,15,9,9,3,1,9,1,9,1,13,11,15,7,
- 11,15,13,15,1,9,9,7,
- 3,5,11,7,3,9,5,15,7,5,3,13,7,1,1,9,
- 15,15,15,11,3,5,15,13,7,15,15,11,11,9,5,15,9,7,3,13,1,1,5,1,
- 3,1,7,1,1,5,1,11,11,9,9,5,13,7,7,7,1,1,9,9,11,11,15,7,5,5,3,
- 11,1,3,7,13,7,7,7,3,15,15,11,9,3,9,3,15,13,5,3,3,3,5,9,15,9,
- 9,1,5,9,9,15,5,15,7,9,1,9,9,5,11,5,15,15,11,7,7,7,1,1,11,11,
- 13,15,3,13,5,1,7,1,11,3,13,15,3,5,3,5,7,3,9,9,5,1,7,11,9,3,5,
- 11,13,13,13,9,15,5,7,1,15,11,9,15,15,13,13,13,1,11,9,15,9,5,
- 15,5,7,3,11,3,15,7,13,11,7,3,7,13,5,13,15,5,13,9,1,15,11,5,5,
- 1,11,3,3,7,1,9,7,15,9,9,3,11,15,7,1,3,1,1,1,9,1,5,15,15,7,5,
- 5,7,9,7,15,13,13,11,1,9,11,1,13,1,7,15,15,5,5,1,11,3,9,11,9,
- 9,9,1,9,3,5,15,1,1,9,7,3,3,1,9,9,11,9,9,13,13,3,13,11,13,5,1,
- 5,5,9,9,3,13,13,9,15,9,11,7,11,9,13,9,1,15,9,7,7,1,7,9,9,15,
- 1,11,1,13,13,15,9,13,7,15,3,9,3,1,13,7,5,9,3,1,7,1,1,13,3,3,
- 11,1,7,13,15,15,5,7,13,13,15,11,13,1,13,13,3,9,15,15,11,15,9,
- 15,1,13,15,1,1,5,
- 11,5,1,11,11,5,3,9,1,3,5,13,9,7,7,1,
- 9,9,15,7,5,5,15,13,9,7,13,3,13,11,13,7,9,13,13,13,15,9,5,5,3,
- 3,3,1,3,15},
- /* [4][*] */
- { 0,0,0,0,0,0,
- 9,3,27,15,29,21,23,19,11,25,7,13,17,1,
- 25,29,3,31,11,5,23,27,19,21,5,1,17,13,7,15,9,31,25,3,5,23,7,
- 3,17,23,3,3,21,25,25,23,11,19,3,11,31,7,9,5,17,23,17,17,25,
- 13,11,31,27,19,17,23,7,5,11,19,19,7,13,21,21,7,9,11,1,5,21,
- 11,13,25,9,7,7,27,15,25,15,21,17,19,19,21,5,11,3,5,29,31,29,
- 5,5,1,31,27,11,13,1,3,7,11,7,3,23,13,31,17,1,27,11,25,1,23,
- 29,17,25,7,25,27,17,13,17,23,5,17,5,13,11,21,5,11,5,9,31,19,
- 17,9,9,27,21,15,15,1,1,29,5,31,11,17,23,19,21,25,15,11,5,5,1,
- 19,19,19,7,13,21,17,17,25,23,19,23,15,13,5,19,25,9,7,3,21,17,
- 25,1,27,25,27,25,9,13,3,17,25,23,9,25,9,13,17,17,3,15,7,7,29,
- 3,19,29,29,19,29,13,15,25,27,1,3,9,9,13,31,29,31,5,15,29,1,
- 19,5,9,19,5,15,3,5,7,15,17,17,23,11,9,23,19,3,17,1,27,9,9,17,
- 13,25,29,23,29,11,31,25,21,29,19,27,31,3,5,3,3,13,21,9,29,3,
- 17,11,11,9,21,19,7,17,31,25,1,27,5,15,27,29,29,29,25,27,25,3,
- 21,17,25,13,15,17,13,23,9,3,11,7,9,9,7,17,7,1,
- 27,1,9,5,31,21,25,25,21,11,1,23,19,27,
- 15,3,5,23,9,25,7,29,11,9,13,5,11,1,3,31,27,3,17,27,11,13,15,
- 29,15,1,15,23,25,13,21,15,3,29,29,5,25,17,11,7,15,5,21,7,31,
- 13,11,23,5,7,23,27,21,29,15,7,27,27,19,7,15,27,27,19,19,9,15,
- 1,3,29,29,5,27,31,9,1,7,3,19,19,29,9,3,21,31,29,25,1,3,9,27,
- 5,27,25,21,11,29,31,27,21,29,17,9,17,13,11,25,15,21,11,19,31,
- 3,19,5,3,3,9,13,13,3,29,7,5,9,23,13,21,23,21,31,11,7,7,3,23,
- 1,23,5,9,17,21,1,17,29,7,5,17,13,25,17,9,19,9,5,7,21,19,13,9,
- 7,3,9,3,15,31,29,29,25,13,9,21,9,31,7,15,5,31,7,15,27,25,19,
- 9,9,25,25,23,1,9,7,11,15,19,15,27,17,11,11,31,13,25,25,9,7,
- 13,29,19,5,19,31,25,13,25,15,5,9,29,31,9,29,27,25,27,11,17,5,
- 17,3,23,15,9,9,17,17,31,11,19,25,13,23,15,25,21,31,19,3,11,
- 25,7,15,19,7,5,3,13,13,1,23,5,25,11,25,15,13,21,11,23,29,5,
- 17,27,9,19,15,5,29,23,19,1,27,3,23,21,19,27,11,17,13,27,11,
- 31,23,5,9,21,31,29,11,21,17,15,7,15,7,9,21,27,25,
- 29,11,3,21,13,23,19,27,17,29,25,17,9,
- 1,19,23,5,23,1,17,17,13,27,23,7,7,11,13,17,13,11,21,13,23,1,
- 27,13,9,7,1,27,29,5,13,25,21,3,31,15,13,3,19,13,1,27,15,17,1,
- 3,13,13,13,31,29,27,7,7,21,29,15,17,17,21,19,17,3,15,5,27,27,
- 3,31,31,7,21,3,13,11,17,27,25,1,9,7,29,27,21,23,13,25,29,15,
- 17,29,9,15,3,21,15,17,17,31,9,9,23,19,25,3,1,11,27,29,1,31,
- 29,25,29,1,23,29,25,13,3,31,25,5,5,11,3,21,9,23,7,11,23,11,1,
- 1,3,23,25,23,1,23,3,27,9,27,3,23,25,19,29,29,13,27,5,9,29,29,
- 13,17,3,23,19,7,13,3,19,23,5,29,29,13,13,5,19,5,17,9,11,11,
- 29,27,23,19,17,25,13,1,13,3,11,1,17,29,1,13,17,9,17,21,1,11,
- 1,1,25,5,7,29,29,19,19,1,29,13,3,1,31,15,13,3,1,11,19,5,29,
- 13,29,23,3,1,31,13,19,17,5,5,1,29,23,3,19,25,19,27,9,27,13,
- 15,29,23,13,25,25,17,19,17,15,27,3,25,17,27,3,27,31,23,13,31,
- 11,15,7,21,19,27,19,21,29,7,31,13,9,9,7,21,13,11,9,11,29,19,
- 11,19,21,5,29,13,7,19,19,27,23,31,1,27,21,7,3,7,11,
- 23,13,29,11,31,19,1,5,5,11,5,3,27,5,
- 7,11,31,1,27,31,31,23,5,21,27,9,25,3,15,19,1,19,9,5,25,21,15,
- 25,29,15,21,11,19,15,3,7,13,11,25,17,1,5,31,13,29,23,9,5,29,
- 7,17,27,7,17,31,9,31,9,9,7,21,3,3,3,9,11,21,11,31,9,25,5,1,
- 31,13,29,9,29,1,11,19,7,27,13,31,7,31,7,25,23,21,29,11,11,13,
- 11,27,1,23,31,21,23,21,19,31,5,31,25,25,19,17,11,25,7,13,1,
- 29,17,23,15,7,29,17,13,3,17},
- /* [5][*] */
- { 0,0,0,0,0,0,0,0,0,0,0,0,
- 37,33,7,5,11,39,63,59,17,15,23,29,3,21,
- 13,31,25,9,49,33,19,29,11,19,27,15,25,63,55,17,63,49,19,41,
- 59,3,57,33,49,53,57,57,39,21,7,53,9,55,15,59,19,49,31,3,39,5,
- 5,41,9,19,9,57,25,1,15,51,11,19,61,53,29,19,11,9,21,19,43,13,
- 13,41,25,31,9,11,19,5,53,37,7,51,45,7,7,61,23,45,7,59,41,1,
- 29,61,37,27,47,15,31,35,31,17,51,13,25,45,5,5,33,39,5,47,29,
- 35,47,63,45,37,47,59,21,59,33,51,9,27,13,25,43,3,17,21,59,61,
- 27,47,57,11,17,39,1,63,21,59,17,13,31,3,31,7,9,27,37,23,31,9,
- 45,43,31,63,21,39,51,27,7,53,11,1,59,39,23,49,23,7,55,59,3,
- 19,35,13,9,13,15,23,9,7,43,55,3,19,9,27,33,27,49,23,47,19,7,
- 11,55,27,35,5,5,55,35,37,9,33,29,47,25,11,47,53,61,59,3,53,
- 47,5,19,59,5,47,23,45,53,3,49,61,47,39,29,17,57,5,17,31,23,
- 41,39,5,27,7,29,29,33,31,41,31,29,17,29,29,9,9,31,27,53,35,5,
- 61,1,49,13,57,29,5,21,43,25,57,49,37,27,11,61,37,49,5,63,63,
- 3,45,37,63,21,21,19,27,59,21,45,23,13,15,3,43,63,39,19,
- 63,31,41,41,15,43,63,53,1,63,31,7,17,
- 11,61,31,51,37,29,59,25,63,59,47,15,27,19,29,45,35,55,39,19,
- 43,21,19,13,17,51,37,5,33,35,49,25,45,1,63,47,9,63,15,25,25,
- 15,41,13,3,19,51,49,37,25,49,13,53,47,23,35,29,33,21,35,23,3,
- 43,31,63,9,1,61,43,3,11,55,11,35,1,63,35,49,19,45,9,57,51,1,
- 47,41,9,11,37,19,55,23,55,55,13,7,47,37,11,43,17,3,25,19,55,
- 59,37,33,43,1,5,21,5,63,49,61,21,51,15,19,43,47,17,9,53,45,
- 11,51,25,11,25,47,47,1,43,29,17,31,15,59,27,63,11,41,51,29,7,
- 27,63,31,43,3,29,39,3,59,59,1,53,63,23,63,47,51,23,61,39,47,
- 21,39,15,3,9,57,61,39,37,21,51,1,23,43,27,25,11,13,21,43,7,
- 11,33,55,1,37,35,27,61,39,5,19,61,61,57,59,21,59,61,57,25,55,
- 27,31,41,33,63,19,57,35,13,63,35,17,11,11,49,41,55,5,45,17,
- 35,5,31,31,37,17,45,51,1,39,49,55,19,41,13,5,51,5,49,1,21,13,
- 17,59,51,11,3,61,1,33,37,33,61,25,27,59,7,49,13,63,3,33,3,15,
- 9,13,35,39,11,59,59,1,57,11,5,57,13,31,13,11,55,45,9,55,55,
- 19,25,41,23,45,29,63,59,27,39,21,37,7,
- 61,49,35,39,9,29,7,25,23,57,5,19,15,33,49,37,25,17,45,29,15,
- 25,3,3,49,11,39,15,19,57,39,15,11,3,57,31,55,61,19,5,41,35,
- 59,61,39,41,53,53,63,31,9,59,13,35,55,41,49,5,41,25,27,43,5,
- 5,43,5,5,17,5,15,27,29,17,9,3,55,31,1,45,45,13,57,17,3,61,15,
- 49,15,47,9,37,45,9,51,61,21,33,11,21,63,63,47,57,61,49,9,59,
- 19,29,21,23,55,23,43,41,57,9,39,27,41,35,61,29,57,63,21,31,
- 59,35,49,3,49,47,49,33,21,19,21,35,11,17,37,23,59,13,37,35,
- 55,57,1,29,45,11,1,15,9,33,19,53,43,39,23,7,13,13,1,19,41,55,
- 1,13,15,59,55,15,3,57,37,31,17,1,3,21,29,25,55,9,37,33,53,41,
- 51,19,57,13,63,43,19,7,13,37,33,19,15,63,51,11,49,23,57,47,
- 51,15,53,41,1,15,37,61,11,35,29,33,23,55,11,59,19,61,61,45,
- 13,49,13,63,5,61,5,31,17,61,63,13,27,57,1,21,5,11,39,57,51,
- 53,39,25,41,39,37,23,31,25,33,17,57,29,27,23,47,41,29,19,47,
- 41,25,5,51,43,39,29,7,31,45,51,49,55,17,43,49,45,9,29,3,5,47,
- 9,15,19,
- 51,45,57,63,9,21,59,3,9,13,45,23,15,
- 31,21,15,51,35,9,11,61,23,53,29,51,45,31,29,5,35,29,53,35,17,
- 59,55,27,51,59,27,47,15,29,37,7,49,55,5,19,45,29,19,57,33,53,
- 45,21,9,3,35,29,43,31,39,3,45,1,41,29,5,59,41,33,35,27,19,13,
- 25,27,43,33,35,17,17,23,7,35,15,61,61,53,5,15,23,11,13,43,55,
- 47,25,43,15,57,45,1,49,63,57,15,31,31,7,53,27,15,47,23,7,29,
- 53,47,9,53,3,25,55,45,63,21,17,23,31,27,27,43,63,55,63,45,51,
- 15,27,5,37,43,11,27,5,27,59,21,7,39,27,63,35,47,55,17,17,17,
- 3,19,21,13,49,61,39,15},
- /* [6][*] */
- { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 13,33,115,41,79,17,29,119,75,73,105,7,
- 59,65,21,3,113,61,89,45,107,21,71,79,19,71,61,41,57,121,87,
- 119,55,85,121,119,11,23,61,11,35,33,43,107,113,101,29,87,119,
- 97,29,17,89,5,127,89,119,117,103,105,41,83,25,41,55,69,117,
- 49,127,29,1,99,53,83,15,31,73,115,35,21,89,5,1,91,53,35,95,
- 83,19,85,55,51,101,33,41,55,45,95,61,27,37,89,75,57,61,15,
- 117,15,21,27,25,27,123,39,109,93,51,21,91,109,107,45,15,93,
- 127,3,53,81,79,107,79,87,35,109,73,35,83,107,1,51,7,59,33,
- 115,43,111,45,121,105,125,87,101,41,95,75,1,57,117,21,27,67,
- 29,53,117,63,1,77,89,115,49,127,15,79,81,29,65,103,33,73,79,
- 29,21,113,31,33,107,95,111,59,99,117,63,63,99,39,9,35,63,125,
- 99,45,93,33,93,9,105,75,51,115,11,37,17,41,21,43,73,19,93,7,
- 95,81,93,79,81,55,9,51,63,45,89,73,19,115,39,47,81,39,5,5,45,
- 53,65,49,17,105,13,107,5,5,19,73,59,43,83,97,115,27,1,69,103,
- 3,99,103,63,67,25,121,97,77,13,83,103,41,11,27,81,37,33,125,
- 71,41,41,59,41,87,123,
- 43,101,63,45,39,21,97,15,97,111,21,49,
- 13,17,79,91,65,105,75,1,45,67,83,107,125,87,15,81,95,105,65,
- 45,59,103,23,103,99,67,99,47,117,71,89,35,53,73,9,115,49,37,
- 1,35,9,45,81,19,127,17,17,105,89,49,101,7,37,33,11,95,95,17,
- 111,105,41,115,5,69,101,27,27,101,103,53,9,21,43,79,91,65,
- 117,87,125,55,45,63,85,83,97,45,83,87,113,93,95,5,17,77,77,
- 127,123,45,81,85,121,119,27,85,41,49,15,107,21,51,119,11,87,
- 101,115,63,63,37,121,109,7,43,69,19,77,49,71,59,35,7,13,55,
- 101,127,103,85,109,29,61,67,21,111,67,23,57,75,71,101,123,41,
- 107,101,107,125,27,47,119,41,19,127,33,31,109,7,91,91,39,125,
- 105,47,125,123,91,9,103,45,23,117,9,125,73,11,37,61,79,21,5,
- 47,117,67,53,85,33,81,121,47,61,51,127,29,65,45,41,95,57,73,
- 33,117,61,111,59,123,65,47,105,23,29,107,37,81,67,29,115,119,
- 75,73,99,103,7,57,45,61,95,49,101,101,35,47,119,39,67,31,103,
- 7,61,127,87,3,35,29,73,95,103,71,75,51,87,57,97,11,105,87,41,
- 73,109,69,35,121,39,111,1,77,
- 39,47,53,91,3,17,51,83,39,125,85,111,
- 21,69,85,29,55,11,117,1,47,17,65,63,47,117,17,115,51,25,33,
- 123,123,83,51,113,95,121,51,91,109,43,55,35,55,87,33,37,5,3,
- 45,21,105,127,35,17,35,37,97,97,21,77,123,17,89,53,105,75,25,
- 125,13,47,21,125,23,55,63,61,5,17,93,57,121,69,73,93,121,105,
- 75,91,67,95,75,9,69,97,99,93,11,53,19,73,5,33,79,107,65,69,
- 79,125,25,93,55,61,17,117,69,97,87,111,37,93,59,79,95,53,115,
- 53,85,85,65,59,23,75,21,67,27,99,79,27,3,95,27,69,19,75,47,
- 59,41,85,77,99,55,49,93,93,119,51,125,63,13,15,45,61,19,105,
- 115,17,83,7,7,11,61,37,63,89,95,119,113,67,123,91,33,37,99,
- 43,11,33,65,81,79,81,107,63,63,55,89,91,25,93,101,27,55,75,
- 121,79,43,125,73,27,109,35,21,71,113,89,59,95,41,45,113,119,
- 113,39,59,73,15,13,59,67,121,27,7,105,15,59,59,35,91,89,23,
- 125,97,53,41,91,111,29,31,3,103,61,71,35,7,119,29,45,49,111,
- 41,109,59,125,13,27,19,79,9,75,83,81,33,91,109,33,29,107,111,
- 101,107,109,65,59,43,37,
- 1,9,15,109,37,111,113,119,79,73,65,
- 71,93,17,101,87,97,43,23,75,109,41,49,53,31,97,105,109,119,
- 51,9,53,113,97,73,89,79,49,61,105,13,99,53,71,7,87,21,101,5,
- 71,31,123,121,121,73,79,115,13,39,101,19,37,51,83,97,55,81,
- 91,127,105,89,63,47,49,75,37,77,15,49,107,23,23,35,19,69,17,
- 59,63,73,29,125,61,65,95,101,81,57,69,83,37,11,37,95,1,73,27,
- 29,57,7,65,83,99,69,19,103,43,95,25,19,103,41,125,97,71,105,
- 83,83,61,39,9,45,117,63,31,5,117,67,125,41,117,43,77,97,15,
- 29,5,59,25,63,87,39,39,77,85,37,81,73,89,29,125,109,21,23,
- 119,105,43,93,97,15,125,29,51,69,37,45,31,75,109,119,53,5,
- 101,125,121,35,29,7,63,17,63,13,69,15,105,51,127,105,9,57,95,
- 59,109,35,49,23,33,107,55,33,57,79,73,69,59,107,55,11,63,95,
- 103,23,125,91,31,91,51,65,61,75,69,107,65,101,59,35,15},
- /* [7][*] */
- { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 7,23,39,217,141,27,53,181,169,35,15,
- 207,45,247,185,117,41,81,223,151,81,189,61,95,185,23,73,113,
- 239,85,9,201,83,53,183,203,91,149,101,13,111,239,3,205,253,
- 247,121,189,169,179,197,175,217,249,195,95,63,19,7,5,75,217,
- 245,111,189,165,169,141,221,249,159,253,207,249,219,23,49,
- 127,237,5,25,177,37,103,65,167,81,87,119,45,79,143,57,79,187,
- 143,183,75,97,211,149,175,37,135,189,225,241,63,33,43,13,73,
- 213,57,239,183,117,21,29,115,43,205,223,15,3,159,51,101,127,
- 99,239,171,113,171,119,189,245,201,27,185,229,105,153,189,33,
- 35,137,77,97,17,181,55,197,201,155,37,197,137,223,25,179,91,
- 23,235,53,253,49,181,249,53,173,97,247,67,115,103,159,239,69,
- 173,217,95,221,247,97,91,123,223,213,129,181,87,239,85,89,
- 249,141,39,57,249,71,101,159,33,137,189,71,253,205,171,13,
- 249,109,131,199,189,179,31,99,113,41,173,23,189,197,3,135,9,
- 95,195,27,183,1,123,73,53,99,197,59,27,101,55,193,31,61,119,
- 11,7,255,233,53,157,193,97,83,65,81,239,167,69,71,109,
- 97,137,71,193,189,115,79,205,37,227,
- 53,33,91,229,245,105,77,229,161,103,93,13,161,229,223,69,15,
- 25,23,233,93,25,217,247,61,75,27,9,223,213,55,197,145,89,199,
- 41,201,5,149,35,119,183,53,11,13,3,179,229,43,55,187,233,47,
- 133,91,47,71,93,105,145,45,255,221,115,175,19,129,5,209,197,
- 57,177,115,187,119,77,211,111,33,113,23,87,137,41,7,83,43,
- 121,145,5,219,27,11,111,207,55,97,63,229,53,33,149,23,187,
- 153,91,193,183,59,211,93,139,59,179,163,209,77,39,111,79,229,
- 85,237,199,137,147,25,73,121,129,83,87,93,205,167,53,107,229,
- 213,95,219,109,175,13,209,97,61,147,19,13,123,73,35,141,81,
- 19,171,255,111,107,233,113,133,89,9,231,95,69,33,1,253,219,
- 253,247,129,11,251,221,153,35,103,239,7,27,235,181,5,207,53,
- 149,155,225,165,137,155,201,97,245,203,47,39,35,105,239,49,
- 15,253,7,237,213,55,87,199,27,175,49,41,229,85,3,149,179,129,
- 185,249,197,15,97,197,139,203,63,33,251,217,199,199,99,249,
- 33,229,177,13,209,147,97,31,125,177,137,
- 187,11,91,223,29,169,231,59,31,163,41,
- 57,87,247,25,127,101,207,187,73,61,105,27,91,171,243,33,3,1,
- 21,229,93,71,61,37,183,65,211,53,11,151,165,47,5,129,79,101,
- 147,169,181,19,95,77,139,197,219,97,239,183,143,9,13,209,23,
- 215,53,137,203,19,151,171,133,219,231,3,15,253,225,33,111,
- 183,213,169,119,111,15,201,123,121,225,113,113,225,161,165,1,
- 139,55,3,93,217,193,97,29,69,231,161,93,69,143,137,9,87,183,
- 113,183,73,215,137,89,251,163,41,227,145,57,81,57,11,135,145,
- 161,175,159,25,55,167,157,211,97,247,249,23,129,159,71,197,
- 127,141,219,5,233,131,217,101,131,33,157,173,69,207,239,81,
- 205,11,41,169,65,193,77,201,173,1,221,157,1,15,113,147,137,
- 205,225,73,45,49,149,113,253,99,17,119,105,117,129,243,75,
- 203,53,29,247,35,247,171,31,199,213,29,251,7,251,187,91,11,
- 149,13,205,37,249,137,139,9,7,113,183,205,187,39,3,79,155,
- 227,89,185,51,127,63,83,41,133,183,181,127,19,255,219,59,251,
- 3,187,57,217,115,217,229,181,185,149,83,115,11,
- 123,19,109,165,103,123,219,129,155,
- 207,177,9,49,181,231,33,233,67,155,41,9,95,123,65,117,249,85,
- 169,129,241,173,251,225,147,165,69,81,239,95,23,83,227,249,
- 143,171,193,9,21,57,73,97,57,29,239,151,159,191,47,51,1,223,
- 251,251,151,41,119,127,131,33,209,123,53,241,25,31,183,107,
- 25,115,39,11,213,239,219,109,185,35,133,123,185,27,55,245,61,
- 75,205,213,169,163,63,55,49,83,195,51,31,41,15,203,41,63,127,
- 161,5,143,7,199,251,95,75,101,15,43,237,197,117,167,155,21,
- 83,205,255,49,101,213,237,135,135,21,73,93,115,7,85,223,237,
- 79,89,5,57,239,67,65,201,155,71,85,195,89,181,119,135,147,
- 237,173,41,155,67,113,111,21,183,23,103,207,253,69,219,205,
- 195,43,197,229,139,177,129,69,97,201,163,189,11,99,91,253,
- 239,91,145,19,179,231,121,7,225,237,125,191,119,59,175,237,
- 131,79,43,45,205,199,251,153,207,37,179,113,255,107,217,61,7,
- 181,247,31,13,113,145,107,233,233,43,79,23,169,137,129,183,
- 53,91,55,103,223,87,177,157,79,213,139,
- 183,231,205,143,129,243,205,93,59,
- 15,89,9,11,47,133,227,75,9,91,19,171,163,79,7,103,5,119,155,
- 75,11,71,95,17,13,243,207,187},
- /* [8][*] */
- { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 235,307,495,417,57,151,19,119,375,451,
- 55,449,501,53,185,317,17,21,487,13,347,393,15,391,307,189,
- 381,71,163,99,467,167,433,337,257,179,47,385,23,117,369,425,
- 207,433,301,147,333,85,221,423,49,3,43,229,227,201,383,281,
- 229,207,21,343,251,397,173,507,421,443,399,53,345,77,385,317,
- 155,187,269,501,19,169,235,415,61,247,183,5,257,401,451,95,
- 455,49,489,75,459,377,87,463,155,233,115,429,211,419,143,487,
- 195,209,461,193,157,193,363,181,271,445,381,231,135,327,403,
- 171,197,181,343,113,313,393,311,415,267,247,425,233,289,55,
- 39,247,327,141,5,189,183,27,337,341,327,87,429,357,265,251,
- 437,201,29,339,257,377,17,53,327,47,375,393,369,403,125,429,
- 257,157,217,85,267,117,337,447,219,501,41,41,193,509,131,207,
- 505,421,149,111,177,167,223,291,91,29,305,151,177,337,183,
- 361,435,307,507,77,181,507,315,145,423,71,103,493,271,469,
- 339,237,437,483,31,219,61,131,391,233,219,69,57,459,225,421,
- 7,461,111,451,277,185,193,125,251,199,73,71,7,409,417,149,
- 193,53,437,29,467,229,31,35,75,105,
- 503,75,317,401,367,131,365,441,433,93,377,405,465,259,283,
- 443,143,445,3,461,329,309,77,323,155,347,45,381,315,463,207,
- 321,157,109,479,313,345,167,439,307,235,473,79,101,245,19,
- 381,251,35,25,107,187,115,113,321,115,445,61,77,293,405,13,
- 53,17,171,299,41,79,3,485,331,13,257,59,201,497,81,451,199,
- 171,81,253,365,75,451,149,483,81,453,469,485,305,163,401,15,
- 91,3,129,35,239,355,211,387,101,299,67,375,405,357,267,363,
- 79,83,437,457,39,97,473,289,179,57,23,49,79,71,341,287,95,
- 229,271,475,49,241,261,495,353,381,13,291,37,251,105,399,81,
- 89,265,507,205,145,331,129,119,503,249,1,289,463,163,443,63,
- 123,361,261,49,429,137,355,175,507,59,277,391,25,185,381,197,
- 39,5,429,119,247,177,329,465,421,271,467,151,45,429,137,471,
- 11,17,409,347,199,463,177,11,51,361,95,497,163,351,127,395,
- 511,327,353,49,105,151,321,331,329,509,107,109,303,467,287,
- 161,45,385,289,363,331,265,407,37,433,315,343,63,51,185,71,
- 27,267,
- 503,239,293,245,281,297,75,461,371,
- 129,189,189,339,287,111,111,379,93,27,185,347,337,247,507,
- 161,231,43,499,73,327,263,331,249,493,37,25,115,3,167,197,
- 127,357,497,103,125,191,165,55,101,95,79,351,341,43,125,135,
- 173,289,373,133,421,241,281,213,177,363,151,227,145,363,239,
- 431,81,397,241,67,291,255,405,421,399,75,399,105,329,41,425,
- 7,283,375,475,427,277,209,411,3,137,195,289,509,121,55,147,
- 275,251,19,129,285,415,487,491,193,219,403,23,97,65,285,75,
- 21,373,261,339,239,495,415,333,107,435,297,213,149,463,199,
- 323,45,19,301,121,499,187,229,63,425,99,281,35,125,349,87,
- 101,59,195,511,355,73,263,243,101,165,141,11,389,219,187,449,
- 447,393,477,305,221,51,355,209,499,479,265,377,145,411,173,
- 11,433,483,135,385,341,89,209,391,33,395,319,451,119,341,227,
- 375,61,331,493,411,293,47,203,375,167,395,155,5,237,361,489,
- 127,21,345,101,371,233,431,109,119,277,125,263,73,135,123,83,
- 123,405,69,75,287,401,23,283,393,41,379,431,11,475,505,19,
- 365,265,271,
- 499,489,443,165,91,83,291,319,199,
- 107,245,389,143,137,89,125,281,381,215,131,299,249,375,455,
- 43,73,281,217,297,229,431,357,81,357,171,451,481,13,387,491,
- 489,439,385,487,177,393,33,71,375,443,129,407,395,127,65,333,
- 309,119,197,435,497,373,71,379,509,387,159,265,477,463,449,
- 47,353,249,335,505,89,141,55,235,187,87,363,93,363,101,67,
- 215,321,331,305,261,411,491,479,65,307,469,415,131,315,487,
- 83,455,19,113,163,503,99,499,251,239,81,167,391,255,317,363,
- 359,395,419,307,251,267,171,461,183,465,165,163,293,477,223,
- 403,389,97,335,357,297,19,469,501,249,85,213,311,265,379,297,
- 283,393,449,463,289,159,289,499,407,129,137,221,43,89,403,
- 271,75,83,445,453,389,149,143,423,499,317,445,157,137,453,
- 163,87,23,391,119,427,323,173,89,259,377,511,249,31,363,229,
- 353,329,493,427,57,205,389,91,83,13,219,439,45,35,371,441,17,
- 267,501,53,25,333,17,201,475,257,417,345,381,377,55,403,77,
- 389,347,363,211,413,419,5,167,219,201,285,425,11,77,269,489,
- 281,403,79,
- 425,125,81,331,437,271,397,299,475,
- 271,249,413,233,261,495,171,69,27,409,21,421,367,81,483,255,
- 15,219,365,497,181,75,431,99,325,407,229,281,63,83,493,5,113,
- 15,271,37,87,451,299,83,451,311,441,47,455,47,253,13,109,369,
- 347,11,409,275,63,441,15},
- /* [9][*] */
- { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 519,307,931,1023,517,771,151,1023,
- 539,725,45,927,707,29,125,371,275,279,817,389,453,989,1015,
- 29,169,743,99,923,981,181,693,309,227,111,219,897,377,425,
- 609,227,19,221,143,581,147,919,127,725,793,289,411,835,921,
- 957,443,349,813,5,105,457,393,539,101,197,697,27,343,515,69,
- 485,383,855,693,133,87,743,747,475,87,469,763,721,345,479,
- 965,527,121,271,353,467,177,245,627,113,357,7,691,725,355,
- 889,635,737,429,545,925,357,873,187,351,677,999,921,477,233,
- 765,495,81,953,479,89,173,473,131,961,411,291,967,65,511,13,
- 805,945,369,827,295,163,835,259,207,331,29,315,999,133,967,
- 41,117,677,471,717,881,755,351,723,259,879,455,721,289,149,
- 199,805,987,851,423,597,129,11,733,549,153,285,451,559,377,
- 109,357,143,693,615,677,701,475,767,85,229,509,547,151,389,
- 711,785,657,319,509,99,1007,775,359,697,677,85,497,105,615,
- 891,71,449,835,609,377,693,665,627,215,911,503,729,131,19,
- 895,199,161,239,633,1013,537,255,23,149,679,1021,595,199,557,
- 659,251,829,727,439,495,647,223,
- 949,625,87,481,85,799,917,769,949,
- 739,115,499,945,547,225,1015,469,737,495,353,103,17,665,639,
- 525,75,447,185,43,729,577,863,735,317,99,17,477,893,537,519,
- 1017,375,297,325,999,353,343,729,135,489,859,267,141,831,141,
- 893,249,807,53,613,131,547,977,131,999,175,31,341,739,467,
- 675,241,645,247,391,583,183,973,433,367,131,467,571,309,385,
- 977,111,917,935,473,345,411,313,97,149,959,841,839,669,431,
- 51,41,301,247,1015,377,329,945,269,67,979,581,643,823,557,91,
- 405,117,801,509,347,893,303,227,783,555,867,99,703,111,797,
- 873,541,919,513,343,319,517,135,871,917,285,663,301,15,763,
- 89,323,757,317,807,309,1013,345,499,279,711,915,411,281,193,
- 739,365,315,375,809,469,487,621,857,975,537,939,585,129,625,
- 447,129,1017,133,83,3,415,661,53,115,903,49,79,55,385,261,
- 345,297,199,385,617,25,515,275,849,401,471,377,661,535,505,
- 939,465,225,929,219,955,659,441,117,527,427,515,287,191,33,
- 389,197,825,63,417,949,35,571,9,131,609,439,95,19,569,893,
- 451,397,971,801,
- 125,471,187,257,67,949,621,453,411,
- 621,955,309,783,893,597,377,753,145,637,941,593,317,555,375,
- 575,175,403,571,555,109,377,931,499,649,653,329,279,271,647,
- 721,665,429,957,803,767,425,477,995,105,495,575,687,385,227,
- 923,563,723,481,717,111,633,113,369,955,253,321,409,909,367,
- 33,967,453,863,449,539,781,911,113,7,219,725,1015,971,1021,
- 525,785,873,191,893,297,507,215,21,153,645,913,755,371,881,
- 113,903,225,49,587,201,927,429,599,513,97,319,331,833,325,
- 887,139,927,399,163,307,803,169,1019,869,537,907,479,335,697,
- 479,353,769,787,1023,855,493,883,521,735,297,1011,991,879,
- 855,591,415,917,375,453,553,189,841,339,211,601,57,765,745,
- 621,209,875,639,7,595,971,263,1009,201,23,77,621,33,535,963,
- 661,523,263,917,103,623,231,47,301,549,337,675,189,357,1005,
- 789,189,319,721,1005,525,675,539,191,813,917,51,167,415,579,
- 755,605,721,837,529,31,327,799,961,279,409,847,649,241,285,
- 545,407,161,591,73,313,811,17,663,269,261,37,783,127,917,231,
- 577,975,793,
- 921,343,751,139,221,79,817,393,545,
- 11,781,71,1,699,767,917,9,107,341,587,903,965,599,507,843,
- 739,579,397,397,325,775,565,925,75,55,979,931,93,957,857,753,
- 965,795,67,5,87,909,97,995,271,875,671,613,33,351,69,811,669,
- 729,401,647,241,435,447,721,271,745,53,775,99,343,451,427,
- 593,339,845,243,345,17,573,421,517,971,499,435,769,75,203,
- 793,985,343,955,735,523,659,703,303,421,951,405,631,825,735,
- 433,841,485,49,749,107,669,211,497,143,99,57,277,969,107,397,
- 563,551,447,381,187,57,405,731,769,923,955,915,737,595,341,
- 253,823,197,321,315,181,885,497,159,571,981,899,785,947,217,
- 217,135,753,623,565,717,903,581,955,621,361,869,87,943,907,
- 853,353,335,197,771,433,743,195,91,1023,63,301,647,205,485,
- 927,1003,987,359,577,147,141,1017,701,273,89,589,487,859,343,
- 91,847,341,173,287,1003,289,639,983,685,697,35,701,645,911,
- 501,705,873,763,745,657,559,699,315,347,429,197,165,955,859,
- 167,303,833,531,473,635,641,195,589,821,205,3,635,371,891,
- 249,123,
- 77,623,993,401,525,427,71,655,951,
- 357,851,899,535,493,323,1003,343,515,859,1017,5,423,315,1011,
- 703,41,777,163,95,831,79,975,235,633,723,297,589,317,679,981,
- 195,399,1003,121,501,155},
- /* [10][*] */
- { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 7,2011,1001,49,825,415,1441,383,1581,
- 623,1621,1319,1387,619,839,217,75,1955,505,281,1629,1379,53,
- 1111,1399,301,209,49,155,1647,631,129,1569,335,67,1955,1611,
- 2021,1305,121,37,877,835,1457,669,1405,935,1735,665,551,789,
- 1543,1267,1027,1,1911,163,1929,67,1975,1681,1413,191,1711,
- 1307,401,725,1229,1403,1609,2035,917,921,1789,41,2003,187,67,
- 1635,717,1449,277,1903,1179,363,1211,1231,647,1261,1029,1485,
- 1309,1149,317,1335,171,243,271,1055,1601,1129,1653,205,1463,
- 1681,1621,197,951,573,1697,1265,1321,1805,1235,1853,1307,945,
- 1197,1411,833,273,1517,1747,1095,1345,869,57,1383,221,1713,
- 335,1751,1141,839,523,1861,1105,389,1177,1877,805,93,1591,
- 423,1835,99,1781,1515,1909,1011,303,385,1635,357,973,1781,
- 1707,1363,1053,649,1469,623,1429,1241,1151,1055,503,921,3,
- 349,1149,293,45,303,877,1565,1583,1001,663,1535,395,1141,
- 1481,1797,643,1507,465,2027,1695,367,937,719,545,1991,83,819,
- 239,1791,1461,1647,1501,1161,1629,139,1595,1921,1267,1415,
- 509,347,777,1083,363,269,1015,
- 1809,1105,1429,1471,2019,381,2025,
- 1223,827,1733,887,1321,803,1951,1297,1995,833,1107,1135,1181,
- 1251,983,1389,1565,273,137,71,735,1005,933,67,1471,551,457,
- 1667,1729,919,285,1629,1815,653,1919,1039,531,393,1411,359,
- 221,699,1485,471,1357,1715,595,1677,153,1903,1281,215,781,
- 543,293,1807,965,1695,443,1985,321,879,1227,1915,839,1945,
- 1993,1165,51,557,723,1491,817,1237,947,1215,1911,1225,1965,
- 1889,1503,1177,73,1767,303,177,1897,1401,321,921,217,1779,
- 327,1889,333,615,1665,1825,1639,237,1205,361,129,1655,983,
- 1089,1171,401,677,643,749,303,1407,1873,1579,1491,1393,1247,
- 789,763,49,5,1607,1891,735,1557,1909,1765,1777,1127,813,695,
- 97,731,1503,1751,333,769,865,693,377,1919,957,1359,1627,1039,
- 1783,1065,1665,1917,1947,991,1997,841,459,221,327,1595,1881,
- 1269,1007,129,1413,475,1105,791,1983,1359,503,691,659,691,
- 343,1375,1919,263,1373,603,1383,297,781,145,285,767,1739,
- 1715,715,317,1333,85,831,1615,81,1667,1467,1457,1453,1825,
- 109,387,1207,2039,213,1351,1329,1173,
- 57,1769,951,183,23,451,1155,1551,
- 2037,811,635,1671,1451,863,1499,1673,363,1029,1077,1525,277,
- 1023,655,665,1869,1255,965,277,1601,329,1603,1901,395,65,
- 1307,2029,21,1321,543,1569,1185,1905,1701,413,2041,1697,725,
- 1417,1847,411,211,915,1891,17,1877,1699,687,1089,1973,1809,
- 851,1495,1257,63,1323,1307,609,881,1543,177,617,1505,1747,
- 1537,925,183,77,1723,1877,1703,397,459,521,257,1177,389,1947,
- 1553,1583,1831,261,485,289,1281,1543,1591,1123,573,821,1065,
- 1933,1373,2005,905,207,173,1573,1597,573,1883,1795,1499,1743,
- 553,335,333,1645,791,871,1157,969,557,141,223,1129,1685,423,
- 1069,391,99,95,1847,531,1859,1833,1833,341,237,1997,1799,409,
- 431,1917,363,335,1039,1085,1657,1975,1527,1111,659,389,899,
- 595,1439,1861,1979,1569,1087,1009,165,1895,1481,1583,29,1193,
- 1673,1075,301,1081,1377,1747,1497,1103,1789,887,739,1577,313,
- 1367,1299,1801,1131,1837,73,1865,1065,843,635,55,1655,913,
- 1037,223,1871,1161,461,479,511,1721,1107,389,151,35,375,1099,
- 937,1185,1701,769,639,1633,
- 1609,379,1613,2031,685,289,975,671,
- 1599,1447,871,647,99,139,1427,959,89,117,841,891,1959,223,
- 1697,1145,499,1435,1809,1413,1445,1675,171,1073,1349,1545,
- 2039,1027,1563,859,215,1673,1919,1633,779,411,1845,1477,1489,
- 447,1545,351,1989,495,183,1639,1385,1805,1097,1249,1431,1571,
- 591,697,1509,709,31,1563,165,513,1425,1299,1081,145,1841,
- 1211,941,609,845,1169,1865,1593,347,293,1277,157,211,93,1679,
- 1799,527,41,473,563,187,1525,575,1579,857,703,1211,647,709,
- 981,285,697,163,981,153,1515,47,1553,599,225,1147,381,135,
- 821,1965,609,1033,983,503,1117,327,453,2005,1257,343,1649,
- 1199,599,1877,569,695,1587,1475,187,973,233,511,51,1083,665,
- 1321,531,1875,1939,859,1507,1979,1203,1965,737,921,1565,1943,
- 819,223,365,167,1705,413,1577,745,1573,655,1633,1003,91,1123,
- 477,1741,1663,35,715,37,1513,815,941,1379,263,1831,1735,1111,
- 1449,353,1941,1655,1349,877,285,1723,125,1753,985,723,175,
- 439,791,1051,1261,717,1555,1757,1777,577,1583,1957,873,331,
- 1163,313,1,1963,963,1905,821,
- 1677,185,709,545,1723,215,1885,
- 1249,583,1803,839,885,485,413,1767,425,129,1035,329,1263,
- 1881,1779,1565,359,367,453,707,1419,831,1889,887,1871,1869,
- 747,223,1547,1799,433,1441,553,2021,1303,1505,1735,1619,1065,
- 1161,2047,347,867,881,1447,329,781,1065,219,589,645,1257,
- 1833,749,1841,1733,1179,1191,1025,1639,1955,1423,1685,1711,
- 493,549,783,1653,397,895,233,759,1505,677,1449,1573,1297,
- 1821,1691,791,289,1187,867,1535,575,183},
- /* [11][*] */
- { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 [...]
- 3915,97,3047,937,2897,953,127,1201,
- 3819,193,2053,3061,3759,1553,2007,2493,603,3343,3751,1059,
- 783,1789,1589,283,1093,3919,2747,277,2605,2169,2905,721,4069,
- 233,261,1137,3993,3619,2881,1275,3865,1299,3757,1193,733,993,
- 1153,2945,3163,3179,437,271,3493,3971,1005,2615,2253,1131,
- 585,2775,2171,2383,2937,2447,1745,663,1515,3767,2709,1767,
- 3185,3017,2815,1829,87,3341,793,2627,2169,1875,3745,367,3783,
- 783,827,3253,2639,2955,3539,1579,2109,379,2939,3019,1999,
- 2253,2911,3733,481,1767,1055,4019,4085,105,1829,2097,2379,
- 1567,2713,737,3423,3941,2659,3961,1755,3613,1937,1559,2287,
- 2743,67,2859,325,2601,1149,3259,2403,3947,2011,175,3389,3915,
- 1315,2447,141,359,3609,3933,729,2051,1755,2149,2107,1741,
- 1051,3681,471,1055,845,257,1559,1061,2803,2219,1315,1369,
- 3211,4027,105,11,1077,2857,337,3553,3503,3917,2665,3823,3403,
- 3711,2085,1103,1641,701,4095,2883,1435,653,2363,1597,767,869,
- 1825,1117,1297,501,505,149,873,2673,551,1499,2793,3277,2143,
- 3663,533,3991,575,1877,1009,3929,473,3009,2595,3249,675,3593,
- 2453,1567,973,595,1335,1715,589,85,
- 2265,3069,461,1659,2627,1307,1731,1501,1699,3545,3803,2157,
- 453,2813,2047,2999,3841,2361,1079,573,69,1363,1597,3427,2899,
- 2771,1327,1117,1523,3521,2393,2537,1979,3179,683,2453,453,
- 1227,779,671,3483,2135,3139,3381,3945,57,1541,3405,3381,2371,
- 2879,1985,987,3017,3031,3839,1401,3749,2977,681,1175,1519,
- 3355,907,117,771,3741,3337,1743,1227,3335,2755,1909,3603,
- 2397,653,87,2025,2617,3257,287,3051,3809,897,2215,63,2043,
- 1757,3671,297,3131,1305,293,3865,3173,3397,2269,3673,717,
- 3041,3341,3595,3819,2871,3973,1129,513,871,1485,3977,2473,
- 1171,1143,3063,3547,2183,3993,133,2529,2699,233,2355,231,
- 3241,611,1309,3829,1839,1495,301,1169,1613,2673,243,3601,
- 3669,2813,2671,2679,3463,2477,1795,617,2317,1855,1057,1703,
- 1761,2515,801,1205,1311,473,3963,697,1221,251,381,3887,1761,
- 3093,3721,2079,4085,379,3601,3845,433,1781,29,1897,1599,2163,
- 75,3475,3957,1641,3911,2959,2833,1279,1099,403,799,2183,2699,
- 1711,2037,727,289,1785,1575,3633,2367,1261,3953,1735,171,
- 1959,
- 2867,859,2951,3211,15,1279,1323,599,
- 1651,3951,1011,315,3513,3351,1725,3793,2399,287,4017,3571,
- 1007,541,3115,429,1585,1285,755,1211,3047,915,3611,2697,2129,
- 3669,81,3939,2437,915,779,3567,3701,2479,3807,1893,3927,2619,
- 2543,3633,2007,3857,3837,487,1769,3759,3105,2727,3155,2479,
- 1341,1657,2767,2541,577,2105,799,17,2871,3637,953,65,69,2897,
- 3841,3559,4067,2335,3409,1087,425,2813,1705,1701,1237,821,
- 1375,3673,2693,3925,1541,1871,2285,847,4035,1101,2029,855,
- 2733,2503,121,2855,1069,3463,3505,1539,607,1349,575,2301,
- 2321,1101,333,291,2171,4085,2173,2541,1195,925,4039,1379,699,
- 1979,275,953,1755,1643,325,101,2263,3329,3673,3413,1977,2727,
- 2313,1419,887,609,2475,591,2613,2081,3805,3435,2409,111,3557,
- 3607,903,231,3059,473,2959,2925,3861,2043,3887,351,2865,369,
- 1377,2639,1261,3625,3279,2201,2949,3049,449,1297,897,1891,
- 411,2773,749,2753,1825,853,2775,3547,3923,3923,987,3723,2189,
- 3877,3577,297,2763,1845,3083,2951,483,2169,3985,245,3655,
- 3441,1023,235,835,3693,3585,327,1003,543,3059,2637,
- 2923,87,3617,1031,1043,903,2913,
- 2177,2641,3279,389,2009,525,4085,3299,987,2409,813,2683,373,
- 2695,3775,2375,1119,2791,223,325,587,1379,2877,2867,3793,655,
- 831,3425,1663,1681,2657,1865,3943,2977,1979,2271,3247,1267,
- 1747,811,159,429,2001,1195,3065,553,1499,3529,1081,2877,3077,
- 845,1793,2409,3995,2559,4081,1195,2955,1117,1409,785,287,
- 1521,1607,85,3055,3123,2533,2329,3477,799,3683,3715,337,3139,
- 3311,431,3511,2299,365,2941,3067,1331,1081,1097,2853,2299,
- 495,1745,749,3819,619,1059,3559,183,3743,723,949,3501,733,
- 2599,3983,3961,911,1899,985,2493,1795,653,157,433,2361,3093,
- 3119,3679,2367,1701,1445,1321,2397,1241,3305,3985,2349,4067,
- 3805,3073,2837,1567,3783,451,2441,1181,487,543,1201,3735,
- 2517,733,1535,2175,3613,3019},
- /* [12][*] */
- {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, [...]
- 2319,653,1379,1675,1951,7075,2087,
- 7147,1427,893,171,2019,7235,5697,3615,1961,7517,6849,2893,
- 1883,2863,2173,4543,73,381,3893,6045,1643,7669,1027,1549,
- 3983,1985,6589,7497,2745,2375,7047,1117,1171,1975,5199,3915,
- 3695,8113,4303,3773,7705,6855,1675,2245,2817,1719,569,1021,
- 2077,5945,1833,2631,4851,6371,833,7987,331,1899,8093,6719,
- 6903,5903,5657,5007,2689,6637,2675,1645,1819,689,6709,7717,
- 6295,7013,7695,3705,7069,2621,3631,6571,6259,7261,3397,7645,
- 1115,4753,2047,7579,2271,5403,4911,7629,4225,1209,6955,6951,
- 1829,5579,5231,1783,4285,7425,599,5785,3275,5643,2263,657,
- 6769,6261,1251,3249,4447,4111,3991,1215,131,4397,3487,7585,
- 5565,7199,3573,7105,7409,1671,949,3889,5971,3333,225,3647,
- 5403,3409,7459,6879,5789,6567,5581,4919,1927,4407,8085,4691,
- 611,3005,591,753,589,171,5729,5891,1033,3049,6567,5257,8003,
- 1757,4489,4923,6379,5171,1757,689,3081,1389,4113,455,2761,
- 847,7575,5829,633,6629,1103,7635,803,6175,6587,2711,3879,67,
- 1179,4761,7281,1557,3379,2459,4273,4127,7147,35,
- 3549,395,3735,5787,4179,5889,5057,
- 7473,4713,2133,2897,1841,2125,1029,1695,6523,1143,5105,7133,
- 3351,2775,3971,4503,7589,5155,4305,1641,4717,2427,5617,1267,
- 399,5831,4305,4241,3395,3045,4899,1713,171,411,7099,5473,
- 5209,1195,1077,1309,2953,7343,4887,3229,6759,6721,6775,675,
- 4039,2493,7511,3269,4199,6625,7943,2013,4145,667,513,2303,
- 4591,7941,2741,987,8061,3161,5951,1431,831,5559,7405,1357,
- 4319,4235,5421,2559,4415,2439,823,1725,6219,4903,6699,5451,
- 349,7703,2927,7809,6179,1417,5987,3017,4983,3479,4525,4643,
- 4911,227,5475,2287,5581,6817,1937,1421,4415,7977,1789,3907,
- 6815,6789,6003,5609,4507,337,7427,7943,3075,6427,1019,7121,
- 4763,81,3587,2929,1795,8067,2415,1265,4025,5599,4771,3025,
- 2313,6129,7611,6881,5253,4413,7869,105,3173,1629,2537,1023,
- 4409,7209,4413,7107,7469,33,1955,2881,5167,6451,4211,179,
- 5573,7879,3387,7759,5455,7157,1891,5683,5689,6535,3109,6555,
- 6873,1249,4251,6437,49,2745,1201,7327,4179,6783,623,2779,
- 5963,2585,6927,5333,4033,285,7467,4443,4917,3,
- 4319,5517,3449,813,5499,2515,5771,
- 3357,2073,4395,4925,2643,7215,5817,1199,1597,1619,7535,4833,
- 609,4797,8171,6847,793,6757,8165,3371,2431,5235,4739,7703,
- 7223,6525,5891,5605,4433,3533,5267,5125,5037,225,6717,1121,
- 5741,2013,4327,4839,569,5227,7677,4315,2391,5551,859,3627,
- 6377,3903,4311,6527,7573,4905,7731,1909,1555,3279,1949,1887,
- 6675,5509,2033,5473,3539,5033,5935,6095,4761,1771,1271,1717,
- 4415,5083,6277,3147,7695,2461,4783,4539,5833,5583,651,1419,
- 2605,5511,3913,5795,2333,2329,4431,3725,6069,2699,7055,6879,
- 1017,3121,2547,4603,2385,6915,6103,5669,7833,2001,4287,6619,
- 955,2761,5711,6291,3415,3909,2841,5627,4939,7671,6059,6275,
- 6517,1931,4583,7301,1267,7509,1435,2169,6939,3515,2985,2787,
- 2123,1969,3307,353,4359,7059,5273,5873,6657,6765,6229,3179,
- 1583,6237,2155,371,273,7491,3309,6805,3015,6831,7819,713,
- 4747,3935,4109,1311,709,3089,7059,4247,2989,1509,4919,1841,
- 3045,3821,6929,4655,1333,6429,6649,2131,5265,1051,261,8057,
- 3379,2179,1993,5655,3063,6381,
- 3587,7417,1579,1541,2107,5085,2873,
- 6141,955,3537,2157,841,1999,1465,5171,5651,1535,7235,4349,
- 1263,1453,1005,6893,2919,1947,1635,3963,397,969,4569,655,
- 6737,2995,7235,7713,973,4821,2377,1673,1,6541}
-};
-
-#endif
diff --git a/ext/src/nlopt/util/sobolseq.c b/ext/src/nlopt/util/sobolseq.c
deleted file mode 100644
index b2e022a..0000000
--- a/ext/src/nlopt/util/sobolseq.c
+++ /dev/null
@@ -1,287 +0,0 @@
-/* Copyright (c) 2007 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/* Generation of Sobol sequences in up to 1111 dimensions, based on the
- algorithms described in:
- P. Bratley and B. L. Fox, Algorithm 659, ACM Trans.
- Math. Soft. 14 (1), 88-100 (1988),
- as modified by:
- S. Joe and F. Y. Kuo, ACM Trans. Math. Soft 29 (1), 49-57 (2003).
-
- Note that the code below was written without even looking at the
- Fortran code from the TOMS paper, which is only semi-free (being
- under the restrictive ACM copyright terms). Then I went to the
- Fortran code and took out the table of primitive polynomials and
- starting direction #'s ... since this is just a table of numbers
- generated by a deterministic algorithm, it is not copyrightable.
- (Obviously, the format of these tables then necessitated some
- slight modifications to the code.)
-
- For the test integral of Joe and Kuo (see the main() program
- below), I get exactly the same results for integrals up to 1111
- dimensions compared to the table of published numbers (to the 5
- published significant digits).
-
- This is not to say that the authors above should not be credited for
- their clear description of the algorithm (and their tabulation of
- the critical numbers). Please cite them. Just that I needed
- a free/open-source implementation. */
-
-#include <stdlib.h>
-#include <math.h>
-
-#include "nlopt/nlopt-util.h"
-
-#include <stdint.h>
-
-typedef struct nlopt_soboldata_s {
- unsigned sdim; /* dimension of sequence being generated */
- uint32_t *mdata; /* array of length 32 * sdim */
- uint32_t *m[32]; /* more convenient pointers to mdata, of direction #s */
- uint32_t *x; /* previous x = x_n, array of length sdim */
- unsigned *b; /* position of fixed point in x[i] is after bit b[i] */
- uint32_t n; /* number of x's generated so far */
-} soboldata;
-
-/* Return position (0, 1, ...) of rightmost (least-significant) zero bit in n.
- *
- * This code uses a 32-bit version of algorithm to find the rightmost
- * one bit in Knuth, _The Art of Computer Programming_, volume 4A
- * (draft fascicle), section 7.1.3, "Bitwise tricks and
- * techniques."
- *
- * Assumes n has a zero bit, i.e. n < 2^32 - 1.
- *
- */
-static unsigned rightzero32(uint32_t n)
-{
-#if defined(__GNUC__) && \
- ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ > 3)
- return __builtin_ctz(~n); /* gcc builtin for version >= 3.4 */
-#else
- const uint32_t a = 0x05f66a47; /* magic number, found by brute force */
- static const unsigned decode[32] = {0,1,2,26,23,3,15,27,24,21,19,4,12,16,28,6,31,25,22,14,20,18,11,5,30,13,17,10,29,9,8,7};
- n = ~n; /* change to rightmost-one problem */
- n = a * (n & (-n)); /* store in n to make sure mult. is 32 bits */
- return decode[n >> 27];
-#endif
-}
-
-/* generate the next term x_{n+1} in the Sobol sequence, as an array
- x[sdim] of numbers in (0,1). Returns 1 on success, 0 on failure
- (if too many #'s generated) */
-static int sobol_gen(soboldata *sd, double *x)
-{
- unsigned c, b, i, sdim;
-
- if (sd->n == 4294967295U) return 0; /* n == 2^32 - 1 ... we would
- need to switch to a 64-bit version
- to generate more terms. */
- c = rightzero32(sd->n++);
- sdim = sd->sdim;
- for (i = 0; i < sdim; ++i) {
- b = sd->b[i];
- if (b >= c) {
- sd->x[i] ^= sd->m[c][i] << (b - c);
- x[i] = ((double) (sd->x[i])) / (1U << (b+1));
- }
- else {
- sd->x[i] = (sd->x[i] << (c - b)) ^ sd->m[c][i];
- sd->b[i] = c;
- x[i] = ((double) (sd->x[i])) / (1U << (c+1));
- }
- }
- return 1;
-}
-
-#include "soboldata.h"
-
-static int sobol_init(soboldata *sd, unsigned sdim)
-{
- unsigned i,j;
-
- if (!sdim || sdim > MAXDIM) return 0;
-
- sd->mdata = (uint32_t *) malloc(sizeof(uint32_t) * (sdim * 32));
- if (!sd->mdata) return 0;
-
- for (j = 0; j < 32; ++j) {
- sd->m[j] = sd->mdata + j * sdim;
- sd->m[j][0] = 1; /* special-case Sobol sequence */
- }
- for (i = 1; i < sdim; ++i) {
- uint32_t a = sobol_a[i-1];
- unsigned d = 0, k;
-
- while (a) {
- ++d;
- a >>= 1;
- }
- d--; /* d is now degree of poly */
-
- /* set initial values of m from table */
- for (j = 0; j < d; ++j)
- sd->m[j][i] = sobol_minit[j][i-1];
-
- /* fill in remaining values using recurrence */
- for (j = d; j < 32; ++j) {
- a = sobol_a[i-1];
- sd->m[j][i] = sd->m[j - d][i];
- for (k = 0; k < d; ++k) {
- sd->m[j][i] ^= ((a & 1) * sd->m[j-d+k][i]) << (d-k);
- a >>= 1;
- }
- }
- }
-
- sd->x = (uint32_t *) malloc(sizeof(uint32_t) * sdim);
- if (!sd->x) { free(sd->mdata); return 0; }
-
- sd->b = (unsigned *) malloc(sizeof(unsigned) * sdim);
- if (!sd->b) { free(sd->x); free(sd->mdata); return 0; }
-
- for (i = 0; i < sdim; ++i) {
- sd->x[i] = 0;
- sd->b[i] = 0;
- }
-
- sd->n = 0;
- sd->sdim = sdim;
-
- return 1;
-}
-
-static void sobol_destroy(soboldata *sd)
-{
- free(sd->mdata);
- free(sd->x);
- free(sd->b);
-}
-
-/************************************************************************/
-/* NLopt API to Sobol sequence creation, which hides soboldata structure
- behind an opaque pointer */
-
-nlopt_sobol nlopt_sobol_create(unsigned sdim)
-{
- nlopt_sobol s = (nlopt_sobol) malloc(sizeof(soboldata));
- if (!s) return NULL;
- if (!sobol_init(s, sdim)) { free(s); return NULL; }
- return s;
-}
-
-extern void nlopt_sobol_destroy(nlopt_sobol s)
-{
- if (s) {
- sobol_destroy(s);
- free(s);
- }
-}
-
-/* next vector x[sdim] in Sobol sequence, with each x[i] in (0,1) */
-void nlopt_sobol_next01(nlopt_sobol s, double *x)
-{
- if (!sobol_gen(s, x)) {
- /* fall back on pseudo random numbers in the unlikely event
- that we exceed 2^32-1 points */
- unsigned i;
- for (i = 0; i < s->sdim; ++i)
- x[i] = nlopt_urand(0.0,1.0);
- }
-}
-
-/* next vector in Sobol sequence, scaled to (lb[i], ub[i]) interval */
-void nlopt_sobol_next(nlopt_sobol s, double *x,
- const double *lb, const double *ub)
-{
- unsigned i, sdim;
- nlopt_sobol_next01(s, x);
- for (sdim = s->sdim, i = 0; i < sdim; ++i)
- x[i] = lb[i] + (ub[i] - lb[i]) * x[i];
-}
-
-/* if we know in advance how many points (n) we want to compute, then
- adopt the suggestion of the Joe and Kuo paper, which in turn
- is taken from Acworth et al (1998), of skipping a number of
- points equal to the largest power of 2 smaller than n */
-void nlopt_sobol_skip(nlopt_sobol s, unsigned n, double *x)
-{
- if (s) {
- unsigned k = 1;
- while (k*2 < n) k *= 2;
- while (k-- > 0) sobol_gen(s, x);
- }
-}
-
-/************************************************************************/
-
-/* compile with -DSOBOLSEQ_TEST for test program */
-#ifdef SOBOLSEQ_TEST
-#include <stdio.h>
-#include <time.h>
-
-/* test integrand from Joe and Kuo paper ... integrates to 1 */
-static double testfunc(unsigned n, const double *x)
-{
- double f = 1;
- unsigned j;
- for (j = 1; j <= n; ++j) {
- double cj = pow((double) j, 0.3333333333333333333);
- f *= (fabs(4*x[j-1] - 2) + cj) / (1 + cj);
- }
- return f;
-}
-
-int main(int argc, char **argv)
-{
- unsigned n, j, i, sdim;
- static double x[MAXDIM];
- double testint_sobol = 0, testint_rand = 0;
- nlopt_sobol s;
- if (argc < 3) {
- fprintf(stderr, "Usage: %s <sdim> <ngen>\n", argv[0]);
- return 1;
- }
- nlopt_init_genrand(time(NULL));
- sdim = atoi(argv[1]);
- s = nlopt_sobol_create(sdim);
- n = atoi(argv[2]);
- nlopt_sobol_skip(s, n, x);
- for (j = 1; j <= n; ++j) {
- nlopt_sobol_next01(s, x);
- testint_sobol += testfunc(sdim, x);
- if (j < 100) {
- printf("x[%d]: %g", j, x[0]);
- for (i = 1; i < sdim; ++i) printf(", %g", x[i]);
- printf("\n");
- }
- for (i = 0; i < sdim; ++i) x[i] = nlopt_urand(0.,1.);
- testint_rand += testfunc(sdim, x);
- }
- nlopt_sobol_destroy(s);
- printf("Test integral = %g using Sobol, %g using pseudorandom.\n",
- testint_sobol / n, testint_rand / n);
- printf(" error = %g using Sobol, %g using pseudorandom.\n",
- testint_sobol / n - 1, testint_rand / n - 1);
- return 0;
-}
-#endif
diff --git a/ext/src/nlopt/util/stop.c b/ext/src/nlopt/util/stop.c
deleted file mode 100644
index 73a634f..0000000
--- a/ext/src/nlopt/util/stop.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/* Copyright (c) 2007-2012 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <math.h>
-#include "nlopt/nlopt-util.h"
-
-/* utility routines to implement the various stopping criteria */
-
-static int relstop(double vold, double vnew, double reltol, double abstol)
-{
- if (nlopt_isinf(vold)) return 0;
- return(fabs(vnew - vold) < abstol
- || fabs(vnew - vold) < reltol * (fabs(vnew) + fabs(vold)) * 0.5
- || (reltol > 0 && vnew == vold)); /* catch vnew == vold == 0 */
-}
-
-int nlopt_stop_ftol(const nlopt_stopping *s, double f, double oldf)
-{
- return (relstop(oldf, f, s->ftol_rel, s->ftol_abs));
-}
-
-int nlopt_stop_f(const nlopt_stopping *s, double f, double oldf)
-{
- return (f <= s->minf_max || nlopt_stop_ftol(s, f, oldf));
-}
-
-int nlopt_stop_x(const nlopt_stopping *s, const double *x, const double *oldx)
-{
- unsigned i;
- for (i = 0; i < s->n; ++i)
- if (!relstop(oldx[i], x[i], s->xtol_rel, s->xtol_abs[i]))
- return 0;
- return 1;
-}
-
-int nlopt_stop_dx(const nlopt_stopping *s, const double *x, const double *dx)
-{
- unsigned i;
- for (i = 0; i < s->n; ++i)
- if (!relstop(x[i] - dx[i], x[i], s->xtol_rel, s->xtol_abs[i]))
- return 0;
- return 1;
-}
-
-static double sc(double x, double smin, double smax)
-{
- return smin + x * (smax - smin);
-}
-
-/* some of the algorithms rescale x to a unit hypercube, so we need to
- scale back before we can compare to the tolerances */
-int nlopt_stop_xs(const nlopt_stopping *s,
- const double *xs, const double *oldxs,
- const double *scale_min, const double *scale_max)
-{
- unsigned i;
- for (i = 0; i < s->n; ++i)
- if (relstop(sc(oldxs[i], scale_min[i], scale_max[i]),
- sc(xs[i], scale_min[i], scale_max[i]),
- s->xtol_rel, s->xtol_abs[i]))
- return 1;
- return 0;
-}
-
-int nlopt_stop_evals(const nlopt_stopping *s)
-{
- return (s->maxeval > 0 && s->nevals >= s->maxeval);
-}
-
-int nlopt_stop_time_(double start, double maxtime)
-{
- return (maxtime > 0 && nlopt_seconds() - start >= maxtime);
-}
-
-int nlopt_stop_time(const nlopt_stopping *s)
-{
- return nlopt_stop_time_(s->start, s->maxtime);
-}
-
-int nlopt_stop_evalstime(const nlopt_stopping *stop)
-{
- return nlopt_stop_evals(stop) || nlopt_stop_time(stop);
-}
-
-int nlopt_stop_forced(const nlopt_stopping *stop)
-{
- return stop->force_stop && *(stop->force_stop);
-}
-
-unsigned nlopt_count_constraints(unsigned p, const nlopt_constraint *c)
-{
- unsigned i, count = 0;
- for (i = 0; i < p; ++i)
- count += c[i].m;
- return count;
-}
-
-unsigned nlopt_max_constraint_dim(unsigned p, const nlopt_constraint *c)
-{
- unsigned i, max_dim = 0;
- for (i = 0; i < p; ++i)
- if (c[i].m > max_dim)
- max_dim = c[i].m;
- return max_dim;
-}
-
-void nlopt_eval_constraint(double *result, double *grad,
- const nlopt_constraint *c,
- unsigned n, const double *x)
-{
- if (c->f)
- result[0] = c->f(n, x, grad, c->f_data);
- else
- c->mf(c->m, result, n, x, grad, c->f_data);
-}
diff --git a/ext/src/nlopt/util/timer.c b/ext/src/nlopt/util/timer.c
deleted file mode 100644
index 02cfb7a..0000000
--- a/ext/src/nlopt/util/timer.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/* Copyright (c) 2007-2012 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include "nlopt/nlopt-util.h"
-
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-
-#if defined(_WIN32) || defined(__WIN32__)
-# include <windows.h>
-#endif
-
-/* return time in seconds since some arbitrary point in the past */
-double nlopt_seconds(void)
-{
- static __thread int start_inited = 0; /* whether start time has been initialized */
-#if defined(HAVE_GETTIMEOFDAY)
- static __thread struct timeval start;
- struct timeval tv;
- if (!start_inited) {
- start_inited = 1;
- gettimeofday(&start, NULL);
- }
- gettimeofday(&tv, NULL);
- return (tv.tv_sec - start.tv_sec) + 1.e-6 * (tv.tv_usec - start.tv_usec);
-#elif defined(HAVE_TIME)
- return time(NULL);
-#elif defined(_WIN32) || defined(__WIN32__)
- static __thread ULONGLONG start;
- FILETIME ft;
- if (!start_inited) {
- start_inited = 1;
- GetSystemTimeAsFileTime(&ft);
- start = (((ULONGLONG) ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
- }
- GetSystemTimeAsFileTime(&ft);
- return 100e-9 * (((((ULONGLONG) ft.dwHighDateTime) << 32) + ft.dwLowDateTime) - start);
-#else
- /* use clock() as a fallback... this is somewhat annoying
- because clock() may wrap around with a fairly short period */
- static __thread clock_t start;
- if (!start_inited) {
- start_inited = 1;
- start = clock();
- }
- return (clock() - start) * 1.0 / CLOCKS_PER_SEC;
-#endif
-}
-
-/* number based on time for use as random seed */
-unsigned long nlopt_time_seed(void)
-{
-#if defined(HAVE_GETTIMEOFDAY)
- struct timeval tv;
- gettimeofday(&tv, NULL);
- return (tv.tv_sec ^ tv.tv_usec);
-#elif defined(HAVE_TIME)
- return time(NULL);
-#elif defined(_WIN32) || defined(__WIN32__)
- FILETIME ft;
- GetSystemTimeAsFileTime(&ft);
- return ft.dwHighDateTime ^ ft.dwLowDateTime;
-#else
- return clock();
-#endif
-}
diff --git a/ext/src/ssw/CMakeLists.txt b/ext/src/ssw/CMakeLists.txt
deleted file mode 100644
index 28a9263..0000000
--- a/ext/src/ssw/CMakeLists.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-############################################################################
-# Copyright (c) 2015 Saint Petersburg State University
-# All Rights Reserved
-# See file LICENSE for details.
-############################################################################
-
-project(ssw C CXX)
-
-add_library(ssw STATIC
- ssw.c
- ssw_cpp.cpp)
-
diff --git a/ext/src/ssw/ssw.c b/ext/src/ssw/ssw.c
deleted file mode 100755
index 39682f2..0000000
--- a/ext/src/ssw/ssw.c
+++ /dev/null
@@ -1,903 +0,0 @@
-/* The MIT License
-
- Copyright (c) 2012-1015 Boston College.
-
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
-*/
-
-/* Contact: Mengyao Zhao <zhangmp at bc.edu> */
-
-/*
- * ssw.c
- *
- * Created by Mengyao Zhao on 6/22/10.
- * Copyright 2010 Boston College. All rights reserved.
- * Version 0.1.4
- * Last revision by Mengyao Zhao on 06/27/14.
- *
- */
-
-#include <emmintrin.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <math.h>
-#include "ssw/ssw.h"
-
-#ifdef __GNUC__
-#define LIKELY(x) __builtin_expect((x),1)
-#define UNLIKELY(x) __builtin_expect((x),0)
-#else
-#define LIKELY(x) (x)
-#define UNLIKELY(x) (x)
-#endif
-
-/* Convert the coordinate in the scoring matrix into the coordinate in one line of the band. */
-#define set_u(u, w, i, j) { int x=(i)-(w); x=x>0?x:0; (u)=(j)-x+1; }
-
-/* Convert the coordinate in the direction matrix into the coordinate in one line of the band. */
-#define set_d(u, w, i, j, p) { int x=(i)-(w); x=x>0?x:0; x=(j)-x; (u)=x*3+p; }
-
-/*! @function
- @abstract Round an integer to the next closest power-2 integer.
- @param x integer to be rounded (in place)
- @discussion x will be modified.
- */
-#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x))
-
-typedef struct {
- uint16_t score;
- int32_t ref; //0-based position
- int32_t read; //alignment ending position on read, 0-based
-} alignment_end;
-
-typedef struct {
- uint32_t* seq;
- int32_t length;
-} cigar;
-
-struct _profile{
- __m128i* profile_byte; // 0: none
- __m128i* profile_word; // 0: none
- const int8_t* read;
- const int8_t* mat;
- int32_t readLen;
- int32_t n;
- uint8_t bias;
-};
-
-/* Generate query profile rearrange query sequence & calculate the weight of match/mismatch. */
-static __m128i* qP_byte (const int8_t* read_num,
- const int8_t* mat,
- const int32_t readLen,
- const int32_t n, /* the edge length of the squre matrix mat */
- uint8_t bias) {
-
- int32_t segLen = (readLen + 15) / 16; /* Split the 128 bit register into 16 pieces.
- Each piece is 8 bit. Split the read into 16 segments.
- Calculat 16 segments in parallel.
- */
- __m128i* vProfile = (__m128i*)malloc(n * segLen * sizeof(__m128i));
- int8_t* t = (int8_t*)vProfile;
- int32_t nt, i, j, segNum;
-
- /* Generate query profile rearrange query sequence & calculate the weight of match/mismatch */
- for (nt = 0; LIKELY(nt < n); nt ++) {
- for (i = 0; i < segLen; i ++) {
- j = i;
- for (segNum = 0; LIKELY(segNum < 16) ; segNum ++) {
- *t++ = j>= readLen ? bias : mat[nt * n + read_num[j]] + bias;
- j += segLen;
- }
- }
- }
- return vProfile;
-}
-
-/* Striped Smith-Waterman
- Record the highest score of each reference position.
- Return the alignment score and ending position of the best alignment, 2nd best alignment, etc.
- Gap begin and gap extension are different.
- wight_match > 0, all other weights < 0.
- The returned positions are 0-based.
- */
-static alignment_end* sw_sse2_byte (const int8_t* ref,
- int8_t ref_dir, // 0: forward ref; 1: reverse ref
- int32_t refLen,
- int32_t readLen,
- const uint8_t weight_gapO, /* will be used as - */
- const uint8_t weight_gapE, /* will be used as - */
- const __m128i* vProfile,
- uint8_t terminate, /* the best alignment score: used to terminate
- the matrix calculation when locating the
- alignment beginning point. If this score
- is set to 0, it will not be used */
- uint8_t bias, /* Shift 0 point to a positive value. */
- int32_t maskLen) {
-
-#define max16(m, vm) (vm) = _mm_max_epu8((vm), _mm_srli_si128((vm), 8)); \
- (vm) = _mm_max_epu8((vm), _mm_srli_si128((vm), 4)); \
- (vm) = _mm_max_epu8((vm), _mm_srli_si128((vm), 2)); \
- (vm) = _mm_max_epu8((vm), _mm_srli_si128((vm), 1)); \
- (m) = _mm_extract_epi16((vm), 0)
-
- uint8_t max = 0; /* the max alignment score */
- int32_t end_read = readLen - 1;
- int32_t end_ref = -1; /* 0_based best alignment ending point; Initialized as isn't aligned -1. */
- int32_t segLen = (readLen + 15) / 16; /* number of segment */
-
- /* array to record the largest score of each reference position */
- uint8_t* maxColumn = (uint8_t*) calloc(refLen, 1);
-
- /* array to record the alignment read ending position of the largest score of each reference position */
- int32_t* end_read_column = (int32_t*) calloc(refLen, sizeof(int32_t));
-
- /* Define 16 byte 0 vector. */
- __m128i vZero = _mm_set1_epi32(0);
-
- __m128i* pvHStore = (__m128i*) calloc(segLen, sizeof(__m128i));
- __m128i* pvHLoad = (__m128i*) calloc(segLen, sizeof(__m128i));
- __m128i* pvE = (__m128i*) calloc(segLen, sizeof(__m128i));
- __m128i* pvHmax = (__m128i*) calloc(segLen, sizeof(__m128i));
-
- int32_t i, j;
- /* 16 byte insertion begin vector */
- __m128i vGapO = _mm_set1_epi8(weight_gapO);
-
- /* 16 byte insertion extension vector */
- __m128i vGapE = _mm_set1_epi8(weight_gapE);
-
- /* 16 byte bias vector */
- __m128i vBias = _mm_set1_epi8(bias);
-
- __m128i vMaxScore = vZero; /* Trace the highest score of the whole SW matrix. */
- __m128i vMaxMark = vZero; /* Trace the highest score till the previous column. */
- __m128i vTemp;
- int32_t edge, begin = 0, end = refLen, step = 1;
-// int32_t distance = readLen * 2 / 3;
-// int32_t distance = readLen / 2;
-// int32_t distance = readLen;
-
- /* outer loop to process the reference sequence */
- if (ref_dir == 1) {
- begin = refLen - 1;
- end = -1;
- step = -1;
- }
- for (i = begin; LIKELY(i != end); i += step) {
- int32_t cmp;
- __m128i e, vF = vZero, vMaxColumn = vZero; /* Initialize F value to 0.
- Any errors to vH values will be corrected in the Lazy_F loop.
- */
-// max16(maxColumn[i], vMaxColumn);
-// fprintf(stderr, "middle[%d]: %d\n", i, maxColumn[i]);
-
- __m128i vH = pvHStore[segLen - 1];
- vH = _mm_slli_si128 (vH, 1); /* Shift the 128-bit value in vH left by 1 byte. */
- const __m128i* vP = vProfile + ref[i] * segLen; /* Right part of the vProfile */
-
- /* Swap the 2 H buffers. */
- __m128i* pv = pvHLoad;
- pvHLoad = pvHStore;
- pvHStore = pv;
-
- /* inner loop to process the query sequence */
- for (j = 0; LIKELY(j < segLen); ++j) {
- vH = _mm_adds_epu8(vH, _mm_load_si128(vP + j));
- vH = _mm_subs_epu8(vH, vBias); /* vH will be always > 0 */
- // max16(maxColumn[i], vH);
- // fprintf(stderr, "H[%d]: %d\n", i, maxColumn[i]);
-// int8_t* t;
-// int32_t ti;
-//for (t = (int8_t*)&vH, ti = 0; ti < 16; ++ti) fprintf(stderr, "%d\t", *t++);
-
- /* Get max from vH, vE and vF. */
- e = _mm_load_si128(pvE + j);
- vH = _mm_max_epu8(vH, e);
- vH = _mm_max_epu8(vH, vF);
- vMaxColumn = _mm_max_epu8(vMaxColumn, vH);
-
- // max16(maxColumn[i], vMaxColumn);
- // fprintf(stderr, "middle[%d]: %d\n", i, maxColumn[i]);
-// for (t = (int8_t*)&vMaxColumn, ti = 0; ti < 16; ++ti) fprintf(stderr, "%d\t", *t++);
-
- /* Save vH values. */
- _mm_store_si128(pvHStore + j, vH);
-
- /* Update vE value. */
- vH = _mm_subs_epu8(vH, vGapO); /* saturation arithmetic, result >= 0 */
- e = _mm_subs_epu8(e, vGapE);
- e = _mm_max_epu8(e, vH);
- _mm_store_si128(pvE + j, e);
-
- /* Update vF value. */
- vF = _mm_subs_epu8(vF, vGapE);
- vF = _mm_max_epu8(vF, vH);
-
- /* Load the next vH. */
- vH = _mm_load_si128(pvHLoad + j);
- }
-
- /* Lazy_F loop: has been revised to disallow adjecent insertion and then deletion, so don't update E(i, j), learn from SWPS3 */
- /* reset pointers to the start of the saved data */
- j = 0;
- vH = _mm_load_si128 (pvHStore + j);
-
- /* the computed vF value is for the given column. since */
- /* we are at the end, we need to shift the vF value over */
- /* to the next column. */
- vF = _mm_slli_si128 (vF, 1);
- vTemp = _mm_subs_epu8 (vH, vGapO);
- vTemp = _mm_subs_epu8 (vF, vTemp);
- vTemp = _mm_cmpeq_epi8 (vTemp, vZero);
- cmp = _mm_movemask_epi8 (vTemp);
-
- while (cmp != 0xffff)
- {
- vH = _mm_max_epu8 (vH, vF);
- vMaxColumn = _mm_max_epu8(vMaxColumn, vH);
- _mm_store_si128 (pvHStore + j, vH);
- vF = _mm_subs_epu8 (vF, vGapE);
- j++;
- if (j >= segLen)
- {
- j = 0;
- vF = _mm_slli_si128 (vF, 1);
- }
- vH = _mm_load_si128 (pvHStore + j);
-
- vTemp = _mm_subs_epu8 (vH, vGapO);
- vTemp = _mm_subs_epu8 (vF, vTemp);
- vTemp = _mm_cmpeq_epi8 (vTemp, vZero);
- cmp = _mm_movemask_epi8 (vTemp);
- }
-
- vMaxScore = _mm_max_epu8(vMaxScore, vMaxColumn);
- vTemp = _mm_cmpeq_epi8(vMaxMark, vMaxScore);
- cmp = _mm_movemask_epi8(vTemp);
- if (cmp != 0xffff) {
- uint8_t temp;
- vMaxMark = vMaxScore;
- max16(temp, vMaxScore);
- vMaxScore = vMaxMark;
-
- if (LIKELY(temp > max)) {
- max = temp;
- if (max + bias >= 255) break; //overflow
- end_ref = i;
-
- /* Store the column with the highest alignment score in order to trace the alignment ending position on read. */
- for (j = 0; LIKELY(j < segLen); ++j) pvHmax[j] = pvHStore[j];
- }
- }
-
- /* Record the max score of current column. */
- max16(maxColumn[i], vMaxColumn);
-// fprintf(stderr, "maxColumn[%d]: %d\n", i, maxColumn[i]);
- if (maxColumn[i] == terminate) break;
- }
-
- /* Trace the alignment ending position on read. */
- uint8_t *t = (uint8_t*)pvHmax;
- int32_t column_len = segLen * 16;
- for (i = 0; LIKELY(i < column_len); ++i, ++t) {
- int32_t temp;
- if (*t == max) {
- temp = i / 16 + i % 16 * segLen;
- if (temp < end_read) end_read = temp;
- }
- }
-
- free(pvHmax);
- free(pvE);
- free(pvHLoad);
- free(pvHStore);
-
- /* Find the most possible 2nd best alignment. */
- alignment_end* bests = (alignment_end*) calloc(2, sizeof(alignment_end));
- bests[0].score = max + bias >= 255 ? 255 : max;
- bests[0].ref = end_ref;
- bests[0].read = end_read;
-
- bests[1].score = 0;
- bests[1].ref = 0;
- bests[1].read = 0;
-
- edge = (end_ref - maskLen) > 0 ? (end_ref - maskLen) : 0;
- for (i = 0; i < edge; i ++) {
-// fprintf (stderr, "maxColumn[%d]: %d\n", i, maxColumn[i]);
- if (maxColumn[i] > bests[1].score) {
- bests[1].score = maxColumn[i];
- bests[1].ref = i;
- }
- }
- edge = (end_ref + maskLen) > refLen ? refLen : (end_ref + maskLen);
- for (i = edge + 1; i < refLen; i ++) {
-// fprintf (stderr, "refLen: %d\tmaxColumn[%d]: %d\n", refLen, i, maxColumn[i]);
- if (maxColumn[i] > bests[1].score) {
- bests[1].score = maxColumn[i];
- bests[1].ref = i;
- }
- }
-
- free(maxColumn);
- free(end_read_column);
- return bests;
-}
-
-static __m128i* qP_word (const int8_t* read_num,
- const int8_t* mat,
- const int32_t readLen,
- const int32_t n) {
-
- int32_t segLen = (readLen + 7) / 8;
- __m128i* vProfile = (__m128i*)malloc(n * segLen * sizeof(__m128i));
- int16_t* t = (int16_t*)vProfile;
- int32_t nt, i, j;
- int32_t segNum;
-
- /* Generate query profile rearrange query sequence & calculate the weight of match/mismatch */
- for (nt = 0; LIKELY(nt < n); nt ++) {
- for (i = 0; i < segLen; i ++) {
- j = i;
- for (segNum = 0; LIKELY(segNum < 8) ; segNum ++) {
- *t++ = j>= readLen ? 0 : mat[nt * n + read_num[j]];
- j += segLen;
- }
- }
- }
- return vProfile;
-}
-
-static alignment_end* sw_sse2_word (const int8_t* ref,
- int8_t ref_dir, // 0: forward ref; 1: reverse ref
- int32_t refLen,
- int32_t readLen,
- const uint8_t weight_gapO, /* will be used as - */
- const uint8_t weight_gapE, /* will be used as - */
- const __m128i* vProfile,
- uint16_t terminate,
- int32_t maskLen) {
-
-#define max8(m, vm) (vm) = _mm_max_epi16((vm), _mm_srli_si128((vm), 8)); \
- (vm) = _mm_max_epi16((vm), _mm_srli_si128((vm), 4)); \
- (vm) = _mm_max_epi16((vm), _mm_srli_si128((vm), 2)); \
- (m) = _mm_extract_epi16((vm), 0)
-
- uint16_t max = 0; /* the max alignment score */
- int32_t end_read = readLen - 1;
- int32_t end_ref = 0; /* 1_based best alignment ending point; Initialized as isn't aligned - 0. */
- int32_t segLen = (readLen + 7) / 8; /* number of segment */
-
- /* array to record the largest score of each reference position */
- uint16_t* maxColumn = (uint16_t*) calloc(refLen, 2);
-
- /* array to record the alignment read ending position of the largest score of each reference position */
- int32_t* end_read_column = (int32_t*) calloc(refLen, sizeof(int32_t));
-
- /* Define 16 byte 0 vector. */
- __m128i vZero = _mm_set1_epi32(0);
-
- __m128i* pvHStore = (__m128i*) calloc(segLen, sizeof(__m128i));
- __m128i* pvHLoad = (__m128i*) calloc(segLen, sizeof(__m128i));
- __m128i* pvE = (__m128i*) calloc(segLen, sizeof(__m128i));
- __m128i* pvHmax = (__m128i*) calloc(segLen, sizeof(__m128i));
-
- int32_t i, j, k;
- /* 16 byte insertion begin vector */
- __m128i vGapO = _mm_set1_epi16(weight_gapO);
-
- /* 16 byte insertion extension vector */
- __m128i vGapE = _mm_set1_epi16(weight_gapE);
-
- __m128i vMaxScore = vZero; /* Trace the highest score of the whole SW matrix. */
- __m128i vMaxMark = vZero; /* Trace the highest score till the previous column. */
- __m128i vTemp;
- int32_t edge, begin = 0, end = refLen, step = 1;
-
- /* outer loop to process the reference sequence */
- if (ref_dir == 1) {
- begin = refLen - 1;
- end = -1;
- step = -1;
- }
- for (i = begin; LIKELY(i != end); i += step) {
- int32_t cmp;
- __m128i e, vF = vZero; /* Initialize F value to 0.
- Any errors to vH values will be corrected in the Lazy_F loop.
- */
- __m128i vH = pvHStore[segLen - 1];
- vH = _mm_slli_si128 (vH, 2); /* Shift the 128-bit value in vH left by 2 byte. */
-
- /* Swap the 2 H buffers. */
- __m128i* pv = pvHLoad;
-
- __m128i vMaxColumn = vZero; /* vMaxColumn is used to record the max values of column i. */
-
- const __m128i* vP = vProfile + ref[i] * segLen; /* Right part of the vProfile */
- pvHLoad = pvHStore;
- pvHStore = pv;
-
- /* inner loop to process the query sequence */
- for (j = 0; LIKELY(j < segLen); j ++) {
- vH = _mm_adds_epi16(vH, _mm_load_si128(vP + j));
-
- /* Get max from vH, vE and vF. */
- e = _mm_load_si128(pvE + j);
- vH = _mm_max_epi16(vH, e);
- vH = _mm_max_epi16(vH, vF);
- vMaxColumn = _mm_max_epi16(vMaxColumn, vH);
-
- /* Save vH values. */
- _mm_store_si128(pvHStore + j, vH);
-
- /* Update vE value. */
- vH = _mm_subs_epu16(vH, vGapO); /* saturation arithmetic, result >= 0 */
- e = _mm_subs_epu16(e, vGapE);
- e = _mm_max_epi16(e, vH);
- _mm_store_si128(pvE + j, e);
-
- /* Update vF value. */
- vF = _mm_subs_epu16(vF, vGapE);
- vF = _mm_max_epi16(vF, vH);
-
- /* Load the next vH. */
- vH = _mm_load_si128(pvHLoad + j);
- }
-
- /* Lazy_F loop: has been revised to disallow adjecent insertion and then deletion, so don't update E(i, j), learn from SWPS3 */
- for (k = 0; LIKELY(k < 8); ++k) {
- vF = _mm_slli_si128 (vF, 2);
- for (j = 0; LIKELY(j < segLen); ++j) {
- vH = _mm_load_si128(pvHStore + j);
- vH = _mm_max_epi16(vH, vF);
- vMaxColumn = _mm_max_epi16(vMaxColumn, vH);
- _mm_store_si128(pvHStore + j, vH);
- vH = _mm_subs_epu16(vH, vGapO);
- vF = _mm_subs_epu16(vF, vGapE);
- if (UNLIKELY(! _mm_movemask_epi8(_mm_cmpgt_epi16(vF, vH)))) goto end;
- }
- }
-
-end:
- vMaxScore = _mm_max_epi16(vMaxScore, vMaxColumn);
- vTemp = _mm_cmpeq_epi16(vMaxMark, vMaxScore);
- cmp = _mm_movemask_epi8(vTemp);
- if (cmp != 0xffff) {
- uint16_t temp;
- vMaxMark = vMaxScore;
- max8(temp, vMaxScore);
- vMaxScore = vMaxMark;
-
- if (LIKELY(temp > max)) {
- max = temp;
- end_ref = i;
- for (j = 0; LIKELY(j < segLen); ++j) pvHmax[j] = pvHStore[j];
- }
- }
-
- /* Record the max score of current column. */
- max8(maxColumn[i], vMaxColumn);
- if (maxColumn[i] == terminate) break;
- }
-
- /* Trace the alignment ending position on read. */
- uint16_t *t = (uint16_t*)pvHmax;
- int32_t column_len = segLen * 8;
- for (i = 0; LIKELY(i < column_len); ++i, ++t) {
- int32_t temp;
- if (*t == max) {
- temp = i / 8 + i % 8 * segLen;
- if (temp < end_read) end_read = temp;
- }
- }
-
- free(pvHmax);
- free(pvE);
- free(pvHLoad);
- free(pvHStore);
-
- /* Find the most possible 2nd best alignment. */
- alignment_end* bests = (alignment_end*) calloc(2, sizeof(alignment_end));
- bests[0].score = max;
- bests[0].ref = end_ref;
- bests[0].read = end_read;
-
- bests[1].score = 0;
- bests[1].ref = 0;
- bests[1].read = 0;
-
- edge = (end_ref - maskLen) > 0 ? (end_ref - maskLen) : 0;
- for (i = 0; i < edge; i ++) {
- if (maxColumn[i] > bests[1].score) {
- bests[1].score = maxColumn[i];
- bests[1].ref = i;
- }
- }
- edge = (end_ref + maskLen) > refLen ? refLen : (end_ref + maskLen);
- for (i = edge; i < refLen; i ++) {
- if (maxColumn[i] > bests[1].score) {
- bests[1].score = maxColumn[i];
- bests[1].ref = i;
- }
- }
-
- free(maxColumn);
- free(end_read_column);
- return bests;
-}
-
-static cigar* banded_sw (const int8_t* ref,
- const int8_t* read,
- int32_t refLen,
- int32_t readLen,
- int32_t score,
- const uint32_t weight_gapO, /* will be used as - */
- const uint32_t weight_gapE, /* will be used as - */
- int32_t band_width,
- const int8_t* mat, /* pointer to the weight matrix */
- int32_t n) {
-
- uint32_t *c = (uint32_t*)malloc(16 * sizeof(uint32_t)), *c1;
- int32_t i, j, e, f, temp1, temp2, s = 16, s1 = 8, l, max = 0;
- int64_t s2 = 1024;
- char op, prev_op;
- int32_t width, width_d, *h_b, *e_b, *h_c;
- int8_t *direction, *direction_line;
- cigar* result = (cigar*)malloc(sizeof(cigar));
- h_b = (int32_t*)malloc(s1 * sizeof(int32_t));
- e_b = (int32_t*)malloc(s1 * sizeof(int32_t));
- h_c = (int32_t*)malloc(s1 * sizeof(int32_t));
- direction = (int8_t*)malloc(s2 * sizeof(int8_t));
-
- do {
- width = band_width * 2 + 3, width_d = band_width * 2 + 1;
- while (width >= s1) {
- ++s1;
- kroundup32(s1);
- h_b = (int32_t*)realloc(h_b, s1 * sizeof(int32_t));
- e_b = (int32_t*)realloc(e_b, s1 * sizeof(int32_t));
- h_c = (int32_t*)realloc(h_c, s1 * sizeof(int32_t));
- }
- while (width_d * readLen * 3 >= s2) {
- ++s2;
- kroundup32(s2);
- if (s2 < 0) {
- fprintf(stderr, "Alignment score and position are not consensus.\n");
- exit(1);
- }
- direction = (int8_t*)realloc(direction, s2 * sizeof(int8_t));
- }
- direction_line = direction;
- for (j = 1; LIKELY(j < width - 1); j ++) h_b[j] = 0;
- for (i = 0; LIKELY(i < readLen); i ++) {
- int32_t beg = 0, end = refLen - 1, u = 0, edge;
- j = i - band_width; beg = beg > j ? beg : j; // band start
- j = i + band_width; end = end < j ? end : j; // band end
- edge = end + 1 < width - 1 ? end + 1 : width - 1;
- f = h_b[0] = e_b[0] = h_b[edge] = e_b[edge] = h_c[0] = 0;
- direction_line = direction + width_d * i * 3;
-
- for (j = beg; LIKELY(j <= end); j ++) {
- int32_t b, e1, f1, d, de, df, dh;
- set_u(u, band_width, i, j); set_u(e, band_width, i - 1, j);
- set_u(b, band_width, i, j - 1); set_u(d, band_width, i - 1, j - 1);
- set_d(de, band_width, i, j, 0);
- set_d(df, band_width, i, j, 1);
- set_d(dh, band_width, i, j, 2);
-
- temp1 = i == 0 ? -weight_gapO : h_b[e] - weight_gapO;
- temp2 = i == 0 ? -weight_gapE : e_b[e] - weight_gapE;
- e_b[u] = temp1 > temp2 ? temp1 : temp2;
- //fprintf(stderr, "de: %d\twidth_d: %d\treadLen: %d\ts2:%d\n", de, width_d, readLen, s2);
- direction_line[de] = temp1 > temp2 ? 3 : 2;
-
- temp1 = h_c[b] - weight_gapO;
- temp2 = f - weight_gapE;
- f = temp1 > temp2 ? temp1 : temp2;
- direction_line[df] = temp1 > temp2 ? 5 : 4;
-
- e1 = e_b[u] > 0 ? e_b[u] : 0;
- f1 = f > 0 ? f : 0;
- temp1 = e1 > f1 ? e1 : f1;
- temp2 = h_b[d] + mat[ref[j] * n + read[i]];
- h_c[u] = temp1 > temp2 ? temp1 : temp2;
-
- if (h_c[u] > max) max = h_c[u];
-
- if (temp1 <= temp2) direction_line[dh] = 1;
- else direction_line[dh] = e1 > f1 ? direction_line[de] : direction_line[df];
- }
- for (j = 1; j <= u; j ++) h_b[j] = h_c[j];
- }
- band_width *= 2;
- } while (LIKELY(max < score));
- band_width /= 2;
-
- // trace back
- i = readLen - 1;
- j = refLen - 1;
- e = 0; // Count the number of M, D or I.
- l = 0; // record length of current cigar
- op = prev_op = 'M';
- temp2 = 2; // h
- while (LIKELY(i > 0)) {
- set_d(temp1, band_width, i, j, temp2);
- switch (direction_line[temp1]) {
- case 1:
- --i;
- --j;
- temp2 = 2;
- direction_line -= width_d * 3;
- op = 'M';
- break;
- case 2:
- --i;
- temp2 = 0; // e
- direction_line -= width_d * 3;
- op = 'I';
- break;
- case 3:
- --i;
- temp2 = 2;
- direction_line -= width_d * 3;
- op = 'I';
- break;
- case 4:
- --j;
- temp2 = 1;
- op = 'D';
- break;
- case 5:
- --j;
- temp2 = 2;
- op = 'D';
- break;
- default:
- fprintf(stderr, "Trace back error: %d.\n", direction_line[temp1 - 1]);
- free(direction);
- free(h_c);
- free(e_b);
- free(h_b);
- free(c);
- free(result);
- return 0;
- }
- if (op == prev_op) ++e;
- else {
- ++l;
- while (l >= s) {
- ++s;
- kroundup32(s);
- c = (uint32_t*)realloc(c, s * sizeof(uint32_t));
- }
- c[l - 1] = to_cigar_int(e, prev_op);
- prev_op = op;
- e = 1;
- }
- }
- if (op == 'M') {
- ++l;
- while (l >= s) {
- ++s;
- kroundup32(s);
- c = (uint32_t*)realloc(c, s * sizeof(uint32_t));
- }
- c[l - 1] = to_cigar_int(e + 1, op);
- }else {
- l += 2;
- while (l >= s) {
- ++s;
- kroundup32(s);
- c = (uint32_t*)realloc(c, s * sizeof(uint32_t));
- }
- c[l - 2] = to_cigar_int(e, op);
- c[l - 1] = to_cigar_int(1, 'M');
- }
-
- // reverse cigar
- c1 = (uint32_t*)malloc(l * sizeof(uint32_t));
- s = 0;
- e = l - 1;
- while (LIKELY(s <= e)) {
- c1[s] = c[e];
- c1[e] = c[s];
- ++ s;
- -- e;
- }
- result->seq = c1;
- result->length = l;
-
- free(direction);
- free(h_c);
- free(e_b);
- free(h_b);
- free(c);
- return result;
-}
-
-static int8_t* seq_reverse(const int8_t* seq, int32_t end) /* end is 0-based alignment ending position */
-{
- int8_t* reverse = (int8_t*)calloc(end + 1, sizeof(int8_t));
- int32_t start = 0;
- while (LIKELY(start <= end)) {
- reverse[start] = seq[end];
- reverse[end] = seq[start];
- ++ start;
- -- end;
- }
- return reverse;
-}
-
-s_profile* ssw_init (const int8_t* read, const int32_t readLen, const int8_t* mat, const int32_t n, const int8_t score_size) {
- s_profile* p = (s_profile*)calloc(1, sizeof(struct _profile));
- p->profile_byte = 0;
- p->profile_word = 0;
- p->bias = 0;
-
- if (score_size == 0 || score_size == 2) {
- /* Find the bias to use in the substitution matrix */
- int32_t bias = 0, i;
- for (i = 0; i < n*n; i++) if (mat[i] < bias) bias = mat[i];
- bias = abs(bias);
-
- p->bias = bias;
- p->profile_byte = qP_byte (read, mat, readLen, n, bias);
- }
- if (score_size == 1 || score_size == 2) p->profile_word = qP_word (read, mat, readLen, n);
- p->read = read;
- p->mat = mat;
- p->readLen = readLen;
- p->n = n;
- return p;
-}
-
-void init_destroy (s_profile* p) {
- free(p->profile_byte);
- free(p->profile_word);
- free(p);
-}
-
-s_align* ssw_align (const s_profile* prof,
- const int8_t* ref,
- int32_t refLen,
- const uint8_t weight_gapO,
- const uint8_t weight_gapE,
- const uint8_t flag, // (from high to low) bit 5: return the best alignment beginning position; 6: if (ref_end1 - ref_begin1 <= filterd) && (read_end1 - read_begin1 <= filterd), return cigar; 7: if max score >= filters, return cigar; 8: always return cigar; if 6 & 7 are both setted, only return cigar when both filter fulfilled
- const uint16_t filters,
- const int32_t filterd,
- const int32_t maskLen) {
-
- alignment_end* bests = 0, *bests_reverse = 0;
- __m128i* vP = 0;
- int32_t word = 0, band_width = 0, readLen = prof->readLen;
- int8_t* read_reverse = 0;
- cigar* path;
- s_align* r = (s_align*)calloc(1, sizeof(s_align));
- r->ref_begin1 = -1;
- r->read_begin1 = -1;
- r->cigar = 0;
- r->cigarLen = 0;
-// if (maskLen < 15) {
-// fprintf(stderr, "When maskLen < 15, the function ssw_align doesn't return 2nd best alignment information.\n");
-// }
-
- // Find the alignment scores and ending positions
- if (prof->profile_byte) {
- bests = sw_sse2_byte(ref, 0, refLen, readLen, weight_gapO, weight_gapE, prof->profile_byte, -1, prof->bias, maskLen);
- if (prof->profile_word && bests[0].score == 255) {
- free(bests);
- bests = sw_sse2_word(ref, 0, refLen, readLen, weight_gapO, weight_gapE, prof->profile_word, -1, maskLen);
- word = 1;
- } else if (bests[0].score == 255) {
- fprintf(stderr, "Please set 2 to the score_size parameter of the function ssw_init, otherwise the alignment results will be incorrect.\n");
- free(r);
- return NULL;
- }
- }else if (prof->profile_word) {
- bests = sw_sse2_word(ref, 0, refLen, readLen, weight_gapO, weight_gapE, prof->profile_word, -1, maskLen);
- word = 1;
- }else {
- fprintf(stderr, "Please call the function ssw_init before ssw_align.\n");
- free(r);
- return NULL;
- }
- r->score1 = bests[0].score;
- r->ref_end1 = bests[0].ref;
- r->read_end1 = bests[0].read;
- if (maskLen >= 15) {
- r->score2 = bests[1].score;
- r->ref_end2 = bests[1].ref;
- } else {
- r->score2 = 0;
- r->ref_end2 = -1;
- }
- free(bests);
- if (flag == 0 || (flag == 2 && r->score1 < filters)) goto end;
-
- // Find the beginning position of the best alignment.
- read_reverse = seq_reverse(prof->read, r->read_end1);
- if (word == 0) {
- vP = qP_byte(read_reverse, prof->mat, r->read_end1 + 1, prof->n, prof->bias);
- bests_reverse = sw_sse2_byte(ref, 1, r->ref_end1 + 1, r->read_end1 + 1, weight_gapO, weight_gapE, vP, r->score1, prof->bias, maskLen);
- } else {
- vP = qP_word(read_reverse, prof->mat, r->read_end1 + 1, prof->n);
- bests_reverse = sw_sse2_word(ref, 1, r->ref_end1 + 1, r->read_end1 + 1, weight_gapO, weight_gapE, vP, r->score1, maskLen);
- }
- free(vP);
- free(read_reverse);
- r->ref_begin1 = bests_reverse[0].ref;
- r->read_begin1 = r->read_end1 - bests_reverse[0].read;
- free(bests_reverse);
- if ((7&flag) == 0 || ((2&flag) != 0 && r->score1 < filters) || ((4&flag) != 0 && (r->ref_end1 - r->ref_begin1 > filterd || r->read_end1 - r->read_begin1 > filterd))) goto end;
-
- // Generate cigar.
- refLen = r->ref_end1 - r->ref_begin1 + 1;
- readLen = r->read_end1 - r->read_begin1 + 1;
- band_width = abs(refLen - readLen) + 1;
- path = banded_sw(ref + r->ref_begin1, prof->read + r->read_begin1, refLen, readLen, r->score1, weight_gapO, weight_gapE, band_width, prof->mat, prof->n);
- if (path == 0) {
- free(r);
- r = NULL;
- }
- else {
- r->cigar = path->seq;
- r->cigarLen = path->length;
- free(path);
- }
-
-end:
- return r;
-}
-
-void align_destroy (s_align* a) {
- free(a->cigar);
- free(a);
-}
-
-char cigar_int_to_op (uint32_t cigar_int)
-{
- uint8_t letter_code = cigar_int & 0xfU;
- static const char map[] = {
- 'M',
- 'I',
- 'D',
- 'N',
- 'S',
- 'H',
- 'P',
- '=',
- 'X',
- };
-
- if (letter_code >= (sizeof(map)/sizeof(map[0]))) {
- return 'M';
- }
-
- return map[letter_code];
-}
-
-uint32_t cigar_int_to_len (uint32_t cigar_int)
-{
- uint32_t res = cigar_int >> 4;
- return res;
-}
diff --git a/ext/src/ssw/ssw_cpp.cpp b/ext/src/ssw/ssw_cpp.cpp
deleted file mode 100644
index 21dde2a..0000000
--- a/ext/src/ssw/ssw_cpp.cpp
+++ /dev/null
@@ -1,477 +0,0 @@
-#include "ssw/ssw_cpp.h"
-#include "ssw/ssw.h"
-
-#include <sstream>
-
-namespace {
-
-static const int8_t kBaseTranslation[128] = {
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- // A C G
- 4, 0, 4, 1, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4,
- // T
- 4, 4, 4, 4, 3, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- // a c g
- 4, 0, 4, 1, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4,
- // t
- 4, 4, 4, 4, 3, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
-};
-
-void BuildSwScoreMatrix(const uint8_t& match_score,
- const uint8_t& mismatch_penalty,
- int8_t* matrix) {
-
- // The score matrix looks like
- // // A, C, G, T, N
- // score_matrix_ = { 2, -2, -2, -2, 0, // A
- // -2, 2, -2, -2, 0, // C
- // -2, -2, 2, -2, 0, // G
- // -2, -2, -2, 2, 0, // T
- // 0, 0, 0, 0, 0};// N
-
- int id = 0;
- for (int i = 0; i < 4; ++i) {
- for (int j = 0; j < 4; ++j) {
- matrix[id] = ((i == j) ? match_score : static_cast<int8_t>(-mismatch_penalty));
- ++id;
- }
- matrix[id] = 0;
- ++id;
- }
-
- for (int i = 0; i < 5; ++i)
- matrix[id++] = 0;
-
-}
-
-void ConvertAlignment(const s_align& s_al,
- const int& query_len,
- StripedSmithWaterman::Alignment* al) {
- al->sw_score = s_al.score1;
- al->sw_score_next_best = s_al.score2;
- al->ref_begin = s_al.ref_begin1;
- al->ref_end = s_al.ref_end1;
- al->query_begin = s_al.read_begin1;
- al->query_end = s_al.read_end1;
- al->ref_end_next_best = s_al.ref_end2;
-
- al->cigar.clear();
- al->cigar_string.clear();
-
- if (s_al.cigarLen > 0) {
- std::ostringstream cigar_string;
- if (al->query_begin > 0) {
- uint32_t cigar = to_cigar_int(al->query_begin, 'S');
- al->cigar.push_back(cigar);
- cigar_string << al->query_begin << 'S';
- }
-
- for (int i = 0; i < s_al.cigarLen; ++i) {
- al->cigar.push_back(s_al.cigar[i]);
- cigar_string << cigar_int_to_len(s_al.cigar[i]) << cigar_int_to_op(s_al.cigar[i]);
- }
-
- int end = query_len - al->query_end - 1;
- if (end > 0) {
- uint32_t cigar = to_cigar_int(end, 'S');
- al->cigar.push_back(cigar);
- cigar_string << end << 'S';
- }
-
- al->cigar_string = cigar_string.str();
- } // end if
-}
-
-// @Function:
-// Calculate the length of the previous cigar operator
-// and store it in new_cigar and new_cigar_string.
-// Clean up in_M (false), in_X (false), length_M (0), and length_X(0).
-void CleanPreviousMOperator(
- bool* in_M,
- bool* in_X,
- uint32_t* length_M,
- uint32_t* length_X,
- std::vector<uint32_t>* new_cigar,
- std::ostringstream* new_cigar_string) {
- if (*in_M) {
- uint32_t match = to_cigar_int(*length_M, '=');
- new_cigar->push_back(match);
- (*new_cigar_string) << *length_M << '=';
- } else if (*in_X){ //in_X
- uint32_t match = to_cigar_int(*length_X, 'X');
- new_cigar->push_back(match);
- (*new_cigar_string) << *length_X << 'X';
- }
-
- // Clean up
- *in_M = false;
- *in_X = false;
- *length_M = 0;
- *length_X = 0;
-}
-
-// @Function:
-// 1. Calculate the number of mismatches.
-// 2. Modify the cigar string:
-// differentiate matches (M) and mismatches(X).
-// Note that SSW does not differentiate matches and mismatches.
-// @Return:
-// The number of mismatches.
-int CalculateNumberMismatch(
- StripedSmithWaterman::Alignment* al,
- int8_t const *ref,
- int8_t const *query,
- const int& query_len) {
-
- ref += al->ref_begin;
- query += al->query_begin;
- int mismatch_length = 0;
-
- std::vector<uint32_t> new_cigar;
- std::ostringstream new_cigar_string;
-
- if (al->query_begin > 0) {
- uint32_t cigar = to_cigar_int(al->query_begin, 'S');
- new_cigar.push_back(cigar);
- new_cigar_string << al->query_begin << 'S';
- }
-
- bool in_M = false; // the previous is match
- bool in_X = false; // the previous is mismatch
- uint32_t length_M = 0;
- uint32_t length_X = 0;
-
- for (unsigned int i = 0; i < al->cigar.size(); ++i) {
- char op = cigar_int_to_op(al->cigar[i]);
- uint32_t length = cigar_int_to_len(al->cigar[i]);
- if (op == 'M') {
- for (uint32_t j = 0; j < length; ++j) {
- if (*ref != *query) {
- ++mismatch_length;
- if (in_M) { // the previous is match; however the current one is mismatche
- uint32_t match = to_cigar_int(length_M, '=');
- new_cigar.push_back(match);
- new_cigar_string << length_M << '=';
- }
- length_M = 0;
- ++length_X;
- in_M = false;
- in_X = true;
- } else { // *ref == *query
- if (in_X) { // the previous is mismatch; however the current one is matche
- uint32_t match = to_cigar_int(length_X, 'X');
- new_cigar.push_back(match);
- new_cigar_string << length_X << 'X';
- }
- ++length_M;
- length_X = 0;
- in_M = true;
- in_X = false;
- } // end of if (*ref != *query)
- ++ref;
- ++query;
- }
- } else if (op == 'I') {
- query += length;
- mismatch_length += length;
- CleanPreviousMOperator(&in_M, &in_X, &length_M, &length_X, &new_cigar, &new_cigar_string);
- new_cigar.push_back(al->cigar[i]);
- new_cigar_string << length << 'I';
- } else if (op == 'D') {
- ref += length;
- mismatch_length += length;
- CleanPreviousMOperator(&in_M, &in_X, &length_M, &length_X, &new_cigar, &new_cigar_string);
- new_cigar.push_back(al->cigar[i]);
- new_cigar_string << length << 'D';
- }
- }
-
- CleanPreviousMOperator(&in_M, &in_X, &length_M, &length_X, &new_cigar, &new_cigar_string);
-
- int end = query_len - al->query_end - 1;
- if (end > 0) {
- uint32_t cigar = to_cigar_int(end, 'S');
- new_cigar.push_back(cigar);
- new_cigar_string << end << 'S';
- }
-
- al->cigar_string.clear();
- al->cigar.clear();
- al->cigar_string = new_cigar_string.str();
- al->cigar = new_cigar;
-
- return mismatch_length;
-}
-
-void SetFlag(const StripedSmithWaterman::Filter& filter, uint8_t* flag) {
- if (filter.report_begin_position) *flag |= 0x08;
- if (filter.report_cigar) *flag |= 0x0f;
-}
-
-// http://www.cplusplus.com/faq/sequences/arrays/sizeof-array/#cpp
-template <typename T, size_t N>
-inline size_t SizeOfArray( const T(&)[ N ] )
-{
- return N;
-}
-
-} // namespace
-
-
-
-namespace StripedSmithWaterman {
-
-Aligner::Aligner(void)
- : score_matrix_(NULL)
- , score_matrix_size_(5)
- , translation_matrix_(NULL)
- , match_score_(2)
- , mismatch_penalty_(2)
- , gap_opening_penalty_(3)
- , gap_extending_penalty_(1)
- , translated_reference_(NULL)
- , reference_length_(0)
-{
- BuildDefaultMatrix();
-}
-
-Aligner::Aligner(
- const uint8_t& match_score,
- const uint8_t& mismatch_penalty,
- const uint8_t& gap_opening_penalty,
- const uint8_t& gap_extending_penalty)
-
- : score_matrix_(NULL)
- , score_matrix_size_(5)
- , translation_matrix_(NULL)
- , match_score_(match_score)
- , mismatch_penalty_(mismatch_penalty)
- , gap_opening_penalty_(gap_opening_penalty)
- , gap_extending_penalty_(gap_extending_penalty)
- , translated_reference_(NULL)
- , reference_length_(0)
-{
- BuildDefaultMatrix();
-}
-
-Aligner::Aligner(const int8_t* score_matrix,
- const int& score_matrix_size,
- const int8_t* translation_matrix,
- const int& translation_matrix_size)
-
- : score_matrix_(NULL)
- , score_matrix_size_(score_matrix_size)
- , translation_matrix_(NULL)
- , match_score_(2)
- , mismatch_penalty_(2)
- , gap_opening_penalty_(3)
- , gap_extending_penalty_(1)
- , translated_reference_(NULL)
- , reference_length_(0)
-{
- score_matrix_ = new int8_t[score_matrix_size_ * score_matrix_size_];
- memcpy(score_matrix_, score_matrix, sizeof(int8_t) * score_matrix_size_ * score_matrix_size_);
- translation_matrix_ = new int8_t[translation_matrix_size];
- memcpy(translation_matrix_, translation_matrix, sizeof(int8_t) * translation_matrix_size);
-}
-
-
-Aligner::~Aligner(void){
- Clear();
-}
-
-int Aligner::SetReferenceSequence(const char* seq, const int& length) {
-
- int len = 0;
- if (translation_matrix_) {
- // calculate the valid length
- //int calculated_ref_length = static_cast<int>(strlen(seq));
- //int valid_length = (calculated_ref_length > length)
- // ? length : calculated_ref_length;
- int valid_length = length;
- // delete the current buffer
- CleanReferenceSequence();
- // allocate a new buffer
- translated_reference_ = new int8_t[valid_length];
-
- len = TranslateBase(seq, valid_length, translated_reference_);
- } else {
- // nothing
- }
-
- reference_length_ = len;
- return len;
-
-
-}
-
-int Aligner::TranslateBase(const char* bases, const int& length,
- int8_t* translated) const {
-
- const char* ptr = bases;
- int len = 0;
- for (int i = 0; i < length; ++i) {
- translated[i] = translation_matrix_[(int) *ptr];
- ++ptr;
- ++len;
- }
-
- return len;
-}
-
-
-bool Aligner::Align(const char* query, const Filter& filter,
- Alignment* alignment) const
-{
- if (!translation_matrix_) return false;
- if (reference_length_ == 0) return false;
-
- int query_len = strlen(query);
- if (query_len == 0) return false;
- int8_t* translated_query = new int8_t[query_len];
- TranslateBase(query, query_len, translated_query);
-
- const int8_t score_size = 2;
- s_profile* profile = ssw_init(translated_query, query_len, score_matrix_,
- score_matrix_size_, score_size);
-
- uint8_t flag = 0;
- SetFlag(filter, &flag);
- s_align* s_al = ssw_align(profile, translated_reference_, reference_length_,
- static_cast<int>(gap_opening_penalty_),
- static_cast<int>(gap_extending_penalty_),
- flag, filter.score_filter, filter.distance_filter, query_len);
-
- alignment->Clear();
- ConvertAlignment(*s_al, query_len, alignment);
- alignment->mismatches = CalculateNumberMismatch(&*alignment, translated_reference_, translated_query, query_len);
-
-
- // Free memory
- delete [] translated_query;
- align_destroy(s_al);
- init_destroy(profile);
-
- return true;
-}
-
-
-bool Aligner::Align(const char* query, const char* ref, const int& ref_len,
- const Filter& filter, Alignment* alignment) const
-{
- if (!translation_matrix_) return false;
-
- int query_len = strlen(query);
- if (query_len == 0) return false;
- int8_t* translated_query = new int8_t[query_len];
- TranslateBase(query, query_len, translated_query);
-
- // calculate the valid length
- //int calculated_ref_length = static_cast<int>(strlen(ref));
- //int valid_ref_len = (calculated_ref_length > ref_len)
- // ? ref_len : calculated_ref_length;
- int valid_ref_len = ref_len;
- int8_t* translated_ref = new int8_t[valid_ref_len];
- TranslateBase(ref, valid_ref_len, translated_ref);
-
-
- const int8_t score_size = 2;
- s_profile* profile = ssw_init(translated_query, query_len, score_matrix_,
- score_matrix_size_, score_size);
-
- uint8_t flag = 0;
- SetFlag(filter, &flag);
- s_align* s_al = ssw_align(profile, translated_ref, valid_ref_len,
- static_cast<int>(gap_opening_penalty_),
- static_cast<int>(gap_extending_penalty_),
- flag, filter.score_filter, filter.distance_filter, query_len);
-
- alignment->Clear();
- ConvertAlignment(*s_al, query_len, alignment);
- alignment->mismatches = CalculateNumberMismatch(&*alignment, translated_ref, translated_query, query_len);
-
- // Free memory
- delete [] translated_query;
- delete [] translated_ref;
- align_destroy(s_al);
- init_destroy(profile);
-
- return true;
-}
-
-void Aligner::Clear(void) {
- ClearMatrices();
- CleanReferenceSequence();
-}
-
-void Aligner::SetAllDefault(void) {
- score_matrix_size_ = 5;
- match_score_ = 2;
- mismatch_penalty_ = 2;
- gap_opening_penalty_ = 3;
- gap_extending_penalty_ = 1;
- reference_length_ = 0;
-}
-
-bool Aligner::ReBuild(void) {
- if (translation_matrix_) return false;
-
- SetAllDefault();
- BuildDefaultMatrix();
-
- return true;
-}
-
-bool Aligner::ReBuild(
- const uint8_t& match_score,
- const uint8_t& mismatch_penalty,
- const uint8_t& gap_opening_penalty,
- const uint8_t& gap_extending_penalty) {
- if (translation_matrix_) return false;
-
- SetAllDefault();
-
- match_score_ = match_score;
- mismatch_penalty_ = mismatch_penalty;
- gap_opening_penalty_ = gap_opening_penalty;
- gap_extending_penalty_ = gap_extending_penalty;
-
- BuildDefaultMatrix();
-
- return true;
-}
-
-bool Aligner::ReBuild(
- const int8_t* score_matrix,
- const int& score_matrix_size,
- const int8_t* translation_matrix,
- const int& translation_matrix_size) {
-
- ClearMatrices();
- score_matrix_ = new int8_t[score_matrix_size_ * score_matrix_size_];
- memcpy(score_matrix_, score_matrix, sizeof(int8_t) * score_matrix_size_ * score_matrix_size_);
- translation_matrix_ = new int8_t[translation_matrix_size];
- memcpy(translation_matrix_, translation_matrix, sizeof(int8_t) * translation_matrix_size);
-
- return true;
-}
-
-void Aligner::BuildDefaultMatrix(void) {
- ClearMatrices();
- score_matrix_ = new int8_t[score_matrix_size_ * score_matrix_size_];
- BuildSwScoreMatrix(match_score_, mismatch_penalty_, score_matrix_);
- translation_matrix_ = new int8_t[SizeOfArray(kBaseTranslation)];
- memcpy(translation_matrix_, kBaseTranslation, sizeof(int8_t) * SizeOfArray(kBaseTranslation));
-}
-
-void Aligner::ClearMatrices(void) {
- delete [] score_matrix_;
- score_matrix_ = NULL;
-
- delete [] translation_matrix_;
- translation_matrix_ = NULL;
-}
-} // namespace StripedSmithWaterman
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/spades.git
More information about the debian-med-commit
mailing list