func (p *acenterProg) F2(x, z *matrix.FloatMatrix) (f, Df, H *matrix.FloatMatrix, err error) { f, Df, err = p.F1(x) u := matrix.Pow(x, 2.0).Scale(-1.0).Add(1.0) z0 := z.GetIndex(0) u2 := matrix.Pow(u, 2.0) hd := matrix.Div(matrix.Add(u2, 1.0), u2).Scale(2 * z0) H = matrix.FloatDiagonal(hd.NumElements(), hd.FloatArray()...) return }
func main() { flag.Parse() m := len(udata) nvars := 2 * m u := matrix.FloatVector(udata[:m]) y := matrix.FloatVector(ydata[:m]) // minimize (1/2) * || yhat - y ||_2^2 // subject to yhat[j] >= yhat[i] + g[i]' * (u[j] - u[i]), j, i = 0,...,m-1 // // Variables yhat (m), g (m). P := matrix.FloatZeros(nvars, nvars) // set m first diagonal indexes to 1.0 //P.SetIndexes(1.0, matrix.DiagonalIndexes(P)[:m]...) P.Diag().SubMatrix(0, 0, 1, m).SetIndexes(1.0) q := matrix.FloatZeros(nvars, 1) q.SubMatrix(0, 0, y.NumElements(), 1).Plus(matrix.Scale(y, -1.0)) // m blocks (i = 0,...,m-1) of linear inequalities // // yhat[i] + g[i]' * (u[j] - u[i]) <= yhat[j], j = 0,...,m-1. G := matrix.FloatZeros(m*m, nvars) I := matrix.FloatDiagonal(m, 1.0) for i := 0; i < m; i++ { // coefficients of yhat[i] (column i) //G.Set(1.0, matrix.ColumnIndexes(G, i)[i*m:(i+1)*m]...) column(G, i).SetIndexes(1.0) // coefficients of gi[i] (column i, rows i*m ... (i+1)*m) //rows := matrix.Indexes(i*m, (i+1)*m) //G.SetAtColumnArray(m+i, rows, matrix.Add(u, -u.GetIndex(i)).FloatArray()) // coefficients of gi[i] (column i, rows i*m ... (i+1)*m) // from column m+i staring at row i*m select m rows and one column G.SubMatrix(i*m, m+i, m, 1).Plus(matrix.Add(u, -u.GetIndex(i))) // coeffients of yhat[i]) from rows i*m ... (i+1)*m, cols 0 ... m //G.SetSubMatrix(i*m, 0, matrix.Minus(G.GetSubMatrix(i*m, 0, m, m), I)) G.SubMatrix(i*m, 0, m, m).Minus(I) } h := matrix.FloatZeros(m*m, 1) var A, b *matrix.FloatMatrix = nil, nil var solopts cvx.SolverOptions solopts.ShowProgress = true solopts.KKTSolverName = solver sol, err := cvx.Qp(P, q, G, h, A, b, &solopts, nil) if err != nil { fmt.Printf("error: %v\n", err) return } if sol != nil && sol.Status != cvx.Optimal { fmt.Printf("status not optimal\n") return } x := sol.Result.At("x")[0] //yhat := matrix.FloatVector(x.FloatArray()[:m]) //g := matrix.FloatVector(x.FloatArray()[m:]) yhat := x.SubMatrix(0, 0, m, 1).Copy() g := x.SubMatrix(m, 0).Copy() rangeFunc := func(n int) []float64 { r := make([]float64, 0) for i := 0; i < n; i++ { r = append(r, float64(i)*2.2/float64(n)) } return r } ts := rangeFunc(1000) fitFunc := func(points []float64) []float64 { res := make([]float64, len(points)) for k, t := range points { res[k] = matrix.Plus(yhat, matrix.Mul(g, matrix.Scale(u, -1.0).Add(t))).Max() } return res } fs := fitFunc(ts) plotData("cvxfit.png", u.FloatArray(), y.FloatArray(), ts, fs) }