示例#1
0
// Step adds d.Scale(amount) to coeffs.
// If any of the entries in coeffs hits a
// constraint, then the step is stopped
// short and true is returned to indicate
// that a new constraint has been added.
//
// This may modify d in any way it pleases.
func (a *activeSet) Step(coeffs, d linalg.Vector, amount float64) bool {
	var maxStep, minStep float64
	var maxIdx, minIdx int
	isFirst := true
	for i, x := range d {
		if x == 0 {
			continue
		}
		coeff := coeffs[i]
		maxValue := (a.MaxCoeff - coeff) / x
		minValue := -coeff / x
		if x < 0 {
			maxValue, minValue = minValue, maxValue
		}
		if isFirst {
			isFirst = false
			minStep, maxStep = minValue, maxValue
			maxIdx, minIdx = i, i
		} else {
			if minValue > minStep {
				minStep = minValue
				minIdx = i
			}
			if maxValue < maxStep {
				maxStep = maxValue
				maxIdx = i
			}
		}
	}

	if isFirst {
		return false
	}

	if amount < minStep {
		coeffs.Add(d.Scale(minStep))
		a.addConstraint(coeffs, minIdx)
	} else if amount > maxStep {
		coeffs.Add(d.Scale(maxStep))
		a.addConstraint(coeffs, maxIdx)
	} else {
		coeffs.Add(d.Scale(amount))
		return false
	}
	return true
}