// Copyright ©2014 The gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package optimize

import "math"

const (
	defaultBisectionCurvature = 0.9
)

// Bisection is a Linesearcher that uses a bisection to find a point that
// satisfies the strong Wolfe conditions with the given curvature factor and
// a decrease factor of zero.
type Bisection struct {
	// CurvatureFactor is the constant factor in the curvature condition.
	// Smaller values result in a more exact line search.
	// A set value must be in the interval (0, 1), otherwise Init will panic.
	// If it is zero, it will be defaulted to 0.9.
	CurvatureFactor float64

	minStep  float64
	maxStep  float64
	currStep float64

	initF float64
	minF  float64
	maxF  float64
	lastF float64

	initGrad float64

	lastOp Operation
}

func (b *Bisection) Init(f, g float64, step float64) Operation {
	if step <= 0 {
		panic("bisection: bad step size")
	}
	if g >= 0 {
		panic("bisection: initial derivative is non-negative")
	}

	if b.CurvatureFactor == 0 {
		b.CurvatureFactor = defaultBisectionCurvature
	}
	if b.CurvatureFactor <= 0 || b.CurvatureFactor >= 1 {
		panic("bisection: CurvatureFactor not between 0 and 1")
	}

	b.minStep = 0
	b.maxStep = math.Inf(1)
	b.currStep = step

	b.initF = f
	b.minF = f
	b.maxF = math.NaN()

	b.initGrad = g

	// Only evaluate the gradient when necessary.
	b.lastOp = FuncEvaluation
	return b.lastOp
}

func (b *Bisection) Iterate(f, g float64) (Operation, float64, error) {
	if b.lastOp != FuncEvaluation && b.lastOp != GradEvaluation {
		panic("bisection: Init has not been called")
	}
	minF := b.initF
	if b.maxF < minF {
		minF = b.maxF
	}
	if b.minF < minF {
		minF = b.minF
	}
	if b.lastOp == FuncEvaluation {
		// See if the function value is good enough to make progress. If it is,
		// evaluate the gradient. If not, set it to the upper bound if the bound
		// has not yet been found, otherwise iterate toward the minimum location.
		if f <= minF {
			b.lastF = f
			b.lastOp = GradEvaluation
			return b.lastOp, b.currStep, nil
		}
		if math.IsInf(b.maxStep, 1) {
			b.maxStep = b.currStep
			b.maxF = f
			return b.nextStep((b.minStep + b.maxStep) / 2)
		}
		if b.minF <= b.maxF {
			b.maxStep = b.currStep
			b.maxF = f
		} else {
			b.minStep = b.currStep
			b.minF = f
		}
		return b.nextStep((b.minStep + b.maxStep) / 2)
	}
	f = b.lastF
	// The function value was lower. Check if this location is sufficient to
	// converge the linesearch, otherwise iterate.
	if StrongWolfeConditionsMet(f, g, minF, b.initGrad, b.currStep, 0, b.CurvatureFactor) {
		b.lastOp = MajorIteration
		return b.lastOp, b.currStep, nil
	}
	if math.IsInf(b.maxStep, 1) {
		// The function value is lower. If the gradient is positive, an upper bound
		// of the minimum been found. If the gradient is negative, search farther
		// in that direction.
		if g > 0 {
			b.maxStep = b.currStep
			b.maxF = f
			return b.nextStep((b.minStep + b.maxStep) / 2)
		}
		b.minStep = b.currStep
		b.minF = f
		return b.nextStep(b.currStep * 2)
	}
	// The interval has been bounded, and we have found a new lowest value. Use
	// the gradient to decide which direction.
	if g < 0 {
		b.minStep = b.currStep
		b.minF = f
	} else {
		b.maxStep = b.currStep
		b.maxF = f
	}
	return b.nextStep((b.minStep + b.maxStep) / 2)
}

// nextStep checks if the new step is equal to the old step.
// This can happen if min and max are the same, or if the step size is infinity,
// both of which indicate the minimization must stop. If the steps are different,
// it sets the new step size and returns the evaluation type and the step. If the steps
// are the same, it returns an error.
func (b *Bisection) nextStep(step float64) (Operation, float64, error) {
	if b.currStep == step {
		b.lastOp = NoOperation
		return b.lastOp, b.currStep, ErrLinesearcherFailure
	}
	b.currStep = step
	b.lastOp = FuncEvaluation
	return b.lastOp, b.currStep, nil
}
