Beispiel #1
0
func Factors(X, Wo, Ho *sparse.Sparse, tolerance float64, iterations int, limit time.Duration) (W, H *sparse.Sparse, ok bool) {
	W = Wo
	H = Ho
	to := time.Now()

	hT := H.T()
	wT := W.T()

	gW := W.Dot(H.Dot(hT)).Sub(X.Dot(hT))
	gH := wT.Dot(W).Dot(H).Sub(wT.Dot(X))

	gradient := gW.Stack(gH.T()).Norm(matrix.Fro)
	toleranceW := math.Max(0.001, tolerance) * gradient
	toleranceH := toleranceW

	wFilter := func(r, c int, v float64) bool {
		w := W.At(r, c)
		return v < 0 || w > 0 // wFilter called with gW as receiver, so v, _ = gW.At(r, c)
	}
	hFilter := func(r, c int, v float64) bool {
		h := H.At(r, c)
		return v < 0 || h > 0 // hFilter called with gH as receiver, so v, _ = gH.At(r, c)
	}

	var (
		subOk  bool
		iW, iH int
	)
	ok = true

	for i := 1; i < iterations; i++ {
		projection := sparse.Elements(gW.Filter(wFilter), (gH.Filter(hFilter))).Norm(matrix.Fro)
		if projection < tolerance*gradient || time.Now().Sub(to) > limit {
			break
		}

		if W, gW, iW, subOk = subproblem(X.T(), H.T(), W.T(), toleranceW, 1000); iW == 1 {
			toleranceW *= 0.1
		}
		ok = ok && subOk

		W = W.T()
		gW = gW.T()

		if H, gH, iH, subOk = subproblem(X, W, H, toleranceH, 1000); iH == 1 {
			toleranceH *= 0.1
		}
		ok = ok && subOk
	}

	return
}