コード例 #1
0
ファイル: mesh.go プロジェクト: gidden/cloudlus
// Nearest returns the nearest grid point to p by rounding each dimensional
// position to the nearest grid point.  If the mesh basis is not the identity
// matrix, then p is transformed to the mesh basis before rounding and then
// retransformed back.
func (m *InfMesh) Nearest(p []float64) []float64 {
	if m.StepSize == 0 {
		return append([]float64{}, p...)
	} else if l := len(m.Center); l != 0 && l != len(p) {
		panic(fmt.Sprintf("origin len %v incompatible with point len %v", l, len(p)))
	}

	// set up origin and inverter matrix if necessary
	if len(m.Center) == 0 {
		m.Center = make([]float64, len(p))
	}
	if m.Basis != nil && m.inverter == nil {
		var err error
		m.inverter, err = mat64.Inverse(m.Basis)
		if err != nil {
			panic("basis inversion failed: " + err.Error())
		}
	}

	// translate p based on origin and transform to new vector space
	newp := make([]float64, len(p))
	for i := range newp {
		newp[i] = p[i] - m.Center[i]
	}
	v := mat64.NewDense(len(m.Center), 1, newp)
	rotv := v
	if m.inverter != nil {
		rotv.Mul(m.inverter, v)
	}

	// calculate nearest point
	nearest := mat64.NewDense(len(p), 1, nil)
	for i := range m.Center {
		n, rem := math.Modf(rotv.At(i, 0) / m.StepSize)
		if rem/m.StepSize > 0.5 {
			n++
		}
		nearest.Set(i, 0, float64(n)*m.StepSize)
	}

	// transform back to standard space
	if m.Basis != nil {
		nearest.Mul(m.Basis, nearest)
	}
	nv := nearest.Col(nil, 0)
	for i := range nv {
		nv[i] += m.Center[i]
	}
	return nv
}
コード例 #2
0
ファイル: optim.go プロジェクト: gidden/cloudlus
// StackConstrBoxed converts the equations:
//
//     lb <= Ix <= ub
//     and
//     low <= Ax <= up
//
// into a single equation of the form:
//
//     Ax <= b
func StackConstrBoxed(lb, ub []float64, low, A, up *mat64.Dense) (stackA, b *mat64.Dense, ranges []float64) {
	lbm := mat64.NewDense(len(lb), 1, lb)
	ubm := mat64.NewDense(len(ub), 1, ub)

	stacklow := &mat64.Dense{}
	stacklow.Stack(low, lbm)

	stackup := &mat64.Dense{}
	stackup.Stack(up, ubm)

	boxA := mat64.NewDense(len(lb), len(lb), nil)
	for i := 0; i < len(lb); i++ {
		boxA.Set(i, i, 1)
	}

	stacked := &mat64.Dense{}
	stacked.Stack(A, boxA)
	return StackConstr(stacklow, stacked, stackup)
}
コード例 #3
0
ファイル: optim.go プロジェクト: gidden/cloudlus
func (o *ObjectivePenalty) Objective(v []float64) (float64, error) {
	o.init()
	val, err := o.Obj.Objective(v)

	if o.Weight == 0 {
		return val, err
	}

	ax := &mat64.Dense{}
	x := mat64.NewDense(len(v), 1, v)
	ax.Mul(o.a, x)

	m, _ := ax.Dims()

	penalty := 0.0
	for i := 0; i < m; i++ {
		if diff := ax.At(i, 0) - o.b.At(i, 0); diff > 0 {
			// maybe use "*=" for compounding penalty buildup
			penalty += diff / o.ranges[i] * o.Weight
		}
	}

	return val * (1 + penalty), err
}
コード例 #4
0
ファイル: optim.go プロジェクト: gidden/cloudlus
func (p *Point) Matrix() *mat64.Dense { return mat64.NewDense(p.Len(), 1, p.Pos) }
コード例 #5
0
ファイル: mesh_test.go プロジェクト: gidden/cloudlus
		Step:   1.3,
		Basis:  nil,
		Origin: []float64{0, 0},
		Point:  []float64{1.0, 1.0},
		Exp:    []float64{1.3, 1.3},
	},
	Problem{
		Step:   1.3,
		Basis:  nil,
		Origin: []float64{0, 0},
		Point:  []float64{1.9, 1.9},
		Exp:    []float64{1.3, 1.3},
	},
	Problem{ // 45 deg clockwise rotation of the identity basis
		Step:   1.0,
		Basis:  mat64.NewDense(2, 2, []float64{1 / math.Sqrt(2), 1 / math.Sqrt(2), -1 / math.Sqrt(2), 1 / math.Sqrt(2)}),
		Origin: []float64{0, 0},
		Point:  []float64{1.0, 1.0},
		Exp:    []float64{1 / math.Sqrt(2), 1 / math.Sqrt(2)},
	},
	Problem{ // non-zero origin
		Step:   1.0,
		Basis:  nil,
		Origin: []float64{0.2, 0.3},
		Point:  []float64{1.6, 2.1},
		Exp:    []float64{1.2, 2.3},
	},
}

func TestSimple(t *testing.T) {
	maxulps := uint64(1)