| 1 | #!/usr/bin/env python |
|---|
| 2 | # |
|---|
| 3 | # Author: Alta Fang (altafang @caltech and alta @princeton) |
|---|
| 4 | # Author: Mike McKerns (mmckerns @caltech and @uqfoundation) |
|---|
| 5 | # Copyright (c) 1997-2016 California Institute of Technology. |
|---|
| 6 | # License: 3-clause BSD. The full license text is available at: |
|---|
| 7 | # - http://mmckerns.github.io/project/mystic/browser/mystic/LICENSE |
|---|
| 8 | """Test Mystic's performance on some benchmark problems, with Mystic's settings |
|---|
| 9 | adjusted to achieve the best results. |
|---|
| 10 | """ |
|---|
| 11 | from mystic.monitors import Monitor |
|---|
| 12 | from mystic.math import almostEqual |
|---|
| 13 | from mystic.tools import random_seed |
|---|
| 14 | random_seed(123) |
|---|
| 15 | import time |
|---|
| 16 | |
|---|
| 17 | def test_rosenbrock(): |
|---|
| 18 | """Test the 2-dimensional Rosenbrock function. |
|---|
| 19 | |
|---|
| 20 | Testing 2-D Rosenbrock: |
|---|
| 21 | Expected: x=[1., 1.] and f=0 |
|---|
| 22 | |
|---|
| 23 | Using DifferentialEvolutionSolver: |
|---|
| 24 | Solution: [ 1.00000037 1.0000007 ] |
|---|
| 25 | f value: 2.29478683682e-13 |
|---|
| 26 | Iterations: 99 |
|---|
| 27 | Function evaluations: 3996 |
|---|
| 28 | Time elapsed: 0.582273006439 seconds |
|---|
| 29 | |
|---|
| 30 | Using DifferentialEvolutionSolver2: |
|---|
| 31 | Solution: [ 0.99999999 0.99999999] |
|---|
| 32 | f value: 3.84824937598e-15 |
|---|
| 33 | Iterations: 100 |
|---|
| 34 | Function evaluations: 4040 |
|---|
| 35 | Time elapsed: 0.577210903168 seconds |
|---|
| 36 | |
|---|
| 37 | Using NelderMeadSimplexSolver: |
|---|
| 38 | Solution: [ 0.99999921 1.00000171] |
|---|
| 39 | f value: 1.08732211477e-09 |
|---|
| 40 | Iterations: 70 |
|---|
| 41 | Function evaluations: 130 |
|---|
| 42 | Time elapsed: 0.0190329551697 seconds |
|---|
| 43 | |
|---|
| 44 | Using PowellDirectionalSolver: |
|---|
| 45 | Solution: [ 1. 1.] |
|---|
| 46 | f value: 0.0 |
|---|
| 47 | Iterations: 28 |
|---|
| 48 | Function evaluations: 859 |
|---|
| 49 | Time elapsed: 0.113857030869 seconds |
|---|
| 50 | """ |
|---|
| 51 | |
|---|
| 52 | print "Testing 2-D Rosenbrock:" |
|---|
| 53 | print "Expected: x=[1., 1.] and f=0" |
|---|
| 54 | from mystic.models import rosen as costfunc |
|---|
| 55 | ndim = 2 |
|---|
| 56 | lb = [-5.]*ndim |
|---|
| 57 | ub = [5.]*ndim |
|---|
| 58 | x0 = [2., 3.] |
|---|
| 59 | maxiter = 10000 |
|---|
| 60 | |
|---|
| 61 | # DifferentialEvolutionSolver |
|---|
| 62 | print "\nUsing DifferentialEvolutionSolver:" |
|---|
| 63 | npop = 40 |
|---|
| 64 | from mystic.solvers import DifferentialEvolutionSolver |
|---|
| 65 | from mystic.termination import ChangeOverGeneration as COG |
|---|
| 66 | from mystic.strategy import Rand1Bin |
|---|
| 67 | esow = Monitor() |
|---|
| 68 | ssow = Monitor() |
|---|
| 69 | solver = DifferentialEvolutionSolver(ndim, npop) |
|---|
| 70 | solver.SetInitialPoints(x0) |
|---|
| 71 | solver.SetStrictRanges(lb, ub) |
|---|
| 72 | solver.SetEvaluationLimits(generations=maxiter) |
|---|
| 73 | solver.SetEvaluationMonitor(esow) |
|---|
| 74 | solver.SetGenerationMonitor(ssow) |
|---|
| 75 | term = COG(1e-10) |
|---|
| 76 | time1 = time.time() # Is this an ok way of timing? |
|---|
| 77 | solver.Solve(costfunc, term, strategy=Rand1Bin) |
|---|
| 78 | sol = solver.Solution() |
|---|
| 79 | time_elapsed = time.time() - time1 |
|---|
| 80 | fx = solver.bestEnergy |
|---|
| 81 | print "Solution: ", sol |
|---|
| 82 | print "f value: ", fx |
|---|
| 83 | print "Iterations: ", solver.generations |
|---|
| 84 | print "Function evaluations: ", len(esow.x) |
|---|
| 85 | print "Time elapsed: ", time_elapsed, " seconds" |
|---|
| 86 | assert almostEqual(fx, 2.29478683682e-13, tol=3e-3) |
|---|
| 87 | |
|---|
| 88 | # DifferentialEvolutionSolver2 |
|---|
| 89 | print "\nUsing DifferentialEvolutionSolver2:" |
|---|
| 90 | npop = 40 |
|---|
| 91 | from mystic.solvers import DifferentialEvolutionSolver2 |
|---|
| 92 | from mystic.termination import ChangeOverGeneration as COG |
|---|
| 93 | from mystic.strategy import Rand1Bin |
|---|
| 94 | esow = Monitor() |
|---|
| 95 | ssow = Monitor() |
|---|
| 96 | solver = DifferentialEvolutionSolver2(ndim, npop) |
|---|
| 97 | solver.SetInitialPoints(x0) |
|---|
| 98 | solver.SetStrictRanges(lb, ub) |
|---|
| 99 | solver.SetEvaluationLimits(generations=maxiter) |
|---|
| 100 | solver.SetEvaluationMonitor(esow) |
|---|
| 101 | solver.SetGenerationMonitor(ssow) |
|---|
| 102 | term = COG(1e-10) |
|---|
| 103 | time1 = time.time() # Is this an ok way of timing? |
|---|
| 104 | solver.Solve(costfunc, term, strategy=Rand1Bin) |
|---|
| 105 | sol = solver.Solution() |
|---|
| 106 | time_elapsed = time.time() - time1 |
|---|
| 107 | fx = solver.bestEnergy |
|---|
| 108 | print "Solution: ", sol |
|---|
| 109 | print "f value: ", fx |
|---|
| 110 | print "Iterations: ", solver.generations |
|---|
| 111 | print "Function evaluations: ", len(esow.x) |
|---|
| 112 | print "Time elapsed: ", time_elapsed, " seconds" |
|---|
| 113 | assert almostEqual(fx, 3.84824937598e-15, tol=3e-3) |
|---|
| 114 | |
|---|
| 115 | # NelderMeadSimplexSolver |
|---|
| 116 | print "\nUsing NelderMeadSimplexSolver:" |
|---|
| 117 | from mystic.solvers import NelderMeadSimplexSolver |
|---|
| 118 | from mystic.termination import CandidateRelativeTolerance as CRT |
|---|
| 119 | esow = Monitor() |
|---|
| 120 | ssow = Monitor() |
|---|
| 121 | solver = NelderMeadSimplexSolver(ndim) |
|---|
| 122 | solver.SetInitialPoints(x0) |
|---|
| 123 | solver.SetStrictRanges(lb, ub) |
|---|
| 124 | solver.SetEvaluationLimits(generations=maxiter) |
|---|
| 125 | solver.SetEvaluationMonitor(esow) |
|---|
| 126 | solver.SetGenerationMonitor(ssow) |
|---|
| 127 | term = CRT() |
|---|
| 128 | time1 = time.time() # Is this an ok way of timing? |
|---|
| 129 | solver.Solve(costfunc, term) |
|---|
| 130 | sol = solver.Solution() |
|---|
| 131 | time_elapsed = time.time() - time1 |
|---|
| 132 | fx = solver.bestEnergy |
|---|
| 133 | print "Solution: ", sol |
|---|
| 134 | print "f value: ", fx |
|---|
| 135 | print "Iterations: ", solver.generations |
|---|
| 136 | print "Function evaluations: ", len(esow.x) |
|---|
| 137 | print "Time elapsed: ", time_elapsed, " seconds" |
|---|
| 138 | assert almostEqual(fx, 1.08732211477e-09, tol=3e-3) |
|---|
| 139 | |
|---|
| 140 | # PowellDirectionalSolver |
|---|
| 141 | print "\nUsing PowellDirectionalSolver:" |
|---|
| 142 | from mystic.solvers import PowellDirectionalSolver |
|---|
| 143 | from mystic.termination import NormalizedChangeOverGeneration as NCOG |
|---|
| 144 | esow = Monitor() |
|---|
| 145 | ssow = Monitor() |
|---|
| 146 | solver = PowellDirectionalSolver(ndim) |
|---|
| 147 | solver.SetInitialPoints(x0) |
|---|
| 148 | solver.SetStrictRanges(lb, ub) |
|---|
| 149 | solver.SetEvaluationLimits(generations=maxiter) |
|---|
| 150 | solver.SetEvaluationMonitor(esow) |
|---|
| 151 | solver.SetGenerationMonitor(ssow) |
|---|
| 152 | term = NCOG(1e-10) |
|---|
| 153 | time1 = time.time() # Is this an ok way of timing? |
|---|
| 154 | solver.Solve(costfunc, term) |
|---|
| 155 | sol = solver.Solution() |
|---|
| 156 | time_elapsed = time.time() - time1 |
|---|
| 157 | fx = solver.bestEnergy |
|---|
| 158 | print "Solution: ", sol |
|---|
| 159 | print "f value: ", fx |
|---|
| 160 | print "Iterations: ", solver.generations |
|---|
| 161 | print "Function evaluations: ", len(esow.x) |
|---|
| 162 | print "Time elapsed: ", time_elapsed, " seconds" |
|---|
| 163 | assert almostEqual(fx, 0.0, tol=3e-3) |
|---|
| 164 | |
|---|
| 165 | def test_griewangk(): |
|---|
| 166 | """Test Griewangk's function, which has many local minima. |
|---|
| 167 | |
|---|
| 168 | Testing Griewangk: |
|---|
| 169 | Expected: x=[0.]*10 and f=0 |
|---|
| 170 | |
|---|
| 171 | Using DifferentialEvolutionSolver: |
|---|
| 172 | Solution: [ 8.87516194e-09 7.26058147e-09 1.02076001e-08 1.54219038e-08 |
|---|
| 173 | -1.54328461e-08 2.34589663e-08 2.02809360e-08 -1.36385836e-08 |
|---|
| 174 | 1.38670373e-08 1.59668900e-08] |
|---|
| 175 | f value: 0.0 |
|---|
| 176 | Iterations: 4120 |
|---|
| 177 | Function evaluations: 205669 |
|---|
| 178 | Time elapsed: 34.4936850071 seconds |
|---|
| 179 | |
|---|
| 180 | Using DifferentialEvolutionSolver2: |
|---|
| 181 | Solution: [ -2.02709316e-09 3.22017968e-09 1.55275472e-08 5.26739541e-09 |
|---|
| 182 | -2.18490470e-08 3.73725584e-09 -1.02315312e-09 1.24680355e-08 |
|---|
| 183 | -9.47898116e-09 2.22243557e-08] |
|---|
| 184 | f value: 0.0 |
|---|
| 185 | Iterations: 4011 |
|---|
| 186 | Function evaluations: 200215 |
|---|
| 187 | Time elapsed: 32.8412370682 seconds |
|---|
| 188 | """ |
|---|
| 189 | |
|---|
| 190 | print "Testing Griewangk:" |
|---|
| 191 | print "Expected: x=[0.]*10 and f=0" |
|---|
| 192 | from mystic.models import griewangk as costfunc |
|---|
| 193 | ndim = 10 |
|---|
| 194 | lb = [-400.]*ndim |
|---|
| 195 | ub = [400.]*ndim |
|---|
| 196 | maxiter = 10000 |
|---|
| 197 | seed = 123 # Re-seed for each solver to have them all start at same x0 |
|---|
| 198 | |
|---|
| 199 | # DifferentialEvolutionSolver |
|---|
| 200 | print "\nUsing DifferentialEvolutionSolver:" |
|---|
| 201 | npop = 50 |
|---|
| 202 | random_seed(seed) |
|---|
| 203 | from mystic.solvers import DifferentialEvolutionSolver |
|---|
| 204 | from mystic.termination import ChangeOverGeneration as COG |
|---|
| 205 | from mystic.termination import CandidateRelativeTolerance as CRT |
|---|
| 206 | from mystic.termination import VTR |
|---|
| 207 | from mystic.strategy import Rand1Bin, Best1Bin, Rand1Exp |
|---|
| 208 | esow = Monitor() |
|---|
| 209 | ssow = Monitor() |
|---|
| 210 | solver = DifferentialEvolutionSolver(ndim, npop) |
|---|
| 211 | solver.SetRandomInitialPoints(lb, ub) |
|---|
| 212 | solver.SetStrictRanges(lb, ub) |
|---|
| 213 | solver.SetEvaluationLimits(generations=maxiter) |
|---|
| 214 | solver.SetEvaluationMonitor(esow) |
|---|
| 215 | solver.SetGenerationMonitor(ssow) |
|---|
| 216 | solver.enable_signal_handler() |
|---|
| 217 | #term = COG(1e-10) |
|---|
| 218 | #term = CRT() |
|---|
| 219 | term = VTR(0.) |
|---|
| 220 | time1 = time.time() # Is this an ok way of timing? |
|---|
| 221 | solver.Solve(costfunc, term, strategy=Rand1Exp, \ |
|---|
| 222 | CrossProbability=0.3, ScalingFactor=1.0) |
|---|
| 223 | sol = solver.Solution() |
|---|
| 224 | time_elapsed = time.time() - time1 |
|---|
| 225 | fx = solver.bestEnergy |
|---|
| 226 | print "Solution: ", sol |
|---|
| 227 | print "f value: ", fx |
|---|
| 228 | print "Iterations: ", solver.generations |
|---|
| 229 | print "Function evaluations: ", len(esow.x) |
|---|
| 230 | print "Time elapsed: ", time_elapsed, " seconds" |
|---|
| 231 | assert almostEqual(fx, 0.0, tol=3e-3) |
|---|
| 232 | |
|---|
| 233 | # DifferentialEvolutionSolver2 |
|---|
| 234 | print "\nUsing DifferentialEvolutionSolver2:" |
|---|
| 235 | npop = 50 |
|---|
| 236 | random_seed(seed) |
|---|
| 237 | from mystic.solvers import DifferentialEvolutionSolver2 |
|---|
| 238 | from mystic.termination import ChangeOverGeneration as COG |
|---|
| 239 | from mystic.termination import CandidateRelativeTolerance as CRT |
|---|
| 240 | from mystic.termination import VTR |
|---|
| 241 | from mystic.strategy import Rand1Bin, Best1Bin, Rand1Exp |
|---|
| 242 | esow = Monitor() |
|---|
| 243 | ssow = Monitor() |
|---|
| 244 | solver = DifferentialEvolutionSolver2(ndim, npop) |
|---|
| 245 | solver.SetRandomInitialPoints(lb, ub) |
|---|
| 246 | solver.SetStrictRanges(lb, ub) |
|---|
| 247 | solver.SetEvaluationLimits(generations=maxiter) |
|---|
| 248 | solver.SetEvaluationMonitor(esow) |
|---|
| 249 | solver.SetGenerationMonitor(ssow) |
|---|
| 250 | #term = COG(1e-10) |
|---|
| 251 | #term = CRT() |
|---|
| 252 | term = VTR(0.) |
|---|
| 253 | time1 = time.time() # Is this an ok way of timing? |
|---|
| 254 | solver.Solve(costfunc, term, strategy=Rand1Exp, \ |
|---|
| 255 | CrossProbability=0.3, ScalingFactor=1.0) |
|---|
| 256 | sol = solver.Solution() |
|---|
| 257 | time_elapsed = time.time() - time1 |
|---|
| 258 | fx = solver.bestEnergy |
|---|
| 259 | print "Solution: ", sol |
|---|
| 260 | print "f value: ", fx |
|---|
| 261 | print "Iterations: ", solver.generations |
|---|
| 262 | print "Function evaluations: ", len(esow.x) |
|---|
| 263 | print "Time elapsed: ", time_elapsed, " seconds" |
|---|
| 264 | assert almostEqual(fx, 0.0, tol=3e-3) |
|---|
| 265 | |
|---|
| 266 | if __name__ == '__main__': |
|---|
| 267 | test_rosenbrock() |
|---|
| 268 | #test_griewangk() |
|---|