mirror of
https://github.com/gonum/gonum.git
synced 2025-10-15 11:40:45 +08:00
optimize: unify Gradient and Hessian API behaviour
This commit is contained in:
@@ -36,13 +36,10 @@ func (Beale) Func(x []float64) float64 {
|
|||||||
return f1*f1 + f2*f2 + f3*f3
|
return f1*f1 + f2*f2 + f3*f3
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Beale) Grad(grad, x []float64) []float64 {
|
func (Beale) Grad(grad, x []float64) {
|
||||||
if len(x) != 2 {
|
if len(x) != 2 {
|
||||||
panic("dimension of the problem must be 2")
|
panic("dimension of the problem must be 2")
|
||||||
}
|
}
|
||||||
if grad == nil {
|
|
||||||
grad = make([]float64, len(x))
|
|
||||||
}
|
|
||||||
if len(x) != len(grad) {
|
if len(x) != len(grad) {
|
||||||
panic("incorrect size of the gradient")
|
panic("incorrect size of the gradient")
|
||||||
}
|
}
|
||||||
@@ -57,16 +54,13 @@ func (Beale) Grad(grad, x []float64) []float64 {
|
|||||||
|
|
||||||
grad[0] = -2 * (f1*t1 + f2*t2 + f3*t3)
|
grad[0] = -2 * (f1*t1 + f2*t2 + f3*t3)
|
||||||
grad[1] = 2 * x[0] * (f1 + 2*f2*x[1] + 3*f3*x[1]*x[1])
|
grad[1] = 2 * x[0] * (f1 + 2*f2*x[1] + 3*f3*x[1]*x[1])
|
||||||
return grad
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Beale) Hess(dst *mat.SymDense, x []float64) {
|
func (Beale) Hess(dst *mat.SymDense, x []float64) {
|
||||||
if len(x) != 2 {
|
if len(x) != 2 {
|
||||||
panic("dimension of the problem must be 2")
|
panic("dimension of the problem must be 2")
|
||||||
}
|
}
|
||||||
if dst.IsZero() {
|
if len(x) != dst.Symmetric() {
|
||||||
*dst = *(dst.GrowSym(len(x)).(*mat.SymDense))
|
|
||||||
} else if len(x) != dst.Symmetric() {
|
|
||||||
panic("incorrect size of the Hessian")
|
panic("incorrect size of the Hessian")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,13 +113,10 @@ func (BiggsEXP2) Func(x []float64) (sum float64) {
|
|||||||
return sum
|
return sum
|
||||||
}
|
}
|
||||||
|
|
||||||
func (BiggsEXP2) Grad(grad, x []float64) []float64 {
|
func (BiggsEXP2) Grad(grad, x []float64) {
|
||||||
if len(x) != 2 {
|
if len(x) != 2 {
|
||||||
panic("dimension of the problem must be 2")
|
panic("dimension of the problem must be 2")
|
||||||
}
|
}
|
||||||
if grad == nil {
|
|
||||||
grad = make([]float64, len(x))
|
|
||||||
}
|
|
||||||
if len(x) != len(grad) {
|
if len(x) != len(grad) {
|
||||||
panic("incorrect size of the gradient")
|
panic("incorrect size of the gradient")
|
||||||
}
|
}
|
||||||
@@ -144,7 +135,6 @@ func (BiggsEXP2) Grad(grad, x []float64) []float64 {
|
|||||||
grad[0] += 2 * f * dfdx0
|
grad[0] += 2 * f * dfdx0
|
||||||
grad[1] += 2 * f * dfdx1
|
grad[1] += 2 * f * dfdx1
|
||||||
}
|
}
|
||||||
return grad
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (BiggsEXP2) Minima() []Minimum {
|
func (BiggsEXP2) Minima() []Minimum {
|
||||||
@@ -181,13 +171,10 @@ func (BiggsEXP3) Func(x []float64) (sum float64) {
|
|||||||
return sum
|
return sum
|
||||||
}
|
}
|
||||||
|
|
||||||
func (BiggsEXP3) Grad(grad, x []float64) []float64 {
|
func (BiggsEXP3) Grad(grad, x []float64) {
|
||||||
if len(x) != 3 {
|
if len(x) != 3 {
|
||||||
panic("dimension of the problem must be 3")
|
panic("dimension of the problem must be 3")
|
||||||
}
|
}
|
||||||
if grad == nil {
|
|
||||||
grad = make([]float64, len(x))
|
|
||||||
}
|
|
||||||
if len(x) != len(grad) {
|
if len(x) != len(grad) {
|
||||||
panic("incorrect size of the gradient")
|
panic("incorrect size of the gradient")
|
||||||
}
|
}
|
||||||
@@ -208,7 +195,6 @@ func (BiggsEXP3) Grad(grad, x []float64) []float64 {
|
|||||||
grad[1] += 2 * f * dfdx1
|
grad[1] += 2 * f * dfdx1
|
||||||
grad[2] += 2 * f * dfdx2
|
grad[2] += 2 * f * dfdx2
|
||||||
}
|
}
|
||||||
return grad
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (BiggsEXP3) Minima() []Minimum {
|
func (BiggsEXP3) Minima() []Minimum {
|
||||||
@@ -245,13 +231,10 @@ func (BiggsEXP4) Func(x []float64) (sum float64) {
|
|||||||
return sum
|
return sum
|
||||||
}
|
}
|
||||||
|
|
||||||
func (BiggsEXP4) Grad(grad, x []float64) []float64 {
|
func (BiggsEXP4) Grad(grad, x []float64) {
|
||||||
if len(x) != 4 {
|
if len(x) != 4 {
|
||||||
panic("dimension of the problem must be 4")
|
panic("dimension of the problem must be 4")
|
||||||
}
|
}
|
||||||
if grad == nil {
|
|
||||||
grad = make([]float64, len(x))
|
|
||||||
}
|
|
||||||
if len(x) != len(grad) {
|
if len(x) != len(grad) {
|
||||||
panic("incorrect size of the gradient")
|
panic("incorrect size of the gradient")
|
||||||
}
|
}
|
||||||
@@ -274,7 +257,6 @@ func (BiggsEXP4) Grad(grad, x []float64) []float64 {
|
|||||||
grad[2] += 2 * f * dfdx2
|
grad[2] += 2 * f * dfdx2
|
||||||
grad[3] += 2 * f * dfdx3
|
grad[3] += 2 * f * dfdx3
|
||||||
}
|
}
|
||||||
return grad
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (BiggsEXP4) Minima() []Minimum {
|
func (BiggsEXP4) Minima() []Minimum {
|
||||||
@@ -311,13 +293,10 @@ func (BiggsEXP5) Func(x []float64) (sum float64) {
|
|||||||
return sum
|
return sum
|
||||||
}
|
}
|
||||||
|
|
||||||
func (BiggsEXP5) Grad(grad, x []float64) []float64 {
|
func (BiggsEXP5) Grad(grad, x []float64) {
|
||||||
if len(x) != 5 {
|
if len(x) != 5 {
|
||||||
panic("dimension of the problem must be 5")
|
panic("dimension of the problem must be 5")
|
||||||
}
|
}
|
||||||
if grad == nil {
|
|
||||||
grad = make([]float64, len(x))
|
|
||||||
}
|
|
||||||
if len(x) != len(grad) {
|
if len(x) != len(grad) {
|
||||||
panic("incorrect size of the gradient")
|
panic("incorrect size of the gradient")
|
||||||
}
|
}
|
||||||
@@ -342,7 +321,6 @@ func (BiggsEXP5) Grad(grad, x []float64) []float64 {
|
|||||||
grad[3] += 2 * f * dfdx3
|
grad[3] += 2 * f * dfdx3
|
||||||
grad[4] += 2 * f * dfdx4
|
grad[4] += 2 * f * dfdx4
|
||||||
}
|
}
|
||||||
return grad
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (BiggsEXP5) Minima() []Minimum {
|
func (BiggsEXP5) Minima() []Minimum {
|
||||||
@@ -382,13 +360,10 @@ func (BiggsEXP6) Func(x []float64) (sum float64) {
|
|||||||
return sum
|
return sum
|
||||||
}
|
}
|
||||||
|
|
||||||
func (BiggsEXP6) Grad(grad, x []float64) []float64 {
|
func (BiggsEXP6) Grad(grad, x []float64) {
|
||||||
if len(x) != 6 {
|
if len(x) != 6 {
|
||||||
panic("dimension of the problem must be 6")
|
panic("dimension of the problem must be 6")
|
||||||
}
|
}
|
||||||
if grad == nil {
|
|
||||||
grad = make([]float64, len(x))
|
|
||||||
}
|
|
||||||
if len(x) != len(grad) {
|
if len(x) != len(grad) {
|
||||||
panic("incorrect size of the gradient")
|
panic("incorrect size of the gradient")
|
||||||
}
|
}
|
||||||
@@ -415,7 +390,6 @@ func (BiggsEXP6) Grad(grad, x []float64) []float64 {
|
|||||||
grad[4] += 2 * f * dfdx4
|
grad[4] += 2 * f * dfdx4
|
||||||
grad[5] += 2 * f * dfdx5
|
grad[5] += 2 * f * dfdx5
|
||||||
}
|
}
|
||||||
return grad
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (BiggsEXP6) Minima() []Minimum {
|
func (BiggsEXP6) Minima() []Minimum {
|
||||||
@@ -466,13 +440,10 @@ func (Box3D) Func(x []float64) (sum float64) {
|
|||||||
return sum
|
return sum
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Box3D) Grad(grad, x []float64) []float64 {
|
func (Box3D) Grad(grad, x []float64) {
|
||||||
if len(x) != 3 {
|
if len(x) != 3 {
|
||||||
panic("dimension of the problem must be 3")
|
panic("dimension of the problem must be 3")
|
||||||
}
|
}
|
||||||
if grad == nil {
|
|
||||||
grad = make([]float64, len(x))
|
|
||||||
}
|
|
||||||
if len(x) != len(grad) {
|
if len(x) != len(grad) {
|
||||||
panic("incorrect size of the gradient")
|
panic("incorrect size of the gradient")
|
||||||
}
|
}
|
||||||
@@ -488,7 +459,6 @@ func (Box3D) Grad(grad, x []float64) []float64 {
|
|||||||
grad[1] += -2 * f * c * math.Exp(c*x[1])
|
grad[1] += -2 * f * c * math.Exp(c*x[1])
|
||||||
grad[2] += -2 * f * y
|
grad[2] += -2 * f * y
|
||||||
}
|
}
|
||||||
return grad
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Box3D) Minima() []Minimum {
|
func (Box3D) Minima() []Minimum {
|
||||||
@@ -573,13 +543,10 @@ func (BrownBadlyScaled) Func(x []float64) float64 {
|
|||||||
return f1*f1 + f2*f2 + f3*f3
|
return f1*f1 + f2*f2 + f3*f3
|
||||||
}
|
}
|
||||||
|
|
||||||
func (BrownBadlyScaled) Grad(grad, x []float64) []float64 {
|
func (BrownBadlyScaled) Grad(grad, x []float64) {
|
||||||
if len(x) != 2 {
|
if len(x) != 2 {
|
||||||
panic("dimension of the problem must be 2")
|
panic("dimension of the problem must be 2")
|
||||||
}
|
}
|
||||||
if grad == nil {
|
|
||||||
grad = make([]float64, len(x))
|
|
||||||
}
|
|
||||||
if len(x) != len(grad) {
|
if len(x) != len(grad) {
|
||||||
panic("incorrect size of the gradient")
|
panic("incorrect size of the gradient")
|
||||||
}
|
}
|
||||||
@@ -589,16 +556,13 @@ func (BrownBadlyScaled) Grad(grad, x []float64) []float64 {
|
|||||||
f3 := x[0]*x[1] - 2
|
f3 := x[0]*x[1] - 2
|
||||||
grad[0] = 2*f1 + 2*f3*x[1]
|
grad[0] = 2*f1 + 2*f3*x[1]
|
||||||
grad[1] = 2*f2 + 2*f3*x[0]
|
grad[1] = 2*f2 + 2*f3*x[0]
|
||||||
return grad
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (BrownBadlyScaled) Hess(dst *mat.SymDense, x []float64) {
|
func (BrownBadlyScaled) Hess(dst *mat.SymDense, x []float64) {
|
||||||
if len(x) != 2 {
|
if len(x) != 2 {
|
||||||
panic("dimension of the problem must be 2")
|
panic("dimension of the problem must be 2")
|
||||||
}
|
}
|
||||||
if dst.IsZero() {
|
if len(x) != dst.Symmetric() {
|
||||||
*dst = *(dst.GrowSym(len(x)).(*mat.SymDense))
|
|
||||||
} else if len(x) != dst.Symmetric() {
|
|
||||||
panic("incorrect size of the Hessian")
|
panic("incorrect size of the Hessian")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -648,13 +612,10 @@ func (BrownAndDennis) Func(x []float64) (sum float64) {
|
|||||||
return sum
|
return sum
|
||||||
}
|
}
|
||||||
|
|
||||||
func (BrownAndDennis) Grad(grad, x []float64) []float64 {
|
func (BrownAndDennis) Grad(grad, x []float64) {
|
||||||
if len(x) != 4 {
|
if len(x) != 4 {
|
||||||
panic("dimension of the problem must be 4")
|
panic("dimension of the problem must be 4")
|
||||||
}
|
}
|
||||||
if grad == nil {
|
|
||||||
grad = make([]float64, len(x))
|
|
||||||
}
|
|
||||||
if len(x) != len(grad) {
|
if len(x) != len(grad) {
|
||||||
panic("incorrect size of the gradient")
|
panic("incorrect size of the gradient")
|
||||||
}
|
}
|
||||||
@@ -672,16 +633,13 @@ func (BrownAndDennis) Grad(grad, x []float64) []float64 {
|
|||||||
grad[2] += 4 * f * f2
|
grad[2] += 4 * f * f2
|
||||||
grad[3] += 4 * f * f2 * math.Sin(c)
|
grad[3] += 4 * f * f2 * math.Sin(c)
|
||||||
}
|
}
|
||||||
return grad
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (BrownAndDennis) Hess(dst *mat.SymDense, x []float64) {
|
func (BrownAndDennis) Hess(dst *mat.SymDense, x []float64) {
|
||||||
if len(x) != 4 {
|
if len(x) != 4 {
|
||||||
panic("dimension of the problem must be 4")
|
panic("dimension of the problem must be 4")
|
||||||
}
|
}
|
||||||
if dst.IsZero() {
|
if len(x) != dst.Symmetric() {
|
||||||
*dst = *(dst.GrowSym(len(x)).(*mat.SymDense))
|
|
||||||
} else if len(x) != dst.Symmetric() {
|
|
||||||
panic("incorrect size of the Hessian")
|
panic("incorrect size of the Hessian")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -758,13 +716,10 @@ func (ExtendedPowellSingular) Func(x []float64) (sum float64) {
|
|||||||
return sum
|
return sum
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ExtendedPowellSingular) Grad(grad, x []float64) []float64 {
|
func (ExtendedPowellSingular) Grad(grad, x []float64) {
|
||||||
if len(x)%4 != 0 {
|
if len(x)%4 != 0 {
|
||||||
panic("dimension of the problem must be a multiple of 4")
|
panic("dimension of the problem must be a multiple of 4")
|
||||||
}
|
}
|
||||||
if grad == nil {
|
|
||||||
grad = make([]float64, len(x))
|
|
||||||
}
|
|
||||||
if len(x) != len(grad) {
|
if len(x) != len(grad) {
|
||||||
panic("incorrect size of the gradient")
|
panic("incorrect size of the gradient")
|
||||||
}
|
}
|
||||||
@@ -781,7 +736,6 @@ func (ExtendedPowellSingular) Grad(grad, x []float64) []float64 {
|
|||||||
grad[i+2] = 10*f2 - 8*f3*t1
|
grad[i+2] = 10*f2 - 8*f3*t1
|
||||||
grad[i+3] = -10*f2 - 40*f4*t2
|
grad[i+3] = -10*f2 - 40*f4*t2
|
||||||
}
|
}
|
||||||
return grad
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ExtendedPowellSingular) Minima() []Minimum {
|
func (ExtendedPowellSingular) Minima() []Minimum {
|
||||||
@@ -826,10 +780,7 @@ func (ExtendedRosenbrock) Func(x []float64) (sum float64) {
|
|||||||
return sum
|
return sum
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ExtendedRosenbrock) Grad(grad, x []float64) []float64 {
|
func (ExtendedRosenbrock) Grad(grad, x []float64) {
|
||||||
if grad == nil {
|
|
||||||
grad = make([]float64, len(x))
|
|
||||||
}
|
|
||||||
if len(x) != len(grad) {
|
if len(x) != len(grad) {
|
||||||
panic("incorrect size of the gradient")
|
panic("incorrect size of the gradient")
|
||||||
}
|
}
|
||||||
@@ -845,7 +796,6 @@ func (ExtendedRosenbrock) Grad(grad, x []float64) []float64 {
|
|||||||
for i := 1; i < dim; i++ {
|
for i := 1; i < dim; i++ {
|
||||||
grad[i] += 200 * (x[i] - x[i-1]*x[i-1])
|
grad[i] += 200 * (x[i] - x[i-1]*x[i-1])
|
||||||
}
|
}
|
||||||
return grad
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ExtendedRosenbrock) Minima() []Minimum {
|
func (ExtendedRosenbrock) Minima() []Minimum {
|
||||||
@@ -952,13 +902,10 @@ func (g Gaussian) Func(x []float64) (sum float64) {
|
|||||||
return sum
|
return sum
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g Gaussian) Grad(grad, x []float64) []float64 {
|
func (g Gaussian) Grad(grad, x []float64) {
|
||||||
if len(x) != 3 {
|
if len(x) != 3 {
|
||||||
panic("dimension of the problem must be 3")
|
panic("dimension of the problem must be 3")
|
||||||
}
|
}
|
||||||
if grad == nil {
|
|
||||||
grad = make([]float64, len(x))
|
|
||||||
}
|
|
||||||
if len(x) != len(grad) {
|
if len(x) != len(grad) {
|
||||||
panic("incorrect size of the gradient")
|
panic("incorrect size of the gradient")
|
||||||
}
|
}
|
||||||
@@ -976,7 +923,6 @@ func (g Gaussian) Grad(grad, x []float64) []float64 {
|
|||||||
grad[1] -= f * e * d * x[0]
|
grad[1] -= f * e * d * x[0]
|
||||||
grad[2] += 2 * f * e * x[0] * x[1] * b
|
grad[2] += 2 * f * e * x[0] * x[1] * b
|
||||||
}
|
}
|
||||||
return grad
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Gaussian) Minima() []Minimum {
|
func (Gaussian) Minima() []Minimum {
|
||||||
@@ -1018,13 +964,10 @@ func (GulfResearchAndDevelopment) Func(x []float64) (sum float64) {
|
|||||||
return sum
|
return sum
|
||||||
}
|
}
|
||||||
|
|
||||||
func (GulfResearchAndDevelopment) Grad(grad, x []float64) []float64 {
|
func (GulfResearchAndDevelopment) Grad(grad, x []float64) {
|
||||||
if len(x) != 3 {
|
if len(x) != 3 {
|
||||||
panic("dimension of the problem must be 3")
|
panic("dimension of the problem must be 3")
|
||||||
}
|
}
|
||||||
if grad == nil {
|
|
||||||
grad = make([]float64, len(x))
|
|
||||||
}
|
|
||||||
if len(x) != len(grad) {
|
if len(x) != len(grad) {
|
||||||
panic("incorrect size of the gradient")
|
panic("incorrect size of the gradient")
|
||||||
}
|
}
|
||||||
@@ -1046,7 +989,6 @@ func (GulfResearchAndDevelopment) Grad(grad, x []float64) []float64 {
|
|||||||
grad[0] *= 2 / x[0]
|
grad[0] *= 2 / x[0]
|
||||||
grad[1] *= 2 * x[2]
|
grad[1] *= 2 * x[2]
|
||||||
grad[2] *= 2
|
grad[2] *= 2
|
||||||
return grad
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (GulfResearchAndDevelopment) Minima() []Minimum {
|
func (GulfResearchAndDevelopment) Minima() []Minimum {
|
||||||
@@ -1100,13 +1042,10 @@ func (HelicalValley) Func(x []float64) float64 {
|
|||||||
return f1*f1 + f2*f2 + f3*f3
|
return f1*f1 + f2*f2 + f3*f3
|
||||||
}
|
}
|
||||||
|
|
||||||
func (HelicalValley) Grad(grad, x []float64) []float64 {
|
func (HelicalValley) Grad(grad, x []float64) {
|
||||||
if len(x) != 3 {
|
if len(x) != 3 {
|
||||||
panic("dimension of the problem must be 3")
|
panic("dimension of the problem must be 3")
|
||||||
}
|
}
|
||||||
if grad == nil {
|
|
||||||
grad = make([]float64, len(x))
|
|
||||||
}
|
|
||||||
if len(x) != len(grad) {
|
if len(x) != len(grad) {
|
||||||
panic("incorrect size of the gradient")
|
panic("incorrect size of the gradient")
|
||||||
}
|
}
|
||||||
@@ -1125,7 +1064,6 @@ func (HelicalValley) Grad(grad, x []float64) []float64 {
|
|||||||
grad[0] = 200 * (5*s*q*x[1] + (h-1)*r*x[0])
|
grad[0] = 200 * (5*s*q*x[1] + (h-1)*r*x[0])
|
||||||
grad[1] = 200 * (-5*s*q*x[0] + (h-1)*r*x[1])
|
grad[1] = 200 * (-5*s*q*x[0] + (h-1)*r*x[1])
|
||||||
grad[2] = 2 * (100*s + x[2])
|
grad[2] = 2 * (100*s + x[2])
|
||||||
return grad
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (HelicalValley) Minima() []Minimum {
|
func (HelicalValley) Minima() []Minimum {
|
||||||
@@ -1183,10 +1121,7 @@ func (PenaltyI) Func(x []float64) (sum float64) {
|
|||||||
return sum
|
return sum
|
||||||
}
|
}
|
||||||
|
|
||||||
func (PenaltyI) Grad(grad, x []float64) []float64 {
|
func (PenaltyI) Grad(grad, x []float64) {
|
||||||
if grad == nil {
|
|
||||||
grad = make([]float64, len(x))
|
|
||||||
}
|
|
||||||
if len(x) != len(grad) {
|
if len(x) != len(grad) {
|
||||||
panic("incorrect size of the gradient")
|
panic("incorrect size of the gradient")
|
||||||
}
|
}
|
||||||
@@ -1198,7 +1133,6 @@ func (PenaltyI) Grad(grad, x []float64) []float64 {
|
|||||||
for i, v := range x {
|
for i, v := range x {
|
||||||
grad[i] = 2 * (2*s*v + 1e-5*(v-1))
|
grad[i] = 2 * (2*s*v + 1e-5*(v-1))
|
||||||
}
|
}
|
||||||
return grad
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (PenaltyI) Minima() []Minimum {
|
func (PenaltyI) Minima() []Minimum {
|
||||||
@@ -1252,10 +1186,7 @@ func (PenaltyII) Func(x []float64) (sum float64) {
|
|||||||
return sum
|
return sum
|
||||||
}
|
}
|
||||||
|
|
||||||
func (PenaltyII) Grad(grad, x []float64) []float64 {
|
func (PenaltyII) Grad(grad, x []float64) {
|
||||||
if grad == nil {
|
|
||||||
grad = make([]float64, len(x))
|
|
||||||
}
|
|
||||||
if len(x) != len(grad) {
|
if len(x) != len(grad) {
|
||||||
panic("incorrect size of the gradient")
|
panic("incorrect size of the gradient")
|
||||||
}
|
}
|
||||||
@@ -1279,7 +1210,6 @@ func (PenaltyII) Grad(grad, x []float64) []float64 {
|
|||||||
grad[i] += 1e-5 * f * math.Exp(x[i]/10) / 5
|
grad[i] += 1e-5 * f * math.Exp(x[i]/10) / 5
|
||||||
}
|
}
|
||||||
grad[0] += 2 * (x[0] - 0.2)
|
grad[0] += 2 * (x[0] - 0.2)
|
||||||
return grad
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (PenaltyII) Minima() []Minimum {
|
func (PenaltyII) Minima() []Minimum {
|
||||||
@@ -1325,13 +1255,10 @@ func (PowellBadlyScaled) Func(x []float64) float64 {
|
|||||||
return f1*f1 + f2*f2
|
return f1*f1 + f2*f2
|
||||||
}
|
}
|
||||||
|
|
||||||
func (PowellBadlyScaled) Grad(grad, x []float64) []float64 {
|
func (PowellBadlyScaled) Grad(grad, x []float64) {
|
||||||
if len(x) != 2 {
|
if len(x) != 2 {
|
||||||
panic("dimension of the problem must be 2")
|
panic("dimension of the problem must be 2")
|
||||||
}
|
}
|
||||||
if grad == nil {
|
|
||||||
grad = make([]float64, len(x))
|
|
||||||
}
|
|
||||||
if len(x) != len(grad) {
|
if len(x) != len(grad) {
|
||||||
panic("incorrect size of the gradient")
|
panic("incorrect size of the gradient")
|
||||||
}
|
}
|
||||||
@@ -1340,16 +1267,13 @@ func (PowellBadlyScaled) Grad(grad, x []float64) []float64 {
|
|||||||
f2 := math.Exp(-x[0]) + math.Exp(-x[1]) - 1.0001
|
f2 := math.Exp(-x[0]) + math.Exp(-x[1]) - 1.0001
|
||||||
grad[0] = 2 * (1e4*f1*x[1] - f2*math.Exp(-x[0]))
|
grad[0] = 2 * (1e4*f1*x[1] - f2*math.Exp(-x[0]))
|
||||||
grad[1] = 2 * (1e4*f1*x[0] - f2*math.Exp(-x[1]))
|
grad[1] = 2 * (1e4*f1*x[0] - f2*math.Exp(-x[1]))
|
||||||
return grad
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (PowellBadlyScaled) Hess(dst *mat.SymDense, x []float64) {
|
func (PowellBadlyScaled) Hess(dst *mat.SymDense, x []float64) {
|
||||||
if len(x) != 2 {
|
if len(x) != 2 {
|
||||||
panic("dimension of the problem must be 2")
|
panic("dimension of the problem must be 2")
|
||||||
}
|
}
|
||||||
if dst.IsZero() {
|
if len(x) != dst.Symmetric() {
|
||||||
*dst = *(dst.GrowSym(len(x)).(*mat.SymDense))
|
|
||||||
} else if len(x) != dst.Symmetric() {
|
|
||||||
panic("incorrect size of the Hessian")
|
panic("incorrect size of the Hessian")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1401,10 +1325,7 @@ func (Trigonometric) Func(x []float64) (sum float64) {
|
|||||||
return sum
|
return sum
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Trigonometric) Grad(grad, x []float64) []float64 {
|
func (Trigonometric) Grad(grad, x []float64) {
|
||||||
if grad == nil {
|
|
||||||
grad = make([]float64, len(x))
|
|
||||||
}
|
|
||||||
if len(x) != len(grad) {
|
if len(x) != len(grad) {
|
||||||
panic("incorrect size of the gradient")
|
panic("incorrect size of the gradient")
|
||||||
}
|
}
|
||||||
@@ -1424,7 +1345,6 @@ func (Trigonometric) Grad(grad, x []float64) []float64 {
|
|||||||
for i, v := range x {
|
for i, v := range x {
|
||||||
grad[i] += 2 * s2 * math.Sin(v)
|
grad[i] += 2 * s2 * math.Sin(v)
|
||||||
}
|
}
|
||||||
return grad
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Trigonometric) Minima() []Minimum {
|
func (Trigonometric) Minima() []Minimum {
|
||||||
@@ -1477,10 +1397,7 @@ func (VariablyDimensioned) Func(x []float64) (sum float64) {
|
|||||||
return sum
|
return sum
|
||||||
}
|
}
|
||||||
|
|
||||||
func (VariablyDimensioned) Grad(grad, x []float64) []float64 {
|
func (VariablyDimensioned) Grad(grad, x []float64) {
|
||||||
if grad == nil {
|
|
||||||
grad = make([]float64, len(x))
|
|
||||||
}
|
|
||||||
if len(x) != len(grad) {
|
if len(x) != len(grad) {
|
||||||
panic("incorrect size of the gradient")
|
panic("incorrect size of the gradient")
|
||||||
}
|
}
|
||||||
@@ -1492,7 +1409,6 @@ func (VariablyDimensioned) Grad(grad, x []float64) []float64 {
|
|||||||
for i, v := range x {
|
for i, v := range x {
|
||||||
grad[i] = 2 * (v - 1 + s*float64(i+1)*(1+2*s*s))
|
grad[i] = 2 * (v - 1 + s*float64(i+1)*(1+2*s*s))
|
||||||
}
|
}
|
||||||
return grad
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (VariablyDimensioned) Minima() []Minimum {
|
func (VariablyDimensioned) Minima() []Minimum {
|
||||||
@@ -1565,10 +1481,7 @@ func (Watson) Func(x []float64) (sum float64) {
|
|||||||
return sum
|
return sum
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Watson) Grad(grad, x []float64) []float64 {
|
func (Watson) Grad(grad, x []float64) {
|
||||||
if grad == nil {
|
|
||||||
grad = make([]float64, len(x))
|
|
||||||
}
|
|
||||||
if len(x) != len(grad) {
|
if len(x) != len(grad) {
|
||||||
panic("incorrect size of the gradient")
|
panic("incorrect size of the gradient")
|
||||||
}
|
}
|
||||||
@@ -1604,14 +1517,11 @@ func (Watson) Grad(grad, x []float64) []float64 {
|
|||||||
t := x[1] - x[0]*x[0] - 1
|
t := x[1] - x[0]*x[0] - 1
|
||||||
grad[0] += x[0] * (2 - 4*t)
|
grad[0] += x[0] * (2 - 4*t)
|
||||||
grad[1] += 2 * t
|
grad[1] += 2 * t
|
||||||
return grad
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Watson) Hess(dst *mat.SymDense, x []float64) {
|
func (Watson) Hess(dst *mat.SymDense, x []float64) {
|
||||||
dim := len(x)
|
dim := len(x)
|
||||||
if dst.IsZero() {
|
if len(x) != dst.Symmetric() {
|
||||||
*dst = *(dst.GrowSym(len(x)).(*mat.SymDense))
|
|
||||||
} else if len(x) != dst.Symmetric() {
|
|
||||||
panic("incorrect size of the Hessian")
|
panic("incorrect size of the Hessian")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1709,13 +1619,10 @@ func (Wood) Func(x []float64) (sum float64) {
|
|||||||
return 100*f1*f1 + f2*f2 + 90*f3*f3 + f4*f4 + 10*f5*f5 + 0.1*f6*f6
|
return 100*f1*f1 + f2*f2 + 90*f3*f3 + f4*f4 + 10*f5*f5 + 0.1*f6*f6
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Wood) Grad(grad, x []float64) []float64 {
|
func (Wood) Grad(grad, x []float64) {
|
||||||
if len(x) != 4 {
|
if len(x) != 4 {
|
||||||
panic("dimension of the problem must be 4")
|
panic("dimension of the problem must be 4")
|
||||||
}
|
}
|
||||||
if grad == nil {
|
|
||||||
grad = make([]float64, len(x))
|
|
||||||
}
|
|
||||||
if len(x) != len(grad) {
|
if len(x) != len(grad) {
|
||||||
panic("incorrect size of the gradient")
|
panic("incorrect size of the gradient")
|
||||||
}
|
}
|
||||||
@@ -1730,16 +1637,13 @@ func (Wood) Grad(grad, x []float64) []float64 {
|
|||||||
grad[1] = 2 * (100*f1 + 10*f5 + 0.1*f6)
|
grad[1] = 2 * (100*f1 + 10*f5 + 0.1*f6)
|
||||||
grad[2] = -2 * (180*f3*x[2] + f4)
|
grad[2] = -2 * (180*f3*x[2] + f4)
|
||||||
grad[3] = 2 * (90*f3 + 10*f5 - 0.1*f6)
|
grad[3] = 2 * (90*f3 + 10*f5 - 0.1*f6)
|
||||||
return grad
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Wood) Hess(dst *mat.SymDense, x []float64) {
|
func (Wood) Hess(dst *mat.SymDense, x []float64) {
|
||||||
if len(x) != 4 {
|
if len(x) != 4 {
|
||||||
panic("dimension of the problem must be 4")
|
panic("dimension of the problem must be 4")
|
||||||
}
|
}
|
||||||
if dst.IsZero() {
|
if len(x) != dst.Symmetric() {
|
||||||
*dst = *(dst.GrowSym(len(x)).(*mat.SymDense))
|
|
||||||
} else if len(x) != dst.Symmetric() {
|
|
||||||
panic("incorrect size of the Hessian")
|
panic("incorrect size of the Hessian")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1780,7 +1684,7 @@ func (ConcaveRight) Func(x []float64) float64 {
|
|||||||
return -x[0] / (x[0]*x[0] + 2)
|
return -x[0] / (x[0]*x[0] + 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ConcaveRight) Grad(grad, x []float64) []float64 {
|
func (ConcaveRight) Grad(grad, x []float64) {
|
||||||
if len(x) != 1 {
|
if len(x) != 1 {
|
||||||
panic("dimension of the problem must be 1")
|
panic("dimension of the problem must be 1")
|
||||||
}
|
}
|
||||||
@@ -1789,7 +1693,6 @@ func (ConcaveRight) Grad(grad, x []float64) []float64 {
|
|||||||
}
|
}
|
||||||
xSqr := x[0] * x[0]
|
xSqr := x[0] * x[0]
|
||||||
grad[0] = (xSqr - 2) / (xSqr + 2) / (xSqr + 2)
|
grad[0] = (xSqr - 2) / (xSqr + 2) / (xSqr + 2)
|
||||||
return grad
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConcaveLeft implements an univariate function that is concave to the left of
|
// ConcaveLeft implements an univariate function that is concave to the left of
|
||||||
@@ -1807,18 +1710,14 @@ func (ConcaveLeft) Func(x []float64) float64 {
|
|||||||
return math.Pow(x[0]+0.004, 4) * (x[0] - 1.996)
|
return math.Pow(x[0]+0.004, 4) * (x[0] - 1.996)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ConcaveLeft) Grad(grad, x []float64) []float64 {
|
func (ConcaveLeft) Grad(grad, x []float64) {
|
||||||
if len(x) != 1 {
|
if len(x) != 1 {
|
||||||
panic("dimension of the problem must be 1")
|
panic("dimension of the problem must be 1")
|
||||||
}
|
}
|
||||||
if grad == nil {
|
|
||||||
grad = make([]float64, len(x))
|
|
||||||
}
|
|
||||||
if len(x) != len(grad) {
|
if len(x) != len(grad) {
|
||||||
panic("incorrect size of the gradient")
|
panic("incorrect size of the gradient")
|
||||||
}
|
}
|
||||||
grad[0] = math.Pow(x[0]+0.004, 3) * (5*x[0] - 7.98)
|
grad[0] = math.Pow(x[0]+0.004, 3) * (5*x[0] - 7.98)
|
||||||
return grad
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Plassmann implements an univariate oscillatory function where the value of L
|
// Plassmann implements an univariate oscillatory function where the value of L
|
||||||
@@ -1855,13 +1754,10 @@ func (f Plassmann) Func(x []float64) float64 {
|
|||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f Plassmann) Grad(grad, x []float64) []float64 {
|
func (f Plassmann) Grad(grad, x []float64) {
|
||||||
if len(x) != 1 {
|
if len(x) != 1 {
|
||||||
panic("dimension of the problem must be 1")
|
panic("dimension of the problem must be 1")
|
||||||
}
|
}
|
||||||
if grad == nil {
|
|
||||||
grad = make([]float64, len(x))
|
|
||||||
}
|
|
||||||
if len(x) != len(grad) {
|
if len(x) != len(grad) {
|
||||||
panic("incorrect size of the gradient")
|
panic("incorrect size of the gradient")
|
||||||
}
|
}
|
||||||
@@ -1877,7 +1773,6 @@ func (f Plassmann) Grad(grad, x []float64) []float64 {
|
|||||||
default: // a > 1+b
|
default: // a > 1+b
|
||||||
grad[0]++
|
grad[0]++
|
||||||
}
|
}
|
||||||
return grad
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// YanaiOzawaKaneko is an univariate convex function where the values of Beta1
|
// YanaiOzawaKaneko is an univariate convex function where the values of Beta1
|
||||||
@@ -1908,13 +1803,10 @@ func (f YanaiOzawaKaneko) Func(x []float64) float64 {
|
|||||||
return g1*math.Sqrt((a-1)*(a-1)+b2*b2) + g2*math.Sqrt(a*a+b1*b1)
|
return g1*math.Sqrt((a-1)*(a-1)+b2*b2) + g2*math.Sqrt(a*a+b1*b1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f YanaiOzawaKaneko) Grad(grad, x []float64) []float64 {
|
func (f YanaiOzawaKaneko) Grad(grad, x []float64) {
|
||||||
if len(x) != 1 {
|
if len(x) != 1 {
|
||||||
panic("dimension of the problem must be 1")
|
panic("dimension of the problem must be 1")
|
||||||
}
|
}
|
||||||
if grad == nil {
|
|
||||||
grad = make([]float64, len(x))
|
|
||||||
}
|
|
||||||
if len(x) != len(grad) {
|
if len(x) != len(grad) {
|
||||||
panic("incorrect size of the gradient")
|
panic("incorrect size of the gradient")
|
||||||
}
|
}
|
||||||
@@ -1924,5 +1816,4 @@ func (f YanaiOzawaKaneko) Grad(grad, x []float64) []float64 {
|
|||||||
g1 := math.Sqrt(1+b1*b1) - b1
|
g1 := math.Sqrt(1+b1*b1) - b1
|
||||||
g2 := math.Sqrt(1+b2*b2) - b2
|
g2 := math.Sqrt(1+b2*b2) - b2
|
||||||
grad[0] = g1*(a-1)/math.Sqrt(b2*b2+(a-1)*(a-1)) + g2*a/math.Sqrt(b1*b1+a*a)
|
grad[0] = g1*(a-1)/math.Sqrt(b2*b2+(a-1)*(a-1)) + g2*a/math.Sqrt(b1*b1+a*a)
|
||||||
return grad
|
|
||||||
}
|
}
|
||||||
|
@@ -41,7 +41,7 @@ func TestBacktracking(t *testing.T) {
|
|||||||
|
|
||||||
type funcGrader interface {
|
type funcGrader interface {
|
||||||
Func([]float64) float64
|
Func([]float64) float64
|
||||||
Grad([]float64, []float64) []float64
|
Grad([]float64, []float64)
|
||||||
}
|
}
|
||||||
|
|
||||||
type linesearcherTest struct {
|
type linesearcherTest struct {
|
||||||
|
@@ -477,12 +477,20 @@ func evaluate(p *Problem, loc *Location, op Operation, x []float64) {
|
|||||||
loc.F = p.Func(x)
|
loc.F = p.Func(x)
|
||||||
}
|
}
|
||||||
if op&GradEvaluation != 0 {
|
if op&GradEvaluation != 0 {
|
||||||
loc.Gradient = p.Grad(loc.Gradient, x)
|
// Make sure we have a destination in which to place the gradient.
|
||||||
|
// TODO(kortschak): Consider making this a check of len(loc.Gradient) != 0
|
||||||
|
// to allow reuse of the slice.
|
||||||
|
if loc.Gradient == nil {
|
||||||
|
loc.Gradient = make([]float64, len(x))
|
||||||
|
}
|
||||||
|
p.Grad(loc.Gradient, x)
|
||||||
}
|
}
|
||||||
if op&HessEvaluation != 0 {
|
if op&HessEvaluation != 0 {
|
||||||
// Make sure we have a destination in which to place the Hessian.
|
// Make sure we have a destination in which to place the Hessian.
|
||||||
|
// TODO(kortschak): Consider making this a check of loc.Hessian.IsZero()
|
||||||
|
// to allow reuse of the matrix.
|
||||||
if loc.Hessian == nil {
|
if loc.Hessian == nil {
|
||||||
loc.Hessian = &mat.SymDense{}
|
loc.Hessian = mat.NewSymDense(len(x), nil)
|
||||||
}
|
}
|
||||||
p.Hess(loc.Hessian, x)
|
p.Hess(loc.Hessian, x)
|
||||||
}
|
}
|
||||||
|
@@ -124,13 +124,13 @@ type Problem struct {
|
|||||||
Func func(x []float64) float64
|
Func func(x []float64) float64
|
||||||
|
|
||||||
// Grad evaluates the gradient at x and returns the result. Grad may use
|
// Grad evaluates the gradient at x and returns the result. Grad may use
|
||||||
// (and return) the provided slice if it is non-nil, or must allocate a new
|
// the provided slice which will be the same length as x. Grad must not
|
||||||
// slice otherwise. Grad must not modify x.
|
// modify x.
|
||||||
Grad func(grad []float64, x []float64) []float64
|
Grad func(grad, x []float64)
|
||||||
|
|
||||||
// Hess evaluates the Hessian at x and stores the result in-place in hess.
|
// Hess evaluates the Hessian at x and stores the result in-place in hess.
|
||||||
// Hess must not modify x. Hess must use the provided mat.SymDense, and
|
// Hess must not modify x. Hess may use the provided mat.SymDense which
|
||||||
// must resize it if it is zero-sized.
|
// will have dimensions matching the length of x.
|
||||||
Hess func(hess *mat.SymDense, x []float64)
|
Hess func(hess *mat.SymDense, x []float64)
|
||||||
|
|
||||||
// Status reports the status of the objective function being optimized and any
|
// Status reports the status of the objective function being optimized and any
|
||||||
|
Reference in New Issue
Block a user