func Normalizer(in <-chan *matrix.Matrix, min, r *matrix.Matrix) <-chan *matrix.Matrix {
	out := make(chan *matrix.Matrix)

	rOver := r.Copy()
	rOver.Apply(oneOver)

	var v *matrix.Matrix

	go func() {
		for vec := range in {
			v, _ = vec.Sub(min)
			out <- v.EWProd(rOver)
		}
		close(out)
	}()

	return out
}
Beispiel #2
0
func Fmincg(f CostGradientFunc, theta *matrix.Matrix, maxIter int, verbose bool) *matrix.Matrix {
	length := maxIter

	M := 0.0
	i := 0
	red := 1.0
	lsFailed := 0

	f1, df1 := f(theta)
	if length < 0 {
		i += 1
	}

	s := df1.Scale(-1.0)
	d1 := s.Scale(-1.0).Dot(s)
	z1 := red / (1 - d1)

	for float64(i) < math.Abs(float64(length)) {
		if length > 0 {
			i += 1
		}

		theta0 := theta.Copy()
		f0 := f1
		df0 := df1

		theta, _ = theta.Add(s.Scale(z1))
		f2, df2 := f(theta)
		if length < 0 {
			i += 1
		}

		d2 := df2.Dot(s)

		f3 := f1
		d3 := d1
		z3 := -1.0 * z1

		if length > 0 {
			M = _MAX
		} else {
			M = math.Min(_MAX, -1.0*float64(length-i))
		}

		success := 0
		limit := -1.0

		var A float64
		var B float64
		var z2 float64

		for {
			for ((f2 > f1+z1*_RHO*d1) || (d2 > -1.0*_SIG*d1)) && (M > 0) {
				limit = z1

				if f2 > f1 {
					z2 = z3 - (0.5*d3*z3*z3)/(d3*z3+f2-f3)
				} else {
					A = 6*(f2-f3)/z3 + 3*(d2+d3)
					B = 3*(f3-f2) - z3*(d3+2*d2)
					z2 = (math.Sqrt(B*B-A*d2*z3*z3) - B) / A
				}

				if math.IsNaN(z2) || math.IsInf(z2, 0) {
					z2 = z3 / 2
				}

				z2 = math.Max(math.Min(z2, _INT*z3), (1-_INT)*z3)
				z1 = z1 + z2

				theta, _ = theta.Add(s.Scale(z2))
				f2, df2 = f(theta)

				M -= 1
				if length < 0 {
					i += 1
				}

				d2 = df2.Dot(s)
				z3 = z3 - z2
			}

			if f2 > f1+z1*_RHO*d1 || d2 > -1.0*_SIG*d1 {
				break // failure
			} else if d2 > _SIG*d1 {
				success = 1
				break // success!
			} else if M == 0 {
				break //failure
			}

			A = 6*(f2-f3)/z3 + 3*(d2+d3)
			B = 3*(f3-f2) - z3*(d3+2*d2)

			z2 = -1.0 * d2 * z3 * z3 / (B + math.Sqrt(B*B-A*d2*z3*z3))

			if math.IsNaN(z2) || math.IsInf(z2, 0) || z2 < 0 {
				if limit < -0.5 {
					z2 = z1 * (_EXT - 1)
				} else {
					z2 = (limit - z1) / 2.0
				}
			} else if (limit > -0.5) && (z2+z1 > z1*_EXT) {
				z2 = (limit - z1) / 2.0
			} else if (limit < -0.5) && (z2+z1 > z1*_EXT) {
				z2 = z1 * (_EXT - 1.0)
			} else if z2 < (-1.0 * z3 * _INT) {
				z2 = -1.0 * z3 * _INT
			} else if (limit > -0.5) && (z2 < (limit-z1)*(1.0-_INT)) {
				z2 = (limit - z1) * (1.0 - _INT)
			}

			f3 = f2
			d3 = d2
			z3 = -1.0 * z2
			z1 = z1 + z2

			theta, _ = theta.Add(s.Scale(z2))
			f2, df2 = f(theta)

			M -= 1
			if length < 0 {
				i += 1
			}

			d2 = df2.Dot(s)
		}

		if success == 1 {
			f1 = f2
			if verbose {
				fmt.Printf("Iteration %d | Cost: %0.15f\n", i, f1)
			}

			numerator := (df2.Dot(df2) - df1.Dot(df2)) / df1.Dot(df1)
			s, _ = s.Scale(numerator).Sub(df2)

			tmp := df1
			df1 = df2
			df2 = tmp

			d2 = df1.Dot(s)

			if d2 > 0 {
				s = df1.Scale(-1.0)
				d2 = s.Scale(-1.0).Dot(s)
			}

			//z1 = z1 * math.Min(_RATIO, d1/(d2-math.SmallestNonzeroFloat64))
			z1 = z1 * math.Min(_RATIO, d1/(d2-1e-15))
			d1 = d2
			lsFailed = 0
		} else {
			theta = theta0
			f1 = f0
			df1 = df0

			if lsFailed == 1 || float64(i) > math.Abs(float64(length)) {
				break
			}

			tmp := df1
			df1 = df2
			df2 = tmp
			s = df1.Scale(-1.0)
			z1 = 1.0 / (1.0 - d1)
			lsFailed = 1
		}
	}

	return theta
}