func funcHoltWinters(vals []Value, args Expressions, enh *EvalNodeHelper) Vector {
	mat := vals[0].(Matrix)

	// The smoothing factor argument.
	sf := vals[1].(Vector)[0].V

	// The trend factor argument.
	tf := vals[2].(Vector)[0].V

	// Sanity check the input.
	if sf <= 0 || sf >= 1 {
		panic(errors.Errorf("invalid smoothing factor. Expected: 0 < sf < 1, got: %f", sf))
	}
	if tf <= 0 || tf >= 1 {
		panic(errors.Errorf("invalid trend factor. Expected: 0 < tf < 1, got: %f", tf))
	}

	var l int
	for _, samples := range mat {
		l = len(samples.Points)

		// Can't do the smoothing operation with less than two points.
		if l < 2 {
			continue
		}

		var s0, s1, b float64
		// Set initial values.
		s1 = samples.Points[0].V
		b = samples.Points[1].V - samples.Points[0].V

		// Run the smoothing operation.
		var x, y float64
		for i := 1; i < l; i++ {

			// Scale the raw value against the smoothing factor.
			x = sf * samples.Points[i].V

			// Scale the last smoothed value with the trend at this point.
			b = calcTrendValue(i-1, sf, tf, s0, s1, b)
			y = (1 - sf) * (s1 + b)

			s0, s1 = s1, x+y
		}

		enh.out = append(enh.out, Sample{
			Point: Point{V: s1},
		})
	}

	return enh.out
}
func funcHoltWinters(vals []Value, args Expressions, enh *EvalNodeHelper) Vector {
	mat := vals[0].(Matrix)

	
	sf := vals[1].(Vector)[0].V

	
	tf := vals[2].(Vector)[0].V

	
	if sf <= 0 || sf >= 1 {
		panic(errors.Errorf("invalid smoothing factor. Expected: 0 < sf < 1, got: %f", sf))
	}
	if tf <= 0 || tf >= 1 {
		panic(errors.Errorf("invalid trend factor. Expected: 0 < tf < 1, got: %f", tf))
	}

	var l int
	for _, samples := range mat {
		l = len(samples.Points)

		
		if l < 2 {
			continue
		}

		var s0, s1, b float64
		
		s1 = samples.Points[0].V
		b = samples.Points[1].V - samples.Points[0].V

		
		var x, y float64
		for i := 1; i < l; i++ {

			
			x = sf * samples.Points[i].V

			
			b = calcTrendValue(i-1, sf, tf, s0, s1, b)
			y = (1 - sf) * (s1 + b)

			s0, s1 = s1, x+y
		}

		enh.out = append(enh.out, Sample{
			Point: Point{V: s1},
		})
	}

	return enh.out
}
func funcHoltWinters ( vals [ ] Value , args Expressions , enh * EvalNodeHelper ) Vector { mat := vals [ 0 ] . ( Matrix ) // The smoothing factor argument. sf := vals [ 1 ] . ( Vector ) [ 0 ] . V // The trend factor argument. tf := vals [ 2 ] . ( Vector ) [ 0 ] . V // Sanity check the input. if sf <= 0 || sf >= 1 { panic ( errors . Errorf ( " " , sf ) ) } if tf <= 0 || tf >= 1 { panic ( errors . Errorf ( " " , tf ) ) } var l int for _ , samples := range mat { l = len ( samples . Points ) // Can't do the smoothing operation with less than two points. if l < 2 { continue } var s0 , s1 , b float64 // Set initial values. s1 = samples . Points [ 0 ] . V b = samples . Points [ 1 ] . V - samples . Points [ 0 ] . V // Run the smoothing operation. var x , y float64 for i := 1 ; i < l ; i ++ { // Scale the raw value against the smoothing factor. x = sf * samples . Points [ i ] . V // Scale the last smoothed value with the trend at this point. b = calcTrendValue ( i - 1 , sf , tf , s0 , s1 , b ) y = ( 1 - sf ) * ( s1 + b ) s0 , s1 = s1 , x + y } enh . out = append ( enh . out , Sample { Point : Point { V : s1 } , } ) } return enh . out }
// Holt-Winters is similar to a weighted moving average, where historical data has exponentially less influence on the current data.
// Holt-Winter also accounts for trends in data. The smoothing factor (0 < sf < 1) affects how historical data will affect the current
// data. A lower smoothing factor increases the influence of historical data. The trend factor (0 < tf < 1) affects
// how trends in historical data will affect the current data. A higher trend factor increases the influence.
// of trends. Algorithm taken from https://en.wikipedia.org/wiki/Exponential_smoothing titled: "Double exponential smoothing".
Holt - Winters is similar to a weighted moving average where historical data has exponentially less influence on the current data . Holt - Winter also accounts for trends in data . The smoothing factor ( 0 < sf < 1 ) affects how historical data will affect the current data . A lower smoothing factor increases the influence of historical data . The trend factor ( 0 < tf < 1 ) affects how trends in historical data will affect the current data . A higher trend factor increases the influence . of trends . Algorithm taken from https : // en . wikipedia . org / wiki / Exponential_smoothing titled : Double exponential smoothing .