func main() { flag.Parse() gdata0 := [][]float64{ []float64{12., 13., 12.}, []float64{6., -3., -12.}, []float64{-5., -5., 6.}} gdata1 := [][]float64{ []float64{3., 3., -1., 1.}, []float64{-6., -6., -9., 19.}, []float64{10., -2., -2., -3.}} c := matrix.FloatVector([]float64{-2.0, 1.0, 5.0}) g0 := matrix.FloatMatrixFromTable(gdata0, matrix.ColumnOrder) g1 := matrix.FloatMatrixFromTable(gdata1, matrix.ColumnOrder) Ghq := sets.FloatSetNew("Gq", "hq") Ghq.Append("Gq", g0, g1) h0 := matrix.FloatVector([]float64{-12.0, -3.0, -2.0}) h1 := matrix.FloatVector([]float64{27.0, 0.0, 3.0, -42.0}) Ghq.Append("hq", h0, h1) var Gl, hl, A, b *matrix.FloatMatrix = nil, nil, nil, nil var solopts cvx.SolverOptions solopts.MaxIter = 30 solopts.ShowProgress = true if maxIter > -1 { solopts.MaxIter = maxIter } if len(solver) > 0 { solopts.KKTSolverName = solver } sol, err := cvx.Socp(c, Gl, hl, A, b, Ghq, &solopts, nil, nil) fmt.Printf("status: %v\n", err) if sol != nil && sol.Status == cvx.Optimal { x := sol.Result.At("x")[0] fmt.Printf("x=\n%v\n", x.ToString("%.9f")) for i, m := range sol.Result.At("sq") { fmt.Printf("sq[%d]=\n%v\n", i, m.ToString("%.9f")) } for i, m := range sol.Result.At("zq") { fmt.Printf("zq[%d]=\n%v\n", i, m.ToString("%.9f")) } sq0 := sol.Result.At("sq")[0] sq1 := sol.Result.At("sq")[1] zq0 := sol.Result.At("zq")[0] zq1 := sol.Result.At("zq")[1] check(x, sq0, sq1, zq0, zq1) } }
func main() { flag.Parse() if len(spPath) > 0 { checkpnt.Reset(spPath) checkpnt.Activate() checkpnt.Verbose(spVerbose) checkpnt.Format("%.17f") } gdata0 := [][]float64{ []float64{-7., -11., -11., 3.}, []float64{7., -18., -18., 8.}, []float64{-2., -8., -8., 1.}} gdata1 := [][]float64{ []float64{-21., -11., 0., -11., 10., 8., 0., 8., 5.}, []float64{0., 10., 16., 10., -10., -10., 16., -10., 3.}, []float64{-5., 2., -17., 2., -6., 8., -17., -7., 6.}} hdata0 := [][]float64{ []float64{33., -9.}, []float64{-9., 26.}} hdata1 := [][]float64{ []float64{14., 9., 40.}, []float64{9., 91., 10.}, []float64{40., 10., 15.}} g0 := matrix.FloatMatrixFromTable(gdata0, matrix.ColumnOrder) g1 := matrix.FloatMatrixFromTable(gdata1, matrix.ColumnOrder) Ghs := sets.FloatSetNew("Gs", "hs") Ghs.Append("Gs", g0, g1) h0 := matrix.FloatMatrixFromTable(hdata0, matrix.ColumnOrder) h1 := matrix.FloatMatrixFromTable(hdata1, matrix.ColumnOrder) Ghs.Append("hs", h0, h1) c := matrix.FloatVector([]float64{1.0, -1.0, 1.0}) var Gs, hs, A, b *matrix.FloatMatrix = nil, nil, nil, nil var solopts cvx.SolverOptions solopts.MaxIter = 30 solopts.ShowProgress = true if maxIter > -1 { solopts.MaxIter = maxIter } if len(solver) > 0 { solopts.KKTSolverName = solver } sol, err := cvx.Sdp(c, Gs, hs, A, b, Ghs, &solopts, nil, nil) if sol != nil && sol.Status == cvx.Optimal { x := sol.Result.At("x")[0] fmt.Printf("x=\n%v\n", x.ToString("%.9f")) for i, m := range sol.Result.At("zs") { fmt.Printf("zs[%d]=\n%v\n", i, m.ToString("%.9f")) } ss0 := sol.Result.At("ss")[0] ss1 := sol.Result.At("ss")[1] zs0 := sol.Result.At("zs")[0] zs1 := sol.Result.At("zs")[1] check(x, ss0, ss1, zs0, zs1) } else { fmt.Printf("status: %v\n", err) } checkpnt.Report() }
func mcsdp(w *matrix.FloatMatrix) (*Solution, error) { // // Returns solution x, z to // // (primal) minimize sum(x) // subject to w + diag(x) >= 0 // // (dual) maximize -tr(w*z) // subject to diag(z) = 1 // z >= 0. // n := w.Rows() G := &matrixFs{n} cngrnc := func(r, x *matrix.FloatMatrix, alpha float64) (err error) { // Congruence transformation // // x := alpha * r'*x*r. // // r and x are square matrices. // err = nil // tx = matrix(x, (n,n)) is copying and reshaping // scale diagonal of x by 1/2, (x is (n,n)) tx := x.Copy() matrix.Reshape(tx, n, n) tx.Diag().Scale(0.5) // a := tril(x)*r // (python: a = +r is really making a copy of r) a := r.Copy() err = blas.TrmmFloat(tx, a, 1.0, linalg.OptLeft) // x := alpha*(a*r' + r*a') err = blas.Syr2kFloat(r, a, tx, alpha, 0.0, linalg.OptTrans) // x[:] = tx[:] tx.CopyTo(x) return } Fkkt := func(W *sets.FloatMatrixSet) (KKTFunc, error) { // Solve // -diag(z) = bx // -diag(x) - inv(rti*rti') * z * inv(rti*rti') = bs // // On entry, x and z contain bx and bs. // On exit, they contain the solution, with z scaled // (inv(rti)'*z*inv(rti) is returned instead of z). // // We first solve // // ((rti*rti') .* (rti*rti')) * x = bx - diag(t*bs*t) // // and take z = -rti' * (diag(x) + bs) * rti. var err error = nil rti := W.At("rti")[0] // t = rti*rti' as a nonsymmetric matrix. t := matrix.FloatZeros(n, n) err = blas.GemmFloat(rti, rti, t, 1.0, 0.0, linalg.OptTransB) if err != nil { return nil, err } // Cholesky factorization of tsq = t.*t. tsq := matrix.Mul(t, t) err = lapack.Potrf(tsq) if err != nil { return nil, err } f := func(x, y, z *matrix.FloatMatrix) (err error) { // tbst := t * zs * t = t * bs * t tbst := z.Copy() matrix.Reshape(tbst, n, n) cngrnc(t, tbst, 1.0) // x := x - diag(tbst) = bx - diag(rti*rti' * bs * rti*rti') diag := tbst.Diag().Transpose() x.Minus(diag) // x := (t.*t)^{-1} * x = (t.*t)^{-1} * (bx - diag(t*bs*t)) err = lapack.Potrs(tsq, x) // z := z + diag(x) = bs + diag(x) // z, x are really column vectors here z.AddIndexes(matrix.MakeIndexSet(0, n*n, n+1), x.FloatArray()) // z := -rti' * z * rti = -rti' * (diag(x) + bs) * rti cngrnc(rti, z, -1.0) return nil } return f, nil } c := matrix.FloatWithValue(n, 1, 1.0) // initial feasible x: x = 1.0 - min(lmbda(w)) lmbda := matrix.FloatZeros(n, 1) wp := w.Copy() lapack.Syevx(wp, lmbda, nil, 0.0, nil, []int{1, 1}, linalg.OptRangeInt) x0 := matrix.FloatZeros(n, 1).Add(-lmbda.GetAt(0, 0) + 1.0) s0 := w.Copy() s0.Diag().Plus(x0.Transpose()) matrix.Reshape(s0, n*n, 1) // initial feasible z is identity z0 := matrix.FloatIdentity(n) matrix.Reshape(z0, n*n, 1) dims := sets.DSetNew("l", "q", "s") dims.Set("s", []int{n}) primalstart := sets.FloatSetNew("x", "s") dualstart := sets.FloatSetNew("z") primalstart.Set("x", x0) primalstart.Set("s", s0) dualstart.Set("z", z0) var solopts SolverOptions solopts.MaxIter = 30 solopts.ShowProgress = false h := w.Copy() matrix.Reshape(h, h.NumElements(), 1) return ConeLpCustomMatrix(c, G, h, nil, nil, dims, Fkkt, &solopts, primalstart, dualstart) }