Exemplo n.º 1
0
func (g *gradientIterator) updateCaches() {
	// This function computes and uses various pieces
	// of the quadratic form 1/2*c'*A*c - b'*c.

	columnMat := &linalg.Matrix{
		Rows: g.matrix.Cols,
		Cols: 1,
		Data: g.solution,
	}

	// Compute A*c.
	columnProduct := g.matrix.Mul(columnMat)

	// Compute c'*A*c.
	quadValue := kahan.NewSummer64()
	for i, x := range g.solution {
		quadValue.Add(x * columnProduct.Data[i])
	}

	// Compute b'*c
	linearValue := kahan.NewSummer64()
	for _, x := range g.solution {
		linearValue.Add(x)
	}

	g.quadraticCache = quadValue.Sum()*0.5 - linearValue.Sum()

	// Compute A*c - b.
	for i, x := range columnProduct.Data {
		columnProduct.Data[i] = x - 1
	}
	g.gradientCache = columnProduct.Data
}
Exemplo n.º 2
0
// ProjectOutComp projects the active constraints
// out of a vector and returns the i-th component
// of the result, without modifying the original
// vector.
func (a *activeSet) ProjectOutComp(d linalg.Vector, comp int) float64 {
	if a.Constraints[comp] != 0 {
		return 0
	}

	signVec := a.SignVec

	var signDotSign int
	signDotD := kahan.NewSummer64()

	for i, x := range a.Constraints {
		if x == 0 {
			signDotSign++
			signDotD.Add(d[i] * signVec[i])
		}
	}

	projAmount := signDotD.Sum() / float64(signDotSign)
	return d[comp] - projAmount*signVec[comp]
}
Exemplo n.º 3
0
func (g *gradientIterator) optimalStep(d linalg.Vector) float64 {
	// The optimal step size is (d'*b - c'*A*d)/(d'*A*d)
	// where d is the direction, A is the matrix, x is
	// the current approximate solution, and b is all 1's.

	dMat := &linalg.Matrix{
		Rows: len(d),
		Cols: 1,
		Data: d,
	}
	ad := linalg.Vector(g.matrix.Mul(dMat).Data)

	summer := kahan.NewSummer64()
	for _, x := range d {
		summer.Add(x)
	}

	numerator := summer.Sum() - g.solution.Dot(ad)
	denominator := d.Dot(ad)

	return numerator / denominator
}
Exemplo n.º 4
0
// ProjectOut projects the active constraints
// out of a gradient vector (in place).
func (a *activeSet) ProjectOut(d linalg.Vector) {
	signVec := a.SignVec

	var signDotSign int
	signDotD := kahan.NewSummer64()

	for i, x := range a.Constraints {
		if x != 0 {
			d[i] = 0
		} else {
			signDotSign++
			signDotD.Add(d[i] * signVec[i])
		}
	}

	projAmount := signDotD.Sum() / float64(signDotSign)

	for i, x := range a.Constraints {
		if x == 0 {
			d[i] -= projAmount * signVec[i]
		}
	}
}