예제 #1
0
// Discriminant returns the discriminant of this polynomial.
func Discriminant(p *poly.IntPolynomial) *mathx.Int {
	if p.Degree() == 2 {
		c, b, a := p.Coeff(0), p.Coeff(1), p.Coeff(2)
		ac4 := mathx.NewInt(4).Mul(a).Mul(c)
		return b.Mul(b).Sub(ac4)
	}
	return nil
}
예제 #2
0
// cohen, 5.7.2,  p. 270
func regulatorRealQuad(poly *poly.IntPolynomial) float64 {
	D := Discriminant(poly).Int64()
	f := math.Sqrt(float64(D))
	c := -poly.Coeff(0).Int64()
	// try all of the small elements
	for x := int64(1); x < 100; x++ {
		for y := int64(1); y < 100; y++ {
			z := x*x - c*y*y
			if z == 4 || z == -4 {
				u := x
				v := y
				return math.Log((float64(u) + float64(v)*math.Sqrt(float64(c))) / 2.0)
			}
		}
	}
	d := int64(math.Floor(f))
	var b int64
	if d&1 == D&1 {
		b = d
	} else {
		b = d - 1
	}
	var u, v int64
	u1 := -b
	u2 := int64(2)
	v1 := int64(1)
	v2 := int64(0)
	p := b
	q := int64(2)
	for {
		A := (p + d) / q
		t := p
		p = A*q - p
		if t == p && v2 != 0 {
			u = (u2*u2 + v2*v2*D) / q
			v = (2 * u2 * v2) / q
			break
		}
		u1, u2 = u2, A*u2+u1
		v1, v2 = v2, A*v2+v1
		t = q
		q = (D - p*p) / q

		if q == t && v2 != 0 {
			u = (u1*u2 + D*v1*v2) / q
			v = (u1*v2 + u2*v1) / q
			break
		}
	}
	return math.Log((math.Abs(float64(u)) + math.Abs(float64(v))*f) / 2.0)
}