diff --git a/internal/lib/continuedFrac.go b/internal/lib/continuedFrac.go
index 5b819cd..bd7a8f0 100644
--- a/internal/lib/continuedFrac.go
+++ b/internal/lib/continuedFrac.go
@@ -21,6 +21,9 @@ import (
"math/big"
)
+/*
+SqrtRepetend returns the repetend of the continued fraction of sqrt(x). It returns an error if x is a perfect square.
+*/
func SqrtRepetend(x *big.Int) ([]*big.Int, error) {
m := big.NewInt(0)
d := big.NewInt(1)
@@ -65,6 +68,9 @@ func cycle(seq []*big.Int) <-chan *big.Int {
return ch
}
+/*
+GaussianBrackets returns a channel that outputs the sequence [], [a1], [a1, a2], ... where each value comes from the input channel and [] denotes Gaussian brackets.
+*/
func GaussianBrackets(ch <-chan *big.Int) <-chan *big.Int {
out := make(chan *big.Int)
@@ -87,6 +93,9 @@ func GaussianBrackets(ch <-chan *big.Int) <-chan *big.Int {
return out
}
+/*
+CFracConvergents returns a channel that outputs convergents of a periodic continued fraction with initial term a0 and repetend stored in denoms.
+*/
func CFracConvergents(a0 *big.Int, denoms []*big.Int) <-chan *big.Rat {
hc := cycle(denoms)
_ = <-hc
diff --git a/internal/lib/crt.go b/internal/lib/crt.go
index 8314702..7375f6d 100644
--- a/internal/lib/crt.go
+++ b/internal/lib/crt.go
@@ -46,6 +46,9 @@ func solveCRT(a1, n1, a2, n2 *big.Int) (*big.Int, *big.Int) {
return x, N
}
+/*
+Given a system of congruences - defined by slices of remainders and moduli such that x = remainders[i] (mod moduli[i]) for each index i - CRTSolution outputs a solution to the system.
+*/
func CRTSolution(remainders, moduli []*big.Int) (*big.Int, *big.Int) {
n1 := new(big.Int)
a1 := new(big.Int)
@@ -63,6 +66,9 @@ func CRTSolution(remainders, moduli []*big.Int) (*big.Int, *big.Int) {
return a1, n1
}
+/*
+ArePairwiseCoprime returns true if each pair of values in the input slice are coprime.
+*/
func ArePairwiseCoprime(moduli []*big.Int) bool {
z := new(big.Int)
for i, a := range moduli {
diff --git a/internal/lib/discreteLog.go b/internal/lib/discreteLog.go
index 9452e7a..3b48361 100644
--- a/internal/lib/discreteLog.go
+++ b/internal/lib/discreteLog.go
@@ -33,9 +33,13 @@ func ceilSqrt(x *big.Int) *big.Int {
return z
}
-// TODO: this can be extended to work with n, b not coprime
-// https://cp-algorithms.com/algebra/discrete-log.html
+/*
+BabyStepGiantStep computes i such that b^i = x (mod n). For more efficient computation, provide the order of the group (i.e. totient(n)).
+*/
func BabyStepGiantStep(n, b, x, order *big.Int) (*big.Int, error) {
+ // TODO: this function be extended to work with n, b not coprime
+ // https://cp-algorithms.com/algebra/discrete-log.html
+
z := new(big.Int).GCD(nil, nil, b, n)
if z.Cmp(big.NewInt(1)) != 0 {
return nil, fmt.Errorf("base %v and modulus %v are not coprime", b, n)
diff --git a/internal/lib/divisor.go b/internal/lib/divisor.go
index 7a4967c..dd21e42 100644
--- a/internal/lib/divisor.go
+++ b/internal/lib/divisor.go
@@ -20,8 +20,12 @@ import (
"math/big"
)
-// TODO: expand to work for different sigmas
+/*
+DivisorSummatory computes the sum of sigma(k) for k=1 to n, where sigma is the divisor sum function.
+*/
func DivisorSummatory(n *big.Int) *big.Int {
+ // TODO: expand to work for different sigmas
+
// employing Dirichlet's hyperbola method
sqrt := new(big.Int).Sqrt(n)
diff --git a/internal/lib/divisors.go b/internal/lib/divisors.go
index 074f120..e9e7267 100644
--- a/internal/lib/divisors.go
+++ b/internal/lib/divisors.go
@@ -48,6 +48,9 @@ func updateMultiples(sieve []uint, x uint, p uint, n uint) {
}
}
+/*
+DivisorSieve computes sigma_x(k) for k=1 to n, where sigma_x is the divisor sum function. x sets the power each divisor is raised to.
+*/
func DivisorsSieve(n uint, x uint) chan uint {
sieve := make([]uint, n)
sieve[0] = 0
diff --git a/internal/lib/mobius.go b/internal/lib/mobius.go
index 6425fbf..b3e7bb3 100644
--- a/internal/lib/mobius.go
+++ b/internal/lib/mobius.go
@@ -16,6 +16,9 @@ along with this program. If not, see .
*/
package lib
+/*
+MobiusSieve computes mobius(k) for k=1 to n, where mobius is the Mobius function.
+*/
func MobiusSieve(n uint) chan int {
sieve := make([]int, n)
for i := 0; i < int(n); i++ {
diff --git a/internal/lib/partitions.go b/internal/lib/partitions.go
index 3063f9a..c3b7df1 100644
--- a/internal/lib/partitions.go
+++ b/internal/lib/partitions.go
@@ -29,6 +29,9 @@ func nextPartition(k int, vals []*big.Int) {
}
}
+/*
+Partitions computes the number of ways to add to n with k or fewer terms.
+*/
func Partitions(n, k int) *big.Int {
if n < 0 {
return big.NewInt(0)
diff --git a/internal/lib/primeOmega.go b/internal/lib/primeOmega.go
index 4ab53bd..d22ca76 100644
--- a/internal/lib/primeOmega.go
+++ b/internal/lib/primeOmega.go
@@ -35,6 +35,9 @@ func primeOmegaUpdateMultiples(sieve []uint, p uint, n uint, multiplicity bool)
}
}
+/*
+PrimeOmegaSieve computes omega(k) for k=1 to n, where omega is the prime omega function. If multiplicity is true, factors are counted with multiplicity.
+*/
func PrimeOmegaSieve(n uint, multiplicity bool) chan uint {
sieve := make([]uint, n)
for i := uint(0); i < n; i++ {
diff --git a/internal/lib/primitiveRoot.go b/internal/lib/primitiveRoot.go
index 099687c..e84c604 100644
--- a/internal/lib/primitiveRoot.go
+++ b/internal/lib/primitiveRoot.go
@@ -21,6 +21,9 @@ import (
"math/big"
)
+/*
+Totient is a naive implementation of Euler's totient function.
+*/
func Totient(n *big.Int) *big.Int {
N := new(big.Int).Set(n)
@@ -52,6 +55,9 @@ func Totient(n *big.Int) *big.Int {
return phi
}
+/*
+MultiplicativeOrder computes the smallest integer k such that g^k = 1 (mod modulus).
+*/
func MultiplicativeOrder(g *big.Int, modulus *big.Int) *big.Int {
e := new(big.Int).Set(g)
var k *big.Int
@@ -63,6 +69,9 @@ func MultiplicativeOrder(g *big.Int, modulus *big.Int) *big.Int {
return k
}
+/*
+PrimitiveRoot computes a primitive root modulo modulus.
+*/
func PrimitiveRoot(modulus *big.Int) (*big.Int, error) {
if modulus.Cmp(big.NewInt(1)) == 0 {
return big.NewInt(0), nil
@@ -85,6 +94,9 @@ func PrimitiveRoot(modulus *big.Int) (*big.Int, error) {
return nil, errors.New("no primitive root")
}
+/*
+PrimitiveRootFast computes a primitive root modulo modulus, utilizing the prime factorization of the totient of the modulus to find a solution more efficiently.
+*/
func PrimitiveRootFast(modulus *big.Int, tpf map[string]*big.Int) (*big.Int, error) {
phi := big.NewInt(1)
for p, exp := range tpf {
diff --git a/internal/lib/shoelace.go b/internal/lib/shoelace.go
index 2b943bf..7c6dfdd 100644
--- a/internal/lib/shoelace.go
+++ b/internal/lib/shoelace.go
@@ -21,6 +21,9 @@ type Point struct {
Y float64
}
+/*
+Area computes the area of a polygon given its vertices using the shoelace formula.
+*/
func Area(points []Point) float64 {
total := float64(0)
n := len(points)
diff --git a/internal/lib/stirling.go b/internal/lib/stirling.go
index 55ced30..ad80425 100644
--- a/internal/lib/stirling.go
+++ b/internal/lib/stirling.go
@@ -30,6 +30,9 @@ func nextStirling1(k int, vals []*big.Int) {
}
}
+/*
+Stirling1 computes Stirling numbers of the first kind.
+*/
func Stirling1(n, k int) *big.Int {
if k > n {
return big.NewInt(0)
@@ -57,6 +60,9 @@ func nextStirling2(k int64, vals []*big.Int) {
}
}
+/*
+Stirling2 computes Stirling numbers of the second kind.
+*/
func Stirling2(n, k int) *big.Int {
if k > n {
return big.NewInt(0)
diff --git a/internal/lib/totient.go b/internal/lib/totient.go
index fd97f24..85629da 100644
--- a/internal/lib/totient.go
+++ b/internal/lib/totient.go
@@ -16,6 +16,9 @@ along with this program. If not, see .
*/
package lib
+/*
+TotientSieve computes totient(k) for k=1 to n, where totient is Euler's totient function.
+*/
func TotientSieve(n uint) chan uint {
totients := make([]uint, n)
totients[0] = 0