nlopt
Version:
A numerical nonlinear optimization library for node. A wrapper around nlopt.
142 lines (135 loc) • 5.08 kB
text/coffeescript
_ = require('lodash')
expect = require('expect.js')
nlopt = require("../nlopt.js")
request = require("request")
describe('basic', ()->
checkResults = (actual, expected)->
equal = _.isEqualWith(actual, expected, (a,b)->
if _.isNumber(a) and _.isNumber(b)
return Math.abs(a-b) < 0.1
)
if !equal
throw new Error("#{if actual then JSON.stringify(actual) else 'undefined' } does not equal #{if expected then JSON.stringify(expected) else 'undefined'}")
it('MLE Example', ()->
data = [
0.988877, 0.991881, 0.739757, 0.940761, 0.986811, 0.903514,
0.984382, 0.888095, 0.864229, 0.95791, 0.915919, 0.990257, 0.94347,
0.89609, 0.996033, 0.873548, 0.899078, 0.893999, 0.900032, 0.945644,
0.843792, 0.932261, 0.810629, 0.971378, 0.994914, 0.954882, 0.96594,
0.995431, 0.867875, 0.988802, 0.989609, 0.988265, 0.937092, 0.949935,
0.880011, 0.872334, 0.880399, 0.96665, 0.774511, 0.848686, 0.863713,
0.897073, 0.959902, 0.885167, 0.943062, 0.898766, 0.825464, 0.999472,
0.924695, 0.874632
]
erfc = (x)->
z = Math.abs(x)
t = 1 / (1 + z / 2)
r = t * Math.exp(-z * z - 1.26551223 + t * (1.00002368 +
t * (0.37409196 + t * (0.09678418 + t * (-0.18628806 +
t * (0.27886807 + t * (-1.13520398 + t * (1.48851587 +
t * (-0.82215223 + t * 0.17087277)))))))))
return if x >= 0 then r else 2 - r
sq = (x)->x*x
log = Math.log
objectiveFunc = (n, x)->
partial = -0.9189385332046727 - log(x[1]) - log(0.5*erfc((0.7071067811865475*(-1 + x[0]))/x[1]) - 0.5*erfc((0.7071067811865475*x[0])/x[1]))
return _.reduce(data, (sum, val)->
return sum - (0.5*sq(val - x[0]))/sq(x[1]) + partial
, 0)
options = {
algorithm: "LN_NELDERMEAD"
numberOfParameters:2
maxObjectiveFunction: objectiveFunc
xToleranceRelative:1e-4
initalGuess:[0.5, 0.5]
lowerBounds:[0, -5]
upperBounds:[1, 5]
}
expectedResult = {
maxObjectiveFunction: 'Success',
lowerBounds: 'Success',
upperBounds: 'Success',
xToleranceRelative: 'Success',
initalGuess: 'Success',
status: 'Success: Optimization stopped because xToleranceRelative or xToleranceAbsolute was reached',
parameterValues: [ 1, 0.1 ],
outputValue: 78.4539
}
checkResults(nlopt(options), expectedResult)
)
it('newton + simplex', ()->
objectiveFunc = (n, x, grad)->
if(grad)
grad[0] = 16*x[0] - 4*x[0]*x[0]*x[0]
x = 4 + 8*x[0]*x[0] - x[0]*x[0]*x[0]*x[0]
#example from
#http://www-rohan.sdsu.edu/~jmahaffy/courses/f00/math122/lectures/newtons_method/newtonmethodeg.html
expectedResult = {
maxObjectiveFunction: 'Success'
lowerBounds: 'Success'
upperBounds: 'Success'
xToleranceRelative: 'Success'
inequalityConstraints: 'Failure: Invalid arguments'
initalGuess: 'Success'
status: 'Success'
parameterValues: [ -2.00000000000279 ]
outputValue: 20
}
options = {
algorithm: "NLOPT_LD_TNEWTON_PRECOND_RESTART"
numberOfParameters:1
maxObjectiveFunction: objectiveFunc
inequalityConstraints:[{callback:(()->),tolerance:1}]#should not work for newton
xToleranceRelative:1e-4
initalGuess:[-1]
lowerBounds:[-10]
upperBounds:[10]
}
checkResults(nlopt(options), expectedResult)
expectedResult.parameterValues[0] = 2
options.initalGuess[0] = 2.5
checkResults(nlopt(options), expectedResult)
options.algorithm = "LN_NELDERMEAD"
expectedResult.status = 'Success: Optimization stopped because xToleranceRelative or xToleranceAbsolute was reached'
checkResults(nlopt(options), expectedResult)
)
it('example', ()->
myfunc = (n, x, grad)->
if(grad)
grad[0] = 0.0
grad[1] = 0.5 / Math.sqrt(x[1])
return Math.sqrt(x[1])
createMyConstraint = (cd)->
return {
callback:(n, x, grad)->
if(grad)
grad[0] = 3.0 * cd[0] * (cd[0]*x[0] + cd[1]) * (cd[0]*x[0] + cd[1])
grad[1] = -1.0
tmp = cd[0]*x[0] + cd[1]
return tmp * tmp * tmp - x[1]
tolerance:1e-8
}
expectedResult = {
minObjectiveFunction: 'Success'
lowerBounds: 'Success'
xToleranceRelative: 'Success'
inequalityConstraints: 'Success'
initalGuess: 'Success'
status: 'Success: Optimization stopped because xToleranceRelative or xToleranceAbsolute was reached'
parameterValues: [ 0.33333333465873644, 0.2962962893886998 ]
outputValue: 0.5443310476067847
}
options = {
algorithm: "LD_MMA"
numberOfParameters:2
minObjectiveFunction: myfunc
inequalityConstraints:[createMyConstraint([2.0, 0.0]), createMyConstraint([-1.0, 1.0])]
xToleranceRelative:1e-4
initalGuess:[1.234, 5.678]
lowerBounds:[Number.MIN_VALUE, 0]
}
checkResults(nlopt(options), expectedResult)
options.algorithm = "NLOPT_LN_COBYLA"
checkResults(nlopt(options), expectedResult)
)
)