Ejemplo n.º 1
0
func (m *mVariable) ShowError(dataline string) {
	refdata, err := matrix.FloatParse(dataline)
	if err != nil {
		fmt.Printf("parse error: %s", err)
		return
	}
	df := matrix.Minus(m.mtx, refdata)
	emtx, _ := matrix.FloatMatrixStacked(matrix.StackRight, m.mtx, refdata, df)
	fmt.Printf("my data | ref.data | diff \n%v\n", emtx.ToString(spformat))
}
Ejemplo n.º 2
0
func (u *epigraph) ShowError(line string) {
	lpar := strings.Index(line, "[")
	rpar := strings.LastIndex(line, "]")
	mstart := strings.Index(line, "{")
	refval, _ := matrix.FloatParse(line[mstart:rpar])
	fval, _ := strconv.ParseFloat(strings.Trim(line[lpar+1:mstart], " "), 64)
	df := matrix.Minus(u.m(), refval)
	em, _ := matrix.FloatMatrixStacked(matrix.StackRight, u.m(), refval, df)
	fmt.Printf("my data | ref.data | diff \n%v\n", em.ToString("%.4e"))
	d := u.t() - fval
	fmt.Printf("/%.4e/ | /%.4e/ | /%4e/\n", u.t(), fval, d)
}
Ejemplo n.º 3
0
// Solves a pair of primal and dual SDPs
//
//        minimize    c'*x
//        subject to  Gl*x + sl = hl
//                    mat(Gs[k]*x) + ss[k] = hs[k], k = 0, ..., N-1
//                    A*x = b
//                    sl >= 0,  ss[k] >= 0, k = 0, ..., N-1
//
//        maximize    -hl'*z - sum_k trace(hs[k]*zs[k]) - b'*y
//        subject to  Gl'*zl + sum_k Gs[k]'*vec(zs[k]) + A'*y + c = 0
//                    zl >= 0,  zs[k] >= 0, k = 0, ..., N-1.
//
// The inequalities sl >= 0 and zl >= 0 are elementwise vector
// inequalities.  The inequalities ss[k] >= 0, zs[k] >= 0 are matrix
// inequalities, i.e., the symmetric matrices ss[k] and zs[k] must be
// positive semidefinite.  mat(Gs[k]*x) is the symmetric matrix X with
// X[:] = Gs[k]*x.  For a symmetric matrix, zs[k], vec(zs[k]) is the
// vector zs[k][:].
//
func Sdp(c, Gl, hl, A, b *matrix.FloatMatrix, Ghs *sets.FloatMatrixSet, solopts *SolverOptions,
	primalstart, dualstart *sets.FloatMatrixSet) (sol *Solution, err error) {
	if c == nil {
		err = errors.New("'c' must a column matrix")
		return
	}
	n := c.Rows()
	if n < 1 {
		err = errors.New("Number of variables must be at least 1")
		return
	}
	if Gl == nil {
		Gl = matrix.FloatZeros(0, n)
	}
	if Gl.Cols() != n {
		err = errors.New(fmt.Sprintf("'G' must be matrix with %d columns", n))
		return
	}
	ml := Gl.Rows()
	if hl == nil {
		hl = matrix.FloatZeros(0, 1)
	}
	if !hl.SizeMatch(ml, 1) {
		err = errors.New(fmt.Sprintf("'hl' must be matrix of size (%d,1)", ml))
		return
	}
	Gsset := Ghs.At("Gs")
	ms := make([]int, 0)
	for i, Gs := range Gsset {
		if Gs.Cols() != n {
			err = errors.New(fmt.Sprintf("'Gs' must be list of matrices with %d columns", n))
			return
		}
		sz := int(math.Sqrt(float64(Gs.Rows())))
		if Gs.Rows() != sz*sz {
			err = errors.New(fmt.Sprintf("the squareroot of the number of rows of 'Gq[%d]' is not an integer", i))
			return
		}
		ms = append(ms, sz)
	}

	hsset := Ghs.At("hs")
	if len(Gsset) != len(hsset) {
		err = errors.New(fmt.Sprintf("'hs' must be a list of %d matrices", len(Gsset)))
		return
	}
	for i, hs := range hsset {
		if !hs.SizeMatch(ms[i], ms[i]) {
			s := fmt.Sprintf("hq[%d] has size (%d,%d). Expected size is (%d,%d)",
				i, hs.Rows(), hs.Cols(), ms[i], ms[i])
			err = errors.New(s)
			return
		}
	}
	if A == nil {
		A = matrix.FloatZeros(0, n)
	}
	if A.Cols() != n {
		err = errors.New(fmt.Sprintf("'A' must be matrix with %d columns", n))
		return
	}
	p := A.Rows()
	if b == nil {
		b = matrix.FloatZeros(0, 1)
	}
	if !b.SizeMatch(p, 1) {
		err = errors.New(fmt.Sprintf("'b' must be matrix of size (%d,1)", p))
		return
	}
	dims := sets.NewDimensionSet("l", "q", "s")
	dims.Set("l", []int{ml})
	dims.Set("s", ms)
	N := dims.Sum("l") + dims.SumSquared("s")

	// Map hs matrices to h vector
	h := matrix.FloatZeros(N, 1)
	h.SetIndexesFromArray(hl.FloatArray()[:ml], matrix.MakeIndexSet(0, ml, 1)...)
	ind := ml
	for k, hs := range hsset {
		h.SetIndexesFromArray(hs.FloatArray(), matrix.MakeIndexSet(ind, ind+ms[k]*ms[k], 1)...)
		ind += ms[k] * ms[k]
	}

	Gargs := make([]*matrix.FloatMatrix, 0)
	Gargs = append(Gargs, Gl)
	Gargs = append(Gargs, Gsset...)
	G, sizeg := matrix.FloatMatrixStacked(matrix.StackDown, Gargs...)

	var pstart, dstart *sets.FloatMatrixSet = nil, nil
	if primalstart != nil {
		pstart = sets.NewFloatSet("x", "s")
		pstart.Set("x", primalstart.At("x")[0])
		slset := primalstart.At("sl")
		margs := make([]*matrix.FloatMatrix, 0, len(slset)+1)
		margs = append(margs, primalstart.At("s")[0])
		margs = append(margs, slset...)
		sl, _ := matrix.FloatMatrixStacked(matrix.StackDown, margs...)
		pstart.Set("s", sl)
	}

	if dualstart != nil {
		dstart = sets.NewFloatSet("y", "z")
		dstart.Set("y", dualstart.At("y")[0])
		zlset := primalstart.At("zl")
		margs := make([]*matrix.FloatMatrix, 0, len(zlset)+1)
		margs = append(margs, dualstart.At("z")[0])
		margs = append(margs, zlset...)
		zl, _ := matrix.FloatMatrixStacked(matrix.StackDown, margs...)
		dstart.Set("z", zl)
	}

	//fmt.Printf("h=\n%v\n", h.ToString("%.3f"))
	//fmt.Printf("G=\n%v\n", G.ToString("%.3f"))

	sol, err = ConeLp(c, G, h, A, b, dims, solopts, pstart, dstart)
	// unpack sol.Result
	if err == nil {
		s := sol.Result.At("s")[0]
		sl := matrix.FloatVector(s.FloatArray()[:ml])
		sol.Result.Append("sl", sl)
		ind := ml
		for _, m := range ms {
			sk := matrix.FloatNew(m, m, s.FloatArray()[ind:ind+m*m])
			sol.Result.Append("ss", sk)
			ind += m * m
		}

		z := sol.Result.At("z")[0]
		zl := matrix.FloatVector(s.FloatArray()[:ml])
		sol.Result.Append("zl", zl)
		ind = ml
		for i, k := range sizeg[1:] {
			zk := matrix.FloatNew(ms[i], ms[i], z.FloatArray()[ind:ind+k])
			sol.Result.Append("zs", zk)
			ind += k
		}
	}
	sol.Result.Remove("s")
	sol.Result.Remove("z")

	return

}
Ejemplo n.º 4
0
// Solves a pair of primal and dual SOCPs
//
//     minimize    c'*x
//     subject to  Gl*x + sl = hl
//                 Gq[k]*x + sq[k] = hq[k],  k = 0, ..., N-1
//                 A*x = b
//                 sl >= 0,
//                 sq[k] >= 0, k = 0, ..., N-1
//
//     maximize   -hl'*z - sum_k hq[k]'*zq[k] - b'*y
//     subject to  Gl'*zl + sum_k Gq[k]'*zq[k] + A'*y + c = 0
//                 zl >= 0,  zq[k] >= 0, k = 0, ..., N-1.
//
// The inequalities sl >= 0 and zl >= 0 are elementwise vector
// inequalities.  The inequalities sq[k] >= 0, zq[k] >= 0 are second
// order cone inequalities, i.e., equivalent to
//
//     sq[k][0] >= || sq[k][1:] ||_2,  zq[k][0] >= || zq[k][1:] ||_2.
//
func Socp(c, Gl, hl, A, b *matrix.FloatMatrix, Ghq *sets.FloatMatrixSet, solopts *SolverOptions,
	primalstart, dualstart *sets.FloatMatrixSet) (sol *Solution, err error) {
	if c == nil {
		err = errors.New("'c' must a column matrix")
		return
	}
	n := c.Rows()
	if n < 1 {
		err = errors.New("Number of variables must be at least 1")
		return
	}
	if Gl == nil {
		Gl = matrix.FloatZeros(0, n)
	}
	if Gl.Cols() != n {
		err = errors.New(fmt.Sprintf("'G' must be matrix with %d columns", n))
		return
	}
	ml := Gl.Rows()
	if hl == nil {
		hl = matrix.FloatZeros(0, 1)
	}
	if !hl.SizeMatch(ml, 1) {
		err = errors.New(fmt.Sprintf("'hl' must be matrix of size (%d,1)", ml))
		return
	}
	Gqset := Ghq.At("Gq")
	mq := make([]int, 0)
	for i, Gq := range Gqset {
		if Gq.Cols() != n {
			err = errors.New(fmt.Sprintf("'Gq' must be list of matrices with %d columns", n))
			return
		}
		if Gq.Rows() == 0 {
			err = errors.New(fmt.Sprintf("the number of rows of 'Gq[%d]' is zero", i))
			return
		}
		mq = append(mq, Gq.Rows())
	}
	hqset := Ghq.At("hq")
	if len(Gqset) != len(hqset) {
		err = errors.New(fmt.Sprintf("'hq' must be a list of %d matrices", len(Gqset)))
		return
	}
	for i, hq := range hqset {
		if !hq.SizeMatch(Gqset[i].Rows(), 1) {
			s := fmt.Sprintf("hq[%d] has size (%d,%d). Expected size is (%d,1)",
				i, hq.Rows(), hq.Cols(), Gqset[i].Rows())
			err = errors.New(s)
			return
		}
	}
	if A == nil {
		A = matrix.FloatZeros(0, n)
	}
	if A.Cols() != n {
		err = errors.New(fmt.Sprintf("'A' must be matrix with %d columns", n))
		return
	}
	p := A.Rows()
	if b == nil {
		b = matrix.FloatZeros(0, 1)
	}
	if !b.SizeMatch(p, 1) {
		err = errors.New(fmt.Sprintf("'b' must be matrix of size (%d,1)", p))
		return
	}
	dims := sets.NewDimensionSet("l", "q", "s")
	dims.Set("l", []int{ml})
	dims.Set("q", mq)
	//N := dims.Sum("l", "q")

	hargs := make([]*matrix.FloatMatrix, 0, len(hqset)+1)
	hargs = append(hargs, hl)
	hargs = append(hargs, hqset...)
	h, indh := matrix.FloatMatrixStacked(matrix.StackDown, hargs...)

	Gargs := make([]*matrix.FloatMatrix, 0, len(Gqset)+1)
	Gargs = append(Gargs, Gl)
	Gargs = append(Gargs, Gqset...)
	G, indg := matrix.FloatMatrixStacked(matrix.StackDown, Gargs...)

	var pstart, dstart *sets.FloatMatrixSet = nil, nil
	if primalstart != nil {
		pstart = sets.NewFloatSet("x", "s")
		pstart.Set("x", primalstart.At("x")[0])
		slset := primalstart.At("sl")
		margs := make([]*matrix.FloatMatrix, 0, len(slset)+1)
		margs = append(margs, primalstart.At("s")[0])
		margs = append(margs, slset...)
		sl, _ := matrix.FloatMatrixStacked(matrix.StackDown, margs...)
		pstart.Set("s", sl)
	}

	if dualstart != nil {
		dstart = sets.NewFloatSet("y", "z")
		dstart.Set("y", dualstart.At("y")[0])
		zlset := primalstart.At("zl")
		margs := make([]*matrix.FloatMatrix, 0, len(zlset)+1)
		margs = append(margs, dualstart.At("z")[0])
		margs = append(margs, zlset...)
		zl, _ := matrix.FloatMatrixStacked(matrix.StackDown, margs...)
		dstart.Set("z", zl)
	}

	sol, err = ConeLp(c, G, h, A, b, dims, solopts, pstart, dstart)
	// unpack sol.Result
	if err == nil {
		s := sol.Result.At("s")[0]
		sl := matrix.FloatVector(s.FloatArray()[:ml])
		sol.Result.Append("sl", sl)
		ind := ml
		for _, k := range indh[1:] {
			sk := matrix.FloatVector(s.FloatArray()[ind : ind+k])
			sol.Result.Append("sq", sk)
			ind += k
		}

		z := sol.Result.At("z")[0]
		zl := matrix.FloatVector(z.FloatArray()[:ml])
		sol.Result.Append("zl", zl)
		ind = ml
		for _, k := range indg[1:] {
			zk := matrix.FloatVector(z.FloatArray()[ind : ind+k])
			sol.Result.Append("zq", zk)
			ind += k
		}
	}
	sol.Result.Remove("s")
	sol.Result.Remove("z")

	return
}
Ejemplo n.º 5
0
func (u *matrixVar) ShowError(dataline string) {
	refval, _ := matrix.FloatParse(dataline)
	em := matrix.Minus(u.val, refval)
	r, _ := matrix.FloatMatrixStacked(matrix.StackRight, u.val, refval, em)
	fmt.Printf("my data | ref.data | diff \n%v\n", r.ToString("%.4e"))
}
Ejemplo n.º 6
0
func TestConeQp(t *testing.T) {
	adata := [][]float64{
		[]float64{0.3, -0.4, -0.2, -0.4, 1.3},
		[]float64{0.6, 1.2, -1.7, 0.3, -0.3},
		[]float64{-0.3, 0.0, 0.6, -1.2, -2.0}}

	// reference values from cvxopt coneqp.py
	xref := []float64{0.72558318685981904, 0.61806264311119252, 0.30253527966423444}
	sref := []float64{
		0.72558318685981904, 0.61806264311119263,
		0.30253527966423449, 1.00000000000041678,
		-0.72558318686012169, -0.61806264311145032,
		-0.30253527966436067}
	zref := []float64{
		0.00000003332583626, 0.00000005116586239,
		0.00000009993673262, 0.56869648433154019,
		0.41264857754144563, 0.35149286573190930,
		0.17201618570052318}

	A := matrix.FloatMatrixFromTable(adata, matrix.ColumnOrder)
	b := matrix.FloatVector([]float64{1.5, 0.0, -1.2, -0.7, 0.0})

	_, n := A.Size()
	N := n + 1 + n

	h := matrix.FloatZeros(N, 1)
	h.SetIndex(n, 1.0)

	I0 := matrix.FloatDiagonal(n, -1.0)
	I1 := matrix.FloatIdentity(n)
	G, _ := matrix.FloatMatrixStacked(matrix.StackDown, I0, matrix.FloatZeros(1, n), I1)

	At := A.Transpose()
	P := matrix.Times(At, A)
	q := matrix.Times(At, b).Scale(-1.0)

	dims := sets.DSetNew("l", "q", "s")
	dims.Set("l", []int{n})
	dims.Set("q", []int{n + 1})

	var solopts SolverOptions
	solopts.MaxIter = 10
	solopts.ShowProgress = false
	sol, err := ConeQp(P, q, G, h, nil, nil, dims, &solopts, nil)
	if err == nil {
		fail := false
		x := sol.Result.At("x")[0]
		s := sol.Result.At("s")[0]
		z := sol.Result.At("z")[0]
		t.Logf("Optimal\n")
		t.Logf("x=\n%v\n", x.ToString("%.9f"))
		t.Logf("s=\n%v\n", s.ToString("%.9f"))
		t.Logf("z=\n%v\n", z.ToString("%.9f"))
		xe, _ := nrmError(matrix.FloatVector(xref), x)
		if xe > TOL {
			t.Logf("x differs [%.3e] from exepted too much.", xe)
			fail = true
		}
		se, _ := nrmError(matrix.FloatVector(sref), s)
		if se > TOL {
			t.Logf("s differs [%.3e] from exepted too much.", se)
			fail = true
		}
		ze, _ := nrmError(matrix.FloatVector(zref), z)
		if ze > TOL {
			t.Logf("z differs [%.3e] from exepted too much.", ze)
			fail = true
		}
		if fail {
			t.Fail()
		}
	}

}