예제 #1
0
파일: gp.go 프로젝트: sguzwf/algorithm
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
}
예제 #2
0
파일: gp_test.go 프로젝트: sguzwf/algorithm
// 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()
	}
}
예제 #3
0
파일: gp.go 프로젝트: sguzwf/algorithm
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
}