Example #1
0
// Subtract
func (a Scalar) Sub_S(b S) S {
	var x, y big.Float
	x = big.Float(a)
	y = big.Float(b.(Scalar))
	z := x.Sub(&x, &y)
	return (Scalar)(*z)
}
Example #2
0
func TestSqrt(t *testing.T) {
	tests := []struct {
		prec uint
		in   float64
	}{
		{16, 0},
		{16, 1},
		{16, 4},
		{16, 10000},
		{16, 2},
		{64, 2},
		{256, 2},
		{1024, 1.5},
	}
	for _, test := range tests {
		x := new(big.Float).SetPrec(test.prec)
		x.SetFloat64(test.in)
		var got, got2, diff big.Float
		pslq := New(test.prec)
		pslq.Sqrt(x, &got)
		got2.SetPrec(test.prec).Mul(&got, &got)
		diff.Sub(&got2, x)
		if diff.MinPrec() > 1 {
			t.Errorf("sqrt(%f) prec %d wrong got %.20f square %.20f expecting %f diff %g minprec %d", test.in, test.prec, &got, &got2, x, &diff, diff.MinPrec())
		}
	}
}
Example #3
0
// Sqrt returns the square root n.
func Sqrt(n *big.Float) *big.Float {
	prec := n.Prec()

	x := new(big.Float).SetPrec(prec).SetInt64(1)
	z := new(big.Float).SetPrec(prec).SetInt64(1)

	half := new(big.Float).SetPrec(prec).SetFloat64(0.5)
	t := new(big.Float).SetPrec(prec)

	for {
		z.Copy(x)

		t.Mul(x, x)
		t.Sub(t, n)
		t.Quo(t, x)
		t.Mul(t, half)
		x.Sub(x, t)

		if x.Cmp(z) == 0 {
			break
		}
	}

	return x
}
Example #4
0
// sincos iterates a sin or cos Taylor series.
func sincos(name string, index int, x, z, exponent, factorial *big.Float) *big.Float {
	plus := false
	term := newF().Set(floatOne)
	for j := 0; j < index; j++ {
		term.Mul(term, x)
	}
	xN := newF().Set(term)
	x2 := newF().Mul(x, x)

	loop := newLoop(name, x, 4)
	for {
		// Invariant: factorial holds exponent!.
		term.Quo(term, factorial)
		if plus {
			z.Add(z, term)
		} else {
			z.Sub(z, term)
		}
		plus = !plus

		if loop.terminate(z) {
			break
		}
		// Advance x**index (multiply by x²).
		term.Mul(xN, x2)
		xN.Set(term)
		// Advance exponent and factorial.
		exponent.Add(exponent, floatOne)
		factorial.Mul(factorial, exponent)
		exponent.Add(exponent, floatOne)
		factorial.Mul(factorial, exponent)
	}
	return z
}
Example #5
0
// twoPiReduce guarantees x < 2𝛑; x is known to be >= 0 coming in.
func twoPiReduce(x *big.Float) {
	// TODO: Is there an easy better algorithm?
	twoPi := newF().Set(floatTwo)
	twoPi.Mul(twoPi, floatPi)
	// Do something clever(er) if it's large.
	if x.Cmp(newF().SetInt64(1000)) > 0 {
		multiples := make([]*big.Float, 0, 100)
		sixteen := newF().SetInt64(16)
		multiple := newF().Set(twoPi)
		for {
			multiple.Mul(multiple, sixteen)
			if x.Cmp(multiple) < 0 {
				break
			}
			multiples = append(multiples, newF().Set(multiple))
		}
		// From the right, subtract big multiples.
		for i := len(multiples) - 1; i >= 0; i-- {
			multiple := multiples[i]
			for x.Cmp(multiple) >= 0 {
				x.Sub(x, multiple)
			}
		}
	}
	for x.Cmp(twoPi) >= 0 {
		x.Sub(x, twoPi)
	}
}
Example #6
0
func mandelbrotFloat(a, b *big.Float) color.Color {
	var x, y, nx, ny, x2, y2, f2, f4, r2, tmp big.Float
	f2.SetInt64(2)
	f4.SetInt64(4)
	x.SetInt64(0)
	y.SetInt64(0)

	defer func() { recover() }()

	for n := uint8(0); n < iterations; n++ {
		// Not update x2 and y2
		// because they are already updated in the previous loop
		nx.Sub(&x2, &y2)
		nx.Add(&nx, a)

		tmp.Mul(&x, &y)
		ny.Mul(&f2, &tmp)
		ny.Add(&ny, b)

		x.Set(&nx)
		y.Set(&ny)

		x2.Mul(&x, &x)
		y2.Mul(&y, &y)
		r2.Add(&x2, &y2)

		if r2.Cmp(&f4) > 0 {
			return color.Gray{255 - contrast*n}
		}
	}
	return color.Black
}
Example #7
0
// Returns pi using Machin's formula
func pi(prec uint, result *big.Float) {
	var tmp, _4 big.Float
	_4.SetPrec(prec).SetInt64(4)
	acot(prec, 5, &tmp)
	tmp.SetPrec(prec).Mul(&tmp, &_4)
	acot(prec, 239, result)
	result.Sub(&tmp, result)
	result.SetPrec(prec).Mul(result, &_4)
}
Example #8
0
File: pslq.go Project: ncw/pslq
// NearestInt set res to the nearest integer to x
func (e *Pslq) NearestInt(x *big.Float, res *big.Int) {
	prec := x.Prec()
	var tmp big.Float
	tmp.SetPrec(prec)
	if x.Sign() >= 0 {
		tmp.Add(x, &e.half)
	} else {
		tmp.Sub(x, &e.half)
	}
	tmp.Int(res)
}
Example #9
0
// compute √z using newton to solve
// t² - z = 0 for t
func sqrtDirect(z *big.Float) *big.Float {
	// f(t)/f'(t) = 0.5(t² - z)/t
	half := big.NewFloat(0.5)
	f := func(t *big.Float) *big.Float {
		x := new(big.Float).Mul(t, t) // x = t²
		x.Sub(x, z)                   // x = t² - z
		x.Mul(half, x)                // x = 0.5(t² - z)
		return x.Quo(x, t)            // return x = 0.5(t² - z)/t
	}

	// initial guess
	zf, _ := z.Float64()
	guess := big.NewFloat(math.Sqrt(zf))

	return newton(f, guess, z.Prec())
}
Example #10
0
File: exp.go Project: ALTree/floats
// Exp returns a big.Float representation of exp(z). Precision is
// the same as the one of the argument. The function returns +Inf
// when z = +Inf, and 0 when z = -Inf.
func Exp(z *big.Float) *big.Float {

	// exp(0) == 1
	if z.Sign() == 0 {
		return big.NewFloat(1).SetPrec(z.Prec())
	}

	// Exp(+Inf) = +Inf
	if z.IsInf() && z.Sign() > 0 {
		return big.NewFloat(math.Inf(+1)).SetPrec(z.Prec())
	}

	// Exp(-Inf) = 0
	if z.IsInf() && z.Sign() < 0 {
		return big.NewFloat(0).SetPrec(z.Prec())
	}

	guess := new(big.Float)

	// try to get initial estimate using IEEE-754 math
	zf, _ := z.Float64()
	if zfs := math.Exp(zf); zfs == math.Inf(+1) || zfs == 0 {
		// too big or too small for IEEE-754 math,
		// perform argument reduction using
		//     e^{2z} = (e^z)²
		halfZ := new(big.Float).Mul(z, big.NewFloat(0.5))
		halfExp := Exp(halfZ.SetPrec(z.Prec() + 64))
		return new(big.Float).Mul(halfExp, halfExp).SetPrec(z.Prec())
	} else {
		// we got a nice IEEE-754 estimate
		guess.SetFloat64(zfs)
	}

	// f(t)/f'(t) = t*(log(t) - z)
	f := func(t *big.Float) *big.Float {
		x := new(big.Float)
		x.Sub(Log(t), z)
		return x.Mul(x, t)
	}

	x := newton(f, guess, z.Prec())

	return x
}
Example #11
0
// This example shows how to use big.Float to compute the square root of 2 with
// a precision of 200 bits, and how to print the result as a decimal number.
func Example_sqrt2() {
	// We'll do computations with 200 bits of precision in the mantissa.
	const prec = 200

	// Compute the square root of 2 using Newton's Method. We start with
	// an initial estimate for sqrt(2), and then iterate:
	//     x_{n+1} = 1/2 * ( x_n + (2.0 / x_n) )

	// Since Newton's Method doubles the number of correct digits at each
	// iteration, we need at least log_2(prec) steps.
	steps := int(math.Log2(prec))

	// Initialize values we need for the computation.
	two := new(big.Float).SetPrec(prec).SetInt64(2)
	half := new(big.Float).SetPrec(prec).SetFloat64(0.5)

	// Use 1 as the initial estimate.
	x := new(big.Float).SetPrec(prec).SetInt64(1)

	// We use t as a temporary variable. There's no need to set its precision
	// since big.Float values with unset (== 0) precision automatically assume
	// the largest precision of the arguments when used as the result (receiver)
	// of a big.Float operation.
	t := new(big.Float)

	// Iterate.
	for i := 0; i <= steps; i++ {
		t.Quo(two, x)  // t = 2.0 / x_n
		t.Add(x, t)    // t = x_n + (2.0 / x_n)
		x.Mul(half, t) // x_{n+1} = 0.5 * t
	}

	// We can use the usual fmt.Printf verbs since big.Float implements fmt.Formatter
	fmt.Printf("sqrt(2) = %.50f\n", x)

	// Print the error between 2 and x*x.
	t.Mul(x, x) // t = x*x
	fmt.Printf("error = %e\n", t.Sub(two, t))

	// Output:
	// sqrt(2) = 1.41421356237309504880168872420969807856967187537695
	// error = 0.000000e+00
}
Example #12
0
// Estimates the Variance based on the data set
// If the data set is relatively small (< 1000 examples), then remove 1 from the total
func (ad *AnomalyDetection) estimateVariance() *big.Float {

	// this means that the mean was never calculated before, therefore do it now
	// the means is needed for the cimputation of the deviation
	if ad.mean.Cmp(zero) == 0 {
		ad.estimateMean()
	}

	// initialize the total to zero
	totalVariance := big.NewFloat(0)
	totalDeviation := big.NewFloat(0)

	var deviation big.Float
	var deviationCopy big.Float

	var singleVariance big.Float

	// Loop while a is smaller than 1e100.
	for _, element := range ad.dataSet {
		// first calculate the deviation for each element, by subtracting the mean, take the absolute value
		deviation.Sub(&element, &ad.mean).Abs(&deviation)

		// add it to the total
		totalDeviation.Add(totalDeviation, &deviation)

		// calculate the variance by squaring it
		singleVariance = *deviationCopy.Mul(&deviation, &deviation) // ^2

		// the calculate the variance
		totalVariance.Add(totalVariance, &singleVariance)
	}

	// calculate the variance
	// assign the variance to the anomaly detection object
	ad.variance = *totalVariance.Quo(totalVariance, &ad.totalSamples)

	// calculate the deviation
	ad.deviation = *totalDeviation.Quo(totalDeviation, &ad.totalSamples)

	return &ad.variance
}
Example #13
0
// compute √z using newton to solve
// 1/t² - z = 0 for x and then inverting.
func sqrtInverse(z *big.Float) *big.Float {
	// f(t)/f'(t) = -0.5t(1 - zt²)
	nhalf := big.NewFloat(-0.5)
	one := big.NewFloat(1)
	f := func(t *big.Float) *big.Float {
		u := new(big.Float)
		u.Mul(t, t)                     // u = t²
		u.Mul(u, z)                     // u = zt²
		u.Sub(one, u)                   // u = 1 - zt²
		u.Mul(u, nhalf)                 // u = -0.5(1 - zt²)
		return new(big.Float).Mul(t, u) // x = -0.5t(1 - zt²)
	}

	// initial guess
	zf, _ := z.Float64()
	guess := big.NewFloat(1 / math.Sqrt(zf))

	// There's another operation after newton,
	// so we need to force it to return at least
	// a few guard digits. Use 32.
	x := newton(f, guess, z.Prec()+32)
	return x.Mul(z, x).SetPrec(z.Prec())
}