add comments

This commit is contained in:
filifa 2025-09-30 23:58:28 -04:00
parent 5c42040e34
commit a760093f9d
12 changed files with 62 additions and 3 deletions

View File

@ -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

View File

@ -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 {

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -16,6 +16,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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++ {

View File

@ -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)

View File

@ -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++ {

View File

@ -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 {

View File

@ -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)

View File

@ -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)

View File

@ -16,6 +16,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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