Beispiel #1
0
func (ps *Swing) OddSwing(z *big.Int, k uint) *big.Int {
	if k < uint(len(SmallOddSwing)) {
		return z.SetInt64(SmallOddSwing[k])
	}
	rootK := xmath.FloorSqrt(k)
	ps.factors = ps.factors[:0] // reset length, reusing existing capacity
	ps.Sieve.Iterate(3, uint64(rootK), func(p uint64) (terminate bool) {
		q := uint64(k) / p
		for q > 0 {
			if q&1 == 1 {
				ps.factors = append(ps.factors, p)
			}
			q /= p
		}
		return
	})
	ps.Sieve.Iterate(uint64(rootK+1), uint64(k/3), func(p uint64) (term bool) {
		if (uint64(k) / p & 1) == 1 {
			ps.factors = append(ps.factors, p)
		}
		return
	})
	ps.Sieve.Iterate(uint64(k/2+1), uint64(k), func(p uint64) (term bool) {
		ps.factors = append(ps.factors, p)
		return
	})
	return xmath.Product(z, ps.factors)
}
Beispiel #2
0
func TestProduct(t *testing.T) {
	m := new(big.Int)

	// test empty list
	if xmath.Product(m, nil).Int64() != 1 {
		t.Error("Product of empty list should be 1. Got", m)
	}

	// compute product with seqential algorithm
	p := big.NewInt(int64(s[0]))
	for _, term := range s[1:] {
		p.Mul(p, m.SetInt64(int64(term)))
	}

	// test
	if _ = xmath.Product(m, s); m.Cmp(p) != 0 {
		t.Error("Product fail on", len(s), "random numbers")
	}
}
Beispiel #3
0
// BinomialS computes the binomial coefficient C(n,k) using prime number
// sieve p.  BinomialS returns nil if p is too small.  Otherwise it leaves
// the result in z, replacing the existing value of z, and returning z.
func BinomialS(z *big.Int, p *sieve.Sieve, n, k uint) *big.Int {
	if uint64(n) > p.Lim {
		return nil
	}
	if k > n {
		return z.SetInt64(0)
	}
	if k > n/2 {
		k = n - k
	}
	if k < 3 {
		switch k {
		case 0:
			return z.SetInt64(1)
		case 1:
			return z.SetInt64(int64(n))
		case 2:
			var n1 big.Int
			return z.Rsh(z.Mul(z.SetInt64(int64(n)), n1.SetInt64(int64(n-1))), 1)
		}
	}
	rootN := uint64(xmath.FloorSqrt(n))
	var factors []uint64
	p.Iterate(2, rootN, func(p uint64) (terminate bool) {
		var r, nn, kk uint64 = 0, uint64(n), uint64(k)
		for nn > 0 {
			if nn%p < kk%p+r {
				r = 1
				factors = append(factors, p)
			} else {
				r = 0
			}
			nn /= p
			kk /= p
		}
		return
	})
	p.Iterate(rootN+1, uint64(n/2), func(p uint64) (terminate bool) {
		if uint64(n)%p < uint64(k)%p {
			factors = append(factors, p)
		}
		return
	})
	p.Iterate(uint64(n-k+1), uint64(n), func(p uint64) (terminate bool) {
		factors = append(factors, p)
		return
	})
	return xmath.Product(z, factors)
}
Beispiel #4
0
func main() {
	tMin := xmath.ProductSerialThreshold - 10
	if tMin < 2 {
		tMin = 2
	}
	tMax := xmath.ProductSerialThreshold + 10
	p := new(big.Int)
	var st int
	// close on st
	f := func(b *testing.B) {
		t0 := xmath.ProductSerialThreshold
		xmath.ProductSerialThreshold = st
		for i := 0; i < b.N; i++ {
			xmath.Product(p, s)
		}
		xmath.ProductSerialThreshold = t0
	}
	for st = tMin; st <= tMax; st++ {
		fmt.Println("Threshold:", st, testing.Benchmark(f))
	}
}