Compare commits

...
962 Commits
Author SHA1 Message Date
Ryan Curtin 384912f38f Update and release version 2.18.2. 2022-02-14 09:36:35 -05:00
Marcus Edel f077ea57e5 Report the correct epoch time in seconds. (#337) 2022-02-12 05:27:13 +01:00
Conrad Sanderson f75b532d16 update Catch2 to 2.13.8 (#336) 2022-02-02 04:12:47 +01:00
Marcus Edel a652ca2ce5 Add new block for next release to HISTORY.md. 2021-11-20 11:32:46 -05:00
Marcus Edel bf42276c5a Update and release version 2.18.1. 2021-11-20 11:32:46 -05:00
Marcus Edel c35e78e489 SCD partial gradient test fix (#332) 2021-11-19 04:24:23 +01:00
Conrad Sanderson d811ff9738 avoid infinite loop for single-precision matrices (#331) 2021-11-17 15:01:01 +01:00
Marcus Edel 525dd6d961 Merge pull request #330 from zoq/sgd-test-break
Accelerate SGD test time by skipping additional trials.
2021-11-15 21:15:44 -05:00
Marcus Edel 025095a180 Accelerate SGD test time by skiping additional trials. 2021-11-12 23:11:41 -05:00
Marcus Edel c493c55e2e Add new block for next release to HISTORY.md. 2021-10-21 19:45:07 -04:00
Marcus Edel ac933c5dba Update and release version 2.18.0. 2021-10-21 19:45:07 -04:00
Conrad Sanderson ee3f0e1ea2 Merge pull request #327
Fix MOEAD test stability
2021-10-20 04:52:48 +02:00
Ryan CurtinandMarcus Edel 7a8c5ae685 Apply suggestions from code review
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-10-18 11:37:18 -04:00
Ryan Curtin bd285743b3 Some cleanup. 2021-10-18 10:29:23 -04:00
Ryan Curtin 23aab9f924 Factor out constant things from the loop. 2021-10-18 10:07:02 -04:00
Ryan Curtin df3a1cf347 Update HISTORY for #324 too. 2021-10-18 10:02:17 -04:00
Ryan Curtin f3b0224187 Update HISTORY. 2021-10-16 13:02:44 -04:00
Ryan Curtin d58258ff6c Fix MOEAD test stability. 2021-10-16 12:58:29 -04:00
Conrad Sanderson 99de75ce7c Merge pull request #325
Fix for C++20 constructor template argument deprecation
2021-10-14 11:19:23 +02:00
Eliane Briand 0f634056d0 Fix for C++20 constructor template argument deprecation 2021-10-13 15:03:33 +02:00
Conrad Sanderson 1db28cf195 Merge pull request #323
more approachable and impactful blurb to match description on website
2021-10-12 07:09:45 +02:00
Conrad Sanderson a04945ea8b simplify blurb to match description on website 2021-10-11 04:21:26 +02:00
Conrad Sanderson 0c1d98d11c Update Catch2 to 2.13.7 (#322) 2021-09-21 03:46:57 +02:00
Marcus Edel cf434a0ed7 Update history. 2021-09-19 12:39:10 -04:00
Marcus Edel 6ec037e7bb Update Catch2 to 2.13.7. 2021-09-19 12:35:54 -04:00
Conrad Sanderson 38e5c691e9 Revert "Add citation file"
This reverts commit 8f074a421a.
2021-09-07 03:04:21 +02:00
Marcus Edel 8f074a421a Add citation file. (#317) 2021-09-06 02:03:00 +02:00
Marcus Edel 1490193fb0 GradClipByValue callback (#315) 2021-08-31 06:53:03 +02:00
Marcus Edel 1208c62381 Bump minimum Armadillo version to 9.800. (#318)
* Bump minimum Armadillo version to 9.800.
* Update history.
* Download armadillo from the offical source (sourceforge).
2021-08-30 03:58:17 +02:00
Ryan Curtin f90ccda31d Merge pull request #316 from mlpack/conradsnicta-citation-update
update citation to JMLR paper
2021-08-15 15:08:10 -04:00
Conrad Sanderson bf77ef6bde update citation to JMLR paper 2021-08-14 05:21:14 +02:00
Conrad Sanderson 8b4cadf3ab Merge pull request #314 from zoq/travis-update
Update travis config to build the ensmallen tests
2021-08-09 04:51:48 +02:00
Conrad Sanderson c3f71b8099 Merge pull request #313 from zoq/test-build
The BUILD_TESTS option was replaced with 'make ensmallen_tests'.
2021-08-09 04:50:47 +02:00
Marcus Edel 9e8696bdb1 Do not fail the build on a warning. 2021-08-06 18:13:20 +02:00
Marcus Edel 122be35c0f Update travis config to build the ensmallen tests. 2021-08-06 02:58:39 +02:00
Marcus Edel b92e576f88 Update history. 2021-08-05 03:20:51 +02:00
Marcus Edel 7b0e36ec3b The BUILD_TESTS option was replaced with 'make ensmallen_tests'. 2021-08-04 05:09:46 +02:00
Ryan Curtin 237daa9c78 Merge pull request #310 from jonpsy/release-2.17.0
Release version 2.17.0: "Pachis Din Me Pesa Double"
2021-07-06 14:59:06 -04:00
Nanubala Gnana Sai c45abbdd9f Add new block for next release to HISTORY.md. 2021-07-06 16:09:25 +00:00
Nanubala Gnana Sai 9bd4bc2527 Update and release version 2.17.0. 2021-07-06 16:09:25 +00:00
Nanubala Gnana Sai 000d4c8488 Update HISTORY.md for release 2.17.0. 2021-07-06 16:08:50 +00:00
Conrad Sanderson b7aab43451 Merge pull request #299 from jonpsy/iterate-moead
Repair MOEAD
2021-07-05 14:43:36 +02:00
Marcus Edel ee8e1601bb Merge pull request #306 from jonpsy/nsga2-speed
Reduce LOC of NSGA-II.
2021-07-04 12:10:41 -04:00
Conrad Sanderson ec114f1904 Merge pull request #305 from mlpack/conradsnicta-init-fixes
various fixes for matrix initialisation
2021-07-02 05:34:37 +02:00
Conrad Sanderson 7582788d14 fix PR number 2021-07-02 05:32:20 +02:00
Nanubala Gnana SaiandMarcus Edel 3b78ab0d43 Update include/ensmallen_bits/nsga2/nsga2_impl.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-07-01 22:13:17 +05:30
Nanubala Gnana Sai 3b4015c289 Update nsga2_impl.hpp
fix indent again
2021-07-01 21:57:09 +05:30
Nanubala Gnana Sai 0dd2b4c6fc Update nsga2_impl.hpp
fix indent
2021-07-01 21:56:23 +05:30
Nanubala Gnana Sai 0873d4a3b9 done changes. 2021-07-01 16:24:11 +00:00
Conrad Sanderson e5f2ca2553 update HISTORY.md 2021-07-01 13:50:39 +02:00
Nanubala Gnana Sai f4da19da12 resize => set_size 2021-07-01 04:51:57 +00:00
Conrad Sanderson 055ebfd3e9 use fill::none to avoid default zeroing 2021-07-01 05:45:17 +02:00
Conrad Sanderson 777fb6ac36 explicitly initialise to zeros 2021-07-01 05:38:54 +02:00
Conrad Sanderson d6ffdc59fa avoid zeroing twice 2021-07-01 05:31:53 +02:00
Conrad Sanderson ba167cefa0 use fill::none to avoid default zeroing 2021-07-01 05:21:18 +02:00
Nanubala Gnana Sai 6d4914ab72 remove unneccessary evaluate() call 2021-07-01 01:39:00 +00:00
Conrad Sanderson 44bb57ceb6 Merge pull request #304 from rcurtin/readd-deprecated-front
Add Front() back into the NSGA2 class.
2021-06-30 04:00:30 +02:00
Ryan Curtin 83bc231e1b Remove unused variables. 2021-06-28 13:38:49 -04:00
Ryan Curtin 9906c22d62 Use 3.x as the version number. 2021-06-28 11:51:24 -04:00
Ryan Curtin 4faea9791a Merge pull request #303 from mlpack/conradsnicta-dont-build-tests-by-default
don't build tests by default
2021-06-28 11:46:31 -04:00
Ryan Curtin 4c0accde96 Add Front() back into the NSGA2 class. 2021-06-28 11:43:15 -04:00
Conrad Sanderson 7a870142d0 update HISTORY.md 2021-06-27 07:06:24 +02:00
Conrad Sanderson a622a767de fix minor typo 2021-06-27 06:59:09 +02:00
Conrad Sanderson 735ae35521 building tests is now optional
- state that building tests is now optional
- show how to build and run the tests
2021-06-27 06:53:04 +02:00
Conrad Sanderson f51bfd71e7 don't build ensmallen_tests as part of make all 2021-06-27 06:43:53 +02:00
Nanubala Gnana Sai 9d55d24b3c Update pbi_decomposition.hpp
Use default arma::norm p value.
2021-06-26 01:35:02 +05:30
Marcus Edel 176aea6ef9 Merge pull request #298 from jonpsy/zdt_fix
ZDT4 Evaluate Fix.
2021-06-25 14:54:12 -04:00
jonpsy 9cad4a5d24 L2 norm not L1. 2021-06-25 20:09:49 +05:30
Ryan Curtin e6406a5c9a Merge pull request #300 from mlpack/README-improved-install-instructions
improved installation and compilation instructions
2021-06-24 10:35:40 -04:00
Conrad Sanderson a0137b07bb adjust line lengths to 80 chars max
this is to make editing on phones easier :)
2021-06-24 15:43:25 +02:00
Conrad Sanderson af145271ba Merge branch 'master' into README-improved-install-instructions 2021-06-24 15:34:55 +02:00
Conrad Sanderson c0b361d88a fix merge clashes 2021-06-24 15:31:51 +02:00
Ryan Curtin 14e1717b8d Merge pull request #302 from jonpsy/history
Modify HISTORY.md release history
2021-06-24 09:06:50 -04:00
jonpsy 0a53dcf7a6 Fix main Evaluate() 2021-06-24 09:49:54 +05:30
jonpsy 3921d34db0 Move up for next release. 2021-06-24 09:04:11 +05:30
Marcus Edel 9232017bd5 Merge pull request #296 from jonpsy/dirichlet
Add Dirichlet Weight Initialization.
2021-06-23 15:54:18 -04:00
Nanubala Gnana Sai 9835cd1149 Update optimizers.md 2021-06-24 00:11:03 +05:30
Nanubala Gnana Sai 96006fa6b2 Merge branch 'master' into dirichlet 2021-06-24 00:08:45 +05:30
Marcus Edel 86cf8f3edb Merge pull request #295 from jonpsy/uniform
Add Das-Dennis weight initialization method.
2021-06-23 14:23:59 -04:00
Conrad Sanderson 0678b0518a change "automatic" to "cmake based"
clarify wording, as the cmake installation isn't really automatic (still need to type commands)
2021-06-23 16:44:31 +02:00
Conrad Sanderson bb18d79413 automatic installation before manual installation
* place automatic installation instructions before manual installation instructions
* adapt text to improve flow
* fix bug in path for cmake non-root installation
2021-06-23 16:35:30 +02:00
NanuSai 7ce177996a frontIndices should be a vector. 2021-06-23 17:54:31 +05:30
jonpsy 8ac18870ef Add source of GFG code. 2021-06-23 14:39:27 +05:30
Conrad Sanderson 3c1bad105c update HISTORY.md 2021-06-23 04:47:20 +02:00
Conrad Sanderson 30bf5d2a67 improved installation and compilation instructions
Improved installation and compilation instructions:
* show how to install manually (in addition to cmake)
* show how to install with and without root access
* added example compilation commands, using standard and non-standard installation directories
2021-06-23 04:06:59 +02:00
jonpsy 5b8fcdf2f9 Set iterate after optimization ends. 2021-06-22 22:41:49 +05:30
jonpsy c585d2e377 HISTORY change isn't required. 2021-06-22 22:21:06 +05:30
jonpsy f108cc51ca history added. 2021-06-22 22:14:12 +05:30
jonpsy edb7e15229 truncatedCoords should be MatType. 2021-06-22 22:11:00 +05:30
Nanubala Gnana SaiandMarcus Edel bb893f683c Update include/ensmallen_bits/moead/weight_init_policies/uniform_init.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-22 00:33:48 +05:30
NanuSai b9b011ea01 Test against ZDT3
Add DirichletMOEAD
2021-06-19 01:03:30 +05:30
NanuSai 3268605bd7 Merge branch 'uniform' of https://github.com/jonpsy/ensmallen into uniform 2021-06-19 00:07:34 +05:30
NanuSai 239916188f add BBSMOEAD 2021-06-19 00:07:16 +05:30
Nanubala Gnana SaiandMarcus Edel 4f297c7abd Update include/ensmallen_bits/moead/weight_init_policies/uniform_init.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-18 23:52:22 +05:30
Nanubala Gnana SaiandMarcus Edel cb3dc29b09 Update include/ensmallen_bits/moead/weight_init_policies/uniform_init.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-18 21:13:34 +05:30
Nanubala Gnana SaiandMarcus Edel 50f1245e01 Update include/ensmallen_bits/moead/weight_init_policies/uniform_init.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-18 21:13:28 +05:30
Nanubala Gnana SaiandMarcus Edel 3c0b4673b4 Update include/ensmallen_bits/moead/weight_init_policies/uniform_init.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-18 21:13:22 +05:30
NanuSai cf38624cf5 added history 2021-06-18 19:34:35 +05:30
NanuSai fde96643fc added in optimizers.md
tests are passing
2021-06-18 19:32:14 +05:30
NanuSai ee1bb9760a Added dirichilet 2021-06-18 19:31:11 +05:30
NanuSai f9c5d7f3d6 revert to normal 2021-06-18 19:05:59 +05:30
NanuSai d98f82599b nit 2021-06-18 19:04:36 +05:30
NanuSai a8c664ece0 oldschool 2021-06-18 18:59:18 +05:30
NanuSai 7ebc527c09 minor indent fix 2021-06-18 18:42:18 +05:30
NanuSai dbfcf7e20f RDP test 2021-06-18 18:20:51 +05:30
NanuSai cf1a9e7e03 document in optimizers.md 2021-06-18 18:14:23 +05:30
NanuSai 501d486fa3 add history 2021-06-18 18:11:28 +05:30
NanuSai 275ded335d Add the braces 2021-06-18 18:09:54 +05:30
NanuSai d7be57a90b fix test params 2021-06-18 18:09:54 +05:30
NanuSai 96a1998ab6 efficient Binomial coefficient O(n) 2021-06-18 18:09:54 +05:30
NanuSai 60f92647a2 => Added uniform init
=> Use 300 instead of 150 population
=> DefaultMOEAD = MOEAD<Uniform, Tchebycheff>
2021-06-18 18:09:54 +05:30
Marcus Edel 0af8004ff9 Merge pull request #293 from jonpsy/moead+
Introduce Policy Methods for MOEA/D-DE.
2021-06-18 08:26:14 -04:00
NanuSai ff03b06848 restore cmake 2021-06-17 00:40:50 +05:30
NanuSai bd6cf8a116 Set bad threshold as of now. 2021-06-17 00:04:23 +05:30
NanuSai 18a4ca67e8 revert appveyor.yml 2021-06-16 23:59:07 +05:30
NanuSai a8b9018d83 use arma::diff 2021-06-16 23:52:31 +05:30
NanuSai 91ed336d0f remove stackoverflow link 2021-06-16 23:41:54 +05:30
NanuSai d66c3d0ca9 Merge branch 'moead+' of https://github.com/jonpsy/ensmallen into moead+ 2021-06-16 23:40:04 +05:30
NanuSai e3b865fcf0 revert moead test 2021-06-16 23:26:47 +05:30
Nanubala Gnana SaiandMarcus Edel e2b883dbda Update include/ensmallen_bits/moead/moead_impl.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-16 23:24:16 +05:30
Nanubala Gnana SaiandMarcus Edel 955e7db555 Update include/ensmallen_bits/moead/weight_init_policies/bbs_init.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-16 22:35:18 +05:30
Nanubala Gnana SaiandMarcus Edel d7f2be2adb Update include/ensmallen_bits/moead/moead.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-16 22:35:06 +05:30
Nanubala Gnana SaiandMarcus Edel 79aa3f637a Update include/ensmallen_bits/moead/decomposition_policies/pbi_decomposition.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-16 22:34:56 +05:30
Nanubala Gnana SaiandMarcus Edel c1fbf16247 Update include/ensmallen_bits/moead/decomposition_policies/weighted_decomposition.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-16 22:34:46 +05:30
Nanubala Gnana SaiandMarcus Edel be9f8b6346 Update include/ensmallen_bits/moead/decomposition_policies/tchebycheff_decomposition.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-16 22:34:35 +05:30
Nanubala Gnana SaiandMarcus Edel 7d86a46a7b Update include/ensmallen_bits/moead/decomposition_policies/pbi_decomposition.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-16 22:34:26 +05:30
Nanubala Gnana Sai c79f593ff2 no need to build redundant tests 2021-06-16 15:39:39 +00:00
Nanubala Gnana Sai 40c9aaad7f Start RDP 2021-06-16 15:38:32 +00:00
NanuSai 23ff19074a minor fix 2021-06-16 11:53:04 +05:30
NanuSai 77bd44bed3 added template doc in optimizer.md 2021-06-16 11:16:11 +05:30
NanuSai d02d5e46aa extra doc for decomp policy 2021-06-16 10:55:02 +05:30
NanuSai 4997f550d2 add doc for bbs 2021-06-16 10:54:43 +05:30
NanuSai 8d81b422d2 indent 2021-06-16 10:47:06 +05:30
NanuSai 6e3e323654 doc decomposition policy 2021-06-16 10:42:54 +05:30
NanuSai de612d3d09 using DefaultMOEAD 2021-06-16 10:30:08 +05:30
NanuSai 9beaa5f0d4 InitPolicy, Generate const 2021-06-16 10:29:02 +05:30
Nanubala Gnana SaiandMarcus Edel 2c02c5f969 Update include/ensmallen_bits/moead/decomposition_policies/tchebycheff_decomposition.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-16 10:25:43 +05:30
Nanubala Gnana SaiandMarcus Edel 8952378a04 Update include/ensmallen_bits/moead/decomposition_policies/weighted_decomposition.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-16 10:25:37 +05:30
Nanubala Gnana SaiandMarcus Edel 4ec1f2e430 Update include/ensmallen_bits/moead/moead.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-16 10:25:30 +05:30
Nanubala Gnana SaiandMarcus Edel ade51c915b Update include/ensmallen_bits/moead/decomposition_policies/pbi_decomposition.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-16 10:25:23 +05:30
Nanubala Gnana SaiandMarcus Edel e092c4d262 Update include/ensmallen_bits/moead/moead.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-16 08:54:03 +05:30
Nanubala Gnana SaiandMarcus Edel 4692047af2 Update include/ensmallen_bits/moead/moead.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-16 08:53:44 +05:30
Nanubala Gnana SaiandMarcus Edel cfed986674 Update include/ensmallen_bits/moead/moead.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-16 08:53:26 +05:30
NanuSai 6e1164e952 remove uniform_init.hpp as of now 2021-06-16 08:43:58 +05:30
NanuSai ee41faad7d Tested against ZDT1 2021-06-16 08:24:02 +05:30
NanuSai 945e21abb5 history fix 2021-06-16 08:19:16 +05:30
NanuSai 6868e2ca94 restore all tests 2021-06-16 08:06:07 +05:30
NanuSai dbc24bbe4c moead doc fix 2021-06-16 08:06:07 +05:30
NanuSai 7505ecc6c7 fix decomposition policy docs 2021-06-16 08:06:07 +05:30
NanuSai e08c0c86c3 fix moead doc 2021-06-16 08:06:07 +05:30
NanuSai 9242279aba Re-configure tests 2021-06-16 08:06:07 +05:30
NanuSai d41c265202 Added Init policies
=> BayesianBootStrap : Working
=> Uniform : **NOT WORKING**
2021-06-16 08:06:07 +05:30
NanuSai 2749d31e7e Added decomposition policies
=> PBI
=> Tchebycheff
=> Weighted
2021-06-16 08:06:07 +05:30
NanuSai c66ee3a098 Make MOEA/D-DE policy based 2021-06-16 08:06:07 +05:30
NanuSai 9e6b3cad22 Fixed minor indent 2021-06-16 08:06:07 +05:30
Marcus Edel 3497f276f4 Merge pull request #269 from jonpsy/moead
Implement MOEA/D - DE.
2021-06-15 15:07:30 -04:00
Marcus Edel db90638fb3 Merge pull request #273 from jonpsy/ZDT
Adding ZDT Test Suite.
2021-06-14 12:30:44 -04:00
Nanubala Gnana SaiandMarcus Edel 973d4a7bcc Update include/ensmallen_bits/moead/moead.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-13 09:17:14 +05:30
Nanubala Gnana SaiandMarcus Edel da7683b770 Update include/ensmallen_bits/moead/moead_impl.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-13 09:17:04 +05:30
Nanubala Gnana SaiandMarcus Edel 5cd6bc8c29 Update tests/moead_test.cpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-13 09:16:56 +05:30
Nanubala Gnana SaiandMarcus Edel 40e44d4ede Update include/ensmallen_bits/moead/moead_impl.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-13 09:16:47 +05:30
Nanubala Gnana SaiandMarcus Edel 7d794cb4bc Update include/ensmallen_bits/moead/moead_impl.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-13 09:16:40 +05:30
Nanubala Gnana SaiandMarcus Edel a2a7ef166b Update include/ensmallen_bits/moead/moead_impl.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-13 09:16:03 +05:30
Nanubala Gnana SaiandMarcus Edel b1fa440fda Update include/ensmallen_bits/moead/moead_impl.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-13 09:15:39 +05:30
NanuSai e893dfd3ee weights are fixed bruh 2021-06-12 19:27:03 +05:30
NanuSai 53cae18ff6 fix default arg in ctor
fix callback test
2021-06-12 10:42:04 +05:30
NanuSai b7178fef0e Added epsilon to docs 2021-06-12 10:28:51 +05:30
NanuSai edd089a72b 2. => 2.0 2021-06-12 10:22:03 +05:30
NanuSai 60d19c48d7 if( 2021-06-12 10:21:19 +05:30
NanuSai 287bf825fa style fix 2021-06-12 10:20:49 +05:30
Nanubala Gnana Sai 5d9e73c139 Update moead_impl.hpp
Another day, another indent
2021-06-12 10:14:42 +05:30
NanuSai aa54aade4a BaseMatType 2021-06-12 10:02:13 +05:30
NanuSai b0c4c1b7b1 reorder tests 2021-06-12 09:59:26 +05:30
NanuSai 3267c42e4d RequireDenseFloatingCheck 2021-06-12 09:58:26 +05:30
NanuSai a646f7c136 re-ordered state variables 2021-06-12 09:55:29 +05:30
NanuSai 81e07bf455 minor style + numobjectives remvoed from opt 2021-06-12 09:37:21 +05:30
NanuSai 604209a0f7 added epsilon 2021-06-12 09:00:30 +05:30
NanuSai 1dadc1bbb0 delta indent fix 2021-06-12 08:46:53 +05:30
NanuSai 80fbf6c9e8 Mate fix 2021-06-12 08:46:30 +05:30
NanuSai ad9f355503 Mating more clear 2021-06-12 08:32:22 +05:30
Nanubala Gnana Sai 27404cdaad Update moead_impl.hpp 2021-06-12 00:25:33 +05:30
Nanubala Gnana Sai cf850f50d1 Update moead_impl.hpp
pick is const
2021-06-12 00:23:33 +05:30
Nanubala Gnana Sai 9d93405f5b Update moead_impl.hpp
delta should be generated per gene.
2021-06-12 00:23:02 +05:30
Nanubala Gnana SaiandMarcus Edel 4824e72f93 Update include/ensmallen_bits/moead/moead_impl.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-11 23:09:17 +05:30
Nanubala Gnana SaiandMarcus Edel 3404708708 Update include/ensmallen_bits/moead/moead_impl.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-11 23:09:09 +05:30
Nanubala Gnana SaiandMarcus Edel 4e4fa69b08 Update include/ensmallen_bits/moead/moead_impl.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-11 23:08:56 +05:30
Nanubala Gnana SaiandMarcus Edel 0828c7bfe4 Update include/ensmallen_bits/moead/moead_impl.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-11 23:08:45 +05:30
Nanubala Gnana SaiandMarcus Edel 7505121ee6 Update include/ensmallen_bits/moead/moead_impl.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-11 23:08:28 +05:30
Nanubala Gnana SaiandMarcus Edel bd2522667e Update include/ensmallen_bits/moead/moead_impl.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-11 23:08:17 +05:30
NanuSai fb587225d4 fix error 2021-06-10 14:51:56 +05:30
NanuSai 6acbe14bfb minor style 2021-06-10 11:59:36 +05:30
Nanubala Gnana Sai 950e36c2d0 Update moead_impl.hpp
Indent fix
2021-06-10 11:57:40 +05:30
Nanubala Gnana Sai d2a396cde1 Update moead.hpp
Fix indent
2021-06-10 11:55:30 +05:30
NanuSai b5f49a00a2 Fix callbacks 2021-06-10 10:08:38 +05:30
NanuSai a068a6e40d Fix docs for optimizers.md 2021-06-10 09:53:25 +05:30
NanuSai 5adfba0bbd use distributionIndex again 2021-06-10 09:53:14 +05:30
NanuSai 08fa726dc1 Tests pass 2021-06-09 21:26:23 +05:30
NanuSai 0f597ddd11 initialize fitness 2021-06-09 19:23:35 +05:30
NanuSai dd4b475b8c All tests compile 2021-06-09 12:49:28 +05:30
NanuSai 7d7ad342ee => cache converted upper and lowerBound
=> PreciisonType flexible
=> Created containers to pass to evaluateobjectives
2021-06-09 12:49:12 +05:30
NanuSai 62dc59099c use MatType lowerBound 2021-06-09 12:47:53 +05:30
NanuSai 556ded8c48 Everything compiles. 2021-06-09 11:14:45 +05:30
NanuSai 34366e7237 perturbationIndex pt.2 2021-06-09 11:07:12 +05:30
NanuSai 274f9f06e9 => Use cleaner Mutate code.
=> Remove redundant for loops.
2021-06-09 11:04:41 +05:30
NanuSai 5fb082a95a distributionIndex => perturbationIndex 2021-06-09 11:03:24 +05:30
NanuSai 2822fae878 Additional docs in declare file 2021-06-09 09:17:36 +05:30
NanuSai 5c11b532bc => Indent fix.
=> Use ElemType in DecomposeObjectives.
=> paretoSet and paretoFront filled.
=> Additional docs.
2021-06-09 09:17:07 +05:30
NanuSai efa5a2efbd Additional docs
remove callback tests
2021-06-08 21:29:16 +05:30
NanuSai b4f862d73f ] => ) 2021-06-08 20:48:28 +05:30
NanuSai 80a2f851b6 g => generation: main loop 2021-06-08 20:32:17 +05:30
NanuSai 57c8d70a02 ideal point uses ElemType 2021-06-08 20:30:58 +05:30
NanuSai a44da082b2 rm StepTaken 2021-06-08 20:23:52 +05:30
NanuSai 6703d07001 Tab fix
Remove const ref for primitive
2021-06-08 20:22:22 +05:30
NanuSai 410eb50fd2 Maintain EvaluateObjectives of NSGA-II 2021-06-08 20:19:32 +05:30
NanuSai e086bf2bd0 Doc fix 2021-06-08 19:58:29 +05:30
NanuSai 391e164fb7 moead_impl.hpp
=> Use BaseMatType
=> Remove redundant checks
2021-06-08 19:47:58 +05:30
NanuSai 1149301fa5 use ParetoSet & ParetoFront in declaration file 2021-06-08 10:29:43 +05:30
NanuSai 2ce3bd3d14 tab v space pt3 2021-06-08 10:21:16 +05:30
NanuSai e515851b40 author fix impl
test comments fixed.
2021-06-08 10:21:16 +05:30
NanuSai 47c981ec3a fix indendations pt2 2021-06-08 10:21:16 +05:30
NanuSai bfde39de2f tab v space 2021-06-08 10:21:16 +05:30
Nanubala Gnana SaiandMarcus Edel 9d7eec84b9 Update include/ensmallen_bits/moead/moead_impl.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-08 10:21:16 +05:30
Nanubala Gnana SaiandMarcus Edel c849873522 Update include/ensmallen_bits/moead/moead_impl.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-08 10:21:16 +05:30
Nanubala Gnana SaiandMarcus Edel faa94ab15b Update include/ensmallen_bits/moead/moead_impl.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-08 10:21:16 +05:30
Nanubala Gnana SaiandMarcus Edel 83e0850cc7 Update include/ensmallen_bits/moead/moead_impl.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-08 10:21:16 +05:30
NanuSai f516864104 arma::square 2021-06-08 10:21:16 +05:30
NanuSai c602dc1386 bound fix in optimizer.MD 2021-06-08 10:21:16 +05:30
NanuSai 9c888154b0 fix bounds 2021-06-08 10:21:16 +05:30
NanuSai 8a52d9ab10 add callbacktest 2021-06-08 10:21:16 +05:30
NanuSai a95c0e647a Remove shuffle from problems 2021-06-08 10:21:16 +05:30
NanuSai f38f6a1d44 modify test a bit 2021-06-08 10:21:16 +05:30
NanuSai 73ef983352 maxreplace is always positive 2021-06-08 10:21:16 +05:30
NanuSai d2615d5471 optimizer.MD update 2021-06-08 10:21:16 +05:30
NanuSai 5e27bdf1f2 minor doc changes 2021-06-08 10:21:16 +05:30
NanuSai f1488ab44e candidateFval => candidateFitness 2021-06-08 10:21:16 +05:30
NanuSai 3f30929c31 => test with def args : pass
=> rm arma::Mat<> => arma::umat
2021-06-08 10:21:16 +05:30
NanuSai be8e45b45a rm
a) mutationProb
 b) mutationStrength

add
 Sanity checks for all params

Styling fix
2021-06-08 10:21:16 +05:30
NanuSai c388bde9ea rm redundant args 2021-06-08 10:21:16 +05:30
NanuSai 33bcfca29d optimizer.md updated 2021-06-08 10:21:16 +05:30
NanuSai 288b3d710a change def args:
- numGen should be 2k
- paper says neighborProb should be less (for diversity) => 0.3
2021-06-08 10:21:16 +05:30
NanuSai b1bd1445ce numGenerations => maxGenerations 2021-06-08 10:21:16 +05:30
Nanubala Gnana SaiandMarcus Edel e73e79de9b Update include/ensmallen_bits/moead/moead.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-08 10:21:16 +05:30
Nanubala Gnana SaiandMarcus Edel eaf86e9c22 Update doc/optimizers.md
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-08 10:21:16 +05:30
Nanubala Gnana SaiandMarcus Edel cab48a009d Update doc/optimizers.md
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-08 10:21:16 +05:30
NanuSai c380dd5d7d rname MOEAD => MOEA/D-DE 2021-06-08 10:21:16 +05:30
NanuSai e04519b936 fix authors 2021-06-08 10:21:16 +05:30
NanuSai cf9ec55754 some work on optimizer.md 2021-06-08 10:21:16 +05:30
NanuSai ee92ed0f7b HISTORY.md updated 2021-06-08 10:21:16 +05:30
NanuSai c067fcc68e fonseca shuffle fix 2021-06-08 10:21:16 +05:30
NanuSai 2e8ba4d144 undo nsga2_test changes 2021-06-08 10:21:16 +05:30
NanuSai aecbe43c3b - Removed preserveDiversity for now
- ALL TESTS PASSED!!!
2021-06-08 10:20:45 +05:30
NanuSai 8b2ae1312d rm preserve diversity 2021-06-08 10:20:45 +05:30
NanuSai 57815a59b0 Shuffle func is wrong 2021-06-08 10:20:45 +05:30
NanuSai fefcaa6b1f minor style change test 2021-06-08 10:20:45 +05:30
NanuSai 08b24f1bc8 - Everything compiles
- All tests fail
-  debug shows weight 0?

Finally hit the "wall".
2021-06-08 10:20:45 +05:30
NanuSai b1ba5a2123 - n_rows
- evaluate should take const population
2021-06-08 10:20:45 +05:30
NanuSai 8b8fe49f7c use arma::datum::eps
add check for lowerBound and upperBound
2021-06-08 10:20:45 +05:30
NanuSai 41d58bc652 minor 2021-06-08 10:20:45 +05:30
NanuSai 1011370953 mutation fixed 2021-06-08 10:20:45 +05:30
NanuSai ed5ad0e53b DE done 2021-06-08 10:20:45 +05:30
NanuSai 7d50c879fc Nits on MatingSelection
-  assert neighborSize > 1
-  minors
2021-06-08 10:20:45 +05:30
NanuSai d794746062 styling fix 2021-06-08 10:20:45 +05:30
NanuSai c281336e64 fix chronology in docs 2021-06-08 10:20:45 +05:30
NanuSai d67ed85dd0 remove
- dominates
rename
- differentialWeight, changed default value
- add
weight stability
2021-06-08 10:20:45 +05:30
NanuSai 73a3b90c1c tchebycheff is max 2021-06-08 10:20:45 +05:30
NanuSai 99f6f2b630 rm:
- externalPopulation
 - externalPopulationFval
 - update neighbor of MOEA/D
 rename:
- FValue => populationFval
- Add
 - update solutions as MOEA/D-DE prefers
 -  use diversity preserve conditions
 -  idealPoint and candidateFval are arma::vec

========
REMAINING
- Fixing the final stuff
- Some additional touches
- Possible code fixes
2021-06-08 10:20:45 +05:30
NanuSai a4dcccd26a rename
-  DecomposeObjectives
2021-06-08 10:20:45 +05:30
NanuSai d69c899bfd Add params
- maxReplace
- preserveDiversity
- Add docs
2021-06-08 10:20:45 +05:30
NanuSai 89f6b8fb41 - fix compile errors
- test still fail
2021-06-08 10:20:45 +05:30
NanuSai 0ae80352d8 - add TODO
- add FIXME
- neighborIndices
2021-06-08 10:20:45 +05:30
NanuSai 09ec4a23ac Scalingfactor in impl
pFlag switch Mating
2021-06-08 10:20:45 +05:30
NanuSai ad8383ebad Add enum for P type 2021-06-08 10:20:45 +05:30
NanuSai a3b812a283 weightNeighborIndex fix 2021-06-08 10:20:45 +05:30
NanuSai f4c348a316 MatingSelection needs popIdx
weighNeighbourMatrix idx fix
2021-06-08 10:20:45 +05:30
NanuSai 5a07b38a3a evaluatedCandidate => candidateFval 2021-06-08 10:20:45 +05:30
NanuSai b01e7fab18 * scalingFactor in ctor
* paper says 0.4  -> 1 is a good for scaling factor
2021-06-08 10:20:45 +05:30
NanuSai ded4a43837 1.f / numVariables, should pass float 2021-06-08 10:20:45 +05:30
NanuSai 28be655f05 numVariables 2021-06-08 10:20:45 +05:30
NanuSai 3cd94aeb67 scalingFactor getter setter 2021-06-08 10:20:45 +05:30
NanuSai bb414e68ed convention 2021-06-08 10:20:45 +05:30
NanuSai a52f1ad5f4 cast to vector only at EvaluateObjectives 2021-06-08 10:20:45 +05:30
NanuSai 3d91ccc37f differential crossover 2021-06-08 10:20:45 +05:30
NanuSai 91df7068c5 crossover inside mainloop 2021-06-08 10:20:45 +05:30
NanuSai 19425d4d78 - wrap mating in a function
- declare DifferentialCrossover
2021-06-08 10:20:45 +05:30
NanuSai 0419469103 - Import previous work
- populationSize > neighborSize + 1
- fix initNeighborhood
- neighborHoodSize => neighborSize
2021-06-08 10:20:45 +05:30
Nanubala Gnana Sai c22c6fc420 Add docs for ZDT_ONE Test 2021-06-08 06:59:34 +05:30
NanuSai 6e9287df1a Fix re-ordering warning 2021-06-06 11:38:14 +05:30
Marcus Edel 447f8086ff Merge branch 'master' into ZDT 2021-06-05 22:25:35 -04:00
Marcus Edel abd5b036f1 Merge pull request #289 from jonpsy/moo-callback
Make Callback flexible for MultiObjective Optimizers.
2021-06-04 09:58:24 -04:00
Marcus Edel 2306acb37e Merge pull request #291 from jonpsy/frontdoc
Doc fix.
2021-06-02 09:32:23 -04:00
NanuSai 6d28ed41c6 rm query front doc in ctor 2021-06-01 22:32:12 +05:30
NanuSai 3eb05e9ddf Merge branch 'moo-callback' of https://github.com/jonpsy/ensmallen into moo-callback 2021-06-01 22:29:51 +05:30
NanuSai 72ced21bb4 history fix 2021-06-01 22:29:33 +05:30
Nanubala Gnana SaiandMarcus Edel 6d4023c855 Update include/ensmallen_bits/callbacks/query_front.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-06-01 22:14:36 +05:30
NanuSai 29b6ff1974 fix 2021-06-01 15:12:19 +05:30
NanuSai 526f1d449f init gensteptaken 2021-06-01 15:03:34 +05:30
NanuSai e6c4513df4 remov e ZDT5 2021-06-01 14:56:23 +05:30
NanuSai e7215436fe fix test for MOO 2021-06-01 14:43:56 +05:30
NanuSai b5e85c9874 Add inbuilt query front hpp 2021-06-01 14:43:48 +05:30
NanuSai 873d951e2e add docs in callbacks.md 2021-06-01 14:43:30 +05:30
NanuSai 5d05ff62ec => Rename to GenerationalStepTaken
=> Move Callback::StepTaken() at the end of for loop nsga2
=> Register GenerationStepTaken in macro
2021-06-01 10:10:03 +05:30
NanuSai 5082d82133 history 2021-05-29 12:21:51 +05:30
NanuSai 5afdcdd9e3 replace callback in nsga2 2021-05-29 11:50:31 +05:30
NanuSai 4a45156130 remove redundant docs 2021-05-29 11:47:28 +05:30
NanuSai 25c4af46bf indendation fix 2021-05-29 11:38:40 +05:30
NanuSai 5853712ba1 1. fix compile error
2. rename to ObjectivesVecType
2021-05-29 11:32:41 +05:30
Nanubala Gnana Sai eb345f1346 Initial push.
=> add MOOTypedForms in traits.hpp.
=> added a specialization for StepTaken for MOO in callbacks.hpp.
2021-05-29 03:05:36 +05:30
Nanubala Gnana Sai a6e8291c66 Document that reference front plot is in the PR. 2021-05-26 22:50:31 +05:30
Nanubala Gnana Sai 4136639d4e Add ZDT1 Test 2021-05-26 22:50:04 +05:30
Nanubala Gnana Sai 2c22ab2407 GetParetoFront => GetReferenceFront 2021-05-25 22:06:04 +05:30
NanuSai d40b12fa77 add ZDT to nsga2 (not working) 2021-05-25 19:08:30 +05:30
NanuSai 3200754617 numParetoPoints specified by user 2021-05-25 19:08:18 +05:30
Marcus Edel f66643e1c5 Merge pull request #288 from zoq/catch-main-seed
Use Catch2 seed command-line argument to set ensmallen seeds.
2021-05-17 19:37:36 -04:00
NanuSai 118bc4ebaa fix compile errors 2021-05-14 10:57:10 +05:30
NanuSai e4c3a63375 Pareto Front for ZDT-4,5,6 2021-05-14 10:43:12 +05:30
NanuSai d34aec8cf8 fix indent 2021-05-14 10:08:11 +05:30
NanuSai 4baf1072e0 fix history 2021-05-14 10:06:49 +05:30
NanuSai 1276ef366b * Pareto Front for ZDT-1,2,3
* Put inside folder
2021-05-14 10:04:53 +05:30
NanuSai f36a517358 Add Pareto Front for ZDT1, ZDT2 2021-05-14 10:04:53 +05:30
NanuSai 6a9a44f62a move to folder 2021-05-14 10:04:53 +05:30
NanuSai 1f7bb9a730 ZDT5 added 2021-05-14 10:04:53 +05:30
NanuSai e6b130bb24 ZDT history 2021-05-14 10:04:53 +05:30
Nanubala Gnana Sai e7b26115f4 Merge branch 'master' into ZDT 2021-05-04 13:05:23 +05:30
Ryan Curtin 27150fc8fd Merge pull request #287 from zoq/ci-dist-update
Switch from Ubuntu Trusty 14.04 to Ubuntu Focal 20.04
2021-05-02 22:34:08 -04:00
Marcus Edel 2751e7968f Merge pull request #285 from jonpsy/indicator
Add MOO Indicators.
2021-05-02 12:04:53 -04:00
Marcus Edel 6e3fbc278e Use Catch2 seed command-line argument to set ensmallen seeds. 2021-05-02 04:15:53 +02:00
Nanubala Gnana Sai 0a1504ef2a Add braces 2021-04-29 01:45:37 +05:30
Nanubala Gnana SaiandMarcus Edel e975ee968f Update include/ensmallen_bits/utility/indicators/epsilon.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-04-29 01:34:17 +05:30
Nanubala Gnana SaiandMarcus Edel 00020ce08a Update include/ensmallen_bits/nsga2/nsga2.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-04-29 01:33:59 +05:30
Marcus Edel 61def4a04b Switch from Ubuntu Trusty 14.04 to Ubuntu Focal 20.04. 2021-04-27 02:41:51 +02:00
NanuSai 284b2f9d30 separate API for paretoset and paretofront 2021-04-26 00:14:59 +05:30
NanuSai 70ed598f53 redundant include 2021-04-25 23:53:00 +05:30
NanuSai 98ba659e86 restore cmakelists.txt 2021-04-25 23:52:03 +05:30
Nanubala Gnana Sai c013fcbaa6 Update .appveyor.yml 2021-04-25 23:48:23 +05:30
Nanubala Gnana Sai 6f79de7668 Update .appveyor.yml 2021-04-25 23:47:50 +05:30
NanuSai 9099b7400c revert appveyor. 2021-04-25 23:46:50 +05:30
NanuSai a62eda2ecc fix float error
compile only indicators
2021-04-25 23:30:00 +05:30
NanuSai 69361e98e5 Hence begins the RDP quest! 2021-04-25 22:48:40 +05:30
Nanubala Gnana Sai 18f7f2a736 use templated std::max
revert tolerance
2021-04-25 11:51:56 +05:30
Nanubala Gnana Sai a977492626 Update indicators_test.cpp
Change tolerance for MSVC15 (Assuming tolerance is causing the problem which I think it isn't, we'll see)
2021-04-25 02:16:29 +05:30
NanuSai b56b5b99c5 => epsilon ctor fix
=> add indicators test
=> Results match with hand calculated values.
2021-04-24 22:01:23 +05:30
NanuSai a1bd37c9a3 => rename igd -> igd+.
=> add public ctor similar to Metric Policy.
=> std::max() fix
2021-04-24 22:00:17 +05:30
NanuSai a26e271960 Zero div handled 2021-04-24 14:58:49 +05:30
Nanubala Gnana Sai ec75ddc04b -> further doc fixes in ensmallen.hpp
-> fix minor error in igd+
2021-04-24 01:04:09 +05:30
Nanubala Gnana Sai 7302ce1093 Doc cleanups 2021-04-24 00:32:20 +05:30
NanuSai 8613e1ba11 => Register at ensmallen.hpp
=> static and ElemType in Evaluate()
2021-04-17 13:35:29 +05:30
Nanubala Gnana Sai 5d90357602 Update nsga2_impl.hpp
fix spacing issue in github
2021-04-17 13:16:07 +05:30
NanuSai cc9d349f1f impl file fixed
test fixed
all test pass
2021-04-17 13:12:14 +05:30
NanuSai 8167ed1185 header arma::cube 2021-04-17 07:24:54 +05:30
NanuSai 41832e401c move to utility 2021-04-17 07:23:52 +05:30
NanuSai 5e2b5747cc shift doc to left 2021-04-16 09:08:47 +05:30
NanuSai 7acf499ceb nits 2021-04-16 09:03:58 +05:30
NanuSai 80955a75e5 spacing issues 2021-04-14 12:13:51 +05:30
Nanubala Gnana Sai 176c24b4fb Update History.md 2021-04-14 12:13:24 +05:30
Nanubala Gnana Sai ec9a93b171 Steal @favre49's work 2021-04-14 12:12:43 +05:30
NanuSai c2dfef1556 Minor style issues 2021-04-14 11:54:14 +05:30
Nanubala Gnana SaiandMarcus Edel 24367895df Update include/ensmallen_bits/problems/zdt1_function.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-04-14 11:54:14 +05:30
Nanubala Gnana SaiandMarcus Edel 499458d20f Update include/ensmallen_bits/problems/zdt1_function.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-04-14 11:54:14 +05:30
NanuSai 69520fbaa4 minor indent fix T_T 2021-04-14 11:54:14 +05:30
NanuSai 6894b7e03c ZDT history 2021-04-14 11:54:14 +05:30
NanuSai 8cbac229ad ElemType 2021-04-14 11:54:14 +05:30
NanuSai 7d20f81cfb => MatType return
=> Indent fix
2021-04-14 11:54:14 +05:30
NanuSai a62416b974 inner access outer. 2021-04-14 11:54:14 +05:30
NanuSai f9f3dc28ea Test working against pagmo2 2021-04-14 11:54:14 +05:30
NanuSai 7ac386e1ec Added
1) ZDT1
2) ZDT2
3) ZDT3
4) ZDT4
5) ZDT6
2021-04-14 11:54:14 +05:30
NanuSai 6924cf1c32 initial push
=> Documentation done.
=> Declared the class.
2021-04-14 11:54:14 +05:30
Marcus Edel 1e70823989 Merge pull request #263 from jonpsy/nsga2-better
Improvise NSGA2.
2021-04-13 20:04:39 -04:00
NanuSai 33974ce3f7 check arbitrary 2021-04-11 00:04:51 +05:30
Nanubala Gnana Sai 9463b153d1 Update HISTORY.md
white space
2021-04-10 23:57:11 +05:30
Nanubala Gnana Sai a4f320a418 Merge branch 'master' into nsga2-better 2021-04-10 23:56:17 +05:30
Marcus Edel 1b6c1d93f0 Merge pull request #283 from jonpsy/moo_traits
Recursively check for Evaluate() in MOO.
2021-04-10 13:34:22 -04:00
Marcus Edel 388bcd82cf Merge pull request #284 from zoq/code-analyzer-fixes
Code analyzer adjustments.
2021-04-09 17:04:56 -04:00
Nanubala Gnana Sai 6be8403fbb Merge branch 'nsga2-better' of https://github.com/jonpsy/ensmallen into nsga2-better 2021-04-09 01:29:42 +05:30
NanuSai 6714a178af Merge branch 'nsga2-better' of https://github.com/jonpsy/ensmallen into nsga2-better 2021-04-09 00:19:57 +05:30
Nanubala Gnana Sai 850612fd97 sanity fix 2021-04-08 19:14:01 +05:30
Marcus Edel 1cd90c6158 Initialize all class parameters. 2021-04-07 22:55:15 +02:00
Marcus Edel bccdbcc7de Remove unused parameter 'numBatches'. 2021-04-07 22:52:25 +02:00
Marcus Edel 089e9395de No need to worry about division by zero. 2021-04-07 22:51:33 +02:00
NanuSai ad8538602d fix compile time error 2021-04-08 01:17:36 +05:30
Nanubala Gnana Sai c6e76e2c62 indent fix 2021-04-07 09:38:47 +05:30
Nanubala Gnana Sai 782b994765 rm unsigned symnb 2021-04-07 09:26:11 +05:30
Nanubala Gnana SaiandMarcus Edel 8ecd483bd4 Update include/ensmallen_bits/function/static_checks.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-04-07 09:01:41 +05:30
Nanubala Gnana Sai 7bffa5df48 restore inline 2021-04-04 19:38:04 +05:30
Nanubala Gnana Sai 6f4362b23e style fixing 2021-04-04 19:35:40 +05:30
Nanubala Gnana Sai 750043d20a - reuse established API
- doc change for MOO trait
2021-04-04 19:31:42 +05:30
Nanubala Gnana Sai 563457848e Added History.MD 2021-04-04 12:57:31 +05:30
NanuSai ccf0dff819 ryans method 2021-04-04 15:50:06 +05:30
NanuSai 0069291572 temporary solution in:
a) static_check (possibly wrong)
b) check Arbitrary in for loop in EvaluateObjectives
2021-04-04 14:18:21 +05:30
NanuSai 9fc7013d8d type trait for multiarbitraryfunction 2021-04-03 23:51:42 +05:30
Nanubala Gnana Sai 02d8d94c18 appveyor from master 2021-04-02 07:18:18 +05:30
Nanubala Gnana Sai 7eafb8a2f5 Revert changes from RDP 2021-04-02 07:06:49 +05:30
Nanubala Gnana Sai 5c31f6ad51 stress test on appveyor proofs => run 3k times 2021-04-01 09:37:22 +05:30
Nanubala Gnana Sai 95bc44f4fa rm appveyor pass 2021-04-01 01:09:51 +05:30
Nanubala Gnana Sai fb5f23db8b revert appveyor and ctest settings 2021-04-01 01:08:30 +05:30
Nanubala Gnana Sai f3f699a508 run appveyor test 3000 times 2021-04-01 00:52:30 +05:30
Nanubala Gnana Sai 400720aa15 appveyor print when test fails 2021-04-01 00:47:00 +05:30
Nanubala Gnana Sai 36e43ae21f run only nsga2 test and use random seeds in main.cpp 2021-03-31 15:16:37 +05:30
Nanubala Gnana Sai 846b01f165 appveyor debug 2021-03-31 15:08:50 +05:30
NanuSai f58e0eba43 fix windows indentation 2021-03-31 12:24:31 +05:30
Nanubala Gnana Sai 252c500696 indent fix 2021-03-31 12:15:47 +05:30
Nanubala Gnana Sai d9f3e7b7f2 Update nsga2_impl.hpp
indent fix
2021-03-31 12:11:43 +05:30
Nanubala Gnana Sai b986687494 fix merge conflicts 2021-03-31 12:06:29 +05:30
Nanubala Gnana Sai bad9062cd6 increase tolerance 2021-03-31 11:57:46 +05:30
NanuSai 68157eede0 build in debug 2021-03-30 19:29:08 +05:30
NanuSai 12c513d26c appveyor debug to check tolerance level 2021-03-30 14:32:06 +05:30
Nanubala Gnana Sai 15618563b9 introduced tolerance 2021-03-30 11:17:18 +05:30
Nanubala Gnana Sai a975138f4e appveyor old 2021-03-30 02:37:26 +05:30
Nanubala Gnana Sai c98b16acd1 SchafferN1 double debug Appveyor 2021-03-30 01:40:03 +05:30
Nanubala Gnana Sai d3b2ce932a Use params from paper
1) crossoverProb: 0.9
2) mutationRate: 1/n; n = num vars
3) numGeneration = 250
2021-03-30 01:31:14 +05:30
Nanubala Gnana Sai 70bfceebc5 Reason for changing:
a) 5k gen is too much, papers stick to ~150
b) The test error which I get is off by 1e-2
c)  Solutions are loosing diversity at higher number of generations (repeating solutions even)
2021-03-29 22:30:04 +05:30
NanuSai 1ad7181e84 everyone use IsInBounds 2021-03-28 15:26:00 +05:30
NanuSai 38f88ab2f2 minor 2021-03-28 10:01:54 +05:30
NanuSai d9c049606a maybe the error should be ok now 2021-03-28 10:00:27 +05:30
NanuSai 2689d5c19e use absolute diff 2021-03-28 09:14:24 +05:30
NanuSai 1d16313112 build in debug 2021-03-28 08:54:09 +05:30
NanuSai d18192e251 building works, now just test fails on double 2021-03-28 07:27:04 +05:30
NanuSai 679d904539 cxx11 compiler error? 2021-03-28 05:55:13 +05:30
NanuSai 6c388a0cac appveyor checks again 2021-03-28 05:38:46 +05:30
NanuSai 0256405a4f check error 2021-03-28 05:33:31 +05:30
Ryan Birmingham 9f90ec92aa Merge pull request #281 from zoq/cmaes-doc-fix
Fix CMAES population size parameter comment
2021-03-27 12:07:55 -04:00
Marcus Edel 3d108b2313 Fix CMAES population size parameter comment. 2021-03-27 02:18:36 +01:00
Ryan Curtin 6dc293ec1d Add new block for next release to HISTORY.md. 2021-03-25 16:47:25 +01:00
Ryan Curtin 259da3d808 Update and release version 2.16.2. 2021-03-25 16:47:25 +01:00
Ryan Curtin 11c2cfe66b Merge pull request #265 from zoq/adam-update-approx
Remove AdamSchafferFunctionN2Test test case
2021-03-24 11:01:04 -04:00
NanuSai 1b0b51f570 appveyor to normal
MSVC Works!
2021-03-23 16:58:29 +05:30
NanuSai a1ef11a077 some more removals 2021-03-23 16:15:44 +05:30
NanuSai c19c5f6870 MSVC-15 fails back_inserter 2021-03-23 14:54:20 +05:30
NanuSai f76c2f2ae7 on finish 2021-03-23 14:19:56 +05:30
NanuSai a691584fa3 dont run test as well 2021-03-23 14:15:16 +05:30
NanuSai a43c447c84 dont build! 2021-03-23 14:08:59 +05:30
NanuSai 6254ac14b2 remove some inlines 2021-03-23 13:58:22 +05:30
NanuSai 8f6af30aec appveyor validated 2021-03-23 11:54:14 +05:30
NanuSai 1c290c3235 back2square1 2021-03-23 11:48:58 +05:30
Nanubala Gnana Sai eec6cad594 Update .appveyor.yml 2021-03-23 11:13:01 +05:30
Nanubala Gnana Sai 69906e100c test appveyor 2021-03-23 11:01:56 +05:30
NanuSai 31e96e2bb4 make class template 2021-03-22 20:21:54 +05:30
NanuSai e508278039 single threaded 2021-03-22 18:01:32 +05:30
NanuSai b12d050fd5 a minor change to spot error(will be removed) 2021-03-22 17:47:32 +05:30
NanuSai b2f525f5aa allow floatonly 2021-03-22 17:47:18 +05:30
Nanubala Gnana Sai 01dbfa3e7b Merge branch 'master' into nsga2-better 2021-03-22 16:11:43 +05:30
Marcus Edel d5f8b865a7 Update history. 2021-03-22 04:08:26 +01:00
Marcus Edel 4ae22bc9a1 Remove the AdamSchafferFunctionN2Test test from the Adam test suite.
The AdamSchafferFunctionN2Test fails on some specific aarch64 machines, since we are unable to reproduce the issue on other devices, we decided to remove the test from the Adam test suite. The Adam optimizer is still tested against many different functions, which all pass, so we don't think the implementation is wrong. It might be possible to optimize the initial function and optimizer settings to help Adam to converge in certain situations, but since we can't reproduce the issue, it's unclear what those settings are. For more details, see #253.
2021-03-22 02:36:57 +01:00
Ryan Curtin 39aa37d655 Merge pull request #276 from rcurtin/comment-problems
Clarifying comments about test problems
2021-03-21 20:53:01 -04:00
Ryan Curtin e7878f7e3b Update HISTORY. 2021-03-20 14:14:46 -04:00
Ryan Curtin af90625b4a Clarify comments about test problems. 2021-03-20 14:12:27 -04:00
NanuSai e8506960a0 Changes (See below)
=> Fix crowdingAssignment
    => Type robust
    => Add bounds to initial population
    => Reduced if / for blocks
    => Added float test
    => Minor additional docs
2021-03-20 09:45:28 +05:30
Ryan Curtin 472d824dcb Merge pull request #275 from jonpsy/initpoint
InitPoint
2021-03-19 21:05:33 -04:00
NanuSai f4f3c33147 oops 2021-03-19 08:43:20 +05:30
NanuSai b5d3203357 Fonseca Init 2021-03-19 08:38:06 +05:30
Marcus Edel 27f37d19f8 Merge pull request #274 from jonpsy/schaffer
SchafferN1 Initial Point fix.
2021-03-18 14:28:23 -04:00
NanuSai 70ee7947f7 iniital point fix 2021-03-18 21:59:59 +05:30
Marcus Edel ccd7b6c9e6 Merge pull request #271 from matteosecli/patch-2
Swapped default params in AugLagrangian docs.
2021-03-17 22:28:42 -04:00
Matteo Seclì a58d88ef7e Update HISTORY.md 2021-03-15 21:53:30 +01:00
Matteo Seclì 3e7007e791 Swapped default params in AugLagrangian docs 2021-03-14 22:30:55 +01:00
Marcus Edel 706695432c CNE distribution test (#267)
Do not continue if a test was successful.
2021-03-13 16:43:57 -05:00
Ryan Curtin 1e6b538045 Merge pull request #270 from matteosecli/patch-1
Typo in LBFGS() method of AugLagrangian
2021-03-12 08:54:00 -05:00
Ryan Curtin abf539f294 Add changelog entry. 2021-03-11 18:09:15 -05:00
Ryan Curtin 254c8e40f8 Merge branch 'patch-1' of https://github.com/matteosecli/ensmallen into matteosecli-patch-1 2021-03-11 18:08:38 -05:00
Ryan Curtin 1bf557c8a1 Merge pull request #268 from zoq/catch2-update-2.13.4
Catch2 update 2.13.4
2021-03-10 09:24:13 -05:00
Matteo Seclì 9c527470e3 Typo in LBFGS() method of AugLagrangian 2021-03-10 11:19:29 +01:00
Marcus Edel df6240725a Add updated Catch2 license file. 2021-03-07 23:19:54 +01:00
Marcus Edel 33ec784ec2 Update History. 2021-03-07 23:10:49 +01:00
Marcus Edel b886823e03 Update Catch2 to 2.13.4. 2021-03-07 23:06:23 +01:00
Nanubala Gnana Sai 28a37d835b Nits on NSGA2 (#262)
Minor grammar fix.
2021-03-05 17:08:32 -05:00
Ryan Curtin da0d2f03cb Add new block for next release to HISTORY.md. 2021-03-04 14:52:09 -05:00
Ryan Curtin d3b6f676fb Update and release version 2.16.1. 2021-03-04 14:52:09 -05:00
Ryan Curtin a449d5ec28 Merge pull request #259 from rcurtin/warning-fix
Remove unused `const` to fix compilation warnings
2021-03-02 20:07:26 -05:00
Ryan Curtin 23e8be799d Add HISTORY entry. 2021-03-02 10:51:39 -05:00
Ryan Birmingham d13848011c Merge pull request #257 from madhavshah49/master
Spelling and grammatical errors
2021-02-27 16:51:45 -05:00
Ryan Curtin 1755bfff72 Remove unused const. 2021-02-27 16:46:48 -05:00
madhavshah49andMarcus Edel a1d17db8ee Update CONTRIBUTING.md
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2021-02-27 13:30:20 +05:30
madhavshah49andRyan Birmingham 2fdfe7803e Update CONTRIBUTING.md
Co-authored-by: Ryan Birmingham <birm@rbirm.us>
2021-02-27 13:28:34 +05:30
Ryan Birmingham 95c10690e3 Merge pull request #258 from rcurtin/cne-population-generation
Use normal distribution for CNE initial population generation
2021-02-26 20:36:44 -05:00
Ryan Curtin 1ab6de507f Update history. 2021-02-26 18:54:12 -05:00
Ryan Curtin 3a25abd33e Comment out random seeds. 2021-02-26 18:51:18 -05:00
Ryan Curtin 2b0da57ce1 Use normal distribution not uniform distribution. 2021-02-26 18:50:01 -05:00
madhavshah49andRyan Birmingham 9f614c3536 Update CONTRIBUTING.md
Co-authored-by: Ryan Birmingham <birm@rbirm.us>
2021-02-26 19:42:49 +05:30
madhavshah49andRyan Birmingham 0d12a69bb1 Update CONTRIBUTING.md
Co-authored-by: Ryan Birmingham <birm@rbirm.us>
2021-02-26 19:41:49 +05:30
madhavshah49 6de5c00628 Update LICENSE.txt 2021-02-26 19:36:25 +05:30
madhavshah49andRyan Birmingham 8f60a60458 Update CONTRIBUTING.md
Co-authored-by: Ryan Birmingham <birm@rbirm.us>
2021-02-26 19:28:32 +05:30
madhavshah49 dc9ed15930 Update CONTRIBUTING.md 2021-02-25 23:03:03 +05:30
madhavshah49 ee12ceff17 Update CONTRIBUTING.md 2021-02-25 23:01:45 +05:30
madhavshah49 7a725f8063 Revert "Update README.md"
This reverts commit 3722860270.
2021-02-25 22:53:51 +05:30
madhavshah49 3d1ee2846d Revert "Update CONTRIBUTING.md"
This reverts commit 84323fcd56.
2021-02-25 22:53:19 +05:30
madhavshah49 84323fcd56 Update CONTRIBUTING.md 2021-02-25 22:13:20 +05:30
madhavshah49 3722860270 Update README.md 2021-02-24 20:41:44 +05:30
madhavshah49 cf2c758ecb Update LICENSE.txt 2021-02-24 20:29:46 +05:30
Marcus Edel f987873082 Merge pull request #255 from rcurtin/fix-omp-test
Fix compilation issue when ENS_USE_OPENMP is specified.
2021-02-22 10:51:31 -05:00
Ryan Curtin 17d662b564 Update HISTORY. 2021-02-21 06:54:56 -05:00
Ryan Curtin b29678d234 Fix compilatuon issue when ENS_USE_OPENMP is specified. 2021-02-21 06:48:46 -05:00
Marcus Edel 66244e095b Merge pull request #252 from rcurtin/fix-empty-reports
Fix Report callback when no steps were taken.
2021-02-16 23:14:21 +01:00
Ryan Curtin 50439fb6b2 Slightly more careful handling. 2021-02-15 09:57:00 -05:00
Ryan CurtinandJames J Balamuta 1171f01fe7 Update include/ensmallen_bits/callbacks/report.hpp
Co-authored-by: James J Balamuta <coatless@users.noreply.github.com>
2021-02-15 09:43:49 -05:00
Ryan Curtin aba5e4c5d0 Add new block for next release to HISTORY.md. 2021-02-15 09:28:06 -05:00
Ryan Curtin d5beea9de3 Update and release version 2.16.0. 2021-02-15 09:28:06 -05:00
Ryan Curtin b70284ae70 Handle when no steps were taken. 2021-02-13 16:03:36 -05:00
Ryan Curtin 19a995e9c1 Remove possibly confusing comments. 2021-02-11 18:01:54 -05:00
Ryan Curtin f25c5754d1 Update history. 2021-02-11 18:01:54 -05:00
Ryan Curtin 0e32f02a0e Refactor all tests so that they run for 1k trials without any failures. 2021-02-11 18:01:54 -05:00
Conrad SandersonConrad SandersonJames J BalamutaMarcus EdelRyan Curtin
39069652c6 add short example program; expand README with example installation (#248)
* add short example program; expand README with example installation

Co-authored-by: Conrad Sanderson
Co-authored-by: James J Balamuta
Co-authored-by: Marcus Edel
Co-authored-by: Ryan Curtin
2021-02-02 08:56:40 +01:00
Ryan Curtin cdfae670da Add new block for next release to HISTORY.md. 2020-11-05 12:18:26 -05:00
Ryan Curtin 59288c607e Update and release version 2.15.1. 2020-11-05 12:18:26 -05:00
Yashwant Singh Parihar 7a253d3c3c Merge pull request #239 from coatless/patch-1
Fix include order of traits which reports depends upon
2020-11-05 12:24:37 +05:30
James J BalamutaandMarcus Edel 359bc7ddd3 Update include/ensmallen.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2020-11-04 16:29:52 -06:00
James J Balamuta 8b7731d93c Update HISTORY.md 2020-11-04 01:05:56 -06:00
James J Balamuta 0d4a67b7a0 Update ensmallen.hpp 2020-11-04 01:03:36 -06:00
Marcus Edel e853632bdc Merge pull request #238 from rcurtin/release-2.15.0
Release version 2.15.0: "Why Can't I Manage To Grow Any Plants?"
2020-11-03 21:37:38 +01:00
Ryan Curtin 531e6f4eb3 Add new block for next release to HISTORY.md. 2020-11-01 15:59:28 -05:00
Ryan Curtin f23c780690 Update and release version 2.15.0. 2020-11-01 15:59:28 -05:00
Ryan Curtin 6f07cab7f7 Merge pull request #213 from zoq/report-callback
Optimizer Summary Report
2020-11-01 15:55:53 -05:00
Marcus EdelandRyan Curtin 2e1c3edfe0 Spelling fix.
Co-authored-by: Ryan Curtin <ryan@ratml.org>
2020-10-31 21:00:53 +01:00
Marcus EdelandRyan Curtin 6035901dc7 Spelling fix.
Co-authored-by: Ryan Curtin <ryan@ratml.org>
2020-10-31 19:44:03 +01:00
Marcus EdelandRyan Curtin 225cc4f3b4 Spelling fix.
Co-authored-by: Ryan Curtin <ryan@ratml.org>
2020-10-31 19:43:21 +01:00
Marcus EdelandRyan Curtin bc61c72c05 Use Batch size instead of Batchsize.
Co-authored-by: Ryan Curtin <ryan@ratml.org>
2020-10-31 19:42:58 +01:00
Ryan Curtin f04de5bdbe Merge pull request #236 from rcurtin/release-script-typo-fix
Make sure there's a space in release script output
2020-10-31 10:50:18 -04:00
Ryan Curtin 75cbeb6f0d Merge branch 'master' into release-script-typo-fix 2020-10-31 10:50:04 -04:00
d53815dd3e Incorporate release date with ensmallen version (#226)
* Incorporate release date with ensmallen version

* Switch to strings instead of ints to preserve prefixed 0.

* More simplification on chare usage.

* 'x' single char, "xyz" multi-char

* Split into two functions

* Update include/ensmallen_bits/ens_version.hpp

Co-authored-by: Ryan Curtin <ryan@ratml.org>

* Update include/ensmallen_bits/ens_version.hpp

Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>

* Switch to directly using the macro definitions

Co-authored-by: Ryan Curtin <ryan@ratml.org>
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2020-10-30 18:51:07 -04:00
Ryan Curtin cf10ebee75 Update HISTORY. 2020-10-30 18:50:13 -04:00
Ryan Curtin 6cae72734a Make sure there's a space. 2020-10-26 20:53:09 -04:00
Marcus Edel 0b48f5b011 Add example Report callback output. 2020-10-24 20:17:46 +02:00
Marcus Edel 273abb2ad3 Test constraint optimizer. 2020-10-24 19:58:04 +02:00
Marcus Edel 376cc5cd3c Fix constraint objective and add number of epochs to the output. 2020-10-24 19:57:24 +02:00
Marcus Edel 25d0d843a7 Merge pull request #230 from shrit/coordiantes
Fix a bug in the function name.
2020-10-19 22:41:37 +02:00
Omar Shrit 677fcc2bb1 The day of typo: another problem of the exact same type
Signed-off-by: Omar Shrit <omar@shrit.me>
2020-10-16 23:13:57 +02:00
Omar Shrit 82a1342579 Fix a bug in the function name
Signed-off-by: Omar Shrit <omar@shrit.me>
2020-10-16 19:54:28 +02:00
Ryan Birmingham a37f49cb9b Merge pull request #228 from rcurtin/simplesgdfmat-fix
Fix SimpleSGDTestFunction arma::fmat test failures
2020-10-04 20:04:01 -04:00
Ryan Curtin 222e0bf67a Add issue number to HISTORY. 2020-10-03 23:35:36 -04:00
Ryan Curtin 37c2f6a0b0 Update HISTORY.md. 2020-10-03 23:33:06 -04:00
Ryan Curtin 0af5a0ec3c Make test strategies for SimpleSGDTestFunction arma::fmat tests more robust. 2020-10-03 23:32:35 -04:00
Ryan Curtin 60a99f780b Add new block for next release to HISTORY.md. 2020-09-05 10:07:19 -04:00
Ryan Curtin 8d9c037153 Update and release version 2.14.2. 2020-09-05 10:07:19 -04:00
Ryan Curtin 5df4088cde Merge pull request #223 from coatless/patch-1
Fix implementation of fonesca fleming problem function f1 and f2     type usage and negative signs.
2020-08-29 20:50:56 -04:00
James J Balamuta ec2cd1c2ad Update HISTORY.md 2020-08-27 09:10:07 -05:00
James J Balamuta a18f5fc2db Fix type issue and implementation of fonesca n1 function
- Improves the mathematical description of the problem
- Fixes the implementation of f1 and f2
- Ensure use of `pow()` and `sqrt()` return double
2020-08-27 09:07:44 -05:00
Ryan Curtin 9490d3c651 Add new block for next release to HISTORY.md. 2020-08-21 09:44:57 -04:00
Ryan Curtin 9d3fc459ce Update and release version 2.14.1. 2020-08-21 09:44:57 -04:00
Marcus Edel 0431e31831 Merge pull request #220 from rcurtin/release-quotation-fix
Fix quotation bug in release script.
2020-08-19 23:23:16 +02:00
Ryan Curtin 34f852258a Update HISTORY.md. 2020-08-18 17:36:15 -04:00
Ryan Curtin 2e52643db0 Fix quotation bug. 2020-08-18 17:32:30 -04:00
Ryan Curtin 0445b10ae8 Merge pull request #216 from say4n/fix-release-script
Fix release script
2020-08-16 19:50:50 -04:00
Marcus Edel b7eb6d08e6 Merge branch 'master' into fix-release-script 2020-08-16 19:46:16 +02:00
Marcus Edel 88879f3200 Merge pull request #217 from rcurtin/auglag-float-fix
Set AugLagrangian tolerance based on ElemType.
2020-08-14 15:56:01 +02:00
Ryan Curtin b9987d8a99 Update HISTORY. 2020-08-11 21:37:27 -04:00
Ryan Curtin 3b411c56a6 Adjust tolerance of AugLagrangian according to ElemType. 2020-08-11 21:36:23 -04:00
Sayan GoswamiandRyan Curtin 216c003002 Fix awk syntax to actually use variable substitution (oops).
Co-authored-by: Ryan Curtin <ryan@ratml.org>
2020-08-12 03:17:22 +05:30
Sayan Goswami eae8fa7602 Trim leading whitespaces (needed for MacOS). 2020-08-11 22:47:43 +05:30
Sayan Goswami 203de9f670 Add changes to HISTORY.md 2020-08-11 22:31:32 +05:30
Sayan Goswami 71c3499cf3 Fix release script. 2020-08-11 22:28:14 +05:30
Marcus Edel a2ddf51396 Merge pull request #214 from say4n/release-2.14.0
Release version 2.14.0: "No Direction Home".
2020-08-11 18:52:00 +02:00
Sayan Goswami 6da0267bc6 Add new block for next release to HISTORY.md. 2020-08-10 23:05:47 +05:30
Sayan Goswami c5673b9ca8 Update and release version 2.14.0. 2020-08-10 23:05:46 +05:30
Ryan Curtin c73c92a2f5 Merge pull request #149 from say4n/nsga2
Add NSGA2
2020-08-10 10:10:47 -04:00
Marcus EdelandRyan Curtin fbc214ee25 Minor style improvement.
Co-authored-by: Ryan Curtin <ryan@ratml.org>
2020-08-08 22:13:03 +02:00
Marcus EdelandRyan Curtin 12b62a6b72 Minor spelling fix.
Co-authored-by: Ryan Curtin <ryan@ratml.org>
2020-08-08 22:12:41 +02:00
Marcus EdelandRyan Curtin 4262e97ee5 Minor spelling fix.
Co-authored-by: Ryan Curtin <ryan@ratml.org>
2020-08-08 22:11:52 +02:00
Marcus EdelandRyan Curtin 48afcf6f48 Minor style improvement.
Co-authored-by: Ryan Curtin <ryan@ratml.org>
2020-08-08 22:11:28 +02:00
Marcus EdelandRyan Curtin 741ed20f98 Improve the function output.
Co-authored-by: Ryan Curtin <ryan@ratml.org>
2020-08-08 22:10:51 +02:00
Marcus EdelandRyan Curtin 9c095b0d7e Naming adjustment, switch from 'Report' to 'Optimization Report'.
Co-authored-by: Ryan Curtin <ryan@ratml.org>
2020-08-08 22:09:36 +02:00
Marcus Edel 30388a8b07 Add optimizer summary report callback to the HISTORY. 2020-08-03 22:46:04 +02:00
Marcus Edel b96b967960 Merge branch 'master' into report-callback 2020-08-03 19:05:19 +02:00
Marcus Edel 8945fd4413 Add Report callback documentation. 2020-08-03 15:48:08 +02:00
Marcus Edel 0f5073e531 Add Report callback test. 2020-08-03 15:47:53 +02:00
Marcus Edel f1e72e4373 Add Report callback, print optimizer summary. 2020-08-03 15:46:29 +02:00
Marcus Edel e09d3543fd Add StepSize() check. 2020-08-03 15:45:24 +02:00
Sayan Goswami 6c9f1ac6e5 Include assert header. 2020-07-30 15:22:30 +05:30
Sayan Goswami 71e609bf2d Use const double instead of const double & for lowerBound and upperBound. 2020-07-30 15:20:36 +05:30
Sayan Goswami ddfb6c36c5 Add Fonseca Fleming function file, oops! 2020-07-30 15:11:23 +05:30
Sayan Goswami c4110d0906 Fix spelling for Fonseca Fleming. 2020-07-30 15:06:58 +05:30
Sayan Goswami ea5a54b77c Add overload for lowerBound, upperBound, add tests for the same. Fix CrowdingDistanceAssignment. 2020-07-30 14:57:11 +05:30
Sayan Goswami e68fbfeabe Add explicit note regarding lowerBound and upperBound in documentation. 2020-07-30 13:52:50 +05:30
Sayan Goswami 5d13117a1f Update documentation on epsilon. 2020-07-30 13:47:40 +05:30
Sayan Goswami d2528f3f11 Set lowerBound to 0 and upperBound as 1 by default.
Note: upper and lower bounds need to be set per variable for the optimization problem being solved.
2020-07-30 13:47:11 +05:30
Sayan Goswami 8579650cb9 Fix indentation to not exceed column limit. 2020-07-30 13:34:05 +05:30
Sayan Goswami 7c1a556209 Remove extra newline. 2020-07-30 13:30:31 +05:30
Sayan Goswami 0c5828ac3e Remove extra newline. 2020-07-30 13:29:31 +05:30
Sayan Goswami c566b4a8c9 Remove extra space. 2020-07-30 13:28:48 +05:30
Sayan Goswami 08dff6ced6 Update NSGA2.Optimize() docstring to reflect changed return ttype. 2020-07-30 13:27:27 +05:30
Sayan Goswami aec42c5fa6 Fix spelling. 2020-07-30 13:24:38 +05:30
Sayan Goswami 457b1cbdd4 Fix docs. 2020-07-30 13:22:54 +05:30
Sayan Goswami 42ee14f08e Fix upper, lower bounds for Fonseca Flemming.
I had forgotten to add the bounds for the third variable.
2020-07-29 17:06:33 +05:30
Sayan Goswami 14e13fc00f Add numVariables to fix Mutate(). 2020-07-29 17:05:11 +05:30
Sayan Goswami f45b6533a6 Use array initialization for bounds instead of string. 2020-07-29 14:05:55 +05:30
Sayan Goswami e8c586c305 Initialize calculatedObjectives with zeros. 2020-07-29 14:05:10 +05:30
Sayan Goswami 021bff545c Use explicit types in callback test, fix typo. 2020-07-29 02:33:17 +05:30
Sayan Goswami 6631165b11 Use ElemType in place of double. 2020-07-28 19:59:47 +05:30
Sayan Goswami 2840027df8 Update MOO description. 2020-07-27 14:55:52 +05:30
Sayan Goswami 9c29738afb Add note about Front() method for MOO. 2020-07-27 14:54:56 +05:30
Sayan Goswami e250f55558 Add generic MO function as example. 2020-07-27 14:52:13 +05:30
Sayan Goswami 20f67a67a5 Merge branch 'master' into nsga2 2020-07-27 14:39:20 +05:30
Sayan GoswamiandRyan Curtin 178e2e0b44 Update doc/optimizers.md
Co-authored-by: Ryan Curtin <ryan@ratml.org>
2020-07-27 14:38:14 +05:30
Sayan GoswamiandRyan Curtin 0a3d23aba2 Fix indentation.
Co-authored-by: Ryan Curtin <ryan@ratml.org>
2020-07-27 14:37:36 +05:30
Sayan GoswamiandRyan Curtin 9ae8fe3096 Update documentation for Front().
Co-authored-by: Ryan Curtin <ryan@ratml.org>
2020-07-27 14:37:16 +05:30
Marcus Edel 8c98f8368d Merge pull request #201 from rcurtin/constrained-optimizer-fixes
Fix constrained optimizer documentation.
2020-07-26 21:45:48 +02:00
Marcus Edel 7aa725b7cf Merge branch 'master' into constrained-optimizer-fixes 2020-07-25 21:03:05 +02:00
Sayan Goswami 69ddc39488 Use min of sum of objectives across entire population as performance measure. 2020-07-24 12:46:00 +05:30
Sayan Goswami 206145bd59 Remove unused variable. 2020-07-23 20:21:41 +05:30
Sayan Goswami 03c4dcba35 Merge branch 'master' into nsga2 2020-07-23 19:54:32 +05:30
Sayan Goswami a8de350b9f Return a single MatType::elem_type performance measure from Optimize(). 2020-07-23 19:53:32 +05:30
Ryan Curtin 852de21b70 Merge pull request #207 from rcurtin/release-script-fixes
Website update release script fixes
2020-07-19 17:01:22 -04:00
Sayan Goswami 1da4b449cd Merge branch 'master' into nsga2 2020-07-20 01:33:28 +05:30
Ryan Curtin 40a6046159 Add note to rebase to generated PR description. 2020-07-18 14:09:29 -04:00
Ryan Curtin e6d8f85a5b Update HISTORY. 2020-07-18 14:05:25 -04:00
Ryan Curtin 2d7b59be7b Update documentation and error output. 2020-07-18 14:03:49 -04:00
Ryan Curtin 7ac88b6385 Fixes to website release script. 2020-07-18 14:02:49 -04:00
Ryan Curtin 38229276c5 Merge pull request #206 from rcurtin/release-2.13.0
Release version 2.13.0: "Automatically Automated Automation"
2020-07-18 13:29:54 -04:00
Ryan Curtin d5c67b10e7 Add new block for next release to HISTORY.md. 2020-07-15 14:51:32 -04:00
Ryan Curtin 5efb1eb637 Update and release version 2.13.0. 2020-07-15 14:51:32 -04:00
Ryan Curtin b42aec9753 Fix changelog extraction script bits. 2020-07-15 14:50:46 -04:00
Ryan Curtin a3c38f6c78 Fix syntax in HISTORY.md. 2020-07-15 14:50:32 -04:00
Ryan Curtin dd9215a1ab Further updates to release script. 2020-07-15 14:45:13 -04:00
Ryan Curtin ad29230f43 Update release script. 2020-07-15 14:41:58 -04:00
Sayan Goswami 3c6aa81ca4 Return objective values from Optimize().
Using separate function Front() to get the best front.
2020-07-15 13:23:53 +05:30
Sayan Goswami 1c79296626 Add spacing as per style guide. 2020-07-15 10:43:36 +05:30
Sayan GoswamiandMarcus Edel db4a84b939 Adjust spacing to follow code style.
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2020-07-15 02:19:27 +05:30
Sayan GoswamiandMarcus Edel bfff7963a5 Adjust spacing to follow code style.
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2020-07-15 02:19:11 +05:30
Sayan GoswamiandRyan Curtin a688988997 Update doc/optimizers.md
Co-authored-by: Ryan Curtin <ryan@ratml.org>
2020-07-14 22:09:43 +05:30
Sayan GoswamiandRyan Curtin 88f6500201 Update doc/function_types.md
Co-authored-by: Ryan Curtin <ryan@ratml.org>
2020-07-14 22:09:05 +05:30
Sayan GoswamiandRyan Curtin fab76f6002 Update doc/function_types.md
Co-authored-by: Ryan Curtin <ryan@ratml.org>
2020-07-14 22:08:53 +05:30
Sayan GoswamiandRyan Curtin c0d3379bc3 Update HISTORY.md
Co-authored-by: Ryan Curtin <ryan@ratml.org>
2020-07-14 22:08:38 +05:30
Sayan Goswami 75ae7efbc4 Merge branch 'master' into nsga2 2020-07-14 20:23:46 +05:30
Sayan Goswami b64a5a3627 Fix Fonseca Flemming implementation. 2020-07-14 20:20:46 +05:30
Ryan Curtin a63ea6d2f0 Merge pull request #165 from shrit/early_stopping
Early stopping at loss min on validation set
2020-07-13 20:59:32 -04:00
Omar Shrit f7aa5e6a85 Add a using in order to avoid a major version bump
Signed-off-by: Omar Shrit <omar@shrit.me>
2020-07-07 12:04:59 +02:00
shritandRyan Curtin 130057ecb9 Update to show example use case
Co-authored-by: Ryan Curtin <ryan@ratml.org>
2020-07-07 10:28:18 +02:00
shritandRyan Curtin 8fff9e8d75 Update class name according to typedef
Co-authored-by: Ryan Curtin <ryan@ratml.org>
2020-07-07 10:25:15 +02:00
shritandRyan Curtin 8fb5903191 Use arma::mat instead of template type
Co-authored-by: Ryan Curtin <ryan@ratml.org>
2020-07-07 10:24:39 +02:00
Omar Shrit ea1c4e494a Fix typos error
Signed-off-by: Omar Shrit <omar@shrit.me>
2020-07-04 23:08:43 +02:00
Omar Shrit 742237f150 Update documentation with the new constructor of early_stop_at_min_loss.
Signed-off-by: Omar Shrit <omar@shrit.me>
2020-07-04 23:08:43 +02:00
Omar Shrit 8f45d8708e Replace climits with limits, and remove limits from callbacks_test
Signed-off-by: Omar Shrit <omar@shrit.me>
2020-07-04 23:08:43 +02:00
Omar Shrit a799406f99 Update HISTORY with the early stop callback new constructor
Now we can evaluate any function loss directly using a lambda
function inside the constructor of early stop at min loss

Signed-off-by: Omar Shrit <omar@shrit.me>
2020-07-04 23:07:32 +02:00
shritandMarcus Edel 14272ea714 Fix style
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2020-07-04 23:06:10 +02:00
shritandMarcus Edel 64d94c20ab Remove non used header
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2020-07-04 23:06:10 +02:00
shritandMarcus Edel d8edac89d8 Update include/ensmallen_bits/callbacks/early_stop_at_min_loss.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2020-07-04 23:06:10 +02:00
shritandMarcus Edel 88c7fa4236 Update include/ensmallen_bits/callbacks/early_stop_at_min_loss.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2020-07-04 23:06:10 +02:00
Omar Shrit 205bdbbb18 Remove non used parameters
Signed-off-by: Omar Shrit <omar@shrit.me>
2020-07-04 23:06:10 +02:00
Omar Shrit 3c13753540 Examine the minValue when we are close to 10 or very far
Signed-off-by: Omar Shrit <omar@shrit.me>
2020-07-04 23:06:10 +02:00
Omar Shrit c1fd65f93f Add custom lambda function test
Signed-off-by: Omar Shrit <omar@shrit.me>
2020-07-04 23:06:10 +02:00
shritandRyan Curtin d3efd15745 Update include/ensmallen_bits/callbacks/early_stop_at_min_loss.hpp
Co-authored-by: Ryan Curtin <ryan@ratml.org>
2020-07-04 23:06:09 +02:00
Omar Shrit 0dbc5006a4 Resolve name conflicts
Signed-off-by: Omar Shrit <omar@shrit.me>
2020-07-04 23:06:09 +02:00
Omar Shrit 2d18880679 Remove logisitic regression validation from tests
Signed-off-by: Omar Shrit <omar@shrit.me>
2020-07-04 23:06:09 +02:00
Omar Shrit f36769aa5e Remove logistic_regression_function_validation wrapper
Signed-off-by: Omar Shrit <omar@shrit.me>
2020-07-04 23:06:09 +02:00
Omar Shrit c14a317364 Improve style
Signed-off-by: Omar Shrit <omar@shrit.me>
2020-07-04 23:06:09 +02:00
Omar Shrit 8885c9f8de Remove output stream for this callbacks
Signed-off-by: Omar Shrit <omar@shrit.me>
2020-07-04 23:06:09 +02:00
shritandRyan Curtin ca5a32947a Update include/ensmallen_bits/callbacks/early_stop_at_min_loss.hpp
Co-authored-by: Ryan Curtin <ryan@ratml.org>
2020-07-04 23:06:09 +02:00
shritandRyan Curtin bfd9cd6861 Update include/ensmallen_bits/function/add_evaluate.hpp
Co-authored-by: Ryan Curtin <ryan@ratml.org>
2020-07-04 23:06:09 +02:00
shritandRyan Curtin 1de185660d Update include/ensmallen_bits/callbacks/early_stop_at_min_loss.hpp
Co-authored-by: Ryan Curtin <ryan@ratml.org>
2020-07-04 23:06:09 +02:00
shritandRyan Curtin ef75756287 Update include/ensmallen_bits/callbacks/early_stop_at_min_loss.hpp
Co-authored-by: Ryan Curtin <ryan@ratml.org>
2020-07-04 23:06:09 +02:00
shritandRyan Curtin 017a15796b Update include/ensmallen_bits/callbacks/early_stop_at_min_loss.hpp
Co-authored-by: Ryan Curtin <ryan@ratml.org>
2020-07-04 23:06:09 +02:00
Omar Shrit 849cd34e16 Update test with the new callbacks
Signed-off-by: Omar Shrit <omar@shrit.me>
2020-07-04 23:06:09 +02:00
Omar Shrit 566cccdc2b Adding boolean to check the std::function
Signed-off-by: Omar Shrit <omar@shrit.me>
2020-07-04 23:06:09 +02:00
Omar Shrit f8e8106335 Remove AnnType, keep only std::function instead
Signed-off-by: Omar Shrit <omar@shrit.me>
2020-07-04 23:06:09 +02:00
Omar Shrit c4e785e555 Adding a Early stop costr with callback
Signed-off-by: Omar Shrit <omar@shrit.me>
2020-07-04 23:06:09 +02:00
Omar Shrit a022be0202 Adding callback test function for early stop
Signed-off-by: Omar Shrit <shrit@lri.fr>
2020-07-04 23:06:09 +02:00
Omar Shrit 32b8285a78 Adding LogisiticRegression on Validation proposed by Marcus Edel
Signed-off-by: Omar Shrit <shrit@lri.fr>
2020-07-04 23:06:09 +02:00
Omar Shrit 8f20f90c53 Adding two templates for features and label matrix type
Signed-off-by: Omar Shrit <shrit@lri.fr>
2020-07-04 23:06:09 +02:00
Omar Shrit 7821bdd294 Remove added header for a old EarlyStopOnValidation
Signed-off-by: Omar Shrit <shrit@lri.fr>
2020-07-04 23:06:09 +02:00
Omar Shrit 34b5deba3a Adding reference to the network model to access to evaluate function
Signed-off-by: Omar Shrit <shrit@lri.fr>
2020-07-04 23:06:09 +02:00
Omar Shrit 44dbd8f3a5 Merge this class with the original one
Signed-off-by: Omar Shrit <shrit@lri.fr>
2020-07-04 23:06:09 +02:00
Omar Shrit 6c53e56667 Remove the interface for Evaluate(mat, mat)
Signed-off-by: Omar Shrit <shrit@lri.fr>
2020-07-04 23:06:09 +02:00
Omar Shrit dee5a7f974 Re-add evaluate(arma, arma) if it has evaluate
Signed-off-by: Omar Shrit <shrit@lri.fr>
2020-07-04 23:06:09 +02:00
Omar Shrit b42d2e1220 Adding const type qualifier
Signed-off-by: Omar Shrit <shrit@lri.fr>
2020-07-04 23:06:09 +02:00
Omar Shrit 48ec6b8dd2 Remove std::move, fix alignment
Signed-off-by: Omar Shrit <shrit@lri.fr>
2020-07-04 23:06:09 +02:00
Omar Shrit addf2f3f4e Adding evalute function
Signed-off-by: Omar Shrit <shrit@lri.fr>
2020-07-04 23:06:09 +02:00
Omar Shrit eccbb5a8c0 Merge two early_stop classes in one class
Signed-off-by: Omar Shrit <shrit@lri.fr>
2020-07-04 23:06:09 +02:00
Omar Shrit a16f309bc2 Remove extra lines, Fix filename and other comments
Signed-off-by: Omar Shrit <shrit@lri.fr>
2020-07-04 23:06:09 +02:00
Omar Shrit 38573580b0 Add Early Stop validation callback in ensmallen global header
Signed-off-by: Omar Shrit <shrit@lri.fr>
2020-07-04 23:06:09 +02:00
Omar Shrit 9f1ed3dd44 Print validation loss to monitor it during training
Signed-off-by: Omar Shrit <shrit@lri.fr>
2020-07-04 23:06:09 +02:00
Omar Shrit 7fb25b48de Overload necessary evaluate function required for callbacks
Signed-off-by: Omar Shrit <shrit@lri.fr>
2020-07-04 23:06:09 +02:00
Omar Shrit 5fd19ed06c Adding first implementation on early_stop_at_min_loss_on_validation
This callback measure the min loss on the validation set rather
than the train set.

Signed-off-by: Omar Shrit <shrit@lri.fr>
2020-07-04 23:06:09 +02:00
Ryan Curtin 64f1dc4c5b Update HISTORY.md. 2020-06-28 11:57:16 -04:00
Ryan Curtin f4feccb442 Add initialization of uninitialized parameter. 2020-06-28 11:56:15 -04:00
Ryan Curtin 31457c291c Oops, one more debug output. 2020-06-22 20:19:21 -04:00
Ryan Curtin 397e6e63dc Oops, remove debugging information. 2020-06-22 20:18:14 -04:00
Ryan Curtin 7d84591eab Allow termination on the first iteration if the gradient is really 0. 2020-06-22 20:13:59 -04:00
Ryan Curtin 0c31e61147 Fix missing comma. 2020-06-22 20:13:26 -04:00
Ryan Curtin 680ab16006 Clarify documentation on constrained function optimization. 2020-06-22 20:13:16 -04:00
Sayan Goswami d49775b28f Fix variable name (oops)
Use camel case.
2020-06-15 13:28:49 +05:30
Sayan Goswami c26c0cf249 Merge branch 'master' into nsga2 2020-06-15 13:20:18 +05:30
Sayan GoswamiandMarcus Edel fdb6cdc72f Update tests/nsga2_test.cpp
Use camel case names.

Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2020-06-15 13:18:45 +05:30
Sayan GoswamiandMarcus Edel c1cb6d1ff1 Update include/ensmallen_bits/nsga2/nsga2_impl.hpp
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2020-06-15 13:18:41 +05:30
Sayan GoswamiandMarcus Edel f0cbba7f98 Update include/ensmallen_bits/nsga2/nsga2_impl.hpp
Use uniform distribution for initialisation.

Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2020-06-15 13:18:35 +05:30
Sayan GoswamiandMarcus Edel ca37423560 Update tests/nsga2_test.cpp
Use camel case names.

Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2020-06-15 13:18:32 +05:30
Sayan GoswamiandMarcus Edel f68144d818 Update tests/nsga2_test.cpp
Use camel case names.

Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2020-06-15 13:18:25 +05:30
Sayan GoswamiandMarcus Edel 776f5aa546 Update tests/nsga2_test.cpp
Remove range based for loops.

Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2020-06-15 13:18:22 +05:30
Sayan GoswamiandMarcus Edel 60ccb22f45 Update tests/nsga2_test.cpp
Use camel case names.

Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2020-06-15 13:18:14 +05:30
Sayan GoswamiandMarcus Edel e014370ec8 Update tests/nsga2_test.cpp
Use camel case names.

Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2020-06-15 13:18:07 +05:30
Sayan GoswamiandMarcus Edel 076e9648f4 Use 1.0 instead of 1.0f for floats.
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2020-06-15 13:17:55 +05:30
Sayan GoswamiandMarcus Edel 778b7ef8a0 Update tests/nsga2_test.cpp
Change optimiser parameter as per suggestion.

Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2020-06-15 13:17:47 +05:30
Sayan GoswamiandMarcus Edel 525724c0d1 Update tolerance (use 10^-6 instead of 10^-5).
Co-authored-by: Marcus Edel <marcus.edel@fu-berlin.de>
2020-06-15 13:17:22 +05:30
Dominique Lasserre 12fe7e0403 Fix cmake package export.
* Fix spelling mistake introduced in 369046f

* Don't export compiler warning flags to interface.
2020-06-15 13:17:04 +05:30
Ryan Birmingham 70a2be8646 Merge pull request #198 from Lasall/cmake-export-fix
Fix cmake package export.
2020-05-06 10:50:10 -04:00
Dominique Lasserre 1aa9e2e991 Fix cmake package export.
* Fix spelling mistake introduced in 369046f

* Don't export compiler warning flags to interface.
2020-05-06 12:25:28 +02:00
Marcus Edel 132e9679f7 Merge branch 'master' into nsga2 2020-04-27 23:21:07 +02:00
Ryan Curtin 82817a6e3b Revert "Remove new HISTORY block for release."
This reverts commit c6a04c02c2.
2020-04-21 13:48:28 -04:00
Ryan Curtin c6a04c02c2 Remove new HISTORY block for release. 2020-04-21 13:48:07 -04:00
Ryan Curtin fecd7d652d Merge pull request #196 from rcurtin/release-2.12.1
Release version 2.12.1
2020-04-21 13:41:47 -04:00
Ryan Birmingham 86e5f679bc Remove extra lines 2020-04-20 14:53:46 -04:00
Ryan Birmingham 371177b80c Merge branch 'master' into release-2.12.1 2020-04-20 14:35:30 -04:00
Sayan Goswami c3a5a56fc8 Resolve merge conflict with upstream/master 2020-04-19 18:06:28 +05:30
Conrad Sanderson de19dddc5d minor documentation fixes (#197)
* "is an an" -> "is an"

* grammar fix

* grammar fix

* update HISTORY.md
2020-04-17 10:35:37 -04:00
Ryan Curtin 7064fbeb60 Add new block for next release to HISTORY.md. 2020-04-16 20:40:32 -04:00
Ryan Curtin 09fccad4a4 Update and release version 2.12.1. 2020-04-16 20:40:32 -04:00
Ryan Curtin c0e08158b2 Allow SSH remotes. 2020-04-16 20:39:35 -04:00
Ryan Curtin 2d25bd933e Update HISTORY for release. 2020-04-16 20:37:08 -04:00
Marcus Edel c19da5560d Merge pull request #195 from say4n/patch-1
Update HISTORY.md.
2020-04-16 20:39:59 +02:00
Gaurav SinghandRyan Curtin a005414da0 Fixing ProgressBar() (#181)
* Initial commit.

* Minor fixes.

* Style changes.

* Minor style changes.

* Minor Changes

* Changes in HISTORY.md and adding a test.

* minor changes.

* Update HISTORY.md

Co-Authored-By: Ryan Curtin <ryan@ratml.org>

* Update include/ensmallen_bits/callbacks/progress_bar.hpp

Co-Authored-By: Ryan Curtin <ryan@ratml.org>

* Incorporating the changes.

* Solving style issues

* Solving merge conflicts.

* Adding tests and correcting the epoch conditionals.

* Minor changes in tests.

* Minor style changes

* Minor changes.

* Style changes.

* Changes in callback tests.

* Style Changes.

* Update include/ensmallen_bits/callbacks/progress_bar.hpp

Co-Authored-By: Ryan Curtin <ryan@ratml.org>

* Update tests/callbacks_test.cpp

Co-Authored-By: Ryan Curtin <ryan@ratml.org>

* Update tests/callbacks_test.cpp

Co-Authored-By: Ryan Curtin <ryan@ratml.org>

* Changes in tests.

Co-authored-by: Ryan Curtin <ryan@ratml.org>
2020-04-16 20:06:46 +02:00
Ryan Curtin a8c29763c0 Merge pull request #194 from conradsnicta/traits-fix
handle SpSubview_col and SpSubview_row in Armadillo 9.870
2020-04-15 22:30:03 -04:00
Ryan CurtinandMarcus Edel 324016696c Update HISTORY.md
Co-Authored-By: Marcus Edel <marcus.edel@fu-berlin.de>
2020-04-15 22:29:53 -04:00
Sayan Goswami 5b5da69148 Update HISTORY.md
Add missing end quote. :)
2020-04-15 23:08:36 +05:30
conrad c05be60ca5 update HISTORY.md 2020-04-15 13:37:56 +10:00
conrad 514cfcd8c0 update HISTORY.md 2020-04-15 13:36:16 +10:00
conrad 9d30e3391b add trais for arma::SpSubview_col and arma::SpSubview_col 2020-04-15 13:25:35 +10:00
Sayan Goswami f6ce7fe753 Add documentation for multi objective fucntion type. 2020-04-13 20:25:29 +05:30
Sayan Goswami b0d7ea5e7d Remove newline, fix indentation 2020-04-13 20:07:55 +05:30
Ryan Curtin 2615335321 Merge pull request #192 from rcurtin/update-release-scripts
Update release scripts
2020-04-03 10:12:14 -04:00
Sayan Goswami bde5152db8 Make objectives public members, use explicit type instead of auto keyword 2020-04-03 13:17:14 +05:30
Sayan Goswami e06d407afc Use explicit types instead of auto 2020-04-03 13:16:11 +05:30
Sayan Goswami 75183d00f7 Fix typo, add braces, correct indentation, spacing 2020-04-03 12:55:37 +05:30
Sayan Goswami 76b71b2594 Remove unnecessary line break 2020-04-03 12:48:31 +05:30
Sayan Goswami c187ad5b0c Wrap lines to <80 columns 2020-04-03 12:47:46 +05:30
Sayan Goswami 0dc99f0831 Reposition multi-objective optimization section to before constrained functions 2020-04-03 12:46:06 +05:30
Sayan Goswami 13c1857c57 Add period to end of line 2020-04-03 12:45:10 +05:30
Sayan Goswami 13bdfc1f5c Merge branch 'nsga2' from remote 2020-04-03 12:40:47 +05:30
Sayan Goswami 2ac289a20d Fix typos 2020-04-03 12:39:13 +05:30
Ryan Curtin f1764fa62f Remove now-unnecessary output. 2020-03-29 18:22:29 -04:00
Ryan Curtin b8cb8e660f Clean up and refactor release scripts so admin access is not needed. 2020-03-29 18:21:53 -04:00
Sayan Goswami e9867d927c Merge branch 'master' into nsga2 2020-03-29 03:54:24 -04:00
Ryan Curtin 82368c4c05 Add new HISTORY block. 2020-03-28 13:06:38 -04:00
Ryan Curtin 12a2522df7 Update and release version 2.12.0. 2020-03-28 13:05:32 -04:00
Ryan Curtin a1c65c55d5 Update HISTORY for release. 2020-03-28 13:05:24 -04:00
Ryan Curtin 761b2dbd18 Minor style fix. 2020-03-28 12:52:00 -04:00
favre49 c76d18b704 Merge pull request #185 from jwdinius/remove-sdp-depr
remove sdp deprecated methods
2020-03-28 21:41:41 +05:30
Sayan Goswami 8fb4578758 Merge remote-tracking branch 'upstream/master' into nsga2 2020-03-27 10:18:58 +05:30
favre49 f948ea6119 Merge pull request #186 from rcurtin/readme-new-logo
Use new ensmallen logo
2020-03-27 09:26:39 +05:30
Ryan Curtin be08b5639d Merge branch 'master' into readme-new-logo 2020-03-26 22:46:07 -04:00
Ryan Curtin 2d5f6d6d37 Change to 'numerical optimization'. 2020-03-26 22:43:13 -04:00
Ryan Curtin d37205b59a Try adding a new logo. 2020-03-26 22:40:11 -04:00
Joe Dinius f29fe7650b address issue #184 - remove sdp deprecated methods 2020-03-26 07:32:09 -07:00
favre49 293cc83cbf Merge pull request #183 from gaurav-singh1998/minor-cmaes-sigma-fix
Correction in the computation of sigma for the next population in CMA-ES.
2020-03-24 17:07:11 +05:30
Gaurav Singh fa2ada3823 Merge branch 'master' into minor-cmaes-sigma-fix 2020-03-24 00:51:37 +05:30
Gaurav Singh f3ed6bb0b1 Changes in HISTORY.md 2020-03-24 00:47:14 +05:30
Gaurav Singh d792bfbc24 Minor Changes. 2020-03-23 20:35:04 +05:30
favre49 7bad0ed0e0 Update include/ensmallen_bits/cmaes/cmaes_impl.hpp 2020-03-21 19:25:17 +05:30
Gaurav Singhandfavre49 a984138685 Update include/ensmallen_bits/cmaes/cmaes_impl.hpp
Co-Authored-By: favre49 <40389657+favre49@users.noreply.github.com>
2020-03-21 19:20:44 +05:30
Gaurav Singh e2b8031fb8 Initial commit. 2020-03-21 17:49:47 +05:30
Sayan Goswami 7d8ac2c05a Remove ambiguity with example in documentation 2020-03-19 17:47:53 +05:30
Sayan Goswami cee6461e69 Fix indentation, spacing, rephrase documentation 2020-03-19 17:41:41 +05:30
Sayan Goswami b3052b9c92 Repharse doc, fix indentation, change bounds to use reference, use camel case 2020-03-15 19:17:12 +05:30
Marcus Edel 7d8707d9f3 Merge branch 'master' into nsga2 2020-03-14 00:28:32 +01:00
Ryan Curtin 3cb3827671 Add new HISTORY block. 2020-03-11 21:06:35 -04:00
Ryan Curtin a174206f99 Update and release version 2.11.5. 2020-03-11 21:05:39 -04:00
Ryan Curtin ef02b18a6f Update HISTORY for release. 2020-03-11 21:05:22 -04:00
Marcus Edel dbd23f3a4a Merge pull request #177 from rcurtin/mathematical-to-numerical
Change 'mathematical optimization' to 'numerical optimization'.
2020-03-09 23:23:00 +01:00
Ryan Curtin d08aa13dab Update history. 2020-03-09 07:44:05 -04:00
Ryan Curtin 60f0d58809 Change 'mathematical' to 'numerical'.
This better matches the existing literature and is likely to be less confusing
to people who come across the term.
2020-03-09 07:41:42 -04:00
Sayan Goswami 594d79369a Fix compiler warnings, change test params 2020-03-08 01:24:39 +05:30
Sayan Goswami e5353694f4 Fix punctuation, indentation, line breaks 2020-03-07 16:41:09 +05:30
Sayan Goswami d4ce416b39 Adjust hyperparameters to fix failing tests 2020-03-07 16:08:09 +05:30
Sayan Goswami b01eb26829 Adjust hyperparameters to fix failing tests 2020-03-07 15:59:12 +05:30
Sayan Goswami 16165f8ceb Fix typo 2020-03-07 09:42:15 +05:30
Sayan Goswami 2c6418b445 Merge branch 'master' into nsga2 2020-03-04 14:01:48 -05:00
Sayan Goswami 8c9f992e3d Update history 2020-03-05 00:29:20 +05:30
Sayan Goswami bb37702917 Fix typo, indentation, line breaks 2020-03-04 21:22:40 +05:30
Ryan Curtin b35b5acbdc Update and release version 2.11.4. 2020-03-03 12:34:33 -05:00
Ryan Curtin 8d187ae4e5 Update HISTORY to latest stable version. 2020-03-03 12:34:04 -05:00
Ryan Curtin 3ee4bcad40 Update HISTORY for #174 merge. 2020-03-03 11:48:30 -05:00
Ryan Curtin 4fdfc97539 Merge pull request #174 from zoq/doc-fix
Example doc fix + add/use default argument.
2020-03-03 11:47:46 -05:00
Ryan Birmingham 777bca8d1d Re-fix Ensmallen History Mod Checker (#175)
* test without history mod

* try ysing name only and wc

* give some info in test itself

* script fix?

* ensure adding history fixes build
2020-03-03 00:37:54 +01:00
Marcus Edel cd56df2061 Add/use default type. 2020-03-01 17:51:55 +01:00
Marcus Edel 1fd6eebe47 The L_BFGS optimizer doesn't use a template. 2020-03-01 17:51:08 +01:00
Ryan Birmingham 29ff827019 not-so-quick fix sanity check for outside of PRs (#172)
Travis CI Staged Build Config
2020-02-29 20:26:54 -05:00
Marcus Edel 08994c52ee Merge pull request #171 from coatless/require-history-entry
Require history entry.
2020-02-27 19:25:40 +01:00
James Balamuta 321f7201d6 EOL issue 2020-02-26 14:15:54 -06:00
James Balamuta 882ecf3122 Revise... 2020-02-26 14:05:33 -06:00
James J Balamuta e28c0c0e4d Exit to avoid duplicate test run 2020-02-26 11:56:51 -06:00
Sayan Goswami 24fa27655d Add documentation for multi objective functions 2020-02-26 02:28:11 +05:30
Sayan Goswami 9618226d84 Fix typo, move includes to ensmallen.hpp, add newline! 2020-02-26 01:49:07 +05:30
James Balamuta 09291cecf4 Enable sanity check with jenkins for history entry (h/t @birm) 2020-02-24 16:02:04 -06:00
James Balamuta 2e9e1e7dde Bump to new version in HISTORY.md 2020-02-19 20:56:44 -06:00
James Balamuta 4cd83b417b Wording tweaks. 2020-02-19 20:55:25 -06:00
James Balamuta 8c98650fb6 Update with latest release commit... 2020-02-19 20:53:25 -06:00
James Balamuta 86836a2a6b Tweak header 2020-02-19 16:38:45 -06:00
James Balamuta d6442a0a0f Fix check 2020-02-19 16:19:52 -06:00
James Balamuta d6051fb393 Add a note to history 2020-02-19 16:15:35 -06:00
James Balamuta f84655b959 Add history check PR update 2020-02-19 16:09:32 -06:00
Ryan Curtin a5891f11a2 Update and release version 2.11.3. 2020-02-19 17:08:04 -05:00
Ryan Curtin 8663a12fac Update HISTORY. 2020-02-19 17:07:46 -05:00
James Balamuta 7f13c8beac Rename from rel to scripts 2020-02-19 16:06:10 -06:00
Marcus Edel f7653343b7 Merge pull request #169 from mlpack/conradsnicta-readme-cmake-note
Proposed note on cmake requirements.
2020-02-19 22:53:11 +01:00
Marcus Edel 078733295d Merge pull request #170 from rcurtin/history-fix
Update HISTORY.
2020-02-19 21:18:22 +01:00
Ryan Curtin c6d233c45e Merge remote-tracking branch 'origin/master' into history-fix 2020-02-19 08:57:26 -05:00
Ryan Curtin e6adb5e9e5 Update HISTORY. 2020-02-19 08:55:29 -05:00
Conrad SandersonandRyan Curtin 55e5f72cf5 more details
Co-Authored-By: Ryan Curtin <ryan@ratml.org>
2020-02-19 04:54:07 +01:00
Conrad Sanderson 0ac60f2e0f proposed note on cmake requirements 2020-02-19 04:35:03 +01:00
Ryan Curtin 4cf66255cf Merge pull request #167 from rcurtin/memory-fix
Fix memory leak
2020-02-18 21:10:29 -05:00
Ryan Curtin 614ba62a5d Merge branch 'favre49-cmake' 2020-02-18 13:40:32 -05:00
Ryan Curtin 67a94b2236 Add newline at end of file. 2020-02-18 13:39:30 -05:00
Ryan Curtin 013a496203 Merge branch 'cmake' of https://github.com/favre49/ensmallen into favre49-cmake 2020-02-18 13:39:17 -05:00
Ryan Curtin 44181d9990 Fix memory leak. 2020-02-17 16:50:14 -05:00
Ryan Curtin 854f0f34ad Merge pull request #158 from rcurtin/appveyor-config
AppVeyor config
2020-02-17 16:26:42 -05:00
Ryan Birmingham 1625cc14e1 Merge pull request #166 from shrit/citations
Adding bib tex format in the README
2020-02-17 14:34:04 -05:00
Omar Shrit fa07a27498 Keep the original version in addition to bibtex
Signed-off-by: Omar Shrit <shrit@lri.fr>
2020-02-17 19:39:32 +01:00
Ryan Curtin 1d5234fbba Remove possibly-unnecessary ARMADILLO_LIBRARY. 2020-02-17 11:55:23 -05:00
Omar Shrit d9ca887eb6 Adding digital object identifier to bibtex
Signed-off-by: Omar Shrit <shrit@lri.fr>
2020-02-17 11:56:47 +01:00
Omar Shrit 0a66f6cd2c Adding bib tex format in the README
Signed-off-by: Omar Shrit <shrit@lri.fr>
2020-02-15 21:25:34 +01:00
Ryan Curtin c0ea1ed4e7 Remove unnecessary line. 2020-02-13 20:29:34 -05:00
Sayan Goswami dd7fd0a3af Merge branch 'master' into nsga2 2020-02-13 00:14:52 -05:00
Sayan Goswami 603d9a18c1 Add NSGA2 Callback test 2020-02-13 10:41:12 +05:30
Sayan Goswami a11974a4ea Update documentation
Remove 'Multi-objective functions', update NSGA2 Optimize() example
2020-02-10 23:07:35 +05:30
Sayan Goswami 6b7c1dac8c Use unnamed arguments for SFINAE base case
Fixes -Werror=unused-parameter
2020-02-10 11:16:13 +05:30
Sayan Goswami cffac3ce6b Add std::tuple to SCH N.1 2020-02-10 11:04:33 +05:30
Sayan Goswami 47824790e6 Remove redundant typedef 2020-02-10 10:41:51 +05:30
Sayan Goswami be24de787c Fix compiler errors
SFINAE to the rescue!
2020-02-10 10:32:09 +05:30
Ryan Curtin 1828468a0a Merge pull request #164 from shrit/execution_right
Remove execution right from headers
2020-02-09 12:50:07 -07:00
Sayan Goswami 216d1dfdbf Use multiple variadic templates — compile failure! 2020-02-09 23:26:57 +05:30
Omar Shrit b8bf5dae1a Remove execution right from headers
Signed-off-by: Omar Shrit <shrit@lri.fr>
2020-02-08 23:03:44 +01:00
Ryan Curtin 42313d38d0 Adjust tolerances. 2020-01-28 18:02:48 -05:00
Ryan Curtin aa9bed34a7 Try running the test alone. 2020-01-24 14:09:48 -05:00
Ryan Curtin 2ce08eb861 Focus on failing test. 2020-01-24 12:49:14 -05:00
Ryan Curtin 8cb84ca9e6 Copy library in the same way the mlpack config does. 2020-01-24 11:58:17 -05:00
Ryan Curtin a8d45cfbd8 Use powershell to copy? What is happening? 2020-01-24 11:15:58 -05:00
Ryan Curtin 10ee5c68c6 Different copy? 2020-01-24 10:53:40 -05:00
Ryan Curtin 0873421fd7 Ok, try copying libopenblas.dll. 2020-01-23 17:11:36 -05:00
Ryan Curtin db36e89305 Oops, forgot the file extension. 2020-01-23 13:44:44 -05:00
Ryan Curtin 5188145f92 Fix path. 2020-01-23 13:14:24 -05:00
Ryan Curtin d4572a0062 Try again using the correct (hopefully) dumpbin. 2020-01-23 12:31:22 -05:00
Ryan Curtin a5f1ab57dc Try to print all needed DLLs. 2020-01-23 10:32:12 -05:00
Sayan Goswami da52154072 Add doc for Multi-objective functions 2020-01-23 15:58:55 +05:30
Sayan Goswami 5d0d9f9a82 Update docs; add getters, setters; use arma::vec instead of arma::mat 2020-01-23 15:45:03 +05:30
Sayan Goswami 532040f356 Add lower, upper bound as optimizer parameter 2020-01-23 15:29:58 +05:30
Ryan Curtin 197fff8c8f Try copying shared objects to working directory. 2020-01-22 13:27:22 -05:00
Ryan Curtin 7e3c41a48a Provide verbose output from tests. 2020-01-22 11:52:25 -05:00
Ryan Curtin 4ee12b0c47 Specify configuration to run tests. 2020-01-21 21:37:08 -05:00
Ryan Curtin 37a0861980 Other little fixes for compilation.
(Should have tested it all first.)
2020-01-21 20:39:33 -05:00
Ryan Curtin 03a717fcd4 Huh, I must not be very smart. 2020-01-21 19:14:47 -05:00
Ryan Curtin da3373464f Fix std::min types for pedantic MSVC. 2020-01-21 19:10:39 -05:00
Ryan Curtin 1e5995571e These might also be necessary. 2020-01-21 17:21:13 -05:00
Ryan Curtin 2764266a44 Fix path. 2020-01-21 11:49:59 -05:00
Ryan Curtin 65463566d4 Could spacing be an issue here? 2020-01-21 11:40:12 -05:00
Marcus Edel 51614c216e Merge pull request #162 from mlpack/conradsnicta-patch-1
Update history.
2020-01-16 19:18:00 +01:00
Conrad Sanderson c2637c0e20 update history 2020-01-16 03:41:18 +01:00
Conrad Sanderson 5469374a2a prevent spurious compiler warnings (#161) 2020-01-16 03:37:14 +01:00
Ryan Curtin b67c673639 Add new block for history. 2020-01-15 10:23:23 -05:00
Ryan Curtin ba0897d57f Update and release version 2.11.2. 2020-01-15 10:22:29 -05:00
Ryan Curtin c8bcbbf430 Update history. 2020-01-15 10:21:37 -05:00
Ryan Curtin 226352ae9f Merge pull request #159 from zoq/lookahead-maxiterations
Fix Lookahead MaxIterations() check
2020-01-15 10:20:45 -05:00
Marcus Edel fe9c6f3c0e Fix Lookahead MaxIterations() check. 2020-01-12 00:29:24 +01:00
Ryan Curtin 11e9ee7c54 Build Armadillo in C:\projects\armadillo. 2020-01-10 13:42:41 -05:00
Ryan Curtin 64d3f6e5f8 Move up to the right directory. 2020-01-10 13:23:38 -05:00
Ryan Curtin 3eff5848b0 Fix syntax. 2020-01-10 13:16:06 -05:00
Ryan Curtin 4ec4f50324 Fix directories. 2020-01-10 13:07:47 -05:00
Ryan Curtin dced93ed12 Update paths. 2020-01-10 09:52:48 -05:00
Ryan Curtin f5464ae540 Whitespace change to trigger build. 2020-01-10 09:09:11 -05:00
Sayan Goswami 3498b0f01b Remove unnecessary logging 2020-01-10 13:43:58 +05:30
Sayan Goswami b8695df78a Add lower, upper bounds for mutation 2020-01-10 13:12:37 +05:30
Ryan Curtin 2fd30ef5dc Add an attempt at an AppVeyor config. 2020-01-09 18:17:58 -05:00
Marcus Edel 4a35fd6e1b Merge pull request #155 from zoq/callback-pass-fix
Fix Callback passing for SGD based optimizers.
2020-01-09 17:15:24 +01:00
Marcus Edel 54e2d408b2 Merge branch 'master' into callback-pass-fix 2020-01-08 19:38:45 +01:00
Sayan Goswami f74619fe7c Add Fonseca Flemming test function 2020-01-08 18:35:15 +05:30
Sayan Goswami 0b14d94dc9 Fix braces, remove redundant check (if-else instead of if) 2020-01-06 17:12:00 +05:30
Sayan Goswami 86276fa29b Fix typos, line width, remove unnecessary logging, braces, add checks in Optimizer 2020-01-06 15:10:30 +05:30
Sayan Goswami 78662ac930 Add doc, rename MutationSize to MutationStrength 2020-01-04 18:41:44 +05:30
favre49 73c03b5e70 Merge pull request #156 from rcurtin/float-tol-fixes
Fix float types and tolerances in some tests.
2020-01-04 16:43:21 +05:30
favre49 0202d479c4 Merge pull request #157 from say4n/typo-fix-SCHn2
Fix typo
2020-01-04 16:42:00 +05:30
Sayan Goswami 9fe48976bf Add template arg for calculatedObjectives, add const reference in Crossover, fix indentation 2020-01-04 13:49:23 +05:30
Sayan Goswami 419b35a1a7 Re-introduce range based checks 2020-01-04 11:43:28 +05:30
Sayan Goswami 177ce878a8 Fix typos, remove unnecessary fields from citation 2020-01-04 11:42:59 +05:30
Sayan Goswami 9785fdf462 Fix typo 2020-01-03 16:00:23 +05:30
Sayan Goswami e54c7ab7a1 Add documentation 2020-01-03 15:48:26 +05:30
Sayan Goswami 39fe0e96d2 Fix indentation, code style. Use const reference for parameters, remove redundant variables, remove auto keyword, fix erroneous check, change return type of Schaffer N.1 function 2020-01-03 14:04:04 +05:30
Marcus Edel 074e6c57c5 Update history (#155). 2020-01-02 17:59:07 +01:00
Ryan Curtin fe2e20d798 Update history. 2020-01-02 11:22:59 -05:00
Ryan Curtin a3afeefc83 Fix float types and tolerances in some tests. 2020-01-02 11:17:52 -05:00
Rahul Prabhu bed37733ab Removed ARCH_INDEPENDENT 2020-01-02 20:03:56 +05:30
Rahul Prabhu 369046f99d Changed case where necessary 2020-01-02 19:28:47 +05:30
Sayan Goswami eee7b78da4 Fix alignment of braces 2020-01-02 18:38:40 +05:30
Sayan Goswami 1fa339cd57 Remove unused variable 2020-01-02 18:32:05 +05:30
Sayan Goswami 1c734d10ed Merge branch 'master' into nsga2 2020-01-02 18:26:20 +05:30
Sayan Goswami 21df412cb0 Change test to just print 2020-01-02 18:11:12 +05:30
Sayan Goswami 73c6fbd92f Rename MaxGenerations, CrossoverRate, MutationProbability, MutationSize; Correct indentation 2020-01-02 18:10:45 +05:30
Sayan Goswami dbbf217388 Arrange includes alphabetically 2020-01-02 18:05:27 +05:30
Marcus Edel 86e289691a Fix callback passing for SGD based optimizers. 2019-12-31 20:21:50 +01:00
Rahul Prabhu 8ef70e346b Added Conrad's suggestion. Must fix styles. 2019-12-30 13:57:07 +05:30
Roberto Hueso Gomez e9bb969b1f Update HISTORY after release 2019-12-28 17:37:50 +01:00
Roberto Hueso Gomez 421c667eac Update and release version 2.11.1. 2019-12-28 17:26:23 +01:00
Roberto Hueso Gomez fab7c1c82e Update HISTORY for release 2019-12-28 15:40:45 +01:00
favre49 95711477bc Merge pull request #154 from rcurtin/doc-function-types-fix
Add some missing optimizer types.
2019-12-28 18:20:43 +05:30
Ryan Curtin 839b94dec4 Merge pull request #153 from zoq/lookahead-type-fix
Lookahead - Synchronization period type fix
2019-12-27 23:33:44 -05:00
Rahul Prabhu fc5ce2ff46 Added warning flags and exporting scripts. 2019-12-27 21:41:52 +05:30
Marcus Edel a00189035a Update HISTORY.md (Lookahead type fix). 2019-12-27 14:03:41 +01:00
Marcus Edel a8bddce1da Merge branch 'master' into lookahead-type-fix 2019-12-27 14:01:35 +01:00
Ryan Curtin 31bb39a7c9 Add some missing optimizer types. 2019-12-26 22:35:53 -05:00
Marcus Edel 4e8c34e33b Use the correct return type for the synchronization period (k). 2019-12-26 21:41:24 +01:00
Sayan Goswami d7d62b0483 Change test parameters, use random initialization for coordinates 2019-12-27 00:42:50 +05:30
Sayan Goswami 2a9fde7e7e Add Schaffer N.1 function 2019-12-27 00:19:08 +05:30
Sayan Goswami a352f60755 Convert vector<double> to arma::vec 2019-12-26 23:36:33 +05:30
Sayan Goswami e150f635d4 Fix check for objectiveNumber 2019-12-26 20:44:58 +05:30
Sayan Goswami 127953bd2f Remove Evaluate callback 2019-12-26 20:22:15 +05:30
Sayan Goswami c417b08b38 Add callbacks, remove unused parameters 2019-12-26 20:10:25 +05:30
Sayan Goswami 80a9a12d3a Remove unused typedef 2019-12-26 19:11:41 +05:30
Sayan Goswami 274b0d74d0 Fix linker, compiler errors & add logging 2019-12-26 19:08:01 +05:30
Sayan Goswami ceeb7cc210 Add tests for NSGA2 2019-12-26 17:09:59 +05:30
Sayan Goswami 4eed69a456 Implement NSGA2 optimizer 2019-12-26 17:09:02 +05:30
Rahul Prabhu 46856b09f7 Fixed add_test 2019-12-26 11:09:22 +05:30
Rahul Prabhu 53ee9f5360 Fixed version 2019-12-25 18:59:52 +05:30
Rahul Prabhu 1812812296 Cut down a bit, and some more documentation 2019-12-25 18:57:26 +05:30
Rahul Prabhu 5c1eb89528 It works 2019-12-25 18:25:20 +05:30
Ryan Curtin 753e3cd4a3 Add names of releases. 2019-12-24 23:30:53 -05:00
Ryan Curtin 3807cec72a Update HISTORY for release. 2019-12-24 23:06:48 -05:00
Ryan Curtin f1e8084a83 Update and release version 2.11.0. 2019-12-24 23:03:35 -05:00
Ryan Curtin 22269e4e4e Merge pull request #138 from zoq/Lookahead
Lookahead Optimizer: k steps forward, 1 step back
2019-12-24 22:47:40 -05:00
Sayan Goswami 79150db4ce Add constructor, FastNonDominatedSort and Dominates (pareto dominance) 2019-12-25 00:59:50 +05:30
Ryan Curtin 540b00ce0b Merge pull request #148 from say4n/readme
Add build/test instructions
2019-12-24 11:50:44 -05:00
Marcus Edel 13291c5505 Merge branch 'master' into Lookahead 2019-12-24 14:38:50 +01:00
Marcus Edel 67dce9f5fb Reword the info if the base optimzer does not have a definition of MaxIterations() and update the function types documentation. 2019-12-24 14:37:05 +01:00
Sayan Goswami 1c2304c027 Update CONTRIBUTING.md
Add build instructions for Arch, fix typo
2019-12-24 13:10:46 +05:30
Ryan Curtin 9efcda94ec Merge pull request #137 from zoq/AdaBound
AdaBound + AMSBound
2019-12-23 21:26:50 -05:00
Marcus Edel 03dbd6a1fc Adjust step size (Lookahead test). 2019-12-24 02:32:49 +01:00
Marcus Edel 64af8f9ab5 Optimize test settings to make the Lookahead test suite more stable. 2019-12-24 00:14:26 +01:00
Marcus Edel 24ab54dc88 Add another constructor that uses a default base optimizer instance. 2019-12-23 22:33:34 +01:00
Marcus Edel d560239f41 Update the defaults for the Lookahead optimzer. 2019-12-23 22:32:16 +01:00
Sayan Goswami ff381b912e Update CONTRIBUTING.md
Add cmake to dependencies, add instructions for Fedora/RHEL/CentOS, add Homebrew package, remove typo (extra backticks)
2019-12-23 15:31:30 +05:30
Sayan Goswami 00660aa99c Update release script
Add updated CONTRIBUTING.md on new release to git
2019-12-23 15:29:08 +05:30
Marcus Edel e076f8b7ab Add parameter (resetPolicy) which resets the update policy before the optimizer call. 2019-12-22 21:09:41 +01:00
Marcus Edel 6e61946f6c Move HasBatchSize() and HasMaxIterations() from the callbacks to the functions traits. 2019-12-22 21:08:28 +01:00
Marcus Edel 84f94e98a9 Fix doxygen bibtex block (start with @code and end with @endcode). 2019-12-22 21:06:57 +01:00
Sayan Goswami 99478eab82 Add NSGA2 (WIP) 2019-12-22 17:47:23 +05:30
Sayan Goswami dbd9fc0c91 Add name to list of contributors 2019-12-21 10:46:16 +05:30
Sayan Goswami ce4aede3b0 Auto update CONTRIBUTING.md test instructions on new release 2019-12-18 20:09:20 +05:30
Sayan Goswami 0438bea03c Update CONTRIBUTING.md
Use semantic version number of latest release instead of x.x.x placeholders
2019-12-18 20:07:05 +05:30
Sayan Goswami b5043a142e Update CONTRIBUTING.md
Remove lapack from dependencies, update archive to use semver instead of latest, default to make without j flag, fix typo.
2019-12-18 11:31:22 +05:30
Sayan Goswami 245aa48c71 Migrate build/test instructions to CONTRIBUTING.md 2019-12-16 12:12:18 +05:30
Sayan Goswami 6392f38133 Add cmake to dependencies 2019-12-15 20:10:17 +05:30
Sayan Goswami 30e2cd499f Update README: add build/test instructions 2019-12-15 19:42:41 +05:30
Marcus EdelandRyan Curtin b447a0cdbe Minor spelling fix.
Co-Authored-By: Ryan Curtin <ryan@ratml.org>
2019-12-14 23:36:09 +01:00
Marcus Edel 1b98ce8394 Add Lookahead to the optimizer function documentation. 2019-12-14 18:53:43 +01:00
Marcus Edel 05d02a168d Update history. 2019-12-14 18:53:05 +01:00
Marcus Edel 9012983751 Merge branch 'master' into Lookahead 2019-12-14 18:47:28 +01:00
Marcus EdelandRyan Curtin 4471cdf0a0 Use the correct update policy.
Co-Authored-By: Ryan Curtin <ryan@ratml.org>
2019-12-14 01:11:35 +01:00
Marcus Edel 5f9d5147ee Update history. 2019-12-13 22:21:35 +01:00
Marcus Edel 5384c73117 Add AdaBound and AMSBound to the optimizer function documentation. 2019-12-13 22:20:04 +01:00
Marcus Edel 1d45614f41 Merge branch 'master' into AdaBound 2019-12-13 22:12:09 +01:00
Ryan Curtin 7557fe83ac Fix history. 2019-12-13 13:41:08 -05:00
Marcus Edel 681cef818f Adjust parameter order and fix indentation. 2019-12-12 23:05:47 +01:00
Marcus EdelandRyan Curtin 1dff1c78ef Use camel casing for the parameter description.
Co-Authored-By: Ryan Curtin <ryan@ratml.org>
2019-12-12 22:56:08 +01:00
Marcus EdelandRyan Curtin 27c310c2b7 Minor indentation fix.
Co-Authored-By: Ryan Curtin <ryan@ratml.org>
2019-12-12 22:55:29 +01:00
Marcus EdelandRyan Curtin c84ba3cd16 Minor spelling fix.
Co-Authored-By: Ryan Curtin <ryan@ratml.org>
2019-12-12 22:54:36 +01:00
Marcus EdelandRyan Curtin 605a7f4eb6 Use camel casing for the parameter description.
Co-Authored-By: Ryan Curtin <ryan@ratml.org>
2019-12-12 22:54:11 +01:00
Marcus Edel 0464db9acf Return model coordinates if the optimization process terminates. 2019-09-29 20:02:45 +02:00
Marcus Edel 59f62b2200 Use batch size from the base optimizer. 2019-09-26 00:20:06 +02:00
Marcus Edel 399793bd57 Fix reorder issue. 2019-09-25 22:08:23 +02:00
Marcus Edel 7e95a4fc1a Update history. 2019-09-25 19:13:09 +02:00
Marcus Edel 39af8fbf5e Use the correct function name. 2019-09-25 19:11:48 +02:00
Marcus Edel 54587897d4 Add Lookahead optimizer test cases. 2019-09-25 19:06:37 +02:00
Marcus Edel 198ac2cda1 Add Lookahead to the optimizer documentation. 2019-09-25 19:06:08 +02:00
Marcus Edel 60450079f7 Add Lookahead optimizer. 2019-09-25 19:05:41 +02:00
Marcus Edel 1f94efdf9b Clarify comment. 2019-09-25 19:02:55 +02:00
Marcus Edel 466bc012a4 Merge branch 'master' into AdaBound 2019-09-21 18:45:21 +02:00
Marcus Edel 24487032e1 Update HISTORY.md (new optimizer AdaBound + AMSBound). 2019-09-21 18:44:30 +02:00
Marcus Edel 4c83c9de44 Add AdaBound and AMSBound to the optimizer documentation. 2019-09-21 18:41:30 +02:00
Marcus Edel 84073d3575 Add AdaBound and AMSBound test cases. 2019-09-21 18:32:00 +02:00
Marcus Edel b13228283b Add AdaBound and AMSBound. 2019-09-21 18:31:39 +02:00
169 changed files with 16231 additions and 4746 deletions
+57
View File
@@ -0,0 +1,57 @@
environment:
ARMADILLO_DOWNLOAD: "https://sourceforge.net/projects/arma/files/armadillo-9.800.6.tar.xz"
BLAS_LIBRARY: "%APPVEYOR_BUILD_FOLDER%/OpenBLAS.0.2.14.1/lib/native/lib/x64/libopenblas.dll.a"
BLAS_LIBRARY_DLL: "%APPVEYOR_BUILD_FOLDER%/OpenBLAS.0.2.14.1/lib/native/lib/x64/libopenblas.dll"
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
VSVER: Visual Studio 14 2015 Win64
MSBUILD: C:\Program Files (x86)\MSBuild\14.0\bin\MSBuild.exe
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
VSVER: Visual Studio 15 2017 Win64
MSBUILD: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
VSVER: Visual Studio 16 2019
MSBUILD: C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe
configuration: Release
install:
- ps: nuget install OpenBLAS -o "${env:APPVEYOR_BUILD_FOLDER}"
build_script:
# First, download and build Armadillo.
- cd ..
- appveyor DownloadFile %ARMADILLO_DOWNLOAD% -FileName armadillo.tar.xz
- 7z x armadillo.tar.xz -so -txz | 7z x -si -ttar > nul
- cd armadillo-9.800.6 && mkdir build && cd build
- >
cmake -G "%VSVER%"
-DBLAS_LIBRARY:FILEPATH=%BLAS_LIBRARY%
-DLAPACK_LIBRARY:FILEPATH=%BLAS_LIBRARY%
-DCMAKE_PREFIX:FILEPATH="%APPVEYOR_BUILD_FOLDER%/armadillo"
-DBUILD_SHARED_LIBS=OFF
-DCMAKE_BUILD_TYPE=Release ..
- >
"%MSBUILD%" "armadillo.sln"
/m /verbosity:quiet /p:Configuration=Release;Platform=x64
- cd ../..
# Now build ensmallen.
- cd ensmallen && mkdir build && cd build
- >
cmake -G "%VSVER%"
-DARMADILLO_INCLUDE_DIR=%APPVEYOR_BUILD_FOLDER%/../armadillo-9.800.6/include/
-DARMADILLO_LIBRARIES=%BLAS_LIBRARY%
-DLAPACK_LIBRARY=%BLAS_LIBRARY%
-DBLAS_LIBRARY=%BLAS_LIBRARY%
-DCMAKE_BUILD_TYPE=Release ..
- >
"%MSBUILD%" "ensmallen.sln"
/m /verbosity:minimal /nologo /p:BuildInParallel=true
# Run tests after copying libraries.
- ps: cp C:\projects\ensmallen\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.* C:\projects\ensmallen\build\
- ctest -C Release -V --output-on-failure .
+18 -12
View File
@@ -1,26 +1,32 @@
sudo: required
dist: trusty
os: linux
dist: focal
language: cpp
env:
- ARMADILLO=latest
- ARMADILLO=latest SANITY_HISTORY=perform
- ARMADILLO=minimum
before_install:
stages:
- test
- name: sanity
if: type = pull_request AND env(SANITY_HISTORY) = "perform"
jobs:
include:
- stage: sanity
name: "HISTORY.md Check"
script: sh ./scripts/history-update-check.sh
script:
- sudo apt-get update
- sudo apt-get install -y --allow-unauthenticated libopenblas-dev liblapack-dev g++ xz-utils
- if [ $ARMADILLO == "latest" ]; then
curl https://ftp.fau.de/macports/distfiles/armadillo/`curl https://ftp.fau.de/macports/distfiles/armadillo/ -- | grep '.tar.xz' | sed 's/^.*<a href="\(armadillo-[0-9]*.[0-9]*.[0-9]*.tar.xz\)".*$/\1/' | tail -1` | tar xvJ && cd armadillo*;
fi
- if [ $ARMADILLO == "minimum" ]; then
curl https://ftp.fau.de/macports/distfiles/armadillo/armadillo-8.400.0.tar.xz | tar -xvJ && cd armadillo*;
else
curl -L https://sourceforge.net/projects/arma/files/armadillo-9.800.6.tar.xz | tar -xvJ && cd armadillo*;
fi
- cmake . && make && sudo make install && cd ..
install:
- mkdir build && cd build && cmake -DCMAKE_CXX_FLAGS="-Werror" -DCMAKE_C_FLAGS="-Werror" .. && make -j2
script:
- mkdir build && cd build && cmake .. && make ensmallen_tests -j2
- CTEST_OUTPUT_ON_FAILURE=1 travis_wait 30 ctest -j2
notifications:
+6
View File
@@ -366,4 +366,10 @@ mark_as_advanced(
ARMADILLO_INCLUDE_DIR
ARMADILLO_LIBRARIES)
if (ARMADILLO_FOUND AND NOT TARGET Armadillo:Armadillo)
add_library(Armadillo::Armadillo INTERFACE IMPORTED)
set_target_properties(Armadillo::Armadillo PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${ARMADILLO_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${ARMADILLO_LIBRARIES}")
endif()
#======================
+4
View File
@@ -0,0 +1,4 @@
@PACKAGE_INIT@
include(${CMAKE_CURRENT_LIST_DIR}/@TARGETS_EXPORT_NAME@.cmake)
check_required_components(ensmallen)
+77 -51
View File
@@ -1,63 +1,91 @@
# ensmallen CMake configuration. This project has no configurable options---it
# just installs the headers to the install location, and optionally builds the
# test program.
cmake_minimum_required(VERSION 2.8.10)
project(ensmallen C CXX)
cmake_minimum_required(VERSION 3.3.2)
project(ensmallen
LANGUAGES C CXX)
# Configurable options for CMake.
option(USE_OPENMP "If available, use OpenMP for parallelization." ON)
option(BUILD_TESTS "Build tests." ON)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/CMake")
# Ensure we have C++11 features. Since we support CMake < 3.1, this needs a
# little bit of special handling.
if ((${CMAKE_MAJOR_VERSION} LESS 3 OR
(${CMAKE_MAJOR_VERSION} EQUAL 3 AND ${CMAKE_MINOR_VERSION} LESS 1))
AND NOT FORCE_CXX11)
# Older versions of CMake do not support target_compile_features(), so we have
# to use something kind of hacky.
include(CMake/CXX11.cmake)
check_for_cxx11_compiler(HAS_CXX11)
if(NOT HAS_CXX11)
message(FATAL_ERROR "No C++11 compiler available!")
endif()
enable_cxx11()
else()
# set required standard to c++11
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
endif ()
# Set required C++ standard to C++11.
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Detect OpenMP support in a compiler. If the compiler supports OpenMP, flags
# to compile with OpenMP are returned and added for compilation.
if (USE_OPENMP)
find_package(OpenMP)
endif ()
# Extract version from sources.
set(ENSMALLEN_VERSION_FILE_NAME "${PROJECT_SOURCE_DIR}/include/ensmallen_bits/ens_version.hpp")
if (OPENMP_FOUND)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
else ()
# Disable warnings for all the unknown OpenMP pragmas.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-pragmas")
endif ()
# Set the CFLAGS and CXXFLAGS depending on the options the user specified.
if(CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wpedantic -Wunused-parameter")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wpedantic -Wunused-parameter")
if(NOT EXISTS ${ENSMALLEN_VERSION_FILE_NAME})
message(FATAL_ERROR "Can't read ${ENSMALLEN_VERSION_FILE_NAME}")
endif()
# The only dependency we need is Armadillo.
#
# We keep the minimum version in sync with mlpack, otherwise we could have
# irritating compatibility issues.
find_package(Armadillo 8.400.0 REQUIRED)
include_directories(BEFORE "${ARMADILLO_INCLUDE_DIR}")
include_directories(BEFORE "${CMAKE_SOURCE_DIR}/include/")
file(READ ${ENSMALLEN_VERSION_FILE_NAME} ENSMALLEN_VERSION_FILE_CONTENTS)
string(REGEX REPLACE ".*#define ENS_VERSION_MAJOR ([0-9]+).*" "\\1" ENSMALLEN_VERSION_MAJOR "${ENSMALLEN_VERSION_FILE_CONTENTS}")
string(REGEX REPLACE ".*#define ENS_VERSION_MINOR ([0-9]+).*" "\\1" ENSMALLEN_VERSION_MINOR "${ENSMALLEN_VERSION_FILE_CONTENTS}")
string(REGEX REPLACE ".*#define ENS_VERSION_PATCH ([0-9]+).*" "\\1" ENSMALLEN_VERSION_PATCH "${ENSMALLEN_VERSION_FILE_CONTENTS}")
# Install the headers to the correct location.
message(STATUS "Configuring ensmallen ${ENSMALLEN_VERSION_MAJOR}.${ENSMALLEN_VERSION_MINOR}.${ENSMALLEN_VERSION_PATCH}")
set(VERSION "${ENSMALLEN_VERSION_MAJOR}.${ENSMALLEN_VERSION_MINOR}.${ENSMALLEN_VERSION_PATCH}")
# Create library target.
add_library(ensmallen INTERFACE)
target_include_directories(ensmallen INTERFACE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
# Set warning flags for target.
if(MSVC)
target_compile_options(ensmallen INTERFACE $<BUILD_INTERFACE:/Wall>)
else()
target_compile_options(ensmallen INTERFACE $<BUILD_INTERFACE:-Wall -Wpedantic -Wunused-parameter>)
endif()
# Find OpenMP and link it.
if(USE_OPENMP)
if(NOT TARGET OpenMP::OpenMP_CXX)
find_package(Threads REQUIRED)
add_library(OpenMP::OpenMP_CXX IMPORTED INTERFACE)
set_property(TARGET OpenMP::OpenMP_CXX
PROPERTY INTERFACE_COMPILE_OPTIONS ${OpenMP_CXX_FLAGS})
# Only works if the same flag is passed to the linker; use CMake 3.9+ otherwise (Intel, AppleClang).
set_property(TARGET OpenMP::OpenMP_CXX
PROPERTY INTERFACE_LINK_LIBRARIES ${OpenMP_CXX_FLAGS} Threads::Threads)
endif()
target_link_libraries(ensmallen INTERFACE OpenMP::OpenMP_CXX)
endif()
# Find Armadillo and link it.
find_package(Armadillo 9.800.0 REQUIRED)
target_link_libraries(ensmallen INTERFACE Armadillo::Armadillo)
# Set helper variables for creating the version, config and target files.
include(CMakePackageConfigHelpers)
set(ENSMALLEN_CMAKE_DIR "lib/cmake/ensmallen" CACHE STRING
"Installation directory for cmake files, relative to ${CMAKE_INSTALL_PREFIX}.")
set(VERSION_CONFIG "${PROJECT_BINARY_DIR}/ensmallen-config-version.cmake")
set(PROJECT_CONFIG "${PROJECT_BINARY_DIR}/ensmallen-config.cmake")
set(TARGETS_EXPORT_NAME ensmallen-targets)
# Generate the version, config and target files into the build directory.
write_basic_package_version_file(${VERSION_CONFIG}
VERSION ${VERSION}
COMPATIBILITY AnyNewerVersion)
configure_package_config_file(${PROJECT_SOURCE_DIR}/CMake/ensmallen-config.cmake.in
${PROJECT_CONFIG}
INSTALL_DESTINATION ${ENSMALLEN_CMAKE_DIR})
export(TARGETS ensmallen NAMESPACE ensmallen::
FILE ${PROJECT_BINARY_DIR}/${TARGETS_EXPORT_NAME}.cmake)
# Install version, config and target files.
install(FILES ${PROJECT_CONFIG} ${VERSION_CONFIG}
DESTINATION ${ENSMALLEN_CMAKE_DIR})
install(EXPORT ${TARGETS_EXPORT_NAME} DESTINATION ${ENSMALLEN_CMAKE_DIR}
NAMESPACE ensmallen::)
# Export the targets and install the header files.
install(TARGETS ensmallen EXPORT ${TARGETS_EXPORT_NAME} DESTINATION lib)
install(DIRECTORY "${CMAKE_SOURCE_DIR}/include/ensmallen_bits"
DESTINATION "${CMAKE_INSTALL_PREFIX}/include"
PATTERN "*~" EXCLUDE
@@ -65,8 +93,6 @@ install(DIRECTORY "${CMAKE_SOURCE_DIR}/include/ensmallen_bits"
install(FILES ${CMAKE_SOURCE_DIR}/include/ensmallen.hpp
DESTINATION "${CMAKE_INSTALL_PREFIX}/include")
# Enable testing and build tests.
enable_testing()
if (BUILD_TESTS)
add_subdirectory(tests)
endif()
add_subdirectory(tests)
+111 -2
View File
@@ -22,7 +22,7 @@ merge, to ensure that:
Please do make sure that if you contribute a new optimizer or other new
functionality, that you've added some tests in the `tests/` directory. And if
you are fixing a bug, it's always nice to include a test case if possible to so
you are fixing a bug, it's always nice to include a test case if possible so
that the bug won't happen again.
## Build/test process
@@ -42,7 +42,116 @@ you have written a test like this, make sure it does not fail often by
uncommenting the code that sets a random seed in `tests/main.cpp` and running
your test many times.
Information on how to build and run the tests is in the main README.md file.
### Install Dependencies
<details open>
<summary>Linux</summary>
Use your distributions' package manager to install the required dependencies. For Ubuntu/Debian, the commands are as shown below.
```bash
$ sudo apt-get update
$ sudo apt-get install libarmadillo-dev cmake
```
To install the dependencies on Fedora/RHEL/CentOS, you can use:
```bash
$ yum install armadillo-devel cmake
```
You can install **ensmallen** on Arch from AUR using:
```bash
$ git clone https://aur.archlinux.org/ensmallen.git
$ cd ensmallen
$ makepkg -si
```
</details>
<details open>
<summary>macOS</summary>
You can install **ensmallen** directly with [Homebrew](https://brew.sh).
```bash
$ brew install ensmallen
```
If you want to build **ensmallen** tests from source, use a package manager like [Homebrew](https://brew.sh) to get the necessary dependencies.
```bash
$ brew install armadillo cmake
```
</details>
<details open>
<summary>Windows</summary>
You can install **ensmallen** directly by using [vcpkg](https://github.com/microsoft/vcpkg).
```
vcpkg install ensmallen:x64-windows
```
</details>
### Build and Test
This section describes how to build the **ensmallen** tests from source. **ensmallen** uses CMake as its build system and [Catch2](https://github.com/catchorg/Catch2) as the unit test framework.
First, clone the source code from Github and change into the cloned directory. Alternatively, you can download the latest release from the [website](http://ensmallen.org) and extract it.
```bash
$ git clone https://github.com/mlpack/ensmallen
$ cd ensmallen
# - or -
$ wget http://ensmallen.org/files/ensmallen-2.18.2.tar.gz
$ tar -xvzpf ensmallen-2.18.2.tar.gz
$ cd ensmallen-latest
```
Next, make a build directory and change into that directory.
```bash
$ mkdir build
$ cd build
```
Then, run the cmake command followed by the make command in the build directory. If the cmake command fails, you probably have missing dependencies.
```bash
$ cmake ..
# or with -w flag to inhibit all warning messages
# $ cmake -DCMAKE_CXX_FLAGS="-w" -DCMAKE_C_FLAGS="-w" .. #
$ make
# or alternately make with the -jN flag to run parallel jobs
# $ make -j4
```
Now, you can either run all of the tests or an individual test case with:
```bash
$ ./ensmallen_tests
$ ./ensmallen_tests <test name>
```
You can list all tests with:
```bash
$ ./ensmallen-tests -l
ensmallen version: 2.10.5 (Fried Chicken)
armadillo version: 9.800.3 (Horizon Scraper)
All available test cases:
SimpleAdaDeltaTestFunction
[AdaDeltaTest]
...
262 test cases
```
## Release process
+3 -1
View File
@@ -37,7 +37,9 @@ Copyright:
Copyright 2018, Dan Timson
Copyright 2019, Rahul Ganesh Prabhu
Copyright 2019, Roberto Hueso <robertohueso96@gmail.com>
Copyright 2019, Sayan Goswami <sayan.goswami.106@gmail.com>
Copyright 2020, Joe Dinius <josephwdinius@gmail.com>
License: BSD-3-clause
All rights reserved.
.
+247 -4
View File
@@ -1,12 +1,255 @@
### ensmallen ?.??.?
###### ????-??-??
* SGD callback test 32-bit safety (big number).
### ensmallen 2.18.2: "Fairmount Bagel"
###### 2022-02-13
* Update Catch2 to 2.13.8
([#336](https://github.com/mlpack/ensmallen/pull/336)).
* Fix epoch timing output
([#337](https://github.com/mlpack/ensmallen/pull/337)).
### ensmallen 2.18.1: "Fairmount Bagel"
###### 2021-11-19
* Accelerate SGD test time
([#330](https://github.com/mlpack/ensmallen/pull/300)).
* Fix potential infinite loop in CMAES
([#331](https://github.com/mlpack/ensmallen/pull/331)).
* Fix SCD partial gradient test
([#332](https://github.com/mlpack/ensmallen/pull/332)).
### ensmallen 2.18.0: "Fairmount Bagel"
###### 2021-10-20
* Add gradient value clipping and gradient norm scaling callback
([#315](https://github.com/mlpack/ensmallen/pull/315)).
* Remove superfluous CMake option to build the tests
([#313](https://github.com/mlpack/ensmallen/pull/313)).
* Bump minimum Armadillo version to 9.800
([#318](https://github.com/mlpack/ensmallen/pull/318)).
* Update Catch2 to 2.13.7
([#322](https://github.com/mlpack/ensmallen/pull/322)).
* Remove redundant template argument for C++20 compatibility
([#324](https://github.com/mlpack/ensmallen/pull/324)).
* Fix MOEAD test stability
([#327](https://github.com/mlpack/ensmallen/pull/327)).
### ensmallen 2.17.0: "Pachis Din Me Pesa Double"
###### 2021-07-06
* CheckArbitraryFunctionTypeAPI extended for MOO support
([#283](https://github.com/mlpack/ensmallen/pull/283)).
* Refactor NSGA2
([#263](https://github.com/mlpack/ensmallen/pull/263),
[#304](https://github.com/mlpack/ensmallen/pull/304)).
* Add Indicators for Multiobjective optimizers
([#285](https://github.com/mlpack/ensmallen/pull/285)).
* Make Callback flexible for MultiObjective Optimizers
([#289](https://github.com/mlpack/ensmallen/pull/289)).
* Add ZDT Test Suite
([#273](https://github.com/mlpack/ensmallen/pull/273)).
* Add MOEA-D/DE Optimizer
([#269](https://github.com/mlpack/ensmallen/pull/269)).
* Introduce Policy Methods for MOEA/D-DE
([#293](https://github.com/mlpack/ensmallen/pull/293)).
* Add Das-Dennis weight initialization method
([#295](https://github.com/mlpack/ensmallen/pull/295)).
* Add Dirichlet Weight Initialization
([#296](https://github.com/mlpack/ensmallen/pull/296)).
* Improved installation and compilation instructions
([#300](https://github.com/mlpack/ensmallen/pull/300)).
* Disable building the tests by default for faster installation
([#303](https://github.com/mlpack/ensmallen/pull/303)).
* Modify matrix initialisation to take into account
default element zeroing in Armadillo 10.5
([#305](https://github.com/mlpack/ensmallen/pull/305)).
### ensmallen 2.16.2: "Severely Dented Can Of Polyurethane"
###### 2021-03-24
* Fix CNE test trials
([#267](https://github.com/mlpack/ensmallen/pull/267)).
* Update Catch2 to 2.13.4
([#268](https://github.com/mlpack/ensmallen/pull/268)).
* Fix typos in documentation
([#270](https://github.com/mlpack/ensmallen/pull/270),
[#271](https://github.com/mlpack/ensmallen/pull/271)).
* Add clarifying comments in problems/ implementations
([#276](https://github.com/mlpack/ensmallen/pull/276)).
### ensmallen 2.16.1: "Severely Dented Can Of Polyurethane"
###### 2021-03-02
* Fix test compilation issue when `ENS_USE_OPENMP` is set
([#255](https://github.com/mlpack/ensmallen/pull/255)).
* Fix CNE initial population generation to use normal distribution
([#258](https://github.com/mlpack/ensmallen/pull/258)).
* Fix compilation warnings
([#259](https://github.com/mlpack/ensmallen/pull/259)).
* Remove `AdamSchafferFunctionN2Test` test from Adam test suite to prevent
spurious issue on some aarch64 ([#265](https://github.com/mlpack/ensmallen/pull/259)).
### ensmallen 2.16.0: "Severely Dented Can Of Polyurethane"
###### 2021-02-11
* Expand README with example installation and add simple example program
showing usage of the L-BFGS optimizer
([#248](https://github.com/mlpack/ensmallen/pull/248)).
* Refactor tests to increase stability and reduce random errors
([#249](https://github.com/mlpack/ensmallen/pull/249)).
### ensmallen 2.15.1: "Why Can't I Manage To Grow Any Plants?"
###### 2020-11-05
* Fix include order to ensure traits is loaded before reports
([#239](https://github.com/mlpack/ensmallen/pull/239)).
### ensmallen 2.15.0: "Why Can't I Manage To Grow Any Plants?"
###### 2020-11-01
* Make a few tests more robust
([#228](https://github.com/mlpack/ensmallen/pull/228)).
* Add release date to version information. ([#226](https://github.com/mlpack/ensmallen/pull/226))
* Fix typo in release script
([#236](https://github.com/mlpack/ensmallen/pull/236)).
### ensmallen 2.14.2: "No Direction Home"
###### 2020-08-31
* Fix implementation of fonesca fleming problem function f1 and f2
type usage and negative signs. ([#223](https://github.com/mlpack/ensmallen/pull/223))
### ensmallen 2.14.1: "No Direction Home"
###### 2020-08-19
* Fix release script (remove hardcoded information, trim leading whitespaces
introduced by `wc -l` in MacOS)
([#216](https://github.com/mlpack/ensmallen/pull/216),
[#220](https://github.com/mlpack/ensmallen/pull/220)).
* Adjust tolerance for AugLagrangian convergence based on element type
([#217](https://github.com/mlpack/ensmallen/pull/217)).
### ensmallen 2.14.0: "No Direction Home"
###### 2020-08-10
* Add NSGA2 optimizer for multi-objective functions
([#149](https://github.com/mlpack/ensmallen/pull/149)).
* Update automatic website update release script
([#207](https://github.com/mlpack/ensmallen/pull/207)).
* Clarify and fix documentation for constrained optimizers
([#201](https://github.com/mlpack/ensmallen/pull/201)).
* Fix L-BFGS convergence when starting from a minimum
([#201](https://github.com/mlpack/ensmallen/pull/201)).
* Add optimizer summary report callback
([#213](https://github.com/mlpack/ensmallen/pull/213)).
### ensmallen 2.13.0: "Automatically Automated Automation"
###### 2020-07-15
* Fix CMake package export
([#198](https://github.com/mlpack/ensmallen/pull/198)).
* Allow early stop callback to accept a lambda function
([#165](https://github.com/mlpack/ensmallen/pull/165)).
### ensmallen 2.12.1: "Stir Crazy"
###### 2020-04-20
* Fix total number of epochs and time estimation for ProgressBar callback
([#181](https://github.com/mlpack/ensmallen/pull/181)).
* Handle SpSubview_col and SpSubview_row in Armadillo 9.870
([#194](https://github.com/mlpack/ensmallen/pull/194)).
* Minor documentation fixes
([#197](https://github.com/mlpack/ensmallen/pull/197)).
### ensmallen 2.12.0: "Stir Crazy"
###### 2020-03-28
* Correction in the formulation of sigma in CMA-ES
([#183](https://github.com/mlpack/ensmallen/pull/183)).
* Remove deprecated methods from PrimalDualSolver implementation
([#185](https://github.com/mlpack/ensmallen/pull/185).
* Update logo ([#186](https://github.com/mlpack/ensmallen/pull/186)).
### ensmallen 2.11.5: "The Poster Session Is Full"
###### 2020-03-11
* Change "mathematical optimization" term to "numerical optimization" in the
documentation ([#177](https://github.com/mlpack/ensmallen/pull/177)).
### ensmallen 2.11.4: "The Poster Session Is Full"
###### 2020-03-03
* Require new HISTORY.md entry for each PR.
([#171](https://github.com/mlpack/ensmallen/pull/171),
[#172](https://github.com/mlpack/ensmallen/pull/172),
[#175](https://github.com/mlpack/ensmallen/pull/175)).
* Update/fix example documentation
([#174](https://github.com/mlpack/ensmallen/pull/174)).
### ensmallen 2.11.3: "The Poster Session Is Full"
###### 2020-02-19
* Prevent spurious compiler warnings
([#161](https://github.com/mlpack/ensmallen/pull/161)).
* Fix minor memory leaks
([#167](https://github.com/mlpack/ensmallen/pull/167)).
* Revamp CMake configuration
([#152](https://github.com/mlpack/ensmallen/pull/152)).
### ensmallen 2.11.2: "The Poster Session Is Full"
###### 2020-01-16
* Allow callback instantiation for SGD based optimizer
([#138](https://github.com/mlpack/ensmallen/pull/155)).
* Minor test stability fixes on i386
([#156](https://github.com/mlpack/ensmallen/pull/156)).
* Fix Lookahead MaxIterations() check.
([#159](https://github.com/mlpack/ensmallen/pull/159)).
### ensmallen 2.11.1: "The Poster Session Is Full"
###### 2019-12-28
* Fix Lookahead Synchronization period type
([#153](https://github.com/mlpack/ensmallen/pull/153)).
### ensmallen 2.11.0: "The Poster Session Is Full"
###### 2019-12-24
* Add Lookahead
([#138](https://github.com/mlpack/ensmallen/pull/138)).
* Add AdaBound and AMSBound
([#137](https://github.com/mlpack/ensmallen/pull/137)).
### ensmallen 2.10.5: "Fried Chicken"
###### 2019-12-13
* SGD callback test 32-bit safety (big number)
([#143](https://github.com/mlpack/ensmallen/pull/143)).
* Use "arbitrary" and "separable" terms in static function type checks
([#145](https://github.com/mlpack/ensmallen/pull/145)).
* Remove 'using namespace std' from problems/ files.
* Remove 'using namespace std' from `problems/` files
([#147](https://github.com/mlpack/ensmallen/pull/147)).
### ensmallen 2.10.4: "Fried Chicken"
+101 -15
View File
@@ -1,14 +1,17 @@
**ensmallen** is a C++ header-only library for mathematical optimization.
<h2 align="center">
<a href="http://ensmallen.org/"><img src="http://ensmallen.org/img/ensmallen_text.svg" style="background-color:rgba(0,0,0,0);" height=230 alt="ensmallen: a C++ header-only library for numerical optimization"></a>
</h2>
**ensmallen** is a high-quality C++ library for non-linear numerical optimization.
ensmallen provides many types of optimizers that can be used
for virtually any numerical optimization task.
This includes gradient descent techniques, gradient-free optimizers,
and constrained optimization.
ensmallen also allows optional callbacks to customize the optimization process.
Documentation and downloads: http://ensmallen.org
ensmallen provides a simple set of abstractions for writing an objective
function to optimize. It also provides a large set of standard and cutting-edge
optimizers that can be used for virtually any mathematical optimization task.
These include full-batch gradient descent techniques, small-batch techniques,
gradient-free optimizers, and constrained optimization.
### Requirements
* C++ compiler with C++11 support
@@ -16,12 +19,82 @@ gradient-free optimizers, and constrained optimization.
* OpenBLAS or Intel MKL or LAPACK (see Armadillo site for details)
### Installation
ensmallen can be installed in several ways: either manually or via cmake,
with or without root access.
The cmake based installation will check the requirements
and optionally build the tests. If cmake 3.3 (or a later version)
is not already available on your system, it can be obtained
from [cmake.org](https://cmake.org). If you are using an older
system such as RHEL 7 or CentOS 7, an updated version of cmake
is also available via the EPEL repository (see the `cmake3` package).
Example cmake based installation with root access:
```
mkdir build
cd build
cmake ..
sudo make install
```
Example cmake based installation without root access,
installing into `/home/blah/` (adapt as required):
```
mkdir build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX:PATH=/home/blah/
make install
```
The above will create a directory named `/home/blah/include/`
and place all ensmallen headers there.
To optionally build and run the tests
(after running cmake as above),
use the following additional commands:
```
make ensmallen_tests
./ensmallen_tests --durations yes
```
Manual installation involves simply copying the `include/ensmallen.hpp` header
***and*** the associated `include/ensmallen_bits` directory to a location
such as `/usr/include/` which is searched by your C++ compiler.
If you can't use `sudo` or don't have write access to `/usr/include/`,
use a directory within your own home directory (eg. `/home/blah/include/`).
### Example Compilation
If you have installed ensmallen in a standard location such as `/usr/include/`:
g++ prog.cpp -o prog -O2 -larmadillo
If you have installed ensmallen in a non-standard location,
such as `/home/blah/include/`, you will need to make sure
that your C++ compiler searches `/home/blah/include/`
by explicitly specifying the directory as an argument/option.
For example, using the `-I` switch in gcc and clang:
g++ prog.cpp -o prog -O2 -I /home/blah/include/ -larmadillo
### Example Optimization
See [`example.cpp`](example.cpp) for example usage of the L-BFGS optimizer
in a linear regression setting.
### License
Unless stated otherwise, the source code for **ensmallen**
is licensed under the 3-clause BSD license (the "License").
A copy of the License is included in the "LICENSE.txt" file.
You may also obtain a copy of the License at
Unless stated otherwise, the source code for **ensmallen** is licensed under the
3-clause BSD license (the "License"). A copy of the License is included in the
"LICENSE.txt" file. You may also obtain a copy of the License at
http://opensource.org/licenses/BSD-3-Clause
@@ -31,10 +104,22 @@ Please cite the following paper if you use ensmallen in your research and/or
software. Citations are useful for the continued development and maintenance of
the library.
* S. Bhardwaj, R. Curtin, M. Edel, Y. Mentekidis, C. Sanderson.
[ensmallen: a flexible C++ library for efficient function optimization](http://www.ensmallen.org/files/ensmallen_2018.pdf).
Workshop on Systems for ML and Open Source Software at NIPS 2018.
* Ryan R. Curtin, Marcus Edel, Rahul Ganesh Prabhu, Suryoday Basak, Zhihao Lou, Conrad Sanderson.
[The ensmallen library for flexible numerical optimization](https://jmlr.org/papers/volume22/20-416/20-416.pdf).
Journal of Machine Learning Research, Vol. 22, No. 166, 2021.
```
@article{ensmallen_JMLR_2021,
author = {Ryan R. Curtin and Marcus Edel and Rahul Ganesh Prabhu and Suryoday Basak and Zhihao Lou and Conrad Sanderson},
title = {The ensmallen library for flexible numerical optimization},
journal = {Journal of Machine Learning Research},
year = {2021},
volume = {22},
number = {166},
pages = {1--6},
url = {http://jmlr.org/papers/v22/20-416.html}
}
```
### Developers and Contributors
@@ -64,3 +149,4 @@ the library.
* Dan Timson
* N Rajiv Vaidyanathan
* Roberto Hueso
* Sayan Goswami
+230 -4
View File
@@ -23,7 +23,7 @@ MomentumSGD optimizer(0.01, 32, 100000, 1e-5, true, MomentumUpdate(0.5));
optimizer.Optimize(f, coordinates, PrintLoss());
```
</details>
</details>
Passing multiple callbacks is just the same as passing a single callback:
@@ -42,7 +42,7 @@ MomentumSGD optimizer(0.01, 32, 100000, 1e-5, true, MomentumUpdate(0.5));
optimizer.Optimize(f, coordinates, PrintLoss(), EarlyStopAtMinLoss());
```
</details>
</details>
It is also possible to pass a callback instantiation that allows accessing of
internal callback parameters at a later state:
@@ -84,12 +84,20 @@ has been made.
* `EarlyStopAtMinLoss()`
* `EarlyStopAtMinLoss(`_`patience`_`)`
* `EarlyStopAtMinLoss(`_`func`_`)`
* `EarlyStopAtMinLoss(`_`func`_`,`_`patience`_`)`
#### Attributes
| **type** | **name** | **description** | **default** |
|----------|----------|-----------------|-------------|
| `size_t` | **`patience`** | The number of epochs to wait after the minimum loss has been reached. | `10` |
| `std::function<double(const arma::mat&)>` | **`func`** | A callback to return immediate loss evaluated by the function. | |
Note that for the `func` argument above, if a
[different matrix type](#alternate-matrix-types) is desired, instead of using
the class `EarlyStopAtMinLoss`, the class `EarlyStopAtMinLossType<MatType>`
should be used.
#### Examples:
@@ -104,9 +112,121 @@ RosenbrockFunction f;
arma::mat coordinates = f.GetInitialPoint();
optimizer.Optimize(f, coordinates, EarlyStopAtMinLoss());
```
Another example of using lambda in the constructor.
```c++
// Generate random training data and labels.
arma::mat trainingData(5, 100, arma::fill::randu);
arma::Row<size_t> trainingLabels =
arma::randi<arma::Row<size_t>>(100, arma::distr_param(0, 1));
// Generate a validation set.
arma::mat validationData(5, 100, arma::fill::randu);
arma::Row<size_t> validationLabels =
arma::randi<arma::Row<size_t>>(100, arma::distr_param(0, 1));
// Create a LogisticRegressionFunction for both the training and validation data.
LogisticRegressionFunction lrfTrain(trainingData, trainingLabels);
LogisticRegressionFunction lrfValidation(validationData, validationLabels);
// Create a callback that will terminate when the validation loss starts to
// increase.
EarlyStopAtMinLoss cb(
[&](const arma::mat& coordinates)
{
// You could also, e.g., print the validation loss here to watch it converge.
return lrfValidation.Evaluate(coordinates);
});
arma::mat coordinates = lrfTrain.GetInitialPoint();
SMORMS3 smorms3;
smorms3.Optimize(lrfTrain, coordinates, cb);
```
</details>
### GradClipByNorm
One difficulty with optimization is that large parameter gradients can lead an
optimizer to update the parameters strongly into a region where the loss
function is much greater, effectively undoing much of the work done to get to
the current solution. Such large updates during the optimization can cause a
numerical overflow or underflow, often referred to as "exploding gradients". The
exploding gradient problem can be caused by: Choosing the wrong learning rate
which leads to huge updates in the gradients. Failing to scale a data set
leading to very large differences between data points. Applying a loss function
that computes very large error values.
A common answer to the exploding gradients problem is to change the derivative
of the error before applying the update step. One option is to clip the norm
`||g||` of the gradient `g` before a parameter update. So given the gradient,
and a maximum norm value, the callback normalizes the gradient so that its
L2-norm is less than or equal to the given maximum norm value.
#### Constructors
* `GradClipByNorm(`_`maxNorm`_`)`
#### Attributes
| **type** | **name** | **description** | **default** |
|----------|----------|-----------------|-------------|
| `double` | **`maxNorm`** | The maximum clipping value. | |
#### Examples:
<details open>
<summary>Click to collapse/expand example code.
</summary>
```c++
AdaDelta optimizer(1.0, 1, 0.99, 1e-8, 1000, 1e-9, true);
RosenbrockFunction f;
arma::mat coordinates = f.GetInitialPoint();
optimizer.Optimize(f, coordinates, GradClipByNorm(0.3));
```
### GradClipByValue
One difficulty with optimization is that large parameter gradients can lead an
optimizer to update the parameters strongly into a region where the loss
function is much greater, effectively undoing much of the work done to get to
the current solution. Such large updates during the optimization can cause a
numerical overflow or underflow, often referred to as "exploding gradients". The
exploding gradient problem can be caused by: Choosing the wrong learning rate
which leads to huge updates in the gradients. Failing to scale a data set
leading to very large differences between data points. Applying a loss function
that computes very large error values.
A common answer to the exploding gradients problem is to change the derivative
of the error before applying the update step. One option is to clip the
parameter gradient element-wise before a parameter update.
#### Constructors
* `GradClipByValue(`_`min, max`_`)`
#### Attributes
| **type** | **name** | **description** | **default** |
|----------|----------|-----------------|-------------|
| `double` | **`min`** | The minimum value to clip to. | |
| `double` | **`max`** | The maximum value to clip to. | |
#### Examples:
<details open>
<summary>Click to collapse/expand example code.
</summary>
```c++
AdaDelta optimizer(1.0, 1, 0.99, 1e-8, 1000, 1e-9, true);
RosenbrockFunction f;
arma::mat coordinates = f.GetInitialPoint();
optimizer.Optimize(f, coordinates, GradClipByValue(0, 1.3));
```
### PrintLoss
Callback that prints loss to stdout or a specified output stream.
@@ -171,6 +291,95 @@ optimizer.Optimize(f, coordinates, ProgressBar());
</details>
### Report
Callback that prints a optimizer report to stdout or a specified output stream.
#### Constructors
* `Report()`
* `Report(`_`iterationsPercentage`_`)`
* `Report(`_`iterationsPercentage, output`_`)`
* `Report(`_`iterationsPercentage, output, outputMatrixSize`_`)`
#### Attributes
| **type** | **name** | **description** | **default** |
|----------|----------|-----------------|-------------|
| `double` | **`iterationsPercentage`** | The number of iterations to report in percent, between [0, 1]. | `0.1` |
| `std::ostream` | **`output`** | Ostream which receives output from this object. | `stdout` |
| `size_t` | **`outputMatrixSize`** | The number of values to output for the function coordinates. | `4` |
#### Examples:
<details open>
<summary>Click to collapse/expand example code.
</summary>
```c++
AdaDelta optimizer(1.0, 1, 0.99, 1e-8, 1000, 1e-9, true);
RosenbrockFunction f;
arma::mat coordinates = f.GetInitialPoint();
optimizer.Optimize(f, coordinates, Report(0.1));
```
<details open>
<summary>Click to collapse/expand example output.
</summary>
```
Optimization Report
--------------------------------------------------------------------------------
Initial Coordinates:
-1.2000 1.0000
Final coordinates:
-1.0490 1.1070
iter loss loss change |gradient| step size total time
0 24.2 0 233 1 4.27e-05
100 8.6 15.6 104 1 0.000215
200 5.26 3.35 48.7 1 0.000373
300 4.49 0.767 23.4 1 0.000533
400 4.31 0.181 11.3 1 0.000689
500 4.27 0.0431 5.4 1 0.000846
600 4.26 0.012 2.86 1 0.00101
700 4.25 0.00734 2.09 1 0.00117
800 4.24 0.00971 1.95 1 0.00132
900 4.22 0.0146 1.91 1 0.00148
--------------------------------------------------------------------------------
Version:
ensmallen: 2.13.0 (Automatically Automated Automation)
armadillo: 9.900.1 (Nocturnal Misbehaviour)
Function:
Number of functions: 1
Coordinates rows: 2
Coordinates columns: 1
Loss:
Initial 24.2
Final 4.2
Change 20
Optimizer:
Maximum iterations: 1000
Reached maximum iterations: true
Batchsize: 1
Iterations: 1000
Number of epochs: 1001
Initial step size: 1
Final step size: 1
Coordinates max. norm: 233
Evaluate calls: 1000
Gradient calls: 1000
Time (in seconds): 0.00163
```
### StoreBestCoordinates
Callback that stores the model parameter after every epoch if the objective
@@ -205,14 +414,14 @@ StoreBestCoordinates<arma::mat> cb;
optimizer.Optimize(f, coordinates, cb);
std::cout << "The optimized model found by AdaDelta has the "
<< "parameters " << cb.BestCoordinatest();
<< "parameters " << cb.BestCoordinates();
```
</details>
## Callback States
Callbacks are called at different states during the optimization process:
Callbacks are called at several states during the optimization process:
* At the beginning and end of the optimization process.
* After any call to `Evaluate()` and `EvaluateConstraint`.
@@ -346,6 +555,23 @@ an estimate depending on `exactObjective` value.
| `size_t` | **`epoch`** | The index of the current epoch. |
| `double` | **`objective`** | Objective value of the current point. |
### GenerationalStepTaken
Called after the evolution of a single generation. Intended specifically for
MultiObjective Optimizers.
* `GenerationalStepTaken(`_`optimizer, function, coordinates, objectives, frontIndices`_`)`
#### Attributes
| **type** | **name** | **description** |
|----------|----------|-----------------|
| `OptimizerType` | **`optimizer`** | The optimizer used to update the function. |
| `FunctionType` | **`function`** | The function to be optimized. |
| `MatType` | **`coordinates`** | The current function parameter. |
| `ObjectivesVecType` | **`objectives`** | The set of calculated objectives so far. |
| `IndicesType` | **`frontIndices`** | The indices of the members belonging to Pareto Front. |
## Custom Callbacks
### Learning rate scheduling
+74 -18
View File
@@ -30,6 +30,7 @@ The following optimizers can be used to optimize an arbitrary function:
- [Simulated Annealing](#simulated-annealing-sa)
- [CNE](#cne)
- [DE](#de)
- [PSO](#pso)
- [SPSA](#simultaneous-perturbation-stochastic-approximation-spsa)
Each of these optimizers has an `Optimize()` function that is called as
@@ -551,16 +552,21 @@ and f'(x) compute some of the same intermediate quantities.
Each of the implemented methods is allowed to have additional cv-modifiers
(`static`, `const`, etc.).
The following optimizers can be used with differentiable functions:
The following optimizers can be used with differentiable separable functions:
- [AdaBound](#adabound)
- [AdaDelta](#adadelta)
- [AdaGrad](#adagrad)
- [Adam](#adam)
- [AdaMax](#adamax)
- [AMSBound](#amsbound)
- [AMSGrad](#amsgrad)
- [Big Batch SGD](#big-batch-sgd)
- [Eve](#eve)
- [FTML](#ftml-follow-the-moving-leader)
- [IQN](#iqn)
- [Katyusha](#katyusha)
- [Lookahead](#lookahead)
- [Momentum SGD](#momentum-sgd)
- [Nadam](#nadam)
- [NadaMax](#nadamax)
@@ -574,8 +580,10 @@ The following optimizers can be used with differentiable functions:
- [Stochastic Gradient Descent with Restarts (SGDR)](#stochastic-gradient-descent-with-restarts-sgdr)
- [Snapshot SGDR](#snapshot-stochastic-gradient-descent-with-restarts)
- [SMORMS3](#smorms3)
- [SVRG](#standard-stochastic-variance-reduced-gradient-svrg)
- [SPALeRA](#spalera-stochastic-gradient-descent-spalerasgd)
- [SWATS](#swats)
- [SVRG](#standard-stochastic-variance-reduced-gradient-svrg)
- [WNGrad](#wngrad)
The example program below demonstrates the implementation and use of an
arbitrary separable function. The function used is the linear regression
@@ -833,23 +841,73 @@ int main()
</details>
## Multi-objective functions
A multi-objective optimizer does not return just one set of coordinates at the
minimum of all objective functions, but instead finds a *front* or *frontier* of
possible coordinates that are Pareto-optimal (that is, no individual objective
function's value can be reduced without increasing at least one other
objective function).
In order to optimize a multi-objective function with ensmallen, a `std::tuple<>`
containing multiple `ArbitraryFunctionType`s ([see here](#arbitrary-functions))
should be passed to a multi-objective optimizer's `Optimize()` function.
An example below simultaneously optimizes the generalized Rosenbrock function
in 6 dimensions and the Wood function using [NSGA2](#nsga2).
<details open>
<summary>Click to collapse/expand example code.
</summary>
```c++
GeneralizedRosenbrockFunction rf(6);
WoodFunction wf;
std::tuple<GeneralizedRosenbrockFunction, WoodFunction> objectives(rf, wf);
// Create an initial point (a random point in 6 dimensions).
arma::mat coordinates(6, 1, arma::fill::randu);
// `coordinates` will be set to the coordinates on the best front that minimize the
// sum of objective functions, and `bestFrontSum` will be the sum of all objectives
// at that coordinate set.
NSGA2 nsga;
double bestFrontSum = nsga.Optimize(objectives, coordinates);
// Set `bestFront` to contain all of the coordinates on the best front.
arma::cube bestFront = optimizer.ParetoFront();
}
```
</details>
*Note*: all multi-objective function optimizers have both the function `Optimize()` to find the
best front, and also the function `ParetoFront()` to return all sets of solutions that are on the
front.
The following optimizers can be used with multi-objective functions:
- [NSGA2](#nsga2)
- [MOEA/D-DE](#moead)
## Constrained functions
A constrained function is an objective function `f(x)` that is also subject to
some constraints on `x`. (For instance, perhaps a constraint could be that `x`
is a positive semidefinite matrix.) ensmallen is able to handle differentiable
objective functions of this type---so, `f'(x)` must also be computable. Given
some set of constraints c_0(x), ... c_M(x), we can re-express our constrained
some set of constraints `c_0(x)`, ..., `c_M(x)`, we can re-express our constrained
objective function as
```
f_C(x) = f(x) + c_0(x) + ... + c_M(x)
```
where the constraint `c_i(x)` is `DBL_MAX` if it is not satisfied, and
otherwise takes some real value. For a "hard constraint", we can simply take
`c_i(x) = 0` when it is satisfied. But allowing `c_i(x)` to return anything
allows us to handle "soft" constraints also.
where the (soft) constraint `c_i(x)` is a positive value if it is not satisfied, and
`0` if it is satisfied. The soft constraint `c_i(x)` should take some value
representing how far from a feasible solution `x` is. It should be
differentiable, since ensmallen's constrained optimizers will use the gradient
of the constraint to find a feasible solution.
In order to optimize a constrained function with ensmallen, a class
implementing the API below is required.
@@ -872,16 +930,14 @@ class ConstrainedFunctionType
size_t NumConstraints();
// Evaluate constraint i at the parameters x. If the constraint is
// unsatisfied, DBL_MAX should be returned. If the constraint is satisfied,
// any real value can be returned. The optimizer will add this value to its
// overall objective that it is trying to minimize. (So, a hard constraint
// can just return 0 if it's satisfied.)
// unsatisfied, a value greater than 0 should be returned. If the constraint
// is satisfied, 0 should be returned. The optimizer will add this value to
// its overall objective that it is trying to minimize.
double EvaluateConstraint(const size_t i, const arma::mat& x);
// Evaluate the gradient of constraint i at the parameters x, storing the
// result in the given matrix g. If this is a hard constraint you can set
// the gradient to 0. If the constraint is not satisfied, it could be
// helpful to set the gradient in such a way that the gradient points in the
// result in the given matrix g. If the constraint is not satisfied, the
// gradient should be set in such a way that the gradient points in the
// direction where the constraint would be satisfied.
void GradientConstraint(const size_t i, const arma::mat& x, arma::mat& g);
};
@@ -1028,12 +1084,12 @@ int main()
// use the PrimalDualSolver to solve it.
// ens::PrimalDualSolver could be replaced with ens::LRSDP or other ensmallen
// SDP solvers.
PrimalDualSolver<SDP<arma::sp_mat>> solver(sdp);
PrimalDualSolver solver;
arma::mat X, Z;
arma::vec ysparse, ydense;
// ysparse, ydense, and Z hold the primal and dual variables found during the
// optimization.
const double obj = solver.Optimize(X, ysparse, ydense, Z);
const double obj = solver.Optimize(sdp, X, ysparse, ydense, Z);
std::cout << "SDP optimized with objective " << obj << "." << std::endl;
}
@@ -1090,14 +1146,14 @@ class SquaredFunction
int main()
{
// The minimum is at x = [0 0 0]. Our initial point is chosen to be
// The minimum is at x = [0 0 0]. Our initial point is chosen to be
// [1.0, -1.0, 1.0].
arma::fmat x("1.0 -1.0 1.0");
// Create simulated annealing optimizer with default options.
// The ens::SA<> type can be replaced with any suitable ensmallen optimizer
// that is able to handle arbitrary functions.
ens::L_BFGS<> optimizer;
ens::L_BFGS optimizer;
SquaredFunction f; // Create function to be optimized.
optimizer.Optimize(f, x); // The optimizer will infer arma::fmat!
+361 -20
View File
@@ -1,3 +1,65 @@
## AdaBound
*An optimizer for [differentiable separable functions](#differentiable-separable-functions).*
AdaBound is a variant of Adam which employs dynamic bounds on learning rates.
#### Constructors
* `AdaBound()`
* `AdaBound(`_`stepSize, batchSize`_`)`
* `AdaBound(`_`stepSize, batchSize, finalLr, gamma, beta1, beta2, epsilon, maxIterations, tolerance, shuffle`_`)`
* `AdaBound(`_`stepSize, batchSize, finalLr, gamma, beta1, beta2, epsilon, maxIterations, tolerance, shuffle, resetPolicy, exactObjective`_`)`
Note that the `AdaBound` class is based on the `AdaBoundType<`_`UpdateRule`_`>`
class with _`UpdateRule`_` = AdaBoundUpdate`.
#### Attributes
| **type** | **name** | **description** | **default** |
|----------|----------|-----------------|-------------|
| `double` | **`stepSize`** | Step size for each iteration. | `0.001` |
| `size_t` | **`batchSize`** | Number of points to process in a single step. | `32` |
| `double` | **`finalLr`** | The final (SGD) learning rate. | `0.1` |
| `double` | **`gamma`** | The convergence speed of the bound functions. | `0.001` |
| `double` | **`beta1`** | Exponential decay rate for the first moment estimates. | `0.9` |
| `double` | **`beta2`** | Exponential decay rate for the weighted infinity norm estimates. | `0.999` |
| `double` | **`epsilon`** | Value used to initialize the mean squared gradient parameter. | `1e-8` |
| `size_t` | **`maxIterations`** | Maximum number of iterations allowed (0 means no limit). | `100000` |
| `double` | **`tolerance`** | Maximum absolute tolerance to terminate algorithm. | `1e-5` |
| `bool` | **`shuffle`** | If true, the function order is shuffled; otherwise, each function is visited in linear order. | `true` |
| `bool` | **`resetPolicy`** | If true, parameters are reset before every Optimize call; otherwise, their values are retained. | `true` |
| `bool` | **`exactObjective`** | Calculate the exact objective (Default: estimate the final objective obtained on the last pass over the data). | `false` |
The attributes of the optimizer may also be modified via the member methods
`FinalLr()`, `Gamma()`, `StepSize()`, `BatchSize()`, `Beta1()`, `Beta2()`,
`Eps()`, `MaxIterations()`, `Tolerance()`, `Shuffle()`, `ResetPolicy()`, and
`ExactObjective()`.
#### Examples
<details open>
<summary>Click to collapse/expand example code.
</summary>
```c++
SphereFunction f(2);
arma::mat coordinates = f.GetInitialPoint();
AdaBound optimizer(0.001, 2, 0.1, 1e-3, 0.9, 0.999, 1e-8, 500000, 1e-3);
optimizer.Optimize(f, coordinates);
```
</details>
#### See also:
* [SGD in Wikipedia](https://en.wikipedia.org/wiki/Stochastic_gradient_descent)
* [SGD](#standard-sgd)
* [Adaptive Gradient Methods with Dynamic Bound of Learning Rate](https://arxiv.org/abs/1902.09843)
* [Adam: A Method for Stochastic Optimization](http://arxiv.org/abs/1412.6980)
* [Differentiable separable functions](#differentiable-separable-functions)
## AdaDelta
*An optimizer for [differentiable separable functions](#differentiable-separable-functions).*
@@ -23,7 +85,7 @@ gradients.
| `double` | **`stepSize`** | Step size for each iteration. | `1.0` |
| `size_t` | **`batchSize`**| Number of points to process in one step. | `32` |
| `double` | **`rho`** | Smoothing constant. Corresponding to fraction of gradient to keep at each time step. | `0.95` |
| `double` | **`epsilon`** | Value used to initialise the mean squared gradient parameter. | `1e-6` |
| `double` | **`epsilon`** | Value used to initialize the mean squared gradient parameter. | `1e-6` |
| `size_t` | **`maxIterations`** | Maximum number of iterations allowed (0 means no limit). | `100000` |
| `double` | **`tolerance`** | Maximum absolute tolerance to terminate algorithm. | `1e-5` |
| `bool` | **`shuffle`** | If true, the function order is shuffled; otherwise, each function is visited in linear order. | `true` |
@@ -79,7 +141,7 @@ parameters.
|----------|----------|-----------------|-------------|
| `double` | **`stepSize`** | Step size for each iteration. | `0.01` |
| `size_t` | **`batchSize`** | Number of points to process in one step. | `32` |
| `double` | **`epsilon`** | Value used to initialise the mean squared gradient parameter. | `1e-8` |
| `double` | **`epsilon`** | Value used to initialize the mean squared gradient parameter. | `1e-8` |
| `size_t` | **`maxIterations`** | Maximum number of iterations allowed (0 means no limit). | `100000` |
| `double` | **`tolerance`** | Maximum absolute tolerance to terminate algorithm. | `tolerance` |
| `bool` | **`shuffle`** | If true, the function order is shuffled; otherwise, each function is visited in linear order. | `true` |
@@ -117,7 +179,7 @@ optimizer.Optimize(f, coordinates);
*An optimizer for [differentiable separable functions](#differentiable-separable-functions).*
Adam is an an algorithm for first-order gradient-based optimization of
Adam is an algorithm for first-order gradient-based optimization of
stochastic objective functions, based on adaptive estimates of lower-order
moments.
@@ -231,6 +293,68 @@ optimizer.Optimize(f, coordinates);
* [Adam: A Method for Stochastic Optimization](http://arxiv.org/abs/1412.6980) (see section 7)
* [Differentiable separable functions](#differentiable-separable-functions)
## AMSBound
*An optimizer for [differentiable separable functions](#differentiable-separable-functions).*
AMSBound is a variant of Adam which employs dynamic bounds on learning rates.
#### Constructors
* `AMSBound()`
* `AMSBound(`_`stepSize, batchSize`_`)`
* `AMSBound(`_`stepSize, batchSize, finalLr, gamma, beta1, beta2, epsilon, maxIterations, tolerance, shuffle`_`)`
* `AMSBound(`_`stepSize, batchSize, finalLr, gamma, beta1, beta2, epsilon, maxIterations, tolerance, shuffle, resetPolicy, exactObjective`_`)`
Note that the `AMSBound` class is based on the `AdaBoundType<`_`UpdateRule`_`>`
class with _`UpdateRule`_` = AdaBoundUpdate`.
#### Attributes
| **type** | **name** | **description** | **default** |
|----------|----------|-----------------|-------------|
| `double` | **`stepSize`** | Step size for each iteration. | `0.001` |
| `size_t` | **`batchSize`** | Number of points to process in a single step. | `32` |
| `double` | **`finalLr`** | The final (SGD) learning rate. | `0.1` |
| `double` | **`gamma`** | The convergence speed of the bound functions. | `0.001` |
| `double` | **`beta1`** | Exponential decay rate for the first moment estimates. | `0.9` |
| `double` | **`beta2`** | Exponential decay rate for the weighted infinity norm estimates. | `0.999` |
| `double` | **`epsilon`** | Value used to initialize the mean squared gradient parameter. | `1e-8` |
| `size_t` | **`maxIterations`** | Maximum number of iterations allowed (0 means no limit). | `100000` |
| `double` | **`tolerance`** | Maximum absolute tolerance to terminate algorithm. | `1e-5` |
| `bool` | **`shuffle`** | If true, the function order is shuffled; otherwise, each function is visited in linear order. | `true` |
| `bool` | **`resetPolicy`** | If true, parameters are reset before every Optimize call; otherwise, their values are retained. | `true` |
| `bool` | **`exactObjective`** | Calculate the exact objective (Default: estimate the final objective obtained on the last pass over the data). | `false` |
The attributes of the optimizer may also be modified via the member methods
`FinalLr()`, `Gamma()`, `StepSize()`, `BatchSize()`, `Beta1()`, `Beta2()`,
`Eps()`, `MaxIterations()`, `Tolerance()`, `Shuffle()`, `ResetPolicy()`, and
`ExactObjective()`.
#### Examples
<details open>
<summary>Click to collapse/expand example code.
</summary>
```c++
SphereFunction f(2);
arma::mat coordinates = f.GetInitialPoint();
AMSBound optimizer(0.001, 2, 0.1, 1e-3, 0.9, 0.999, 1e-8, 500000, 1e-3);
optimizer.Optimize(f, coordinates);
```
</details>
#### See also:
* [SGD in Wikipedia](https://en.wikipedia.org/wiki/Stochastic_gradient_descent)
* [SGD](#standard-sgd)
* [Adaptive Gradient Methods with Dynamic Bound of Learning Rate](https://arxiv.org/abs/1902.09843)
* [Adam: A Method for Stochastic Optimization](http://arxiv.org/abs/1412.6980)
* [Differentiable separable functions](#differentiable-separable-functions)
## AMSGrad
*An optimizer for [differentiable separable functions](#differentiable-separable-functions).*
@@ -300,19 +424,19 @@ optimizer uses [L-BFGS](#l-bfgs).
#### Constructors
* `AugLagrangian(`_`maxIterations, penaltyThresholdFactor sigmaUpdateFactor`_`)`
* `AugLagrangian(`_`maxIterations, penaltyThresholdFactor, sigmaUpdateFactor`_`)`
#### Attributes
| **type** | **name** | **description** | **default** |
|----------|----------|-----------------|-------------|
| `size_t` | **`maxIterations`** | Maximum number of iterations allowed (0 means no limit). | `1000` |
| `double` | **`penaltyThresholdFactor`** | When penalty threshold is updated, set it to this multiplied by the penalty. | `10.0` |
| `double` | **`sigmaUpdateFactor`** | When sigma is updated, multiply it by this. | `0.25` |
| `double` | **`penaltyThresholdFactor`** | When penalty threshold is updated, set it to this multiplied by the penalty. | `0.25` |
| `double` | **`sigmaUpdateFactor`** | When sigma is updated, multiply it by this. | `10.0` |
| `L_BFGS&` | **`lbfgs`** | Internal l-bfgs optimizer. | `L_BFGS()` |
The attributes of the optimizer may also be modified via the member methods
`MaxIterations()`, `PenaltyThresholdFactor()`, `SigmaUpdateFactor()` and `L_BFGS()`.
`MaxIterations()`, `PenaltyThresholdFactor()`, `SigmaUpdateFactor()` and `LBFGS()`.
<details open>
<summary>Click to collapse/expand example code.
@@ -430,11 +554,11 @@ RosenbrockFunction f;
arma::mat coordinates = f.GetInitialPoint();
// Big-Batch SGD with the adaptive stepsize policy.
BBS_BB optimizer(batchSize, 0.01, 0.1, 8000, 1e-4);
BBS_BB optimizer(10, 0.01, 0.1, 8000, 1e-4);
optimizer.Optimize(f, coordinates);
// Big-Batch SGD with backtracking line search.
BBS_Armijo optimizer2(batchSize, 0.01, 0.1, 8000, 1e-4);
BBS_Armijo optimizer2(10, 0.01, 0.1, 8000, 1e-4);
optimizer2.Optimize(f, coordinates);
```
@@ -505,11 +629,11 @@ RosenbrockFunction f;
arma::mat coordinates = f.GetInitialPoint();
// CMAES with the FullSelection policy.
CMAES<> optimizer(0, -1, 1, 32, 200, 0.1e-4);
CMAES<> optimizer(0, -1, 1, 32, 200, 1e-4);
optimizer.Optimize(f, coordinates);
// CMAES with the RandomSelection policy.
ApproxCMAES<> approxOptimizer(batchSize, 0.01, 0.1, 8000, 1e-4);
ApproxCMAES<> approxOptimizer(0, -1, 1. 32, 200, 1e-4);
approxOptimizer.Optimize(f, coordinates);
```
@@ -642,7 +766,7 @@ Eve is a stochastic gradient based optimization method with locally and globally
| `double` | **`beta2`** | Exponential decay rate for the weighted infinity norm estimates. | `0.999` |
| `double` | **`beta3`** | Exponential decay rate for relative change. | `0.999` |
| `double` | **`epsilon`** | Value used to initialize the mean squared gradient parameter. | `1e-8` |
| `double` | **`clip`** | Clipping range to avoid extreme valus. | `10` |
| `double` | **`clip`** | Clipping range to avoid extreme values. | `10` |
| `size_t` | **`max_iterations`** | Maximum number of iterations allowed (0 means no limit). | `100000` |
| `double` | **`tolerance`** | Maximum absolute tolerance to terminate algorithm. | `1e-5` |
| `bool` | **`shuffle`** | If true, the function order is shuffled; otherwise, each function is visited in linear order. | `true` |
@@ -1043,7 +1167,7 @@ proximalOptimizer.Optimize(f, coordinates);
*An optimizer for [differentiable functions](#differentiable-functions)*
L-BFGS is an optimization algorithm in the family of quasi-Newton methods that approximates the Broyden-Fletcher-Goldfarb-Shanno (BFGS) algorithm using a limited amount of computer memory.
L-BFGS is an optimization algorithm in the family of quasi-Newton methods that approximates the Broyden-Fletcher-Goldfarb-Shanno (BFGS) algorithm using a limited amount of computer memory.
#### Constructors
@@ -1094,6 +1218,66 @@ optimizer.Optimize(f, coordinates);
* [Limited-memory BFGS in Wikipedia](https://en.wikipedia.org/wiki/Limited-memory_BFGS)
* [Differentiable functions](#differentiable-functions)
## Lookahead
*An optimizer for [differentiable separable functions](#differentiable-separable-functions).*
Lookahead is a stochastic gradient based optimization method which chooses a
search direction by looking ahead at the sequence of "fast weights" generated
by another optimizer.
#### Constructors
* `Lookahead<>()`
* `Lookahead<>(`_`stepSize`_`)`
* `Lookahead<>(`_`stepSize, k`_`)`
* `Lookahead<>(`_`stepSize, k, maxIterations, tolerance, decayPolicy, exactObjective`_`)`
* `Lookahead<>(`_`baseOptimizer, stepSize, k, maxIterations, tolerance, decayPolicy, exactObjective`_`)`
Note that `Lookahead<>` is based on the templated type
`LookaheadType<`_`BaseOptimizerType, DecayPolicyType`_`>` with _`BaseOptimizerType`_` = Adam` and _`DecayPolicyType`_` = NoDecay`.
Any optimizer that implements the differentiable separable functions interface
can be paired with the `Lookahead` optimizer.
#### Attributes
| **type** | **name** | **description** | **default** |
|----------|----------|-----------------|-------------|
| `BaseOptimizerType` | **`baseOptimizer`** | Optimizer for the forward step. | Adam |
| `double` | **`stepSize`** | Step size for each iteration. | `0.5` |
| `size_t` | **`k`** | The synchronization period. | `5` |
| `size_t` | **`max_iterations`** | Maximum number of iterations allowed (0 means no limit). | `100000` |
| `double` | **`tolerance`** | Maximum absolute tolerance to terminate algorithm. | `1e-5` |
| `DecayPolicyType` | **`decayPolicy`** | Instantiated decay policy used to adjust the step size. | `DecayPolicyType()` |
| `bool` | **`exactObjective`** | Calculate the exact objective (Default: estimate the final objective obtained on the last pass over the data). | `false` |
The attributes of the optimizer may also be modified via the member methods
`BaseOptimizer()`, `StepSize()`, `K()`, `MaxIterations()`,
`Tolerance()`, `DecayPolicy()` and `ExactObjective()`.
#### Examples
<details open>
<summary>Click to collapse/expand example code.
</summary>
```c++
RosenbrockFunction f;
arma::mat coordinates = f.GetInitialPoint();
Lookahead<> optimizer(0.5, 5, 100000, 1e-5);
optimizer.Optimize(f, coordinates);
```
</details>
#### See also:
* [SGD in Wikipedia](https://en.wikipedia.org/wiki/Stochastic_gradient_descent)
* [SGD](#standard-sgd)
* [Lookahead Optimizer: k steps forward, 1 step back](https://arxiv.org/abs/1907.08610)
* [Differentiable separable functions](#differentiable-separable-functions)
## LRSDP (low-rank SDP solver)
*An optimizer for [semidefinite programs](#semidefinite-programs).*
@@ -1379,6 +1563,163 @@ optimizer.Optimize(f, coordinates);
* [SGD in Wikipedia](https://en.wikipedia.org/wiki/Stochastic_gradient_descent)
* [Differentiable separable functions](#differentiable-separable-functions)
## MOEA/D-DE
*An optimizer for arbitrary multi-objective functions.*
MOEA/D-DE (Multi Objective Evolutionary Algorithm based on Decomposition - Differential Evolution) is a multi
objective optimization algorithm. It works by decomposing the problem into a number of scalar optimization
subproblems which are solved simultaneously per generation. MOEA/D in itself is a framework, this particular
algorithm uses Differential Crossover followed by Polynomial Mutation to create offsprings which are then
decomposed to form a Single Objective Problem. A diversity preserving mechanism is also employed which encourages
a varied set of solution.
#### Constructors
* `MOEAD<`_`InitPolicyType, DecompPolicyType`_`>()`
* `MOEAD<`_`InitPolicyType, DecompPolicyType`_`>(`_`populationSize, maxGenerations, crossoverProb, neighborProb, neighborSize, distributionIndex, differentialWeight, maxReplace, epsilon, lowerBound, upperBound`_`)`
The _`InitPolicyType`_ template parameter refers to the strategy used to
initialize the reference directions.
The following types are available:
* **`Uniform`**
* **`BayesianBootstrap`**
* **`Dirichlet`**
The _`DecompPolicyType`_ template parameter refers to the strategy used to
decompose the weight vectors to form a scalar objective function.
The following types are available:
* **`Tchebycheff`**
* **`WeightedAverage`**
* **`PenaltyBoundaryIntersection`**
For convenience the following types can be used:
* **`DefaultMOEAD`** (equivalent to `MOEAD<Uniform, Tchebycheff>`): utilizes Uniform method for weight initialization
and Tchebycheff for weight decomposition.
* **`BBSMOEAD`** (equivalent to `MOEAD<BayesianBootstrap, Tchebycheff>`): utilizes Bayesian Bootstrap method for weight initialization and Tchebycheff for weight decomposition.
* **`DirichletMOEAD`** (equivalent to `MOEAD<Dirichlet, Tchebycheff>`): utilizes Dirichlet sampling for weight init
and Tchebycheff for weight decomposition.
#### Attributes
| **type** | **name** | **description** | **default** |
|----------|----------|-----------------|-------------|
| `size_t` | **`populationSize`** | The number of candidates in the population. | `150` |
| `size_t` | **`maxGenerations`** | The maximum number of generations allowed. | `300` |
| `double` | **`crossoverProb`** | Probability that a crossover will occur. | `1.0` |
| `double` | **`neighborProb`** | The probability of sampling from neighbor. | `0.9` |
| `size_t` | **`neighborSize`** | The number of nearest-neighbours to consider per weight vector. | `20` |
| `double` | **`distributionIndex`** | The crowding degree of the mutation. | `20` |
| `double` | **`differentialWeight`** | Amplification factor of the differentiation. | `0.5` |
| `size_t` | **`maxReplace`** | The limit of solutions allowed to be replaced by a child. | `2`|
| `double` | **`epsilon`** | Handles numerical stability after weight initialization. | `1E-10`|
| `double`, `arma::vec` | **`lowerBound`** | Lower bound of the coordinates on the coordinates of the whole population during the search process. | `0` |
| `double`, `arma::vec` | **`upperBound`** | Lower bound of the coordinates on the coordinates of the whole population during the search process. | `1` |
| `InitPolicyType` | **`initPolicy`** | Instantiated init policy used to initialize weights. | `InitPolicyType()` |
| `DecompPolicyType` | **`decompPolicy`** | Instantiated decomposition policy used to create scalar objective problem. | `DecompPolicyType()` |
Attributes of the optimizer may also be changed via the member methods
`PopulationSize()`, `MaxGenerations()`, `CrossoverRate()`, `NeighborProb()`, `NeighborSize()`, `DistributionIndex()`,
`DifferentialWeight()`, `MaxReplace()`, `Epsilon()`, `LowerBound()`, `UpperBound()`, `InitPolicy()` and `DecompPolicy()`.
#### Examples:
<details open>
<summary>Click to collapse/expand example code.
</summary>
```c++
SchafferFunctionN1<arma::mat> SCH;
arma::vec lowerBound("-10 -10");
arma::vec upperBound("10 10");
DefaultMOEAD opt(300, 300, 1.0, 0.9, 20, 20, 0.5, 2, 1E-10, lowerBound, upperBound);
typedef decltype(SCH.objectiveA) ObjectiveTypeA;
typedef decltype(SCH.objectiveB) ObjectiveTypeB;
arma::mat coords = SCH.GetInitialPoint();
std::tuple<ObjectiveTypeA, ObjectiveTypeB> objectives = SCH.GetObjectives();
// obj will contain the minimum sum of objectiveA and objectiveB found on the best front.
double obj = opt.Optimize(objectives, coords);
// Now obtain the best front.
arma::cube bestFront = opt.ParetoFront();
```
</details>
#### See also
* [MOEA/D-DE Algorithm](https://ieeexplore.ieee.org/document/4633340)
* [Multi-objective Functions in Wikipedia](https://en.wikipedia.org/wiki/Test_functions_for_optimization#Test_functions_for_multi-objective_optimization)
* [Multi-objective functions](#multi-objective-functions)
## NSGA2
*An optimizer for arbitrary multi-objective functions.*
NSGA2 (Non-dominated Sorting Genetic Algorithm - II) is a multi-objective
optimization algorithm. The algorithm works by generating a candidate population
from a fixed starting point. At each stage of optimization, a new population of
children is generated. This new population along with its predecessor is sorted
using non-domination as the metric. Following this, the population is further
segregated into fronts. A new population is generated from these fronts having
size equal to that of the starting population.
#### Constructors
* `NSGA2()`
* `NSGA2(`_`populationSize, maxGenerations, crossoverProb, mutationProb, mutationStrength, epsilon, lowerBound, upperBound`_`)`
#### Attributes
| **type** | **name** | **description** | **default** |
|----------|----------|-----------------|-------------|
| `size_t` | **`populationSize`** | The number of candidates in the population. This should be at least 4 in size and a multiple of 4. | `100` |
| `size_t` | **`maxGenerations`** | The maximum number of generations allowed for NSGA2. | `2000` |
| `double` | **`crossoverProb`** | Probability that a crossover will occur. | `0.6` |
| `double` | **`mutationProb`** | Probability that a weight will get mutated. | `0.3` |
| `double` | **`mutationStrength`** | The range of mutation noise to be added. This range is between 0 and mutationStrength. | `0.001` |
| `double` | **`epsilon`** | The value used internally to evaluate approximate equality in crowding distance based sorting. | `1e-6` |
| `double`, `arma::vec` | **`lowerBound`** | Lower bound of the coordinates on the coordinates of the whole population during the search process. | `0` |
| `double`, `arma::vec` | **`upperBound`** | Lower bound of the coordinates on the coordinates of the whole population during the search process. | `1` |
Note that the parameters `lowerBound` and `upperBound` are overloaded. Data types of `double` or `arma::mat` may be used. If they are initialized as single values of `double`, then the same value of the bound applies to all the axes, resulting in an initialization following a uniform distribution in a hypercube. If they are initialized as matrices of `arma::mat`, then the value of `lowerBound[i]` applies to axis `[i]`; similarly, for values in `upperBound`. This results in an initialization following a uniform distribution in a hyperrectangle within the specified bounds.
Attributes of the optimizer may also be changed via the member methods
`PopulationSize()`, `MaxGenerations()`, `CrossoverRate()`, `MutationProbability()`, `MutationStrength()`, `Epsilon()`, `LowerBound()` and `UpperBound()`.
#### Examples:
<details open>
<summary>Click to collapse/expand example code.
</summary>
```c++
SchafferFunctionN1<arma::mat> SCH;
arma::vec lowerBound("-1000 -1000");
arma::vec upperBound("1000 1000");
NSGA2 opt(20, 5000, 0.5, 0.5, 1e-3, 1e-6, lowerBound, upperBound);
typedef decltype(SCH.objectiveA) ObjectiveTypeA;
typedef decltype(SCH.objectiveB) ObjectiveTypeB;
arma::mat coords = SCH.GetInitialPoint();
std::tuple<ObjectiveTypeA, ObjectiveTypeB> objectives = SCH.GetObjectives();
// obj will contain the minimum sum of objectiveA and objectiveB found on the best front.
double obj = opt.Optimize(objectives, coords);
// Now obtain the best front.
arma::cube bestFront = opt.Front();
```
</details>
#### See also:
* [NSGA-II Algorithm](https://www.iitk.ac.in/kangal/Deb_NSGA-II.pdf)
* [Multi-objective Functions in Wikipedia](https://en.wikipedia.org/wiki/Test_functions_for_optimization#Test_functions_for_multi-objective_optimization)
* [Multi-objective functions](#multi-objective-functions)
## OptimisticAdam
*An optimizer for [differentiable separable functions](#differentiable-separable-functions).*
@@ -1387,7 +1728,7 @@ OptimisticAdam is an optimizer which implements the Optimistic Adam algorithm
which uses Optmistic Mirror Descent with the Adam Optimizer. It addresses the
problem of limit cycling while training GANs (generative adversarial networks).
It uses OMD to achieve faster regret rates in solving the zero sum game of
training a GAN. It consistently achieves a smaller KL divergnce with~ respect to
training a GAN. It consistently achieves a smaller KL divergence with~ respect to
the true underlying data distribution. The implementation here can be used with
any differentiable separable function, not just GAN training.
@@ -1730,7 +2071,7 @@ optimizer.Optimize(f, coordinates);
QHAdam is an optimizer that uses quasi-hyperbolic descent with the Adam
optimizer. This replaces the moment estimators of Adam with quasi-hyperbolic
terms, and different values of the `v1` and `v2` parameters are equivalent to
terms, and various values of the `v1` and `v2` parameters are equivalent to
the following other optimizers:
* When `v1 = v2 = 1`, `QHAdam` is equivalent to `Adam`.
@@ -1808,7 +2149,7 @@ RMSProp utilizes the magnitude of recent gradients to normalize the gradients.
| `double` | **`stepSize`** | Step size for each iteration. | `0.01` |
| `size_t` | **`batchSize`** | Number of points to process in each step. | `32` |
| `double` | **`alpha`** | Smoothing constant, similar to that used in AdaDelta and momentum methods. | `0.99` |
| `double` | **`epsilon`** | Value used to initialise the mean squared gradient parameter. | `1e-8` |
| `double` | **`epsilon`** | Value used to initialize the mean squared gradient parameter. | `1e-8` |
| `size_t` | **`maxIterations`** | Maximum number of iterations allowed (0 means no limit). | `100000` |
| `double` | **`tolerance`** | Maximum absolute tolerance to terminate algorithm. |
| `bool` | **`shuffle`** | If true, the function order is shuffled; otherwise, each function is visited in linear order. | `true` |
@@ -1884,7 +2225,7 @@ shorter type `SA<>` may be used instead of the equivalent
| **type** | **name** | **description** | **default** |
|----------|----------|-----------------|-------------|
| `CoolingScheduleType` | **`coolingSchedule`** | Instantiated cooling schedule (default ExponentialSchedule). | **n/a** |
| `CoolingScheduleType` | **`coolingSchedule`** | Instantiated cooling schedule (default ExponentialSchedule). | **CoolingScheduleType()** |
| `size_t` | **`maxIterations`** | Maximum number of iterations allowed (0 indicates no limit). | `1000000` |
| `double` | **`initT`** | Initial temperature. | `10000.0` |
| `size_t` | **`initMoves`** | Number of initial iterations without changing temperature. | `1000` |
@@ -2325,7 +2666,7 @@ optimizer.Optimize(f, coordinates);
*An optimizer for [differentiable separable functions](#differentiable-separable-functions).*
SMORMS3 is a hybrid of RMSprop, which is trying to estimate a safe and optimal
distance based on curvature or perhaps just normalizing the stepsize in the
distance based on curvature or perhaps just normalizing the step-size in the
parameter space.
#### Constructors
@@ -2341,7 +2682,7 @@ parameter space.
|----------|----------|-----------------|-------------|
| `double` | **`stepSize`** | Step size for each iteration. | `0.001` |
| `size_t` | **`batchSize`** | Number of points to process at each step. | `32` |
| `double` | **`epsilon`** | Value used to initialise the mean squared gradient parameter. | `1e-16` |
| `double` | **`epsilon`** | Value used to initialize the mean squared gradient parameter. | `1e-16` |
| `size_t` | **`maxIterations`** | Maximum number of iterations allowed (0 means no limit). | `100000` |
| `double` | **`tolerance`** | Maximum absolute tolerance to terminate algorithm. | `1e-5` |
| `bool` | **`shuffle`** | If true, the mini-batch order is shuffled; otherwise, each mini-batch is visited in linear order. | `true` |
@@ -2548,7 +2889,7 @@ the projection of Adam steps on the gradient subspace.
| `size_t` | **`batchSize`** | Number of points to process at each step. | `32` |
| `double` | **`beta1`** | Exponential decay rate for the first moment estimates. | `0.9` |
| `double` | **`beta2`** | Exponential decay rate for the weighted infinity norm estimates. | `0.999` |
| `double` | **`epsilon`** | Value used to initialise the mean squared gradient parameter. | `1e-16` |
| `double` | **`epsilon`** | Value used to initialize the mean squared gradient parameter. | `1e-16` |
| `size_t` | **`maxIterations`** | Maximum number of iterations allowed (0 means no limit). | `100000` |
| `double` | **`tolerance`** | Maximum absolute tolerance to terminate algorithm. | `1e-5` |
| `bool` | **`shuffle`** | If true, the mini-batch order is shuffled; otherwise, each mini-batch is visited in linear order. | `true` |
+70
View File
@@ -0,0 +1,70 @@
// Example implementation of an objective function class for linear regression
// and usage of the L-BFGS optimizer.
//
// Compilation:
// g++ example.cpp -o example -O3 -larmadillo
#include <iostream>
#include <armadillo>
#include <ensmallen.hpp>
class LinearRegressionFunction
{
public:
LinearRegressionFunction(arma::mat& X, arma::vec& y) : X(X), y(y) { }
double EvaluateWithGradient(const arma::mat& theta, arma::mat& gradient)
{
const arma::vec tmp = X.t() * theta - y;
gradient = 2 * X * tmp;
return arma::dot(tmp,tmp);
}
private:
const arma::mat& X;
const arma::vec& y;
};
int main(int argc, char** argv)
{
if (argc < 3)
{
std::cout << "usage: " << argv[0] << " n_dims n_points" << std::endl;
return -1;
}
int n_dims = atoi(argv[1]);
int n_points = atoi(argv[2]);
// generate noisy dataset with a slight linear pattern
arma::mat X(n_dims, n_points, arma::fill::randu);
arma::vec y( n_points, arma::fill::randu);
for (size_t i = 0; i < n_points; ++i)
{
double a = arma::randu();
X(1, i) += a;
y(i) += a;
}
LinearRegressionFunction lrf(X, y);
// create a Limited-memory BFGS optimizer object with default parameters
ens::L_BFGS opt;
opt.MaxIterations() = 10;
// initial point (uniform random)
arma::vec theta(n_dims, arma::fill::randu);
opt.Optimize(lrf, theta);
// theta now contains the optimized parameters
theta.print("theta:");
return 0;
}
+25 -10
View File
@@ -33,20 +33,24 @@
#error "need Armadillo version 8.400 or later"
#endif
#include <cmath>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <climits>
#include <cfloat>
#include <climits>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <set>
#include <limits>
#include <sstream>
#include <stdexcept>
#include <string>
#include <tuple>
#include <utility>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
// On Visual Studio, disable C4519 (default arguments for function templates)
// since it's by default an error, which doesn't even make any sense because
@@ -61,17 +65,27 @@
#include "ensmallen_bits/utility/any.hpp"
#include "ensmallen_bits/utility/arma_traits.hpp"
#include "ensmallen_bits/utility/indicators/epsilon.hpp"
#include "ensmallen_bits/utility/indicators/igd_plus.hpp"
// Contains traits, must be placed before report callback.
#include "ensmallen_bits/function.hpp" // TODO: should move to function/
// Callbacks.
#include "ensmallen_bits/callbacks/callbacks.hpp"
#include "ensmallen_bits/callbacks/early_stop_at_min_loss.hpp"
#include "ensmallen_bits/callbacks/grad_clip_by_norm.hpp"
#include "ensmallen_bits/callbacks/grad_clip_by_value.hpp"
#include "ensmallen_bits/callbacks/print_loss.hpp"
#include "ensmallen_bits/callbacks/progress_bar.hpp"
#include "ensmallen_bits/callbacks/query_front.hpp"
#include "ensmallen_bits/callbacks/report.hpp"
#include "ensmallen_bits/callbacks/store_best_coordinates.hpp"
#include "ensmallen_bits/callbacks/timer_stop.hpp"
#include "ensmallen_bits/problems/problems.hpp" // TODO: should move to another place
#include "ensmallen_bits/ada_bound/ada_bound.hpp"
#include "ensmallen_bits/ada_delta/ada_delta.hpp"
#include "ensmallen_bits/ada_grad/ada_grad.hpp"
#include "ensmallen_bits/adam/adam.hpp"
@@ -84,14 +98,15 @@
#include "ensmallen_bits/eve/eve.hpp"
#include "ensmallen_bits/ftml/ftml.hpp"
#include "ensmallen_bits/function.hpp" // TODO: should move to function/
#include "ensmallen_bits/fw/frank_wolfe.hpp"
#include "ensmallen_bits/gradient_descent/gradient_descent.hpp"
#include "ensmallen_bits/grid_search/grid_search.hpp"
#include "ensmallen_bits/iqn/iqn.hpp"
#include "ensmallen_bits/katyusha/katyusha.hpp"
#include "ensmallen_bits/lbfgs/lbfgs.hpp"
#include "ensmallen_bits/lookahead/lookahead.hpp"
#include "ensmallen_bits/moead/moead.hpp"
#include "ensmallen_bits/nsga2/nsga2.hpp"
#include "ensmallen_bits/padam/padam.hpp"
#include "ensmallen_bits/parallel_sgd/parallel_sgd.hpp"
#include "ensmallen_bits/pso/pso.hpp"
@@ -0,0 +1,209 @@
/**
* @file ada_bound.hpp
* @author Marcus Edel
*
* Class wrapper for the AdaBound and AMSBound update Policy.
*
* ensmallen is free software; you may redistribute it and/or modify it under
* the terms of the 3-clause BSD license. You should have received a copy of
* the 3-clause BSD license along with ensmallen. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef ENSMALLEN_ADA_BOUND_HPP
#define ENSMALLEN_ADA_BOUND_HPP
#include <ensmallen_bits/sgd/sgd.hpp>
#include "ada_bound_update.hpp"
#include "ams_bound_update.hpp"
namespace ens {
/**
* AdaBound and AMSBound, employ dynamic bounds on learning rates to achieve a
* gradual and smooth transition from adaptive methods to SGD.
*
* For more information, see the following.
*
* @code
* @inproceedings{Luo2019AdaBound,
* author = {Luo, Liangchen and Xiong, Yuanhao and Liu, Yan and Sun, Xu},
* title = {Adaptive Gradient Methods with Dynamic Bound of Learning
* Rate},
* booktitle = {Proceedings of the 7th International Conference on Learning
* Representations},
* month = {May},
* year = {2019},
* address = {New Orleans, Louisiana}
* }
* @endcode
*
* AdaBound and AMSBound can optimize differentiable separable functions.
* For more details, see the documentation on function types included with this
* distribution or on the ensmallen website.
*/
template<typename UpdatePolicyType = AdaBoundUpdate,
typename DecayPolicyType = NoDecay>
class AdaBoundType
{
public:
/**
* Construct the AdaBoundType optimizer with the given function and
* parameters. AdaBoundType is sensitive to its parameters and hence a good
* hyper paramater selection is necessary as its default may not fit every
* case.
*
* The maximum number of iterations refers to the maximum number of
* points that are processed (i.e., one iteration equals one point; one
* iteration does not equal one pass over the dataset).
*
* @param stepSize Step size for each iteration.
* @param batchSize Number of points to process in a single step.
* @param finalLr The final (SGD) learning rate.
* @param gamma The convergence speed of the bound functions.
* @param beta1 Exponential decay rate for the first moment estimates.
* @param beta2 Exponential decay rate for the weighted infinity norm
* estimates.
* @param epsilon Value used to initialise the mean squared gradient
* parameter.
* @param maxIterations Maximum number of iterations allowed (0 means no
* limit).
* @param tolerance Maximum absolute tolerance to terminate algorithm.
* @param shuffle If true, the function order is shuffled; otherwise, each
* function is visited in linear order.
* @param resetPolicy If true, parameters are reset before every Optimize
* call; otherwise, their values are retained.
* @param exactObjective Calculate the exact objective (Default: estimate the
* final objective obtained on the last pass over the data).
*/
AdaBoundType(const double stepSize = 0.001,
const size_t batchSize = 32,
const double finalLr = 0.1,
const double gamma = 1e-3,
const double beta1 = 0.9,
const double beta2 = 0.999,
const double epsilon = 1e-8,
const size_t maxIterations = 100000,
const double tolerance = 1e-5,
const bool shuffle = true,
const bool resetPolicy = true,
const bool exactObjective = false);
/**
* Optimize the given function using AdaBoundType. The given starting point
* will be modified to store the finishing point of the algorithm, and the
* final objective value is returned. The DecomposableFunctionType is checked
* for API consistency at compile time.
*
* @tparam DecomposableFunctionType Type of the function to be optimized.
* @tparam MatType Type of matrix to optimize with.
* @tparam GradType Type of matrix to use to represent function gradients.
* @tparam CallbackTypes Types of callback functions.
* @param function Function to optimize.
* @param iterate Starting point (will be modified).
* @param callbacks Callback functions.
* @return Objective value of the final point.
*/
template<typename DecomposableFunctionType,
typename MatType,
typename GradType,
typename... CallbackTypes>
typename std::enable_if<IsArmaType<GradType>::value,
typename MatType::elem_type>::type
Optimize(DecomposableFunctionType& function,
MatType& iterate,
CallbackTypes&&... callbacks)
{
return optimizer.template Optimize<DecomposableFunctionType, MatType,
GradType, CallbackTypes...>(function, iterate,
std::forward<CallbackTypes>(callbacks)...);
}
//! Forward the MatType as GradType.
template<typename DecomposableFunctionType,
typename MatType,
typename... CallbackTypes>
typename MatType::elem_type Optimize(DecomposableFunctionType& function,
MatType& iterate,
CallbackTypes&&... callbacks)
{
return Optimize<DecomposableFunctionType, MatType, MatType,
CallbackTypes...>(function, iterate,
std::forward<CallbackTypes>(callbacks)...);
}
//! Get the final (SGD) learning rate.
double FinalLr() const { return optimizer.UpdatePolicy().FinalLr(); }
//! Modify the final (SGD) learning rate.
double& FinalLr() { return optimizer.UpdatePolicy().FinalLr(); }
//! Get the convergence speed of the bound functions.
double Gamma() const { return optimizer.UpdatePolicy().Gamma(); }
//! Modify the convergence speed of the bound functions.
double& Gamma() { return optimizer.UpdatePolicy().Gamma(); }
//! Get the step size.
double StepSize() const { return optimizer.StepSize(); }
//! Modify the step size.
double& StepSize() { return optimizer.StepSize(); }
//! Get the batch size.
size_t BatchSize() const { return optimizer.BatchSize(); }
//! Modify the batch size.
size_t& BatchSize() { return optimizer.BatchSize(); }
//! Get the smoothing parameter.
double Beta1() const { return optimizer.UpdatePolicy().Beta1(); }
//! Modify the smoothing parameter.
double& Beta1() { return optimizer.UpdatePolicy().Beta1(); }
//! Get the second moment coefficient.
double Beta2() const { return optimizer.UpdatePolicy().Beta2(); }
//! Modify the second moment coefficient.
double& Beta2() { return optimizer.UpdatePolicy().Beta2(); }
//! Get the value used to initialise the mean squared gradient parameter.
double Epsilon() const { return optimizer.UpdatePolicy().Epsilon(); }
//! Modify the value used to initialise the mean squared gradient parameter.
double& Epsilon() { return optimizer.UpdatePolicy().Epsilon(); }
//! Get the maximum number of iterations (0 indicates no limit).
size_t MaxIterations() const { return optimizer.MaxIterations(); }
//! Modify the maximum number of iterations (0 indicates no limit).
size_t& MaxIterations() { return optimizer.MaxIterations(); }
//! Get the tolerance for termination.
double Tolerance() const { return optimizer.Tolerance(); }
//! Modify the tolerance for termination.
double& Tolerance() { return optimizer.Tolerance(); }
//! Get whether or not the individual functions are shuffled.
bool Shuffle() const { return optimizer.Shuffle(); }
//! Modify whether or not the individual functions are shuffled.
bool& Shuffle() { return optimizer.Shuffle(); }
//! Get whether or not the actual objective is calculated.
bool ExactObjective() const { return optimizer.ExactObjective(); }
//! Modify whether or not the actual objective is calculated.
bool& ExactObjective() { return optimizer.ExactObjective(); }
//! Get whether or not the update policy parameters are reset before
//! Optimize call.
bool ResetPolicy() const { return optimizer.ResetPolicy(); }
//! Modify whether or not the update policy parameters
//! are reset before Optimize call.
bool& ResetPolicy() { return optimizer.ResetPolicy(); }
private:
//! The Stochastic Gradient Descent object with QHAdam policy.
SGD<UpdatePolicyType, DecayPolicyType> optimizer;
};
using AdaBound = AdaBoundType<AdaBoundUpdate>;
using AMSBound = AdaBoundType<AMSBoundUpdate>;
} // namespace ens
// Include implementation.
#include "ada_bound_impl.hpp"
#endif
@@ -0,0 +1,47 @@
/**
* @file qhadam_impl.hpp
* @author Niteya Shah
*
* Implementation of QHAdam class wrapper.
*
* ensmallen is free software; you may redistribute it and/or modify it under
* the terms of the 3-clause BSD license. You should have received a copy of
* the 3-clause BSD license along with ensmallen. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef ENSMALLEN_ADA_BOUND_IMPL_HPP
#define ENSMALLEN_ADA_BOUND_IMPL_HPP
// In case it hasn't been included yet.
#include "ada_bound.hpp"
namespace ens {
template<typename UpdatePolicyType, typename DecayPolicyType>
AdaBoundType<UpdatePolicyType, DecayPolicyType>::AdaBoundType(
const double stepSize,
const size_t batchSize,
const double finalLr,
const double gamma,
const double beta1,
const double beta2,
const double epsilon,
const size_t maxIterations,
const double tolerance,
const bool shuffle,
const bool resetPolicy,
const bool exactObjective) :
optimizer(stepSize,
batchSize,
maxIterations,
tolerance,
shuffle,
UpdatePolicyType(finalLr, gamma, epsilon, beta1, beta2),
NoDecay(),
resetPolicy,
exactObjective)
{ /* Nothing to do. */ }
} // namespace ens
#endif
@@ -0,0 +1,207 @@
/**
* @file ada_bound_update.hpp
* @author Marcus Edel
*
* Implments the AdaBound Optimizer. AdaBound is a variant of Adam which
* employs dynamic bounds on learning rates.
*
* ensmallen is free software; you may redistribute it and/or modify it under
* the terms of the 3-clause BSD license. You should have received a copy of
* the 3-clause BSD license along with ensmallen. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef ENSMALLEN_ADA_BOUND_UPDATE_HPP
#define ENSMALLEN_ADA_BOUND_UPDATE_HPP
namespace ens {
/**
* AdaBound employs dynamic bounds on learning rates to achieve a gradual and
* smooth transition from adaptive methods to SGD.
*
* For more information, see the following.
*
* @code
* @inproceedings{Luo2019AdaBound,
* author = {Luo, Liangchen and Xiong, Yuanhao and Liu, Yan and Sun, Xu},
* title = {Adaptive Gradient Methods with Dynamic Bound of Learning
* Rate},
* booktitle = {Proceedings of the 7th International Conference on Learning
* Representations},
* month = {May},
* year = {2019},
* address = {New Orleans, Louisiana}
* }
* @endcode
*/
class AdaBoundUpdate
{
public:
/**
* Construct the AdaBound update policy with the given parameters.
*
* @param finalLr The final (SGD) learning rate.
* @param gamma The convergence speed of the bound functions.
* @param epsilon The epsilon value used to initialise the squared gradient
* parameter.
* @param beta1 The smoothing parameter.
* @param beta2 The second moment coefficient.
*/
AdaBoundUpdate(const double finalLr = 0.1,
const double gamma = 1e-3,
const double epsilon = 1e-8,
const double beta1 = 0.9,
const double beta2 = 0.999) :
finalLr(finalLr),
gamma(gamma),
epsilon(epsilon),
beta1(beta1),
beta2(beta2),
iteration(0)
{
// Nothing to do.
}
//! Get the final (SGD) learning rate.
double FinalLr() const { return finalLr; }
//! Modify the final (SGD) learning rate.
double& FinalLr() { return finalLr; }
//! Get the convergence speed of the bound functions.
double Gamma() const { return finalLr; }
//! Modify the convergence speed of the bound functions.
double& Gamma() { return finalLr; }
//! Get the value used to initialise the squared gradient parameter.
double Epsilon() const { return epsilon; }
//! Modify the value used to initialise the squared gradient parameter.
double& Epsilon() { return epsilon; }
//! Get the smoothing parameter.
double Beta1() const { return beta1; }
//! Modify the smoothing parameter.
double& Beta1() { return beta1; }
//! Get the second moment coefficient.
double Beta2() const { return beta2; }
//! Modify the second moment coefficient.
double& Beta2() { return beta2; }
//! Get the current iteration number.
size_t Iteration() const { return iteration; }
//! Modify the current iteration number.
size_t& Iteration() { return iteration; }
/**
* The UpdatePolicyType policy classes must contain an internal 'Policy'
* template class with two template arguments: MatType and GradType. This is
* instantiated at the start of the optimization, and holds parameters
* specific to an individual optimization.
*/
template<typename MatType, typename GradType>
class Policy
{
public:
/**
* This constructor is called by the SGD Optimize() method before the start
* of the iteration update process.
*
* @param parent AdaBoundUpdate object.
* @param rows Number of rows in the gradient matrix.
* @param cols Number of columns in the gradient matrix.
*/
Policy(AdaBoundUpdate& parent, const size_t rows, const size_t cols) :
parent(parent), first(true), initialStepSize(0)
{
m.zeros(rows, cols);
v.zeros(rows, cols);
}
/**
* Update step for AdaBound.
*
* @param iterate Parameters that minimize the function.
* @param stepSize Step size to be used for the given iteration.
* @param gradient The gradient matrix.
*/
void Update(MatType& iterate,
const double stepSize,
const GradType& gradient)
{
// Convenience typedefs.
typedef typename MatType::elem_type ElemType;
// Save the initial step size.
if (first)
{
first = false;
initialStepSize = stepSize;
}
// Increment the iteration counter variable.
++parent.iteration;
// Decay the first and second moment running average coefficient.
m *= parent.beta1;
m += (1 - parent.beta1) * gradient;
v *= parent.beta2;
v += (1 - parent.beta2) * (gradient % gradient);
const ElemType biasCorrection1 = 1.0 - std::pow(parent.beta1,
parent.iteration);
const ElemType biasCorrection2 = 1.0 - std::pow(parent.beta2,
parent.iteration);
const ElemType fl = parent.finalLr * stepSize / initialStepSize;
const ElemType lower = fl * (1.0 - 1.0 / (parent.gamma *
parent.iteration + 1));
const ElemType upper = fl * (1.0 + 1.0 / (parent.gamma *
parent.iteration));
// Applies bounds on actual learning rate.
iterate -= arma::clamp((stepSize *
std::sqrt(biasCorrection2) / biasCorrection1) / (arma::sqrt(v) +
parent.epsilon), lower, upper) % m;
}
private:
// Instantiated parent object.
AdaBoundUpdate& parent;
// The exponential moving average of gradient values.
GradType m;
// The exponential moving average of squared gradient values.
GradType v;
// Whether this is the first call of the Update method.
bool first;
// The initial (Adam) learning rate.
double initialStepSize;
};
private:
// The final (SGD) learning rate.
double finalLr;
// The convergence speed of the bound functions.
double gamma;
// The epsilon value used to initialise the squared gradient parameter.
double epsilon;
// The smoothing parameter.
double beta1;
// The second moment coefficient.
double beta2;
// The number of iterations.
size_t iteration;
};
} // namespace ens
#endif
@@ -0,0 +1,214 @@
/**
* @file ams_bound_update.hpp
* @author Marcus Edel
*
* Implments the AMSBound Optimizer. AMSBound is a variant of Adam which
* employs dynamic bounds on learning rates.
*
* ensmallen is free software; you may redistribute it and/or modify it under
* the terms of the 3-clause BSD license. You should have received a copy of
* the 3-clause BSD license along with ensmallen. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef ENSMALLEN_AMS_BOUND_UPDATE_HPP
#define ENSMALLEN_AMS_BOUND_UPDATE_HPP
namespace ens {
/**
* AMSBound employs dynamic bounds on learning rates to achieve a gradual and
* smooth transition from adaptive methods to SGD.
*
* For more information, see the following.
*
* @code
* @inproceedings{Luo2019AdaBound,
* author = {Luo, Liangchen and Xiong, Yuanhao and Liu, Yan and Sun, Xu},
* title = {Adaptive Gradient Methods with Dynamic Bound of Learning
* Rate},
* booktitle = {Proceedings of the 7th International Conference on Learning
* Representations},
* month = {May},
* year = {2019},
* address = {New Orleans, Louisiana}
* }
* @endcode
*/
class AMSBoundUpdate
{
public:
/**
* Construct the AMSBound update policy with the given parameters.
*
* @param finalLr The final (SGD) learning rate.
* @param gamma The convergence speed of the bound functions.
* @param epsilon The epsilon value used to initialise the squared gradient
* parameter.
* @param beta1 The smoothing parameter.
* @param beta2 The second moment coefficient.
*/
AMSBoundUpdate(const double finalLr = 0.1,
const double gamma = 1e-3,
const double epsilon = 1e-8,
const double beta1 = 0.9,
const double beta2 = 0.999) :
finalLr(finalLr),
gamma(gamma),
epsilon(epsilon),
beta1(beta1),
beta2(beta2),
iteration(0)
{
// Nothing to do.
}
//! Get the final (SGD) learning rate.
double FinalLr() const { return finalLr; }
//! Modify the final (SGD) learning rate.
double& FinalLr() { return finalLr; }
//! Get the convergence speed of the bound functions.
double Gamma() const { return finalLr; }
//! Modify the convergence speed of the bound functions.
double& Gamma() { return finalLr; }
//! Get the value used to initialise the squared gradient parameter.
double Epsilon() const { return epsilon; }
//! Modify the value used to initialise the squared gradient parameter.
double& Epsilon() { return epsilon; }
//! Get the smoothing parameter.
double Beta1() const { return beta1; }
//! Modify the smoothing parameter.
double& Beta1() { return beta1; }
//! Get the second moment coefficient.
double Beta2() const { return beta2; }
//! Modify the second moment coefficient.
double& Beta2() { return beta2; }
//! Get the current iteration number.
size_t Iteration() const { return iteration; }
//! Modify the current iteration number.
size_t& Iteration() { return iteration; }
/**
* The UpdatePolicyType policy classes must contain an internal 'Policy'
* template class with two template arguments: MatType and GradType. This is
* instantiated at the start of the optimization, and holds parameters
* specific to an individual optimization.
*/
template<typename MatType, typename GradType>
class Policy
{
public:
/**
* This constructor is called by the SGD Optimize() method before the start
* of the iteration update process.
*
* @param parent AMSBoundUpdate object.
* @param rows Number of rows in the gradient matrix.
* @param cols Number of columns in the gradient matrix.
*/
Policy(AMSBoundUpdate& parent, const size_t rows, const size_t cols) :
parent(parent), first(true), initialStepSize(0)
{
m.zeros(rows, cols);
v.zeros(rows, cols);
vImproved.zeros(rows, cols);
}
/**
* Update step for AMSBound.
*
* @param iterate Parameters that minimize the function.
* @param stepSize Step size to be used for the given iteration.
* @param gradient The gradient matrix.
*/
void Update(MatType& iterate,
const double stepSize,
const GradType& gradient)
{
// Convenience typedefs.
typedef typename MatType::elem_type ElemType;
// Save the initial step size.
if (first)
{
first = false;
initialStepSize = stepSize;
}
// Increment the iteration counter variable.
++parent.iteration;
// Decay the first and second moment running average coefficient.
m *= parent.beta1;
m += (1 - parent.beta1) * gradient;
v *= parent.beta2;
v += (1 - parent.beta2) * (gradient % gradient);
const ElemType biasCorrection1 = 1.0 - std::pow(parent.beta1,
parent.iteration);
const ElemType biasCorrection2 = 1.0 - std::pow(parent.beta2,
parent.iteration);
const ElemType fl = parent.finalLr * stepSize / initialStepSize;
const ElemType lower = fl * (1.0 - 1.0 / (parent.gamma *
parent.iteration + 1));
const ElemType upper = fl * (1.0 + 1.0 / (parent.gamma *
parent.iteration));
// Element wise maximum of past and present squared gradients.
vImproved = arma::max(vImproved, v);
// Applies bounds on actual learning rate.
iterate -= arma::clamp((stepSize *
std::sqrt(biasCorrection2) / biasCorrection1) /
(arma::sqrt(vImproved) + parent.epsilon), lower, upper) % m;
}
private:
// Instantiated parent object.
AMSBoundUpdate& parent;
// The exponential moving average of gradient values.
GradType m;
// The exponential moving average of squared gradient values.
GradType v;
// Whether this is the first call of the Update method.
bool first;
// The initial (Adam) learning rate.
double initialStepSize;
// The optimal squared gradient value.
GradType vImproved;
};
private:
// The final (SGD) learning rate.
double finalLr;
// The convergence speed of the bound functions.
double gamma;
// The epsilon value used to initialise the squared gradient parameter.
double epsilon;
// The smoothing parameter.
double beta1;
// The second moment coefficient.
double beta2;
// The number of iterations.
size_t iteration;
};
} // namespace ens
#endif
@@ -105,7 +105,8 @@ class AdaDelta
CallbackTypes&&... callbacks)
{
return optimizer.Optimize<SeparableFunctionType, MatType, GradType,
CallbackTypes...>(function, iterate, callbacks...);
CallbackTypes...>(function, iterate,
std::forward<CallbackTypes>(callbacks)...);
}
//! Forward the MatType as GradType.
+2 -1
View File
@@ -101,7 +101,8 @@ class AdaGrad
CallbackTypes&&... callbacks)
{
return optimizer.Optimize<SeparableFunctionType, MatType, GradType,
CallbackTypes...>(function, iterate, callbacks...);
CallbackTypes...>(function, iterate,
std::forward<CallbackTypes>(callbacks)...);
}
//! Forward the MatType as GradType.
+1 -1
View File
@@ -128,7 +128,7 @@ class AdamType
{
return optimizer.template Optimize<
SeparableFunctionType, MatType, GradType, CallbackTypes...>(
function, iterate, callbacks...);
function, iterate, std::forward<CallbackTypes>(callbacks)...);
}
//! Forward the MatType as GradType.
@@ -2,7 +2,7 @@
* @file optimisticadam_update.hpp
* @author Moksh Jain
*
* OptmisticAdam optimizer. Implements Optimistic Adam, an algorithm which
* OptmisticAdam optimizer. Implements Optimistic Adam, an algorithm which
* uses Optimistic Mirror Descent with the Adam optimizer.
*
* ensmallen is free software; you may redistribute it and/or modify it under
@@ -16,18 +16,18 @@
namespace ens {
/**
* OptimisticAdam is an optimizer which implements the Optimistic Adam
* OptimisticAdam is an optimizer which implements the Optimistic Adam
* algorithm which uses Optmistic Mirror Descent with the Adam Optimizer.
* It addresses the problem of limit cycling while training GANs. It uses
* OMD to achieve faster regret rates in solving the zero sum game of
* training a GAN. It consistently achieves a smaller KL divergnce with
* OMD to achieve faster regret rates in solving the zero sum game of
* training a GAN. It consistently achieves a smaller KL divergnce with
* respect to the true underlying data distribution.
*
* For more information, see the following.
*
* @code
* @article{
* author = {Constantinos Daskalakis, Andrew Ilyas, Vasilis Syrgkanis,
* author = {Constantinos Daskalakis, Andrew Ilyas, Vasilis Syrgkanis,
* Haoyang Zeng},
* title = {Training GANs with Optimism},
* year = {2017},
@@ -27,7 +27,8 @@ inline AugLagrangian::AugLagrangian(const size_t maxIterations,
penaltyThresholdFactor(penaltyThresholdFactor),
sigmaUpdateFactor(sigmaUpdateFactor),
lbfgs(lbfgs),
terminate(false)
terminate(false),
sigma(0.0)
{
}
@@ -107,6 +108,10 @@ AugLagrangian::Optimize(
// Track the last objective to compare for convergence.
ElemType lastObjective = function.Evaluate(coordinates);
// Convergence tolerance---depends on the epsilon of the type we are using for
// optimization.
ElemType tolerance = 1e3 * std::numeric_limits<ElemType>::epsilon();
// Then, calculate the current penalty.
ElemType penalty = 0;
for (size_t i = 0; i < function.NumConstraints(); i++)
@@ -134,6 +139,7 @@ AugLagrangian::Optimize(
if (!lbfgs.Optimize(augfunc, coordinates, callbacks...))
Info << "L-BFGS reported an error during optimization."
<< std::endl;
Info << "Done with L-BFGS: " << coordinates << "\n";
const ElemType objective = function.Evaluate(coordinates);
@@ -142,7 +148,7 @@ AugLagrangian::Optimize(
// Check if we are done with the entire optimization (the threshold we are
// comparing with is arbitrary).
if (std::abs(lastObjective - objective) < 1e-10 &&
if (std::abs(lastObjective - objective) < tolerance &&
augfunc.Sigma() > 500000)
{
lambda = std::move(augfunc.Lambda());
@@ -196,6 +202,13 @@ AugLagrangian::Optimize(
// We multiply sigma by a constant value.
augfunc.Sigma() *= sigmaUpdateFactor;
Info << "Updated sigma to " << augfunc.Sigma() << "." << std::endl;
if (augfunc.Sigma() >= std::numeric_limits<ElemType>::max() / 2.0)
{
Warn << "AugLagrangian::Optimize(): sigma too large for element type; "
<< "terminating." << std::endl;
Callback::EndOptimization(*this, function, coordinates, callbacks...);
return false;
}
}
terminate |= Callback::StepTaken(*this, function, coordinates,
@@ -101,6 +101,12 @@ class BigBatchSGD
const double tolerance = 1e-5,
const bool shuffle = true,
const bool exactObjective = false);
/**
* Clean any memory associated with the BigBatchSGD object.
*/
~BigBatchSGD();
/**
* Optimize the given function using big-batch SGD. The given starting point
* will be modified to store the finishing point of the algorithm, and the
@@ -38,6 +38,12 @@ BigBatchSGD<UpdatePolicyType>::BigBatchSGD(
updatePolicy(UpdatePolicyType())
{ /* Nothing to do. */ }
template<typename UpdatePolicyType>
BigBatchSGD<UpdatePolicyType>::~BigBatchSGD()
{
instUpdatePolicy.Clean();
}
//! Optimize the function (minimize).
template<typename UpdatePolicyType>
template<typename SeparableFunctionType,
+116 -1
View File
@@ -257,6 +257,7 @@ class Callback
{
// This will return immediately once a callback returns true.
bool result = false;
(void)(objective); // prevent spurious compiler warnings
(void)std::initializer_list<bool>{ result =
result || Callback::EvaluateFunction(callbacks, optimizer, function,
coordinates, objective)... };
@@ -332,6 +333,8 @@ class Callback
{
// This will return immediately once a callback returns true.
bool result = false;
(void)(constraint); // prevent spurious compiler warnings
(void)(constraintValue);
(void)std::initializer_list<bool>{ result =
result || Callback::EvaluateConstraintFunction(callbacks, optimizer,
function, coordinates, constraint, constraintValue)... };
@@ -478,6 +481,7 @@ class Callback
{
// This will return immediately once a callback returns true.
bool result = false;
(void)(constraint); // prevent spurious compiler warnings
(void)std::initializer_list<bool>{ result =
result || Callback::GradientConstraintFunction(callbacks, optimizer,
function, coordinates, constraint, gradient)... };
@@ -509,6 +513,7 @@ class Callback
{
// This will return immediately once a callback returns true.
bool result = false;
(void)(objective); // prevent spurious compiler warnings
(void)std::initializer_list<bool>{ result =
result || Callback::EvaluateFunction(callbacks, optimizer, function,
coordinates, objective)... };
@@ -584,6 +589,8 @@ class Callback
{
// This will return immediately once a callback returns true.
bool result = false;
(void)(epoch); // prevent spurious compiler warnings
(void)(objective);
(void)std::initializer_list<bool>{ result =
result || Callback::BeginEpochFunction(callbacks, optimizer, function,
coordinates, epoch, objective)... };
@@ -672,6 +679,8 @@ class Callback
{
// This will return immediately once a callback returns true.
bool result = false;
(void)(epoch); // prevent spurious compiler warnings
(void)(objective);
(void)std::initializer_list<bool>{ result =
result || Callback::EndEpochFunction(callbacks, optimizer, function,
coordinates, epoch, objective)... };
@@ -735,6 +744,79 @@ class Callback
MatType& /* coordinates */)
{ return false; }
/**
* Invoke the GenerationalStepTaken() callback if it exists.
* Specialization for MultiObjective case.
*
* @param callback The callback to call.
* @param optimizer The optimizer used to update the function.
* @param function Function to optimize.
* @param coordinates Starting point.
* @param objectives The set of calculated objectives so far.
* @param frontIndices The indices of the members belonging to Pareto Front.
*/
template<typename CallbackType,
typename OptimizerType,
typename FunctionType,
typename MatType,
typename ObjectivesVecType,
typename IndicesType>
static typename std::enable_if<
callbacks::traits::HasGenerationalStepTakenSignature<
CallbackType, OptimizerType, FunctionType, MatType, ObjectivesVecType,
IndicesType>::hasBool, bool>::type
GenerationalStepTakenFunction(CallbackType& callback,
OptimizerType& optimizer,
FunctionType& function,
MatType& coordinates,
ObjectivesVecType& objectives,
IndicesType& frontIndices)
{
return const_cast<CallbackType&>(callback).GenerationalStepTaken(
optimizer, function, coordinates, objectives, frontIndices);
}
template<typename CallbackType,
typename OptimizerType,
typename FunctionType,
typename MatType,
typename ObjectivesVecType,
typename IndicesType>
static typename std::enable_if<
callbacks::traits::HasGenerationalStepTakenSignature<
CallbackType, OptimizerType, FunctionType, MatType, ObjectivesVecType,
IndicesType>::hasVoid, bool>::type
GenerationalStepTakenFunction(CallbackType& callback,
OptimizerType& optimizer,
FunctionType& function,
MatType& coordinates,
ObjectivesVecType& objectives,
IndicesType& frontIndices)
{
const_cast<CallbackType&>(callback).GenerationalStepTaken(
optimizer, function, coordinates, objectives, frontIndices);
return false;
}
template<typename CallbackType,
typename OptimizerType,
typename FunctionType,
typename MatType,
typename ObjectivesVecType,
typename IndicesType>
static typename std::enable_if<
callbacks::traits::HasGenerationalStepTakenSignature<
CallbackType, OptimizerType, FunctionType, MatType, ObjectivesVecType,
IndicesType>::hasNone, bool>::type
GenerationalStepTakenFunction(CallbackType& /* callback */,
OptimizerType& /* optimizer */,
FunctionType& /* function */,
MatType& /* coordinates */,
ObjectivesVecType& /* objectives */,
IndicesType& /* frontIndices */)
{ return false; }
/**
* Iterate over the callbacks and invoke the StepTaken() callback if it
* exists.
@@ -760,8 +842,41 @@ class Callback
function, coordinates)... };
return result;
}
};
/**
* Iterate over the callbacks and invoke the GenerationalStepTaken() callback if it
* exists.
*
* Specialization for MultiObjective case.
*
* @param optimizer The optimizer used to update the function.
* @param function Function to optimize.
* @param coordinates Starting point.
* @param objectives The set of calculated objectives so far.
* @param frontIndices The indices of the members belonging to Pareto Front.
* @param callbacks The callbacks container.
*/
template<typename OptimizerType,
typename FunctionType,
typename ObjectivesVecType,
typename IndicesType,
typename MatType,
typename ...CallbackTypes>
static bool GenerationalStepTaken(OptimizerType& optimizer,
FunctionType& functions,
MatType& coordinates,
ObjectivesVecType& objectives,
IndicesType& frontIndices,
CallbackTypes&... callbacks)
{
// This will return immediately once a callback returns true.
bool result = false;
(void)std::initializer_list<bool>{ result =
result || Callback::GenerationalStepTakenFunction(callbacks, optimizer,
functions, coordinates, objectives, frontIndices)... };
return result;
}
};
} // namespace ens
#endif
@@ -1,6 +1,7 @@
/**
* @file early_stop_at_min_loss.hpp
* @author Marcus Edel
* @author Omar Shrit
*
* Implementation of the early stop at minimum loss callback function.
*
@@ -12,13 +13,16 @@
#ifndef ENSMALLEN_CALLBACKS_EARLY_STOP_AT_MIN_LOSS_HPP
#define ENSMALLEN_CALLBACKS_EARLY_STOP_AT_MIN_LOSS_HPP
#include <functional>
namespace ens {
/**
* Early stopping to terminate the optimization process early if the loss stops
* decreasing.
*/
class EarlyStopAtMinLoss
template<typename MatType = arma::mat>
class EarlyStopAtMinLossType
{
public:
/**
@@ -28,12 +32,33 @@ class EarlyStopAtMinLoss
* @param patienceIn The number of epochs to wait after the minimum loss has
* been reached or no improvement has been made (Default: 10).
*/
EarlyStopAtMinLoss(const size_t patienceIn = 10) :
patience(patienceIn),
EarlyStopAtMinLossType(const size_t patienceIn = 10) :
callbackUsed(false),
patience(patienceIn),
bestObjective(std::numeric_limits<double>::max()),
steps(0)
{ /* Nothing to do here */ }
/**
* Set up the early stop at min loss class, which keeps track of the minimum
* loss and stops the optimization process if the loss stops decreasing.
*
* @param func, callback to return immediate loss evaluated by the function
* @param patienceIn The number of epochs to wait after the minimum loss has
* been reached or no improvement has been made (Default: 10).
*/
EarlyStopAtMinLossType(
std::function<double(const MatType&)> func,
const size_t patienceIn = 10)
: callbackUsed(true),
patience(patienceIn),
bestObjective(std::numeric_limits<double>::max()),
steps(0),
localFunc(func)
{
// Nothing to do here
}
/**
* Callback function called at the end of a pass over the data.
*
@@ -43,13 +68,18 @@ class EarlyStopAtMinLoss
* @param epoch The index of the current epoch.
* @param objective Objective value of the current point.
*/
template<typename OptimizerType, typename FunctionType, typename MatType>
template<typename OptimizerType, typename FunctionType>
bool EndEpoch(OptimizerType& /* optimizer */,
FunctionType& /* function */,
const MatType& /* coordinates */,
const MatType& coordinates,
const size_t /* epoch */,
const double objective)
double objective)
{
if (callbackUsed)
{
objective = localFunc(coordinates);
}
if (objective < bestObjective)
{
steps = 0;
@@ -68,6 +98,9 @@ class EarlyStopAtMinLoss
}
private:
//! False if the first constructor is called, true if the user passed a lambda.
bool callbackUsed;
//! The number of epochs to wait before terminating the optimization process.
size_t patience;
@@ -76,8 +109,19 @@ class EarlyStopAtMinLoss
//! Locally-stored number of steps since the loss improved.
size_t steps;
//! Function to call at the end of the epoch.
std::function<double(const MatType&)> localFunc;
};
/*
* Note that the using definition is temporary, this definition should
* be removed when releasing ensmallen 3.0
* The renaming of the class is only to avoid a major version bump
* because if the template type added to this class
*/
using EarlyStopAtMinLoss = EarlyStopAtMinLossType<arma::mat>;
} // namespace ens
#endif
@@ -0,0 +1,60 @@
/**
* @file grad_clip_by_norm.hpp
* @author Marcus Edel
*
* Clip the gradients by multiplying the unit vector of the gradients with the
* threshold.
*
* ensmallen is free software; you may redistribute it and/or modify it under
* the terms of the 3-clause BSD license. You should have received a copy of
* the 3-clause BSD license along with ensmallen. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef ENSMALLEN_CALLBACKS_GRAD_CLIP_BY_NORM_HPP
#define ENSMALLEN_CALLBACKS_GRAD_CLIP_BY_NORM_HPP
namespace ens {
/**
* Clip the gradients by multiplying the unit vector of the gradients with the
* threshold.
*/
class GradClipByNorm
{
public:
/**
* Set up the gradient clip by norm callback class with the maximum clipping
* value.
*
* @param maxNorm The maximum clipping value.
*/
GradClipByNorm(const double maxNorm) : maxNorm(maxNorm)
{ /* Nothing to do here. */ }
/**
* Callback function called at any call to Gradient().
*
* @param optimizer The optimizer used to update the function.
* @param function Function to optimize.
* @param coordinates Starting point.
* @param gradient Matrix that holds the gradient.
*/
template<typename OptimizerType, typename FunctionType, typename MatType>
void Gradient(OptimizerType& /* optimizer */,
FunctionType& /* function */,
const MatType& /* coordinates */,
MatType& gradient)
{
const double gradientNorm = arma::norm(gradient);
if (gradientNorm > maxNorm)
gradient = maxNorm * gradient / gradientNorm;
}
private:
//! The maximum clipping value for gradient clipping.
const double maxNorm;
};
} // namespace ens
#endif
@@ -0,0 +1,60 @@
/**
* @file grad_clip_by_value.hpp
* @author Marcus Edel
*
* Clips the gradient to a specified min and max.
*
* ensmallen is free software; you may redistribute it and/or modify it under
* the terms of the 3-clause BSD license. You should have received a copy of
* the 3-clause BSD license along with ensmallen. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef ENSMALLEN_CALLBACKS_GRAD_CLIP_BY_VALUE_HPP
#define ENSMALLEN_CALLBACKS_GRAD_CLIP_BY_VALUE_HPP
namespace ens {
/**
* Clip the gradient to a specified min and max.
*/
class GradClipByValue
{
public:
/**
* Set up the gradient clip by value callback class with the min and max
* value.
*
* @param min The minimum value to clip to.
* @param max The maximum value to clip to.
*/
GradClipByValue(const double min, const double max) : lower(min), upper(max)
{ /* Nothing to do here. */ }
/**
* Callback function called at any call to Gradient().
*
* @param optimizer The optimizer used to update the function.
* @param function Function to optimize.
* @param coordinates Starting point.
* @param gradient Matrix that holds the gradient.
*/
template<typename OptimizerType, typename FunctionType, typename MatType>
void Gradient(OptimizerType& /* optimizer */,
FunctionType& /* function */,
const MatType& /* coordinates */,
MatType& gradient)
{
gradient = arma::clamp(gradient, lower, upper);
}
private:
//! The minimum value to clip to.
const double lower;
//! The maximum value to clip to.
const double upper;
};
} // namespace ens
#endif
View File
+20 -22
View File
@@ -12,6 +12,8 @@
#ifndef ENSMALLEN_CALLBACKS_PROGRESS_BAR_HPP
#define ENSMALLEN_CALLBACKS_PROGRESS_BAR_HPP
#include <ensmallen_bits/function.hpp>
namespace ens {
/**
@@ -54,21 +56,21 @@ class ProgressBar
FunctionType& function,
MatType& /* coordinates */)
{
static_assert(callbacks::traits::HasBatchSizeSignature<
static_assert(traits::HasBatchSizeSignature<
OptimizerType>::value,
"The OptimizerType does not have a correct definition of BatchSize(). "
"Please check that the OptimizerType fully satisfies the requirements "
"of the ProgressBar API; see the callbacks documentation for more "
"details.");
static_assert(callbacks::traits::HasMaxIterationsSignature<
static_assert(traits::HasMaxIterationsSignature<
OptimizerType>::value,
"The OptimizerType does not have a correct definition of MaxIterations()."
" Please check that the OptimizerType fully satisfies the requirements "
"of the ProgressBar API; see the callbacks documentation for more "
"details.");
static_assert(callbacks::traits::HasNumFunctionsSignature<
static_assert(traits::HasNumFunctionsSignature<
FunctionType>::value,
"The OptimizerType does not have a correct definition of NumFunctions(). "
"Please check that the OptimizerType fully satisfies the requirements "
@@ -79,17 +81,9 @@ class ProgressBar
if (function.NumFunctions() % optimizer.BatchSize() > 0)
epochSize++;
if (!optimizer.MaxIterations())
{
Warn << "Maximum number of iterations not defined (no limit),"
<< " no progress bar shown." << std::endl;
}
else
{
epochs = optimizer.MaxIterations() / epochSize;
if (optimizer.MaxIterations() % epochSize > 0)
epochs++;
}
epochs = optimizer.MaxIterations() / function.NumFunctions();
if (optimizer.MaxIterations() % function.NumFunctions() > 0)
epochs++;
stepTimer.tic();
}
@@ -136,8 +130,12 @@ class ProgressBar
{
if (newEpoch)
{
output << "Epoch " << epoch << "/" << epochs << "\n";
output.flush();
output << "Epoch " << epoch;
if (epochs > 0)
{
output << "/" << epochs;
}
output << '\n';
newEpoch = false;
}
@@ -159,8 +157,8 @@ class ProgressBar
}
}
output << "] " << progress << "% - ETA: " << (size_t) stepTimer.toc() *
(epochSize - step + 1) % 60 << "s - loss: " <<
output << "] " << progress << "% - ETA: " << (size_t) (stepTimer.toc() *
(epochSize - step + 1)) % 60 << "s - loss: " <<
objective / (double) step << "\r";
output.flush();
@@ -218,10 +216,10 @@ class ProgressBar
output << ".";
}
}
const size_t stepTime = epochTimer.toc() / (double) epochSize * 1000;
output << "] " << progress << "% - " << (size_t) epochTimer.toc() % 60
<< "s " << stepTime << "ms/step " << "- loss: " << objective << "\n";
const double epochTimerElapsed = epochTimer.toc();
const size_t stepTime = epochTimerElapsed / (double) epochSize * 1000;
output << "] " << progress << "% - " << epochTimerElapsed
<< "s/epoch; " << stepTime << "ms/step; loss: " << objective << "\n";
output.flush();
}
@@ -0,0 +1,85 @@
/**
* @file query_front.hpp
* @author Nanubala Gnana Sai
*
* Implementation of the query front callback function.
*
* ensmallen is free software; you may redistribute it and/or modify it under
* the terms of the 3-clause BSD license. You should have received a copy of
* the 3-clause BSD license along with ensmallen. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef ENSMALLEN_CALLBACKS_QUERY_FRONT_HPP
#define ENSMALLEN_CALLBACKS_QUERY_FRONT_HPP
namespace ens {
/**
* Query the current Pareto Front after every GenerationalStepTaken callback function.
*/
class QueryFront
{
public:
/**
* Set up the query front callback class with the specified inputs.
*
* @param queryRate The frequency at which the Pareto Front is queried.
* @param paretoFrontArray A reference to a vector of cube to store the queried fronts.
*/
QueryFront(const size_t queryRate, std::vector<arma::cube>& paretoFrontArray) :
queryRate(queryRate),
paretoFrontArray(paretoFrontArray),
genCounter(0)
{ /* Nothing to do here */ }
/**
* Callback function called at the end of a single generational run.
*
* @param optimizer The optimizer used to update the function.
* @param function Function to optimize.
* @param coordinates Starting point.
* @param objectives The set of calculated objectives so far.
* @param frontIndices The indices of the members belonging to Pareto Front.
*/
template<typename OptimizerType,
typename FunctionType,
typename MatType,
typename ObjectivesVecType,
typename IndicesType>
void GenerationalStepTaken(OptimizerType& opt,
FunctionType& /* function */,
const MatType& /* coordinates */,
const ObjectivesVecType& objectives,
const IndicesType& frontIndices)
{
arma::cube currentParetoFront{};
if (genCounter % queryRate == 0)
{
currentParetoFront.resize(objectives[0].n_rows, objectives[0].n_cols,
frontIndices[0].size());
for (size_t solutionIdx = 0; solutionIdx < frontIndices[0].size(); ++solutionIdx)
{
currentParetoFront.slice(solutionIdx) =
arma::conv_to<arma::mat>::from(objectives[frontIndices[0][solutionIdx]]);
}
paretoFrontArray.emplace_back(std::move(currentParetoFront));
}
++genCounter;
}
private:
//! The rate of query.
size_t queryRate;
//! A reference to the array of pareto fronts.
std::vector<arma::cube>& paretoFrontArray;
//! A counter for the current generation.
size_t genCounter;
};
} // namespace ens
#endif
+613
View File
@@ -0,0 +1,613 @@
/**
* @file report.hpp
* @author Marcus Edel
*
* Implementation of a simple report callback function.
*
* ensmallen is free software; you may redistribute it and/or modify it under
* the terms of the 3-clause BSD license. You should have received a copy of
* the 3-clause BSD license along with ensmallen. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef ENSMALLEN_CALLBACKS_REPORT_HPP
#define ENSMALLEN_CALLBACKS_REPORT_HPP
#include <ensmallen_bits/function.hpp>
#include <iomanip>
namespace ens {
/**
* A simple optimization report.
*/
class Report
{
public:
/**
* Set up the report callback class with the given output stream.
*
* @param iterationsPercentageIn The number of iterations to report in
* percent, between [0, 1]).
* @param outputIn Ostream which receives output from this object.
* @param outputMatrixSizeIn The number of values to output for the function
* coordinates.
*/
Report(const double iterationsPercentageIn = 0.1,
std::ostream& outputIn = arma::get_cout_stream(),
const size_t outputMatrixSizeIn = 4) :
iterationsPercentage(iterationsPercentageIn),
output(outputIn),
outputMatrixSize(outputMatrixSizeIn),
objective(0),
gradientNorm(0),
hasGradient(false),
hasEndEpoch(false),
gradientCalls(0),
evaluateCalls(0),
epochCalls(0)
{ /* Nothing to do here. */ }
/**
* Callback function called at the begin of the optimization process.
*
* @param optimizer The optimizer used to update the function.
* @param function Function to optimize.
* @param coordinates Starting point.
*/
template<typename OptimizerType, typename FunctionType, typename MatType>
void BeginOptimization(OptimizerType& /* optimizer */,
FunctionType& /* function */,
MatType& coordinates)
{
initialCoordinates = coordinates;
optimizationTimer.tic();
}
/**
* Callback function called at the begin of the optimization process.
*
* @param optimizer The optimizer used to update the function.
* @param function Function to optimize.
* @param coordinates Starting point.
*/
template<typename OptimizerType, typename FunctionType, typename MatType>
void EndOptimization(OptimizerType& optimizer,
FunctionType& function,
MatType& coordinates)
{
output << "Optimization Report" << std::endl;
output << std::string(80, '-') << std::endl << std::endl;
std::streamsize streamPrecision = output.precision(4);
if (coordinates.n_rows > outputMatrixSize ||
coordinates.n_cols > outputMatrixSize)
{
output << "Initial coordinates: " << std::endl;
TruncatePrint(initialCoordinates, outputMatrixSize);
output << std::endl << "Final coordinates: " << std::endl;
TruncatePrint(coordinates, outputMatrixSize);
}
else
{
output << "Initial Coordinates:" << std::endl << initialCoordinates.t();
output << std::endl << "Final coordinates:" << std::endl
<< coordinates.t() << std::endl;
}
PrettyPrintElement("iter");
PrettyPrintElement("loss");
PrettyPrintElement("loss change");
if (hasGradient)
PrettyPrintElement("|gradient|");
if (!stepsizes.empty())
PrettyPrintElement("step size");
PrettyPrintElement("total time");
output << std::endl;
size_t iterationStep = objectives.size() / (iterationsPercentage * 100);
if (iterationStep <= 0)
iterationStep = 1;
for (size_t i = 0; i < objectives.size(); i += iterationStep)
{
PrettyPrintElement(i);
PrettyPrintElement(objectives[i]);
PrettyPrintElement(
i > 0 ? objectives[i - iterationStep] - objectives[i] : 0);
if (hasGradient)
PrettyPrintElement(gradientsNorm[i]);
if (!stepsizes.empty())
PrettyPrintElement(stepsizes[i]);
PrettyPrintElement(timings[i]);
output << std::endl;
}
output << std::endl << std::string(80, '-') << std::endl << std::endl;
output << "Version:" << std::endl;
PrettyPrintElement("ensmallen:", 30);
output << ens::version::as_string() << std::endl;
PrettyPrintElement("armadillo:", 30);
output << arma::arma_version::as_string() << std::endl << std::endl;
output << "Function:" << std::endl;
std::stringstream functionStream;
PrintNumFunctions(function, functionStream);
if (functionStream.rdbuf()->in_avail() > 0)
output << functionStream.str();
PrettyPrintElement("Coordinates rows:", 30);
output << coordinates.n_rows << std::endl;
PrettyPrintElement("Coordinates columns:", 30);
output << coordinates.n_cols << std::endl;
output << std::endl;
// If we did not take any steps, at least fill what the initial objective
// was.
const bool tookStep = (objectives.size() > 0);
if (objectives.size() == 0 && evaluateCalls > 0)
{
objectives.push_back(objective);
timings.push_back(optimizationTimer.toc());
}
else if (evaluateCalls == 0)
{
// It's not entirely clear how to compute the objective (since the
// function could implement many different ways of evaluating the
// objective), so issue an error and return.
output << "Objective never computed. Did the optimization fail?"
<< std::endl;
PrettyPrintElement("Time (in seconds):", 30);
output << optimizationTimer.toc() << std::endl;
return;
}
output << "Loss:" << std::endl;
PrettyPrintElement("Initial", 30);
output << objectives[0] << std::endl;
PrettyPrintElement("Final", 30);
output << objectives[objectives.size() - 1] << std::endl;
PrettyPrintElement("Change", 30);
output << objectives[0] - objectives[objectives.size() - 1] << std::endl;
output << std::endl << "Optimizer:" << std::endl;
std::stringstream optimizerStream;
PrintMaxIterations(optimizer, optimizerStream);
PrintBatchSize(optimizer, optimizerStream);
if (functionStream.rdbuf()->in_avail() > 0)
output << optimizerStream.str();
PrettyPrintElement("Iterations:", 30);
if (tookStep)
output << objectives.size() << std::endl;
else
output << "0 (No steps taken! Did the optimization fail?)" << std::endl;
if (epochCalls > 0)
{
PrettyPrintElement("Number of epochs:", 30);
output << epochCalls << std::endl;
}
if (!stepsizes.empty())
{
PrettyPrintElement("Initial step size:", 30);
output << stepsizes.front() << std::endl;
PrettyPrintElement("Final step size:", 30);
output << stepsizes.back() << std::endl;
}
if (hasGradient && gradientsNorm.size() > 0)
{
PrettyPrintElement("Coordinates max. norm:", 30);
output << *std::max_element(std::begin(gradientsNorm),
std::end(gradientsNorm)) << std::endl;
}
PrettyPrintElement("Evaluate calls:", 30);
output << evaluateCalls << std::endl;
if (hasGradient)
{
PrettyPrintElement("Gradient calls:", 30);
output << gradientCalls << std::endl;
}
PrettyPrintElement("Time (in seconds):", 30);
output << timings[timings.size() - 1] << std::endl;
// Restore precision.
output.precision(streamPrecision);
}
/**
* Callback function called at the beginning of a pass over the data.
*
* @param optimizer The optimizer used to update the function.
* @param function Function to optimize.
* @param coordinates Starting point.
* @param epoch The index of the current epoch.
* @param objective Objective value of the current point.
*/
template<typename OptimizerType, typename FunctionType, typename MatType>
void BeginEpoch(OptimizerType& /* optimizer */,
FunctionType& /* function */,
const MatType& /* coordinates */,
const size_t /* epoch */,
const double /* objective */)
{
epochCalls++;
}
/**
* Callback function called at the end of a pass over the data.
*
* @param optimizer The optimizer used to update the function.
* @param function Function to optimize.
* @param coordinates Starting point.
* @param epoch The index of the current epoch.
* @param objective Objective value of the current point.
*/
template<typename OptimizerType, typename FunctionType, typename MatType>
void EndEpoch(OptimizerType& optimizer,
FunctionType& /* function */,
const MatType& /* coordinates */,
const size_t /* epoch */,
const double objective)
{
// In case StepTaken() has been called first we clear the existing data.
if (!hasEndEpoch)
{
hasEndEpoch = true;
objectives.clear();
timings.clear();
gradientsNorm.clear();
stepsizes.clear();
}
objectives.push_back(objective);
timings.push_back(optimizationTimer.toc());
if (hasGradient)
gradientsNorm.push_back(gradientNorm);
SaveStepSize(optimizer);
}
/**
* Callback function called once a step is taken.
*
* @param optimizer The optimizer used to update the function.
* @param function Function to optimize.
* @param coordinates Starting point.
* @param objective Objective value of the current point.
*/
template<typename OptimizerType, typename FunctionType, typename MatType>
void StepTaken(OptimizerType& optimizer,
FunctionType& /* function */,
const MatType& /* coordinates */)
{
if (!hasEndEpoch)
{
objectives.push_back(objective);
timings.push_back(optimizationTimer.toc());
if (hasGradient)
gradientsNorm.push_back(gradientNorm);
SaveStepSize(optimizer);
}
}
/**
* Callback function called at any call to Evaluate().
*
* @param optimizer The optimizer used to update the function.
* @param function Function to optimize.
* @param coordinates Starting point.
* @param objectiveIn Objective value of the current point.
*/
template<typename OptimizerType, typename FunctionType, typename MatType>
void Evaluate(OptimizerType& /* optimizer */,
FunctionType& /* function */,
const MatType& /* coordinates */,
const double objectiveIn)
{
objective = objectiveIn;
evaluateCalls++;
}
/**
* Callback function called at any call to EvaluateConstraint().
*
* @param optimizer The optimizer used to update the function.
* @param function Function to optimize.
* @param coordinates Starting point.
* @param constraint The index of the constraint;
* @param objectiveIn Objective value of the current point.
*/
template<typename OptimizerType, typename FunctionType, typename MatType>
void EvaluateConstraint(OptimizerType& /* optimizer */,
FunctionType& /* function */,
const MatType& /* coordinates */,
const size_t /* constraint */,
const double objectiveIn)
{
objective += objectiveIn;
evaluateCalls++;
}
/**
* Callback function called at any call to Gradient().
*
* @param optimizer The optimizer used to update the function.
* @param function Function to optimize.
* @param coordinates Starting point.
* @param gradientIn Matrix that holds the gradient.
*/
template<typename OptimizerType, typename FunctionType, typename MatType>
void Gradient(OptimizerType& /* optimizer */,
FunctionType& /* function */,
const MatType& /* coordinates */,
const MatType& gradientIn)
{
hasGradient = true;
gradientNorm = arma::norm(gradientIn);
gradientCalls++;
}
/**
* Callback function called at any call to GradientConstraint().
*
* @param optimizer The optimizer used to update the function.
* @param function Function to optimize.
* @param coordinates Starting point.
* @param constraint The index of the constraint;
* @param gradient Matrix that holds the gradient;
*/
template<typename OptimizerType, typename FunctionType, typename MatType>
void GradientConstraint(OptimizerType& optimizer,
FunctionType& function,
const MatType& coordinates,
const size_t /* constraint */,
const MatType& gradient)
{
Gradient(optimizer, function, coordinates, gradient);
}
private:
/**
* Helper function to print the number of function to the specified output
* stream.
*
* @param function The instantiated function that implements NumFunctions().
* @param stream The output stream.
*/
template<typename FunctionType>
typename std::enable_if<
traits::HasNumFunctionsSignature<FunctionType>::value, void>::type
PrintNumFunctions(const FunctionType& function, std::stringstream& stream)
{
PrettyPrintElement(stream, "Number of functions:", 30);
stream << function.NumFunctions() << std::endl;
}
template<typename FunctionType>
typename std::enable_if<
!traits::HasNumFunctionsSignature<FunctionType>::value, void>::type
PrintNumFunctions(const FunctionType& /* function */,
std::stringstream& /* stream */) { }
/**
* Helper function to output the max-iterations to the specified output
* stream.
*
* @param optimizer The instantiated optimizer that implements
* MaxIterations().
* @param stream The output stream.
*/
template<typename OptimizerType>
typename std::enable_if<
traits::HasMaxIterationsSignature<OptimizerType>::value, void>::type
PrintMaxIterations(const OptimizerType& optimizer, std::stringstream& stream)
{
PrettyPrintElement(stream, "Maximum iterations:", 30);
stream << optimizer.MaxIterations() << std::endl;
PrettyPrintElement(stream, "Reached maximum iterations:", 30);
stream << std::string(optimizer.MaxIterations() == objectives.size() ?
"true" : "false") << std::endl;
}
template<typename OptimizerType>
typename std::enable_if<
!traits::HasMaxIterationsSignature<OptimizerType>::value, void>::type
PrintMaxIterations(const OptimizerType& /* optimizer */,
std::stringstream& /* stream */) { }
/**
* Helper function to output the batch-size to the specified output stream.
*
* @param optimizer The instantiated optimizer that implements BatchSize().
* @param stream The output stream.
*/
template<typename OptimizerType>
typename std::enable_if<traits::HasBatchSizeSignature<OptimizerType>::value,
void>::type
PrintBatchSize(const OptimizerType& optimizer, std::stringstream& stream)
{
PrettyPrintElement(stream, "Batch size:", 30);
stream << optimizer.BatchSize() << std::endl;
}
template<typename OptimizerType>
typename std::enable_if<!traits::HasBatchSizeSignature<OptimizerType>::value,
void>::type
PrintBatchSize(const OptimizerType& /* optimizer */,
std::stringstream& /* stream */) { }
/**
* Output formatted data.
*
* @param out Output stream.
* @param data The data to print on the given stream.
* @param width The width of the the formatted output data.
*/
template<typename T>
void PrettyPrintElement(std::ostream& out,
const T& data,
const size_t width = 14)
{
out << std::left << std::setw(width) << std::setfill(' ')
<< std::setprecision(3) << data;
}
/**
* Output formatted data.
*
* @param data The data to print on the given stream.
* @param width The width of the the formatted output data.
*/
template<typename T>
void PrettyPrintElement(const T& data, const size_t width = 14)
{
PrettyPrintElement(output, data, width);
}
/**
* Outputs the given matrix in a truncated format. For example, the matrix:
*
* 1 2 3 4 5
* 6 7 8 9 10
* 11 12 13 14
* 15 16 17 18
*
* will be truncated to:
*
* 1 2 ... 5
* 6 7 ... 10
* ...
* 15 16 ... 18
*
* @param data The data to print on the given stream in a truncated format.
* @param size The number of elements per column/row.
*/
template<typename T>
void TruncatePrint(const T& data, const size_t size)
{
// We can't directly output the result of submat or use .print, because
// both introduce a new line at the end, so we iterate over the elements.
for (size_t c = 0, n = 0; c < data.n_cols; ++c)
{
// Skip to the last column.
if (c >= (size - 1))
{
output << "..." << std::endl;
n = (data.n_cols - 2) * data.n_rows - 1;
}
for (size_t r = 0; r < data.n_rows; ++r)
{
// Check if need to skip to the last row.
if (r < (size - 1))
{
output << std::fixed;
// Add space for positive value, to align with negative values.
if (data(n) >= 0)
output << " ";
output << data(n++) << " ";
}
else
{
n = (c + 1) * data.n_rows - 1;
output << " ... " << data(n) << std::endl;
break;
}
}
if (c >= (size - 1))
break;
}
}
/**
* Helper function to store the step-size.
*
* @param optimizer The instantiated optimzer that implements StepSize().
*/
template<typename OptimizerType>
typename std::enable_if<traits::HasStepSizeSignature<OptimizerType>::value,
void>::type
SaveStepSize(const OptimizerType& optimizer)
{
stepsizes.push_back(optimizer.StepSize());
}
template<typename OptimizerType>
typename std::enable_if<!traits::HasStepSizeSignature<OptimizerType>::value,
void>::type
SaveStepSize(const OptimizerType& /* optimizer */) { }
//! The number of iterations to print in percent.
double iterationsPercentage;
//! The output stream that all data is to be sent to; example: std::cout.
std::ostream& output;
//! The number of values to print for the function coordinates.
size_t outputMatrixSize;
//! The initial coordinates.
arma::mat initialCoordinates;
//! Gradient norm storage.
std::vector<double> gradientsNorm;
//! Objective storage.
std::vector<double> objectives;
//! Timing storage.
std::vector<double> timings;
//! Step-size storage.
std::vector<double> stepsizes;
//! Objective over the current epoch.
double objective;
//! Locally-stored gradient norm for a single step.
double gradientNorm;
//! Whether Gradient() was called.
bool hasGradient;
//! Whether EndEpoch() was called.
bool hasEndEpoch;
//! The number of Gradient() calls.
size_t gradientCalls;
//! The number of Evaluate() calls.
size_t evaluateCalls;
//! The number of BeginEpoch() calls.
size_t epochCalls;
//! Locally-stored optimization step timer object.
arma::wall_clock optimizationTimer;
};
} // namespace ens
#endif
+1 -1
View File
@@ -55,7 +55,7 @@ class StoreBestCoordinates
//! Get the best coordinates.
ModelMatType const& BestCoordinates() const { return bestCoordinates; }
//! Modify the best coordinates.
ModelMatType& BestCoordinatesl() { return bestCoordinates; }
ModelMatType& BestCoordinates() { return bestCoordinates; }
//! Get the best objective.
double const& BestObjective() const { return bestObjective; }
View File
+108 -43
View File
@@ -37,12 +37,8 @@ ENS_HAS_EXACT_METHOD_FORM(BeginEpoch, HasBeginEpoch)
ENS_HAS_EXACT_METHOD_FORM(EndEpoch, HasEndEpoch)
//! Detect an StepTaken() method.
ENS_HAS_EXACT_METHOD_FORM(StepTaken, HasStepTaken)
//! Detect an BatchSize() method.
ENS_HAS_EXACT_METHOD_FORM(BatchSize, HasBatchSize)
//! Detect an MaxIterations() method.
ENS_HAS_EXACT_METHOD_FORM(MaxIterations, HasMaxIterations)
//! Detect an NumFunctions() method.
ENS_HAS_EXACT_METHOD_FORM(NumFunctions, HasNumFunctions)
//! Detect an GenerationalStepTaken() method.
ENS_HAS_EXACT_METHOD_FORM(GenerationalStepTaken, HasGenerationalStepTaken)
template<typename OptimizerType,
typename FunctionType,
@@ -92,6 +88,15 @@ struct TypedForms
const MatType&,
const MatType&);
//! This is the form of a bool Gradient() callback method where the gradient
//! is modifiable.
template<typename CallbackType>
using GradientBoolModifiableForm =
void(CallbackType::*)(OptimizerType&,
FunctionType&,
const MatType&,
MatType&);
//! This is the form of a void Gradient() callback method.
template<typename CallbackType>
using GradientVoidForm =
@@ -100,6 +105,15 @@ struct TypedForms
const MatType&,
const MatType&);
//! This is the form of a void Gradient() callback method where the gradient
//! is modifiable.
template<typename CallbackType>
using GradientVoidModifiableForm =
void(CallbackType::*)(OptimizerType&,
FunctionType&,
const MatType&,
MatType&);
//! This is the form of a bool GradientConstraint() callback method.
template<typename CallbackType>
using GradientConstraintBoolForm =
@@ -109,6 +123,16 @@ struct TypedForms
const size_t,
const MatType&);
//! This is the form of a bool GradientConstraint() callback method where the
//! gradient is modifiable.
template<typename CallbackType>
using GradientConstraintBoolModifiableForm =
void(CallbackType::*)(OptimizerType&,
FunctionType&,
const MatType&,
const size_t,
MatType&);
//! This is the form of a void GradientConstraint() callback method.
template<typename CallbackType>
using GradientConstraintVoidForm =
@@ -118,6 +142,16 @@ struct TypedForms
const size_t,
const MatType&);
//! This is the form of a void GradientConstraint() callback method where the
//! gradient is modifiable.
template<typename CallbackType>
using GradientConstraintVoidModifiableForm =
void(CallbackType::*)(OptimizerType&,
FunctionType&,
const MatType&,
const size_t,
MatType&);
//! This is the form of a bool BeginOptimization() callback method.
template<typename CallbackType>
using BeginOptimizationBoolForm =
@@ -234,9 +268,9 @@ struct HasEvaluateSignature
{
const static bool value =
HasEvaluate<CallbackType, TypedForms<OptimizerType,
FunctionType, MatType>::template EvaluateBoolForm>::value ||
FunctionType, MatType>::template EvaluateBoolForm>::value ||
HasEvaluate<CallbackType, TypedForms<OptimizerType,
FunctionType, MatType>::template EvaluateVoidForm>::value;
FunctionType, MatType>::template EvaluateVoidForm>::value;
};
//! Utility struct, check if either void EvaluateConstraint() or
@@ -249,9 +283,9 @@ struct HasEvaluateConstraintSignature
{
const static bool value =
HasEvaluateConstraint<CallbackType, TypedForms<OptimizerType,
FunctionType, MatType>::template EvaluateConstraintBoolForm>::value ||
FunctionType, MatType>::template EvaluateConstraintBoolForm>::value ||
HasEvaluateConstraint<CallbackType, TypedForms<OptimizerType,
FunctionType, MatType>::template EvaluateConstraintVoidForm>::value;
FunctionType, MatType>::template EvaluateConstraintVoidForm>::value;
};
//! Utility struct, check if either void Gradient() or bool Gradient()
@@ -265,9 +299,15 @@ struct HasGradientSignature
{
const static bool value =
HasGradient<CallbackType, TypedForms<OptimizerType,
FunctionType, MatType, Gradient>::template GradientBoolForm>::value ||
FunctionType, MatType, Gradient>::template GradientBoolForm>::value ||
HasGradient<CallbackType, TypedForms<OptimizerType,
FunctionType, MatType, Gradient>::template GradientVoidForm>::value;
FunctionType, MatType,
Gradient>::template GradientBoolModifiableForm>::value ||
HasGradient<CallbackType, TypedForms<OptimizerType,
FunctionType, MatType, Gradient>::template GradientVoidForm>::value ||
HasGradient<CallbackType, TypedForms<OptimizerType,
FunctionType, MatType,
Gradient>::template GradientVoidModifiableForm>::value;
};
//! Utility struct, check if either void GradientConstraint() or
@@ -371,44 +411,69 @@ struct HasStepTakenSignature
FunctionType, MatType>::template StepTakenVoidForm>::value;
};
//! Utility struct, check if size_t BatchSize() const exists.
template<typename OptimizerType>
struct HasBatchSizeSignature
//! A utility struct for Typed Forms required in
//! callbacks for MultiObjective Optimizers.
template<typename OptimizerType,
typename FunctionType,
typename MatType,
typename ObjectivesVecType,
typename IndicesType,
typename GradType = MatType>
struct MOOTypedForms
{
template<typename C>
using BatchSizeForm = size_t(C::*)(void) const;
//! This is the form of a bool GenerationalStepTaken() for MOO callback method.
template<typename CallbackType>
using GenerationalStepTakenBoolForm =
bool(CallbackType::*)(OptimizerType&,
FunctionType&,
const MatType&,
const ObjectivesVecType&,
const IndicesType&);
const static bool value =
HasBatchSize<OptimizerType, BatchSizeForm>::value;
//! This is the form of a void StepTaken() for MOO callback method.
template<typename CallbackType>
using GenerationalStepTakenVoidForm =
void(CallbackType::*)(OptimizerType&,
FunctionType&,
const MatType&,
const ObjectivesVecType&,
const IndicesType&);
};
//! Utility struct, check if size_t MaxIterations() const exists.
template<typename OptimizerType>
struct HasMaxIterationsSignature
//! Utility struct, check if either void StepTaken() or bool StepTaken() exists.
//! Specialization for Multiobjective case.
template<typename CallbackType,
typename OptimizerType,
typename FunctionType,
typename ObjectivesVecType,
typename IndicesType,
typename MatType>
struct HasGenerationalStepTakenSignature
{
template<typename C>
using HasMaxIterationsForm = size_t(C::*)(void) const;
const static bool hasBool =
HasGenerationalStepTaken<CallbackType, MOOTypedForms<OptimizerType,
FunctionType, MatType, ObjectivesVecType, IndicesType>::
template GenerationalStepTakenBoolForm>::value &&
!HasGenerationalStepTaken<CallbackType, MOOTypedForms<OptimizerType,
FunctionType, MatType, ObjectivesVecType, IndicesType>::
template GenerationalStepTakenVoidForm>::value;
const static bool value =
HasMaxIterations<OptimizerType, HasMaxIterationsForm>::value;
const static bool hasVoid =
!HasGenerationalStepTaken<CallbackType, MOOTypedForms<OptimizerType,
FunctionType, MatType, ObjectivesVecType, IndicesType>::
template GenerationalStepTakenBoolForm>::value &&
HasGenerationalStepTaken<CallbackType, MOOTypedForms<OptimizerType,
FunctionType, MatType, ObjectivesVecType, IndicesType>::
template GenerationalStepTakenVoidForm>::value;
const static bool hasNone =
!HasGenerationalStepTaken<CallbackType, MOOTypedForms<OptimizerType,
FunctionType, MatType, ObjectivesVecType, IndicesType>::
template GenerationalStepTakenBoolForm>::value &&
!HasGenerationalStepTaken<CallbackType, MOOTypedForms<OptimizerType,
FunctionType, MatType, ObjectivesVecType, IndicesType>::
template GenerationalStepTakenVoidForm>::value;
};
//! Utility struct, check if size_t NumFunctions() const or
//! size_t NumFunctions() exists.
template<typename OptimizerType>
struct HasNumFunctionsSignature
{
template<typename C>
using NumFunctionsConstForm = size_t(C::*)(void) const;
template<typename C>
using NumFunctionsForm = size_t(C::*)(void);
const static bool value =
HasNumFunctions<OptimizerType, NumFunctionsForm>::value ||
HasNumFunctions<OptimizerType, NumFunctionsConstForm>::value;
};
} // namespace traits
} // namespace callbacks
} // namespace ens
+2 -2
View File
@@ -97,9 +97,9 @@ class CMAES
MatType& iterate,
CallbackTypes&&... callbacks);
//! Get the step size.
//! Get the population size.
size_t PopulationSize() const { return lambda; }
//! Modify the step size.
//! Modify the population size.
size_t& PopulationSize() { return lambda; }
//! Get the lower bound of decision variables.
+4 -5
View File
@@ -77,7 +77,7 @@ typename MatType::elem_type CMAES<SelectionPolicyType>::Optimize(
const double muEffective = 1 / arma::accu(arma::pow(w, 2));
// Step size control parameters.
BaseMatType sigma(3, 1); // sigma is vector-shaped.
BaseMatType sigma(2, 1); // sigma is vector-shaped.
sigma(0) = 0.3 * (upperBound - lowerBound);
const double cs = (muEffective + 2) / (iterate.n_elem + muEffective + 5);
const double ds = 1 + cs + 2 * std::max(std::sqrt((muEffective - 1) /
@@ -97,7 +97,7 @@ typename MatType::elem_type CMAES<SelectionPolicyType>::Optimize(
muEffective) / (std::pow(iterate.n_elem + 2, 2) +
alphaMu * muEffective / 2));
std::vector<BaseMatType> mPosition(3, BaseMatType(iterate.n_rows,
std::vector<BaseMatType> mPosition(2, BaseMatType(iterate.n_rows,
iterate.n_cols));
mPosition[0] = lowerBound + arma::randu<BaseMatType>(
iterate.n_rows, iterate.n_cols) * (upperBound - lowerBound);
@@ -159,7 +159,7 @@ typename MatType::elem_type CMAES<SelectionPolicyType>::Optimize(
// add a small value and try again.
BaseMatType covLower;
while (!arma::chol(covLower, C[idx0], "lower"))
C[idx0].diag() += 1e-16;
C[idx0].diag() += std::numeric_limits<ElemType>::epsilon();
for (size_t j = 0; j < lambda; ++j)
{
@@ -216,8 +216,7 @@ typename MatType::elem_type CMAES<SelectionPolicyType>::Optimize(
}
const ElemType psNorm = arma::norm(ps[idx1]);
sigma(idx1) = sigma(idx0) * std::pow(
std::exp(cs / ds * psNorm / enn - 1), 0.3);
sigma(idx1) = sigma(idx0) * std::exp(cs / ds * ( psNorm / enn - 1));
// Update covariance matrix.
if ((psNorm / sqrt(1 - std::pow(1 - cs, 2 * i))) < h)
+1 -1
View File
@@ -93,7 +93,7 @@ typename MatType::elem_type CNE::Optimize(ArbitraryFunctionType& function,
std::vector<BaseMatType> population;
for (size_t i = 0 ; i < populationSize; ++i)
{
population.push_back(arma::randu<BaseMatType>(iterate.n_rows,
population.push_back(arma::randn<BaseMatType>(iterate.n_rows,
iterate.n_cols) + iterate);
}
+2
View File
@@ -43,12 +43,14 @@ namespace ens {
*
* For more information, see the following:
*
* @code
* @techreport{storn1995,
* title = {Differential Evolution—a simple and efficient adaptive scheme
* for global optimization over continuous spaces},
* author = {Storn, Rainer and Price, Kenneth},
* year = 1995
* }
* @endcode
*
* DE can optimize arbitrary functions. For more details, see the
* documentation on function types included with this distribution or on the
+15 -3
View File
@@ -15,13 +15,17 @@
#define ENS_VERSION_MAJOR 2
// The minor version is two digits so regular numerical comparisons of versions
// work right. The first minor version of a release is always 10.
#define ENS_VERSION_MINOR 10
#define ENS_VERSION_PATCH 5
#define ENS_VERSION_MINOR 18
#define ENS_VERSION_PATCH 2
// If this is a release candidate, it will be reflected in the version name
// (i.e. the version name will be "RC1", "RC2", etc.). Otherwise the version
// name will typically be a seemingly arbitrary set of words that does not
// contain the capitalized string "RC".
#define ENS_VERSION_NAME "Fried Chicken"
#define ENS_VERSION_NAME "Fairmount Bagel"
// Incorporate the date the version was released.
#define ENS_VERSION_YEAR "2022"
#define ENS_VERSION_MONTH "02"
#define ENS_VERSION_DAY "13"
namespace ens {
@@ -41,6 +45,14 @@ struct version
return ss.str();
}
static inline std::string date()
{
std::stringstream ss;
ss << ENS_VERSION_YEAR << '-' << ENS_VERSION_MONTH << '-' << ENS_VERSION_DAY;
return ss.str();
}
};
} // namespace ens
+4 -3
View File
@@ -31,6 +31,7 @@ namespace ens {
* year = {2016},
* url = {http://arxiv.org/abs/1611.01505}
* }
* @endcode
*
* For Eve to work, a SeparableFunctionType template parameter is required.
* This class must implement the following function:
@@ -88,9 +89,9 @@ class Eve
const bool exactObjective = false);
/**
* Optimize the given function using stochastic gradient descent. The given
* starting point will be modified to store the finishing point of the
* algorithm, and the final objective value is returned.
* Optimize the given function using Eve. The given starting point will be
* modified to store the finishing point of the algorithm, and the final
* objective value is returned.
*
* @tparam SeparableFunctionType Type of the function to be optimized.
* @tparam MatType Type of the parameters matrix.
+2 -1
View File
@@ -105,7 +105,8 @@ class FTML
CallbackTypes&&... callbacks)
{
return optimizer.Optimize<SeparableFunctionType, MatType, GradType,
CallbackTypes...>(function, iterate, callbacks...);
CallbackTypes...>(function, iterate,
std::forward<CallbackTypes>(callbacks)...);
}
//! Forward the MatType as GradType.
@@ -76,6 +76,31 @@ struct MatTypeTraits<arma::SpSubview<eT>>
"or a matrix alias instead!");
};
#if ((ARMA_VERSION_MAJOR >= 10) || \
((ARMA_VERSION_MAJOR == 9) && (ARMA_VERSION_MINOR >= 869)))
// Armadillo 9.869+ has SpSubview_col and SpSubview_row
template<typename eT>
struct MatTypeTraits<arma::SpSubview_col<eT>>
{
static_assert(sizeof(arma::SpSubview_col<eT>) == 0,
"Armadillo subviews cannot be passed to Optimize()! Create a matrix "
"or a matrix alias instead!");
};
template<typename eT>
struct MatTypeTraits<arma::SpSubview_row<eT>>
{
static_assert(sizeof(arma::SpSubview_row<eT>) == 0,
"Armadillo subviews cannot be passed to Optimize()! Create a matrix "
"or a matrix alias instead!");
};
#endif
template<typename eT>
struct MatTypeTraits<arma::Cube<eT>>
{
@@ -387,6 +387,25 @@ inline void CheckArbitraryFunctionTypeAPI()
#endif
}
template<typename FunctionType, typename... RemainingTypes>
typename std::enable_if<(sizeof...(RemainingTypes) > 1), void>::type
CheckArbitraryFunctionTypeAPI()
{
#ifndef ENS_DISABLE_TYPE_CHECKS
constexpr size_t size = sizeof...(RemainingTypes);
using TupleType = typename std::tuple<RemainingTypes...>;
using MatType = typename std::tuple_element<size - 1, TupleType>::type;
static_assert(CheckEvaluate<FunctionType, MatType, MatType>::value,
"One of the provided FunctionType does not have a correct definition of Evaluate(). "
"Please check that the corresponding FunctionType fully satisfies the requirements "
"of the ArbitraryFunctionType API; see the optimizer tutorial for "
"more details.");
CheckArbitraryFunctionTypeAPI<RemainingTypes...>();
#endif
}
/**
* Perform checks for the ResolvableFunctionType API.
*/
@@ -39,6 +39,14 @@ ENS_HAS_EXACT_METHOD_FORM(GradientConstraint, HasGradientConstraint)
ENS_HAS_EXACT_METHOD_FORM(NumFeatures, HasNumFeatures)
//! Detect a PartialGradient() method.
ENS_HAS_EXACT_METHOD_FORM(PartialGradient, HasPartialGradient)
//! Detect an MaxIterations() method.
ENS_HAS_EXACT_METHOD_FORM(MaxIterations, HasMaxIterations)
//! Detect an ResetPolicy() method.
ENS_HAS_EXACT_METHOD_FORM(ResetPolicy, HasResetPolicy)
//! Detect an BatchSize() method.
ENS_HAS_EXACT_METHOD_FORM(BatchSize, HasBatchSize)
//! Detect an StepSize() method.
ENS_HAS_EXACT_METHOD_FORM(StepSize, HasStepSize)
template<typename MatType, typename GradType>
struct TypedForms
@@ -369,6 +377,76 @@ struct HasConstSignatures
const static bool value = HasEitherConstForm && HasAnyFormA && HasAnyFormB;
};
//! Utility struct, check if size_t BatchSize() const or size_t BatchSize()
//! exists.
template<typename OptimizerType>
struct HasBatchSizeSignature
{
template<typename C>
using BatchSizeConstForm = size_t(C::*)(void) const;
template<typename C>
using BatchSizeForm = size_t(C::*)(void);
const static bool value =
HasBatchSize<OptimizerType, BatchSizeForm>::value ||
HasBatchSize<OptimizerType, BatchSizeConstForm>::value;
};
//! Utility struct, check if size_t StepSize() const or size_t StepSize()
//! exists.
template<typename OptimizerType>
struct HasStepSizeSignature
{
template<typename C>
using StepSizeConstForm = double(C::*)(void) const;
template<typename C>
using StepSizeForm = double(C::*)(void);
const static bool value =
HasStepSize<OptimizerType, StepSizeForm>::value ||
HasStepSize<OptimizerType, StepSizeConstForm>::value;
};
//! Utility struct, check if size_t MaxIterations() const exists.
template<typename OptimizerType>
struct HasMaxIterationsSignature
{
template<typename C>
using HasMaxIterationsForm = size_t(C::*)(void) const;
const static bool value =
HasMaxIterations<OptimizerType, HasMaxIterationsForm>::value;
};
//! Utility struct, check if size_t NumFunctions() const or
//! size_t NumFunctions() exists.
template<typename OptimizerType>
struct HasNumFunctionsSignature
{
template<typename C>
using NumFunctionsConstForm = size_t(C::*)(void) const;
template<typename C>
using NumFunctionsForm = size_t(C::*)(void);
const static bool value =
HasNumFunctions<OptimizerType, NumFunctionsForm>::value ||
HasNumFunctions<OptimizerType, NumFunctionsConstForm>::value;
};
//! Utility struct, check if bool ResetPolicy() exists.
template<typename OptimizerType>
struct HasResetPolicySignature
{
template<typename C>
using HasResetPolicyForm = bool&(C::*)(void);
const static bool value =
HasResetPolicy<OptimizerType, HasResetPolicyForm>::value;
};
} // namespace traits
} // namespace ens
@@ -45,7 +45,7 @@ inline void Proximal::ProjectToL1Ball(MatType& v, double tau)
MatType simplexSum = arma::cumsum(simplexSol);
double nu = 0;
size_t rho = 0;
size_t rho = simplexSol.n_rows - 1;
for (size_t j = 1; j <= simplexSol.n_rows; j++)
{
rho = simplexSol.n_rows - j;
+1 -1
View File
@@ -391,7 +391,7 @@ L_BFGS::Optimize(FunctionType& function,
//
// But don't do this on the first iteration to ensure we always take at
// least one descent step.
if (itNum > 0 && (arma::norm(gradient, 2) < minGradientNorm))
if (arma::norm(gradient, 2) < minGradientNorm)
{
Info << "L-BFGS gradient norm too small (terminating successfully)."
<< std::endl;
@@ -0,0 +1,259 @@
/**
* @file lookahead.hpp
* @author Marcus Edel
*
* Lookahead is a stochastic gradient based optimization method which chooses a
* search direction by looking ahead at the sequence of "fast weights" generated
* by another optimizer.
*
* ensmallen is free software; you may redistribute it and/or modify it under
* the terms of the 3-clause BSD license. You should have received a copy of
* the 3-clause BSD license along with ensmallen. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef ENSMALLEN_LOOKAHEAD_LOOKAHEAD_HPP
#define ENSMALLEN_LOOKAHEAD_LOOKAHEAD_HPP
#include <ensmallen_bits/adam/adam.hpp>
#include <ensmallen_bits/sgd/decay_policies/no_decay.hpp>
namespace ens {
/**
* Lookahead is a stochastic gradient based optimization method which chooses a
* search direction by looking ahead at the sequence of "fast weights" generated
* by another optimizer.
*
* For more information, see the following.
*
* @code
* @article{Zhang2019,
* author = {Michael R. Zhang and James Lucas and Geoffrey E. Hinton and
* Jimmy Ba},
* title = {Lookahead Optimizer: k steps forward, 1 step back},
* journal = {CoRR},
* year = {2019},
* url = {http://arxiv.org/abs/1907.08610}
* }
* @endcode
*
* Lookahead can optimize differentiable separable functions. For more details,
* see the documentation on function types included with this distribution or on
* the ensmallen website.
*
* @tparam BaseOptimizerType Optimizer type for the forward step. By default the
* Adam optimizer is used.
* @tparam DecayPolicyType Decay policy used during the iterative update
* process to adjust the step size. By default the step size isn't going to
* be adjusted (i.e. NoDecay is used).
*/
template<typename BaseOptimizerType = Adam, typename DecayPolicyType = NoDecay>
class Lookahead
{
public:
/**
* Construct the Lookahead optimizer with the given function, parameters
* and the default Adam optimizer for the forward step. The defaults here are
* not necessarily good for the given problem, so it is suggested that the
* values used be tailored to the task at hand. The maximum number of
* iterations refers to the maximum number of points that are processed
* (i.e., one iteration equals one point; one iteration does not equal
* one pass over the dataset).
*
* @param stepSize Step size for each iteration.
* @param k The synchronization period.
* @param maxIterations Maximum number of iterations allowed (0 means no
* limit).
* @param tolerance Maximum absolute tolerance to terminate algorithm.
* @param decayPolicy Instantiated decay policy used to adjust the step size.
* @param resetPolicy Flag that determines whether update policy parameters
* are reset before every outer Optimize call.
* @param exactObjective Calculate the exact objective (Default: estimate the
* final objective obtained on the last pass over the data).
*/
Lookahead(const double stepSize = 0.5,
const size_t k = 5,
const size_t maxIterations = 100000,
const double tolerance = 1e-5,
const DecayPolicyType& decayPolicy = DecayPolicyType(),
const bool resetPolicy = false,
const bool exactObjective = false);
/**
* Construct the Lookahead optimizer with the given function and parameters.
* The defaults here are not necessarily good for the given problem, so it is
* suggested that the values used be tailored to the task at hand. The
* maximum number of iterations refers to the maximum number of points that
* are processed (i.e., one iteration equals one point; one iteration does not
* equal one pass over the dataset).
*
* @param baseOptimizer Optimizer for the forward step.
* @param stepSize Step size for each iteration.
* @param k The synchronization period.
* @param maxIterations Maximum number of iterations allowed (0 means no
* limit).
* @param tolerance Maximum absolute tolerance to terminate algorithm.
* @param decayPolicy Instantiated decay policy used to adjust the step size.
* @param resetPolicy Flag that determines whether update policy parameters
* are reset before every outer Optimize call.
* @param exactObjective Calculate the exact objective (Default: estimate the
* final objective obtained on the last pass over the data).
*/
Lookahead(const BaseOptimizerType& baseOptimizer,
const double stepSize = 0.5,
const size_t k = 5,
const size_t maxIterations = 100000,
const double tolerance = 1e-5,
const DecayPolicyType& decayPolicy = DecayPolicyType(),
const bool resetPolicy = false,
const bool exactObjective = false);
/**
* Clean any memory associated with the Lookahead object.
*/
~Lookahead();
/**
* Optimize the given function using Lookahead. The given starting point will
* be modified to store the finishing point of the algorithm, and the final
* objective value is returned.
*
* @tparam SeparableFunctionType Type of the function to be optimized.
* @tparam MatType Type of the parameters matrix.
* @tparam GradType Type of the gradient matrix.
* @tparam CallbackTypes Types of callback functions.
* @param function Function to optimize.
* @param iterate Starting point (will be modified).
* @param callbacks Callback functions.
* @return Objective value of the final point.
*/
template<typename SeparableFunctionType,
typename MatType,
typename GradType,
typename... CallbackTypes>
typename std::enable_if<IsArmaType<GradType>::value,
typename MatType::elem_type>::type
Optimize(SeparableFunctionType& function,
MatType& iterate,
CallbackTypes&&... callbacks);
//! Forward the MatType as GradType.
template<typename SeparableFunctionType,
typename MatType,
typename... CallbackTypes>
typename MatType::elem_type Optimize(SeparableFunctionType& function,
MatType& iterate,
CallbackTypes&&... callbacks)
{
return Optimize<SeparableFunctionType, MatType, MatType,
CallbackTypes...>(function, iterate,
std::forward<CallbackTypes>(callbacks)...);
}
//! Get the base optimizer.
BaseOptimizerType BaseOptimizer() const { return baseOptimizer; }
//! Modify the base optimizer.
BaseOptimizerType& BaseOptimizer() { return baseOptimizer; }
//! Get the step size.
double StepSize() const { return stepSize; }
//! Modify the step size.
double& StepSize() { return stepSize; }
//! Get the synchronization period.
size_t K() const { return k; }
//! Modify the synchronization period.
size_t& K() { return k; }
//! Get the maximum number of iterations (0 indicates no limit).
size_t MaxIterations() const { return maxIterations; }
//! Modify the maximum number of iterations (0 indicates no limit).
size_t& MaxIterations() { return maxIterations; }
//! Get the tolerance for termination.
double Tolerance() const { return tolerance; }
//! Modify the tolerance for termination.
double& Tolerance() { return tolerance; }
//! Get the step size decay policy.
const DecayPolicyType& DecayPolicy() const { return decayPolicy; }
//! Modify the step size decay policy.
DecayPolicyType& DecayPolicy() { return decayPolicy; }
//! Get the instantiated decay policy type. Be sure to check its type with
//! Has() before using!
const Any& InstDecayPolicy() const { return instDecayPolicy; }
//! Modify the instantiated decay policy type. Be sure to check its type with
//! Has() before using!
Any& InstDecayPolicy() { return instDecayPolicy; }
//! Get whether or not the actual objective is calculated.
bool ExactObjective() const { return exactObjective; }
//! Modify whether or not the actual objective is calculated.
bool& ExactObjective() { return exactObjective; }
private:
/**
* Set the maximum number of iterations if the given optimizer implements
* MaxIterations().
*
* @param optimizer Optimizer to check for MaxIterations().
* @param k The number of iterations.
*/
template<typename OptimizerType>
static typename std::enable_if<traits::HasMaxIterationsSignature<
OptimizerType>::value, void>::type
SetMaxIterations(OptimizerType& optimizer, const size_t k)
{
optimizer.MaxIterations() = k;
}
template<typename OptimizerType>
static typename std::enable_if<!traits::HasMaxIterationsSignature<
OptimizerType>::value, void>::type
SetMaxIterations(const OptimizerType& /* optimizer */, const size_t /* k */)
{
Warn << "The base optimizer does not have a definition of "
<< "MaxIterations(), the base optimizer will have its configuration "
<< "unchanged.";
}
//! The base optimizer for the forward step.
BaseOptimizerType baseOptimizer;
//! The step size for each example.
double stepSize;
//! Synchronization period.
size_t k;
//! The maximum number of allowed iterations.
size_t maxIterations;
//! The tolerance for termination.
double tolerance;
//! The decay policy used to update the step size.
DecayPolicyType decayPolicy;
//! Flag indicating whether update policy
//! should be reset before running the outer optimization.
bool resetPolicy;
//! Controls whether or not the actual Objective value is calculated.
bool exactObjective;
//! Flag indicating whether the update policy
//! parameters have been initialized.
bool isInitialized;
//! The initialized decay policy.
Any instDecayPolicy;
};
} // namespace ens
// Include implementation.
#include "lookahead_impl.hpp"
#endif
@@ -0,0 +1,211 @@
/**
* @file lookahead_impl.hpp
* @author Marcus Edel
*
* Implementation of Lookahead Optimizer: k steps forward, 1 step back.
*
* ensmallen is free software; you may redistribute it and/or modify it under
* the terms of the 3-clause BSD license. You should have received a copy of
* the 3-clause BSD license along with ensmallen. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef ENSMALLEN_LOOKAHEAD_LOOKAHEAD_IMPL_HPP
#define ENSMALLEN_LOOKAHEAD_LOOKAHEAD_IMPL_HPP
// In case it hasn't been included yet.
#include "lookahead.hpp"
#include <ensmallen_bits/function.hpp>
namespace ens {
template<typename BaseOptimizerType, typename DecayPolicyType>
inline Lookahead<BaseOptimizerType, DecayPolicyType>::Lookahead(
const double stepSize,
const size_t k,
const size_t maxIterations,
const double tolerance,
const DecayPolicyType& decayPolicy,
const bool resetPolicy,
const bool exactObjective) :
baseOptimizer(BaseOptimizerType()),
stepSize(stepSize),
k(k),
maxIterations(maxIterations),
tolerance(tolerance),
decayPolicy(decayPolicy),
resetPolicy(resetPolicy),
exactObjective(exactObjective),
isInitialized(false)
{ /* Nothing to do. */ }
template<typename BaseOptimizerType, typename DecayPolicyType>
inline Lookahead<BaseOptimizerType, DecayPolicyType>::Lookahead(
const BaseOptimizerType& baseOptimizer,
const double stepSize,
const size_t k,
const size_t maxIterations,
const double tolerance,
const DecayPolicyType& decayPolicy,
const bool resetPolicy,
const bool exactObjective) :
baseOptimizer(baseOptimizer),
stepSize(stepSize),
k(k),
maxIterations(maxIterations),
tolerance(tolerance),
decayPolicy(decayPolicy),
resetPolicy(resetPolicy),
exactObjective(exactObjective),
isInitialized(false)
{ /* Nothing to do. */ }
template<typename BaseOptimizerType, typename DecayPolicyType>
inline Lookahead<BaseOptimizerType, DecayPolicyType>::~Lookahead()
{
instDecayPolicy.Clean();
}
//! Optimize the function (minimize).
template<typename BaseOptimizerType, typename DecayPolicyType>
template<typename SeparableFunctionType,
typename MatType,
typename GradType,
typename... CallbackTypes>
typename std::enable_if<IsArmaType<GradType>::value,
typename MatType::elem_type>::type
Lookahead<BaseOptimizerType, DecayPolicyType>::Optimize(
SeparableFunctionType& function,
MatType& iterateIn,
CallbackTypes&&... callbacks)
{
// Convenience typedefs.
typedef typename MatType::elem_type ElemType;
typedef typename MatTypeTraits<MatType>::BaseMatType BaseMatType;
typedef typename MatTypeTraits<GradType>::BaseMatType BaseGradType;
typedef Function<SeparableFunctionType, BaseMatType, BaseGradType>
FullFunctionType;
FullFunctionType& f(static_cast<FullFunctionType&>(function));
// The decay policy internally use a templated class so that
// we can know MatType and GradType only when Optimize() is called.
typedef typename DecayPolicyType::template Policy<BaseMatType, BaseGradType>
InstDecayPolicyType;
// Make sure we have all the methods that we need.
traits::CheckSeparableFunctionTypeAPI<FullFunctionType, BaseMatType,
BaseGradType>();
RequireFloatingPointType<BaseMatType>();
RequireFloatingPointType<BaseGradType>();
RequireSameInternalTypes<BaseMatType, BaseGradType>();
BaseMatType& iterate = (BaseMatType&) iterateIn;
// Check if the optimizer implements HasMaxIterations() and override the
// parameter with k.
SetMaxIterations(baseOptimizer, k);
// Check if the optimizer implements ResetPolicy() and override the reset
// policy.
if (traits::HasResetPolicySignature<BaseOptimizerType>::value &&
baseOptimizer.ResetPolicy())
{
Warn << "Parameters are reset before every Optimize call; set "
<< "ResetPolicy() to false.";
baseOptimizer.ResetPolicy() = resetPolicy;
}
// To keep track of where we are and how things are going.
ElemType overallObjective = 0;
ElemType lastOverallObjective = DBL_MAX;
// Controls early termination of the optimization process.
bool terminate = false;
// Initialize the decay policy if needed.
if (!isInitialized || !instDecayPolicy.Has<InstDecayPolicyType>())
{
instDecayPolicy.Clean();
instDecayPolicy.Set<InstDecayPolicyType>(
new InstDecayPolicyType(decayPolicy));
isInitialized = true;
}
// Now iterate!
terminate |= Callback::BeginOptimization(*this, f, iterate, callbacks...);
const size_t actualMaxIterations = (maxIterations == 0) ?
std::numeric_limits<size_t>::max() : maxIterations;
for (size_t i = 0; i < actualMaxIterations && !terminate; i++)
{
BaseMatType iterateModel = iterate;
overallObjective = baseOptimizer.Optimize(f, iterateModel,
callbacks...);
// Now update the learning rate if requested by the user, note we pass the
// latest inner model coordinates instead of the gradient.
instDecayPolicy.As<InstDecayPolicyType>().Update(iterate, stepSize,
iterateModel);
if (std::isnan(overallObjective) || std::isinf(overallObjective))
{
Warn << "Lookahead: converged to " << overallObjective
<< "; terminating with failure. Try a smaller step size?"
<< std::endl;
iterate = iterateModel;
Callback::EndOptimization(*this, f, iterate, callbacks...);
return overallObjective;
}
if (std::abs(lastOverallObjective - overallObjective) < tolerance)
{
Info << "Lookahead: minimized within tolerance " << tolerance << "; "
<< "terminating optimization." << std::endl;
iterate = iterateModel;
Callback::EndOptimization(*this, f, iterate, callbacks...);
return overallObjective;
}
iterate += stepSize * (iterateModel - iterate);
terminate |= Callback::StepTaken(*this, f, iterate, callbacks...);
// Save the current objective.
lastOverallObjective = overallObjective;
}
Info << "Lookahead: maximum iterations (" << maxIterations << ") reached; "
<< "terminating optimization." << std::endl;
// Calculate final objective if exactObjective is set to true.
if (exactObjective)
{
// Find the number of functions to use.
const size_t numFunctions = f.NumFunctions();
size_t batchSize = 1;
// Check if the optimizer implements the BatchSize() method and use the
// parameter for the objective calculation.
if (traits::HasBatchSizeSignature<BaseOptimizerType>::value)
batchSize = baseOptimizer.BatchSize();
overallObjective = 0;
for (size_t i = 0; i < numFunctions; i += batchSize)
{
const size_t effectiveBatchSize = std::min(batchSize, numFunctions - i);
const ElemType objective = f.Evaluate(iterate, i, effectiveBatchSize);
overallObjective += objective;
Callback::Evaluate(*this, f, iterate, objective, callbacks...);
}
}
Callback::EndOptimization(*this, f, iterate, callbacks...);
return overallObjective;
}
} // namespace ens
#endif
@@ -0,0 +1,81 @@
/**
* @file pbi_decomposition.hpp
* @author Nanubala Gnana Sai
*
* The Penalty Based Boundary Intersection (PBI) decomposition policy.
*
* ensmallen is free software; you may redistribute it and/or modify it under
* the terms of the 3-clause BSD license. You should have received a copy of
* the 3-clause BSD license along with ensmallen. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef ENSMALLEN_MOEAD_PBI_HPP
#define ENSMALLEN_MOEAD_PBI_HPP
namespace ens {
/**
* Penalty Based Boundary Intersection (PBI) method is a weight decomposition method,
* it tries to find the intersection between bottom-most boundary of the attainable
* objective set with the reference directions.
*
* The goal is to minimize the distance between objective vectors with the ideal point
* along the reference direction. To handle equality constraints, a penalty parameter
* theta is used.
*
* For more information, see the following:
* @code
* article{zhang2007moea,
* title={MOEA/D: A multiobjective evolutionary algorithm based on decomposition},
* author={Zhang, Qingfu and Li, Hui},
* journal={IEEE Transactions on evolutionary computation},
* pages={712--731},
* year={2007}
* @endcode
*/
class PenaltyBoundaryIntersection
{
public:
/**
* Constructor for Penalty Based Boundary Intersection decomposition
* policy.
*
* @param theta The penalty value.
*/
PenaltyBoundaryIntersection(const double theta = 5) :
theta(theta)
{
/* Nothing to do. */
}
/**
* Decompose the weight vectors.
*
* @tparam VecType The type of the vector used in the decommposition.
* @param weight The weight vector corresponding to a subproblem.
* @param idealPoint The reference point in the objective space.
* @param candidateFitness The objective vector of the candidate.
*/
template<typename VecType>
typename VecType::elem_type Apply(const VecType& weight,
const VecType& idealPoint,
const VecType& candidateFitness)
{
typedef typename VecType::elem_type ElemType;
//! A unit vector in the same direction as the provided weight vector.
const VecType referenceDirection = weight / arma::norm(weight);
//! Distance of F(x) from the idealPoint along the reference direction.
const ElemType d1 = arma::dot(candidateFitness - idealPoint, referenceDirection);
//! The perpendicular distance of F(x) from reference direction.
const ElemType d2 = arma::norm(candidateFitness - (idealPoint + d1 * referenceDirection));
return d1 + static_cast<ElemType>(theta) * d2;
}
private:
double theta;
};
} // namespace ens
#endif
@@ -0,0 +1,66 @@
/**
* @file tchebycheff_decomposition.hpp
* @author Nanubala Gnana Sai
*
* The Tchebycheff Weight decomposition policy.
*
* ensmallen is free software; you may redistribute it and/or modify it under
* the terms of the 3-clause BSD license. You should have received a copy of
* the 3-clause BSD license along with ensmallen. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef ENSMALLEN_MOEAD_TCHEBYCHEFF_HPP
#define ENSMALLEN_MOEAD_TCHEBYCHEFF_HPP
namespace ens {
/**
* The Tchebycheff method works by taking the maximum of element-wise product
* between reference direction and the line connecting objective vector and
* ideal point.
*
* Under mild conditions, for each Pareto Optimal point there exists a reference
* direction such that the given point is also the optimal solution
* to this scalar objective.
*
* For more information, see the following:
* @code
* article{zhang2007moea,
* title={MOEA/D: A multiobjective evolutionary algorithm based on decomposition},
* author={Zhang, Qingfu and Li, Hui},
* journal={IEEE Transactions on evolutionary computation},
* pages={712--731},
* year={2007}
* @endcode
*/
class Tchebycheff
{
public:
/**
* Constructor for Tchebycheff decomposition policy.
*/
Tchebycheff()
{
/* Nothing to do. */
}
/**
* Decompose the weight vectors.
*
* @tparam VecType The type of the vector used in the decommposition.
* @param weight The weight vector corresponding to a subproblem.
* @param idealPoint The reference point in the objective space.
* @param candidateFitness The objective vector of the candidate.
*/
template<typename VecType>
typename VecType::elem_type Apply(const VecType& weight,
const VecType& idealPoint,
const VecType& candidateFitness)
{
return arma::max(weight % arma::abs(candidateFitness - idealPoint));
}
};
} // namespace ens
#endif
@@ -0,0 +1,62 @@
/**
* @file weighted_decomposition.hpp
* @author Nanubala Gnana Sai
*
* The Weighted Average decomposition policy.
*
* ensmallen is free software; you may redistribute it and/or modify it under
* the terms of the 3-clause BSD license. You should have received a copy of
* the 3-clause BSD license along with ensmallen. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef ENSMALLEN_MOEAD_WEIGHTED_HPP
#define ENSMALLEN_MOEAD_WEIGHTED_HPP
namespace ens {
/**
* The Weighted average method of decomposition. The working principle is to
* minimize the dot product between reference direction and the line connecting
* objective vector and ideal point.
*
* For more information, see the following:
* @code
* article{zhang2007moea,
* title={MOEA/D: A multiobjective evolutionary algorithm based on decomposition},
* author={Zhang, Qingfu and Li, Hui},
* journal={IEEE Transactions on evolutionary computation},
* pages={712--731},
* year={2007}
* @endcode
*/
class WeightedAverage
{
public:
/**
* Constructor for Weighted Average decomposition policy.
*/
WeightedAverage()
{
/* Nothing to do. */
}
/**
* Decompose the weight vectors.
*
* @tparam VecType The type of the vector used in the decommposition.
* @param weight The weight vector corresponding to a subproblem.
* @param idealPoint The reference point in the objective space.
* @param candidateFitness The objective vector of the candidate.
*/
template<typename VecType>
typename VecType::elem_type Apply(const VecType& weight,
const VecType& /* idealPoint */,
const VecType& candidateFitness)
{
return arma::dot(weight, candidateFitness);
}
};
} // namespace ens
#endif
+338
View File
@@ -0,0 +1,338 @@
/**
* @file moead.hpp
* @author Nanubala Gnana Sai
*
* MOEA/D-DE is a multi objective optimization algorithm. MOEA/D-DE
* uses genetic algorithms along with a set of reference directions
* to drive the population towards the Optimal Front.
*
* ensmallen is free software; you may redistribute it and/or modify it under
* the terms of the 3-clause BSD license. You should have received a copy of
* the 3-clause BSD license along with ensmallen. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef ENSMALLEN_MOEAD_MOEAD_HPP
#define ENSMALLEN_MOEAD_MOEAD_HPP
//! Decomposition policies.
#include "decomposition_policies/tchebycheff_decomposition.hpp"
#include "decomposition_policies/weighted_decomposition.hpp"
#include "decomposition_policies/pbi_decomposition.hpp"
//! Weight initialization policies.
#include "weight_init_policies/uniform_init.hpp"
#include "weight_init_policies/bbs_init.hpp"
#include "weight_init_policies/dirichlet_init.hpp"
namespace ens {
/**
* MOEA/D-DE (Multi Objective Evolutionary Algorithm based on Decompositon -
* Differential Variant) is a multiobjective optimization algorithm. This class
* implements the said optimizer.
*
* The algorithm works by generating a candidate population from a fixed starting point.
* Reference directions are generated to guide the optimization process towards the Pareto Front.
* Further, a decomposition function is defined to decompose the problem to a scalar optimization
* objective. Utilizing genetic operators, offsprings are generated with better decomposition values
* to replace the neighboring parent solutions.
*
* For more information, see the following:
* @code
* @article{li2008multiobjective,
* title={Multiobjective optimization problems with complicated Pareto sets, MOEA/D and NSGA-II},
* author={Li, Hui and Zhang, Qingfu},
* journal={IEEE transactions on evolutionary computation},
* pages={284--302},
* year={2008},
* @endcode
*/
template<typename InitPolicyType = Uniform,
typename DecompPolicyType = Tchebycheff>
class MOEAD {
public:
/**
* Constructor for the MOEA/D optimizer.
*
* The default values provided here are not necessarily suitable for a
* given function. Therefore, it is highly recommended to adjust the
* parameters according to the problem.
*
* @param populationSize The number of elements in the population.
* @param maxGenerations The maximum number of generations allowed.
* @param crossoverProb The probability that a crossover will occur.
* @param neighborProb The probability of sampling from neighbor.
* @param neighborSize The number of nearest neighbours of weights
* to find.
* @param distributionIndex The crowding degree of the mutation.
* @param differentialWeight A parameter used in the mutation of candidate
* solutions controls amplification factor of the differentiation.
* @param maxReplace The limit of solutions allowed to be replaced by a child.
* @param epsilon Handle numerical stability after weight initialization.
* @param lowerBound The lower bound on each variable of a member
* of the variable space.
* @param upperBound The upper bound on each variable of a member
* of the variable space.
*/
MOEAD(const size_t populationSize = 300,
const size_t maxGenerations = 500,
const double crossoverProb = 1.0,
const double neighborProb = 0.9,
const size_t neighborSize = 20,
const double distributionIndex = 20,
const double differentialWeight = 0.5,
const size_t maxReplace = 2,
const double epsilon = 1E-10,
const arma::vec& lowerBound = arma::zeros(1, 1),
const arma::vec& upperBound = arma::ones(1, 1),
const InitPolicyType initPolicy = InitPolicyType(),
const DecompPolicyType decompPolicy = DecompPolicyType());
/**
* Constructor for the MOEA/D optimizer. This constructor is provides an
* overload to use lowerBound and upperBound as doubles, in case all the
* variables in the problem have the same limits.
*
* The default values provided here are not necessarily suitable for a
* given function. Therefore, it is highly recommended to adjust the
* parameters according to the problem.
*
* @param populationSize The number of elements in the population.
* @param maxGenerations The maximum number of generations allowed.
* @param crossoverProb The probability that a crossover will occur.
* @param neighborProb The probability of sampling from neighbor.
* @param neighborSize The number of nearest neighbours of weights
* to find.
* @param distributionIndex The crowding degree of the mutation.
* @param differentialWeight A parameter used in the mutation of candidate
* solutions controls amplification factor of the differentiation.
* @param maxReplace The limit of solutions allowed to be replaced by a child.
* @param epsilon Handle numerical stability after weight initialization.
* @param lowerBound The lower bound on each variable of a member
* of the variable space.
* @param upperBound The upper bound on each variable of a member
* of the variable space.
*/
MOEAD(const size_t populationSize = 300,
const size_t maxGenerations = 500,
const double crossoverProb = 1.0,
const double neighborProb = 0.9,
const size_t neighborSize = 20,
const double distributionIndex = 20,
const double differentialWeight = 0.5,
const size_t maxReplace = 2,
const double epsilon = 1E-10,
const double lowerBound = 0,
const double upperBound = 1,
const InitPolicyType initPolicy = InitPolicyType(),
const DecompPolicyType decompPolicy = DecompPolicyType());
/**
* Optimize a set of objectives. The initial population is generated
* using the initial point. The output is the best generated front.
*
* @tparam MatType The type of matrix used to store coordinates.
* @tparam ArbitraryFunctionType The type of objective function.
* @tparam CallbackTypes Types of callback function.
* @param objectives std::tuple of the objective functions.
* @param iterate The initial reference point for generating population.
* @param callbacks The callback functions.
*/
template<typename MatType,
typename... ArbitraryFunctionType,
typename... CallbackTypes>
typename MatType::elem_type Optimize(std::tuple<ArbitraryFunctionType...>& objectives,
MatType& iterate,
CallbackTypes&&... callbacks);
//! Retrieve population size.
size_t PopulationSize() const { return populationSize; }
//! Modify the population size.
size_t& PopulationSize() { return populationSize; }
//! Retrieve number of generations.
size_t MaxGenerations() const { return maxGenerations; }
//! Modify the number of generations.
size_t& MaxGenerations() { return maxGenerations; }
//! Retrieve crossover rate.
double CrossoverRate() const { return crossoverProb; }
//! Modify the crossover rate.
double& CrossoverRate() { return crossoverProb; }
//! Retrieve size of the weight neighbor.
size_t NeighborSize() const { return neighborSize; }
//! Modify the size of the weight neighbor.
size_t& NeighborSize() { return neighborSize; }
//! Retrieve value of the distribution index.
double DistributionIndex() const { return distributionIndex; }
//! Modify the value of the distribution index.
double& DistributionIndex() { return distributionIndex; }
//! Retrieve value of neighbor probability.
double NeighborProb() const { return neighborProb; }
//! Modify the value of neigbourhood probability.
double& NeighborProb() { return neighborProb; }
//! Retrieve value of scaling factor.
double DifferentialWeight() const { return differentialWeight; }
//! Modify the value of scaling factor.
double& DifferentialWeight() { return differentialWeight; }
//! Retrieve value of maxReplace.
size_t MaxReplace() const { return maxReplace; }
//! Modify value of maxReplace.
size_t& MaxReplace() { return maxReplace; }
//! Retrieve value of epsilon.
double Epsilon() const { return epsilon; }
//! Modify value of maxReplace.
double& Epsilon() { return epsilon; }
//! Retrieve value of lowerBound.
const arma::vec& LowerBound() const { return lowerBound; }
//! Modify value of lowerBound.
arma::vec& LowerBound() { return lowerBound; }
//! Retrieve value of upperBound.
const arma::vec& UpperBound() const { return upperBound; }
//! Modify value of upperBound.
arma::vec& UpperBound() { return upperBound; }
//! Retrieve the Pareto optimal points in variable space. This returns an empty cube
//! until `Optimize()` has been called.
const arma::cube& ParetoSet() const { return paretoSet; }
//! Retrieve the best front (the Pareto frontier). This returns an empty cube until
//! `Optimize()` has been called.
const arma::cube& ParetoFront() const { return paretoFront; }
//! Get the weight initialization policy.
const InitPolicyType& InitPolicy() const { return initPolicy; }
//! Modify the weight initialization policy.
InitPolicyType& InitPolicy() { return initPolicy; }
//! Get the weight decomposition policy.
const DecompPolicyType& DecompPolicy() const { return decompPolicy; }
//! Modify the weight decomposition policy.
DecompPolicyType& DecompPolicy() { return decompPolicy; }
private:
/**
* @brief Randomly selects two members from the population.
*
* @param subProblemIdx Index of the current subproblem.
* @param neighborSize A matrix containing indices of the neighbors.
* @return std::tuple<size_t, size_t> The chosen pair of indices.
*/
std::tuple<size_t, size_t> Mating(size_t subProblemIdx,
const arma::umat& neighborSize,
bool sampleNeighbor);
/**
* Mutate the child formed by the crossover of two random members of the
* population. Uses polynomial mutation.
*
* @tparam MatType The type of matrix used to store coordinates.
* @param child The candidate to be mutated.
* @param mutationRate The probability of mutation.
* @param lowerBound The lower bound on each variable in the matrix.
* @param upperBound The upper bound on each variable in the matrix.
* @return The mutated child.
*/
template<typename MatType>
void Mutate(MatType& child,
double mutationRate,
const MatType& lowerBound,
const MatType& upperBound);
/**
* Evaluate objectives for the elite population.
*
* @tparam ArbitraryFunctionType std::tuple of multiple function types.
* @tparam MatType Type of matrix to optimize.
* @param population The elite population.
* @param objectives The set of objectives.
* @param calculatedObjectives Vector to store calculated objectives.
*/
template<std::size_t I = 0,
typename MatType,
typename ...ArbitraryFunctionType>
typename std::enable_if<I == sizeof...(ArbitraryFunctionType), void>::type
EvaluateObjectives(
std::vector<MatType>&,
std::tuple<ArbitraryFunctionType...>&,
std::vector<arma::Col<typename MatType::elem_type> >&);
template<std::size_t I = 0,
typename MatType,
typename ...ArbitraryFunctionType>
typename std::enable_if<I < sizeof...(ArbitraryFunctionType), void>::type
EvaluateObjectives(
std::vector<MatType>& population,
std::tuple<ArbitraryFunctionType...>& objectives,
std::vector<arma::Col<typename MatType::elem_type> >&
calculatedObjectives);
//! Size of the population.
size_t populationSize;
//! Maximum number of generations before termination criteria is met.
size_t maxGenerations;
//! Probability of crossover between two members.
double crossoverProb;
//! The probability that two elements will be chosen from the neighbor.
double neighborProb;
//! Number of nearest neighbours of weights to consider.
size_t neighborSize;
//! The crowding degree of the mutation. Higher value produces a mutant
//! resembling its parent.
double distributionIndex;
//! Amplification factor for differentiation.
double differentialWeight;
//! Maximum number of childs which can replace the parent. Higher value
//! leads to a loss of diversity.
size_t maxReplace;
//! A small numeric value to be added to the weights after initialization.
//! Prevents zero value inside inited weights.
double epsilon;
//! Lower bound on each variable in the variable space.
arma::vec lowerBound;
//! Upper bound on each variable in the variable space.
arma::vec upperBound;
//! The set of all the Pareto optimal points.
//! Stored after Optimize() is called.
arma::cube paretoSet;
//! The set of all the Pareto optimal objective vectors.
//! Stored after Optimize() is called.
arma::cube paretoFront;
//! Policy to initialize the reference directions (weights) matrix.
InitPolicyType initPolicy;
//! Policy to decompose the weights.
DecompPolicyType decompPolicy;
};
using DefaultMOEAD = MOEAD<Uniform, Tchebycheff>;
using BBSMOEAD = MOEAD<BayesianBootstrap, Tchebycheff>;
using DirichletMOEAD = MOEAD<Dirichlet, Tchebycheff>;
} // namespace ens
// Include implementation.
#include "moead_impl.hpp"
#endif
+441
View File
@@ -0,0 +1,441 @@
/**
* @file moead_impl.hpp
* @author Nanubala Gnana Sai
*
* Implementation of the MOEA/D-DE algorithm. Used for multi-objective
* optimization problems on arbitrary functions.
*
* ensmallen is free software; you may redistribute it and/or modify it under
* the terms of the 3-clause BSD license. You should have received a copy of
* the 3-clause BSD license along with ensmallen. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more Information.
*/
#ifndef ENSMALLEN_MOEAD_MOEAD_IMPL_HPP
#define ENSMALLEN_MOEAD_MOEAD_IMPL_HPP
#include "moead.hpp"
#include <assert.h>
namespace ens {
template <typename InitPolicyType, typename DecompPolicyType>
inline MOEAD<InitPolicyType, DecompPolicyType>::
MOEAD(const size_t populationSize,
const size_t maxGenerations,
const double crossoverProb,
const double neighborProb,
const size_t neighborSize,
const double distributionIndex,
const double differentialWeight,
const size_t maxReplace,
const double epsilon,
const arma::vec& lowerBound,
const arma::vec& upperBound,
const InitPolicyType initPolicy,
const DecompPolicyType decompPolicy) :
populationSize(populationSize),
maxGenerations(maxGenerations),
crossoverProb(crossoverProb),
neighborProb(neighborProb),
neighborSize(neighborSize),
distributionIndex(distributionIndex),
differentialWeight(differentialWeight),
maxReplace(maxReplace),
epsilon(epsilon),
lowerBound(lowerBound),
upperBound(upperBound),
initPolicy(initPolicy),
decompPolicy(decompPolicy)
{ /* Nothing to do here. */ }
template <typename InitPolicyType, typename DecompPolicyType>
inline MOEAD<InitPolicyType, DecompPolicyType>::
MOEAD(const size_t populationSize,
const size_t maxGenerations,
const double crossoverProb,
const double neighborProb,
const size_t neighborSize,
const double distributionIndex,
const double differentialWeight,
const size_t maxReplace,
const double epsilon,
const double lowerBound,
const double upperBound,
const InitPolicyType initPolicy,
const DecompPolicyType decompPolicy) :
populationSize(populationSize),
maxGenerations(maxGenerations),
crossoverProb(crossoverProb),
neighborProb(neighborProb),
neighborSize(neighborSize),
distributionIndex(distributionIndex),
differentialWeight(differentialWeight),
maxReplace(maxReplace),
epsilon(epsilon),
lowerBound(lowerBound * arma::ones(1, 1)),
upperBound(upperBound * arma::ones(1, 1)),
initPolicy(initPolicy),
decompPolicy(decompPolicy)
{ /* Nothing to do here. */ }
//! Optimize the function.
template <typename InitPolicyType, typename DecompPolicyType>
template<typename MatType,
typename... ArbitraryFunctionType,
typename... CallbackTypes>
typename MatType::elem_type MOEAD<InitPolicyType, DecompPolicyType>::
Optimize(std::tuple<ArbitraryFunctionType...>& objectives,
MatType& iterateIn,
CallbackTypes&&... callbacks)
{
// Population Size must be at least 3 for MOEA/D-DE to work.
if (populationSize < 3)
{
throw std::logic_error("MOEA/D-DE::Optimize(): population size should be at least"
" 3!");
}
// Convenience typedefs.
typedef typename MatType::elem_type ElemType;
typedef typename MatTypeTraits<MatType>::BaseMatType BaseMatType;
BaseMatType& iterate = (BaseMatType&) iterateIn;
// Make sure that we have the methods that we need. Long name...
traits::CheckArbitraryFunctionTypeAPI<ArbitraryFunctionType...,
BaseMatType>();
RequireDenseFloatingPointType<BaseMatType>();
if (neighborSize < 2)
{
throw std::invalid_argument(
"neighborSize should be atleast 2, however "
+ std::to_string(neighborSize) + " was detected."
);
}
if (neighborSize > populationSize - 1u)
{
std::ostringstream oss;
oss << "MOEAD::Optimize(): " << "neighborSize is " << neighborSize
<< " but populationSize is " << populationSize << "(should be"
<< " atleast " << (neighborSize + 1u) << ")" << std::endl;
throw std::logic_error(oss.str());
}
// Check if lower bound is a vector of a single dimension.
if (lowerBound.n_rows == 1)
lowerBound = lowerBound(0, 0) * arma::ones(iterate.n_rows, iterate.n_cols);
// Check if upper bound is a vector of a single dimension.
if (upperBound.n_rows == 1)
upperBound = upperBound(0, 0) * arma::ones(iterate.n_rows, iterate.n_cols);
// Check the dimensions of lowerBound and upperBound.
assert(lowerBound.n_rows == iterate.n_rows && "The dimensions of "
"lowerBound are not the same as the dimensions of iterate.");
assert(upperBound.n_rows == iterate.n_rows && "The dimensions of "
"upperBound are not the same as the dimensions of iterate.");
const size_t numObjectives = sizeof...(ArbitraryFunctionType);
const size_t numVariables = iterate.n_rows;
//! Useful temporaries for float-like comparisons.
const BaseMatType castedLowerBound = arma::conv_to<BaseMatType>::from(lowerBound);
const BaseMatType castedUpperBound = arma::conv_to<BaseMatType>::from(upperBound);
// Controls early termination of the optimization process.
bool terminate = false;
// The weight matrix. Each vector represents a decomposition subproblem (M X N).
const BaseMatType weights = initPolicy.template Generate<BaseMatType>(
numObjectives, populationSize, epsilon);
// 1.1 Storing the indices of nearest neighbors of each weight vector.
arma::umat neighborIndices(neighborSize, populationSize);
for (size_t i = 0; i < populationSize; ++i)
{
// Cache the distance between weights[i] and other weights.
const arma::Row<ElemType> distances =
arma::sqrt(arma::sum(arma::square(weights.col(i) - weights.each_col())));
arma::uvec sortedIndices = arma::stable_sort_index(distances);
// Ignore distance from self.
neighborIndices.col(i) = sortedIndices(arma::span(1, neighborSize));
}
// 1.2 Random generation of the initial population.
std::vector<BaseMatType> population(populationSize);
for (BaseMatType& individual : population)
{
individual = arma::randu<BaseMatType>(
iterate.n_rows, iterate.n_cols) - 0.5 + iterate;
// Constrain all genes to be within bounds.
individual = arma::min(arma::max(individual, castedLowerBound), castedUpperBound);
}
Info << "MOEA/D-DE initialized successfully. Optimization started." << std::endl;
std::vector<arma::Col<ElemType>> populationFitness(populationSize);
std::fill(populationFitness.begin(), populationFitness.end(),
arma::Col<ElemType>(numObjectives, arma::fill::zeros));
EvaluateObjectives(population, objectives, populationFitness);
// 1.3 Initialize the ideal point z.
arma::Col<ElemType> idealPoint(numObjectives);
idealPoint.fill(std::numeric_limits<ElemType>::max());
for (const arma::Col<ElemType>& individualFitness : populationFitness)
idealPoint = arma::min(idealPoint, individualFitness);
terminate |= Callback::BeginOptimization(*this, objectives, iterate, callbacks...);
// 2 The main loop.
for (size_t generation = 1; generation <= maxGenerations && !terminate; ++generation)
{
// Shuffle indexes of subproblems.
const arma::uvec shuffle = arma::shuffle(
arma::linspace<arma::uvec>(0, populationSize - 1, populationSize));
for (size_t subProblemIdx : shuffle)
{
// 2.1 Randomly select two indices in neighborIndices[subProblemIdx] and use them
// to make a child.
size_t r1, r2, r3;
r1 = subProblemIdx;
// Randomly choose to sample from the population or the neighbors.
const bool sampleNeighbor = arma::randu() < neighborProb;
std::tie(r2, r3) =
Mating(subProblemIdx, neighborIndices, sampleNeighbor);
// 2.2 - 2.3 Reproduction and Repair: Differential Operator followed by
// Polynomial Mutation.
BaseMatType candidate(iterate.n_rows, iterate.n_cols);
for (size_t geneIdx = 0; geneIdx < numVariables; ++geneIdx)
{
if (arma::randu() < crossoverProb)
{
candidate(geneIdx) = population[r1](geneIdx) +
differentialWeight * (population[r2](geneIdx) -
population[r3](geneIdx));
// Boundary conditions.
if (candidate(geneIdx) < castedLowerBound(geneIdx))
{
candidate(geneIdx) = castedLowerBound(geneIdx) +
arma::randu() * (population[r1](geneIdx) - castedLowerBound(geneIdx));
}
if (candidate(geneIdx) > castedUpperBound(geneIdx))
{
candidate(geneIdx) = castedUpperBound(geneIdx) -
arma::randu() * (castedUpperBound(geneIdx) - population[r1](geneIdx));
}
}
else
candidate(geneIdx) = population[r1](geneIdx);
}
Mutate(candidate, 1.0 / static_cast<double>(numVariables),
castedLowerBound, castedUpperBound);
arma::Col<ElemType> candidateFitness(numObjectives);
//! Creating temp vectors to pass to EvaluateObjectives.
std::vector<BaseMatType> candidateContainer { candidate };
std::vector<arma::Col<ElemType>> fitnessContainer { candidateFitness };
EvaluateObjectives(candidateContainer, objectives, fitnessContainer);
candidateFitness = std::move(fitnessContainer[0]);
//! Flush out the dummy containers.
fitnessContainer.clear();
candidateContainer.clear();
// 2.4 Update of ideal point.
idealPoint = arma::min(idealPoint, candidateFitness);
// 2.5 Update of the population.
size_t replaceCounter = 0;
const size_t sampleSize = sampleNeighbor ? neighborSize : populationSize;
const arma::uvec idxShuffle = arma::shuffle(
arma::linspace<arma::uvec>(0, sampleSize - 1, sampleSize));
for (size_t idx : idxShuffle)
{
// Preserve diversity by controlling replacement of neighbors
// by child solution.
if (replaceCounter >= maxReplace)
break;
const size_t pick = sampleNeighbor ?
neighborIndices(idx, subProblemIdx) : idx;
const ElemType candidateDecomposition = decompPolicy.template
Apply<arma::Col<ElemType>>(weights.col(pick), idealPoint, candidateFitness);
const ElemType parentDecomposition = decompPolicy.template
Apply<arma::Col<ElemType>>(weights.col(pick), idealPoint, populationFitness[pick]);
if (candidateDecomposition < parentDecomposition)
{
population[pick] = candidate;
populationFitness[pick] = candidateFitness;
++replaceCounter;
}
}
} // End of pass over all subproblems.
// The final population itself is the best front.
const std::vector<arma::uvec> frontIndices { arma::shuffle(
arma::linspace<arma::uvec>(0, populationSize - 1, populationSize)) };
terminate |= Callback::GenerationalStepTaken(*this, objectives, iterate,
populationFitness, frontIndices, callbacks...);
} // End of pass over all the generations.
// Set the candidates from the Pareto Set as the output.
paretoSet.set_size(population[0].n_rows, population[0].n_cols, population.size());
// The Pareto Front is stored, can be obtained via ParetoSet() getter.
for (size_t solutionIdx = 0; solutionIdx < population.size(); ++solutionIdx)
{
paretoSet.slice(solutionIdx) =
arma::conv_to<arma::mat>::from(population[solutionIdx]);
}
// Set the candidates from the Pareto Front as the output.
paretoFront.set_size(populationFitness[0].n_rows, populationFitness[0].n_cols,
populationFitness.size());
// The Pareto Front is stored, can be obtained via ParetoFront() getter.
for (size_t solutionIdx = 0; solutionIdx < populationFitness.size(); ++solutionIdx)
{
paretoFront.slice(solutionIdx) =
arma::conv_to<arma::mat>::from(populationFitness[solutionIdx]);
}
// Assign iterate to first element of the Pareto Set.
iterate = population[0];
Callback::EndOptimization(*this, objectives, iterate, callbacks...);
ElemType performance = std::numeric_limits<ElemType>::max();
for (size_t geneIdx = 0; geneIdx < numObjectives; ++geneIdx)
{
if (arma::accu(populationFitness[geneIdx]) < performance)
performance = arma::accu(populationFitness[geneIdx]);
}
return performance;
}
//! Randomly chooses to select from parents or neighbors.
template <typename InitPolicyType, typename DecompPolicyType>
inline std::tuple<size_t, size_t>
MOEAD<InitPolicyType, DecompPolicyType>::
Mating(size_t subProblemIdx,
const arma::umat& neighborIndices,
bool sampleNeighbor)
{
//! Indexes of two points from the sample space.
size_t pointA = sampleNeighbor
? neighborIndices(
arma::randi(arma::distr_param(0, neighborSize - 1u)), subProblemIdx)
: arma::randi(arma::distr_param(0, populationSize - 1u));
size_t pointB = sampleNeighbor
? neighborIndices(
arma::randi(arma::distr_param(0, neighborSize - 1u)), subProblemIdx)
: arma::randi(arma::distr_param(0, populationSize - 1u));
//! If the sampled points are equal, then modify one of them
//! within reasonable bounds.
if (pointA == pointB)
{
if (pointA == populationSize - 1u)
--pointA;
else
++pointA;
}
return std::make_tuple(pointA, pointB);
}
//! Perform Polynomial mutation of the candidate.
template <typename InitPolicyType, typename DecompPolicyType>
template<typename MatType>
inline void MOEAD<InitPolicyType, DecompPolicyType>::
Mutate(MatType& candidate,
double mutationRate,
const MatType& lowerBound,
const MatType& upperBound)
{
const size_t numVariables = candidate.n_rows;
for (size_t geneIdx = 0; geneIdx < numVariables; ++geneIdx)
{
// Should this gene be mutated?
if (arma::randu() > mutationRate)
continue;
const double geneRange = upperBound(geneIdx) - lowerBound(geneIdx);
// Normalised distance from the bounds.
const double lowerDelta = (candidate(geneIdx) - lowerBound(geneIdx)) / geneRange;
const double upperDelta = (upperBound(geneIdx) - candidate(geneIdx)) / geneRange;
const double mutationPower = 1. / (distributionIndex + 1.0);
const double rand = arma::randu();
double value, perturbationFactor;
if (rand < 0.5)
{
value = 2.0 * rand + (1.0 - 2.0 * rand) *
std::pow(upperDelta, distributionIndex + 1.0);
perturbationFactor = std::pow(value, mutationPower) - 1.0;
}
else
{
value = 2.0 * (1.0 - rand) + 2.0 *(rand - 0.5) *
std::pow(lowerDelta, distributionIndex + 1.0);
perturbationFactor = 1.0 - std::pow(value, mutationPower);
}
candidate(geneIdx) += perturbationFactor * geneRange;
}
//! Enforce bounds.
candidate = arma::min(arma::max(candidate, lowerBound), upperBound);
}
//! No objectives to evaluate.
template <typename InitPolicyType, typename DecompPolicyType>
template<std::size_t I,
typename MatType,
typename ...ArbitraryFunctionType>
typename std::enable_if<I == sizeof...(ArbitraryFunctionType), void>::type
MOEAD<InitPolicyType, DecompPolicyType>::
EvaluateObjectives(
std::vector<MatType>&,
std::tuple<ArbitraryFunctionType...>&,
std::vector<arma::Col<typename MatType::elem_type> >&)
{
// Nothing to do here.
}
//! Evaluate the objectives for the entire population.
template <typename InitPolicyType, typename DecompPolicyType>
template<std::size_t I,
typename MatType,
typename ...ArbitraryFunctionType>
typename std::enable_if<I < sizeof...(ArbitraryFunctionType), void>::type
MOEAD<InitPolicyType, DecompPolicyType>::
EvaluateObjectives(
std::vector<MatType>& population,
std::tuple<ArbitraryFunctionType...>& objectives,
std::vector<arma::Col<typename MatType::elem_type> >& calculatedObjectives)
{
for (size_t i = 0; i < population.size(); i++)
{
calculatedObjectives[i](I) = std::get<I>(objectives).Evaluate(population[i]);
EvaluateObjectives<I+1, MatType, ArbitraryFunctionType...>(population, objectives,
calculatedObjectives);
}
}
} // namespace ens
#endif
@@ -0,0 +1,76 @@
/**
* @file bbs_init.hpp
* @author Nanubala Gnana Sai
*
* The Bayesian Bootstrap (BBS) method of Weight Initialization.
*
* ensmallen is free software; you may redistribute it and/or modify it under
* the terms of the 3-clause BSD license. You should have received a copy of
* the 3-clause BSD license along with ensmallen. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef ENSMALLEN_MOEAD_BBS_HPP
#define ENSMALLEN_MOEAD_BBS_HPP
namespace ens {
/**
* The Bayesian Bootstrap method for initializing weights. Samples are randomly picked from uniform
* distribution followed by sorting and finding adjacent difference. This gives you a list of
* numbers which is guaranteed to sum up to 1.
*
* @code
* @article{rubin1981bayesian,
* title={The bayesian bootstrap},
* author={Rubin, Donald B},
* journal={The annals of statistics},
* pages={130--134},
* year={1981},
* @endcode
*
*/
class BayesianBootstrap
{
public:
/**
* Constructor for Bayesian Bootstrap policy.
*/
BayesianBootstrap()
{
/* Nothing to do. */
}
/**
* Generate the reference direction matrix.
*
* @tparam MatType The type of the matrix used for constructing weights.
* @param numObjectives The dimensionality of objective space.
* @param numPoints The number of reference directions requested.
* @param epsilon Handle numerical stability after weight initialization.
*/
template<typename MatType>
MatType Generate(const size_t numObjectives,
const size_t numPoints,
const double epsilon)
{
typedef typename MatType::elem_type ElemType;
typedef typename arma::Col<ElemType> VecType;
MatType weights(numObjectives, numPoints);
for (size_t pointIdx = 0; pointIdx < numPoints; ++pointIdx)
{
VecType referenceDirection(numObjectives + 1, arma::fill::randu);
referenceDirection(0) = 0;
referenceDirection(numObjectives) = 1;
referenceDirection = arma::sort(referenceDirection);
referenceDirection = arma::diff(referenceDirection);
weights.col(pointIdx) = std::move(referenceDirection) + epsilon;
}
return weights;
}
};
} // namespace ens
#endif
@@ -0,0 +1,55 @@
/**
* @file dirichlet_init.hpp
* @author Nanubala Gnana Sai
*
* The Dirichlet method of Weight Initialization.
*
* ensmallen is free software; you may redistribute it and/or modify it under
* the terms of the 3-clause BSD license. You should have received a copy of
* the 3-clause BSD license along with ensmallen. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef ENSMALLEN_MOEAD_DIRICHLET_HPP
#define ENSMALLEN_MOEAD_DIRICHLET_HPP
namespace ens {
/**
* The Dirichlet method for initializing weights. Sampling a
* Dirichlet distribution with parameters set to one returns
* point lying on unit simplex with uniform distribution.
*/
class Dirichlet
{
public:
/**
* Constructor for Dirichlet policy.
*/
Dirichlet()
{
/* Nothing to do. */
}
/**
* Generate the reference direction matrix.
*
* @tparam MatType The type of the matrix used for constructing weights.
* @param numObjectives The dimensionality of objective space.
* @param numPoints The number of reference directions requested.
* @param epsilon Handle numerical stability after weight initialization.
*/
template<typename MatType>
MatType Generate(const size_t numObjectives,
const size_t numPoints,
const double epsilon)
{
MatType weights = arma::randg<MatType>(numObjectives, numPoints,
arma::distr_param(1.0, 1.0)) + epsilon;
// Normalize each column.
return arma::normalise(weights, 1, 0);
}
};
} // namespace ens
#endif
@@ -0,0 +1,208 @@
/**
* @file uniform_init.hpp
* @author Nanubala Gnana Sai
*
* The Uniform (Das Dennis) methodology of Weight Initialization.
*
* ensmallen is free software; you may redistribute it and/or modify it under
* the terms of the 3-clause BSD license. You should have received a copy of
* the 3-clause BSD license along with ensmallen. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef ENSMALLEN_MOEAD_UNIFORM_HPP
#define ENSMALLEN_MOEAD_UNIFORM_HPP
namespace ens {
/**
* The Uniform (Das Dennis) method for initializing weights. This algorithm guarantees
* that the distance between adjacent points would be uniform.
*
* For more information, see the following:
*
* @code
* article{zhang2007moea,
* title={MOEA/D: A multiobjective evolutionary algorithm based on decomposition},
* author={Zhang, Qingfu and Li, Hui},
* journal={IEEE Transactions on evolutionary computation},
* pages={712--731},
* year={2007}
* @endcode
*/
class Uniform
{
public:
/**
* Constructor for Uniform Weight Initializatoin Policy.
*/
Uniform()
{
/* Nothing to do. */
}
/**
* Generate the reference direction matrix.
*
* @tparam MatType The type of the matrix used for constructing weights.
* @param numObjectives The dimensionality of objective space.
* @param numPoints The number of reference directions requested.
* @param epsilon Handle numerical stability after weight initialization.
*/
template<typename MatType>
MatType Generate(size_t numObjectives,
size_t numPoints,
double epsilon)
{
size_t numPartitions = FindNumParitions(numObjectives, numPoints);
size_t validNumPoints = FindNumUniformPoints(numObjectives, numPartitions);
//! The requested number of points is not matching any partition number.
if (numPoints != validNumPoints)
{
size_t nextValidNumPoints = FindNumUniformPoints(numObjectives, numPartitions + 1);
std::ostringstream oss;
oss << "DasDennis::Generate(): " << "The requested numPoints " << numPoints
<< " cannot be generated uniformly.\n " << "Either choose numPoints as "
<< validNumPoints << " (numPartition = " << numPartitions << ") or "
<< "numPoints as " << nextValidNumPoints << " (numPartition = "
<< numPartitions + 1 << ").";
throw std::logic_error(oss.str());
}
return DasDennis<MatType>(numObjectives, numPoints,
numPartitions, epsilon);
}
private:
/**
* Finds the number of points which can be sampled uniformly from a
* unit simplex given the number of partitions.
*/
size_t FindNumUniformPoints(const size_t numObjectives,
const size_t numPartitions)
{
//! O(N) algorithm to calculate binomial coefficient.
//! Source: https://www.geeksforgeeks.org/space-and-time-efficient-binomial-coefficient/
auto BinomialCoefficient =
[](size_t n, size_t k) -> size_t
{
size_t retval = 1;
// Since, C(n, k) = C(n, n - k).
if (k > n - k)
k = n - k;
// [n * (n - 1) * .... * (n - k + 1)] / [k * (k - 1) * .... * 1].
for (size_t i = 0; i < k; ++i)
{
retval *= (n - i);
retval /= (i + 1);
}
return retval;
};
return BinomialCoefficient(numObjectives + numPartitions - 1, numPartitions);
}
/**
* Calculates the appropriate number of partitions such that, the binomial
* coefficient value is closest to the number of points requested.
*/
size_t FindNumParitions(size_t numObjectives, size_t numPoints)
{
if (numObjectives == 1) return 0;
// Iteratively increase numPartitions so that the binomial coefficient
// comes near to numPoints;
size_t numPartitions {1};
size_t sampledNumPoints = FindNumUniformPoints(numPartitions,
numObjectives);
while (sampledNumPoints <= numPoints)
{
++numPartitions;
sampledNumPoints = FindNumUniformPoints(numObjectives,
numPartitions);
}
return numPartitions - 1;
}
/**
* A helper function for DasDennis
*/
template<typename AuxInfoStackType,
typename MatType>
void DasDennisHelper(AuxInfoStackType& progressStack,
MatType& weights,
const size_t numObjectives,
const size_t numPoints,
const size_t numPartitions,
const double epsilon)
{
typedef typename MatType::elem_type ElemType;
typedef typename arma::Row<ElemType> RowType;
size_t counter = 0;
const ElemType delta = 1.0 / (ElemType)numPartitions;
while ((counter < numPoints) && !progressStack.empty())
{
MatType point{};
size_t beta{};
std::tie(point, beta) = progressStack.back();
progressStack.pop_back();
if (point.size() + 1 == numObjectives)
{
point.insert_rows(point.n_rows, RowType(1).fill(
delta * static_cast<ElemType>(beta)));
weights.col(counter) = point + epsilon;
++counter;
}
else
{
for (size_t i = 0; i <= beta; ++i)
{
MatType pointClone(point);
pointClone.insert_rows(pointClone.n_rows, RowType(1).fill(
delta * static_cast<ElemType>(i)));
progressStack.push_back({pointClone, beta - i});
}
}
}
}
/**
* Generates the weight matrix after verifying the
* validity of the parameters.
*/
template <typename MatType>
MatType DasDennis(const size_t numObjectives,
const size_t numPoints,
const size_t numPartitions,
const double epsilon)
{
//! Holds auxillary information required for the helper function.
//! Holds the current point and beta value.
using AuxContainer = std::pair<MatType, size_t>;
std::vector<AuxContainer> progressStack{};
//! Init the progress stack.
progressStack.push_back({{}, numPartitions});
MatType weights(numObjectives, numPoints);
weights.fill(arma::datum::nan);
DasDennisHelper<decltype(progressStack), MatType>(
progressStack,
weights,
numObjectives,
numPoints,
numPartitions,
epsilon);
return weights;
}
};
} // namespace ens
#endif
+392
View File
@@ -0,0 +1,392 @@
/**
* @file nsga2.hpp
* @author Sayan Goswami
* @author Nanubala Gnana Sai
*
* NSGA-II is a multi-objective optimization algorithm, widely used in
* many real-world applications. NSGA-II generates offsprings using
* crossover and mutation and then selects the next generation according
* to non-dominated-sorting and crowding distance comparison.
*
* ensmallen is free software; you may redistribute it and/or modify it under
* the terms of the 3-clause BSD license. You should have received a copy of
* the 3-clause BSD license along with ensmallen. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef ENSMALLEN_NSGA2_NSGA2_HPP
#define ENSMALLEN_NSGA2_NSGA2_HPP
namespace ens {
/**
* NSGA-II (Non-dominated Sorting Genetic Algorithm - II) is a multi-objective
* optimization algorithm. This class implements the NSGA-II algorithm.
*
* The algorithm works by generating a candidate population from a fixed
* starting point. At each stage of optimization, a new population of children
* is generated. This new population along with its predecessor is sorted using
* non-domination as the metric. Following this, the population is further
* segregated in fronts. A new population is generated from these fronts having
* size equal to that of the starting population.
*
* During evolution, two parents are randomly chosen using binary tournament
* selection. A pair of children are generated by crossing over these two
* candidates followed by mutation.
*
* The best front (Pareto optimal) is returned by the Optimize() method.
*
* For more information, see the following:
*
* @code
* @article{10.1109/4235.996017,
* author = {Deb, K. and Pratap, A. and Agarwal, S. and Meyarivan, T.},
* title = {A Fast and Elitist Multiobjective Genetic Algorithm: NSGA-II},
* year = {2002},
* url = {https://doi.org/10.1109/4235.996017},
* journal = {Trans. Evol. Comp}}
* @endcode
*
* NSGA-II can optimize arbitrary multi-objective functions. For more details,
* see the documentation on function types included with this distribution or
* on the ensmallen website.
*/
class NSGA2
{
public:
/**
* Constructor for the NSGA2 optimizer.
*
* The default values provided over here are not necessarily suitable for a
* given function. Therefore it is highly recommended to adjust the
* parameters according to the problem.
*
* @param populationSize The number of candidates in the population.
* This should be atleast 4 in size and a multiple of 4.
* @param maxGenerations The maximum number of generations allowed for NSGA-II.
* @param crossoverProb The probability that a crossover will occur.
* @param mutationProb The probability that a mutation will occur.
* @param mutationStrength The strength of the mutation.
* @param epsilon The minimum difference required to distinguish between
* candidate solutions.
* @param lowerBound Lower bound of the coordinates of the initial population.
* @param upperBound Upper bound of the coordinates of the initial population.
*/
NSGA2(const size_t populationSize = 100,
const size_t maxGenerations = 2000,
const double crossoverProb = 0.6,
const double mutationProb = 0.3,
const double mutationStrength = 1e-3,
const double epsilon = 1e-6,
const arma::vec& lowerBound = arma::zeros(1, 1),
const arma::vec& upperBound = arma::ones(1, 1));
/**
* Constructor for the NSGA2 optimizer. This constructor provides an overload
* to use `lowerBound` and `upperBound` of type double.
*
* The default values provided over here are not necessarily suitable for a
* given function. Therefore it is highly recommended to adjust the
* parameters according to the problem.
*
* @param populationSize The number of candidates in the population.
* This should be atleast 4 in size and a multiple of 4.
* @param maxGenerations The maximum number of generations allowed for NSGA-II.
* @param crossoverProb The probability that a crossover will occur.
* @param mutationProb The probability that a mutation will occur.
* @param mutationStrength The strength of the mutation.
* @param epsilon The minimum difference required to distinguish between
* candidate solutions.
* @param lowerBound Lower bound of the coordinates of the initial population.
* @param upperBound Upper bound of the coordinates of the initial population.
*/
NSGA2(const size_t populationSize = 100,
const size_t maxGenerations = 2000,
const double crossoverProb = 0.6,
const double mutationProb = 0.3,
const double mutationStrength = 1e-3,
const double epsilon = 1e-6,
const double lowerBound = 0,
const double upperBound = 1);
/**
* Optimize a set of objectives. The initial population is generated using the
* starting point. The output is the best generated front.
*
* @tparam ArbitraryFunctionType std::tuple of multiple objectives.
* @tparam MatType Type of matrix to optimize.
* @tparam CallbackTypes Types of callback functions.
* @param objectives Vector of objective functions to optimize for.
* @param iterate Starting point.
* @param callbacks Callback functions.
* @return MatType::elem_type The minimum of the accumulated sum over the
* objective values in the best front.
*/
template<typename MatType,
typename... ArbitraryFunctionType,
typename... CallbackTypes>
typename MatType::elem_type Optimize(
std::tuple<ArbitraryFunctionType...>& objectives,
MatType& iterate,
CallbackTypes&&... callbacks);
//! Get the population size.
size_t PopulationSize() const { return populationSize; }
//! Modify the population size.
size_t& PopulationSize() { return populationSize; }
//! Get the maximum number of generations.
size_t MaxGenerations() const { return maxGenerations; }
//! Modify the maximum number of generations.
size_t& MaxGenerations() { return maxGenerations; }
//! Get the crossover rate.
double CrossoverRate() const { return crossoverProb; }
//! Modify the crossover rate.
double& CrossoverRate() { return crossoverProb; }
//! Get the mutation probability.
double MutationProbability() const { return mutationProb; }
//! Modify the mutation probability.
double& MutationProbability() { return mutationProb; }
//! Get the mutation strength.
double MutationStrength() const { return mutationStrength; }
//! Modify the mutation strength.
double& MutationStrength() { return mutationStrength; }
//! Get the tolerance.
double Epsilon() const { return epsilon; }
//! Modify the tolerance.
double& Epsilon() { return epsilon; }
//! Retrieve value of lowerBound.
const arma::vec& LowerBound() const { return lowerBound; }
//! Modify value of lowerBound.
arma::vec& LowerBound() { return lowerBound; }
//! Retrieve value of upperBound.
const arma::vec& UpperBound() const { return upperBound; }
//! Modify value of upperBound.
arma::vec& UpperBound() { return upperBound; }
//! Retrieve the Pareto optimal points in variable space. This returns an empty cube
//! until `Optimize()` has been called.
const arma::cube& ParetoSet() const { return paretoSet; }
//! Retrieve the best front (the Pareto frontier). This returns an empty cube until
//! `Optimize()` has been called.
const arma::cube& ParetoFront() const { return paretoFront; }
/**
* Retrieve the best front (the Pareto frontier). This returns an empty
* vector until `Optimize()` has been called. Note that this function is
* deprecated and will be removed in ensmallen 3.x! Use `ParetoFront()`
* instead.
*/
ens_deprecated const std::vector<arma::mat>& Front()
{
if (rcFront.size() == 0)
{
// Match the old return format.
for (size_t i = 0; i < paretoFront.n_slices; ++i)
{
rcFront.push_back(arma::mat(paretoFront.slice(i)));
}
}
return rcFront;
}
private:
/**
* Evaluate objectives for the elite population.
*
* @tparam ArbitraryFunctionType std::tuple of multiple function types.
* @tparam MatType Type of matrix to optimize.
* @param population The elite population.
* @param objectives The set of objectives.
* @param calculatedObjectives Vector to store calculated objectives.
*/
template<std::size_t I = 0,
typename MatType,
typename ...ArbitraryFunctionType>
typename std::enable_if<I == sizeof...(ArbitraryFunctionType), void>::type
EvaluateObjectives(std::vector<MatType>&,
std::tuple<ArbitraryFunctionType...>&,
std::vector<arma::Col<typename MatType::elem_type> >&);
template<std::size_t I = 0,
typename MatType,
typename ...ArbitraryFunctionType>
typename std::enable_if<I < sizeof...(ArbitraryFunctionType), void>::type
EvaluateObjectives(std::vector<MatType>& population,
std::tuple<ArbitraryFunctionType...>& objectives,
std::vector<arma::Col<typename MatType::elem_type> >&
calculatedObjectives);
/**
* Reproduce candidates from the elite population to generate a new
* population.
*
* @tparam MatType Type of matrix to optimize.
* @param population The elite population.
* @param objectives The set of objectives.
* @param lowerBound Lower bound of the coordinates of the initial population.
* @param upperBound Upper bound of the coordinates of the initial population.
*/
template<typename MatType>
void BinaryTournamentSelection(std::vector<MatType>& population,
const MatType& lowerBound,
const MatType& upperBound);
/**
* Crossover two parents to create a pair of new children.
*
* @tparam MatType Type of matrix to optimize.
* @param childA A newly generated candidate.
* @param childB Another newly generated candidate.
* @param parentA First parent from elite population.
* @param parentB Second parent from elite population.
*/
template<typename MatType>
void Crossover(MatType& childA,
MatType& childB,
const MatType& parentA,
const MatType& parentB);
/**
* Mutate the coordinates for a candidate.
*
* @tparam MatType Type of matrix to optimize.
* @param child The candidate whose coordinates are being modified.
* @param objectives The set of objectives.
* @param lowerBound Lower bound of the coordinates of the initial population.
* @param upperBound Upper bound of the coordinates of the initial population.
*/
template<typename MatType>
void Mutate(MatType& child,
const MatType& lowerBound,
const MatType& upperBound);
/**
* Sort the candidate population using their domination count and the set of
* dominated nodes.
*
* @tparam MatType Type of matrix to optimize.
* @param fronts The population is sorted into these Pareto fronts. The first
* front is the best, the second worse and so on.
* @param ranks The assigned ranks, used for crowding distance based sorting.
* @param calculatedObjectives The previously calculated objectives.
*/
template<typename MatType>
void FastNonDominatedSort(
std::vector<std::vector<size_t> >& fronts,
std::vector<size_t>& ranks,
std::vector<arma::Col<typename MatType::elem_type> >& calculatedObjectives);
/**
* Operator to check if one candidate Pareto-dominates the other.
*
* A candidate is said to dominate the other if it is at least as good as the
* other candidate for all the objectives and there exists at least one
* objective for which it is strictly better than the other candidate.
*
* @tparam MatType Type of matrix to optimize.
* @param calculatedObjectives The previously calculated objectives.
* @param candidateP The candidate being compared from the elite population.
* @param candidateQ The candidate being compared against.
* @return true if candidateP Pareto dominates candidateQ, otherwise, false.
*/
template<typename MatType>
bool Dominates(
std::vector<arma::Col<typename MatType::elem_type> >& calculatedObjectives,
size_t candidateP,
size_t candidateQ);
/**
* Assigns crowding distance metric for sorting.
*
* @param front The previously generated Pareto fronts.
* @param calculatedObjectives The previously calculated objectives.
* @param crowdingDistance The crowding distance for each individual in
* the population.
*/
template <typename MatType>
void CrowdingDistanceAssignment(
const std::vector<size_t>& front,
std::vector<arma::Col<typename MatType::elem_type>>& calculatedObjectives,
std::vector<typename MatType::elem_type>& crowdingDistance);
/**
* The operator used in the crowding distance based sorting.
*
* If a candidates has a lower rank then it is preferred.
* Otherwise, if the ranks are equal then the candidate with the larger
* crowding distance is preferred.
*
* @param idxP The index of the first cadidate from the elite population being
* sorted.
* @param idxQ The index of the second cadidate from the elite population
* being sorted.
* @param ranks The previously calculated ranks.
* @param crowdingDistance The crowding distance for each individual in
* the population.
* @return true if the first candidate is preferred, otherwise, false.
*/
template<typename MatType>
bool CrowdingOperator(size_t idxP,
size_t idxQ,
const std::vector<size_t>& ranks,
const std::vector<typename MatType::elem_type>& crowdingDistance);
//! The number of objectives being optimised for.
size_t numObjectives;
//! The numbeer of variables used per objectives.
size_t numVariables;
//! The number of candidates in the population.
size_t populationSize;
//! Maximum number of generations before termination criteria is met.
size_t maxGenerations;
//! Probability that crossover will occur.
double crossoverProb;
//! Probability that mutation will occur.
double mutationProb;
//! Strength of the mutation.
double mutationStrength;
//! The tolerance for termination.
double epsilon;
//! Lower bound of the initial swarm.
arma::vec lowerBound;
//! Upper bound of the initial swarm.
arma::vec upperBound;
//! The set of all the Pareto optimal points.
//! Stored after Optimize() is called.
arma::cube paretoSet;
//! The set of all the Pareto optimal objective vectors.
//! Stored after Optimize() is called.
arma::cube paretoFront;
//! A different representation of the Pareto front, for reverse compatibility
//! purposes. This can be removed when ensmallen 3.x is released! (Along
//! with `Front()`.) This is only populated when `Front()` is called.
std::vector<arma::mat> rcFront;
};
} // namespace ens
// Include implementation.
#include "nsga2_impl.hpp"
#endif
+488
View File
@@ -0,0 +1,488 @@
/**
* @file nsga2_impl.hpp
* @author Sayan Goswami
* @author Nanubala Gnana Sai
*
* Implementation of the NSGA-II algorithm. Used for multi-objective
* optimization problems on arbitrary functions.
*
* ensmallen is free software; you may redistribute it and/or modify it under
* the terms of the 3-clause BSD license. You should have received a copy of
* the 3-clause BSD license along with ensmallen. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more Information.
*/
#ifndef ENSMALLEN_NSGA2_NSGA2_IMPL_HPP
#define ENSMALLEN_NSGA2_NSGA2_IMPL_HPP
#include "nsga2.hpp"
#include <assert.h>
namespace ens {
inline NSGA2::NSGA2(const size_t populationSize,
const size_t maxGenerations,
const double crossoverProb,
const double mutationProb,
const double mutationStrength,
const double epsilon,
const arma::vec& lowerBound,
const arma::vec& upperBound) :
numObjectives(0),
numVariables(0),
populationSize(populationSize),
maxGenerations(maxGenerations),
crossoverProb(crossoverProb),
mutationProb(mutationProb),
mutationStrength(mutationStrength),
epsilon(epsilon),
lowerBound(lowerBound),
upperBound(upperBound)
{ /* Nothing to do here. */ }
inline NSGA2::NSGA2(const size_t populationSize,
const size_t maxGenerations,
const double crossoverProb,
const double mutationProb,
const double mutationStrength,
const double epsilon,
const double lowerBound,
const double upperBound) :
numObjectives(0),
numVariables(0),
populationSize(populationSize),
maxGenerations(maxGenerations),
crossoverProb(crossoverProb),
mutationProb(mutationProb),
mutationStrength(mutationStrength),
epsilon(epsilon),
lowerBound(lowerBound * arma::ones(1, 1)),
upperBound(upperBound * arma::ones(1, 1))
{ /* Nothing to do here. */ }
//! Optimize the function.
template<typename MatType,
typename... ArbitraryFunctionType,
typename... CallbackTypes>
typename MatType::elem_type NSGA2::Optimize(
std::tuple<ArbitraryFunctionType...>& objectives,
MatType& iterateIn,
CallbackTypes&&... callbacks)
{
// Make sure for evolution to work at least four candidates are present.
if (populationSize < 4 && populationSize % 4 != 0)
{
throw std::logic_error("NSGA2::Optimize(): population size should be at"
" least 4, and, a multiple of 4!");
}
// Convenience typedefs.
typedef typename MatType::elem_type ElemType;
typedef typename MatTypeTraits<MatType>::BaseMatType BaseMatType;
BaseMatType& iterate = (BaseMatType&) iterateIn;
// Make sure that we have the methods that we need. Long name...
traits::CheckArbitraryFunctionTypeAPI<ArbitraryFunctionType...,
BaseMatType>();
RequireDenseFloatingPointType<BaseMatType>();
// Check if lower bound is a vector of a single dimension.
if (lowerBound.n_rows == 1)
lowerBound = lowerBound(0, 0) * arma::ones(iterate.n_rows, iterate.n_cols);
// Check if upper bound is a vector of a single dimension.
if (upperBound.n_rows == 1)
upperBound = upperBound(0, 0) * arma::ones(iterate.n_rows, iterate.n_cols);
// Check the dimensions of lowerBound and upperBound.
assert(lowerBound.n_rows == iterate.n_rows && "The dimensions of "
"lowerBound are not the same as the dimensions of iterate.");
assert(upperBound.n_rows == iterate.n_rows && "The dimensions of "
"upperBound are not the same as the dimensions of iterate.");
numObjectives = sizeof...(ArbitraryFunctionType);
numVariables = iterate.n_rows;
// Cache calculated objectives.
std::vector<arma::Col<ElemType> > calculatedObjectives(populationSize);
// Population size reserved to 2 * populationSize + 1 to accommodate
// for the size of intermediate candidate population.
std::vector<BaseMatType> population;
population.reserve(2 * populationSize + 1);
// Pareto fronts, initialized during non-dominated sorting.
// Stores indices of population belonging to a certain front.
std::vector<std::vector<size_t> > fronts;
// Initialised in CrowdingDistanceAssignment.
std::vector<ElemType> crowdingDistance;
// Initialised during non-dominated sorting.
std::vector<size_t> ranks;
//! Useful temporaries for float-like comparisons.
const BaseMatType castedLowerBound = arma::conv_to<BaseMatType>::from(lowerBound);
const BaseMatType castedUpperBound = arma::conv_to<BaseMatType>::from(upperBound);
// Controls early termination of the optimization process.
bool terminate = false;
// Generate the population based on a uniform distribution around the given
// starting point.
for (size_t i = 0; i < populationSize; i++)
{
population.push_back(arma::randu<BaseMatType>(iterate.n_rows,
iterate.n_cols) - 0.5 + iterate);
// Constrain all genes to be within bounds.
population[i] = arma::min(arma::max(population[i], castedLowerBound), castedUpperBound);
}
Info << "NSGA2 initialized successfully. Optimization started." << std::endl;
// Iterate until maximum number of generations is obtained.
terminate |= Callback::BeginOptimization(*this, objectives, iterate, callbacks...);
for (size_t generation = 1; generation <= maxGenerations && !terminate; generation++)
{
Info << "NSGA2: iteration " << generation << "." << std::endl;
// Create new population of candidate from the present elite population.
// Have P_t, generate G_t using P_t.
BinaryTournamentSelection(population, castedLowerBound, castedUpperBound);
// Evaluate the objectives for the new population.
calculatedObjectives.resize(population.size());
std::fill(calculatedObjectives.begin(), calculatedObjectives.end(),
arma::Col<ElemType>(numObjectives, arma::fill::zeros));
EvaluateObjectives(population, objectives, calculatedObjectives);
// Perform fast non dominated sort on P_t G_t.
ranks.resize(population.size());
FastNonDominatedSort<BaseMatType>(fronts, ranks, calculatedObjectives);
// Perform crowding distance assignment.
crowdingDistance.resize(population.size());
std::fill(crowdingDistance.begin(), crowdingDistance.end(), 0.);
for (size_t fNum = 0; fNum < fronts.size(); fNum++)
{
CrowdingDistanceAssignment<BaseMatType>(
fronts[fNum], calculatedObjectives, crowdingDistance);
}
// Sort based on crowding distance.
std::sort(population.begin(), population.end(),
[this, ranks, crowdingDistance, population]
(BaseMatType candidateP, BaseMatType candidateQ)
{
size_t idxP{}, idxQ{};
for (size_t i = 0; i < population.size(); i++)
{
if (arma::approx_equal(population[i], candidateP, "absdiff", epsilon))
idxP = i;
if (arma::approx_equal(population[i], candidateQ, "absdiff", epsilon))
idxQ = i;
}
return CrowdingOperator<BaseMatType>(idxP, idxQ, ranks, crowdingDistance);
}
);
// Yield a new population P_{t+1} of size populationSize.
// Discards unfit population from the R_{t} to yield P_{t+1}.
population.resize(populationSize);
terminate |= Callback::GenerationalStepTaken(*this, objectives, iterate,
calculatedObjectives, fronts, callbacks...);
}
// Set the candidates from the Pareto Set as the output.
paretoSet.set_size(population[0].n_rows, population[0].n_cols, fronts[0].size());
// The Pareto Set is stored, can be obtained via ParetoSet() getter.
for (size_t solutionIdx = 0; solutionIdx < fronts[0].size(); ++solutionIdx)
{
paretoSet.slice(solutionIdx) =
arma::conv_to<arma::mat>::from(population[fronts[0][solutionIdx]]);
}
// Set the candidates from the Pareto Front as the output.
paretoFront.set_size(calculatedObjectives[0].n_rows, calculatedObjectives[0].n_cols,
fronts[0].size());
// The Pareto Front is stored, can be obtained via ParetoFront() getter.
for (size_t solutionIdx = 0; solutionIdx < fronts[0].size(); ++solutionIdx)
{
paretoFront.slice(solutionIdx) =
arma::conv_to<arma::mat>::from(calculatedObjectives[fronts[0][solutionIdx]]);
}
// Clear rcFront, in case it is later requested by the user for reverse
// compatibility reasons.
rcFront.clear();
// Assign iterate to first element of the Pareto Set.
iterate = population[fronts[0][0]];
Callback::EndOptimization(*this, objectives, iterate, callbacks...);
ElemType performance = std::numeric_limits<ElemType>::max();
for (const arma::Col<ElemType>& objective: calculatedObjectives)
if (arma::accu(objective) < performance)
performance = arma::accu(objective);
return performance;
}
//! No objectives to evaluate.
template<std::size_t I,
typename MatType,
typename ...ArbitraryFunctionType>
typename std::enable_if<I == sizeof...(ArbitraryFunctionType), void>::type
NSGA2::EvaluateObjectives(
std::vector<MatType>&,
std::tuple<ArbitraryFunctionType...>&,
std::vector<arma::Col<typename MatType::elem_type> >&)
{
// Nothing to do here.
}
//! Evaluate the objectives for the entire population.
template<std::size_t I,
typename MatType,
typename ...ArbitraryFunctionType>
typename std::enable_if<I < sizeof...(ArbitraryFunctionType), void>::type
NSGA2::EvaluateObjectives(
std::vector<MatType>& population,
std::tuple<ArbitraryFunctionType...>& objectives,
std::vector<arma::Col<typename MatType::elem_type> >& calculatedObjectives)
{
for (size_t i = 0; i < populationSize; i++)
{
calculatedObjectives[i](I) = std::get<I>(objectives).Evaluate(population[i]);
EvaluateObjectives<I+1, MatType, ArbitraryFunctionType...>(population, objectives,
calculatedObjectives);
}
}
//! Reproduce and generate new candidates.
template<typename MatType>
inline void NSGA2::BinaryTournamentSelection(std::vector<MatType>& population,
const MatType& lowerBound,
const MatType& upperBound)
{
std::vector<MatType> children;
while (children.size() < population.size())
{
// Choose two random parents for reproduction from the elite population.
size_t indexA = arma::randi<size_t>(arma::distr_param(0, populationSize - 1));
size_t indexB = arma::randi<size_t>(arma::distr_param(0, populationSize - 1));
// Make sure that the parents differ.
if (indexA == indexB)
{
if (indexB < populationSize - 1)
indexB++;
else
indexB--;
}
// Initialize the children to the respective parents.
MatType childA = population[indexA], childB = population[indexB];
Crossover(childA, childB, population[indexA], population[indexB]);
Mutate(childA, lowerBound, upperBound);
Mutate(childB, lowerBound, upperBound);
// Add the children to the candidate population.
children.push_back(childA);
children.push_back(childB);
}
// Add the candidates to the elite population.
population.insert(std::end(population), std::begin(children), std::end(children));
}
//! Perform crossover of genes for the children.
template<typename MatType>
inline void NSGA2::Crossover(MatType& childA,
MatType& childB,
const MatType& parentA,
const MatType& parentB)
{
// Indices at which crossover is to occur.
const arma::umat idx = arma::randu<MatType>(childA.n_rows, childA.n_cols) < crossoverProb;
// Use traits from parentA for indices where idx is 1 and parentB otherwise.
childA = parentA % idx + parentB % (1 - idx);
// Use traits from parentB for indices where idx is 1 and parentA otherwise.
childB = parentA % (1 - idx) + parentA % idx;
}
//! Perform mutation of the candidates weights with some noise.
template<typename MatType>
inline void NSGA2::Mutate(MatType& child,
const MatType& lowerBound,
const MatType& upperBound)
{
child += (arma::randu<MatType>(child.n_rows, child.n_cols) < mutationProb) %
(mutationStrength * arma::randn<MatType>(child.n_rows, child.n_cols));
// Constrain all genes to be between bounds.
child = arma::min(arma::max(child, lowerBound), upperBound);
}
//! Sort population into Pareto fronts.
template<typename MatType>
inline void NSGA2::FastNonDominatedSort(
std::vector<std::vector<size_t> >& fronts,
std::vector<size_t>& ranks,
std::vector<arma::Col<typename MatType::elem_type> >& calculatedObjectives)
{
std::map<size_t, size_t> dominationCount;
std::map<size_t, std::set<size_t> > dominated;
// Reset and initialize fronts.
fronts.clear();
fronts.push_back(std::vector<size_t>());
for (size_t p = 0; p < populationSize; p++)
{
dominated[p] = std::set<size_t>();
dominationCount[p] = 0;
for (size_t q = 0; q < populationSize; q++)
{
if (Dominates<MatType>(calculatedObjectives, p, q))
dominated[p].insert(q);
else if (Dominates<MatType>(calculatedObjectives, q, p))
dominationCount[p] += 1;
}
if (dominationCount[p] == 0)
{
ranks[p] = 0;
fronts[0].push_back(p);
}
}
size_t i = 0;
while (!fronts[i].empty())
{
std::vector<size_t> nextFront;
for (size_t p: fronts[i])
{
for (size_t q: dominated[p])
{
dominationCount[q]--;
if (dominationCount[q] == 0)
{
ranks[q] = i + 1;
nextFront.push_back(q);
}
}
}
i++;
fronts.push_back(nextFront);
}
// Remove the empty final set.
fronts.pop_back();
}
//! Check if a candidate Pareto dominates another candidate.
template<typename MatType>
inline bool NSGA2::Dominates(
std::vector<arma::Col<typename MatType::elem_type> >& calculatedObjectives,
size_t candidateP,
size_t candidateQ)
{
bool allBetterOrEqual = true;
bool atleastOneBetter = false;
size_t n_objectives = calculatedObjectives[0].n_elem;
for (size_t i = 0; i < n_objectives; i++)
{
// P is worse than Q for the i-th objective function.
if (calculatedObjectives[candidateP](i) > calculatedObjectives[candidateQ](i))
allBetterOrEqual = false;
// P is better than Q for the i-th objective function.
else if (calculatedObjectives[candidateP](i) < calculatedObjectives[candidateQ](i))
atleastOneBetter = true;
}
return allBetterOrEqual && atleastOneBetter;
}
//! Assign crowding distance to the population.
template <typename MatType>
inline void NSGA2::CrowdingDistanceAssignment(
const std::vector<size_t>& front,
std::vector<arma::Col<typename MatType::elem_type>>& calculatedObjectives,
std::vector<typename MatType::elem_type>& crowdingDistance)
{
// Convenience typedefs.
typedef typename MatType::elem_type ElemType;
size_t fSize = front.size();
// Stores the sorted indices of the fronts.
arma::uvec sortedIdx = arma::regspace<arma::uvec>(0, 1, fSize - 1);
for (size_t m = 0; m < numObjectives; m++)
{
// Cache fValues of individuals for current objective.
arma::Col<ElemType> fValues(fSize);
std::transform(front.begin(), front.end(), fValues.begin(),
[&](const size_t& individual)
{
return calculatedObjectives[individual](m);
});
// Sort front indices by ascending fValues for current objective.
std::sort(sortedIdx.begin(), sortedIdx.end(),
[&](const size_t& frontIdxA, const size_t& frontIdxB)
{
return (fValues(frontIdxA) < fValues(frontIdxB));
});
crowdingDistance[front[sortedIdx(0)]] =
std::numeric_limits<ElemType>::max();
crowdingDistance[front[sortedIdx(fSize - 1)]] =
std::numeric_limits<ElemType>::max();
ElemType minFval = fValues(sortedIdx(0));
ElemType maxFval = fValues(sortedIdx(fSize - 1));
ElemType scale =
std::abs(maxFval - minFval) == 0. ? 1. : std::abs(maxFval - minFval);
for (size_t i = 1; i < fSize - 1; i++)
{
crowdingDistance[front[sortedIdx(i)]] +=
(fValues(sortedIdx(i + 1)) - fValues(sortedIdx(i - 1))) / scale;
}
}
}
//! Comparator for crowding distance based sorting.
template<typename MatType>
inline bool NSGA2::CrowdingOperator(size_t idxP,
size_t idxQ,
const std::vector<size_t>& ranks,
const std::vector<typename MatType::elem_type>& crowdingDistance)
{
if (ranks[idxP] < ranks[idxQ])
return true;
else if (ranks[idxP] == ranks[idxQ] && crowdingDistance[idxP] > crowdingDistance[idxQ])
return true;
return false;
}
} // namespace ens
#endif
+1 -1
View File
@@ -113,7 +113,7 @@ class Padam
{
return optimizer.template Optimize<
SeparableFunctionType, MatType, GradType, CallbackTypes...>(
function, iterate, callbacks...);
function, iterate, std::forward<CallbackTypes>(callbacks)...);
}
//! Forward the MatType as GradType.
@@ -22,6 +22,8 @@ namespace ens {
* HOGWILD! approach.
*
* For more information, see the following.
*
* @code
* @misc{1106.5730,
* Author = {Feng Niu and Benjamin Recht and Christopher Re and Stephen J.
* Wright},
@@ -30,6 +32,7 @@ namespace ens {
* Year = {2011},
* Eprint = {arXiv:1106.5730},
* }
* @endcode
*
* ParallelSGD can optimize sparse differentiable separable functions. For more
* details, see the documentation on function types included with this
@@ -59,10 +59,6 @@ class AckleyFunction
//! Return 1 (the number of functions).
size_t NumFunctions() const { return 1; }
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("-5.0; 5.0"); }
/**
* Evaluate a function for a particular batch-size.
*
@@ -116,6 +112,22 @@ class AckleyFunction
//! Modify the value used for numerical stability.
double& Epsilon() { return epsilon; }
// Note: GetInitialPoint(), GetFinalPoint(), and GetFinalObjective() are not
// required for using ensmallen to optimize this function! They are
// specifically used as a convenience just for ensmallen's testing
// infrastructure.
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("0.02; 0.02"); }
//! Get the final point.
template<typename MatType = arma::mat>
MatType GetFinalPoint() const { return MatType("0.0; 0.0"); }
//! Get the final objective.
double GetFinalObjective() const { return 0.0; }
private:
//! The value of the multiplicative constant.
double c;
@@ -129,14 +129,15 @@ inline typename MatType::elem_type GockenbachFunction::EvaluateConstraint(
switch (index)
{
case 0: // g(x) = (x_3 - x_2 - x_1 - 1) = 0
constraint = (coordinates[2] - coordinates[1] - coordinates[0] - 1);
constraint = (coordinates[2] - coordinates[1] - coordinates[0] -
typename MatType::elem_type(1));
break;
case 1: // h(x) = (x_3 - x_1^2) >= 0
// To deal with the inequality, the constraint will simply evaluate to 0
// when h(x) >= 0.
constraint = std::min(0.0,
(coordinates[2] - std::pow(coordinates[0], 2)));
constraint = std::min(typename MatType::elem_type(0), (coordinates[2] -
std::pow(coordinates[0], typename MatType::elem_type(2))));
break;
}
@@ -52,10 +52,6 @@ class BealeFunction
//! Return 1 (the number of functions).
size_t NumFunctions() const { return 1; }
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("-4.5; 4.5"); }
/**
* Evaluate a function for a particular batch-size.
*
@@ -98,6 +94,22 @@ class BealeFunction
*/
template<typename MatType, typename GradType>
void Gradient(const MatType& coordinates, GradType& gradient);
// Note: GetInitialPoint(), GetFinalPoint(), and GetFinalObjective() are not
// required for using ensmallen to optimize this function! They are
// specifically used as a convenience just for ensmallen's testing
// infrastructure.
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("2.8; 0.35"); }
//! Get the final point.
template<typename MatType = arma::mat>
MatType GetFinalPoint() const { return MatType("3.0; 0.5"); }
//! Get the final objective.
double GetFinalObjective() const { return 0.0; }
};
} // namespace test
@@ -52,10 +52,6 @@ class BoothFunction
//! Return 1 (the number of functions).
size_t NumFunctions() const { return 1; }
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("-9; -9"); }
/**
* Evaluate a function for a particular batch-size.
*
@@ -98,6 +94,22 @@ class BoothFunction
*/
template<typename MatType, typename GradType>
void Gradient(const MatType& coordinates, GradType& gradient);
// Note: GetInitialPoint(), GetFinalPoint(), and GetFinalObjective() are not
// required for using ensmallen to optimize this function! They are
// specifically used as a convenience just for ensmallen's testing
// infrastructure.
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("-9; -9"); }
//! Get the final point.
template<typename MatType = arma::mat>
MatType GetFinalPoint() const { return MatType("1.0; 3.0"); }
//! Get the final objective.
double GetFinalObjective() const { return 0.0; }
};
} // namespace test
@@ -57,10 +57,6 @@ class BukinFunction
//! Return 1 (the number of functions).
size_t NumFunctions() const { return 1; }
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("-10; -2.0"); }
/**
* Evaluate a function for a particular batch-size.
*
@@ -109,6 +105,22 @@ class BukinFunction
//! Modify the value used for numerical stability.
double& Epsilon() { return epsilon; }
// Note: GetInitialPoint(), GetFinalPoint(), and GetFinalObjective() are not
// required for using ensmallen to optimize this function! They are
// specifically used as a convenience just for ensmallen's testing
// infrastructure.
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("-10; -2.0"); }
//! Get the final point.
template<typename MatType = arma::mat>
MatType GetFinalPoint() const { return MatType("-10.0; 1.0"); }
//! Get the final objective.
double GetFinalObjective() const { return 0.0; }
private:
//! The value used for numerical stability.
double epsilon;
@@ -53,10 +53,6 @@ class ColvilleFunction
//! Return 1 (the number of functions).
size_t NumFunctions() const { return 1; }
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("-5; 3; 1; -9"); }
/**
* Evaluate a function for a particular batch-size.
*
@@ -99,6 +95,22 @@ class ColvilleFunction
*/
template<typename MatType, typename GradType>
void Gradient(const MatType& coordinates, GradType& gradient) const;
// Note: GetInitialPoint(), GetFinalPoint(), and GetFinalObjective() are not
// required for using ensmallen to optimize this function! They are
// specifically used as a convenience just for ensmallen's testing
// infrastructure.
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("-5; 3; 1; -9"); }
//! Get the final point.
template<typename MatType = arma::mat>
MatType GetFinalPoint() const { return MatType("1; 1; 1; 1"); }
//! Get the final objective.
double GetFinalObjective() const { return 0.0; }
};
} // namespace test
@@ -57,10 +57,6 @@ class CrossInTrayFunction
//! Return 1 (the number of functions).
size_t NumFunctions() const { return 1; }
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("0; 0"); }
/*
* Evaluate a function for a particular batch-size.
*
@@ -80,6 +76,14 @@ class CrossInTrayFunction
*/
template<typename MatType>
typename MatType::elem_type Evaluate(const MatType& coordinates) const;
// Note: GetInitialPoint() is not required for using ensmallen to optimize
// this function! It is specifically used as a convenience just for
// ensmallen's testing infrastructure.
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("0; 0"); }
};
} // namespace test
@@ -52,10 +52,6 @@ class DropWaveFunction
//! Return 1 (the number of functions).
size_t NumFunctions() const { return 1; }
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("0.5; 0.5"); }
/**
* Evaluate a function for a particular batch-size.
*
@@ -98,6 +94,22 @@ class DropWaveFunction
*/
template<typename MatType, typename GradType>
void Gradient(const MatType& coordinates, GradType& gradient);
// Note: GetInitialPoint(), GetFinalPoint(), and GetFinalObjective() are not
// required for using ensmallen to optimize this function! They are
// specifically used as a convenience just for ensmallen's testing
// infrastructure.
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("0.5; 0.5"); }
//! Get the final point.
template<typename MatType = arma::mat>
MatType GetFinalPoint() const { return MatType("0.0; 0.0"); }
//! Get the final objective.
double GetFinalObjective() const { return 0.0; }
};
} // namespace test
@@ -52,10 +52,6 @@ class EasomFunction
//! Return 1 (the number of functions).
size_t NumFunctions() const { return 1; }
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("-90.0; 90.0"); }
/**
* Evaluate a function for a particular batch-size.
*
@@ -98,6 +94,22 @@ class EasomFunction
*/
template<typename MatType, typename GradType>
void Gradient(const MatType& coordinates, GradType& gradient);
// Note: GetInitialPoint(), GetFinalPoint(), and GetFinalObjective() are not
// required for using ensmallen to optimize this function! They are
// specifically used as a convenience just for ensmallen's testing
// infrastructure.
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("2.9; 2.9"); }
//! Get the final point.
template<typename MatType = arma::mat>
MatType GetFinalPoint() const { return MatType("3.14; 3.14"); }
//! Get the final objective.
double GetFinalObjective() const { return -1.0; }
};
} // namespace test
@@ -53,10 +53,6 @@ class EggholderFunction
//! Return 1 (the number of functions).
size_t NumFunctions() const { return 1; }
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("-333; -333"); }
/**
* Evaluate a function for a particular batch-size.
*
@@ -99,6 +95,22 @@ class EggholderFunction
*/
template<typename MatType, typename GradType>
void Gradient(const MatType& coordinates, GradType& gradient);
// Note: GetInitialPoint(), GetFinalPoint(), and GetFinalObjective() are not
// required for using ensmallen to optimize this function! They are
// specifically used as a convenience just for ensmallen's testing
// infrastructure.
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("-333; -333"); }
//! Get the final point.
template<typename MatType = arma::mat>
MatType GetFinalPoint() const { return MatType("512; 404.2319"); }
//! Get the final objective.
double GetFinalObjective() const { return -959.6407; }
};
} // namespace test
@@ -0,0 +1,106 @@
/**
* @file fonseca_fleming_function_n1.hpp
* @author Sayan Goswami
*
* Implementation of Fonseca Fleming function.
*
* ensmallen is free software; you may redistribute it and/or modify it under
* the terms of the 3-clause BSD license. You should have received a copy of
* the 3-clause BSD license along with ensmallen. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef ENSMALLEN_PROBLEMS_FONSECA_FLEEMING_FUNCTION_HPP
#define ENSMALLEN_PROBLEMS_FONSECA_FLEEMING_FUNCTION_HPP
#include <tuple>
namespace ens {
namespace test {
/**
* The Fonseca Fleming function N.1 is defined by
*
* \f[
* f_{1}\left(\boldsymbol{x}\right) = 1 - \exp \left[-\sum_{i=1}^{3} \left(x_{i} - \frac{1}{\sqrt{n}} \right)^{2} \right] \\
* f_{2}\left(\boldsymbol{x}\right) = 1 - \exp \left[-\sum_{i=1}^{3} \left(x_{i} + \frac{1}{\sqrt{n}} \right)^{2} \right] \\
* \f]
*
* The optimal solutions to this multi-objective function lie in the
* range [-1/sqrt(3), 1/sqrt(3)].
*
* @tparam arma::mat Type of matrix to optimize.
*/
template<typename MatType = arma::mat>
class FonsecaFlemingFunction
{
private:
size_t numObjectives;
size_t numVariables;
public:
FonsecaFlemingFunction() : numObjectives(2), numVariables(3)
{/* Nothing to do here. */}
/**
* Evaluate the objectives with the given coordinate.
*
* @param coords The function coordinates.
* @return arma::Col<typename MatType::elem_type>
*/
arma::Col<typename MatType::elem_type> Evaluate(const MatType& coords)
{
// Convenience typedef.
typedef typename MatType::elem_type ElemType;
arma::Col<ElemType> objectives(numObjectives);
objectives(0) = objectiveA.Evaluate(coords);
objectives(1) = objectiveB.Evaluate(coords);
return objectives;
}
//! Get the starting point.
MatType GetInitialPoint()
{
// Convenience typedef.
typedef typename MatType::elem_type ElemType;
return arma::Col<ElemType>(numVariables, 1, arma::fill::zeros);
}
struct ObjectiveA
{
typename MatType::elem_type Evaluate(const MatType& coords)
{
return 1.0 - exp(
-pow(static_cast<double>(coords[0]) - 1.0 / sqrt(3.0), 2.0)
-pow(static_cast<double>(coords[1]) - 1.0 / sqrt(3.0), 2.0)
-pow(static_cast<double>(coords[2]) - 1.0 / sqrt(3.0), 2.0)
);
}
} objectiveA;
struct ObjectiveB
{
typename MatType::elem_type Evaluate(const MatType& coords)
{
return 1.0 - exp(
-pow(static_cast<double>(coords[0]) + 1.0 / sqrt(3.0), 2.0)
-pow(static_cast<double>(coords[1]) + 1.0 / sqrt(3.0), 2.0)
-pow(static_cast<double>(coords[2]) + 1.0 / sqrt(3.0), 2.0)
);
}
} objectiveB;
//! Get objective functions.
std::tuple<ObjectiveA, ObjectiveB> GetObjectives()
{
return std::make_tuple(objectiveA, objectiveB);
}
};
} // namespace test
} // namespace ens
#endif
@@ -61,13 +61,6 @@ class GeneralizedRosenbrockFunction
//! Return 1 (the number of functions).
size_t NumFunctions() const { return n - 1; }
//! Get the starting point.
template<typename MatType = arma::mat>
const MatType GetInitialPoint() const
{
return arma::conv_to<MatType>::from(initialPoint);
}
/**
* Evaluate a function for a particular batch-size.
*
@@ -111,6 +104,28 @@ class GeneralizedRosenbrockFunction
template<typename MatType, typename GradType>
void Gradient(const MatType& coordinates, GradType& gradient) const;
// Note: GetInitialPoint(), GetFinalPoint(), and GetFinalObjective() are not
// required for using ensmallen to optimize this function! They are
// specifically used as a convenience just for ensmallen's testing
// infrastructure.
//! Get the starting point.
template<typename MatType = arma::mat>
const MatType GetInitialPoint() const
{
return arma::conv_to<MatType>::from(initialPoint);
}
//! Get the final point.
template<typename MatType = arma::mat>
const MatType GetFinalPoint() const
{
return arma::ones<MatType>(initialPoint.n_rows, initialPoint.n_cols);
}
//! Get the final objective.
double GetFinalObjective() const { return 0.0; }
private:
//! Locally-stored Initial point.
arma::mat initialPoint;
@@ -61,10 +61,6 @@ class GoldsteinPriceFunction
//! Return 1 (the number of functions).
size_t NumFunctions() const { return 1; }
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("-2; 2"); }
/**
* Evaluate a function for a particular batch-size.
*
@@ -107,6 +103,22 @@ class GoldsteinPriceFunction
*/
template<typename MatType, typename GradType>
void Gradient(const MatType& coordinates, GradType& gradient);
// Note: GetInitialPoint(), GetFinalPoint(), and GetFinalObjective() are not
// required for using ensmallen to optimize this function! They are
// specifically used as a convenience just for ensmallen's testing
// infrastructure.
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("0.2; -0.5"); }
//! Get the final point.
template<typename MatType = arma::mat>
MatType GetFinalPoint() const { return MatType("0.0; -1.0"); }
//! Get the final objective.
double GetFinalObjective() const { return 3.0; }
};
} // namespace test
@@ -25,10 +25,6 @@ class GDTestFunction
//! Nothing to do for the constructor.
GDTestFunction() { }
//! Get the starting point.
template<typename MatType>
MatType GetInitialPoint() const { return MatType("1; 3; 2"); }
//! Evaluate a function.
template<typename MatType>
typename MatType::elem_type Evaluate(const MatType& coordinates) const;
@@ -36,6 +32,22 @@ class GDTestFunction
//! Evaluate the gradient of a function.
template<typename MatType, typename GradType>
void Gradient(const MatType& coordinates, GradType& gradient) const;
// Note: GetInitialPoint(), GetFinalPoint(), and GetFinalObjective() are not
// required for using ensmallen to optimize this function! They are
// specifically used as a convenience just for ensmallen's testing
// infrastructure.
//! Get the starting point.
template<typename MatType>
MatType GetInitialPoint() const { return MatType("1; 3; 2"); }
//! Get the final point.
template<typename MatType = arma::mat>
MatType GetFinalPoint() const { return MatType("0; 0; 0"); }
//! Get the final objective.
double GetFinalObjective() const { return 0.0; }
};
} // namespace test
@@ -48,10 +48,6 @@ class LevyFunctionN13
//! Return 1 (the number of functions).
size_t NumFunctions() const { return 1; }
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("-10; 10"); }
/**
* Evaluate a function for a particular batch-size.
*
@@ -94,6 +90,22 @@ class LevyFunctionN13
*/
template<typename MatType, typename GradType>
void Gradient(const MatType& coordinates, GradType& gradient);
// Note: GetInitialPoint(), GetFinalPoint(), and GetFinalObjective() are not
// required for using ensmallen to optimize this function! They are
// specifically used as a convenience just for ensmallen's testing
// infrastructure.
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("0.9; 1.1"); }
//! Get the final point.
template<typename MatType = arma::mat>
MatType GetFinalPoint() const { return MatType("1.0; 1.0"); }
//! Get the final objective.
double GetFinalObjective() const { return 0.0; }
};
} // namespace test
@@ -52,10 +52,6 @@ class MatyasFunction
//! Return 1 (the number of functions).
size_t NumFunctions() const { return 1; }
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("-3; 3"); }
/**
* Evaluate a function for a particular batch-size.
*
@@ -98,6 +94,22 @@ class MatyasFunction
*/
template<typename MatType, typename GradType>
void Gradient(const MatType& coordinates, GradType& gradient);
// Note: GetInitialPoint(), GetFinalPoint(), and GetFinalObjective() are not
// required for using ensmallen to optimize this function! They are
// specifically used as a convenience just for ensmallen's testing
// infrastructure.
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("-3; 3"); }
//! Get the final point.
template<typename MatType = arma::mat>
MatType GetFinalPoint() const { return MatType("0.0; 0.0"); }
//! Get the final objective.
double GetFinalObjective() const { return 0.0; }
};
} // namespace test
@@ -52,10 +52,6 @@ class McCormickFunction
//! Return 1 (the number of functions).
size_t NumFunctions() const { return 1; }
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("-2; 4"); }
/**
* Evaluate a function for a particular batch-size.
*
@@ -98,6 +94,22 @@ class McCormickFunction
*/
template<typename MatType, typename GradType>
void Gradient(const MatType& coordinates, GradType& gradient);
// Note: GetInitialPoint(), GetFinalPoint(), and GetFinalObjective() are not
// required for using ensmallen to optimize this function! They are
// specifically used as a convenience just for ensmallen's testing
// infrastructure.
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("-2; 4"); }
//! Get the final point.
template<typename MatType = arma::mat>
MatType GetFinalPoint() const { return MatType("-0.54719; -1.54719"); }
//! Get the final objective.
double GetFinalObjective() const { return -1.9133; }
};
} // namespace test
@@ -17,6 +17,7 @@
#include "drop_wave_function.hpp"
#include "easom_function.hpp"
#include "eggholder_function.hpp"
#include "fonseca_fleming_function.hpp"
#include "fw_test_function.hpp"
#include "generalized_rosenbrock_function.hpp"
#include "goldstein_price_function.hpp"
@@ -30,6 +31,7 @@
#include "rastrigin_function.hpp"
#include "rosenbrock_function.hpp"
#include "rosenbrock_wood_function.hpp"
#include "schaffer_function_n1.hpp"
#include "schaffer_function_n2.hpp"
#include "schaffer_function_n4.hpp"
#include "schwefel_function.hpp"
@@ -40,5 +42,10 @@
#include "styblinski_tang_function.hpp"
#include "three_hump_camel_function.hpp"
#include "wood_function.hpp"
#include "zdt/zdt1_function.hpp"
#include "zdt/zdt2_function.hpp"
#include "zdt/zdt3_function.hpp"
#include "zdt/zdt4_function.hpp"
#include "zdt/zdt6_function.hpp"
#endif
@@ -44,24 +44,17 @@ class RastriginFunction
*
* @param n Number of dimensions for the function.
*/
RastriginFunction(const size_t n);
RastriginFunction(const size_t n = 2);
/**
* Shuffle the order of function visitation. This may be called by the
* optimizer.
*/
void Shuffle();
void Shuffle();
//! Return 1 (the number of functions).
size_t NumFunctions() const { return n; }
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const
{
return arma::conv_to<MatType>::from(initialPoint);
}
/**
* Evaluate a function for a particular batch-size.
*
@@ -104,6 +97,29 @@ class RastriginFunction
*/
template<typename MatType, typename GradType>
void Gradient(const MatType& coordinates, GradType& gradient);
// Note: GetInitialPoint(), GetFinalPoint(), and GetFinalObjective() are not
// required for using ensmallen to optimize this function! They are
// specifically used as a convenience just for ensmallen's testing
// infrastructure.
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const
{
return arma::conv_to<MatType>::from(initialPoint);
}
//! Get the final point.
template<typename MatType = arma::mat>
MatType GetFinalPoint() const
{
return arma::zeros<MatType>(initialPoint.n_rows, initialPoint.n_cols);
}
//! Get the final objective.
double GetFinalObjective() const { return 0.0; }
private:
//! Number of dimensions for the function.
size_t n;
@@ -55,16 +55,6 @@ class RosenbrockFunction
//! Return 1 (the number of functions).
size_t NumFunctions() const { return 1; }
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const
{
MatType m(2, 1);
m[0] = -1.2;
m[1] = 1.0;
return m;
}
/**
* Evaluate a function for a particular batch-size.
*
@@ -114,6 +104,22 @@ class RosenbrockFunction
template<typename MatType, typename GradType>
typename MatType::elem_type EvaluateWithGradient(const MatType& coordinates,
GradType& gradient) const;
// Note: GetInitialPoint(), GetFinalPoint(), and GetFinalObjective() are not
// required for using ensmallen to optimize this function! They are
// specifically used as a convenience just for ensmallen's testing
// infrastructure.
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("-1.2; 1.0"); }
//! Get the final point.
template<typename MatType = arma::mat>
MatType GetFinalPoint() const { return MatType("1.0; 1.0"); }
//! Get the final objective.
double GetFinalObjective() const { return 0.0; }
};
} // namespace test
@@ -39,13 +39,6 @@ class RosenbrockWoodFunction
//! Return 1 (the number of functions).
size_t NumFunctions() const { return 1; }
//! Get the starting point.
template<typename MatType = arma::mat>
const MatType GetInitialPoint() const
{
return arma::conv_to<MatType>::from(initialPoint);
}
/**
* Evaluate a function for a particular batch-size.
*
@@ -89,6 +82,28 @@ class RosenbrockWoodFunction
template<typename MatType, typename GradType>
void Gradient(const MatType& coordinates, GradType& gradient) const;
// Note: GetInitialPoint(), GetFinalPoint(), and GetFinalObjective() are not
// required for using ensmallen to optimize this function! They are
// specifically used as a convenience just for ensmallen's testing
// infrastructure.
//! Get the starting point.
template<typename MatType = arma::mat>
const MatType GetInitialPoint() const
{
return arma::conv_to<MatType>::from(initialPoint);
}
//! Get the final point.
template<typename MatType = arma::mat>
MatType GetFinalPoint() const
{
return arma::ones<MatType>(initialPoint.n_rows, initialPoint.n_cols);
}
//! Get the final objective.
double GetFinalObjective() const { return 0.0; }
private:
//! Locally-stored initial point.
arma::mat initialPoint;
@@ -0,0 +1,97 @@
/**
* @file schaffer_function_n1.hpp
* @author Sayan Goswami
*
* Implementation of Schaffer function N.1.
*
* ensmallen is free software; you may redistribute it and/or modify it under
* the terms of the 3-clause BSD license. You should have received a copy of
* the 3-clause BSD license along with ensmallen. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef ENSMALLEN_PROBLEMS_SCHAFFER_FUNCTION_N1_HPP
#define ENSMALLEN_PROBLEMS_SCHAFFER_FUNCTION_N1_HPP
namespace ens {
namespace test {
/**
* The Schaffer function N.1 is defined by
*
* \f[
* f_1(x) = x^2
* f_2(x) = (x-2)^2
* \f]
*
* The optimal solutions to this multi-objective function lie in the
* range [0, 2].
*
* @tparam arma::mat Type of matrix to optimize.
*/
template<typename MatType = arma::mat>
class SchafferFunctionN1
{
private:
size_t numObjectives;
size_t numVariables;
public:
//! Initialize the SchafferFunctionN1
SchafferFunctionN1() : numObjectives(2), numVariables(1)
{/* Nothing to do here. */}
/**
* Evaluate the objectives with the given coordinate.
*
* @param coords The function coordinates.
* @return arma::Col<typename MatType::elem_type>
*/
arma::Col<typename MatType::elem_type> Evaluate(const MatType& coords)
{
// Convenience typedef.
typedef typename MatType::elem_type ElemType;
arma::Col<ElemType> objectives(numObjectives);
objectives(0) = std::pow(coords[0], 2);
objectives(1) = std::pow(coords[0] - 2, 2);
return objectives;
}
//! Get the starting point.
MatType GetInitialPoint()
{
// Convenience typedef.
typedef typename MatType::elem_type ElemType;
return arma::Col<ElemType>(numVariables, 1, arma::fill::zeros);
}
struct ObjectiveA
{
typename MatType::elem_type Evaluate(const MatType& coords)
{
return std::pow(coords[0], 2);
}
} objectiveA;
struct ObjectiveB
{
typename MatType::elem_type Evaluate(const MatType& coords)
{
return std::pow(coords[0] - 2, 2);
}
} objectiveB;
//! Get objective functions.
std::tuple<ObjectiveA, ObjectiveB> GetObjectives()
{
return std::make_tuple(objectiveA, objectiveB);
}
};
} // namespace test
} // namespace ens
#endif
@@ -41,7 +41,7 @@ namespace test {
class SchafferFunctionN2
{
public:
//! Initialize the SchafferFunctionN4.
//! Initialize the SchafferFunctionN2.
SchafferFunctionN2();
/**
@@ -53,10 +53,6 @@ class SchafferFunctionN2
//! Return 1 (the number of functions).
size_t NumFunctions() const { return 1; }
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("-100; 100"); }
/**
* Evaluate a function for a particular batch-size.
*
@@ -99,6 +95,22 @@ class SchafferFunctionN2
*/
template<typename MatType, typename GradType>
void Gradient(const MatType& coordinates, GradType& gradient);
// Note: GetInitialPoint(), GetFinalPoint(), and GetFinalObjective() are not
// required for using ensmallen to optimize this function! They are
// specifically used as a convenience just for ensmallen's testing
// infrastructure.
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("-100; 100"); }
//! Get the final point.
template<typename MatType = arma::mat>
MatType GetFinalPoint() const { return MatType("0.0; 0.0"); }
//! Get the final objective.
double GetFinalObjective() const { return 0.0; }
};
} // namespace test
@@ -55,13 +55,6 @@ class SchwefelFunction
//! Return 1 (the number of functions).
size_t NumFunctions() const { return n; }
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const
{
return arma::conv_to<MatType>::from(initialPoint);
}
/**
* Evaluate a function for a particular batch-size.
*
@@ -104,6 +97,31 @@ class SchwefelFunction
*/
template<typename MatType, typename GradType>
void Gradient(const MatType& coordinates, GradType& gradient);
// Note: GetInitialPoint(), GetFinalPoint(), and GetFinalObjective() are not
// required for using ensmallen to optimize this function! They are
// specifically used as a convenience just for ensmallen's testing
// infrastructure.
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const
{
return arma::conv_to<MatType>::from(initialPoint);
}
//! Get the final point.
template<typename MatType = arma::mat>
MatType GetFinalPoint() const
{
MatType result(initialPoint.n_rows, initialPoint.n_cols, arma::fill::none);
result.fill(420.9687);
return result;
}
//! Get the final objective.
double GetFinalObjective() const { return 0.0; }
private:
//! Number of dimensions for the function.
size_t n;
@@ -37,10 +37,6 @@ class SGDTestFunction
//! Return 3 (the number of functions).
size_t NumFunctions() const { return 3; }
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("6; -45.6; 6.2"); }
//! Evaluate a function for a particular batch-size.
template<typename MatType>
typename MatType::elem_type Evaluate(const MatType& coordinates,
@@ -53,6 +49,22 @@ class SGDTestFunction
const size_t begin,
GradType& gradient,
const size_t batchSize) const;
// Note: GetInitialPoint(), GetFinalPoint(), and GetFinalObjective() are not
// required for using ensmallen to optimize this function! They are
// specifically used as a convenience just for ensmallen's testing
// infrastructure.
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("6; -45.6; 6.2"); }
//! Get the final point.
template<typename MatType = arma::mat>
MatType GetFinalPoint() const { return MatType("0.0; 0.0; 0.0"); }
//! Get the final objective.
double GetFinalObjective() const { return -1.0; }
};
} // namespace test
@@ -32,10 +32,6 @@ class SparseTestFunction
//! Return 4 (the number of features).
size_t NumFeatures() const { return 4; }
//! Get the starting point.
template<typename MatType>
MatType GetInitialPoint() const { return MatType("0 0 0 0;"); }
//! Evaluate a function.
template<typename MatType>
typename MatType::elem_type Evaluate(const MatType& coordinates,
@@ -61,6 +57,22 @@ class SparseTestFunction
const size_t j,
GradType& gradient) const;
// Note: GetInitialPoint(), GetFinalPoint(), and GetFinalObjective() are not
// required for using ensmallen to optimize this function! They are
// specifically used as a convenience just for ensmallen's testing
// infrastructure.
//! Get the starting point.
template<typename MatType>
MatType GetInitialPoint() const { return MatType("0 0 0 0;"); }
//! Get the final point.
template<typename MatType = arma::mat>
MatType GetFinalPoint() const { return MatType("2.0 1.0 1.5 4.0"); }
//! Get the final objective.
double GetFinalObjective() const { return 123.75; }
private:
// Each quadratic polynomial is monic. The intercept and coefficient of the
// first order term is stored.
@@ -45,7 +45,7 @@ class SphereFunction
*
* @param n Number of dimensions for the function.
*/
SphereFunction(const size_t n);
SphereFunction(const size_t n = 2);
/**
* Shuffle the order of function visitation. This may be called by the
@@ -56,13 +56,6 @@ class SphereFunction
//! Return 1 (the number of functions).
size_t NumFunctions() const { return n; }
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const
{
return arma::conv_to<MatType>::from(initialPoint);
}
/**
* Evaluate a function for a particular batch-size.
*
@@ -106,6 +99,28 @@ class SphereFunction
template<typename MatType, typename GradType>
void Gradient(const MatType& coordinates, GradType& gradient);
// Note: GetInitialPoint(), GetFinalPoint(), and GetFinalObjective() are not
// required for using ensmallen to optimize this function! They are
// specifically used as a convenience just for ensmallen's testing
// infrastructure.
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const
{
return arma::conv_to<MatType>::from(initialPoint);
}
//! Get the final point.
template<typename MatType = arma::mat>
MatType GetFinalPoint() const
{
return arma::zeros<MatType>(initialPoint.n_rows, initialPoint.n_cols);
}
//! Get the final objective.
double GetFinalObjective() const { return 0.0; }
private:
//! Number of dimensions for the function.
size_t n;
@@ -46,7 +46,7 @@ class StyblinskiTangFunction
*
* @param n Number of dimensions for the function.
*/
StyblinskiTangFunction(const size_t n);
StyblinskiTangFunction(const size_t n = 2);
/**
* Shuffle the order of function visitation. This may be called by the
@@ -57,13 +57,6 @@ class StyblinskiTangFunction
//! Return 1 (the number of functions).
size_t NumFunctions() const { return n; }
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const
{
return arma::conv_to<MatType>::from(initialPoint);
}
/**
* Evaluate a function for a particular batch-size.
*
@@ -107,6 +100,31 @@ class StyblinskiTangFunction
template<typename MatType, typename GradType>
void Gradient(const MatType& coordinates, GradType& gradient);
// Note: GetInitialPoint(), GetFinalPoint(), and GetFinalObjective() are not
// required for using ensmallen to optimize this function! They are
// specifically used as a convenience just for ensmallen's testing
// infrastructure.
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const
{
return arma::conv_to<MatType>::from(initialPoint);
}
//! Get the final point.
template<typename MatType = arma::mat>
MatType GetFinalPoint() const
{
MatType result(initialPoint.n_rows, initialPoint.n_cols);
for (size_t i = 0; i < result.n_elem; ++i)
result[i] = -2.903534;
return result;
}
//! Get the final objective.
double GetFinalObjective() const { return -39.16599 * n; }
private:
//! Number of dimensions for the function.
size_t n;
@@ -58,10 +58,6 @@ class ThreeHumpCamelFunction
//! Return 1 (the number of functions).
size_t NumFunctions() const { return 1; }
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("-4.5; 4.5"); }
/**
* Evaluate a function for a particular batch-size.
*
@@ -104,6 +100,22 @@ class ThreeHumpCamelFunction
*/
template<typename MatType, typename GradType>
void Gradient(const MatType& coordinates, GradType& gradient);
// Note: GetInitialPoint(), GetFinalPoint(), and GetFinalObjective() are not
// required for using ensmallen to optimize this function! They are
// specifically used as a convenience just for ensmallen's testing
// infrastructure.
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("1; 1"); }
//! Get the final point.
template<typename MatType = arma::mat>
MatType GetFinalPoint() const { return MatType("0.0; 0.0"); }
//! Get the final objective.
double GetFinalObjective() const { return 0.0; }
};
} // namespace test
@@ -59,10 +59,6 @@ class WoodFunction
//! Return 1 (the number of functions).
size_t NumFunctions() const { return 1; }
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("-3; -1; -3; -1"); }
/**
* Evaluate a function for a particular batch-size.
*
@@ -105,6 +101,22 @@ class WoodFunction
*/
template<typename MatType, typename GradType>
void Gradient(const MatType& coordinates, GradType& gradient) const;
// Note: GetInitialPoint(), GetFinalPoint(), and GetFinalObjective() are not
// required for using ensmallen to optimize this function! They are
// specifically used as a convenience just for ensmallen's testing
// infrastructure.
//! Get the starting point.
template<typename MatType = arma::mat>
MatType GetInitialPoint() const { return MatType("-3; -1; -3; -1"); }
//! Get the final point.
template<typename MatType = arma::mat>
MatType GetFinalPoint() const { return MatType("1; 1; 1; 1"); }
//! Get the final objective.
double GetFinalObjective() const { return 0.0; }
};
} // namespace test
@@ -0,0 +1,157 @@
/**
* @file zdt1_function.hpp
* @author Nanubala Gnana Sai
*
* Implementation of the first ZDT(Zitzler, Deb and Thiele) test.
*
* ensmallen is free software; you may redistribute it and/or modify it under
* the terms of the 3-clause BSD license. You should have received a copy of
* the 3-clause BSD license along with ensmallen. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef ENSMALLEN_PROBLEMS_ZDT_ONE_FUNCTION_HPP
#define ENSMALLEN_PROBLEMS_ZDT_ONE_FUNCTION_HPP
namespace ens {
namespace test {
/**
* The ZDT1 function, defined by:
* \f[
* g(x) = 1 + 9(\sum_{i=2}^{n} x_i )/(n-1)
* f_1(x) = x_1
* h(f_1, g) = g(x)[1-\sqrt{f_1/g}\ ]
* f_2(x) = g(x) * h(f_1, g)
* \f]
*
* This is a 30-variable problem (n = 30) with a convex optimal set.
*
* Bounds of the variable space is:
* 0 <= x_i <= 1 for i = 1,...,n.
*
* This should be optimized to g(x) = 1.0, at:
* x_1* in [0, 1] ; x_i* = 0 for i = 2,...,n
*
* For more information, please refer to:
*
* @code
* @article{Zitzler2000,
* title = {Comparison of multiobjective evolutionary algorithms:
* Empirical results},
* author = {Zitzler, Eckart and Deb, Kalyanmoy and Thiele, Lothar},
* journal = {Evolutionary computation},
* year = {2000},
* doi = {10.1162/106365600568202}
* }
* @endcode
*
* @tparam MatType Type of matrix to optimize.
*/
template<typename MatType = arma::mat>
class ZDT1
{
private:
size_t numParetoPoints {100};
size_t numObjectives {2};
size_t numVariables {30};
public:
//! Initialize the ZDT1
ZDT1(size_t numParetoPoints = 100) :
numParetoPoints(numParetoPoints),
objectiveF1(*this),
objectiveF2(*this)
{/* Nothing to do here. */}
/**
* Evaluate the objectives with the given coordinate.
*
* @param coords The function coordinates.
* @return arma::Col<typename MatType::elem_type>
*/
arma::Col<typename MatType::elem_type> Evaluate(const MatType& coords)
{
// Convenience typedef.
typedef typename MatType::elem_type ElemType;
arma::Col<ElemType> objectives(numObjectives);
objectives(0) = coords[0];
ElemType sum = arma::accu(coords(arma::span(1, numVariables - 1), 0));
ElemType g = 1. + 9. * sum / (static_cast<ElemType>(numVariables) - 1.);
ElemType objectiveRatio = objectives(0) / g;
objectives(1) = g * (1. - std::sqrt(objectiveRatio));
return objectives;
}
//! Get the starting point.
MatType GetInitialPoint()
{
// Convenience typedef.
typedef typename MatType::elem_type ElemType;
return arma::Col<ElemType>(numVariables, 1, arma::fill::zeros);
}
struct ObjectiveF1
{
ObjectiveF1(ZDT1& zdtClass) : zdtClass(zdtClass)
{/*Nothing to do here */}
typename MatType::elem_type Evaluate(const MatType& coords)
{
return coords[0];
}
ZDT1& zdtClass;
};
struct ObjectiveF2
{
ObjectiveF2(ZDT1& zdtClass) : zdtClass(zdtClass)
{/*Nothing to do here */}
typename MatType::elem_type Evaluate(const MatType& coords)
{
// Convenience typedef.
typedef typename MatType::elem_type ElemType;
size_t numVariables = zdtClass.numVariables;
ElemType sum = arma::accu(coords(arma::span(1, numVariables - 1), 0));
ElemType g = 1. + 9. * sum / (static_cast<ElemType>(numVariables - 1));
ElemType objectiveRatio = zdtClass.objectiveF1.Evaluate(coords) / g;
return g * (1. - std::sqrt(objectiveRatio));
}
ZDT1& zdtClass;
};
//! Get objective functions.
std::tuple<ObjectiveF1, ObjectiveF2> GetObjectives()
{
return std::make_tuple(objectiveF1, objectiveF2);
}
//! Get the Reference Front.
//! Refer PR #273 Ipynb notebook to see the plot of Reference
//! Front. The implementation has been taken from pymoo.
arma::cube GetReferenceFront()
{
arma::cube front(2, 1, numParetoPoints);
arma::vec x = arma::linspace(0, 1, numParetoPoints);
arma::vec y = 1 - arma::sqrt(x);
for (size_t idx = 0; idx < numParetoPoints; ++idx)
front.slice(idx) = arma::vec{ x(idx), y(idx) };
return front;
}
ObjectiveF1 objectiveF1;
ObjectiveF2 objectiveF2;
};
} //namespace test
} //namespace ens
#endif
@@ -0,0 +1,158 @@
/**
* @file zdt2_function.hpp
* @author Nanubala Gnana Sai
*
* Implementation of the second ZDT(Zitzler, Deb and Thiele) test.
*
* ensmallen is free software; you may redistribute it and/or modify it under
* the terms of the 3-clause BSD license. You should have received a copy of
* the 3-clause BSD license along with ensmallen. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef ENSMALLEN_PROBLEMS_ZDT_TWO_FUNCTION_HPP
#define ENSMALLEN_PROBLEMS_ZDT_TWO_FUNCTION_HPP
namespace ens {
namespace test {
/**
* The ZDT2 function, defined by:
* \f[
* g(x) = 1 + 9(\sum_{i=2}^{n} x_i )/(n-1)
* f_1(x) = x_1
* h(f_1, g) = 1 - (f_1/g)^2
* f_2(x) = g(x) * h(f_1, g)
* \f]
*
* This is a 30-variable problem(n = 30) with a
* non convex optimal set.
*
* Bounds of the variable space is:
* 0 <= x_i <= 1 for i = 1,..,n.
*
* This should be optimized to g(x) = 1.0, at:
* x_1* in [0, 1] ; x_i* = 0 for i = 2,...,n
*
* For more information, please refer to:
*
* @code
* @article{Zitzler2000,
* title = {Comparison of multiobjective evolutionary algorithms:
* Empirical results},
* author = {Zitzler, Eckart and Deb, Kalyanmoy and Thiele, Lothar},
* journal = {Evolutionary computation},
* year = {2000},
* doi = {10.1162/106365600568202}
* }
* @endcode
*
* @tparam MatType Type of matrix to optimize.
*/
template<typename MatType = arma::mat>
class ZDT2
{
private:
size_t numParetoPoints {100};
size_t numObjectives {2};
size_t numVariables {30};
public:
//! Initialize the ZDT2
ZDT2(size_t numParetoPoints = 100) :
numParetoPoints(numParetoPoints),
objectiveF1(*this),
objectiveF2(*this)
{/* Nothing to do here. */}
/**
* Evaluate the objectives with the given coordinate.
*
* @param coords The function coordinates.
* @return arma::Col<typename MatType::elem_type>
*/
arma::Col<typename MatType::elem_type> Evaluate(const MatType& coords)
{
// Convenience typedef.
typedef typename MatType::elem_type ElemType;
arma::Col<ElemType> objectives(numObjectives);
objectives(0) = coords[0];
ElemType sum = arma::accu(coords(arma::span(1, numVariables - 1), 0));
ElemType g = 1. + 9. * sum / (static_cast<ElemType>(numVariables) - 1.);
ElemType objectiveRatio = objectives(0) / g;
objectives(1) = g * (1. - std::pow(objectiveRatio, 2));
return objectives;
}
//! Get the starting point.
MatType GetInitialPoint()
{
// Convenience typedef.
typedef typename MatType::elem_type ElemType;
return arma::Col<ElemType>(numVariables, 1, arma::fill::zeros);
}
struct ObjectiveF1
{
ObjectiveF1(ZDT2& zdtClass) : zdtClass(zdtClass)
{/*Nothing to do here */}
typename MatType::elem_type Evaluate(const MatType& coords)
{
return coords[0];
}
ZDT2& zdtClass;
};
struct ObjectiveF2
{
ObjectiveF2(ZDT2& zdtClass) : zdtClass(zdtClass)
{/*Nothing to do here */}
typename MatType::elem_type Evaluate(const MatType& coords)
{
// Convenience typedef.
typedef typename MatType::elem_type ElemType;
size_t numVariables = zdtClass.numVariables;
ElemType sum = arma::accu(coords(arma::span(1, numVariables - 1), 0));
ElemType g = 1. + 9. * sum / (static_cast<ElemType>(numVariables - 1));
ElemType objectiveRatio = zdtClass.objectiveF1.Evaluate(coords) / g;
return g * (1. - std::pow(objectiveRatio, 2));
}
ZDT2& zdtClass;
};
//! Get objective functions.
std::tuple<ObjectiveF1, ObjectiveF2> GetObjectives()
{
return std::make_tuple(objectiveF1, objectiveF2);
}
//! Get the Reference Front.
//! Refer PR #273 Ipynb notebook to see the plot of Reference
//! Front. The implementation has been taken from pymoo.
arma::cube GetReferenceFront()
{
arma::cube front(2, 1, numParetoPoints);
arma::vec x = arma::linspace(0, 1, numParetoPoints);
arma::vec y = 1 - arma::square(x);
for (size_t idx = 0; idx < numParetoPoints; ++idx)
front.slice(idx) = arma::vec{ x(idx), y(idx) };
return front;
}
ObjectiveF1 objectiveF1;
ObjectiveF2 objectiveF2;
};
} //namespace test
} //namespace ens
#endif
@@ -0,0 +1,188 @@
/**
* @file zdt3_function.hpp
* @author Nanubala Gnana Sai
*
* Implementation of the third ZDT(Zitzler, Deb and Thiele) test.
*
* ensmallen is free software; you may redistribute it and/or modify it under
* the terms of the 3-clause BSD license. You should have received a copy of
* the 3-clause BSD license along with ensmallen. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef ENSMALLEN_PROBLEMS_ZDT_THREE_FUNCTION_HPP
#define ENSMALLEN_PROBLEMS_ZDT_THREE_FUNCTION_HPP
namespace ens {
namespace test {
/**
* The ZDT3 function, defined by:
* \f[
* g(x) = 1 + 9(\sum_{i=2}^{n} x_i )/(n-1)
* f_1(x) = x_1
* h(f_1,g) = 1 - \sqrt{f_1/g} - (f_1/g)sin(10\pi f_1)
* f_2(x) = g(x) * h(f_1, g)
* \f]
*
* This is a 30-variable problem(n = 30) with a number
* of disconnected optimal fronts.
*
* Bounds of the variable space is:
* 0 <= x_i <= 1 for i = 1,...,n.
*
* This should be optimized to g(x) = 1.0, at:
*
* x_1* in [0.0000, 0.0830] OR
* x_1* in [0.1822, 0.2577] OR
* x_1* in [0.4093, 0.4538] OR
* x_1* in [0.6183, 0.6525] OR
* x_1* in [0.8233, 0.8518].
*
* x_i* = 0 for i = 2,...,n.
*
* For more information, please refer to:
*
* @code
* @article{Zitzler2000,
* title = {Comparison of multiobjective evolutionary algorithms:
* Empirical results},
* author = {Zitzler, Eckart and Deb, Kalyanmoy and Thiele, Lothar},
* journal = {Evolutionary computation},
* year = {2000},
* doi = {10.1162/106365600568202}
* }
* @endcode
*
* @tparam MatType Type of matrix to optimize.
*/
template<typename MatType = arma::mat>
class ZDT3
{
private:
size_t numParetoPoints {100};
size_t numObjectives {2};
size_t numVariables {30};
public:
//! Initialize the ZDT3
ZDT3(size_t numParetoPoints = 100) :
numParetoPoints(numParetoPoints),
objectiveF1(*this),
objectiveF2(*this)
{/* Nothing to do here. */}
/**
* Evaluate the objectives with the given coordinate.
*
* @param coords The function coordinates.
* @return arma::Col<typename MatType::elem_type>
*/
arma::Col<typename MatType::elem_type> Evaluate(const MatType& coords)
{
typedef typename MatType::elem_type ElemType;
arma::Col<ElemType> objectives(numObjectives);
objectives(0) = coords[0];
ElemType sum = arma::accu(coords(arma::span(1, numVariables - 1), 0));
ElemType g = 1. + 9. * sum / (static_cast<ElemType>(numVariables) - 1.);
ElemType objectiveRatio = objectives(0) / g;
objectives(1) = g * (1. - std::sqrt(objectiveRatio) -
(objectiveRatio) * std::sin(10. * arma::datum::pi * coords[0]));
return objectives;
}
//! Get the starting point.
MatType GetInitialPoint()
{
// Convenience typedef.
typedef typename MatType::elem_type ElemType;
return arma::Col<ElemType>(numVariables, 1, arma::fill::zeros);
}
struct ObjectiveF1
{
ObjectiveF1(ZDT3& zdtClass) : zdtClass(zdtClass)
{/*Nothing to do here */}
typename MatType::elem_type Evaluate(const MatType& coords)
{
return coords[0];
}
ZDT3& zdtClass;
};
struct ObjectiveF2
{
ObjectiveF2(ZDT3& zdtClass) : zdtClass(zdtClass)
{/*Nothing to do here */}
typename MatType::elem_type Evaluate(const MatType& coords)
{
typedef typename MatType::elem_type ElemType;
size_t numVariables = zdtClass.numVariables;
ElemType sum = arma::accu(coords(arma::span(1, numVariables - 1), 0));
ElemType g = 1. + 9. * sum / (static_cast<ElemType>(numVariables - 1));
ElemType objectiveRatio = zdtClass.objectiveF1.Evaluate(coords) / g;
return g * (1. - std::sqrt(objectiveRatio) -
(objectiveRatio) * std::sin(10. * arma::datum::pi * coords[0]));
}
ZDT3& zdtClass;
};
//! Get objective functions.
std::tuple<ObjectiveF1, ObjectiveF2> GetObjectives()
{
return std::make_tuple(objectiveF1, objectiveF2);
}
//! Get the Reference Front.
//! Refer PR #273 Ipynb notebook to see the plot of Reference
//! Front. The implementation has been taken from pymoo.
arma::cube GetReferenceFront()
{
size_t numRegions = 5;
size_t regionDensity = std::floor(numParetoPoints / numRegions);
size_t apparentParetoPoints = numRegions * regionDensity;
arma::cube front(2, 1, apparentParetoPoints);
arma::mat regions{
{0.0, 0.182228780, 0.4093136748,
0.6183967944, 0.8233317983},
{0.0830015349, 0.2577623634, 0.4538821041,
0.6525117038, 0.8518328654}
};
for (size_t regionIdx = 0; regionIdx < numRegions; ++regionIdx)
{
arma::vec region = regions.col(regionIdx);
//! Generate x and y coordinates for the region.
arma::vec x = arma::linspace(
region(0), region(1), regionDensity);
arma::vec y = 1 - arma::sqrt(x) - x
% arma::sin(10 * arma::datum::pi * x);
//! Fill the front with the generated points.
for (size_t pointIdx = 0; pointIdx < regionDensity; ++pointIdx)
{
size_t sliceIdx = regionIdx * regionDensity + pointIdx;
front.slice(sliceIdx) = arma::vec{ x(pointIdx), y(pointIdx) };
}
}
return front;
}
ObjectiveF1 objectiveF1;
ObjectiveF2 objectiveF2;
};
} //namespace test
} //namespace ens
#endif
@@ -0,0 +1,160 @@
/**
* @file zdt4_function.hpp
* @author Nanubala Gnana Sai
*
* Implementation of the fourth ZDT(Zitzler, Deb and Thiele) test.
*
* ensmallen is free software; you may redistribute it and/or modify it under
* the terms of the 3-clause BSD license. You should have received a copy of
* the 3-clause BSD license along with ensmallen. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef ENSMALLEN_PROBLEMS_ZDT_FOUR_FUNCTION_HPP
#define ENSMALLEN_PROBLEMS_ZDT_FOUR_FUNCTION_HPP
namespace ens {
namespace test {
/**
* The ZDT4 function, defined by:
* \f[
* g(x) = 1 + 10(n-1) + \sum_{i=2}^{n}(x_i^2 - 10cos(4\pi x_i))
* f_1(x) = x_i
* h(f_1,g) = 1 - \sqrt{f_i/g}
* f_2(x) = g(x) * h(f_1, g)
* \f]
*
* This is a 10-variable problem(n = 10) with a convex
* optimal front. This problem contains several local
* optimum, making it difficult to reach the global optimum.
*
* Bounds of the variable space is:
* 0 <= x_1 <= 1;
* -10 <= x_i <= 10 for i = 2,...,n.
*
* This should be optimized to g(x) = 1.0, at:
* x_1* in [0, 1] ; x_i* = 0 for i = 2,...,n
*
* For more information, please refer to:
*
* @code
* @article{Zitzler2000,
* title = {Comparison of multiobjective evolutionary algorithms:
* Empirical results},
* author = {Zitzler, Eckart and Deb, Kalyanmoy and Thiele, Lothar},
* journal = {Evolutionary computation},
* year = {2000},
* doi = {10.1162/106365600568202}
* }
* @endcode
*
* @tparam MatType Type of matrix to optimize.
*/
template<typename MatType = arma::mat>
class ZDT4
{
private:
size_t numParetoPoints {100};
size_t numObjectives {2};
size_t numVariables {10};
public:
//! Initialize the ZDT4
ZDT4(size_t numParetoPoints = 100) :
numParetoPoints(numParetoPoints),
objectiveF1(*this),
objectiveF2(*this)
{/* Nothing to do here. */}
/**
* Evaluate the objectives with the given coordinate.
*
* @param coords The function coordinates.
* @return arma::Col<typename MatType::elem_type>
*/
arma::Col<typename MatType::elem_type> Evaluate(const MatType& coords)
{
typedef typename MatType::elem_type ElemType;
arma::Col<ElemType> objectives(numObjectives);
objectives(0) = coords[0];
MatType truncatedCoords = coords(arma::span(1, numVariables - 1), 0);
ElemType sum = arma::accu(arma::square(truncatedCoords) -
10. * arma::cos(4 * arma::datum::pi * truncatedCoords));
ElemType g = 1. + 10. * static_cast<ElemType>(numVariables - 1) + sum;
ElemType objectiveRatio = objectives(0) / g;
objectives(1) = g * (1. - std::sqrt(objectiveRatio));
return objectives;
}
//! Get the starting point.
MatType GetInitialPoint()
{
// Convenience typedef.
typedef typename MatType::elem_type ElemType;
return arma::Col<ElemType>(numVariables, 1, arma::fill::zeros);
}
struct ObjectiveF1
{
ObjectiveF1(ZDT4& zdtClass) : zdtClass(zdtClass)
{/*Nothing to do here */}
typename MatType::elem_type Evaluate(const MatType& coords)
{
return coords[0];
}
ZDT4& zdtClass;
};
struct ObjectiveF2
{
ObjectiveF2(ZDT4& zdtClass) : zdtClass(zdtClass)
{/*Nothing to do here */}
typename MatType::elem_type Evaluate(const MatType& coords)
{
typedef typename MatType::elem_type ElemType;
size_t numVariables = zdtClass.numVariables;
MatType truncatedCoords = coords(arma::span(1, numVariables - 1), 0);
ElemType sum = arma::accu(arma::square(truncatedCoords) -
10. * arma::cos(4 * arma::datum::pi * truncatedCoords));
ElemType g = 1. + 10 * static_cast<ElemType>(numVariables - 1) + sum;
ElemType objectiveRatio = zdtClass.objectiveF1.Evaluate(coords) / g;
return g * (1. - std::sqrt(objectiveRatio));
}
ZDT4& zdtClass;
};
//! Get objective functions.
std::tuple<ObjectiveF1, ObjectiveF2> GetObjectives()
{
return std::make_tuple(objectiveF1, objectiveF2);
}
//! Get the Reference Front.
//! Refer PR #273 Ipynb notebook to see the plot of Reference
//! Front. The implementation has been taken from pymoo.
arma::cube GetReferenceFront()
{
arma::cube front(2, 1, numParetoPoints);
arma::vec x = arma::linspace(0, 1, numParetoPoints);
arma::vec y = 1 - arma::sqrt(x);
for (size_t idx = 0; idx < numParetoPoints; ++idx)
front.slice(idx) = arma::vec{ x(idx), y(idx) };
return front;
}
ObjectiveF1 objectiveF1;
ObjectiveF2 objectiveF2;
};
} //namespace test
} //namespace ens
#endif
@@ -0,0 +1,162 @@
/**
* @file zdt6_function.hpp
* @author Nanubala Gnana Sai
*
* Implementation of the sixth ZDT(Zitzler, Deb and Thiele) test.
*
* ensmallen is free software; you may redistribute it and/or modify it under
* the terms of the 3-clause BSD license. You should have received a copy of
* the 3-clause BSD license along with ensmallen. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef ENSMALLEN_PROBLEMS_ZDT_SIX_FUNCTION_HPP
#define ENSMALLEN_PROBLEMS_ZDT_SIX_FUNCTION_HPP
namespace ens {
namespace test {
/**
* The ZDT6 function, defined by:
* \f[
* g(x) = 1 + 9[ \sum_{i=2}^{n}(x_i^2)/9]^{0.25}
* f_1(x) = 1 - e^{-4x_1}sin^{6}(6\pi x_1)
* h(f1, g) = 1 - (f_1/g)^{2}
* f_2(x) = g(x) * h(f_1, g)
* \f]
*
* This is a 10-variable problem(n = 10) with a
* non-convex optimal front. The density of the
* solutions across optimal region is non-uniform.
*
* Bounds of the variable space is:
* 0 <= x_i <= 1 for i = 1,...,n
*
* This should be optimized to g(x) = 1.0, at:
* x_1* in [0, 1] ; x_i* = 0 for i = 2,...,n
*
*
* For more information, please refer to:
*
* @code
* @article{Zitzler2000,
* title = {Comparison of multiobjective evolutionary algorithms:
* Empirical results},
* author = {Zitzler, Eckart and Deb, Kalyanmoy and Thiele, Lothar},
* journal = {Evolutionary computation},
* year = {2000},
* doi = {10.1162/106365600568202}
* }
* @endcode
*
* @tparam MatType Type of matrix to optimize.
*/
template<typename MatType = arma::mat>
class ZDT6
{
private:
size_t numParetoPoints {100};
size_t numObjectives {2};
size_t numVariables {10};
public:
//! Initialize the ZDT6
ZDT6(size_t numParetoPoints = 100) :
numParetoPoints(numParetoPoints),
objectiveF1(*this),
objectiveF2(*this)
{/* Nothing to do here. */}
/**
* Evaluate the objectives with the given coordinate.
*
* @param coords The function coordinates.
* @return arma::Col<typename MatType::elem_type>
*/
arma::Col<typename MatType::elem_type> Evaluate(const MatType& coords)
{
// Convenience typedef.
typedef typename MatType::elem_type ElemType;
arma::Col<ElemType> objectives(numObjectives);
objectives(0) = 1. - std::exp(-4 * coords[0]) *
std::pow(std::sin(6 * arma::datum::pi * coords[0]), 6);
ElemType sum = std::pow(
arma::accu(coords(arma::span(1, numVariables - 1), 0)) / 9, 0.25);
ElemType g = 1. + 9. * sum;
ElemType objectiveRatio = objectives(0) / g;
objectives(1) = g * (1. - std::pow(objectiveRatio, 2));
return objectives;
}
//! Get the starting point.
MatType GetInitialPoint()
{
// Convenience typedef.
typedef typename MatType::elem_type ElemType;
return arma::Col<ElemType>(numVariables, 1, arma::fill::zeros);
}
struct ObjectiveF1
{
ObjectiveF1(ZDT6& zdtClass) : zdtClass(zdtClass)
{/*Nothing to do here */}
typename MatType::elem_type Evaluate(const MatType& coords)
{
return 1. - std::exp(-4. * coords[0]) *
std::pow(std::sin(6. * arma::datum::pi * coords[0]), 6.);
}
ZDT6& zdtClass;
};
struct ObjectiveF2
{
ObjectiveF2(ZDT6& zdtClass) : zdtClass(zdtClass)
{/*Nothing to do here */}
typename MatType::elem_type Evaluate(const MatType& coords)
{
typedef typename MatType::elem_type ElemType;
size_t numVariables = zdtClass.numVariables;
ElemType sum = std::pow(
arma::accu(coords(arma::span(1, numVariables - 1), 0)) / 9, 0.25);
ElemType g = 1. + 9. * sum;
ElemType objectiveRatio = zdtClass.objectiveF1.Evaluate(coords) / g;
return g * (1. - std::pow(objectiveRatio, 2));
}
ZDT6& zdtClass;
};
//! Get objective functions.
std::tuple<ObjectiveF1, ObjectiveF2> GetObjectives()
{
return std::make_tuple(objectiveF1, objectiveF2);
}
//! Get the Reference Front.
//! Refer PR #273 Ipynb notebook to see the plot of Reference
//! Front. The implementation has been taken from pymoo.
arma::cube GetReferenceFront()
{
arma::cube front(2, 1, numParetoPoints);
arma::vec x = arma::linspace(0.2807753191, 1, numParetoPoints);
arma::vec y = 1 - arma::square(x);
for (size_t idx = 0; idx < numParetoPoints; ++idx)
front.slice(idx) = arma::vec{ x(idx), y(idx) };
return front;
}
ObjectiveF1 objectiveF1;
ObjectiveF2 objectiveF2;
};
} //namespace test
} //namespace ens
#endif
+10
View File
@@ -39,6 +39,7 @@ namespace ens {
*
* For more information, refer to:
*
* @code
* @inproceedings{Kennedy1995,
* author = {Kennedy, James and Eberhart, Russell C.},
* booktitle = {Proceedings of the IEEE International Conference on
@@ -47,6 +48,7 @@ namespace ens {
* title = {Particle swarm optimization},
* year = 1995
* }
* @endcode
*
* PSO can optimize arbitrary functions. For more details, see the documentation
* on function types included with this distribution or on the ensmallen
@@ -108,6 +110,14 @@ class PSOType
initPolicy(initPolicy)
{ /* Nothing to do. */ }
/**
* Clean memory associated with the PSO object.
*/
~PSOType()
{
instUpdatePolicy.Clean();
}
/**
* Construct the particle swarm optimizer with the given function and
* parameters. The defaults here are not necessarily good for the given
+3 -1
View File
@@ -18,7 +18,9 @@
#include <queue>
namespace ens {
/* After the velocity of each particle is updated at the end of each iteration
/**
* After the velocity of each particle is updated at the end of each iteration
* in PSO, the position of particle i (in iteration j) is updated as:
*
* \f[
@@ -73,7 +73,8 @@ class LBestUpdate
*
* @param parent Instantiated parent class.
*/
Policy(const LBestUpdate& /* parent */) { /* Do nothing. */ }
Policy(const LBestUpdate& /* parent */) : n(0)
{ /* Do nothing. */ }
/**
* The Initialize method is called by PSO Optimizer method before the

Some files were not shown because too many files have changed in this diff Show More