func (gp *gpConvexProg) F1(x *matrix.FloatMatrix) (f, Df *matrix.FloatMatrix, err error) { f = nil Df = nil err = nil f = matrix.FloatZeros(gp.mnl+1, 1) Df = matrix.FloatZeros(gp.mnl+1, gp.n) y := gp.g.Copy() blas.GemvFloat(gp.F, x, y, 1.0, 1.0) for i, s := range gp.ind { start := s[0] stop := s[1] // yi := exp(yi) = exp(Fi*x+gi) ymax := maxvec(y.FloatArray()[start:stop]) // ynew = exp(y[start:stop] - ymax) ynew := matrix.Exp(matrix.FloatVector(y.FloatArray()[start:stop]).Add(-ymax)) y.SetIndexesFromArray(ynew.FloatArray(), matrix.Indexes(start, stop)...) // fi = log sum yi = log sum exp(Fi*x+gi) ysum := blas.AsumFloat(y, &la.IOpt{"n", stop - start}, &la.IOpt{"offset", start}) f.SetIndex(i, ymax+math.Log(ysum)) blas.ScalFloat(y, 1.0/ysum, &la.IOpt{"n", stop - start}, &la.IOpt{"offset", start}) blas.GemvFloat(gp.F, y, Df, 1.0, 0.0, la.OptTrans, &la.IOpt{"m", stop - start}, &la.IOpt{"incy", gp.mnl + 1}, &la.IOpt{"offseta", start}, &la.IOpt{"offsetx", start}, &la.IOpt{"offsety", i}) } return }
func main() { flag.Parse() aflr := 1000.0 awall := 100.0 alpha := 0.5 beta := 2.0 gamma := 0.5 delta := 2.0 fdata := [][]float64{ []float64{-1.0, 1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 0.0}, []float64{-1.0, 1.0, 0.0, 1.0, 1.0, -1.0, 1.0, -1.0}, []float64{-1.0, 0.0, 1.0, 1.0, 0.0, 0.0, -1.0, 1.0}} gdata := []float64{1.0, 2.0 / awall, 2.0 / awall, 1.0 / aflr, alpha, 1.0 / beta, gamma, 1.0 / delta} g := matrix.FloatNew(8, 1, gdata).Log() F := matrix.FloatMatrixFromTable(fdata) K := []int{1, 2, 1, 1, 1, 1, 1} var solopts cvx.SolverOptions solopts.MaxIter = 40 if maxIter > 0 { solopts.MaxIter = maxIter } if len(spPath) > 0 { checkpnt.Reset(spPath) checkpnt.Activate() checkpnt.Verbose(spVerbose) checkpnt.Format("%.7f") } solopts.ShowProgress = true if maxIter > 0 { solopts.MaxIter = maxIter } if len(solver) > 0 { solopts.KKTSolverName = solver } sol, err := cvx.Gp(K, F, g, nil, nil, nil, nil, &solopts) if sol != nil && sol.Status == cvx.Optimal { x := sol.Result.At("x")[0] r := matrix.Exp(x) h := r.GetIndex(0) w := r.GetIndex(1) d := r.GetIndex(2) fmt.Printf("x=\n%v\n", x.ToString("%.9f")) fmt.Printf("\n h = %f, w = %f, d = %f.\n", h, w, d) check(x) } else { fmt.Printf("status: %v\n", err) } }
// The small GP of section 9.3 (Geometric programming). func TestGp(t *testing.T) { xref := []float64{1.06032641296944741, 1.75347359157296845, 2.44603683900611868} aflr := 1000.0 awall := 100.0 alpha := 0.5 beta := 2.0 gamma := 0.5 delta := 2.0 fdata := [][]float64{ []float64{-1.0, 1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 0.0}, []float64{-1.0, 1.0, 0.0, 1.0, 1.0, -1.0, 1.0, -1.0}, []float64{-1.0, 0.0, 1.0, 1.0, 0.0, 0.0, -1.0, 1.0}} gdata := []float64{1.0, 2.0 / awall, 2.0 / awall, 1.0 / aflr, alpha, 1.0 / beta, gamma, 1.0 / delta} g := matrix.FloatNew(8, 1, gdata).Log() F := matrix.FloatMatrixFromTable(fdata) K := []int{1, 2, 1, 1, 1, 1, 1} var solopts SolverOptions solopts.MaxIter = 40 solopts.ShowProgress = false solopts.KKTSolverName = "ldl" sol, err := Gp(K, F, g, nil, nil, nil, nil, &solopts) if sol != nil && sol.Status == Optimal { x := sol.Result.At("x")[0] r := matrix.Exp(x) h := r.GetIndex(0) w := r.GetIndex(1) d := r.GetIndex(2) t.Logf("x=\n%v\n", x.ToString("%.9f")) t.Logf("h = %f, w = %f, d = %f.\n", h, w, d) xe, _ := nrmError(matrix.FloatVector(xref), x) if xe > TOL { t.Logf("x differs [%.3e] from exepted too much.", xe) t.Fail() } } else { t.Logf("status: %v\n", err) t.Fail() } }
func (gp *gpConvexProg) F2(x, z *matrix.FloatMatrix) (f, Df, H *matrix.FloatMatrix, err error) { err = nil f = matrix.FloatZeros(gp.mnl+1, 1) Df = matrix.FloatZeros(gp.mnl+1, gp.n) H = matrix.FloatZeros(gp.n, gp.n) y := gp.g.Copy() Fsc := matrix.FloatZeros(gp.maxK, gp.n) blas.GemvFloat(gp.F, x, y, 1.0, 1.0) //fmt.Printf("y=\n%v\n", y.ToString("%.3f")) for i, s := range gp.ind { start := s[0] stop := s[1] // yi := exp(yi) = exp(Fi*x+gi) ymax := maxvec(y.FloatArray()[start:stop]) ynew := matrix.Exp(matrix.FloatVector(y.FloatArray()[start:stop]).Add(-ymax)) y.SetIndexesFromArray(ynew.FloatArray(), matrix.Indexes(start, stop)...) // fi = log sum yi = log sum exp(Fi*x+gi) ysum := blas.AsumFloat(y, &la.IOpt{"n", stop - start}, &la.IOpt{"offset", start}) f.SetIndex(i, ymax+math.Log(ysum)) blas.ScalFloat(y, 1.0/ysum, &la.IOpt{"n", stop - start}, &la.IOpt{"offset", start}) blas.GemvFloat(gp.F, y, Df, 1.0, 0.0, la.OptTrans, &la.IOpt{"m", stop - start}, &la.IOpt{"incy", gp.mnl + 1}, &la.IOpt{"offseta", start}, &la.IOpt{"offsetx", start}, &la.IOpt{"offsety", i}) Fsc.SetSubMatrix(0, 0, gp.F.GetSubMatrix(start, 0, stop-start)) for k := start; k < stop; k++ { blas.AxpyFloat(Df, Fsc, -1.0, &la.IOpt{"n", gp.n}, &la.IOpt{"incx", gp.mnl + 1}, &la.IOpt{"incy", Fsc.Rows()}, &la.IOpt{"offsetx", i}, &la.IOpt{"offsety", k - start}) blas.ScalFloat(Fsc, math.Sqrt(y.GetIndex(k)), &la.IOpt{"inc", Fsc.Rows()}, &la.IOpt{"offset", k - start}) } // H += z[i]*Hi = z[i] *Fisc' * Fisc blas.SyrkFloat(Fsc, H, z.GetIndex(i), 1.0, la.OptTrans, &la.IOpt{"k", stop - start}) } return }
func main() { m := 6 Vdata := [][]float64{ []float64{1.0, -1.0, -2.0, -2.0, 0.0, 1.5, 1.0}, []float64{1.0, 2.0, 1.0, -1.0, -2.0, -1.0, 1.0}} V := matrix.FloatMatrixFromTable(Vdata, matrix.RowOrder) // V[1, :m] - V[1,1:] a0 := matrix.Minus(V.GetSubMatrix(1, 0, 1, m), V.GetSubMatrix(1, 1, 1)) // V[0, :m] - V[0,1:] a1 := matrix.Minus(V.GetSubMatrix(0, 0, 1, m), V.GetSubMatrix(0, 1, 1)) A0, _ := matrix.FloatMatrixStacked(matrix.StackDown, a0.Scale(-1.0), a1) A0 = A0.Transpose() b0 := matrix.Mul(A0, V.GetSubMatrix(0, 0, 2, m).Transpose()) b0 = matrix.Times(b0, matrix.FloatWithValue(2, 1, 1.0)) A := make([]*matrix.FloatMatrix, 0) b := make([]*matrix.FloatMatrix, 0) A = append(A, A0) b = append(b, b0) // List of symbols C := make([]*matrix.FloatMatrix, 0) C = append(C, matrix.FloatZeros(2, 1)) var row *matrix.FloatMatrix = nil for k := 0; k < m; k++ { row = A0.GetRow(k, row) nrm := blas.Nrm2Float(row) row.Scale(2.0 * b0.GetIndex(k) / (nrm * nrm)) C = append(C, row.Transpose()) } // Voronoi set around C[1] A1 := matrix.FloatZeros(3, 2) A1.SetSubMatrix(0, 0, A0.GetSubMatrix(0, 0, 1).Scale(-1.0)) A1.SetSubMatrix(1, 0, matrix.Minus(C[m], C[1]).Transpose()) A1.SetSubMatrix(2, 0, matrix.Minus(C[2], C[1]).Transpose()) b1 := matrix.FloatZeros(3, 1) b1.SetIndex(0, -b0.GetIndex(0)) v := matrix.Times(A1.GetRow(1, nil), matrix.Plus(C[m], C[1])).Float() * 0.5 b1.SetIndex(1, v) v = matrix.Times(A1.GetRow(2, nil), matrix.Plus(C[2], C[1])).Float() * 0.5 b1.SetIndex(2, v) A = append(A, A1) b = append(b, b1) // Voronoi set around C[2] ... C[5] for k := 2; k < 6; k++ { A1 = matrix.FloatZeros(3, 2) A1.SetSubMatrix(0, 0, A0.GetSubMatrix(k-1, 0, 1).Scale(-1.0)) A1.SetSubMatrix(1, 0, matrix.Minus(C[k-1], C[k]).Transpose()) A1.SetSubMatrix(2, 0, matrix.Minus(C[k+1], C[k]).Transpose()) b1 = matrix.FloatZeros(3, 1) b1.SetIndex(0, -b0.GetIndex(k-1)) v := matrix.Times(A1.GetRow(1, nil), matrix.Plus(C[k-1], C[k])).Float() * 0.5 b1.SetIndex(1, v) v = matrix.Times(A1.GetRow(2, nil), matrix.Plus(C[k+1], C[k])).Float() * 0.5 b1.SetIndex(2, v) A = append(A, A1) b = append(b, b1) } // Voronoi set around C[6] A1 = matrix.FloatZeros(3, 2) A1.SetSubMatrix(0, 0, A0.GetSubMatrix(5, 0, 1).Scale(-1.0)) A1.SetSubMatrix(1, 0, matrix.Minus(C[1], C[6]).Transpose()) A1.SetSubMatrix(2, 0, matrix.Minus(C[5], C[6]).Transpose()) b1 = matrix.FloatZeros(3, 1) b1.SetIndex(0, -b0.GetIndex(5)) v = matrix.Times(A1.GetRow(1, nil), matrix.Plus(C[1], C[6])).Float() * 0.5 b1.SetIndex(1, v) v = matrix.Times(A1.GetRow(2, nil), matrix.Plus(C[5], C[6])).Float() * 0.5 b1.SetIndex(2, v) A = append(A, A1) b = append(b, b1) P := matrix.FloatIdentity(2) q := matrix.FloatZeros(2, 1) solopts := &cvx.SolverOptions{ShowProgress: false, MaxIter: 30} ovals := make([]float64, 0) for k := 1; k < 7; k++ { sol, err := cvx.Qp(P, q, A[k], b[k], nil, nil, solopts, nil) _ = err x := sol.Result.At("x")[0] ovals = append(ovals, math.Pow(blas.Nrm2Float(x), 2.0)) } optvals := matrix.FloatVector(ovals) //fmt.Printf("optvals=\n%v\n", optvals) rangeFunc := func(n int) []float64 { r := make([]float64, 0) for i := 0; i < n; i++ { r = append(r, float64(i)) } return r } nopts := 200 sigmas := matrix.FloatVector(rangeFunc(nopts)) sigmas.Scale((0.5 - 0.2) / float64(nopts)).Add(0.2) bndsVal := func(sigma float64) float64 { // 1.0 - sum(exp( -optvals/(2*sigma**2))) return 1.0 - matrix.Exp(matrix.Scale(optvals, -1.0/(2*sigma*sigma))).Sum() } bnds := matrix.FloatZeros(sigmas.NumElements(), 1) for j, v := range sigmas.FloatArray() { bnds.SetIndex(j, bndsVal(v)) } plotData("plot.png", sigmas.FloatArray(), bnds.FloatArray()) }