NAME
Sidef::Types::Number::Number - Arbitrary-precision numeric type providing extensive mathematical and number-theoretic functionality.
DESCRIPTION
The Number class implements support for numerical operations, supporting integers, rationals, floating-points and complex numbers at arbitrary precision.
This class also implements many useful mathematical methods, from basic arithmetical operations, to advanced number-theoretic functions, including primality testing and prime factorization methods.
The following class-variables can be changed during runtime:
Num!PREC = 192 # precision for floating-point numbers
Num!ROUND = 0 # rounding mode for floating-point numbers
Num!VERBOSE = false # true to enable verbose/debug mode
Num!USE_YAFU = false # true to use YAFU for factoring large integers
Num!USE_PFGW = false # true to use PFGW64 as a primality pretest for large enough n
Num!USE_PARI_GP = false # true to use PARI/GP in several methods
Num!USE_FACTORDB = false # true to use factordb.com for factoring large integers
Num!USE_PRIMESUM = false # true to use Kim Walisch's primesum in prime_sum(n)
Num!USE_PRIMECOUNT = false # true to use Kim Walisch's primecount in prime_count(n)
Num!USE_CONJECTURES = false # true to use conjectured methods for better performance
Num!SPECIAL_FACTORS = true # true to try to find factors of special form in factor(n)
The supported rounding modes for floating-point numbers, are:
Num!ROUND = 0 # Round to nearest.
Num!ROUND = 1 # Round towards zero.
Num!ROUND = 2 # Round towards +infinity.
Num!ROUND = 3 # Round towards -infinity.
Num!ROUND = 4 # Round away from zero. (with MPFR >= 3.0.0)
Num!ROUND = 5 # Faithful rounding. (with MPFR >= 4.0.0)
The values can also be modified only in a local scope, by using the local keyword:
func f(n) {
local Num!PREC = 1024
# do some work
}
In the above example, the f(n) function will use 1024 bits of precision for floating-point numbers, while outside the function, the default precision will be used.
NOTE: the local scope extends to any other functions or methods that the are called from the local scope.
SYNOPSIS
# Basic number creation
var a = Num("3.14159")
var b = Number("1010", 2) # Binary: 10
var c = 42 # Integer literal
# Arithmetic operations
say (2**100 + 1) # Large integer arithmetic
say as_frac(1/3 + 1/6) # Rational arithmetic: 1/2
# Number-theoretic functions
say 100.prime # 100th prime: 541
say factor(2**64 + 1) # Prime factorization
say euler_phi(100) # Euler's totient: 40
# Floating-point with custom precision
local Num!PREC = 1024 # set precision to 1024 bits
say sqrt(2) # High-precision square root
INHERITS
Inherits methods from Sidef::Object::Object.
OPERATORS & COMPARISONS
!=
a != b
ne(a, b)
Returns true if a and b are different.
say (42 != 13) #=> true
say (5 != 5) #=> false
Aliases: ≠, ne
*
a * b
mul(a, b)
Multiplies a and b.
say (6 * 7) #=> 42
say (2/3 * 3/4) #=> 1/2
Aliases: mul
**
a ** b
pow(a, b)
Raises a to the power b.
say 2**10 #=> 1024
say 5**3 #=> 125
say pow(2, 100) #=> 1267650600228229401496703205376
Aliases: pow
+
a + b
add(a, b)
Adds two numbers a and b.
say (42 + 13) #=> 55
say (1/3 + 1/6) #=> 1/2
say add(2.5, 3.7) #=> 6.2
Aliases: add
++
n++
++n
n.inc
Increments n by 1 and returns the result.
var x = 5
say ++x #=> 6
say x++ #=> 6 (returns 6, x is now 7)
say x.inc #=> 8
The inc method-call does not modify the variable in-place.
Aliases: inc
-
a - b
sub(a, b)
Subtracts b from a.
say (50 - 8) #=> 42
say (1/2 - 1/3) #=> 1/6
Aliases: sub
--
n--
--n
n.dec
Decrements n by 1 and returns the result.
var x = 5
say --x #=> 4
say x-- #=> 4 (returns 4, x is now 3)
say x.dec #=> 2
The dec method-call does not modify the variable in-place.
Aliases: dec
..
a .. b
Create an inclusive-inclusive RangeNum object, from a to b.
Equivalent with:
RangeNum(a, b)
Aliases: to, upto
..^
a ..^ b
Create an inclusive-exclusive RangeNum object, from a to b-1.
Equivalent with:
RangeNum(a, b-1)
Aliases: xto, xupto
/
a / b
div(a, b)
Divides a by b.
say (10 / 3) #=> 10/3
say (15 / 5) #=> 3
say (7.5 / 2.5) #=> 3
Aliases: ÷, div
//
a // b
idiv(a, b)
Integer floor division. Equivalent to floor(a/b) for integers.
say (17 // 5) #=> 3
say (-17 // 5) #=> -4
say idiv(100, 7) #=> 14
Aliases: divint, fld, idiv, idiv_floor
<
a < b
lt(a, b)
Returns true if a is less than b.
say (3 < 5 ) #=> true
say (10 < 7) #=> false
Aliases: lt
<=
a <= b
le(a, b)
Returns true if a is less than or equal to b.
say (3 <= 5) #=> true
say (5 <= 5) #=> true
Aliases: ≤, le
<=>
a <=> b
cmp(a, b)
Three-way comparison: returns -1 if a < b, 0 if a == b, +1 if a > b.
say (5 <=> 10) #=> -1
say (10 <=> 10) #=> 0
say (15 <=> 10) #=> 1
Aliases: cmp
<~>
a <~> b
approx_cmp(a, b)
approx_cmp(a, b, k)
Approximate comparison of a and b.
Equivalent with:
a.round(k) <=> b.round(k)
When k is omitted, it uses the default floating-point precision to deduce k.
say (0.1f + 0.2f <~> 0.3) #=> 0 (equal once rounded)
Aliases: approx_cmp
==
a == b
eq(a, b)
Returns true if a and b are equal.
say (42 == 42) #=> true
say (1/2 == 0.5) #=> true
Aliases: eq
=~=
a =~= b
Returns true if a and b are approximately equal to each other.
Aliases: ≅, approx_eq
>
a > b
gt(a, b)
Returns true if a is greater than b.
say (10 > 7) #=> true
say (3 > 5) #=> false
Aliases: gt
>=
a >= b
ge(a, b)
Returns true if a is greater than or equal to b.
say (10 >= 7) #=> true
say (7 >= 7) #=> true
Aliases: ≥, ge
^..
a ^.. b
Creates a reversed exclusive-inclusive RangeNum object, from a-1 down to b.
Equivalent with:
RangeNum(a-1, b, -1)
Aliases: xdownto
abs
n.abs
The absolute value of n. Works for integers, rationals, floating-points and complex numbers.
say abs(-42) #=> 42
say abs(-1/3) #=> 1/3
acmp
acmp(a,b)
Absolute comparison of a and b, defined as:
abs(a) <=> abs(b)
say acmp(-10, 3) #=> 1
say acmp(-3, 10) #=> -1
approx_ge
approx_ge(a, b)
approx_ge(a, b, k)
True if a is approximately greater than or equal to b.
Equivalent with:
a.round(k) >= b.round(k)
approx_gt
approx_gt(a, b)
approx_gt(a, b, k)
True if a is approximately greater than b.
Equivalent with:
a.round(k) > b.round(k)
approx_le
approx_le(a, b)
approx_le(a, b, k)
True if a is approximately less than or equal to b.
Equivalent with:
a.round(k) <= b.round(k)
approx_lt
approx_lt(a, b)
approx_lt(a, b, k)
True if a is approximately less than b.
Equivalent with:
a.round(k) < b.round(k)
approx_ne
approx_ne(a, b)
approx_ne(a, b, k)
True if a is approximately different than b.
Equivalent with:
a.round(k) != b.round(k)
divides
a.divides(b)
a `divides` b
Returns true if a divides b.
say 3.divides(15) #=> true
divmod
divmod(a, b)
divmod(a, b, m)
When only two arguments are provided, it returns (a//b, a%b).
say [divmod(23, 10)] #=> [2, 3]
When three arguments are given, it does integer modular division: (a/b) % m.
say divmod(43, 97, 127) # == (43 * invmod(97, 127))%127
geometric_sum
geometric_sum(n,r)
Geometric sum: r^0 + r^1 + ... + r^n, using the following formula:
geometric_sum(n, r) = (r^(n+1) - 1) / (r - 1)
Example:
say geometric_sum(5, 8) # 8^0 + 8^1 + 8^2 + 8^3 + 8^4 + 8^5 = 37449
hypot
hypot(x,y)
The value of the hypotenuse for catheti x and y, defined as:
sqrt(x**2 + y**2)
Also defined for complex numbers.
say hypot(3, 4) #=> 5
iabs
iabs(n)
Integer absolute value, by first truncating n to an integer.
say iabs(-4.7) #=> 4
Aliases: absint
iadd
iadd(a,b)
Integer addition, by first truncating a and b to integers: int(a) + int(b).
say iadd(2.9, 3.1) #=> 5
Aliases: addint
icmp
x.icmp(y)
Integer comparison, by first truncating x and y to integers.
say 5.5.icmp(5.1) #=> 0 (both truncate to 5)
Aliases: cmpint
imod
imod(a,m)
Integer remainder of a when divided by m, by first truncating a and m to integers: int(a) % int(m).
say imod(17.9, 5) #=> 2
Aliases: modint
imul
imul(a,b)
Integer multiplication, by first truncating a and b to integers: int(a) * int(b).
say imul(2.9, 3.9) #=> 6
Aliases: mulint
ineg
ineg(n)
Integer negation, by first truncating n to an integer.
say ineg(4.7) #=> -4
Aliases: negint
inv
inv(n)
Multiplicative inverse of n: 1/n.
say inv(4) #=> 1/4
say inv(1/3) #=> 3
is_divisible
n %% k
n.is_divisible(k)
Returns true if n is divisible by k. False otherwise.
say 15.is_divisible(5) #=> true
say (17 %% 5) #=> false
Aliases: %%, is_divisible_by, is_div
isub
isub(a,b)
Integer subtraction, by first truncating a and b to integers: int(a) - int(b).
say isub(10.9, 3.1) #=> 7
Aliases: subint
max
max(...)
Returns the maximum value from a list of numbers.
say max(3, 7, 2, 9, 1) #=> 9
Aliases: vecmax
min
min(...)
Returns the smallest value from a list of numbers.
say min(3, 7, 2, 9, 1) #=> 1
Aliases: vecmin
mod
n % k
mod(n, k)
Returns the remainder of n divided by k.
say (17 % 5) #=> 2
say (-17 % 5) #=> 3
say 100.mod(7) #=> 2
Aliases: %
neg
x.neg
Negates the sign of x (equivalent with: -x).
say 5.neg #=> -5
say (-5 -> neg) #=> 5
prod
prod(...)
Returns the product of a given list of numbers.
say prod(1, 2, 3, 4, 5) #=> 120
Aliases: Π, vecprod
remdiv
n.remdiv(k)
Removes all occurrences of the divisor k from integer n.
Equivalent with:
n / k**valuation(n,k)
Aliases: remove
sgn
sgn(x)
Returns the sign of x, as -1, 0 or 1.
Defined as:
x / abs(x) # for x != 0
say sgn(-42) #=> -1
say sgn(0) #=> 0
say sgn(1/3) #=> 1
Aliases: sign
smod
x.smod(m)
Returns the residual mod m such that it is within half of the modulus.
say smod(1, 6) #=> 1
say smod(4, 6) #=> -2
sum
sum(...)
Returns the sum of a given list of numbers.
say sum(1, 2, 3, 4, 5) #=> 15
Aliases: Σ, vecsum
sum_remainders
sum_remainders(n, v)
Returns the following sum: Sum_{k=1..n} v % k, computed in O(sqrt(v)) steps.
say 20.of {|n| sum_remainders(n, n) } #=> OEIS: A004125
say 20.of {|n| sum_remainders(n, n.prime) } #=> OEIS: A099726
Negative values of v are also supported.
BITWISE OPERATIONS
&
a & b
and(a, b)
Performs bitwise AND operation on integers a and b.
say (0b1100 & 0b1010) #=> 8 (0b1000)
say 12.and(10) #=> 8
Aliases: and
<<
a << b
shift_left(a, b)
Left shifts a by b bits. Equivalent to a × 2^b for integers.
say (5 << 3) #=> 40 (5 × 8)
say shift_left(1, 10) #=> 1024
Aliases: lsft, shift_left
>>
a >> b
shift_right(a, b)
Right shifts a by b bits. Equivalent to floor(a / 2^b) for integers.
say (40 >> 3) #=> 5 (40 / 8)
say shift_right(1024, 10) #=> 1
Aliases: rsft, shift_right
^
a ^ b
xor(a, b)
Performs bitwise XOR operation on integers a and b.
say (0b1100 ^ 0b1010) #=> 6 (0b0110)
say 12.xor(10) #=> 6
Aliases: xor
bit
n.bit(k)
n.getbit(k)
Returns 1 if bit k of n is set, and 0 if it is not set.
Return nil when n cannot be truncated to an integer or when k is negative.
say getbit(0b1001, 0) # 1
say getbit(0b1000, 0) # 0
Aliases: getbit, testbit
bit_scan0
n.bit_scan0
n.bit_scan0(k)
Scan n, starting from bit index k, towards more significant bits, until a 0-bit is found.
When k is omitted, k=0 is assumed.
Returns nil if n cannot be truncated to an integer or if k is negative.
say 0b1011.bit_scan0 #=> 2
bit_scan1
n.bit_scan1
n.bit_scan1(k)
Scan n, starting from bit index k, towards more significant bits, until a 1-bit is found.
When k is omitted, k=0 is assumed.
Returns nil if n cannot be truncated to an integer or if k is negative.
say 0b1100.bit_scan1 #=> 2
bits
n.bits
Returns the binary digits of n.
The bits are ordered from the most significant bit to the least significant bit.
say 1234.bits #=> [1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0]
Equivalent with:
n.digits(2).flip
clearbit
n.clearbit(k)
Set the k-th bit of integer n to 0.
say clearbit(0b1001, 0).as_bin #=> 1000
say clearbit(0b1100, 2).as_bin #=> 1000
flipbit
flipbit(n,k)
Flip the value of the k-th bit of integer n.
say flipbit(0b1000, 0).as_bin #=> 1001
say flipbit(0b1001, 0).as_bin #=> 1000
hamdist
hamdist(a,b)
Returns the Hamming distance (number of bit-positions where the bits differ) between integers a and b.
say hamdist(0b1010, 0b0011) #=> 2
lsb
lsb(n)
Returns the index of the least significant bit of n that is nonzero.
say 0b110010101111000000.lsb # 6
msb
msb(n)
Returns the index of the most significant bit of n.
say 0b110010101111000000.msb # 17
popcount
n.popcount
Number of 1's in binary representation of n.
This value is also known as the Hamming weight value.
say 0b1011.popcount #=> 3
Aliases: hammingweight
rotate
rotate(n, k, b=10)
Rotate the digits of n to the left when k is positive or to the right otherwise, in a given base b, or base 10 when no base is given.
say rotate(12345, 2) #=> 34512
say rotate(12345, -1) #=> 51234
setbit
setbit(n,k)
Set the k-th bit of integer n to 1.
say setbit(0b1000, 0).as_bin #=> 1001
say setbit(0b1000, 2).as_bin #=> 1100
|
a | b
or(a, b)
Performs bitwise OR operation on integers a and b.
say (0b1100 | 0b1010) #=> 14 (0b1110)
say 12.or(10) #=> 14
Aliases: or
~
~a
not(a)
Returns the bitwise complement of a.
say as_bin(~0b1010) #=> -1011
say 10.not #=> -11
Aliases: not
TYPE CONVERSION & FORMATTING
as_bin
n.as_bin
Returns a String with the binary representation of n.
say 42.as_bin # "101011"
as_dec
n.as_dec
n.as_dec(k)
Given a rational number n, it returns its decimal expansion as a String object, expanded at k decimal places.
say (1/17 -> as_dec(10)) # 0.05882352941
say (1/17 -> as_dec(30)) # 0.0588235294117647058823529411765
Aliases: as_float
as_frac
n.as_frac
n.as_frac(base)
String-representation of n as fraction.
say 24.as_frac # 24/1
say bernoulli(10).as_frac # 5/66
say bernoulli(12).as_frac(36) # -j7/23u
If n is an integer, it uses 1 for the denominator.
as_hex
n.as_hex
Returns a String representing the integer part of n in hexadecimal (base 16).
say 42.as_hex # "2a"
Returns nil when n cannot be converted to an integer.
as_int
n.as_int
n.as_int(base)
Returns a String containing the integer representation of n in the given base.
The base must be between 2 and 62 and defaults to base 10. The sign is preserved for negative values.
This method first converts n to an integer. Returns nil when that conversion is not possible.
say 255.as_int #=> 255
say 255.as_int(16) #=> ff
say (-255).as_int(16) #=> -ff
as_oct
n.as_oct
Returns a String representing the integer part of n in octal (base 8).
say 42.as_oct # 52
Returns nil when n cannot be converted to an integer.
as_rat
n.as_rat
n.as_rat(base)
Returns a rational string-representation of n in a given base, where the base must be between 2 and 62.
When the base is omitted, it defaults to base 10.
say as_rat(42) # "42"
say as_rat(2/4) # "1/2"
say as_rat(255, 16) # "ff"
Returns nil when n cannot be converted to a rational number.
base
n.base(b)
Returns a String-representation of n in a given base b, which must be between 2 and 62.
say 255.base(16) #=> ff
say 10.base(2) #=> 1010
Aliases: in_base
cfrac
n.cfrac
n.cfrac(k)
Compute k terms of the simple continued-fraction expansion of n.
say sqrt(12).cfrac(6) # [3, 2, 6, 2, 6, 2, 6]
Can also be used to compute very good rational approximations to a given real number:
say Num.pi.cfrac(10).flip.reduce{|a,b| b + 1/a }.as_rat # 4272943/1360120
When k is omitted, it uses the default floating-point precision to deduce k.
Aliases: as_cfrac
chr
n.chr
Convert the integer n into a character.
say 97.chr # "a"
say 9786.chr # "☺"
commify
n.commify
Returns a string with thousands separators inserted in the decimal representation of n.
The sign and any fractional part are preserved.
Example:
say 1000.commify #=> 1,000
say 1e10.commify #=> 10,000,000,000
say (-12345.678).commify #=> -12,345.678
convergents
n.convergents(k)
Returns an array with the continued fraction convergents for a given real number n, where k is the number of convergents to be computed and returned.
say Num.pi.convergents(5) #=> [3, 22/7, 333/106, 355/113, 103993/33102]
de
r.de
r.denominator
Returns the denominator for a rational number r.
say denominator(43/97) #=> 97
Aliases: denominator
digit
n.digit(k, b=10)
Returns the k-th digit of n in a base b.
say 1119.digit(0) #=> 9
say 1181.digit(1) #=> 8
say 1711.digit(2) #=> 7
say 6111.digit(3) #=> 6
say 1234.digit(4) #=> 0
It also supports negative indices:
say 9111.digit(-1) #=> 9
say 1811.digit(-2) #=> 8
say 1234.digit(-42) #=> nil
digital_root
digital_root(n, b=10)
Returns the digital root of n, with respect to base b. (OEIS A010888)
say 30.of { .digital_root } #=> OEIS: A010888
say 30.of { .digital_root(.isqrt+1) } #=> OEIS: A122197
Also known as "repeated digital sum".
Both n and b can be arbitrary large, as long as b > 1.
digits
n.digits(b=10)
Returns the digits of n in base b, ordered from the least significant digit to the most significant digit.
Negative numbers are treated by their absolute value. If b <= 1, it returns an empty array.
say 1234.digits #=> [4, 3, 2, 1]
say 1234.digits(20) #=> [14, 1, 3]
say (-42).digits #=> [2, 4]
say 0.digits #=> [0]
The reverse operation is:
b.digits2num(n.digits(b)) == abs(n)
digits2num
b.digits2num(digits)
Convert an array of digits to a number in the base b.
The array of digits are ordered from the least significant digit to the most significant digit, as returned by n.digits(b).
say 10.digits2num([4,3,2,1]) #=> 1234
Aliases: from_digits
digits_sum
sumdigits(n, b=10)
Sum of base b digits of n.
say sumdigits(1234) #=> 10
say sumdigits(1e5!, 100) #=> 10658934
This is equivalent to:
n.digits(b).sum
Aliases: sum_digits, sumdigits
dump
n.dump
Returns a stringification version of n.
say dump(42) #=> "42"
say dump(3/4) #=> "3/4"
egypt_greedy
egypt_greedy(p/q)
Greedy algorithm for Egyptian fraction expansion (also called the Fibonacci-Sylvester algorithm): at each step, extract the largest unit fraction less than the target and replace the target with the remainder.
say egypt_greedy(9/10) #=> [2, 3, 15]
say egypt_greedy(5/121) #=> [25, 757, 763309, 873960180913, 1527612795642093418846225]
Returns the array of denominators, such that egypt_greedy(p/q).sum{|d| 1/d } equals p/q.
flip
n.flip(base=10)
Returns the reversal of n in base b. When b is not given, it defaults to base 10.
say 20.of { .flip } # A004086
say 20.of { .flip(2) } # A030101
Aliases: reverse
int
int(n)
trunc(n)
Truncate n to an integer (rounding towards zero).
say int(4.7) #=> 4
say int(-4.7) #=> -4
say int(7/2) #=> 3
Aliases: to_i, to_int, trunc
len
n.len(b=10)
Returns the number of digits of the integer part of n in a given base..
say 5040.len #=> 4
say 5040.len(2) #=> 13
Aliases: size, length
lift
n.lift
Returns the self object.
new
Number(string, base=10)
Num.new(string, base=10)
Create a new Number object, given a string and a base.
say Number("42") #=> 42
say Number("101", 2) #=> 5
say Number("ff", 16) #=> 255
Aliases: call
nu
r.nu
r.numerator
Returns the numerator of rational number r.
say numerator(43/97) #=> 43
Aliases: numerator
nude
nude(r)
Returns a list with the numerator and the denominator of a rational number r.
say [nude(43/97)] #=> [43, 97]
numify
n.numify
Returns a raw native number representation for the self-number.
Can be used for assigning values to Num!PREC variable.
local Num!PREC = 42.numify # set precision to 42 bits
say sqrt(2) # 1.414213562
Native numbers can also be used when indexing an array:
var arr = [42, 43, 44]
var idx = 2.numify
say arr[idx] #=> 44
Although this may or may not be actually faster.
rat
x.rat
Convert x to a rational number. Returns NaN when this conversion is not possible.
say 0.5.rat #=> 1/2
say 4.rat #=> 4
Aliases: to_r, to_rat
rat_approx
x.rat_approx
x.rat_approx(max_den)
Given a real number x, it returns a very good (sometimes exact) rational approximation to n, computed with continued fractions.
say rat_approx(3.14).as_frac #=> 22/7
say rat_approx(zeta(-5)).as_frac #=> -1/252
It also accepts and optional argument max_den, returning the best rational approximation to <x> with denominator q <= max_den.
say rat_approx(Num.pi, 1e4).as_frac #=> 355/113
say rat_approx(Num.pi, 1e9).as_frac #=> 2549491779/811528438
Returns NaN when x is not a real number.
Aliases: best_rational_approx
to_f
x.to_f
Convert x to a floating-point value number.
say to_f(1/3) #=> 0.333333333333333333333333333333333333333333333333
say 42.to_f #=> 42
Aliases: f, float, to_float
to_n
x.to_n
Fixed-point function: returns x.
Aliases: to_num
to_poly
x.to_poly
Converts x to a Polynomial object.
to_s
x.to_s
Converts x to a String object.
Aliases: to_str
SEARCH, RANGES & ITERATION
bsearch
bsearch(n, {...})
bsearch(a, b, {...})
Binary search from to 0 to n, or from a to b, which can be any arbitrary large integers.
The last argument is a block which does the comparisons.
This function finds a value k such that f(k) = 0. Returns nil otherwise.
say bsearch(20, {|k| k*k <=> 49 }) #=> 7 (7*7 = 49)
say bsearch(3, 1000, {|k| k**k <=> 3125 }) #=> 5 (5**5 = 3125)
bsearch_ge
bsearch_ge(n, {...})
bsearch_ge(a, b, {...})
Binary search from to 0 to n, or from a to b, which can be any arbitrary large integers.
The last argument is a block which does the comparisons.
This function finds a value k such that f(k-1) < 0 and f(k) >= 0. Returns nil otherwise.
bsearch_ge(1e6, { .exp <=> 1e+9 }) # 21 (exp( 21) >= 1e+9)
bsearch_ge(-1e6, 1e6, { .exp <=> 1e-9 }) # -20 (exp(-20) >= 1e-9)
bsearch_le
bsearch_le(n, {...})
bsearch_le(a, b, {...})
Binary search from to 0 to n, or from a to b, which can be any arbitrary large integers.
The last argument is a block which does the comparisons.
This function finds a value k such that f(k) <= 0 and f(k+1) > 0. Returns nil otherwise.
bsearch_le(1e6, { .exp <=> 1e+9 }) # 20 (exp( 20) <= 1e+9)
bsearch_le(-1e6, 1e6, { .exp <=> 1e-9 }) # -21 (exp(-21) <= 1e-9)
bsearch_max
bsearch_max(n, {...})
bsearch_max(a,b, {...})
Binary search, returning the largest integer value in the range a..b that satisfies the given comparison function.
say bsearch_max(1, 1e6, {|k| pi(k) <=> 100 }) #=> 546
where:
n = 546 is the largest value satisfying pi(n) <= 100
bsearch_min
bsearch_min(n, {...})
bsearch_min(a,b, {...})
Binary search, returning the smallest integer value in the range a..b that satisfies the given comparison function.
say bsearch_min(1, 1e6, {|k| pi(k) <=> 100 }) #=> 541
where:
n = 541 is the smallest value satisfying pi(n) >= 100
bsearch_solve
bsearch_solve(n, {...})
bsearch_solve(a,b, {...})
It computes the inverse of any continuous function, given the range that includes the inverse value.
For floating-point values, the approx_cmp(a,b) method (or the `<~>` operator) is recommended to be used for comparisons.
say bsearch_inverse(100, {|x| exp(x) <~> 2 }) # solution to x for: exp(x) = 2
say bsearch_inverse(200, {|x| x**2 <=> 43 }) # solution to x for: x^2 = 43
say bsearch_inverse(-10, 10, {|x| x**3 <~> -43 }) # solution to x for: x^3 = -43
say bsearch_inverse(300, 500, {|x| Li(x) <~> 100 }) # solution to x for: Li(x) = 100
This method can also be used in computing approximations to some integer-specific functions:
var n = 100000
var v = 2*int(n*log(n) / log(log(n)))
say nth_semiprime(n) #=> 459577
say bsearch_inverse(v, {|x| semiprime_count(x) <=> n }) #=> 459577.93302154541015625
Aliases: bsearch_inverse
by
n.by { ... }
Returns an array with n elements >= 0 that satisfy the provided block of code.
say 10.by { .is_prime } # first 10 primes
say 10.by { .is_square } # first 10 squares
defs
n.defs { ... }
Returns an array with the first n defined values returned by the given block. The block is called with k = 0,1,2,...
10.defs {|k| k.is_prime ? k+1 : nil } # array of p+1 for the first 10 primes p
downto
a.downto(b, step=1)
Returns a reverse range from a down to b, with an optional stepping value.
say 10.downto(1) #=> RangeNum(10, 1, -1)
say 10.downto(1, 2) #=> RangeNum(10, 1, -2)
nd
n.st({...})
n.nd({...})
n.rd({...})
n.th({...})
It returns the n-th value for which the provided block evaluates to a true value, starting counting from 0.
say 100.th { .is_prime } # 100-th prime
Also aliased as .st, .nd and .rd:
say 1.st { .is_prime } # first prime
say 2.nd { .is_prime } # second prime
say 3.rd { .is_prime } # third prime
Aliases: rd, st, th
of
n.of {|k| ... }
Returns an array with n elements mapped to the given block. The block is called with k = 0,1,2...,n-1.
say 10.of { _*_ } #=> first 10 squares
say 10.of { .fib } #=> first 10 Fibonacci numbers
range
range(n)
range(a,b)
range(a,b,step)
Creates a new RangeNumber object.
say range(10) #=> RangeNum(0, 9, 1)
say range(1, 10) #=> RangeNum(1, 10, 1)
say range(1, 10, 2) #=> RangeNum(1, 10, 2)
run
run(a,b)
Given two arguments, it returns the second one.
say run(1, 42) #=> 42
times
n.times {|k| ... }
Call a given block of code n times with k = 0,1,2,...,n-1.
5.times {|k| say "k = #{k}" }
ROUNDING, ROOTS, POWERS & LOGARITHMS
cbrt
n.cbrt
Cube root of n, as a (complex) floating-point value.
say cbrt(27) #=> 3
say cbrt(-8) #=> 1 + 1.73205080756887729352744634150587236694280525381i
ceil
n.ceil
Round n towards positive Infinity.
say ceil(2.1) #=> 3
say ceil(-2.1) #=> -2
Aliases: ceiling
cube
cube(x)
Returns the cube of x. Equivalent with x**3.
say cube(5) #=> 125
exp
exp(x)
exp(b, x)
Exponential function: e^x.
When two arguments are given, it does floating-point exponentiation: b^x.
say exp(1) #=> 2.718281828459045
say exp(2, 10) #=> 1024
exp10
exp10(x)
Exponential function: 10^x.
say exp10(3) #=> 1000
exp2
exp2(x)
Exponential function: 2^x.
say exp2(10) #=> 1024
expnorm
expnorm(n, b=10)
Returns exp(n) normalized in the range [0,1). The base b can be any value != {0,1}.
say expnorm(log(2) * 20996011) #=> 0.125976895450330105020494309574...
say exp(log(10!)) #=> 3628800
say expnorm(log(10!)) #=> 0.36288
say expnorm(log(10!), 2) #=> 0.86517333984375
say 3628800.base(2) #=> 1101110101111100000000
say 0.86517333984375.base(2) #=> 11011101011111/100000000000000
Complex numbers are also supported:
say expnorm(log(-1)) #=> 0.06682015101903....+0.074398033695749....i
say expnorm(log(-1234)).abs #=> 0.1234
Equivalent with:
exp(n) / b**k # for some positive integer value of k
floor
floor(x)
Round x towards -Infinity.
say floor( 2.5) # 2
say floor(-2.5) # -3
icbrt
icbrt(n)
Integer cube root of n.
say icbrt(27) #=> 3
say icbrt(-8) #=> -2
Aliases: cbrtint
idiv_ceil
idiv_ceil(a,b)
Integer division of integers a and b, rounded towards +Infinity.
When a and b are integers, this is equivalent with:
ceil(a/b)
say idiv_ceil(7, 2) #=> 4
say idiv_ceil(-7, 2) #=> -3
Aliases: cld
idiv_round
idiv_round(a,b)
Integer division of integers a and b, rounded towards nearest integer.
When a and b are integers, this is equivalent with:
floor(a/b + 1/2)
say idiv_round(7, 2) #=> 4
say idiv_round(5, 2) #=> 3
Aliases: rdd
idiv_trunc
idiv_trunc(a,b)
Integer division of integers a and b, rounded towards 0.
When a and b are integers, this is equivalent with:
trunc(a/b)
say idiv_trunc(7, 2) #=> 3
say idiv_trunc(-7, 2) #=> -3
Aliases: trd
ilog
ilog(n,b)
Integer logarithm of n to base b, satisfying:
b**ilog(n,b) <= n < b**(ilog(n,b)+1)
say ilog(100, 3) #=> 4 (3**4 = 81 <= 100 < 3**5 = 243)
Aliases: logint
ilog10
ilog10(n)
Integer logarithm of n to base 10, equivalent to:
ilog(n,10)
say ilog10(999) #=> 2
say ilog10(1000) #=> 3
ilog2
ilog2(n)
Integer logarithm of n to base 2, equivalent to:
ilog(n,2)
say ilog2(1023) #=> 9
say ilog2(1024) #=> 10
ipow
ipow(b,n)
Integer exponentiation: b^n.
say ipow(2, 10) #=> 1024
Aliases: powint
ipow10
ipow10(n)
Integer exponentiation: 10^n.
say ipow10(6) #=> 1000000
ipow2
ipow2(n)
Integer exponentiation: 2^n.
say ipow2(10) #=> 1024
iroot
n.iroot(k)
Integer k-th root of n: the largest integer r such that r**k <= n.
say iroot(100, 2) #=> 10
say iroot(30, 3) #=> 3
Aliases: rootint
irootrem
n.irootrem(k)
Returns a list with the integer k-th root of n and k-th root remainder of n.
say [30.irootrem(3)] #=> [3, 3]
Equivalent with:
(n.iroot(k), n - n.iroot(k)**k)
isqrt
n.isqrt
Integer square root of n: the largest integer r such that r**2 <= n.
say isqrt(100) #=> 10
say isqrt(99) #=> 9
Aliases: sqrtint
isqrtrem
n.isqrtrem
Returns a list with the integer square root of n and the square root remainder of n.
say [99.isqrtrem] #=> [9, 18]
Equivalent with:
(n.isqrt, n - n.isqrt**2)
lgrt
lgrt(x)
Returns the "logarithm-root" of x, such that lgrt(x) ** lgrt(x) =~= x.
say lgrt(100) #=> 3.59728502354041750549765225178229
say lgrt(-100) #=> 3.70202936660214594290193962952737+1.34823128471151901327831464969872i
ln
x.ln
Natural logarithm of x.
say ln(exp(1)) #=> 1
say ln(1) #=> 0
ln2
Num.ln2
Returns the natural logarithm of 2 constant.
say Num.ln2 #=> 0.6931471805599453
log
log(x)
log(x, b)
Natural logarithm of x to base e, or to a given base b.
say log(exp(1)) #=> 1
say log(100, 10) #=> 2
log10
x.log10
Logarithm of x to base 10.
say log10(1000) #=> 3
log2
x.log2
Logarithm of x to base 2.
say log2(1024) #=> 10
perfect_root
n.perfect_root
Returns the smallest root r of n for which there exists an integer k, such that: n = r^k.
say perfect_root(15**5) #=> 15
root
root(n,k)
The k-th root of n, defined as n**(1/k).
say root(8, 3) #=> 2
say root(16, 4) #=> 2
round
round(x,k=0)
Rounds x to the k-th decimal place.
A negative argument rounds that many digits after the decimal point, while a positive argument rounds that many digits before the decimal point.
say round(1234.567) #=> 1235
say round(1234.567, 2) #=> 1200
say round(3.123+4.567i, -2) #=> 3.12+4.57*i
Aliases: roundf
sqr
sqr(x)
Returns the square of x. Equivalent with x*x.
say sqr(9) #=> 81
Aliases: square
sqrt
sqrt(x)
Returns the square root of x. Equivalent with x**(1/2).
say sqrt(16) #=> 4
say sqrt(2) #=> 1.414213562373095
say sqrt(-1) #=> 1i
sqrt_cfrac
n.sqrt_cfrac
n.sqrt_cfrac(k)
Returns the expansion of the continued fraction for square root of n.
When an additional argument k is specified, it includes only the first k terms from the expansion period.
say 28.sqrt_cfrac #=> [5, 3, 2, 3, 10]
say 28.sqrt_cfrac(2) #=> [5, 3, 2]
say 12345678910.sqrt_cfrac(10) #=> [111111, 9, 26, 1, 2, 3, 1, 1, 2, 8, 1]
sqrt_cfrac_period
n.sqrt_cfrac_period
Returns the period of the expansion of the continued fraction for square root of n.
say 28.sqrt_cfrac_period #=> [3, 2, 3, 10]
sqrt_cfrac_period_each
n.sqrt_cfrac_period_each { ... }
n.sqrt_cfrac_period_each({ ... }, max_iter)
Iterate over the period of the expansion of the continued fraction for square root of n.
28.sqrt_cfrac_period_each {|r| say r }
sqrt_cfrac_period_len
n.sqrt_cfrac_period_len
Returns the length of the period of continued fraction for square root of n. (OEIS A003285)
say sqrt_cfrac_period_len(28) #=> 4
sqrtQ
sqrtQ(n)
Returns a Quadratic object, representing sqrt(n).
say sqrtQ(2)**2 #=> Quadratic(2, 0, 2, 0)
TRIGONOMETRIC & HYPERBOLIC FUNCTIONS
acos
n.acos
Inverse cosine of n in radians.
say acos(1) #=> 0
say acos(0) #=> 1.570796326794897
acosh
n.acosh
Inverse hyperbolic cosine of n.
say acosh(1) #=> 0
acot
n.acot
Inverse cotangent of n in radians.
say acot(1) #=> 0.7853981633974483
acoth
n.acoth
Inverse hyperbolic cotangent of n.
say acoth(2) #=> 0.5493061443340548
acsc
n.acsc
Inverse cosecant of n in radians.
say acsc(1) #=> 1.570796326794897
acsch
n.acsch
Inverse hyperbolic cosecant of n.
say acsch(1) #=> 0.881373587019543
asec
n.asec
Inverse secant of n in radians.
say asec(1) #=> 0
asech
n.asech
Inverse hyperbolic secant of n.
say asech(1) #=> 0
asin
n.asin
Inverse sine of n in radians.
say asin(1) #=> 1.570796326794897
asinh
n.asinh
Inverse hyperbolic sine of n.
say asinh(0) #=> 0
atan
n.atan
Inverse tangent of n in radians.
say atan(1) #=> 0.7853981633974483
atan2
atan2(a, b)
Four-quadrant inverse tangent of a and b (the angle, in radians, of the point (b,a)).
say atan2(1, 1) #=> 0.7853981633974483
say atan2(1, -1) #=> 2.356194490192345
atanh
n.atanh
Inverse hyperbolic tangent of n.
say atanh(0) #=> 0
cos
cos(x)
Trigonometric cosine function.
say cos(0) #=> 1
say cos(Num.pi) #=> -1
cosh
cosh(x)
Hyperbolic cosine function.
say cosh(0) #=> 1
cot
cot(x)
Trigonometric cotangent function.
say cot(Num.pi/4) #=> 1
coth
coth(x)
Hyperbolic cotangent function.
say coth(1) #=> 1.313035285499331
csc
csc(x)
Trigonometric cosecant function.
say csc(Num.pi/2) #=> 1
csch
csch(x)
Hyperbolic cosecant function.
say csch(1) #=> 0.8509181282393215
deg2rad
deg2rad(x)
Convert degrees to radians.
say deg2rad(180) #=> 3.14159...
rad2deg
rad2deg(x)
Convert radians to degrees.
say rad2deg(Num.pi) #=> 180
sec
sec(x)
Trigonometric secant function.
say sec(0) #=> 1
sech
sech(x)
Hyperbolic secant function.
say sech(0) #=> 1
sin
sin(x)
Trigonometric sine function.
say sin(0) #=> 0
say sin(Num.pi/2) #=> 1
sin_cos
sin_cos(x)
Returns a list with the values (sin(x), cos(x)).
say [sin_cos(0)] #=> [0, 1]
sinh
sinh(x)
Hyperbolic sine function.
say sinh(0) #=> 0
tan
tan(x)
Trigonometric tangent function.
say tan(0) #=> 0
say tan(Num.pi/4) #=> 1
tanh
tanh(x)
Hyperbolic tangent function.
say tanh(0) #=> 0
SPECIAL FUNCTIONS & CONSTANTS
agm
agm(a, b)
Arithmetic-geometric mean of a and b.
say agm(1, sqrt(2)) #=> 1.198140234735592
ai
x.ai
Ai(x)
Airy function of the first kind: Ai(x).
Aliases: airy
bessel_j
bessel_j(x, n)
First order Bessel function: J_n(x).
say bessel_j(1, 0) #=> 0.7651976865579666
bessel_y
bessel_y(x, n)
Second order Bessel function: Y_n(x).
say bessel_y(1, 0) #=> 0.08825696421567696
beta
beta(a, b)
The beta function (also called the Euler integral of the first kind).
Defined as:
beta(a, b) = gamma(a)*gamma(b) / gamma(a+b)
say beta(2, 3) #=> 1/12
CatalanG
Num.CatalanG
Returns the Catalan constant:
say Num.CatalanG #=> 0.915965594177219015054603514932384110774149374282
Aliases: C
digamma
digamma(x)
The digamma function, defined as: Gamma'(x)/Gamma(x).
say digamma(1) #=> -0.5772156649015329
Aliases: Ψ
e
Num.e
Returns the e mathematical constant:
say Num.e #=> 2.718281828459045
ei
ei(x)
Exponential integral function.
say ei(1) #=> 1.895117816355937
Aliases: eint
erf
erf(x)
The Gauss error function.
say erf(1) #=> 0.8427007929497149
erfc
erfc(x)
The complementary error function.
say erfc(1) #=> 0.1572992070502851
eta
eta(s)
The Dirichlet eta function, defined as:
eta(s) = (1 - 2^(1-s)) * zeta(s)
Aliases: η
EulerGamma
Num.EulerGamma
Returns the Euler–Mascheroni constant: 0.5772156649...
Aliases: γ, y
gamma
gamma(n)
Num.gamma
When called as Num.gamma, it returns the Euler-Mascheroni constant:
say Num.gamma #=> 0.5772156...
When given a real numeric value, it computes the gamma function as a floating-point value. For positive integers, it satisfies the identity gamma(n) = (n-1)!.
say gamma(6) #=> 120
say gamma(1/2) #=> 1.7724538...
Aliases: Γ
harm
harmonic(n)
harmonic(n, k)
Returns the n-th Harmonic number H_n. The harmonic numbers are the sum of reciprocals of the first n natural numbers: 1 + 1/2 + 1/3 + ... + 1/n.
say harmonic(10).as_rat # 7381/2520
When an additional argument is given, it returns the n-th Harmonic number of the k-th order.
say harmonic(10, 2).as_rat # 55991/2520
Aliases: harmfrac, harmonic, harmonic_number
harmreal
harmreal(n)
harmreal(n, k)
Returns the n-th Harmonic number H_n as a floating-point value, defined as:
harmreal(n) = digamma(n+1) + γ
where γ is the Euler-Mascheroni constant.
When an additional argument is given, it returns the n-th Harmonic number of the k-th order.
hclassno
hclassno(n)
Returns the Hurwitz-Kronecker class number.
say 30.of { .hclassno.nu } # OEIS: A058305
say 30.of { .hclassno.de } # OEIS: A058306
say 30.of { 12 * .hclassno } # OEIS: A259825
ellcard
ellcard(A, B, p)
Returns the number of points on the elliptic curve:
E : y² = x³ + Ax + B
over the finite field F_p, including the point at infinity.
The modulus p must be a positive prime. The curve is assumed to be nonsingular, that is:
4A³ + 27B² ≠ 0 (mod p).
Example:
say ellcard(2, 3, 5) # => 7
say ellcard(2, 3, 7) # => 6
say ellcard(0, 1, 11) # => 12
By Hasse's theorem, the returned value always satisfies:
|#E(F_p) - (p + 1)| ≤ 2√p
Aliases: elliptic_curve_cardinality
lambert_w
lambert_w(x)
The Lambert-W function. When the value of x is less than -1/e, it returns a complex number.
It also accepts a complex number as input.
Identities (assuming x>0):
LambertW(exp(x)*x) = x
LambertW(log(x)*x) = log(x)
lgamma
lgamma(x)
Natural logarithm of abs(Γ(x)).
Aliases: gamma_abs_log
li
li(x)
Returns the logarithmic integral of x.
say 100.li # prints: 30.12614158...
li2
li2(x)
Dilogarithm function, defined as the integral of -log(1-t)/t from 0 to x.
lnbern
lnbern(n)
lnbern(n,x)
Returns the natural logarithm of the n-th Bernoulli number.
When a second argument x is given, it returns the natural logarithm of the n-th Bernoulli polynomial, evaluated at x:
log(B_n(x)) # as a floating-point number
This is usually faster than log(bernreal(n,x)) for large n, but it may be inaccurate in precision in the least significant digits for certain inputs.
Aliases: bern_log, lnbernreal, bernoulli_log
lngamma
lngamma(x)
Natural logarithm of Γ(x).
say lngamma(6) #=> 4.787491742782046
Aliases: gamma_log
mone
Num.mone
Returns the -1 value.
say Num.mone #=> -1
nan
Num.nan
Returns the Not-a-Number special value (NaN).
say Num.nan #=> NaN
say (Num.nan == Num.nan) #=> false
inf
Num.inf
Returns the positive Infinity special floating-point value (Inf).
say Num.inf #=> Inf
say (1 / Num.inf) #=> 0
ninf
Num.ninf
Returns the negative infinity special value (-Inf).
say Num.ninf #=> -Inf
one
Num.one
Returns the 1 value.
say Num.one #=> 1
pi
pi(n)
pi(a,b)
Num.pi
Returns the PI numerical value:
say Num.pi #=> 3.1415...
When applied on a Number object (as n.pi or pi(n)), it returns the number of primes <= n:
say 100.pi #=> number of primes <= 100
say pi(100) #=> 25
When an additional argument is given, it returns the number of primes in the range a..b:
say pi(50, 100) # number of primes in the range 50..100
Aliases: π
zero
Num.zero
Returns the number 0.
say Num.zero #=> 0
zeta
zeta(s)
The Euler-Riemann zeta function. It is currently defined only for real arguments.
say zeta(2) #=> 1.644934...
say zeta(4) #=> 1.082323...
Aliases: ζ
COMPLEX NUMBERS
arg
z.arg
z.angle
z.phase
Returns the argument (phase angle) of the complex number in radians.
say arg(1+1i) #=> 0.7853981633974483
cadd
cadd(a,b,x,y)
Complex arithmetic addition, defined as:
cadd(a,b,x,y) #=> (a+x, b+y)
Aliases: complex_add
cdiv
cdiv(a,b,x,y)
Complex arithmetic division, defined as:
cdiv(a,b,x,y) #=> ((a*x + b*y)/(x*x + y*y), (b*x - a*y)/(x*x + y*y))
Aliases: complex_div
cinv
cinv(a,b)
Complex arithmetic inversion, defined as:
cinv(a,b) #=> (a/(a*a + b*b), (-b)/(a*a + b*b))
Aliases: complex_inv
cinvmod
cinvmod(a,b,m)
Complex modular inversion modulo m: returns a pair of integers (x,y) such that:
cmod(cmul(a,b,x,y), m) == (1, 0)
Aliases: complex_invmod
cis
cis(x)
Euler's formula applied on x, defined as:
cis(x) = cos(x) + sin(x)*i
cmod
cmod(a,b,m)
Complex arithmetic modular operation, defined as:
cmod(a,b,m) #=> (a%m, b%m)
Aliases: complex_mod
cmul
cmul(a,b,x,y)
Complex arithmetic multiplication, defined as:
cmul(a,b,x,y) #=> (a*x - b*y, a*y + b*x)
Aliases: complex_mul
complex
n.complex
complex(a,b)
Converts n to a complex number, or creates a complex number from a and b.
say complex(3, 4) #=> 3+4i
This is equivalent with:
say Complex(3, 4) #=> 3+4i
complex_cmp
complex_cmp(a,b,x,y)
Complex number comparison, defined as:
(a <=> x) || (b <=> y)
complex_ipow
complex_ipow(a,b,n)
Complex integer exponentiation: returns (x,y) such that x+y*i = (a+b*i)^n.
say [complex_ipow(3,4,5)] #=> [-237, -3116]
conj
conj(x)
Complex conjugate of x. For real integers, this is a fixed-point function.
say conj(3+4i) #=> 3 - 4i
say 5.conj #=> 5
cpow
cpow(a,b,n)
Computes (a + b*i)^n, where a,b are real numbers and n is an integer. Returns the real and imaginary part as a list.
say [cpow(3, 4, 10)] #=> [-9653287, 1476984]
Aliases: complex_pow
cpowmod
cpowmod(a,b,n,m)
Efficiently computes (a + b*i)^n mod m, where a,b,n,m are all integers. Returns the real and imaginary part as a list.
say [complex_powmod(3, 4, 1000, 1e6)] #=> [585313, 426784]
Aliases: complex_powmod
csub
csub(a,b,x,y)
Complex arithmetic subtraction, defined as:
csub(a,b,x,y) #=> (a-x, b-y)
Aliases: complex_sub
i
x.i
Multiplies x by the imaginary unit i.
say 42.i #=> 42i
say 42i.i #=> -42
im
x.im
The imaginary part of complex number x. Return 0 when x is a real number.
say im(3+4i) #=> 4
say 5.im #=> 0
Aliases: imag, imaginary
is_complex
x.is_complex
Returns true if x is a complex number.
say is_complex(complex(4)) # false (is real)
say is_complex(complex(4i)) # false (is imaginary)
say is_complex(complex(3+4i)) # true
is_imag
x.is_imag
Returns true if x is an imaginary number.
say is_imag(complex(4)) # false (is real)
say is_imag(complex(4i)) # true
say is_imag(complex(3+4i)) # false (is complex)
is_real
x.is_real
Returns true if x is a real number.
say is_real(complex(4)) # true
say is_real(complex(4i)) # false (is imaginary)
say is_real(complex(3+4i)) # false (is complex)
norm
norm(x)
Returns the normalized value of x: abs(x)^2.
say norm(3+4i) #=> 25
say norm(-5) #=> 25
pair
a.pair(b)
Create a new complex number.
Equivalent with:
Complex(a, b)
Aliases: :, pair
parts
x.parts
Returns an array with the real and imaginary parts of x.
say parts(5) #=> [5, 0]
say parts(3+4i) #=> [3, 4]
re
re(z)
Returns the real part of a complex number z.
say re(3+4i) #=> 3
say 5.re #=> 5
Aliases: real
reals
reals(z)
Returns a list with the real and imaginary parts of z.
say [reals(3+4i)] #=> [3, 4]
roots_of_unity
roots_of_unity(n)
Returns an array with the complex n-th roots of 1, as floating-point approximations.
say roots_of_unity(4).map { .round(-5) } #=> [1, 1i, -1, -1i]
MODULAR ARITHMETIC & CONGRUENCES
addmod
addmod(a, b, m)
Modular integer addition: (a+b) % m.
say addmod(43, 97, 127) # == (43+97)%127
addmulmod
addmulmod(a, b, c, m)
Modular operation: (a + b*c) % m.
say addmulmod(43, 97, 2, 127) # == (43 + 97*2) % 127
expmod
powmod(b, n, m)
Modular exponentiation: b^n mod m, where b is an integer or a rational number and n and m are both integers.
say powmod(2, 42, 43) #=> 1
say powmod(3/4, 1234, 4171) #=> 2138
Aliases: powmod
geometric_summod
geometric_summod(n, r, m)
Geometric sum modulo m: r^0 + r^1 + ... + r^n (mod m), using the following formula:
geometric_summod(n, r, m) = ((powmod(r, n+1, m)-1) * invmod(r-1, m)) % m
invmod
n.invmod(m)
Returns the modular inverse of n modulo m.
say 3.invmod(7) #=> 5 (since 3*5 % 7 == 1)
is_congruent
n.is_congruent(a,m)
Returns true when n is congruent to a modulo m.
say 99923.is_congruent(-2, 5) #=> true
say 99923.is_congruent(3, 5) #=> true
Also defined for rationals, floats and complex numbers:
say is_congruent(124, 1/4, 3/4) #=> true
is_primitive_root
n.is_primitive_root(m)
Returns true if n is a primitive root modulo m.
say 3.is_primitive_root(7) #=> true
say 2.is_primitive_root(7) #=> false
dedekind_sum
dedekind_sum(h, k)
Returns the Dedekind sum s(h, k) as an exact rational number.
The Dedekind sum is defined by
s(h, k) = Σ ((n/k)) * ((hn/k))
where the sum is taken over n = 1, 2, ..., k-1, and the sawtooth function is:
((x)) = x - floor(x) - 1/2 if x is not an integer
= 0 otherwise
The second argument k must be a positive integer.
say dedekind_sum(1, 4) # s(1,4) = 1/8
say dedekind_sum(1, 5) # s(1,5) = 1/5
say dedekind_sum(2, 3) # s(2,3) = -1/18
legendre
legendre(a,p)
Returns the Legendre symbol: (a|p).
say legendre(2, 7) #=> 1
say legendre(3, 7) #=> -1
jacobi
jacobi(a,n)
Returns the Jacobi symbol: (a|n).
say jacobi(2, 15) #=> 1
say jacobi(7, 15) #=> -1
kronecker
kronecker(a,n)
Returns the Kronecker symbol: (a|n).
say kronecker(2, 8) #=> 0
say kronecker(5, 8) #=> -1
hilbert
hilbert(a, b, p)
Returns the Hilbert symbol (a, b)_p, whose value is either 1 or -1.
For a prime p, the Hilbert symbol determines whether the quadratic equation
z² = ax² + by²
has a nontrivial solution over the field of p-adic numbers Q_p. It is a fundamental invariant in algebraic number theory, quadratic forms, and local class field theory.
The arguments a and b must be nonzero, and p must be a positive prime. If either a or b is zero, or if p <= 0, the function returns 0.
say hilbert(2, 3, 5) # => 1
say hilbert(2, 3, 2) # => -1
say hilbert(-1, -1, 2) # => -1
say hilbert(-1, -1, 5) # => 1
The Hilbert symbol is symmetric:
hilbert(a, b, p) == hilbert(b, a, p)
and satisfies the multiplicative identities
(ab, c)_p = (a, c)_p * (b, c)_p
(a, bc)_p = (a, b)_p * (a, c)_p
Aliases: hilbert_symbol
coredisc
coredisc(n)
Returns the fundamental discriminant associated with n. The result is obtained from the squarefree kernel of n, preserving the sign of n:
D = core(n) if core(n) ≡ 1 (mod 4)
= 4*core(n) otherwise
The returned value is the discriminant of the quadratic field Q(sqrt(n)), making it useful in algebraic number theory and quadratic forms.
say coredisc(12) #=> 12
say coredisc(20) #=> 5
say coredisc(-5) #=> -20
say coredisc(-12) #=> -3
Aliases: fundamental_discriminant
reduce_quadratic_form
reduce_quadratic_form(A, B, C)
Returns the Gauss-reduced form equivalent to the positive definite binary quadratic form
Ax² + Bxy + Cy²
The input form must be positive definite, that is,
A > 0
B² - 4AC < 0
If these conditions are not satisfied, the function returns an empty array.
The returned form (a, b, c) is properly equivalent to the input form and satisfies the classical reduction conditions:
|b| ≤ a ≤ c,
with the additional tie-breaking rules
b ≥ 0 if |b| = a
b ≥ 0 if a = c
Thus, each equivalence class of positive definite binary quadratic forms has a unique reduced representative.
say reduce_quadratic_form(5, 6, 5) #=> [4, 4, 5]
say reduce_quadratic_form(7, 10, 4) #=> [1, 0, 3]
Reduced quadratic forms play a central role in the theory of binary quadratic forms, ideal class groups, and quadratic fields.
kronecker_delta
kronecker_delta(a,b)
The Kronecker delta function, which returns 1 iff a==b and 0 otherwise.
say kronecker_delta(3, 3) #=> 1
say kronecker_delta(3, 4) #=> 0
Aliases: δ
muladdmod
muladdmod(a, b, c, m)
Modular operation: (a*b + c) % m.
say muladdmod(43, 97, 5, 127) # == (43*97 + 5) % 127
muladdmulmod
muladdmulmod(a, b, c, d, m)
Modular operation: (a*b + c*d) % m.
say muladdmulmod(43, 97, 5, 3, 127) # == (43*97 + 5*3) % 127
mulmod
mulmod(a,b,m)
Modular integer multiplication: (a*b) % m.
say mulmod(43, 97, 127) # == (43*97)%127
mulsubmod
mulsubmod(a, b, c, m)
Modular operation: (a*b - c) % m.
say mulsubmod(43, 97, 5, 127) # == (43*97 - 5) % 127
mulsubmulmod
mulsubmulmod(a, b, c, d, m)
Modular operation: (a*b - c*d) % m.
say mulsubmulmod(43, 97, 5, 3, 127) # == (43*97 - 5*3) % 127
polymod
n.polymod(...)
Returns a list of mod results corresponding to the divisors in given list.
say [120.polymod(10)] # (0, 12)
say [120.polymod(10,10)] # [0, 2, 1]
Particularly useful for:
var (sec, min, hours, days) = seconds.polymod(60, 60, 24)
qnr
qnr(n)
Returns the least quadratic nonresidue of n.
say qnr(17676352761153241) #=> 37
say qnr(172138573277896681) #=> 41
Aliases: quadratic_nonresidue
rootmod
rootmod(a, k, n)
Returns a solution x to the following congruence:
x^k == a (mod n)
Return NaN if a solution does not exist.
say rootmod(2131968,5,10000000000) #=> 7811648
say rootmod(15,3,1000000000000000000117) #=> 72574612502199260377
rootmod_all
rootmod_all(a, k, n)
Returns an array with all the solutions x to the following congruence:
x^k == a (mod n)
If no solution exists, an empty array is returned.
say rootmod_all(243, 5, 1000) #=> [3, 203, 403, 603, 803]
sqrtmod
sqrtmod(a,m)
Modular square root of a, returning a solution r, such that r^2 = a (mod m).
say sqrtmod(544, 800) #=> 288
say sqrtmod(436, 1752) #=> 134
sqrtmod_all
sqrtmod_all(a, n)
Returns an array with all the solutions x to the following congruence:
x^2 == a (mod n)
If no solution exists, an empty array is returned.
say sqrtmod_all(4095, 8469) #=> [1110, 1713, 3933, 4536, 6756, 7359]
submod
submod(a,b,m)
Modular integer subtraction: (a-b) % m.
say submod(43, 97, 127) #=> (43-97)%127
submulmod
submulmod(a, b, c, m)
Modular operation: (a - b*c) % m.
say submulmod(43, 97, 5, 127) # == (43 - 97*5) % 127
znlog
znlog(a, g, m)
Returns the integer k that solves the congruence: a = g^k (mod m).
Returns NaN if a solution is not found.
say znlog(9, 2, 11) #=> 6 (since 2**6 % 11 == 9)
znorder
znorder(a,m)
The smallest positive integer k such that powmod(a, k, m) == 1.
Return NaN if a is not coprime to m.
Aliases: multiplicative_order
znprimroot
znprimroot(n)
The smallest primitive root of (Z/nZ)^*.
COMBINATORICS & PARTITIONS
bell
n.bell
Returns the n-th Bell number.
say 10.bell #=> 115975
Aliases: bell_number
bellmod
bellmod(n, m)
Returns the n-th Bell number modulo m.
say bellmod(10, 1000) #=> 975
binomial
binomial(n,k)
Returns the binomial coefficient for choosing k objects from n objects, also called the "choose" function.
For the usual case of nonnegative integers, it counts the number of ways to choose k objects from n objects.
say binomial(5, 2) #=> 10
say binomial(10, 0) #=> 1
say binomial(5, 8) #=> 0
Aliases: nok
binomialmod
binomialmod(n, k, m)
Returns the binomial coefficient binomial(n,k) modulo m.
say binomialmod(1e10, 1e5, 20!) #=> 286953611424480000
Equivalent with (but much faster):
binomial(n,k) % m
eulerian
eulerian(n, k)
Returns the Eulerian number A(n, k), which counts the number of permutations of {1, 2, ..., n} having exactly k ascents (equivalently, exactly k descents).
say 30.of {|n| eulerian(n, 1) } #=> OEIS: A000295
say 30.of {|n| eulerian(n, 2) } #=> OEIS: A000460
say 10.of {|n| ^n->map {|k| eulerian(n,k) }.flat } #=> OEIS: A008292
The first few rows of the Eulerian triangle are:
1
1
1 1
1 4 1
1 11 11 1
1 26 66 26 1
Aliases: eulerian_number
circular_permutations
n.circular_permutations
n.circular_permutations { ... }
Returns an array of arrays with the circular permutations of the integers in the range 0..n-1, or iterates over the circular permutations when a block is given.
5.circular_permutations {|*a| say a }
combinations
n.combinations(k)
n.combinations(k, { ... })
Returns an array with the k-combinations of the integers in the range 0..n-1, or iterates over the k-combinations when a block is given.
5.combinations(2, {|*a| say a })
combinations_with_repetition
n.combinations_with_repetition(k)
n.combinations_with_repetition(k, { ... })
Returns an array with the k-combinations with repetition of the integers in the range 0..n-1, or iterates over the k-combinations with repetition when a block is given.
5.combinations_with_repetition(2, {|*a| say a })
derangements
n.derangements
Returns an array of arrays with the derangements of the integers in the range 0..n-1, or iterates over the derangements when a block is given.
5.derangements {|*a| say a }
Aliases: complete_permutations
double_factorial
n!!
double_factorial(n)
Double-factorial of n. (OEIS A006882)
say 8.double_factorial #=> 384 (8*6*4*2)
say 7.double_factorial #=> 105 (7*5*3*1)
Aliases: !!, dfac, dfactorial
factorial
n!
n.factorial
Computes the factorial of n: 1*2*3*...*n.
Defined for nonnegative integers.
say 0.factorial #=> 1
say 5.factorial #=> 120
say 10.factorial #=> 3628800
say 100.factorial #=> 93326215443944152681699...
Aliases: !, fac
factorial_sum
factorial_sum(n)
Left factorial of n (OEIS A003422), defined as:
Sum_{k=0..n-1} k!
Example:
say 20.of { .factorial_sum } # OEIS: A003422
Aliases: left_factorial
factorial_valuation
factorial_valuation(n, k)
Returns the number of times n! is divisible by k, where k is either prime or composite.
Equivalent with (but more efficient):
valuation(n!, k)
say factorial_valuation(10, 2) #=> 8 (10! has 2^8 as a factor)
Aliases: factorial_power
factorialmod
factorialmod(n,m)
Returns the factorial of n modulo m.
Equivalent with (but much faster):
factorial(n) % m
say factorialmod(20, 1000) #=> 0
falling_factorial
falling_factorial(n,k)
Falling factorial: (n)_k = n * (n - 1) * ... * (n - k + 1), defined as:
binomial(n, k) * k!
For negative values of k, falling factorial is defined as:
falling_factorial(n, -k) = 1/falling_factorial(n + k, k)
When the denominator is zero, NaN is returned.
say falling_factorial(5, 3) #=> 60 (5*4*3)
farey
farey(n)
Generates the Farey sequence of maximum denominator n.
say farey(5) #=> [0, 1/5, 1/4, 1/3, 2/5, 1/2, 3/5, 2/3, 3/4, 4/5, 1]
farey_neighbors
farey_neighbors(n, p/q)
Returns the neighbors of p/q in the Farey sequence of max denominator n.
say [farey_neighbors(5, 2/5)] #=> [1/3, 1/2]
say [farey_neighbors(2**32, 43/97)] #=> [1903954555/4294967252, 1903954563/4294967270]
fubini
fubini(n)
Returns the n-th Fubini number. (OEIS A000670)
say 10.of { .fubini } #=> OEIS: A000670
Aliases: fubini_number
fubini_numbers
fubini_numbers(n)
Returns an array containing the Fubini numbers with indices in the range 0..n.
say fubini_numbers(5) #=> [1, 1, 3, 13, 75, 541]
hyperfactorial
hyperfactorial(n)
Hyperfactorial of n, defined as Prod_{k=1..n} k^k.
say hyperfactorial(4) #=> 27648 (1^1 * 2^2 * 3^3 * 4^4)
hyperfactorial_ln
hyperfactorial_ln(n)
Natural logarithm of hyperfactorial(n), where n is a nonnegative integer.
say hyperfactorial_ln(4) #=> 10.22730867160378
Aliases: lnhyperfactorial, hyperfactorial_log
kempner
kempner(n)
Returns the smallest positive integer m such that n divides factorial(m).
say 30.of { .kempner } #=> OEIS: A002034
Aliases: smarandache
lnsuperfactorial
lnsuperfactorial(n)
Natural logarithm of superfactorial(n).
say lnsuperfactorial(4) #=> 5.662960480135946
Aliases: superfactorial_ln, superfactorial_log
mfac
mfac(n,k)
mfactorial(n,k)
The generalized multi-factorial of n.
say 15.of { .mfac(2) } # double-factorials (OEIS: A006882)
say 15.of { .mfac(3) } # triple-factorials (OEIS: A007661)
Aliases: mfactorial, multi_factorial
multinomial
multinomial(...)
The multinomial coefficient, given a list of native integers.
say multinomial(1, 4, 4, 2) #=> 34650
multiplicative_partitions
multiplicative_partitions(n)
multiplicative_partitions(n, max_value)
multiplicative_partitions(n, max_value, max_sum)
Returns an array of arrays of integers > 1 whose product is n.
say multiplicative_partitions(6) #=> [[6], [2, 3]]
say multiplicative_partitions(8) #=> [[8], [2, 4], [2, 2, 2]]
say multiplicative_partitions(30) #=> [[30], [2, 15], [3, 10], [5, 6], [2, 3, 5]]
The number of such partitions is given by OEIS A001055.
When the max_value argument is provided, it generates only the partitions with values <= max_value.
say multiplicative_partitions(30, 10) #=> [[3, 10], [5, 6], [2, 3, 5]]
When the max_sum argument is provided, it generates only the partitions whose sum is <= max_sum.
say multiplicative_partitions(30, nil, 11) #=> [[5, 6], [2, 3, 5]]
Aliases: mpartitions
multisets
multisets(n, k)
multisets(n, k, max_sum)
Returns an array of arrays of integers of size n, with integers in the range 1..k.
say multisets(3, 2)
#=> [[1, 1, 1], [2, 1, 1], [2, 2, 1], [2, 2, 2]]
When the max_sum argument is provided, it generates only the multisets whose sum is <= max_sum.
say multisets(3, 4, 6)
#=> [[1, 1, 1], [2, 1, 1], [2, 2, 1], [2, 2, 2], [3, 1, 1], [3, 2, 1], [4, 1, 1]]
NOTE: these are also called "combinations with replacements".
necklaces
necklaces(n,k)
Number of n-bead necklaces with k colors when turning over is not allowed.
say 30.of { .necklaces(2) } #=> OEIS: A000031
Defined as:
(1/n)*Sum_{d|n} phi(n/d)*k^d
necklaces_aperiodic
necklaces_aperiodic(n,k)
Number of n-bead necklaces with beads of k colors when turning over is not allowed and with primitive period n.
say 30.of { .necklaces_aperiodic(2) } #=> OEIS: A001037
Also number of degree-n irreducible polynomials over GF(k).
Defined as:
(1/n) * Sum_{d|n} mu(n/d) * k^d
frobenius_number
var g = frobenius_number(a, b, ...)
Returns the Frobenius number of a set of positive integers.
The Frobenius number is the largest integer that cannot be expressed as a non-negative integer linear combination of the given values.
The input values must be positive and have greatest common divisor equal to 1. Otherwise, the Frobenius number is undefined and the function returns NaN.
say frobenius_number(4, 7) # => 17
say frobenius_number(5, 8) # => 27
say frobenius_number(6, 9, 20) # => 43
say frobenius_number(1) # => -1
num2perm
num2perm(n,k)
Given a nonnegative integer n and integer k, return the rank k lexicographic permutation of n elements.
k will be interpreted as mod n!.
The inverse value for k is given by Array#perm2num:
say num2perm(5, 43) #=> [1, 4, 0, 3, 2]
say num2perm(5, 43).perm2num #=> 43
partition_count
n.partition_count
n.partition_count(k)
n.partition_count(set)
Returns the number of integer partitions of n.
With a single argument, this function returns the partition number p(n), that is, the number of ways to write n as a sum of positive integers, where the order of the summands is ignored.
Examples:
say 0.partition_count # => 1
say 5.partition_count # => 7
say 10.partition_count # => 42
say 100.partition_count # => 190569292
Partitions into exactly k parts
When the second argument is an integer k, the function returns the number of partitions of n into exactly k positive parts.
say 7.partition_count(1) # => 1
say 7.partition_count(2) # => 3
say 7.partition_count(3) # => 4
say 7.partition_count(7) # => 1
say 7.partition_count(8) # => 0
Restricted partitions
When the second argument is an array, it is interpreted as the set of allowed part sizes. The function then counts only those partitions whose parts belong to the specified set.
# Parts from {2, 3, 5}
say 10.partition_count([2, 3, 5]) # => 4
# 10 = 5+5
# = 5+3+2
# = 3+3+2+2
# = 2+2+2+2+2
# Odd parts only
say 8.partition_count([1, 3, 5, 7]) # => 6
Aliases: partition_number
partitions
partitions(n)
partitions(n, max_value)
Return an array of arrays with the additive partitions of n, such that their sum equals n.
say partitions(4) #=> [[4], [3, 1], [2, 2], [2, 1, 1], [1, 1, 1, 1]]
When the max_value argument is provided, it returns only the partitions with value <= max_value.
say partitions(4, 2) #=> [[2, 2], [2, 1, 1], [1, 1, 1, 1]]
It uses the "Mathematica" ordering of the partitions (graded reverse lexicographic ordering).
permutations
n.permutations
Returns an array of arrays with the permutations of the integers in the range 0..n-1, or iterates over the permutations when a block is given.
5.permutations {|*a| say a }
rising_factorial
rising_factorial(n,k)
Rising factorial: n^(k) = n * (n + 1) * ... * (n + k - 1), defined as:
binomial(n + k - 1, k) * k!
For negative values of k, rising factorial is defined as:
rising_factorial(n, -k) = 1/rising_factorial(n - k, k)
say rising_factorial(5, 3) #=> 210 (5*6*7)
stirling
stirling(n,k)
Stirling numbers of the first kind.
say stirling(5, 2) #=> -50
Aliases: stirling1
stirling2
stirling2(n,k)
Stirling numbers of the second kind.
say stirling2(5, 2) #=> 15
stirling3
stirling3(n,k)
Stirling numbers of the third kind (also known as Lah numbers).
say stirling3(5, 2) #=> 240
strict_partitions
strict_partitions(n)
strict_partitions(n, max_value)
Return an array of arrays with the additive strict partitions of n (partitions where all integers in a single partition are strictly unique/different), such that their sum equals n.
say strict_partitions(6) #=> [[6], [5, 1], [4, 2], [3, 2, 1]]
When the max_value argument is provided, it returns only the strict partitions with value <= max_value.
say strict_partitions(12, 5) #=> [[5, 4, 3], [5, 4, 2, 1]]
subfactorial
subfactorial(n,k=0)
Number of derangements of a set with n elements having exactly k fixed points. Also known as the rencontres numbers.
say 20.of { .subfactorial } #=> OEIS: A000166
say 20.of { .subfactorial(2) } #=> OEIS: A000387
Aliases: rencontres
subsets
n.subsets
n.subsets(k)
n.subsets { ... }
n.subsets(k, { ... })
Returns an array with the subsets of the integers in the range 0..n-1, or iterates over the k-subsets when a block is given.
say 5.subsets # all k-subsets of 0..4
say 5.subsets(2) # all 2-subsets of 0..4
5.subsets {|*a| say a } # iterate over all k-subsets of 0..4
5.subsets(2, {|*a| say a }) # iterate over all 2-subsets of 0..4
superfactorial
superfactorial(n)
Returns the product of first n factorials. (OEIS A000178)
say 10.of { .superfactorial } #=> OEIS: A000178
tuples
n.tuples(k)
n.tuples(k, { ... })
Returns an array with the k-tuples of the integers in the range 0..n-1, or iterates over the k-tuples when a block is given.
5.tuples(2, {|*a| say a })
Aliases: variations
tuples_with_repetition
n.tuples_with_repetition(k)
n.tuples_with_repetition(k, { ... })
Returns an array with the k-tuples with repetition of the integers in the range 0..n-1, or iterates over the k-tuples with repetition when a block is given.
5.tuples_with_repetition(2, {|*a| say a })
Aliases: variations_with_repetition
SEQUENCES, POLYNOMIALS & FIGURATE NUMBERS
bern
n.bern
bernoulli(n)
bernoulli(n, x)
Returns the n-th Bernoulli number of the first kind (with B_1 = -1/2). When an additional argument is provided, it returns the n-th Bernoulli polynomial evaluated at x.
say bernoulli(10).as_rat # B_10 = 5/66
say bernoulli(10, 2).as_rat # B_10(2) = 665/66
For Bernoulli numbers of the second kind (with B_1 = 1/2) use:
bernoulli(n, 1) # here B_1 = 1/2
Aliases: bernfrac, bernoulli, bernoulli_number
bernoulli_numbers
bernoulli_numbers(n)
Returns an array containing the Bernoulli numbers with indices in the range 0..n.
say bernoulli_numbers(5) #=> [1, -1/2, 1/6, 0, -1/30, 0]
say bernoulli_numbers(6) #=> [1, -1/2, 1/6, 0, -1/30, 0, 1/42]
bernoulli_polynomial
bernoulli_polynomial(n)
bernoulli_polynomial(n, x)
Returns the n-th Bernoulli polynomial: B_n(x).
say bernoulli_polynomial(3, 2) #=> 3
When x is omitted, a Polynomial object is returned.
bernreal
bernreal(n)
bernreal(n,x)
Return an approximation to the n-th Bernoulli number as a floating-point number.
say bernreal(10) #=> 0.0757575757575757575757575757575757575757575757576
When a second argument x is given, it return the n-th Bernoulli polynomial evaluated at x:
B_n(x) # as a floating-point number
catalan
n.catalan
n.catalan(k)
Returns the n-th Catalan number.
If two arguments are provided, it returns the C(n,k) entry in Catalan's triangle.
say 10.catalan #=> 16796
say catalan(4, 2) #=> 9
centered_polygonal
n.centered_polygonal(k)
Returns the n-th centered k-gonal number.
say 15.of {|n| centered_polygonal(n, 3) } # centered triangular numbers
say 15.of {|n| centered_polygonal(n, 6) } # centered hexagonal numbers
centered_polygonal_root
n.centered_polygonal_root(k)
Returns the centered k-gonal root of n. Also defined for complex numbers.
say centered_polygonal_root(n, 3) # centered triangular root
say centered_polygonal_root(n, 5) # centered pentagonal root
centered_pyramidal
n.centered_pyramidal(k)
Returns the n-th centered k-gonal pyramidal number.
say centered_pyramidal(4, 6) #=> 54
centered_pyramidal_root
n.centered_pyramidal_root(k)
Returns the centered k-gonal pyramidal root of n. Also defined for complex numbers.
say centered_pyramidal_root(54, 6) #=> 4
chebyshevT
chebyshevT(n)
chebyshevT(n, x)
Compute the Chebyshev polynomials of the first kind: T_n(x), where n must be a native integer.
say chebyshevT(3, 2) #=> 26
Defined as:
T(0, x) = 1
T(1, x) = x
T(n, x) = 2*x*T(n-1, x) - T(n-2, x)
When x is omitted, a Polynomial object is returned.
Aliases: chebyshevt
chebyshevTmod
chebyshevTmod(n, x, m)
Compute the modular Chebyshev polynomials of the first kind: T_n(x) mod m, where n and m must be integers (arbitrarily large).
say chebyshevTmod(3, 2, 100) #=> 26
chebyshevU
chebyshevU(n)
chebyshevU(n, x)
Compute the Chebyshev polynomials of the second kind: U_n(x), where n must be a native integer.
say chebyshevU(3, 2) #=> 56
Defined as:
U(0, x) = 1
U(1, x) = 2*x
U(n, x) = 2*x*U(n-1, x) - U(n-2, x)
When x is omitted, a Polynomial object is returned.
Aliases: chebyshevu
chebyshevUmod
chebyshevUmod(n, x, m)
Compute the modular Chebyshev polynomials of the second kind: U_n(x) mod m, where n and m must be integers (arbitrarily large).
say chebyshevUmod(3, 2, 100) #=> 56
collatz
n.collatz
Returns the number of halving and tripling steps to reach 1 in the 3x+1 Collatz problem.
say 27.collatz #=> 111
cyclotomic
cyclotomic(n)
cyclotomic(n,x)
Returns the n-th Cyclotomic polynomial evaluated at x.
say cyclotomic(12, 10) #=> 9901
When x is omitted, a Polynomial object is returned:
say cyclotomic(12) #=> x^4 - x^2 + 1
Aliases: cyclotomic_polynomial
cyclotomicmod
cyclotomicmod(n, x, m)
Returns the n-th Cyclotomic polynomial evaluated at x, computed modulo m.
say cyclotomicmod(30!, 5040, 2**128 + 1)
It returns NaN when moebius(d) = -1 and gcd(n/d, m) != 1, for some d|n.
euler
euler(n)
euler(n,x)
Returns the n-th Euler number:
say 10.of {|n| euler_number(n) } #=> [1, 0, -1, 0, 5, 0, -61, 0, 1385, 0]
Returns the n-th Euler polynomial evaluated at x, when x is given:
say euler(10, 5) #=> 1981100
Aliases: euler_number
euler_numbers
euler_numbers(n)
Returns an array containing the Euler numbers with indices in the range 0..n.
say euler_numbers(9) #=> [1, 0, -1, 0, 5, 0, -61, 0, 1385, 0]
say euler_numbers(10) #=> [1, 0, -1, 0, 5, 0, -61, 0, 1385, 0, -50521]
euler_polynomial
euler_polynomial(n)
euler_polynomial(n, x)
Returns the n-th Euler polynomial evaluated at x.
say euler_polynomial(3, 2) #=> 9/4
When x is omitted, a Polynomial object is returned.
faulhaber
faulhaber(n,k)
Sum of powers: 1^k + 2^k + ... + n^k, using Faulhaber's summation formula.
faulhaber(5, 2) # 1^2 + 2^2 + 3^2 + 4^2 + 5^2 = 55
The value for k must be a nonnegative native integer.
Aliases: faulhaber_sum
faulhaber_polynomial
faulhaber_polynomial(n)
faulhaber_polynomial(n, x)
Computes the n-th Faulhaber polynomials evaluated at x.
Defined in terms of the Bernoulli polynomials, as:
faulhaber_polynomial(n,x) = (bernoulli_polynomial(n+1,x+1) - bernoulli_polynomial(n+1, 1))/(n+1)
When x is omitted, a Polynomial object is returned.
faulhaber_range
faulhaber_range(a, b, k)
Sum of powers: a^k + (a+1)^k + (a+2)^k + ... + b^k, using Faulhaber's summation formula.
faulhaber_range(50, 100, 2) # 50^2 + 51^2 + ... + 100^2 = 297925
The value for k must be a nonnegative native integer.
fibbinary
fibbinary(n)
Returns the n-th Fibbinary number. (OEIS A003714)
say 10.of { .fibbinary } # [0, 1, 2, 4, 5, 8, 9, 10, 16, 17]
say 30.of { .fibbinary.as_bin } # Zeckendorf representation of n (OEIS: A014417)
zeckendorf
var terms = n.zeckendorf
Returns the Zeckendorf representation of n as an array of Fibonacci numbers.
By Zeckendorf's theorem, every positive integer can be written uniquely as a sum of distinct, non-consecutive Fibonacci numbers. This function returns the Fibonacci terms in decreasing order.
say 10.zeckendorf # => [8, 2]
say 42.zeckendorf # => [34, 8]
say 100.zeckendorf # => [89, 8, 3]
The returned terms always satisfy:
n == terms.sum
and no two consecutive Fibonacci numbers appear in the representation.
fibmod
fibmod(n,m)
fibmod(n,k,m)
Efficiently computes the n-th Fibonacci number modulo m.
fibmod(n,m) == (fibonacci(n) % m)
When three arguments are given, it computes the n-th k-th order Fibonacci number modulo m.
fibmod(n,k,m) == (fibonacci(n,k) % m)
Aliases: fibonacci_mod, fibonaccimod
fibonacci
fibonacci(n)
fibonacci(n,k)
Returns the n-th Fibonacci number. (OEIS A000045)
say 10.of { .fibonacci } #=> [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
When an additional argument k is provided, it returns the n-th k-th order Fibonacci number. For k > 2, the sequence starts with zeros up to index k-2.
say 20.of { .fibonacci(3) } #=> Tribonacci numbers
say 20.of { .fibonacci(4) } #=> Tetranacci numbers
say 20.of { .fibonacci(5) } #=> Pentanacci numbers
say fibonacci(2, 5) #=> 0
Aliases: fib
fibonacci_inverse
fibonacci_inverse(n)
Returns the index of the Fibonacci number n.
If n = F(k), where F(k) denotes the k-th Fibonacci number, the function returns k. If n is not a Fibonacci number, the function returns -1.
The Fibonacci indexing used is
F(0) = 0
F(1) = 1
F(2) = 1
F(3) = 2
F(4) = 3
...
Examples:
say 144.fibonacci_inverse # => 12
say 145.fibonacci_inverse # => -1
Aliases: fib_inverse
fusc
fusc(n)
Returns the n-th term in Stern's diatomic series (or Stern-Brocot sequence). (OEIS A002487)
say 30.of { .fusc } #=> OEIS: A002487
genocchi
genocchi(n)
Returns the n-th Genocchi number (of first kind). (OEIS A001469)
Defined as:
gennochi(n) = 2*(1 - 4^n) * bernoulli(2*n)
hermiteH
hermiteH(n)
hermiteH(n, x)
Physicists' Hermite polynomials: H_n(x).
say hermiteH(3, 2) #=> 40
When x is omitted, a Polynomial object is returned.
Aliases: hermite_polynomialH
hermiteHe
hermiteHe(n)
hermiteHe(n, x)
Probabilists' Hermite polynomials: He_n(x).
say hermiteHe(3, 2) #=> 2
When x is omitted, a Polynomial object is returned.
Aliases: hermite_polynomialHe
ipolygonal_root
ipolygonal_root(n,k)
First integer k-gonal root of n.
say ipolygonal_root(n, 5) # integer pentagonal root
say ipolygonal_root(polygonal(10, 5), 5) # prints: "10"
ipolygonal_root2
ipolygonal_root2(n,k)
Second integer k-gonal root of n.
say ipolygonal_root2(n, 5) # second integer pentagonal root
say ipolygonal_root2(polygonal(-10, 5), 5) # prints: "-10"
isolve_quadratic
isolve_quadratic(a,b,c)
Returns a list of integer solutions (x_1, x_2) to the quadratic equation: a*x^2 + b*x + c = 0, defined as:
floor((-b ± isqrt(b^2 - 4ac)) / (2a))
Example:
say [isolve_quadratic(13, -42, -34)] #=> [3, -1]
Aliases: integer_quadratic_formula, iquadratic_formula
is_centered_polygonal
n.is_centered_polygonal(k)
Returns true if n is a centered k-gonal number.
say 15.by { .is_centered_polygonal(3) } # centered triangular numbers
say 15.by { .is_centered_polygonal(6) } # centered hexagonal numbers
is_chebyshev
n.is_chebyshev
Returns true if n is an odd composite Chebyshev pseudoprime, as defined by OEIS A175530.
Aliases: is_chebyshev_psp, is_chebyshev_pseudoprime
is_fib
n.is_fib
Returns true if n is a Fibonacci number. False otherwise.
Aliases: is_fibonacci
is_lucas
n.is_lucas
Returns true if n is a Lucas number. False otherwise.
is_polygonal
is_polygonal(n,k)
Returns true if n is a first k-gonal number.
say is_polygonal(145, 5) #=> 1 ("145" is a pentagonal number)
say is_polygonal(155, 5) #=> 0
is_polygonal2
is_polygonal2(n,k)
Returns true when n is a second k-gonal number.
say is_polygonal2(145, 5) #=> 0
say is_polygonal2(155, 5) #=> 1 ("155" is a second-pentagonal number)
is_pyramidal
n.is_pyramidal(k)
Returns true if n is a k-gonal pyramidal number.
say 15.by { .is_pyramidal(3) } #=> tetrahedral numbers
say 15.by { .is_pyramidal(5) } #=> pentagonal pyramidal numbers
jacobsthal
jacobsthal(n)
Returns the n-th Jacobsthal number. (OEIS A001045)
Equivalent to: lucasU(1, -2, n).
jacobsthal_lucas
jacobsthal_lucas(n)
Returns the n-th Jacobsthal-Lucas number. (OEIS A014551)
Equivalent to: lucasV(1, -2, n).
laguerre
laguerre(n)
laguerre(n, x)
Laguerre polynomials: L_n(x).
say laguerre(3, 2) #=> -1/3
When x is omitted, a Polynomial object is returned.
Aliases: laguerreL, laguerre_polynomial
legendreP
legendreP(n)
legendreP(n,x)
Legendre polynomials: P_n(x).
say legendreP(3, 2) #=> 17
When x is omitted, a Polynomial object is returned.
Aliases: legendrep, legendre_polynomial
lucas
lucas(n)
Returns the n-th Lucas number.
say 10.of { .lucas } #=> [2, 1, 3, 4, 7, 11, 18, 29, 47, 76]
lucas_mod
lucasmod(n,m)
Efficiently compute the n-th Lucas number modulo m.
say lucas_mod(100, 1000) #=> (lucas(100) % 1000)
Aliases: lucasmod
lucasU
lucasU(P, Q, n)
The Lucas U_n(P, Q) function.
say 20.of{|n| lucasU(1, -1, n) } # the Fibonacci numbers
say 20.of{|n| lucasU(2, -1, n) } # the Pell numbers
say 20.of{|n| lucasU(1, -2, n) } # the Jacobsthal numbers
Aliases: lucasu
lucasUmod
lucasUmod(P,Q,n,m)
Efficiently compute the Lucas U_n(P, Q) function modulo m.
say lucasUmod(1, -1, 100, 1000) #=> (lucasU(1,-1,100) % 1000)
Aliases: lucasumod
lucasUVmod
lucasUVmod(P,Q,n,m)
Efficiently compute the Lucas U_n(P, Q) and V_n(P,Q) functions modulo m.
Equivalent with:
(lucasUmod(P,Q,n,m), lucasVmod(P,Q,n,m))
Aliases: lucasuvmod
lucasV
lucasV(P, Q, n)
The Lucas V_n(P, Q) function.
say 20.of{|n| lucasV(1, -1, n) } # the Lucas numbers
say 20.of{|n| lucasV(2, -1, n) } # the Pell-Lucas numbers
say 20.of{|n| lucasV(1, -2, n) } # the Jacobsthal-Lucas numbers
Aliases: lucasv
lucasvmod
lucasVmod(P,Q,n,m)
Efficiently compute the Lucas V_n(P, Q) function modulo m.
say lucasvmod(1, -1, 100, 1000) #=> (lucasV(1,-1,100) % 1000)
Aliases: lucasVmod
motzkin
motzkin(n)
Returns the n-th Motzkin number. (OEIS A001006)
say 10.of { .motzkin } #=> [1, 1, 2, 4, 9, 21, 51, 127, 323, 835]
padovan
padovan(n)
Returns the n-th Padovan number (OEIS A000931), defined as:
a(0) = 1
a(1) = 0
a(2) = 0
a(n) = a(n-2) + a(n-3)
Example:
say 10.of { .padovan } #=> [1, 0, 0, 1, 0, 1, 1, 1, 2, 2]
padovanmod
padovanmod(n,m)
Returns the n-th Padovan number, modulo m.
say padovanmod(1000, 97) #=> (padovan(1000) % 97)
pell
pell(n)
Returns the n-th Pell number. (OEIS A000129)
say 10.of { .pell } #=> [0, 1, 2, 5, 12, 29, 70, 169, 408, 985]
Equivalent to: lucasU(2, -1, n).
pell_lucas
pell_lucas(n)
Returns the n-th Pell-Lucas number. (OEIS A002203)
say 10.of { .pell_lucas } #=> [2, 2, 6, 14, 34, 82, 198, 478, 1154, 2786]
Equivalent to: lucasV(2, -1, n).
perrin
perrin(n)
Returns the n-th Perrin number (OEIS A001608), defined as:
a(0) = 3
a(1) = 0
a(2) = 2
a(n) = a(n-2) + a(n-3)
Example:
say 10.of { .perrin } #=> [3, 0, 2, 3, 2, 5, 5, 7, 10, 12]
perrinmod
perrinmod(n,m)
Returns the n-th Perrin number, modulo m.
say perrinmod(1000, 97) #=> (perrin(1000) % 97)
This function can be used as a pseudo-primality test for n > 1:
perrinmod(n, n) == 0 #=> n is a prime number or a Perrin pseudoprime
The list of Perrin pseudoprimes is given by OEIS A013998.
pisano_period
pisano_period(n)
Returns the n-th Pisano number: period of Fibonacci numbers mod n.
say pisano_period(10!) #=> 86400
say pisano_period(2**128 + 1) #=> 28356863910078205764000346543980814080
polygonal
polygonal(n,k)
Returns the n-th k-gonal number. When n is negative, it returns the second k-gonal number.
say 10.of {|n| polygonal( n, 3) } # triangular numbers
say 10.of {|n| polygonal( n, 5) } # pentagonal numbers
say 10.of {|n| polygonal(-n, 5) } # second pentagonal numbers
polygonal_inverse
polygonal_inverse(n)
Returns an array of pairs [r,k] such that polygonal(r,k) = n.
say polygonal_inverse(4012) #=> [[2, 4012], [4, 670], [8, 145], [4012, 2]]
Aliases: inverse_polygonal
polygonal_root
polygonal_root(n,k)
Returns the k-gonal root of n. Also defined for complex numbers.
say polygonal_root(n, 3) # triangular root
say polygonal_root(n, 5) # pentagonal root
polygonal_root2
polygonal_root2(n,k)
Returns the second k-gonal root of n. Also defined for complex numbers.
say polygonal_root2(n, 5) # second pentagonal root
pyramidal
n.pyramidal(k)
Returns the n-th k-gonal pyramidal number.
say 15.of {|n| pyramidal(n, 3) } # tetrahedral numbers
say 15.of {|n| pyramidal(n, 5) } # pentagonal pyramidal numbers
pyramidal_root
n.pyramidal_root(k)
Returns the k-gonal pyramidal root of n. Also defined for complex numbers.
say pyramidal_root(pyramidal(1234, 3), 3) #=> 1234
ramanujan_tau
ramanujan_tau(n)
Ramanujan's tau function.
say ramanujan_tau(1) #=> 1
say ramanujan_tau(2) #=> -24
say ramanujan_tau(3) #=> 252
secant_number
secant_number(n)
Return the n-th secant/zig number. (OEIS A000364)
say secant_number(0) #=> 1
say secant_number(1) #=> 1
say secant_number(2) #=> 5
say secant_number(3) #=> 61
solve_pell
solve_pell(D)
solve_pell(D, N)
Finds all fundamental integer solutions (x, y) of the generalized Pell equation:
x^2 - D*y^2 = N
where D is a positive non-square integer and N is an arbitrary integer (default: 1).
For the classical Pell equations (N = ±1), the method computes the fundamental solution using the continued fraction expansion of sqrt(D). When available and advantageous, PARI/GP is used for large inputs to accelerate the computation. (with Num!USE_PARI_GP = true)
For arbitrary values of N, the method implements the LMM (Lagrange–Matthews–Mollin) continued-fraction algorithm to enumerate all primitive solution classes. Each solution is then reduced to its fundamental representative under multiplication by the fundamental unit of Q(sqrt(D)).
Returns an array of [x, y] pairs sorted by increasing x. If the equation has no integer solutions, an empty array is returned.
say solve_pell(61) #=> [[1766319049, 226153980]]
say solve_pell(61, -1) #=> [[29718, 3805]]
say solve_pell(10, 9) #=> [[3, 0], [7, 2], [7, -2]]
# Iterate over solutions
var (D, N) = (10, 9)
var U = Quadratic(solve_pell(D)[0]..., D)
var V = Quadratic(solve_pell(D, N)[0]..., D)
for n in (0..5) { say (U**n * V) }
solve_lcg
solve_lcg(n, r, m)
Return the smallest solution for x to the following linear congruence:
n*x == r (mod m)
Example:
say solve_lcg(143, 44, 231) #=> 10
Return NaN when no solution exists (i.e.: when r is not divisible by gcd(n, m)).
Aliases: solve_linear_congruence
solve_lcg_all
solve_lcg_all(n, r, m)
Return an array with the values of x satisfying the following linear congruence:
n*x == r (mod m)
Example:
say solve_lcg_all(3, 12, 15) #=> [4, 9, 14]
Aliases: linear_congruence
solve_quadratic
solve_quadratic(a,b,c)
Returns a list of (complex) solutions (x_1, x_2) to the quadratic equation: a*x^2 + b*x + c = 0, defined as:
(-b ± sqrt(b^2 - 4ac)) / (2a)
Example:
say [solve_quadratic(13, -42, -34)] #=> [3.9011...., -0.6704...]
Aliases: quadratic_formula
solve_cubic
solve_cubic(a, b, c, d)
Returns a list of (complex) solutions (x_1, x_2, x_3) to the cubic equation:
a*x^3 + b*x^2 + c*x + d = 0
Aliases: cubic_formula
solve_quadraticQ
solve_quadraticQ(a,b,c)
Returns a list of Quadratic objects, which are solutions (x_1, x_2) to the quadratic equation: a*x^2 + b*x + c = 0.
say [solve_quadraticQ(3,4,5)] #=> [Quadratic(-2/3, 1/6, -44, 0), Quadratic(-2/3, -1/6, -44, 0)]
Aliases: quadratic_formulaQ
solve_quadratic_mod
solve_quadratic_mod(a, b, c, m)
Returns all solutions to the quadratic congruence:
a*x^2 + b*x + c ≡ 0 (mod m)
The result is returned as an array containing all distinct solutions modulo m, sorted in ascending order. If the congruence has no solutions, an empty array is returned.
If the leading coefficient a is zero, the congruence degenerates into the linear congruence:
b*x + c ≡ 0 (mod m)
which is solved automatically using solve_lcg_all.
When m is odd and the leading coefficient a is invertible modulo m, the function uses the modular analogue of the quadratic formula. After normalizing the equation by a, it completes the square to obtain:
(x + b/(2a))^2 ≡ (b/2a)^2 - c/a (mod m)
and computes all modular square roots using sqrtmod_all.
For the general case (including even moduli or noninvertible leading coefficients), the congruence is transformed into the equivalent square-root problem:
k^2 ≡ b^2 - 4ac (mod 4am)
Solutions are then reconstructed from the corresponding square roots modulo 4am.
Examples:
# x^2 - 1 ≡ 0 (mod 13)
say solve_quadratic_mod(1, 0, -1, 13) #=> [1, 12]
# Linear congruence: 5x + 2 ≡ 0 (mod 11)
say solve_quadratic_mod(0, 5, 2, 11) #=> [4]
# 3*x^2 + 4*x + 5 ≡ 0 (mod 124)
say solve_quadratic_mod(3, 4, 5, 124) #=> [47, 55, 109, 117]
Aliases: modular_quadratic_formula, quadratic_congruence
solve_cubic_mod
solve_cubic_mod(A, B, C, D, m)
Returns all solutions to the cubic polynomial congruence:
A*x^3 + B*x^2 + C*x + D ≡ 0 (mod m)
The result is returned as an array containing all distinct solutions modulo m, sorted in ascending order. If no solutions exist, or if the equation cannot be transformed into a monic cubic modulo m, an empty array is returned.
The function requires that the modular inverses of 2, 3, 27, and the leading coefficient A exist modulo m. If any of these inverses do not exist, the function returns an empty array.
# x^3 - 1 ≡ 0 (mod 13)
say solve_cubic_mod(1, 0, 0, -1, 13) # [1, 3, 9]
# x^3 + 2x + 5 ≡ 0 (mod 17)
say solve_cubic_mod(1, 0, 2, 5, 17) # [2]
solve_quadratic_form
var solutions = solve_quadratic_form(d, n)
Given a positive integer n and a positive integer d, returns an array with [x,y] solutions to the equation:
x^2 + d*y^2 = n
Example:
say solve_quadratic_form(13, 97) #=> []
say solve_quadratic_form(18, 43*97) #=> [[11, 15], [61, 5]]
Returns an empty array if there are no solutions.
Aliases: cornacchia
solve_binary_quadratic_form
var solutions = solve_binary_quadratic_form(A, B, C, n)
Returns all integer solutions [x, y] of the binary quadratic equation:
Ax² + Bxy + Cy² = n.
The result is returned as an array of pairs [x, y], sorted lexicographically. If no integer solutions exist, an empty array is returned.
The current implementation applies to positive definite binary quadratic forms, namely those satisfying:
A > 0
4AC - B² > 0.
It transforms the equation into the equivalent form:
X² + DY² = 4An,
where
D = 4AC - B²,
X = 2Ax + By,
Y = y.
The transformed equation is solved using solve_quadratic_form, after which all valid sign combinations are examined to recover the corresponding integer solutions [x, y].
Examples:
# x² + y² = 25
say solve_binary_quadratic_form(1, 0, 1, 25)
# => [[-5,0], [-4,-3], [-4,3], [-3,-4], [-3,4],
# [0,-5], [0,5], [3,-4], [3,4], [4,-3],
# [4,3], [5,0]]
# x² + xy + y² = 13
say solve_binary_quadratic_form(1, 1, 1, 13)
# => [[-4, 1], [-4, 3], [-3, -1], [-3, 4],
# [-1, -3], [-1, 4], [1, -4], [1, 3], [3, -4],
# [3, 1], [4, -3], [4, -1]]
Every returned pair satisfies:
A*x² + B*x*y + C*y² == n
solve_ternary_quadratic_form
var solutions = solve_ternary_quadratic_form(a, b, c, n)
Returns all the positive solutions to the ternary quadratic form (up to rearrangement):
a*x^2 + b*y^2 + c*z^2 = n
Example:
say solve_ternary_quadratic_form(1, 1, 1, 18) #=> [[0, 3, 3], [1, 1, 4]]
say solve_ternary_quadratic_form(1, 1, 2, 18) #=> [[0, 0, 3], [0, 4, 1], [1, 3, 2], [3, 3, 0]]
say solve_ternary_quadratic_form(1, 2, 2, 18) #=> [[0, 0, 3], [4, 0, 1]]
say solve_ternary_quadratic_form(1, 2, 3, 18) #=> [[0, 3, 0], [2, 1, 2], [4, 1, 0]]
It does not support degenerate forms where a coefficient is zero or negative. It requires:
a > 0, b > 0, c > 0, n > 0
sum_of_polygonals
sum_of_polygonals(n, k)
Returns all representations as a sum of two k-gonal numbers: n = P(x,k) + P(y,k) with 0 ≤ x ≤ y, as an array of [x, y] arrays, sorted by x.
Example:
say sum_of_polygonals(18736, 3) # sums of two triangular numbers
say sum_of_polygonals(99025, 4) # sums of two squares numbers
say sum_of_polygonals(10622, 5) # sums of two pentagonal numbers
sum_of_squares
sum_of_squares(n)
Returns all representations as a sum of two squares: n = x² + y² with 0 ≤ x ≤ y, as an array of [x, y] arrays, sorted by x.
Example:
say sum_of_squares(99025)
Output:
[[41, 312], [48, 311], [95, 300], [104, 297], [183, 256], [220, 225]]
sum_of_cubes
sum_of_cubes(n)
Returns all integer solutions (x, y) satisfying:
x^3 + y^3 = n
The result is returned as an array of pairs, where each pair is itself an array [x, y].
Returns an empty array when no integer solutions exist or when n = 0.
This implementation uses the factorization identity:
x^3 + y^3 = (x + y)(x^2 - xy + y^2)
to reduce the problem to testing the divisors of |n|. For each divisor A = x + y, the algorithm derives the corresponding quadratic equation, checks whether its discriminant is a perfect square, and reconstructs the integer solution when possible.
The algorithm naturally supports both positive and negative values of n.
Examples:
say sum_of_cubes(35) # [[2, 3]]
say sum_of_cubes(1729) # [[1, 12], [9, 10]]
say sum_of_cubes(-728) # [[-12, 10], [-9, 1], [-8, -6]]
say sum_of_cubes(30) # []
primitive_pythagorean_triples
primitive_pythagorean_triples(limit)
Returns all primitive Pythagorean triples whose perimeter does not exceed limit.
Each returned triple is an array [a, b, c], satisfying:
a² + b² = c²
gcd(a, b, c) = 1
a < b < c
A primitive Pythagorean triple is one whose three components are coprime. Every primitive Pythagorean triple appears exactly once in the returned array.
say primitive_pythagorean_triples(50)
#=> [[3, 4, 5], [5, 12, 13], [8, 15, 17]]
tangent_number
tangent_number(n)
Returns the n-th tangent/zag number. (OEIS A000182)
say 5.of { .tangent_number } #=> [0, 1, 2, 16, 272]
tetranacci
tetranacci(n)
Returns the n-th Tetranacci number. (OEIS A000078)
Alias for: fibonacci(n,4).
say 10.of { .tetranacci } #=> [0, 0, 0, 1, 1, 2, 4, 7, 13, 24]
tribonacci
tribonacci(n)
Returns the n-th Tribonacci number. (OEIS A000073)
Alias for: fibonacci(n, 3).
say 10.of { .tribonacci } #=> [0, 0, 1, 1, 2, 4, 7, 13, 24, 44]
NUMBER THEORY: PRIMES & PRIMALITY
all_prime
all_prime(...)
Returns true if all the given values are prime numbers.
say all_prime(2, 3, 5, 7) #=> true
say all_prime(2, 3, 4, 5) #=> false
is_abs_euler_psp
n.is_abs_euler_psp
Returns true if n is an absolute Euler pseudoprime: p-1 | (n-1)/2 for every p|n, where n is a squarefree composite integer. (OEIS A033181)
say 10.by { .is_abs_euler_psp } #=> OEIS: A033181
Aliases: is_absolute_euler_psp
is_aks_prime
n.is_aks_prime
Return true if n passes the Agrawal-Kayal-Saxena (AKS) primality test.
is_balanced_prime
is_balanced_prime(n, order=1)
Returns true if n is a balanced prime of a given order.
say 10.by { .is_balanced_prime } #=> OEIS: A006562
say 10.by { .is_balanced_prime(2) } #=> OEIS: A082077
say 10.by { .is_balanced_prime(3) } #=> OEIS: A082078
A prime number p_k is a balanced prime, of order n, iff the following equality holds:
p_k = 1/(2*n) * Sum_{i=1..n} (p_{k-i} + p_{k+i})
is_bfsw_psp
n.is_bfsw_psp
Returns true if n passes a slightly stronger and faster variant of the BFW primality test, based on the Lucas-V function, checking the following congruences:
V_{n+1} == 2*Q (mod n)
Q^(n+1) == Q^2 (mod n)
where Q = -2 and P is the first integer >= 2 such that D = P^2 - 4*Q gives kronecker(D, n) == -1.
There are no known composites that pass this test.
is_bpsw_prime
n.is_bpsw_prime
Returns true if n passes the B-PSW primality test (extra-strong variant).
is_ecpp_prime
n.is_ecpp_prime
Return true if n can be proved prime using the Elliptic Curve Primality Proving algorithm.
is_emirp
n.is_emirp(base = 10)
Returns true if n is prime and its reversal is a different prime (in the given base). Also known as emirps.
say 10.by { .is_emirp } #=> decimal emirps (OEIS: A006567)
say 10.by { .is_emirp(2) } #=> binary emirps (OEIS: A080790)
is_euler_psp
n.is_euler_psp(bases...)
Return true if n is an Euler-Jacobi pseudoprime, given a list of bases.
Aliases: is_euler_pseudoprime
is_fib_psp
n.is_fib_psp(P=1, Q=-1)
Returns true if n passes the Lucas test to the U, using the parameters P and Q.
say 10.by { .is_composite && .is_lucasU_psp } # Fibonacci pseudoprimes
say 10.by { .is_odd_composite && .is_lucasU_psp(2, -1) } #=> OEIS: A327651
Aliases: is_lucasu_psp, is_lucasU_psp, is_fibonacci_psp, is_lucasU_pseudoprime, is_fibonacci_pseudoprime
is_frobenius_psp
n.is_frobenius_psp(a,b)
Return true if n is a Frobenius probable prime with respect to the polynomial x^2 - ax + b.
Aliases: is_frobenius_pseudoprime
is_gaussian_prime
is_gaussian_prime(a,b)
Returns true if a+b*i is a Gaussian prime.
say is_gaussian_prime(3, 4) #=> false
say is_gaussian_prime(13, 42) #=> true
Provided by Math::Prime::Util::GMP >= 0.52.
is_khashin_psp
n.is_khashin_psp
Return true if n passes the Frobenius test of Sergey Khashin.
Aliases: is_khashin_pseudoprime, is_frobenius_khashin_psp, is_frobenius_khashin_pseudoprime
is_llr_prime
n.is_llr_prime(k)
Returns true if 2^n * k - 1 is prime, using the Lucas-Lehmer-Riesel (LLR) primality test.
say 15.by { .is_llr_prime(3) } # numbers n such that 2^n * 3 - 1 is prime
is_lucas_psp
n.is_lucas_psp
Return true if n is a Lucas pseudoprime.
Aliases: is_lucas_pseudoprime
is_lucasv_psp
n.is_lucasv_psp(P=1, Q=-1)
Returns true if n passes the Lucas test to the V sequence, using the parameters P and Q.
say 10.by { .is_composite && .is_lucasV_psp } # Bruckman-Lucas pseudoprimes
say 10.by { .is_odd_composite && .is_lucasV_psp(2, -1) } #=> OEIS: A330276
Aliases: is_lucasV_psp, is_bruckman_lucas_psp, is_lucasV_pseudoprime, is_bruckman_lucas_pseudoprime
is_mersenne_prime
is_mersenne_prime(p)
Returns true if 2^p - 1 is a Mersenne prime.
say 31.is_mersenne_prime #=> true (2^31 - 1 is prime)
say 11.is_mersenne_prime #=> false
Uses the Lucas-Lehmer test for efficiency. =cut
is_nm1_prime
n.is_nm1_prime
Return true if n can be proved prime using the factorization of n-1.
Aliases: is_pm1_prime, is_nminus1_prime
is_np1_prime
n.is_np1_prime
Return true if n can be proved prime using the factorization of n+1.
Aliases: is_pp1_prime, is_nplus1_prime
is_over_psp
n.is_over_psp
Returns true if n is an overpseudoprime to base b. Multiple bases can also be provided.
An overpseudoprime to base b is a also a strong Fermat pseudoprime to base b and a super-pseudoprime to base b, where znorder(b,n) == znorder(b,p) for every p|n.
say 10.by { .is_composite && .is_over_psp } # overpseudoprimes to base 2
say 10.by { .is_composite && .is_over_psp(3) } # overpseudoprimes to base 3
Aliases: is_over_pseudoprime, is_overpseudoprime
is_pell_lucas_psp
n.is_pell_lucas_psp
It returns true if V_n(2, -1) = 2 (mod n). (OEIS A270342)
say 20.by { .is_pell_lucas_pseudoprime } #=> OEIS: A270342
say 20.by { .is_pell_lucas_pseudoprime && .is_composite } #=> OEIS: A335668
say 20.by { .is_pell_lucas_pseudoprime && .is_composite && .is_odd } #=> OEIS: A330276
Aliases: is_pell_lucas_pseudoprime
is_pell_psp
n.is_pell_psp
These are odd numbers that satisfy:
U_n(2, -1) = (2|n) (mod n)
Example:
say 10.by { .is_pell_pseudoprime && .is_composite } # OEIS: A099011
Aliases: is_pell_pseudoprime
is_perrin_psp
n.is_perrin_psp
Returns true if n passes the Perrin primality test.
Aliases: is_perrin_pseudoprime
is_plumb_psp
n.is_plumb_psp
Return true if n passes Colin Plumb's Euler Criterion primality test.
Aliases: is_euler_plumb_psp, is_plumb_pseudoprime, is_euler_plumb_pseudoprime
is_prime
n.is_prime
Returns true if n is a prime number.
Values less than 2 are not prime.
say 17.is_prime #=> true
say 18.is_prime #=> false
say 1.is_prime #=> false
say is_prime(2**127 - 1) #=> true
For small native integers, this uses fast deterministic tests. For larger integers, it uses strong probable-prime tests together with additional checks from the underlying libraries.
is_prob_prime
n.is_prob_prime
Returns true if n is probably prime. Performs trial division followed by a B-PSW test.
say is_prob_prime(1003200318091) #=> true
Faster than is_prime but may (extremely rarely) give false positives for large numbers.
is_proth_prime
n.is_proth_prime(k)
Returns true if 2^n * k + 1 is prime, using the Proth primality test.
say 15.by { .is_proth_prime(3) } # numbers n such that 2^n * 3 + 1 is prime
is_prov_prime
n.is_prov_prime
Returns true if n is definitely a prime.
Aliases: is_provable_prime
is_psp
n.is_psp(bases...)
Returns true if n is a Fermat pseudoprime to the provided bases.
Each base must be coprime to n.
Aliases: is_fermat_psp, is_pseudoprime, is_fermat_pseudoprime
is_safe_prime
n.is_safe_prime
It returns true if both n and (n-1)/2 are prime. (OEIS A005385)
say 30.by { .is_safe_prime } #=> OEIS: A005385
is_sexy_prime
is_sexy_prime(n)
Returns true if n and n+6 are both prime numbers.
say is_sexy_prime(5) #=> true (5 and 11 are both prime)
say is_sexy_prime(9) #=> false
is_sophie_germain
is_sophie_germain(n)
Returns true if n and 2*n + 1 are both prime numbers.
say is_sophie_germain(11) #=> true (11 and 23 are both prime)
say is_sophie_germain(7) #=> false
Aliases: is_sophie_germain_prime
is_strong_fib
n.is_strong_fib
Returns true if n is a strong Fibonacci pseudoprime, satisfying:
V_n(P,Q) = P (mod)
for Q = -1 and all P.
Odd composite integer n is a strong Fibonacci pseudoprime iff:
1) n is a Carmichael number: p-1 | n-1
2) 2(p + 1) | (n − 1) or 2(p + 1) | (n − p)
for each prime p|n.
Example:
say is_strong_fibonacci_pseudoprime(443372888629441) #=> true
say is_strong_fibonacci_pseudoprime(39671149333495681) #=> true
Aliases: is_strong_fib_psp, is_strong_fibonacci, is_strong_fibonacci_psp, is_strong_fibonacci_pseudoprime
is_strong_lucas_psp
n.is_strong_lucas_psp
Return true if n is a strong Lucas pseudoprime.
Aliases: is_strong_lucas_pseudoprime
is_strong_psp
n.is_strong_psp(bases...)
Return true if n is a strong Fermat pseudoprime to the given bases.
Each base must be coprime to n.
Aliases: miller_rabin, is_strong_fermat_psp, is_strong_pseudoprime, is_strong_fermat_pseudoprime
is_stronger_lucas_psp
n.is_stronger_lucas_psp
Return true if n is an extra-strong Lucas pseudoprime.
Aliases: is_extra_strong_lucas_psp, is_stronger_lucas_pseudoprime, is_extra_strong_lucas_pseudoprime
is_strongish_lucas_psp
n.is_strongish_lucas_psp
Return true if n is almost an extra-strong Lucas pseudoprime.
Aliases: is_strongish_lucas_pseudoprime
is_super_psp
n.is_super_psp(bases...)
It returns true if the given value of n is a super-pseudoprime to the given bases.
When no base is given, the base 2 is used (which represents the Super-Poulet numbers: A050217)
# Super-Poulet numbers (OEIS: A050217)
say 1e4.range.grep { .is_super_pseudoprime }.grep{ .is_composite }
# Super-Poulet numbers to base 3 (OEIS: A328662)
say 1e4.range.grep { .is_super_pseudoprime(3) }.grep{ .is_composite }
# Super-Poulet numbers to base 2 and 3
say 1e5.range.grep { .is_super_pseudoprime(2, 3) }.grep{ .is_composite }
Aliases: is_super_pseudoprime, is_superpseudoprime
is_twin_prime
is_twin_prime(n)
Returns true if n and n+2 are both prime numbers.
say is_twin_prime(11) #=> true (11 and 13 are both prime)
say is_twin_prime(7) #=> false
is_underwood_psp
n.is_underwood_psp
Return true if n passes the efficient Frobenius test of Paul Underwood.
Aliases: is_underwood_pseudoprime, is_frobenius_underwood_psp, is_frobenius_underwood_pseudoprime
is_vpsp
n.is_vpsp
Returns true if n passes the Lucas-V BFW test: V_{n+1} == 2*Q (mod n) for carefully chosen values of P and Q.
The composite numbers that pass this test are extremely rare. (OEIS A365514)
When combined with a strong Fermat pseudoprime test to base 2, there are no known composites that pass both tests.
Reference:
Strengthening the Baillie-PSW primality test
https://arxiv.org/abs/2006.14425
Aliases: is_bfw_psp
next_prime
n.next_prime
Returns the next prime number greater than n.
say 10.next_prime #=> 11
say 100.next_prime #=> 101
say (10**20 -> next_prime) #=> 100000000000000000039
next_primes
n.next_primes(start=2)
Returns an array of n consecutive primes starting from start (if omitted, then start = 2).
say 10.next_primes #=> [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
say 10.next_primes(1000) #=> [1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061]
The value for start can be any arbitrarily large integer:
say 10.next_primes(2**128 + 1) # first 10 primes >= 2^128
next_twin_prime
n.next_twin_prime
Returns next twin prime number larger than n.
Provided by Math::Prime::Util::GMP >= 0.52.
pn_primes
pn_primes(n)
pn_primes(a,b)
Returns the first n prime numbers, or the primes in the range prime(a)..prime(b).
say pn_primes(25) # the first 25 primes
say pn_primes(100, 110) # the primes from 100-th prime to 110-th prime (inclusive)
prev_prime
n.prev_prime
Returns the previous prime number smaller than n.
say 11.prev_prime #=> 7
say 100.prev_prime #=> 97
Returns nil if n <= 2.
prev_primes
n.prev_primes(start)
Returns an array with n consecutive decreasing prime numbers starting from start.
say 5.prev_primes(100) #=> [97, 89, 83, 79, 73]
primality_pretest
n.primality_pretest
The method returns true when n passes the internal primality pretest (when n is large enough and it has no small factors).
prime
prime(n)
nth_prime(n)
Returns the n-th prime number (1-indexed).
say prime(1) #=> 2
say prime(100) #=> 541
say prime(1000000) #=> 15485863
For convenience, prime(0) returns 1, although 1 is not a prime.
say prime(0) #=> 1
Aliases: nth_prime
prime_cluster
prime_cluster(lo, hi, *diffs)
Returns an array of primes p such that p+diffs[0], p+diffs[1], etc, are also primes.
say prime_cluster(1, 100, 2) # twin primes <= 100
Aliases: sieve_prime_cluster
prime_lower
n.prime_lower
Lower bound for the n-th prime.
Aliases: nth_prime_lower
prime_upper
n.prime_upper
Upper bound for the n-th prime.
Aliases: nth_prime_upper
primepi
pi(n)
primepi(n)
primepi(a, b)
Counts the number of primes less than or equal to n, or in the range [a, b].
In the two-argument form, the lower bound is effectively clamped to 2, so values below 2 contribute nothing.
say primepi(1) #=> 0
say primepi(100) #=> 25
say primepi(50, 100) #=> 10
say pi(10**12) #=> 37607912018
Aliases: prime_count, count_primes
primepi_lower
n.primepi_lower
Lower bound for prime_count(n).
Aliases: prime_count_lower
primepi_upper
n.primepi_upper
Upper bound for prime_count(n).
Aliases: prime_count_upper
primes
primes(n)
primes(a, b)
Returns an array of prime numbers <= n, or in the range [a,b].
say primes(20) #=> [2, 3, 5, 7, 11, 13, 17, 19]
say primes(10, 20) #=> [11, 13, 17, 19]
primes_each
n.primes_each {...}
primes_each(a,b,{...})
Iterates over the primes in the given range.
# Iterate over the primes between 100 and 200
primes_each(100, 200, {|p| say p })
# Iterate over the primes <= 100
100.primes_each {|p| say p }
Aliases: each_prime
primes_sum
primes_sum(n)
primes_sum(a,b,k=1)
Sum of the prime numbers <= n, or in the range a..b, each prime raised to the k-th power.
Aliases: prime_sum, sum_primes
strong_fermat_psp
k.strong_fermat_psp(base, n)
k.strong_fermat_psp(base, a, b)
Returns an array with all the strong Fermat pseudoprimes to the given base that are <= n or in the range a..b and have k distinct prime factors.
say 3.strong_fermat_psp(2, 1e6) # 3-omega strong Fermat psp to base 2
say 4.strong_fermat_psp(2, 1e6, 1e7) # 4-omega strong Fermat psp to base 2 in range
strong_fermat_psp_each
k.strong_fermat_psp_each(base, n, { ... })
k.strong_fermat_psp_each(base, a, b, { ... })
Iterates over the k-omega strong Fermat pseudoprimes <= n or in the range a..b.
3.strong_fermat_psp_each(2, 1e6, {|n| say n }) # iterate over 3-omega strong Fermat psp to base 2 <= 1e6
4.strong_fermat_psp_each(2, 1e7, 1e8, {|n| say n }) # iterate over 4-omega strong Fermat psp to base 2 in range 1e7..1e8
Aliases: each_strong_fermat_psp
twin_primes
twin_primes(n)
twin_primes(a,b)
Returns an array of primes p such that p+2 is also prime, where p <= n or in range a..b.
say twin_primes(100) #=> [3, 5, 11, 17, 29, 41, 59, 71]
say twin_primes(50, 200) #=> [59, 71, 101, 107, 137, 149, 179, 191, 197]
NUMBER THEORY: PRIME-RELATED FAMILIES
almost_prime_count
k.almost_prime_count(n)
k.almost_prime_count(a,b)
Returns the count of k-almost primes <= n, or in the range a..b.
say 1.almost_prime_count(100) # count of primes <= 100
say 2.almost_prime_count(50, 100) # count of semiprimes in range 50..100
Aliases: almost_primepi, pi_k
almost_prime_divisors
n.almost_prime_divisors
n.almost_prime_divisors(k)
Returns the k-almost prime divisors of n.
say 5040.almost_prime_divisors(7) #=> [720, 1008, 1680, 2520]
When k is omitted, an array of arrays with the k-almost prime divisors of n, for each k in the range 0..bigomega(n), is returned:
say 120.almost_prime_divisors #=> [[1], [2, 3, 5], [4, 6, 10, 15], [8, 12, 20, 30], [24, 40, 60], [120]]
almost_prime_sum
k.almost_prime_sum(n)
k.almost_prime_sum(a,b)
Returns the sum of k-almost primes <= n, or in the range a..b.
say 1.almost_prime_sum(100) # sum of primes <= 100
say 2.almost_prime_sum(50, 100) # sum of semiprimes in range 50..100
almost_primes
k.almost_primes(n)
k.almost_primes(a,b)
Return an array with the k-almost primes <= n, or in the range a..b.
5.almost_primes(1e6) # array of 5-almost primes <= 1e6
5.almost_primes(1e5, 1e6) # array of 5-almost primes in the range [1e5, 1e6]
almost_primes_each
k.almost_primes_each(n, {...})
k.almost_primes_each(a,b, {...})
Iterates over the k-almost prime numbers <= n, or in the range a..b.
11.almost_primes_each(1e7, {|n| say n }) # iterate over 11-almost primes <= 1e6
11.almost_primes_each(1e6, 1e7, {|n| say n }) # iterate over 11-almost primes in the range [1e6, 1e7]
Aliases: each_almost_prime
carmichael
k.carmichael(n)
k.carmichael(a, b)
Returns an array with all the Carmichael numbers <= n or in the range a..b that have exactly k prime factors.
say 3.carmichael(1e4) # 3-Carmichael numbers <= 1e4
say 4.carmichael(1e4, 1e6) # 4-Carmichael numbers in range 1e4..1e6
carmichael_each
k.carmichael_each(n, { ... })
k.carmichael_each(a, b, { ... })
Iterates over the Carmichael <= n or in the range a..b that have exactly k prime factors.
3.carmichael_each(1e5, {|n| say n }) # iterate over 3-Carmichael numbers <= 1e5
4.carmichael_each(1e5, 1e6, {|n| say n }) # iterate over 4-Carmichael in range 1e5..1e6
Aliases: each_carmichael
carmichael_strong_fermat
k.carmichael_strong_fermat(base, n)
k.carmichael_strong_fermat(base, a, b)
Returns an array with all the Carmichael numbers <= n or in the range a..b that are also strong Fermat pseudoprimes to base and have exactly k prime factors.
say 3.carmichael_strong_fermat(2, 1e7) # 3-Carmichael strong Fermat pseudoprimes to base 2 <= 1e7
say 4.carmichael_strong_fermat(2, 1e7, 1e9) # 4-Carmichael strong Fermat pseudoprimes to base 2, in range 1e7..1e9
Aliases: strong_fermat_carmichael, carmichael_strong_psp
carmichael_strong_fermat_each
k.carmichael_strong_fermat_each(base, n, { ... })
k.carmichael_strong_fermat_each(base, a, b, { ... })
Iterates over the Carmichael <= n or in the range a..b that are also strong Fermat pseudoprimes to base and have exactly k prime factors.
3.carmichael_strong_fermat_each(2, 1e7, {|n| say n }) # iterate over 3-Carmichael strong Fermat to base 2 <= 1e7
4.carmichael_strong_fermat_each(2, 1e5, 1e9, {|n| say n }) # iterate over 4-Carmichael strong Fermat to base 2 in range 1e5..1e9
Aliases: carmichael_strong_psp_each, each_carmichael_strong_psp, each_carmichael_strong_fermat, each_strong_fermat_carmichael, strong_fermat_carmichael_each
fermat_psp
k.fermat_psp(base, n)
k.fermat_psp(base, a, b)
Returns an array with all the k-omega Fermat pseudoprimes to the given base that are <= n or in the range a..b.
say 3.fermat_psp(2, 10000) # 3-omega Fermat psp to base 2
say 4.fermat_psp(2, 10000, 100000) # 4-omega Fermat psp to base 2 in range
fermat_psp_each
k.fermat_psp_each(base, n, { ... })
k.fermat_psp_each(base, a, b, { ... })
Iterates over the k-omega Fermat pseudoprimes <= n or in the range a..b.
3.fermat_psp_each(2, 1e5, {|n| say n }) # iterate over 3-Fermat psp to base 2 <= 1e5
4.fermat_psp_each(2, 1e5, 1e6, {|n| say n }) # iterate over 4-Fermat psp to base 2 in range 1e4..1e6
Aliases: each_fermat_psp
is_almost_prime
n.is_almost_prime(k=2)
Return true if n is a k-almost prime (i.e.: true iff n is the product of k not necessarily distinct primes).
Equivalently, k-almost primes are numbers n that satisfy bigomega(n) == k.
say 20.by { .is_almost_prime(1) } # primes
say 20.by { .is_almost_prime(2) } # semiprimes
say 20.by { .is_almost_prime(3) } # 3-almost primes
In order for n to have at least k prime factors, without having any prime factors less than or equal to B, it implies that n must be greater than B^k, since all the prime factors of n are greater than B.
By setting Num!USE_CONJECTURES = true, the function uses a conjectured approach based on Pollard's rho method to find a larger bound for B, which requires O(sqrt(B)) steps to find a prime factor less than B. Therefore, if we take B = 10^12, after c*10^6 iterations (we use c=2) of the Pollard rho method without success in finding a prime factor of n, it's very probable that n has no prime factor less than 10^12.
By enabling the conjectured approach, the function becomes about 5x faster than the rigorous method, for large enough inputs.
is_carmichael
n.is_carmichael
Determine if n is a Carmichael number or not.
is_imprimitive_carmichael
n.is_imprimitive_carmichael
Returns true if n is an imprimitive Carmichael numbers, as defined by OEIS A328935.
say 325533792014488126487416882038879701391121.is_imprimitive_carmichael # true
The method efficiently tries to factorize large Carmichael numbers, using the miller_factor(n) method.
is_lucas_carmichael
n.is_lucas_carmichael
Returns true if n is a Lucas-Carmichael number. (OEIS A006972)
say 10.by(:is_lucas_carmichael) # OEIS: A006972
say is_lucas_carmichael(58735331016965175152455996272482303) # true
is_omega_prime
n.is_omega_prime(k=2)
Return true if n is a k-omega prime (i.e.: true if n is divisible by exactly k different primes).
Equivalently, k-omega primes are numbers n such that omega(n) == k.
say 20.by { .is_omega_prime(1) } # prime powers
say 20.by { .is_omega_prime(2) } # numbers n such that omega(n) == 2
In order for n to have at least k prime factors, without having any prime factors less than or equal to B, it implies that n must be greater than B^k, since all the prime factors of n are greater than B.
By setting Num!USE_CONJECTURES = true, the function uses a conjectured approach based on Pollard's rho method to find a larger bound for B, which requires O(sqrt(B)) steps to find a prime factor less than B. Therefore, if we take B = 10^12, after c*10^6 iterations (we use c=2) of the Pollard rho method without success in finding a prime factor of n, it's very probable that n has no prime factor less than 10^12.
By enabling the conjectured approach, the function becomes about 5x faster than the rigorous method, for large enough inputs.
is_prime_power
n.is_prime_power
Returns true if n is a power of some prime.
is_semiprime
n.is_semiprime
Returns true if n has exactly two prime factors (not necessarily distinct).
linear_forms_primes
linear_forms_primes(A, B, [a_1, b_1], ..., [a_k, b_k])
Returns an array with values m in the range [A, B], such that m * a_1 + b_1, m * a_2 + b_2, ..., m * a_k + b_k are all prime.
say linear_forms_primes(1, 100, [1, 0]) # primes in range 1..100
say linear_forms_primes(1, 500, [1, 0], [1, 2]) # lesser of twin primes in range 1..500
say linear_forms_primes(1, 200, [2,-1], [4,-1], [6, -1]) # OEIS: A124486
lnsuperprimorial
lnsuperprimorial(n)
Natural logarithm of superprimorial(n).
Aliases: superprimorial_ln, superprimorial_log
lucas_carmichael
k.lucas_carmichael(n)
k.lucas_carmichael(a, b)
Returns an array with all the Lucas-Carmichael numbers <= n or in the range a..b that have exactly k prime factors.
say 3.lucas_carmichael(10000) # 3-Lucas-Carmichael numbers
say 4.lucas_carmichael(10000, 100000) # 4-Lucas-Carmichael numbers in range
lucas_carmichael_each
k.lucas_carmichael_each(n, { ... })
k.lucas_carmichael_each(a, b, { ... })
Iterates over the Lucas-Carmichael <= n or in the range a..b that have exactly k prime factors.
3.lucas_carmichael_each(1e5, {|n| say n }) # iterate over 3-Lucas-Carmichael numbers <= 1e5
4.lucas_carmichael_each(1e5, 1e6, {|n| say n }) # iterate over 4-Lucas-Carmichael in range 1e4..1e6
Aliases: each_lucas_carmichael
next_almost_prime
n.next_almost_prime(k=2)
Returns the next k-almost prime greater than n.
next_omega_prime
n.next_omega_prime(k=2)
Returns the next k-omega prime greater than n.
next_prime_power
n.next_prime_power
Given a nonnegative integer n, returns the next prime power (p^k with k >= 1) greater than n.
next_semiprime
n.next_semiprime
Returns the next semiprime greater than n.
next_sphenic
n.next_sphenic
Returns the next number that is the product of three distinct primes.
next_squarefree_almost_prime
n.next_squarefree_almost_prime(k=2)
Returns the next squarefree k-almost prime greater than n.
next_squarefree_semiprime
n.next_squarefree_semiprime
Returns the next squarefree semiprime greater than n.
nth_almost_prime
nth_almost_prime(n, k=2)
Returns the n-th k-almost prime.
say nth_almost_prime(1e7, 2) #=> 56168169
say nth_almost_prime(1e7, 3) #=> 41657362
say nth_almost_prime(1e7, 4) #=> 47997635
nth_omega_prime
nth_omega_prime(n, k=2)
Returns the n-th k-omega prime.
say nth_omega_prime(1e7, 2) #=> 42314023
say nth_omega_prime(1e7, 3) #=> 28013887
say nth_omega_prime(1e7, 4) #=> 39780102
nth_prime_power
nth_prime_power(n)
Returns the n-th prime power p^k with k >= 1.
say nth_prime_power(1e12) #=> 29996212395727
nth_sphenic
nth_sphenic(n)
Returns the n-th number that is the product of three distinct primes. (OEIS A007304)
say nth_sphenic(1e7) #=> 48108421
nth_squarefree_almost_prime
nth_squarefree_almost_prime(n, k=2)
Returns the n-th squarefree k-almost prime.
say nth_squarefree_almost_prime(1e7, 2) #=> 56173891
say nth_squarefree_almost_prime(1e7, 3) #=> 48108421
say nth_squarefree_almost_prime(1e7, 4) #=> 81556446
omega_prime_count
k.omega_prime_count(n)
k.omega_prime_count(a,b)
Returns the count of k-omega primes <= n, or in the range a..b.
say 1.omega_prime_count(100) # number prime powers <= 100
say 2.omega_prime_count(50, 100) # number of 2-omega primes in range 50..100
Aliases: omega_primepi
omega_prime_divisors
n.omega_prime_divisors
n.omega_prime_divisors(k)
Returns the k-omega prime divisors of n.
say 5040.omega_prime_divisors(4) #=> [210, 420, 630, 840, 1260, 1680, 2520, 5040]
When k is omitted, an array of arrays with the k-omega prime divisors of n, for each k in the range 0..omega(n), is returned:
say 120.omega_prime_divisors #=> [[1], [2, 3, 4, 5, 8], [6, 10, 12, 15, 20, 24, 40], [30, 60, 120]]
omega_prime_sum
k.omega_prime_sum(n)
k.omega_prime_sum(a,b)
Returns the sum of k-omega primes <= n, or in the range a..b.
say 1.omega_prime_sum(100) # sum of prime powers <= 100
say 2.omega_prime_sum(50, 100) # sum of 2-omega primes in range 50..100
omega_primes
k.omega_primes(n)
k.omega_primes(a,b)
Returns an array with k-omega primes <= n, or in the range a..b.
k-omega primes are numbers n that satisfy omega(n) == k.
say 1.omega_primes(100) # prime powers <= 100
say 2.omega_primes(50, 100) # 2-omega primes in range 50..100
omega_primes_each
k.omega_primes_each(n, { ... })
k.omega_primes_each(a, b, { ... })
Iterates over the k-omega primes <= n, or in the range a..b.
k-omega primes are numbers n that satisfy omega(n) == k.
1.omega_primes_each(100, {|n| say n }) # iterate over prime powers <= 100
2.omega_primes_each(50, 100, {|n| say n }) # iterate over 2-omega primes in range 50..100
Aliases: each_omega_prime
pn_primorial
pn_primorial(n)
Returns the product of the first n primes.
prev_almost_prime
n.prev_almost_prime(k=2)
Returns the previous k-almost prime smaller than n.
prev_omega_prime
n.prev_omega_prime(k=2)
Returns the previous k-omega prime smaller than n.
prev_prime_power
n.prev_prime_power
Returns the previous prime power smaller than n.
prev_semiprime
n.prev_semiprime
Returns the previous semiprime smaller than n.
prev_sphenic
n.prev_sphenic
Returns the previous number that is the product of three distinct primes.
prev_squarefree_almost_prime
n.prev_squarefree_almost_prime(k=2)
Returns the previous squarefree k-almost prime smaller than n.
prev_squarefree_semiprime
n.prev_squarefree_semiprime
Returns the previous squarefree semiprime smaller than n.
prime_power
n.prime_power
Returns the exponent k if n is a power of the form n = p^k for some prime p. Returns 1 otherwise.
say prime_power(15) #=> 1
say prime_power(43**5) #=> 5
prime_power_count
prime_power_count(n)
prime_power_count(a,b)
Returns the count of prime powers <= n, or in the range a..b.
say prime_power_count(1e15) # number of prime powers <= 10^15
say prime_power_count(1e6, 1e8) # number of prime powers in [10^6, 10^8]
prime_power_count_lower
prime_power_count_lower(n)
Lower bound for prime_power_count(n).
prime_power_count_upper
prime_power_count_upper(n)
Upper bound for prime_power_count(n).
prime_power_lower
prime_power_lower(n)
Lower bound for the n-th prime power.
Aliases: nth_prime_power_lower
prime_power_sum
prime_power_sum(n)
prime_power_sum(a,b)
Returns the sum of prime powers <= n, or in the range a..b.
Aliases: prime_powers_sum
prime_power_upper
prime_power_upper(n)
Upper bound for the n-th prime power.
Aliases: nth_prime_power_upper
prime_powers
prime_powers(n)
prime_powers(a,b)
Returns an array with the prime powers <= n, or in the range a..b.
say prime_powers(100) # prime powers <= 100
say prime_powers(50, 100) # prime powers in the range [50, 100]
prime_powers_each
n.prime_powers_each { ... }
prime_powers_each(a,b, { ... })
Iterate over prime powers <= n, or in the range a..b:
100.prime_powers_each {|k| say k } # iterate over prime powers <= 100
prime_powers_each(50, 100, {|k| say k }) # iterate over prime powers in the range [50, 100]
Aliases: each_prime_power
prime_root
n.prime_root
Returns the prime p if n can be expressed as n = p^k for some prime number p and an integer k. Returns n otherwise.
say prime_root(15) #=> 15
say prime_root(43**5) #=> 43
semiprime
semiprime(n)
Returns the n-th semiprime number. (OEIS A001358)
say 10.of {|k| semiprime(10**k) } #=> OEIS: A114125
Aliases: nth_semiprime
semiprime_count
semiprime_count(n)
semiprime_count(a,b)
Counts the number of semiprimes <= n (OEIS A072000), or in the range a..b.
say 20.of {|k| semiprime_count(2**k) }
semiprime_sum
semiprime_sum(n)
semiprime_sum(a,b)
Returns the sum of semiprimes <= n, or in the range a..b.
Aliases: semiprimes_sum
semiprimes
semiprimes(n)
semiprimes(a,b)
Returns an array with the semiprimes <= n, or in the range a..b.
say semiprimes(100) # semiprimes <= 100
say semiprimes(50, 100) # semiprimes in the range [50, 100]
semiprimes_each
n.semiprimes_each { ... }
semiprimes_each(a,b, { ... })
Iterate over semiprimes <= n, or in the range a..b:
100.semiprimes_each {|k| say k } # iterate over semiprimes <= 100
semiprimes_each(50, 100, {|k| say k }) # iterate over semiprimes in the range [50, 100]
Aliases: each_semiprime
sphenic
sphenic(n)
sphenic(a, b)
Returns an array with the numbers with exactly three distinct prime factors <= n or in range a..b. (OEIS A007304)
say sphenic(200) #=> OEIS: A007304
Aliases: sphenic_numbers
sphenic_count
sphenic_count(n)
sphenic_count(a,b)
Count of the numbers with exactly three distinct prime factors <= n or in range a..b. (OEIS A215218)
say sphenic_count(1e10) #=> 1997171674
say sphenic_count(1e11) #=> 19522428788
sphenic_each
sphenic_each(n, {|k| ... })
sphenic_each(a, b, {|k| ... })
Iterate over the numbers with exactly three distinct prime factors <= n or in range a..b.
sphenic_each(500, 1000, {|k| say k })
squarefree_almost_prime_count
k.squarefree_almost_prime_count(n)
k.squarefree_almost_prime_count(a,b)
Returns the count of squarefree k-almost primes <= n, or in the range a..b.
say 1.squarefree_almost_prime_count(1000) # count of primes <= 1000
say 2.squarefree_almost_prime_count(50, 1000) # count of squarefree semiprimes in range 50..1000
Aliases: squarefree_almost_primepi, squarefree_pi_k
squarefree_almost_prime_sum
k.squarefree_almost_prime_sum(n)
k.squarefree_almost_prime_sum(a,b)
Returns the sum of squarefree k-almost primes <= n, or in the range a..b.
say 1.squarefree_almost_prime_sum(1000) # sum of primes <= 1000
say 2.squarefree_almost_prime_sum(50, 1000) # sum of squarefree semiprimes in range 50..1000
squarefree_almost_primes
k.squarefree_almost_primes(n)
k.squarefree_almost_primes(a,b)
Returns an array with the squarefree k-almost primes <= n, or in the range a..b.
say 2.squarefree_almost_primes(100) #=> squarefree semiprimes <= 100
say 2.squarefree_almost_primes(50, 100) #=> squarefree semiprimes in the range 50..100
say 3.squarefree_almost_primes(100) #=> squarefree 3-almost primes <= 100
say 3.squarefree_almost_primes(50, 100) #=> squarefree 3-almost primes in the range 50..100
squarefree_almost_primes_each
k.squarefree_almost_primes_each(n, {...})
k.squarefree_almost_primes_each(a,b,{...})
Iterates over the squarefree k-almost primes <= n, or in the range a..b.
# Iterate over squarefree 3-almost primes <= 100
3.squarefree_almost_primes_each(100, { .say })
# Iterate over squarefree 3-almost primes in the range 50..100
3.squarefree_almost_primes_each(50, 100, { . say })
Aliases: each_squarefree_almost_prime
squarefree_fermat_psp
k.squarefree_fermat_psp(base, n)
k.squarefree_fermat_psp(base, a, b)
Returns an array with all the squarefree Fermat pseudoprimes to the given base that are <= n or in the range a..b and have exactly k prime factors.
say 3.squarefree_fermat_psp(2, 10000) # squarefree 3-Fermat psp to base 2
say 4.squarefree_fermat_psp(2, 10000, 100000) # squarefree 4-Fermat psp to base 2 in range
squarefree_fermat_psp_each
k.squarefree_fermat_psp_each(base, n, { ... })
k.squarefree_fermat_psp_each(base, a, b, { ... })
Iterates over the squarefree Fermat pseudoprimes <= n or in the range a..b that have exactly k prime factors.
3.squarefree_fermat_psp_each(2, 1e5, {|n| say n }) # iterate over squarefree 3-Fermat psp to base 2 <= 1e5
4.squarefree_fermat_psp_each(2, 1e5, 1e6, {|n| say n }) # iterate over squarefree 4-Fermat psp to base 2 in range 1e4..1e6
Aliases: each_squarefree_fermat_psp
squarefree_semiprime_count
squarefree_semiprime_count(n)
squarefree_semiprime_count(a,b)
Counts the number of squarefree semiprimes <= n (OEIS A072613), or in the range a..b.
say 10.of {|k| squarefree_semiprime_count(10**k) } # OEIS: A036351
Aliases: squarefree_semiprimes_count
squarefree_semiprime_sum
squarefree_semiprime_sum(n)
squarefree_semiprime_sum(a,b)
Returns the sum of squarefree semiprimes <= n, or in the range a..b.
Aliases: squarefree_semiprimes_sum
squarefree_semiprimes
squarefree_semiprimes(n)
squarefree_semiprimes(a,b)
Returns an array with the squarefree semiprimes <= n, or in the range a..b.
say squarefree_semiprimes(100) # squarefree semiprimes <= 100
say squarefree_semiprimes(50, 100) # squarefree semiprimes in the range [50, 100]
squarefree_semiprimes_each
n.squarefree_semiprimes_each { ... }
squarefree_semiprimes_each(a,b, { ... })
Iterate over the squarefree semiprimes <= n, or in the range a..b:
100.squarefree_semiprimes_each {|k| say k } # iterate over squarefree semiprimes <= 100
squarefree_semiprimes_each(50, 100, {|k| say k }) # iterate over squarefree semiprimes in the range [50, 100]
Aliases: each_squarefree_semiprime
squarefree_strong_fermat_psp
k.squarefree_strong_fermat_psp(base, n)
k.squarefree_strong_fermat_psp(base, a, b)
Returns an array with all the squarefree strong Fermat pseudoprimes to the given base that are <= n or in the range a..b and have exactly k prime factors.
say 3.squarefree_strong_fermat_psp(2, 1e6) # squarefree strong 3-Fermat psp to base 2 <= 1e6
say 4.squarefree_strong_fermat_psp(2, 1e7, 1e8) # squarefree strong 4-Fermat psp to base 2, in range 1e7..1e8
squarefree_strong_fermat_psp_each
k.squarefree_strong_fermat_psp_each(base, n, { ... })
k.squarefree_strong_fermat_psp_each(base, a, b, { ... })
Iterates over the squarefree strong Fermat pseudoprimes <= n or in the range a..b that have exactly k prime factors.
3.squarefree_strong_fermat_psp_each(2, 1e6, {|n| say n }) # iterate over squarefree strong 3-Fermat psp to base 2 <= 1e6
4.squarefree_strong_fermat_psp_each(2, 1e7, 1e8, {|n| say n }) # iterate over squarefree strong 4-Fermat psp to base 2 in range 1e7..1e8
Aliases: each_squarefree_strong_fermat_psp
NUMBER THEORY: FACTORIZATION, GCD & LCM
chebyshev_factor
n.chebyshev_factor
n.chebyshev_factor(B)
n.chebyshev_factor(B,x)
Integer factorization method, based on Chebyshev polynomials, which have the following nesting property:
T_{m n}(x) = T_m(T_n(x))
which are efficiently computed using the Lucas V function V_n(P,Q):
T_n(x) = (1/2) * V_n(2x, 1)
This method is particularly effective for numbers that have a prime factor p such that p-1 or p+1 is B-smooth.
say chebyshev_factor(1124075136413 * 3556516507813, 4000, 3)
The product of the factors will give back n. However, some factors may be composite.
consecutive_lcm
consecutive_lcm(n)
Returns the least common multiple (LCM) of all the integers in the range 1..n.
Aliases: consecutive_integer_lcm
cop_factor
n.cop_factor(tries=n.ilog2)
Congruence of Powers (CoP) factorization method, trying to find algebraic factors of n.
say cop_factor((5**48 + 1)*(3**120 + 1))
An additional argument can be given to limit the number of iterations.
The product of the factors will give back n. However, some factors may be composite.
cyclotomic_factor
n.cyclotomic_factor
n.cyclotomic_factor(bases...)
Factorization method, based on cyclotomic polynomials, trying to find algebraic factors of n.
say cyclotomic_factor(2**120 + 1)
say cyclotomic_factor((10**258 - 1)/9 - 10**(258/2) - 1, 10)
An optional list of bases can be given to restrict the search only to the given bases.
The product of the factors will give back n. However, some factors may be composite.
dop_factor
n.dop_factor(tries=n.ilog2)
Difference of Powers (DoP) factorization method, trying to find algebraic factors of n.
say dop_factor(2**120 + 1)
An additional argument can be given to limit the number of iterations.
The product of the factors will give back n. However, some factors may be composite.
ecm_factor
n.ecm_factor
n.ecm_factor(B1)
n.ecm_factor(B1, curves)
Hendrik Lenstra's elliptic curve factorization method (ECM).
The product of the factors will give back n. However, some factors may be composite.
factor
factor(n)
factor(n, { ... })
Returns the prime factors of n (with repetition), sorted in ascending order.
For n <= 0, it returns an empty array.
say 180.factor #=> [2, 2, 3, 3, 5]
say 2023.factor #=> [7, 17, 17]
say factor(2**67 - 1) #=> [193707721, 761838257287]
say factor(1) #=> []
An optional block can specify custom factorization methods:
say factor(10**120 - 10**40, {|k| k.ecm_factor })
say factor(10**120 - 10**40, {|k| k.fermat_factor })
The block is expected to return an array with zero or more factors of k. These factors do not need to be prime. The block is applied recursively to each new composite factor until no further splitting is possible.
Aliases: factors
factor_exp
factor_exp(n)
Returns an array of pairs [p,k] factors p^k of n.
say 180.factor_exp #=> [[2, 2], [3, 2], [5, 1]]
Aliases: factors_exp
factor_map
n.factor_map {|p,k| ... }
Maps the prime-power factorization (p,k) of n to the given block.
say 5040.factor_map {|p,k| p**k } #=> [16, 9, 5, 7]
factor_prod
n.factor_prod {|p,k| ... }
Product of the mapping of the prime-power factorization of n.
say 5040.factor_prod {|p,k| (p-1) * p**(k-1) } #=> 1152
Equivalent with:
n.factor_map {|p,k| ... }.prod
Aliases: factors_prod
factor_sum
n.factor_sum {|p,k| ... }
Sum of the mapping of the prime-power factorization of n.
Equivalent with:
n.factor_map {|p,k| ... }.sum
Aliases: factors_sum
factor_upto
n.factor_upto(limit)
Returns an array of factors of n, using trial division, the Pollard Rho method and the Elliptic Curve method, based on heuristic bounds to find all the prime factors of n that are less than limit.
The product of the factors will give back n. However, the last factor may be composite.
NOTE: some factors may be larger than limit. Also, it's not guaranteed that a prime factor less than limit is always found, even when it exists.
fermat_factor
n.fermat_factor(k=1e4)
Tries to factorize a given number using Fermat's factorization method (using at most k iterations).
Works for odd composite nonpower numbers n that have two divisors close to sqrt(n).
The product of the factors will give back n. However, some factors may be composite.
fibonacci_factor
n.fibonacci_factor(upto = 2*n.ilog2)
Tries to find special factors of a Fibonacci-like number.
say fibonacci_factor(480.fib)
say fibonacci_factor(480.lucas)
The product of the factors will give back n. However, some factors may be composite.
Aliases: fib_factor
flt_factor
n.flt_factor(base=2, tries=1e4)
Tries to find a factor of n, using a new factorization method, inspired by Fermat's Little Theorem (FLT).
This method is particularly effective for numbers that have factors close to each other, or have a factor k for which znorder(2,k) is small.
Example (try with base 3 and give up after 10^6 iterations):
say flt_factor(2**64 + 1, 3, 1e6) #=> [274177, 67280421310721]
The product of the factors will give back n. However, some factors may be composite.
is_coprime
is_coprime(a,b)
Returns true if gcd(a,b) = 1.
gcd
gcd(...)
Returns the greatest common divisor of a list of integers.
With one argument, it returns the absolute value of that argument. By convention, gcd() is 0.
say gcd(54, 24) #=> 6
say gcd(-54, 24) #=> 6
say gcd(-42) #=> 42
say gcd() #=> 0
gcd_factors
n.gcd_factors([a, b, ...])
Given a positive integer and an array of integers, it tries to find nontrivial factors of n, checking each gcd(n, array[0]), gcd(n, array[1]), etc.
var n = 43*43*97*503
var a = [19*43*97, 1, 13*41*43*101]
say gcd_factors(n, a) #=> [43, 43, 97, 503]
The product of the factors gives back n. However, some factors may be composite.
gcdext
gcdext(a,b)
The extended greatest common divisor of a and b, returning (u, v, d), where d = gcd(a,b), while u and v are the coefficients satisfying:
u*a + v*b = d.
The value of d is always nonnegative.
gcud
gcud(...)
Returns the greatest common unitary divisor of a list of integers.
germain_factor
germain_factor(n)
Tries to factorize n, using the Sophie Germain identity:
x^4 + 4y^4 = (x^2 - 2xy + 2y^2) * (x^2 + 2xy + 2y^2)
The product of the factors will give back n. However, some factors may be composite.
Aliases: sophie_germain_factor
gpf
gpf(n)
Returns the greatest prime factor of n.
Defined with the base-cases:
gpf(0) = 0
gpf(1) = 1
Example:
say gpf(2**128 + 1) #=> 5704689200685129054721
gpf_sum
gpf_sum(n)
gpf_sum(a,b)
Returns the sum of largest prime factors of numbers from 1 to n, or in the range a..b. (OEIS A088822)
say 30.of { .gpf_sum } #=> OEIS: A088822
holf_factor
n.holf_factor(tries=1e4)
Hart's OLF method (variant of Fermat's method).
The product of the factors will give back n. However, some factors may be composite.
lcm
lcm(...)
Returns the least common multiple of a list of integers.
With one argument, it returns the absolute value of that argument. By convention, lcm() is 1.
say lcm(6, 10) #=> 30
say lcm(-6, 10) #=> 30
say lcm(21) #=> 21
say lcm() #=> 1
lpf
lpf(n)
Returns the least prime factor of n.
Defined with the base-cases:
lpf(0) = 0
lpf(1) = 1
Example:
say lpf(fibonacci(1234)) #=> 234461
lpf_sum
lpf_sum(n)
lpf_sum(a,b)
Returns the sum of least prime factors of numbers from 1 to n, or in the range a..b. (OEIS A088821)
say 30.of { .lpf_sum } #=> OEIS: A088821
lucas_factor
n.lucas_factor(j=1, tries=100)
A factorization method, using the modular Lucas sequences, which is effective in factoring Carmichael numbers, Fermat pseudoprimes, Lucas pseudoprimes and Lucas-Carmichael numbers.
say lucas_factor(2425361208749736840354501506901183117777758034612345610725789878400467)
The product of the factors will give back n. However, some factors may be composite.
Aliases: lucas_miller_factor
mbe_factor
n.mbe_factor(tries=10)
Tries to find a factor of n, by using the "Modular Binary Exponentiation" factorization method (randomized version).
This method is particularly effective for numbers that contain a prime factor p such that p-1 is sufficiently smooth.
The running time of the method, is: O(tries * log(n)^2).
Example:
say mbe_factor(2**64 + 1, 1) #=> [274177, 67280421310721]
The product of the factors will give back n. However, some factors may be composite.
miller_factor
n.miller_factor(tries=100)
A factorization method, based on the Miller-Rabin primality test. Effective in factoring Carmichael numbers and Fermat pseudoprimes.
It returns an array with the factors of n. The product of the factors will give back n. However, some factors may be composite.
Aliases: miller_rabin_factor
pell_factor
n.pell_factor(tries=1e4)
Pell factorization method, trying to find a factor of n.
This method is particularly effective for numbers that have factors close to sqrt(n).
say pell_factor(10**120 - 10**40)
The product of the factors will give back n. However, some factors may be composite.
phi_finder_factor
n.phi_finder_factor(tries=1e4)
Tries to find a factor of n, using the Phi-finder factorization method due to Kyle Kloster (2010).
This method is particularly effective for semiprimes n = p*q such that p and q are relatively close to each other.
Example:
say phi_finder_factor(622882096110539) #=> [23099599, 26965061]
say phi_finder_factor(132750061135361, 1e5) #=> [9369673, 14168057]
The product of the factors will give back n. However, some factors may be composite.
pm1_factor
n.pm1_factor
n.pm1_factor(B)
Pollard p-1 factorization method.
The product of the factors will give back n. However, some factors may be composite.
Aliases: pminus1_factor
pp1_factor
n.pp1_factor(B)
Williams' p+1 factorization method.
The product of the factors will give back n. However, some factors may be composite.
Aliases: pplus1_factor
prime_divisors
prime_divisors(n)
Returns the unique prime factors of n.
prime_signature
n.prime_signature
Given a non-negative integer n, returns the prime signature of n.
This is the exponents of the prime-power factorization of n, sorted in descending order.
say prime_signature(324) #=> [4, 2] (324 = 2^2 * 3^4)
say 30.of { .prime_signature.prod_kv{|k,v| prime(k+1)**v } } #=> OEIS: A046523
prime_signature_inverse
prime_signature_inverse(A, B, prime_signature)
Returns an array of numbers in range [A, B] that have a given prime signature.
say prime_signature_inverse(1, 1e3, [1]) #=> prime numbers
say prime_signature_inverse(1, 1e3, [2]) #=> squares of numbers
say prime_signature_inverse(1, 1e3, [2,1]) #=> squares of primes times another prime
say prime_signature_inverse(1, 1e3, [2,1,1]) #=> numbers of the form p^2*q*r
Aliases: prime_signature_numbers.
prime_signature_inverse_len
prime_signature_inverse_len(A, B, prime_signature)
Count numbers in range [A, B] that have a given prime signature.
say 10.of {|n| prime_signature_inverse_len(1, 10**n, [1]) } # prime number count
say 10.of {|n| prime_signature_inverse_len(1, 10**n, [1,1]) } # A036351
say 10.of {|n| prime_signature_inverse_len(1, 10**n, [1,1,1]) } # A215218
Aliases: prime_signature_count.
qs_factor
qs_factor(n)
Pomerance's Quadratic Sieve factorization method (SIMPQS).
The product of the factors will give back n. However, some factors may be composite.
rho_brent_factor
n.rho_brent_factor
n.rho_brent_factor(tries)
Pollard-Brent rho factorization method.
The product of the factors will give back n. However, some factors may be composite.
rho_factor
n.rho_factor
n.rho_factor(tries)
Pollard rho factorization method.
The product of the factors will give back n. However, some factors may be composite.
special_factor
n.special_factor(tries=1)
Tries to find special factors of n, using various special-factorization methods, including trial division, p-1 method, p+1 method, HOLF method, Fermat method, Pell method, Miller-Rabin method and the Lucas-Miller method.
An additional optional argument can be given to increase the number of tries by the given factor. For example, tries = 2 will double the number of tries.
The method returns an array with the factors of n:
say special_factor((3**120 + 1) * (5**240 - 1))
The product of the factors will give back n. However, some factors may be composite.
Aliases: special_factors
squfof_factor
n.squfof_factor(tries=1e4)
Shanks' SQUFOF method.
The product of the factors will give back n. However, some factors may be composite.
trial_factor
n.trial_factor(limit)
Trial division.
The product of the factors will give back n. However, some factors may be composite.
valuation
n.valuation(k)
Returns the number of times n is divisible by k.
say valuation(2**32, 4) # prints: 16
NUMBER THEORY: DIVISORS & DIVISOR SUMS
abundancy
abundancy(n)
Returns the abundancy index of n, defined as:
sigma(n)/n
Aliases: abundancy_index
aliquot
aliquot(n)
Returns the sum of divisors of n that are less than n.
Equivalent with:
sigma(n) - n
antidivisor_count
antidivisor_count(n)
Returns the number of antidivisors of n.
say antidivisor_count(13) #=> 4
say antidivisor_count(27) #=> 5
antidivisor_sum
antidivisor_sum(n, k=1)
Returns the sum of anti-divisors of n.
When k is specified, it computes the sum of d**k for all antidivisors d of n.
Aliases: antidivisor_sigma
antidivisors
antidivisors(n)
Returns an array with the antidivisors of n sorted from 1..n.
Antidivisors of n are numbers that do not divide n by the largest possible margin.
say antidivisors(24) #=> [7, 16]
say antidivisors(128) #=> [3, 5, 15, 17, 51, 85]
bdivisors
bdivisors(n)
Returns an array with the bi-unitary divisors of n.
say 48.bdivisors #=> [1, 2, 3, 6, 8, 16, 24, 48]
These are divisors d of n that satisfy:
gcud(n/d, d) = 1
Aliases: biudivisors, bi_unitary_divisors
bsigma
bsigma(n, k=1)
Returns the sum of the bi-unitary divisors of n, each divisor raised to the k-th power. (OEIS A188999)
say 20.of { .bsigma } #=> OEIS: A188999
Aliases: biusigma
bsigma0
bsigma0(n)
Returns the count of the bi-unitary divisors of n. (OEIS A286324)
say 20.of { .bsigma0 } #=> OEIS: A286324
Aliases: biusigma0
bsigma0_sum
bsigma0_sum(n)
Sum of number of bi-unitary divisors of k for k=1..n.
say 30.of { .bsigma0_sum } #=> OEIS: A306069
bsigma_sum
bsigma_sum(n,k=1)
Sum of the bsigma(x,k) function, for x = 1..n.
say 30.of { .bsigma_sum(0) } # OEIS: A306069
say 30.of { .bsigma_sum } # OEIS: A307159
cube_divisors
n.cube_divisors
Returns the cube divisors of n.
say 10!.cube_divisors #=> [1, 8, 27, 64, 216, 1728]
Equivalent with:
n.divisors.grep { .is_cube }
cube_sigma
n.cube_sigma(k=1)
Sum of the cube divisors of n, each divisor raised to the power k.
say 10!.cube_sigma #=> 2044
say 10!.cube_sigma(2) #=> 3037530
Equivalent with:
n.cube_divisors.sum {|d| d**k }
cube_sigma0
n.cube_sigma0
Returns the count of cube divisors of n.
cube_udivisors
n.cube_udivisors
Returns the unitary cube divisors of n, such that each divisor d is a cube and gcd(n/d, d) = 1.
say 15!.cube_udivisors #=> [1, 125, 729, 91125]
cube_usigma
n.cube_usigma(k=1)
Sum of the unitary cube divisors of n, each divisor raised to power k.
say cube_usigma(15!) #=> 91980
say cube_usigma(15!, 2) #=> 8304312692
Equivalent with:
n.cube_udivisors.sum {|d| d**k }
cube_usigma0
n.cube_usigma0
Returns the count of unitary cube divisors of n.
cubefree_divisors
n.cubefree_divisors
Returns an array with the cubefree divisors of n.
say cubefree_divisors(120) #=> [1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30, 60]
cubefree_sigma
n.cubefree_sigma(k=1)
Sum of the cubefree divisors of n, each divisor raised to power k.
say cubefree_sigma(5040) #=> 4368
say cubefree_sigma(5040, 2) #=> 2484300
cubefree_sigma0
n.cubefree_sigma0
Returns the count of cubefree divisors of n.
cubefree_udivisors
n.cubefree_udivisors
Returns the unitary cubefree divisors of n.
say cubefree_udivisors(5040) #=> [1, 5, 7, 9, 35, 45, 63, 315]
cubefree_usigma
n.cubefree_usigma(k=1)
Sum of the unitary cubefree divisors of n, each divisor raised to power k.
say 5040.cubefree_usigma #=> 480
say 5040.cubefree_usigma(2) #=> 106600
cubefree_usigma0
n.cubefree_usigma0
Returns the number of unitary cubefree divisors of n.
say cubefree_usigma0(5040) #=> 8
cubefull_divisors
cubefull_divisors(n)
Return an array with the cubefull (3-powerful) divisors of n.
cubefull_sigma
cubefull_sigma(n, j=1)
Sum of the cubefull (3-powerful) divisors of n, each divisor raised to the power j.
cubefull_sigma0
cubefull_sigma0(n)
Count of the cubefull (3-powerful) divisors of n.
cubefull_udivisors
cubefull_udivisors(n)
Return an array with the unitary cubefull (3-powerful) divisors of n.
cubefull_usigma
cubefull_usigma(n, j=1)
Sum of the unitary cubefull (3-powerful) divisors of n, each divisor raised to the power j.
cubefull_usigma0
cubefull_usigma0(n)
Count of the unitary cubefull (3-powerful) divisors of n.
divisors
n.divisors(k=n)
Returns an array with the positive divisors of n that are less than or equal to k.
When k is omitted, all positive divisors of n are returned in ascending order. Non-positive inputs produce an empty array.
say 120.divisors #=> [1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 20, 24, 30, 40, 60, 120]
say 120.divisors(13) #=> [1, 2, 3, 4, 5, 6, 8, 10, 12]
say 0.divisors #=> []
divisors_each
n.divisors_each {|d| ... }
Lazily iterate over the divisors d of n. (not in sorted order)
24.divisors_each {|d| say d }
Aliases: divisor_each
divisors_map
n.divisors_map {|d| ... }
Maps the divisors of n to the given block.
say 24.divisors_map {|d| 1/d } #=> [1, 1/2, 1/3, 1/4, 1/6, 1/8, 1/12, 1/24]
Aliases: divisor_map
divisors_prod
n.divisors_prod {|d| ... }
Product of the mapping of the positive divisors of n.
Equivalent with:
n.divisors_map {|d| ... }.prod
Aliases: divisor_prod
divisors_sum
n.divisors_sum {|d| ... }
Sum of the mapping of the positive divisors of n.
say 5040.divisors_sum {|d| euler_phi(d)**2 } #=> 2217854
Equivalent with:
n.divisors_map {|d| ... }.sum
Aliases: divisor_sum
edivisors
edivisors(n)
Returns an array with the exponential divisors (or e-divisors) of n.
say edivisors(5040) #=> [210, 420, 630, 1260, 1680, 5040]
Aliases: exponential_divisors
esigma
esigma(n, k=1)
Returns the sum of the exponential divisors (or e-divisors) of n, each divisor raised to k-th power. (OEIS A051377)
say 20.of { .esigma } #=> OEIS: A051377
esigma0
esigma0(n)
Returns the count of the exponential divisors (or e-divisors) of n. (OEIS A049419)
say 20.of { .esigma0 } #=> OEIS: A049419
idivisors
n.idivisors
Returns an array with the infinitary divisors (or i-divisors) of n.
say 96.idivisors #=> [1, 2, 3, 6, 16, 32, 48, 96]
Aliases: infinitary_divisors
inverse_count
inverse_count(target, count_func, bsearch_method='bsearch_min')
Finds the smallest integer m >= 0 such that count_func(m) >= target.
This method implements the following search strategy:
1. Exponential Search: Rapidly doubles the search range to find an upper bound hi such that count_func(hi) >= target.
2. Binary Search: Refines the range between lo and hi using the specified bsearch_method (defaults to 'bsearch_min').
The complexity is logarithmic relative to the value of the result, making it suitable for inverting monotonic functions like prime counts or smooth counts. Returns NaN if target is negative.
say inverse_count(25, { .prime_count }) #=> 97
say inverse_count(100, { 10.smooth_count(_) }) #=> 450
isigma
isigma(n, k=1)
Returns the sum of the infinitary divisors of n, each divisor raised to the k-th power. (OEIS A049417)
say 20.of { .isigma } #=> OEIS: A049417
isigma0
isigma0(n)
Returns the count of the infinitary divisors of n. (OEIS A037445)
say 20.of { .isigma0 } #=> OEIS: A037445
isigma0_sum
isigma0_sum(n)
Sum of number of infinitary divisors of k for k=1..n.
say 30.of { .isigma0_sum } #=> OEIS: A327573
isigma_sum
isigma_sum(n, k=1)
Sum of the isigma(x,k) function, for x=1..n.
say 30.of { .isigma_sum(0) } # OEIS: A327573
say 30.of { .isigma_sum } # OEIS: A327566
nbdivisors
nbdivisors(n)
Returns an array with the non-bi-unitary divisors of n.
say 720.nbdivisors #=> [3, 4, 6, 12, 15, 20, 24, 30, 36, 48, 60, 120, 180, 240]
Equivalent to the set difference between the divisors and the bi-unitary-divisors:
divisors(n) - bdivisors(n) == nbdivisors(n)
These are divisors d of n that satisfy:
gcud(n/d, d) != 1
Aliases: non_bi_unitary_divisors, nbiudivisors
nbsigma
nbsigma(n, k=1)
Returns the sum of the non-bi-unitary divisors of n, each divisor raised to the k-th power. (OEIS A319072)
say 30.of { .nbsigma } #=> OEIS: A319072
nbsigma0
nbsigma0(n)
Returns the count of the non-bi-unitary divisors of n.
nbsigma0_sum
nbsigma0_sum(n)
Sum of number of non-bi-unitary divisors of k for k=1..n.
say 30.of { .nbsigma0_sum } # Partial sums of OEIS A390957
nbsigma_sum
nbsigma_sum(n,k=1)
Sum of the nbsigma(x,k) function, for x = 1..n.
say 30.of { .nbsigma_sum(0) } # Partial sums of OEIS A390957
say 30.of { .nbsigma_sum } # Partial sums of OEIS A319072
nedivisors
nedivisors(n)
Returns an array with the nonexponential divisors of n.
say 120.nedivisors #=> [1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 20, 24, 40, 60]
Equivalent to the set difference between the divisors and the exponential divisors:
divisors(n) - edivisors(n) == nedivisors(n)
Aliases: non_exponential_divisors
nesigma
nesigma(n, k=1)
Returns the sum of the nonexponential divisors of n, each divisor raised to the k-th power. (OEIS A160135)
say 30.of { .nesigma } #=> OEIS: A160135
nesigma0
nesigma0(n)
Returns the count of the nonexponential divisors of n. (OEIS A160097)
say 30.of { .nesigma0 } #=> OEIS: A160097
next_tau_inverse
next_tau_inverse(n, k)
Returns the next number, greater than n, that has exactly k divisors.
nidivisors
nidivisors(n)
Returns an array with the noninfinitary divisors of n.
say 240.nidivisors #=> [2, 4, 6, 8, 10, 12, 20, 24, 30, 40, 60, 120]
Equivalent to the set difference between the divisors and the infinitary divisors:
divisors(n) - idivisors(n) == nidivisors(n)
Aliases: non_infinitary_divisors
nisigma
nisigma(n, k=1)
Returns the sum of the noninfinitary divisors of n, each divisor raised to the k-th power. (OEIS A348271)
say 30.of { .nisigma } #=> OEIS: A348271
nisigma0
nisigma0(n)
Returns the count of the noninfinitary divisors of n. (OEIS A348341)
say 30.of { .nisigma0 } #=> OEIS: A348341
nisigma0_sum
nisigma0_sum(n)
Sum of number of noninfinitary divisors of k for k=1..n.
say 30.of { .nisigma0_sum } # Partial sums of OEIS A348341
nisigma_sum
nisigma_sum(n,k=1)
Sum of the nisigma(x,k) function, for x = 1..n.
say 30.of { .nisigma_sum(0) } # Partial sums of OEIS A348341
say 30.of { .nisigma_sum } # Partial sums of OEIS A348271
nudivisors
nudivisors(n)
Returns an array with the non-unitary divisors of n.
say 120.nudivisors #=> [2, 4, 6, 10, 12, 20, 30, 60]
Equivalent to the set difference between the divisors and the unitary-divisors:
divisors(n) - udivisors(n) == nudivisors(n)
These are divisors d of n that satisfy:
gcd(n/d, d) != 1
Aliases: non_unitary_divisors
nusigma
nusigma(n, k=1)
Returns the sum of the nonunitary divisors of n, each divisor raised to the k-th power. (OEIS A048146)
say 30.of { .nusigma } #=> OEIS: A048146
nusigma0
nusigma0(n)
Returns the count of the nonunitary divisors of n. (OEIS A048105)
say 30.of { .nusigma0 } #=> OEIS: A048105
nusigma0_sum
nusigma0_sum(n)
Sum of number of nonunitary divisors of k for k=1..n.
say 30.of { .nusigma0_sum } # Partial sums of OEIS A048105
nusigma_sum
nusigma_sum(n,k=1)
Sum of the nusigma(x,k) function, for x = 1..n.
say 30.of { .nusigma_sum(0) } # Partial sums of OEIS A048105
say 30.of { .nusigma_sum } # Partial sums of OEIS A048146
power_divisors
k.power_divisors(n)
Return an array with the k-th power divisors of n.
say 3.power_divisors(10!) #=> [1, 8, 27, 64, 216, 1728]
say 4.power_divisors(10!) #=> [1, 16, 81, 256, 1296, 20736]
Equivalent with:
n.divisors.grep { .is_power(k) }
power_sigma
k.power_sigma(n, j=1)
Returns the sum of the k-th power divisors of n, each divisor raised to the power j.
say 30.of { 2.power_sigma(_) } # OEIS: A035316
say 30.of { 3.power_sigma(_) } # OEIS: A113061
Equivalent with (but much faster):
n.divisors.grep { .is_power(k) }.sum {|d| d**j }
power_sigma0
k.power_sigma0(n)
Returns the number of the k-th power divisors of n.
say 30.of { 2.power_sigma0(_) } # OEIS: A046951
power_udivisors
k.power_udivisors(n)
Returns an array with the k-th power unitary divisors of n.
say 2.power_udivisors(15!) #=> [1, 49, 729, 35721]
say 3.power_udivisors(15!) #=> [1, 125, 729, 91125]
Equivalent with:
n.udivisors.grep { .is_power(k) }
Aliases: power_unitary_divisors, unitary_power_divisors
power_usigma
k.power_usigma(n, j=1)
Returns the sum of the k-th power unitary divisors of n, each divisor raised to the power j.
Equivalent with (but much faster):
n.udivisors.grep { .is_power(k) }.sum {|d| d**j }
power_usigma0
k.power_usigma0(n)
Returns the number of the k-th power unitary divisors of n.
say 30.of { 2.power_usigma0(_) } # OEIS: A056624
powerfree_divisors
k.powerfree_divisors(n)
Returns an array with the k-powerfree divisors of n.
say 2.powerfree_divisors(5040) # squarefree divisors of 5040
say 3.powerfree_divisors(5040) # cubefree divisors of 5040
powerfree_sigma
k.powerfree_sigma(n, j=1)
Returns the sum of the k-powerfree divisors of n, each divisor raised to the power j.
say 30.of { 2.powerfree_sigma(_) } # OEIS: A048250
say 30.of { 3.powerfree_sigma(_) } # OEIS: A073185
Equivalent with (but much faster):
n.divisors.grep { .is_powerfree(k) }.sum {|d| d**j }
powerfree_sigma0
k.powerfree_sigma0(n)
Returns the number of the k-powerfree divisors of n.
say 30.of { 3.powerfree_sigma0(_) } # OEIS: A073184
powerfree_udivisors
k.powerfree_udivisors(n)
Returns an array with the k-powerfree unitary divisors of n.
say 2.powerfree_udivisors(5040) # squarefree unitary divisors of 5040
say 3.powerfree_udivisors(5040) # cubefree unitary divisors of 5040
Equivalent with (but much faster):
n.udivisors.grep { .is_powerfree(k) }
k.powerfree_divisors(n).grep {|d| gcd(n/d, d) == 1 }
powerfree_usigma
k.powerfree_usigma(n, j=1)
Returns the sum of the k-powerfree unitary divisors of n, each divisor raised to the power j.
say 20.of { 2.powerfree_usigma(_) } # OEIS: A092261
say 20.of { 2.powerfree_usigma(_, 2) } # OEIS: A091306
Equivalent with (but much faster):
n.udivisors.grep { .is_powerfree(k) }.sum {|d| d**j }
powerfree_usigma0
k.powerfree_usigma0(n)
Returns the number of the k-powerfree unitary divisors of n.
say 20.of { 2.powerfree_usigma0(_) } # OEIS: A056671
powerful_divisors
k.powerful_divisors(n)
Returns an array with the k-powerful divisors of n.
powerful_sigma
k.powerful_sigma(n, j=1)
Sum of the k-powerful divisors of n, each divisor raised to the power j.
say 2.powerful_sigma(n) # OEIS: A183097
say 3.powerful_sigma(n) # OEIS: A385005
powerful_sigma0
k.powerful_sigma0(n)
Count the number of k-powerful divisors of n.
powerful_udivisors
k.powerful_udivisors(n)
Returns an array with the unitary k-powerful divisors of n.
Aliases: unitary_powerful_divisors, powerful_unitary_divisors
powerful_usigma
k.powerful_usigma(n, j=1)
Sum of the unitary k-powerful divisors of n, each divisor raised to the power j.
say 30.of{|n| 2.powerful_usigma(n) } # OEIS: A360720
say 30.of{|n| 3.powerful_usigma(n) } # OEIS: A385048
powerful_usigma0
k.powerful_usigma0(n)
Count the number of unitary k-powerful divisors of n.
pp_divisors
pp_divisors(n)
Returns an array with the perfect power divisors of n.
say 5040.pp_divisors #=> [1, 4, 8, 9, 16, 36, 144]
Equivalent with:
n.divisors.grep { .is_perfect_power }
Aliases: perfect_power_divisors
pp_udivisors
pp_udivisors(n)
Returns an array with the perfect power unitary divisors of n, such that each divisor d is a perfect power and gcd(n/d, d) = 1.
say 15!.pp_udivisors #=> [1, 49, 125, 729, 2048, 35721, 91125]
Equivalent with:
n.udivisors.grep { .is_perfect_power }
Aliases: perfect_power_udivisors, perfect_power_unitary_divisors
prev_tau_inverse
prev_tau_inverse(n, k)
Returns the previous number, smaller than n, that has exactly k divisors.
prime_power_divisors
n.prime_power_divisors
Returns the prime power divisors of n.
say prime_power_divisors(5040) #=> [2, 3, 4, 5, 7, 8, 9, 16]
Equivalent with:
n.divisors.grep{.is_prime_power}
prime_power_sigma
n.prime_power_sigma(k=1)
Sum of the prime power divisors of n, each divisor raised to the k-th power.
say prime_power_sigma(10!) #=> 667
say prime_power_sigma(10!, 2) #=> 95459
Equivalent with:
n.prime_power_divisors.sum {|d| d**k }
prime_power_sigma0
prime_power_sigma0(n)
Returns the count of prime power divisors of n.
Equivalent with:
bigomega(n)
prime_power_udivisors
prime_power_udivisors(n)
Returns the unitary prime power divisors of n.
say prime_power_udivisors(10!) #=> [7, 25, 81, 256]
The product of the unitary prime power divisors of a number, is the number itself.
This method is equivalent with:
n.factor_map {|p,k| p**k }.sort
Aliases: prime_power_unitary_divisors, unitary_prime_power_divisors
prime_power_usigma
Number.prime_power_usigma(k=1)
Returns the sum of the unitary prime power divisors of n, each divisor raised to power k.
say prime_power_usigma(10!) #=> 369 (== 7 + 25 + 81 + 256)
say prime_power_usigma(10!, 2) #=> 72771 (== 7^2 + 25^2 + 81^2 + 256^2)
Equivalent with:
n.factor_map {|p,e| p**(e * k) }.sum
prime_power_usigma0
prime_power_usigma0(n)
Returns the count of unitary prime power divisors of n.
Equivalent with:
omega(n)
prime_sigma
n.prime_sigma(k=1)
Sum of the unique prime divisors of n, each divisor raised to the k-th power.
say prime_sigma(100!) #=> 1060
say prime_sigma(100!, 2) #=> 65796
prime_sigma0
prime_sigma0(n)
Returns the count of prime divisors of n.
Equivalent with:
omega(n)
prime_udivisors
n.prime_udivisors
Returns the unique unitary prime factors of n.
Aliases: prime_unitary_divisors, unitary_prime_divisors
prime_usigma
n.prime_usigma(k=1)
Sum of the unique unitary prime divisors of n, each divisor raised to the k-th power.
say prime_usigma(100!) #=> 732
say prime_usigma(100!, 2) #=> 55330
prime_usigma0
prime_usigma0(n)
The number of unique unitary prime divisors of n.
proper_divisors
n.proper_divisors
Return an array with the divisors of n less than n.
say proper_divisors(6) #=> [1, 2, 3]
proper_sigma0
n.proper_sigma0
Returns the number of proper divisors of n.
say proper_sigma0(6) #=> 3
Aliases: proper_divisor_count
sigma
sigma(n,k=1)
Returns the sum of the positive divisors of n, each raised to the power k.
The default k = 1 gives the usual sum-of-divisors function. When k = 0, it is equivalent to sigma0(n). Negative values of k return the reciprocal divisor-power sum as a rational value.
say sigma(12) #=> 28
say sigma(12, 0) #=> 6
say sigma(12, 2) #=> 210
say sigma(12, -1).as_frac #=> 7/3
Aliases: σ
sigma0
sigma0(n)
Returns the count of positive divisors of n.
Aliases: d, tau
sigma0_sum
sigma0_sum(n)
Sum of the sigma_0(k) function, for k = 1..n.
say 30.of { .sigma0_sum } #=> OEIS: A006218
Aliases: tau_sum
sigma_inverse
n.sigma_inverse(k=1)
Returns an array with all the solutions x to the sigma sum of divisors function: sigma(x,k) = n.
say sigma_inverse(42) #=> [20, 26, 41]
say sigma_inverse(22100, 2) #=> [120, 130, 141]
Also works with arbitrary large integers:
say sigma_inverse(9325257382230393314439814176)
Aliases: inverse_sigma
sigma_inverse_len
n.sigma_inverse_len(k=1)
Returns the number of solutions to the sigma sum of divisors function: sigma_k(x) = n.
Equivalent to n.sigma_inverse(k).len, but much faster.
Aliases: inverse_sigma_len
sigma_inverse_max
n.sigma_inverse_max(k=1)
Returns the largest solution x to the sum of divisors function: sigma_k(x) = n.
Equivalent to n.sigma_inverse(k).max, but much faster.
Returns nil if there are no solutions.
Aliases: inverse_sigma_max
sigma_inverse_min
n.sigma_inverse_min(k=1)
Returns the smallest solution x to the sum of divisors function: sigma_k(x) = n.
Equivalent to n.sigma_inverse(k).min, but much faster.
Returns nil if there are no solutions.
Aliases: inverse_sigma_min
sigma_sum
sigma_sum(n, k=1, j=0)
Returns the sum of m^j * sigma_k(m), for m=1..n, computed in O(sqrt(n)) steps.
say sigma_sum(100, 0) #=> 482
say sigma_sum(100, 1) #=> 8299
say sigma_sum(100, 2) #=> 407819
say sigma_sum(100, 2, 3) #=> 207528104123
square_divisors
square_divisors(n)
Returns the square divisors of n.
say 5040.square_divisors #=> [1, 4, 9, 16, 36, 144]
Equivalent with:
n.divisors.grep { .is_square }
square_sigma
n.square_sigma(k=1)
Sum of the square divisors of n, each divisor raised to the power k.
say 5040.square_sigma #=> 210
say 5040.square_sigma(2) #=> 22386
Equivalent with:
n.square_divisors.sum {|d| d**k }
square_sigma0
square_sigma0(n)
Returns the count of square divisors of n.
square_udivisors
square_udivisors(n)
Returns the unitary square divisors of n, such that each divisor d is a square and gcd(n/d, d) = 1.
say 5040.square_udivisors #=> [1, 9, 16, 144]
square_usigma
n.square_usigma(k=1)
Sum of the unitary square divisors of n, each divisor raised to power k.
say square_usigma(5040) #=> 170
say square_usigma(5040, 2) #=> 21074
Equivalent with:
n.square_udivisors.sum {|d| d**k }
square_usigma0
square_usigma0(n)
Returns the count of unitary square divisors of n.
squarefree_divisors
squarefree_divisors(n)
Returns an array with the squarefree divisors of n.
say squarefree_divisors(120) #=> [1, 2, 3, 5, 6, 10, 15, 30]
squarefree_sigma
squarefree_sigma(n,k=1)
Sum of the squarefree divisors of n, each divisor raised to power k.
say squarefree_sigma(5040) #=> 576
say squarefree_sigma(5040, 2) #=> 65000
squarefree_udivisors
squarefree_udivisors(n)
Returns the unitary squarefree divisors of n.
say squarefree_udivisors(5040) #=> [1, 5, 7, 35]
squarefree_usigma
n.squarefree_usigma(k=1)
Sum of the unitary squarefree divisors of n, each divisor raised to power k.
say 5040.squarefree_usigma #=> 48
say 5040.squarefree_usigma(2) #=> 1300
squarefree_usigma0
squarefree_usigma0(n)
Returns the number of unitary squarefree divisors of n.
say squarefree_usigma0(5040) #=> 4
squarefull_divisors
squarefull_divisors(n)
Return an array with the squarefull (2-powerful) divisors of n.
squarefull_sigma
squarefull_sigma(n, j=1)
Sum of the squarefull (2-powerful) divisors of n, each divisor raised to the power j.
squarefull_sigma0
squarefull_sigma0(n)
Count of the squarefull (2-powerful) divisors of n.
squarefull_udivisors
squarefull_udivisors(n)
Return an array with the unitary squarefull (2-powerful) divisors of n.
squarefull_usigma
squarefull_usigma(n, j=1)
Sum of the unitary squarefull (2-powerful) divisors of n, each divisor raised to the power j.
squarefull_usigma0
squarefull_usigma0(n)
Count of the unitary squarefull (2-powerful) divisors of n.
tau
Num.tau
tau(n)
Returns the TAU constant (2*PI), or the number of positive divisors of n (i.e.: sigma_0(n)).
say Num.tau #=> 6.283185307179...
say tau(120) #=> 16
Aliases: τ
tau_inverse
See tau_inverse_len below for the shared documentation of both inverse methods.
tau_inverse_len
tau_inverse(A, B, n)
tau_inverse_len(A, B, n)
Generate or count the numbers k in the range [A, B] such that tau(k) = n, where tau(k) is the number of positive divisors of k (i.e.: sigma_0(k)).
say tau_inverse(1, 100, 6) # numbers with exactly 6 divisors in range [1, 100]
say tau_inverse(1, 2**40, 5040) # numbers with exactly 5040 divisors in range [1, 2^40]
say tau_inverse_len(1, 100, 6) # count the numbers with exactly 6 divisors in range [1, 100]
say tau_inverse_len(1, 2**40, 5040) # count the numbers with exactly 5040 divisors in range [1, 2^40]
udivisors
udivisors(n)
Returns an array with the unitary divisors of n.
say 120.udivisors #=> [1, 3, 5, 8, 15, 24, 40, 120]
These are divisors d of n that satisfy:
gcd(n/d, d) = 1
Aliases: unitary_divisors
usigma
usigma(n, k=1)
Returns the sum of the unitary divisors of n, each divisor raised to the power k.
usigma0
usigma0(n)
Returns the count of unitary divisor of n.
Equivalently, the count of squarefree divisors of n.
say usigma0(5040) #=> 16
Aliases: squarefree_sigma0
usigma0_sum
usigma0_sum(n)
Sum of number of unitary divisors of k for k=1..n.
say 30.of { .usigma0_sum } #=> OEIS: A064608
usigma_inverse
n.usigma_inverse
Returns an array with all the solutions x to usigma(x) = n.
say usigma_inverse(120) #=> [60, 87, 92, 95, 99]
Aliases: inverse_usigma
usigma_sum
usigma_sum(n, k=1)
Sum of the usigma(x,k) function, for x = 1..n.
say 30.of { .usigma_sum } #=> OEIS: A064609
say 30.of { .usigma_sum(0) } #=> OEIS: A064608
NUMBER THEORY: TOTIENTS & MULTIPLICATIVE FUNCTIONS
bigomega
bigomega(n,k=0)
For k = 0, it returns the number of prime factors of n (counted with multiplicity).
In general, is equivalent with:
n.prime_power_divisors.sum {|d| n**k / d**k }
Aliases: Ω
bigomega_inverse
See bigomega_inverse_sum below for the shared documentation of all three inverse methods.
bigomega_inverse_len
See bigomega_inverse_sum below for the shared documentation of all three inverse methods.
bigomega_inverse_sum
bigomega_inverse(A, B, n)
bigomega_inverse_len(A, B, n)
bigomega_inverse_sum(A, B, n)
Generate, count, or sum the numbers k in the range [A, B] such that Ω(k) = n, where Ω(k) is the number of prime factors of k, counted with multiplicity.
say bigomega_inverse(1, 100, 3)
# means: (1..100).grep { .bigomega == 3 }
say bigomega_inverse_len(1, 100, 3)
# means: (1..100).count { .bigomega == 3 }
say bigomega_inverse_sum(1, 100, 3)
# means: (1..100).grep { .bigomega == 3 }.sum
bigomega_sum
bigomega_sum(n, k=0)
Returns the sum of the generalized Omega function Ω_k(j), for j=1..n.
say bigomega_sum(100, 0) #=> 239
say bigomega_sum(100, 1) #=> 2815
say bigomega_sum(100, 2) #=> 66799
bphi
bphi(n)
The bi-unitary analog of Euler's totient function of n. (OEIS A116550)
cototient
cototient(n, k=1)
Generalized cototient function:
n^k - J_k(n)
where J_k(n) is the Jordan totient function.
For k=1, it equals: n - phi(n).
cototient_sum
cototient_sum(n, k=1)
Partial sums of the generalized cototient function, equivalent to:
faulhaber_sum(n, k) - totient_sum(n, k)
dconv
n.dconv(f,g)
The Dirichlet convolution of functions f and g, defined as:
Sum_{d|n} f(d) * g(n/d)
Example:
say 20.of { .dconv({.moebius}, {_}) }
Aliases: dirichlet_convolution
derivative
derivative(n)
Arithmetic derivative of n, defined for rationals and integers (positive and negative).
say derivative(5040) #=> 15168
say derivative(-5040/4323).as_frac #=> -6240176/2076481
Aliases: arithmetic_derivative
dinv
n.dinv(f)
The Dirichlet inverse of a function f.
say 30.of { .dinv { .sigma } } # Dirichlet inverse of sigma function (OEIS: A046692)
Aliases: dirichlet_inverse
dirichlet_sum
n.dirichlet_sum(f, g, F, G)
This method computes the following sum in O(sqrt(n)) steps:
Sum_{k=1..n} Sum_{d|k} f(d) * g(k/d)
where F and G are the partial sums of f and g, respectively.
Computing Sum_{k=1..n} Sum_{d|k, d is squarefree} (n/d)^2:
var f = { .is_squarefree ? 1 : 0 }
var g = { .square }
var F = { .squarefree_count }
var G = { .faulhaber_sum(2) }
say 30.of {|n| dirichlet_sum(n, f, g, F, G) } # OEIS: A321973
Computing Sum_{k=1..n} Sum_{d|k} n * mu(k/d):
var f = {|n| n }
var g = {|n| mu(n) }
var F = {|n| n*(n+1)/2 }
var G = {|n| mertens(n) }
say 30.of {|n| dirichlet_sum(n, f, g, F, G) } # OEIS: A002088
Aliases: dirichlet_hyperbola, dsum
exp_bigomega
exp_bigomega(n,k)
Returns the result of k**bigomega(n).
exp_bigomega_sum
exp_bigomega_sum(n,k)
Partial sums of the exp_bigomega() function.
exp_bigomega_sum(n, 2) # Sum_{k=1..n} 2^bigomega(k)
exp_bigomega_sum(n, -1) # Sum_{k=1..n} (-1)^bigomega(k) = liouville_sum(n)
exp_mangoldt
exp_mangoldt(n)
Returns exp(Λ(n)): the exponential of the Mangoldt function.
say 30.of { .exp_mangoldt } #=> OEIS: A014963
exp_mangoldt_sum
exp_mangoldt_sum(n)
Partial sums of the exponential of the Mangoldt function.
say 30.of { .exp_mangoldt_sum } #=> OEIS: A072107
say exp_mangoldt_sum(1e10) #=> 2220822442581396891
say exp_mangoldt_sum(1e11) #=> 201467077843736717398
exp_omega
exp_omega(n,k)
Returns the result of k**omega(n).
exp_omega_sum
exp_omega_sum(n,k)
Partial sums of the exp_omega() function.
exp_omega_sum(n, 2) # Sum_{k=1..n} 2^omega(k)
exp_omega_sum(n, -1) # Sum_{k=1..n} (-1)^omega(k)
exp_squarefree_omega
exp_squarefree_omega(n,k)
Returns the result of k**omega(n) * mu(n)**2.
exp_squarefree_omega_sum
exp_squarefree_omega_sum(n,k)
Partial sums of the exp_squarefree_omega() function.
exp_squarefree_omega_sum(n, 3) # Sum_{k=1..n} 3^omega(k) * mu(k)^2
exp_squarefree_omega_sum(n, -1) # Sum_{k=1..n} (-1)^omega(k) * mu(k)^2 = mertens(n)
iphi
iphi(n, k=1)
Infinitary analog of Euler's phi function. (OEIS A091732)
iphi_sum
iphi_sum(n,k=1)
Partial sums of the infinitary totient function iphi(x,k) for x=1..n.
say 30.of { .iphi_sum } #=> OEIS: A327572
is_abundant
n.is_abundant
Returns true if n is an abundant number, else false. (OEIS A005101)
say 20.by { .is_abundant } #=> OEIS: A005101
An abundant number is smaller than the sum of its positive proper divisors.
is_amicable
is_amicable(n,m)
Returns true if the numbers n and m are "amicable", else false.
Amicable numbers are two different numbers so related that the sum of the proper divisors of each is equal to that of the other.
say is_amicable(220, 284) #=> true
is_deficient
n.is_deficient
Returns true if n is a deficient number, else false.
A deficient number is greater than the sum of its positive proper divisors.
is_perfect
n.is_perfect
Returns true if n is a perfect number (i.e.: sigma(n) == 2*n).
is_pseudoperfect
var bool = n.is_pseudoperfect
Returns true if n is a pseudoperfect (semiperfect) number, and false otherwise.
A positive integer is pseudoperfect if it can be written as the sum of some (or all) of its proper divisors. Every perfect number is pseudoperfect, since the sum of all proper divisors equals the number itself.
say 30.by { .is_pseudoperfect } # OEIS: A005835
Aliases: is_semiperfect
is_weird
is_weird(n)
Returns true if n is a weird number, and false otherwise.
A weird number is a positive integer that is abundant, but not pseudoperfect.
Equivalently, a weird number is an abundant number that cannot be expressed as the sum of a subset of its proper divisors.
say 10.by { .is_weird } #=> OEIS: A006037
is_zumkeller
is_zumkeller(n)
Returns true if n is a Zumkeller number, and false otherwise.
A Zumkeller number is a positive integer whose positive divisors can be partitioned into two disjoint subsets having equal sums.
say 30.by { .is_zumkeller } #=> OEIS: A083207
is_practical
n.is_practical
Returns true if n is a practical number. (OEIS A005153)
say 20.by { .is_practical }
is_primitive_abundant
n.is_primitive_abundant
Returns true if n is a primitive abundant number, else false. (OEIS A091191)
say 20.by { .is_primitive_abundant } #=> OEIS: A091191
A primitive abundant number is an abundant number having no abundant proper divisor.
is_totient
n.is_totient
Given an integer n, returns true if there exists an integer x such that euler_phi(x) == n.
jordan_totient
jordan_totient(n,k)
Jordan's totient J_k(n), which is a generalization of Euler's totient function.
lambda
lambda(n)
Carmichael lambda function: λ(n), defined as the smallest positive integer m such that:
powmod(a, m, n) == 1
for every integer a between 1 and n that is coprime to n.
Alias: carmichael_lambda.
legendre_phi
n.legendre_phi(k)
Returns the count of numbers <= n that are not divisible by the first k primes.
Equivalent with:
prime(k+1).rough_count(n)
liouville
liouville(n)
The Liouville function.
Equivalent to:
(-1)**omega(n)
liouville_sum
liouville_sum(n)
liouville_sum(a,b)
Computes partial sums of the Liouville lambda function:
Sum_{k=1..n} liouville(k)
When an additional argument is given, the returned result is:
Sum_{k=a..b} liouville(k)
Example:
say liouville_sum(10**9) #=> -25216
say liouville_sum(10**9, 10**10) #=> -90809
logarithmic_derivative
logarithmic_derivative(n)
Return the logarithmic derivative of n, defined as:
derivative(n)/n
make_coprime
n.make_coprime(k)
Returns the largest divisor of n that is coprime to k.
mangoldt
mangoldt(n)
The Mangoldt function. For the exponential values, see exp_mangoldt.
mertens
mertens(n)
mertens(a,b)
Returns the Mertens functions, which is defined as the partial sums of the Moebius function:
Sum_{k=1..n} moebius(k)
When an additional argument is given, the returned result is:
Sum_{k=a..b} moebius(k)
Example:
say mertens(100000) # equivalent with: (1..100000 -> sum { .moebius })
say mertens(21, 123) # equivalent with: (21..123 -> sum { .moebius })
mobius_range
mobius_range(a, b)
Returns an array with the Möbius values for the range a..b.
say moebius_range(7, 17) => [-1, 0, 0, 1, -1, 0, -1, 1, 1, 0, -1]
Aliases: moebius_range
moebius
mu(n)
moebius(n)
The Möbius function: μ(n). (OEIS A008683)
It is 1 when n = 1, 0 when n is divisible by the square of a prime, and (-1)^k when n is a product of k distinct primes.
say mu(1) #=> 1
say mu(12) #=> 0
say mu(30) #=> -1
say mu(210) #=> 1
Aliases: μ, mu, mobius, möbius
moebius_inverse
n.moebius_inverse(f)
The Möbius transform (inversion) of a function f, defined as:
Sum_{d|n} mu(d) * f(n/d)
Example:
say 30.of { .moebius_inverse { .psi } } # Möbius transform of Dedekind psi function (OEIS: A063659)
Aliases: moebius_transform
nuphi
nuphi(n, k=1)
The generalized nonunitary totient function (also called nphi). (OEIS A254503)
Multiplicative with:
a(p, k) = p^k
a(p^e, k) = J_k(p^e) = (p^k - 1) * p^(k*(e-1)), for e > 1.
Example:
say 30.of { .nuphi } # OEIS: A254503
say 30.of { .nuphi(2) } # OEIS: A254520
nuphi_sum
nuphi_sum(n,k=1)
Partial sums of the nonunitary totient function nuphi(x,k) for x=1..n.
omega
omega(n,k=0)
For k = 0, it returns the number of distinct prime factors of n.
In general, is equivalent with:
n.prime_divisors.sum {|d| n**k / d**k }
Aliases: ω
omega_inverse
See omega_inverse_sum below for the shared documentation of all three inverse methods.
omega_inverse_len
See omega_inverse_sum below for the shared documentation of all three inverse methods.
omega_inverse_sum
omega_inverse(A, B, n)
omega_inverse_len(A, B, n)
omega_inverse_sum(A, B, n)
Generate, count, or sum the numbers k in the range [A, B] such that ω(k) = n, where ω(k) is the number of distinct prime factors of k.
say omega_inverse(1, 100, 3)
# means: (1..100).grep { .omega == 3 }
say omega_inverse_len(1, 100, 3)
# means: (1..100).count { .omega == 3 }
say omega_inverse_sum(1, 100, 3)
# means: (1..100).grep { .omega == 3 }.sum
omega_sum
omega_sum(n, k=0)
Returns the sum of the generalized omega function ω_k(j), for j=1..n.
say omega_sum(100, 0) #=> 171
say omega_sum(100, 1) #=> 2298
say omega_sum(100, 2) #=> 59962
phi
Num.phi
phi(n,k=1)
Returns the golden ratio constant PHI, or Euler's totient function of n.
say Num.phi #=> 1.618033988749...
say phi(12) #=> 4
When called with an integer argument, phi(n) is the count of positive integers in the range 1..n that are coprime to n. When k > 1, it returns Jordan's totient function J_k(n).
say phi(12, 2) #=> 96
Aliases: φ
phi_inverse
n.phi_inverse
Returns an array with all the solutions x to the Euler totient function: phi(x) = n.
say phi_inverse(24) #=> [35, 39, 45, 52, 56, 70, 72, 78, 84, 90]
Aliases: inverse_phi, inverse_totient
phi_inverse_len
n.phi_inverse_len
Returns the number of solutions to the Euler totient function: phi(x) = n.
Equivalent to n.phi_inverse.len, but much faster.
Aliases: inverse_phi_len, inverse_totient_len
phi_inverse_max
n.phi_inverse_max
Returns the largest solution x to the Euler totient function: phi(x) = n.
Equivalent to n.phi_inverse.max, but much faster.
Returns nil if there are no solutions.
Aliases: inverse_phi_max, inverse_euler_phi_max
phi_inverse_min
n.phi_inverse_min
Returns the smallest solution x to the Euler totient function: phi(x) = n.
Equivalent to n.phi_inverse.min, but much faster.
Returns nil if there are no solutions.
Aliases: inverse_phi_min, inverse_euler_phi_min
pillai
pillai(n, k=1)
Pillai's arithmetical function: Sum_{k=1..n} gcd(k, n). (OEIS A018804)
Generalized as:
pillai(n,k) = Sum_{1 <= x_1, x_2, ..., x_k <= n} gcd(x_1, x_2, ..., x_k, n)^k
Which has the identity:
pillai(n,k) = Sum_{d|n} mu(n/d) * d^k * tau(d)
pillai_sum
pillai_sum(n,k=1)
Partial sums of the generalized Pillai arithmetical function pillai(n,k).
psi
n.psi(k=1)
dedekind_psi(n,k=1)
Dedekind psi function. (OEIS A001615)
say 10.of { .dedekind_psi } #=> [0, 1, 3, 4, 6, 6, 12, 8, 12, 12]
say 10.of { .dedekind_psi(2) } #=> [0, 1, 5, 10, 20, 26, 50, 50, 80, 90]
Aliases: dedekind_psi
psi_inverse
n.psi_inverse
Returns an array with all the solutions x to Dedekind's psi function: psi(x) = n.
say psi_inverse(120) #=> [75, 76, 87, 95]
Aliases: inverse_psi, inverse_dedekind_psi
psi_inverse_len
n.psi_inverse_len
Returns the number of solutions to Dedekind's psi function: psi(x) = n.
Equivalent to n.psi_inverse.len, but much faster.
Aliases: inverse_psi_len, inverse_dedekind_psi_len
psi_inverse_max
n.psi_inverse_max
Returns the largest solution x to Dedekind's psi function: psi(x) = n.
Equivalent to n.psi_inverse.max, but much faster.
Returns nil if there are no solutions.
Aliases: inverse_psi_max, inverse_dedekind_psi_max
psi_inverse_min
n.psi_inverse_min
Returns the smallest solution x to Dedekind's psi function: psi(x) = n.
Equivalent to n.psi_inverse.min, but much faster.
Returns nil if there are no solutions.
Aliases: inverse_psi_min, inverse_dedekind_psi_min
psi_sum
n.psi_sum(k=1)
Returns the sum of the Dedekind psi function ψ_k(j), for j=1..n.
say psi_sum(100, 1) #=> 7664
say psi_sum(100, 2) #=> 400576
Aliases: dedekind_psi_sum
rad
rad(n)
Returns the radical of n, which is the largest squarefree divisor of n.
say rad(2**5 * 3**9) #=> 6
Equivalent to:
n.factor.uniq.prod
Aliases: squarefree_kernel
ramanujan_sum
ramanujan_sum(n,q)
The Ramanujan sum function, defined as:
c_q(n) = μ(q/gcd(n,q)) * φ(q) / φ(q/gcd(n,q))
Example:
say 20.of {|q| ramanujan_sum(2, q) } #=> OEIS: A086831
sopf
sopf(n)
Sum of the distinct primes dividing n. (OEIS A008472)
say 30.of { .sopf } #=> OEIS: A008472
sopf_sum
sopf_sum(n)
Partial sums of the sopf(k) function: sum of all distinct prime factors of k for k = 2..n. (OEIS A024924)
say 20.of { .sopf_sum } #=> OEIS: A024924
say sopf_sum(1e9) #=> 41986415795828892
sopfr
sopfr(n)
Sum of the primes dividing n (with repetition). (OEIS A001414)
say 30.of { .sopfr } #=> OEIS: A001414
sopfr_sum
sopfr_sum(n)
Partial sums of the sopfr(k) function: sum of primes dividing k (with repetition) for k = 2..n. (OEIS A025281)
say 20.of { .sopfr_sum } #=> OEIS: A025281
say sopfr_sum(1e9) #=> 41986419147434739
totient
phi(n,k=1)
totient(n,k=1)
Euler's totient function.
totient(n) counts the positive integers in the range 1..n that are coprime to n. For k > 1, it returns the generalized Jordan totient J_k(n).
say totient(12) #=> 4
say totient(36) #=> 12
say totient(12, 2) #=> 96
Aliases: euler_phi, eulerphi, euler_totient
totient_range
totient_range(a, b)
Returns an array with the totient values for the range a..b.
say totient_range(7, 17) #=> [6, 4, 6, 4, 10, 4, 12, 6, 8, 8, 16]
totient_sum
totient_sum(n, k=1)
Returns the sum of the Jordan totient function J_k(j), for j=1..n.
say totient_sum(100, 1) #=> 3044
say totient_sum(100, 2) #=> 280608
Aliases: phi_sum, euler_phi_sum, jordan_totient_sum
uphi
uphi(n,k=1)
The unitary totient function. (OEIS A047994)
uphi_inverse
n.uphi_inverse
Returns an array with all the solutions x to uphi(x) = n.
say uphi_inverse(120) #=> [121, 143, 144, 155, 164, 183, 220, 231, 240, 242, 286, 310, 366, 462]
Aliases: inverse_uphi
uphi_sum
uphi_sum(n,k=1)
Partial sums of the unitary totient function uphi(x,k) for x=1..n.
say 30.of { .uphi_sum } #=> OEIS: A177754
NUMBER THEORY: SPECIAL INTEGER SETS
all_composite
all_composite(...)
Returns true if all the given values are positive composite numbers.
composite
n.composite
Returns the n-th composite number. (OEIS A002808)
say composite(10**9) #=> 1053422339
Aliases: nth_composite
composite_count
composite_count(n)
composite_count(a,b)
Returns the count of composite numbers <= n, or in the range a..b.
say composite_count(100) # number of composites <= 100
say composite_count(50, 100) # number of composites in the range 50..100
composite_count_lower
composite_count_lower(n)
Lower bound for composite_count(n).
composite_count_upper
composite_count_upper(n)
Upper bound for composite_count(n).
composite_lower
composite_lower(n)
Lower bound for the n-th composite number.
Aliases: nth_composite_lower
composite_sum
composite_sum(n)
composite_sum(a, b, k=1)
Returns the sum of composite numbers <= n, or in the range a..b.
say composite_sum(100) # sum of composite numbers <= 100
say composite_sum(50, 100) # sum of composite numbers in range 50..100
When k is specified, it returns the sum of composite numbers, each number raised to the k-th power:
say composite_sum(50, 100, 2) # 50^2 + 51^2 + ... + 100^2
Aliases: composites_sum
composite_upper
composite_upper(n)
Upper bound for the n-th composite number.
Aliases: nth_composite_upper
composites
composites(n)
composites(a,b)
Returns an array with the composite numbers <= n, or in the range a..b.
composites_each
n.composites_each { ... }
composites_each(a,b, { ... })
Iterate over the composite numbers <= n, or in the given range a..b.
# Iterate over the composite integers between 100 and 200
composites_each(100, 200, {|c|
say c
})
# Iterate over the composite integers <= 100
100.composites_each {|c|
say c
}
Aliases: each_composite
core
core(n)
Squarefree part of n. (OEIS A007913)
say 30.of { .core } #=> OEIS: A007913
Equivalent to PARI/GP core(n) function.
Aliases: squarefree_part
cube_part
cube_part(n)
Largest cube dividing n. (OEIS A008834)
cubefree
cubefree(n)
cubefree(a,b)
Returns an array with the cubefree numbers <= n, or in the range a..b.
cubefree_count
cubefree_count(n)
cubefree_count(a,b)
Returns the count of cubefree numbers <= n, or in the range a..b.
cubefree_each
n.cubefree_each { ... }
cubefree_each(a, b, { ... })
Iterates over the cubefree numbers <= n, or in the range a..b.
Aliases: each_cubefree
cubefree_kernel
cubefree_kernel(n)
Largest cubefree number dividing n. (OEIS A007948)
cubefree_part
cubefree_part(n)
Cubefree part of n. (OEIS A050985)
cubefree_sum
cubefree_sum(n)
cubefree_sum(a,b)
Returns the sum of cubefree numbers <= n, or in the range a..b.
cubefull
cubefull(n)
cubefull(a,b)
Returns an array with the cubefull numbers <= n, or in the range a..b.
cubefull_count
cubefull_count(n)
cubefull_count(a,b)
Returns the count of cubefull numbers <= n, or in the range a..b.
cubefull_each
n.cubefull_each { ... }
cubefull_each(a, b, { ... })
Iterates over the cubefull numbers <= n, or in the range a..b.
Aliases: each_cubefull
cubefull_part
cubefull_part(n)
Largest divisor of n that is a cubefull (3-powerful) number. (OEIS A360540)
cubefull_sum
cubefull_sum(n)
cubefull_sum(a,b)
Returns the sum of cubefull numbers <= n, or in the range a..b.
difference_of_squares
difference_of_squares(n)
Returns an array of [a,b] pairs with all the possible solutions to the equation: a^2 - b^2 = n.
say difference_of_squares(48) #=> [[7, 1], [8, 4], [13, 11]]
Aliases: diff_of_squares
difference_of_cubes
difference_of_cubes(n)
Returns all integer solutions (x, y) satisfying:
x^3 - y^3 = n
The result is returned as an array of pairs, where each pair is itself an array [x, y]. Returns an empty array when no integer solutions exist or when n = 0.
The implementation is based on the factorization:
x^3 - y^3 = (x - y)(x^2 + xy + y^2)
and enumerates the divisors of |n|. For each divisor A = x - y, the corresponding quadratic equation is constructed, its discriminant is tested for being a perfect square, and any resulting integer solutions are recovered.
The algorithm supports both positive and negative values of n.
Examples:
say difference_of_cubes(19) # [[-2, -3], [3, 2]]
say difference_of_cubes(1729) # [[1, -12], [9, -10], [10, -9], [12, -1]]
say difference_of_cubes(-728) # [[-12, -10], [-9, -1], [-8, 6], [-6, 8], [1, 9], [10, 12]]
say difference_of_cubes(30) # []
Aliases: diff_of_cubes
fibonorial
fibonorial(n)
Returns the product of first n nonzero Fibonacci numbers F(1), ..., F(n).
is_between
n.is_between(min, max)
Returns a true value when `n >= min` and `n <= max`.
is_composite
n.is_composite
Returns true if n is a positive > 1 composite number.
is_cube
n.is_cube
Return true if n is a cube number (i.e.: if it can be written as b^3, for some integer b).
is_cubefree
n.is_cubefree
Returns true if n is not divisible by any perfect cube > 1.
is_cubefull
n.is_cubefull
Returns true if n is divisible by the cubes of all its prime factors.
is_cyclic
n.is_cyclic
Returns true when gcd(phi(n), n) = 1, where phi(n) is the Euler totient function. (OEIS A003277)
say 30.by { .is_cyclic } # OEIS: A003277
is_even
n.is_even
Returns true if n is an integer divisible by 2.
is_fundamental
n.is_fundamental
Returns true if n is a fundamental discriminant.
is_noncubefree
n.is_noncubefree
Returns true if n is a positive integer divisible by the cube of a prime.
is_nonpowerfree
n.is_nonpowerfree
Returns true if n is a positive integer divisible by the k-th power of a prime.
is_nonsquarefree
n.is_nonsquarefree
Returns true if n is a positive integer divisible by the square of a prime.
is_ntf
g.is_ntf(n)
Returns true if g is a nontrivial integer factor of n.
Equivalent with (assuming g and n are both integers):
g.divides(n) && g.is_between(2, n-1)
Aliases: is_nontrivial_factor
is_odd
n.is_odd
Returns true when n is an integer not divisible by 2.
is_odd_composite
n.is_odd_composite
Returns true when n is an odd composite integer.
is_palindrome
n.is_palindrome(base=10)
Returns true if the given number n is palindromic in the given base. When no base is given, it defaults to 10.
# Numbers that are palindromic in bases 2 and 10 (OEIS: A007632)
say 1e6.range.grep{ .is_palindrome(2) && .is_palindrome(10) }
Aliases: is_palindromic
is_pandigital
n.is_pandigital(base=10)
Returns true if n is pandigital in the specified base, and false otherwise.
A number is pandigital in base b if its representation contains every digit from 0 to b-1 at least once. Digits may appear more than once.
If no base is specified, base 10 is assumed.
say 1023456789.is_pandigital #=> true
say 123456789.is_pandigital #=> false
say 9876543210.is_pandigital #=> true
Pandigitality can also be tested in other bases:
say 0b11010010.is_pandigital(2) #=> true
say 0x123456789ABCDEF0.is_pandigital(16) #=> true
is_smith
n.is_smith(base=10)
Returns true if n is a Smith number, and false otherwise. (OEIS A006753)
A Smith number is a composite integer whose digit sum equals the sum of the digit sums of its prime factors, counted with multiplicity.
By default, the comparison is performed in base 10. An alternative numeral base can be specified with the optional base argument.
say 30.by { .is_smith(2) } #=> OEIS: A278909
say 30.by { .is_smith(10) } #=> OEIS: A006753
is_pow
n.is_power
n.is_power(k)
When k is provided, it returns true if n can be expressed as n = b^k for some integer b >= 1.
say 225.is_power # true: 225 == 15**2
say 100.is_power(2) # true: 100 is square (10**2)
say 125.is_power(3) # true: 125 is a cube ( 5**3)
When k is omitted, it true if n is a perfect power.
Aliases: is_power, is_perfect_power
is_power_of
n.is_power_of(b)
Return true if n is a power of b, such that n = b^k for some k >= 0:
n.is_power_of(b) # true if n == b^k for some k >= 0
Example:
say 1000.range.grep { .is_power_of(2) } # powers of 2
say 1000.range.grep { .is_power_of(5) } # powers of 5
is_powerfree
n.is_powerfree(k=2)
Returns true when all the exponents in the prime-power factorization of n are less than k.
say 15.by { .is_powerfree(2) } # squarefree numbers
say 15.by { .is_powerfree(3) } # cubefree numbers
is_powerful
n.is_powerful(k=2)
Returns true when all the exponents in the prime-power factorization of n are greater than or equal to k.
is_prob_squarefree
n.is_prob_squarefree
n.is_prob_squarefree(limit)
Returns true if n is probably squarefree, checking if n is divisible by a square p^2 with p less than or equal to limit:
say is_prob_squarefree(2**512 - 1, 1e6) # true (probably squarefree)
say is_prob_squarefree(10**136 + 1, 1e3) # false (definitely not squarefree)
If n is less than limit^3 and the function returns true, then n is definitely squarefree.
If the limit parameter is omitted, multiple limits are tested internally, trying to find a square factor of n, up to limit = 10^7.
is_rough
n.is_rough(k)
Returns true if all prime factors of n are >= k.
say 30.by { .is_rough(3) } #=> OEIS: A005408
say 30.by { .is_rough(5) } #=> OEIS: A007310
say 30.by { .is_rough(7) } #=> OEIS: A007775
# ...
say 30.by { .is_rough(23) } #=> OEIS: A166063
is_smooth
n.is_smooth(k)
Returns true if all the prime factors of n are <= k. False otherwise.
is_smooth_over_prod
n.is_smooth_over_prod(k)
Returns true when n is smooth over the prime factors of k.
is_square
n.is_square
Returns true if n is a perfect square integer.
Aliases: is_sqr, is_perfect_square
is_squarefree
n.is_squarefree
Returns true if the prime factorization of n does not include duplicated factors (i.e.: n is not divisible by a square).
Aliases: is_square_free
is_squarefree_almost_prime
n.is_squarefree_almost_prime(k=2)
Returns true if n is a squarefree k-almost prime (i.e.: true iff n is the product of k distinct primes).
Equivalently, k-almost primes are numbers n that satisfy bigomega(n) == omega(n) == k.
say 20.by { .is_squarefree_almost_prime(1) } # primes
say 20.by { .is_squarefree_almost_prime(2) } # squarefree semiprimes
say 20.by { .is_squarefree_almost_prime(3) } # sphenic numbers
is_squarefree_semiprime
is_squarefree_semiprime(n)
Returns true if n is a squarefree semiprime (i.e.: n = p*q, where p and q are two distinct primes).
is_squarefull
n.is_squarefull
Returns true if n is divisible by the squares of all its prime factors.
next_composite
n.next_composite
Given a nonnegative integer n, returns the next composite number greater than n.
next_composites
n.next_composites(start=4)
Returns an array with n consecutive composite numbers starting from start.
say 5.next_composites #=> [4, 6, 8, 9, 10]
say 5.next_composites(50) #=> [50, 51, 52, 54, 55]
next_cubefree
n.next_cubefree
Returns the next cubefree number greater than n.
next_cubefull
n.next_cubefull
Returns the next cubefull (or 2-full) number greater than n.
next_noncubefree
n.next_noncubefree
Returns the next noncubefree number greater than n.
next_nonpowerfree
n.next_nonpowerfree(k=2)
Returns the next k-nonpowerfree number greater than n.
next_nonsquarefree
n.next_nonsquarefree
Returns the next nonsquarefree number greater than n.
next_palindrome
n.next_palindrome(b=10)
Efficiently returns the next palindrome in base-b greater than n.
# Iterate over the base-10 palindromic numbers < 10^6
for (var n = 0; n < 1e6; n = n.next_palindrome) {
say n
}
next_perfect_power
next_perfect_power(n)
next_perfect_power(n,k)
Returns the next perfect power greater than n.
say next_perfect_power(1e6) #=> 1002001
When k is given, it returns the next k-perfect-power greater than n.
say next_perfect_power(1e6, 3) #=> 1030301
next_pow
n.next_pow(b)
Returns the next perfect power greater than n, with base b.
say 63.next_pow(2) #=> 64
say 64.next_pow(2) #=> 128
Equivalent with:
b**(1+ilog(n,b))
Aliases: next_power
next_powerfree
n.next_powerfree(k=2)
Returns the next k-powerfree number greater than n.
next_powerful
n.next_powerful(k=2)
Returns the next k-powerful (or k-full) number greater than n.
next_rough(n, k)
Returns the smallest k-rough integer strictly greater than n.
If n is zero, it returns 1.
next_smooth(n, k)
Returns the smallest k-smooth integer strictly greater than n.
If n is zero, it returns 1.
next_squarefree
n.next_squarefree
Returns the next squarefree number greater than n.
next_squarefull
n.next_squarefull
Returns the next squarefull (or 2-full) number greater than n.
noncubefree
noncubefree(n)
noncubefree(a,b)
Returns an array with the noncubefree numbers <= n, or in the range a..b.
noncubefree_count
noncubefree_count(n)
noncubefree_count(a,b)
Returns the count of noncubefree numbers <= n, or in the range a..b.
noncubefree_each
n.noncubefree_each { ... }
noncubefree_each(a, b, { ... })
Iterates over the noncubefree numbers <= n, or in the range a..b.
Aliases: each_noncubefree
noncubefree_sum
noncubefree_sum(n)
noncubefree_sum(a,b)
Returns the sum of noncubefree numbers <= n, or in the range a..b.
nonpowerfree
k.nonpowerfree(n)
k.nonpowerfree(a,b)
Returns an array of numbers <= n, or in the range a..b, that are not k-powerfree.
say 2.nonpowerfree(100) # numbers that are not squarefree <= 100
say 3.nonpowerfree(50, 100) # numbers that are not cubefree in range 50..100
nonpowerfree_count
k.nonpowerfree_count(n)
k.nonpowerfree_count(a,b)
Returns the count of numbers <= n, or in the range a..b, that are not k-powerfree.
nonpowerfree_each
k.nonpowerfree_each(n, { ... })
k.nonpowerfree_each(a, b, { ... })
Iterates over the numbers <= n, or in the range a..b, that are not k-powerfree.
2.nonpowerfree_each(100, {|n| say n }) # iterate over nonsquarefree numbers <= 100
3.nonpowerfree_each(50, 100, {|n| say n }) # iterate over noncubefree numbers in range 50..100
Aliases: each_nonpowerfree
nonpowerfree_sum
k.nonpowerfree_sum(n)
k.nonpowerfree_sum(a,b)
Returns the sum of numbers <= n, or in the range a..b, that are not k-powerfree.
nonsquarefree
nonsquarefree(n)
nonsquarefree(a,b)
Returns an array with the nonsquarefree numbers <= n, or in the range a..b.
nonsquarefree_count
nonsquarefree_count(n)
nonsquarefree_count(a,b)
Returns the count of nonsquarefree numbers <= n, or in the range a..b.
nonsquarefree_each
n.nonsquarefree_each { ... }
nonsquarefree_each(a, b, { ... })
Iterates over the nonsquarefree numbers <= n, or in the range a..b.
Aliases: each_nonsquarefree
nonsquarefree_sum
nonsquarefree_sum(n)
nonsquarefree_sum(a,b)
Returns the sum of nonsquarefree numbers <= n, or in the range a..b.
nth_cubefree
n.nth_cubefree
Returns the n-th cubefree number.
nth_cubefull
n.nth_cubefull
Returns the n-th cubefull (or 3-full) number.
nth_noncubefree
n.nth_noncubefree
Returns the n-th noncubefree number.
nth_nonpowerfree
n.nth_nonpowerfree(k)
Returns the n-th k-nonpowerfree number.
say nth_nonpowerfree(1e9, 2) #=> 2550546152
say nth_nonpowerfree(1e9, 3) #=> 5949100928
say nth_nonpowerfree(1e9, 4) #=> 13147239114
nth_nonsquarefree
n.nth_nonsquarefree
Returns the n-th nonsquarefree number.
nth_perfect_power
nth_perfect_power(n)
nth_perfect_power(n,k)
Returns the n-th perfect power.
say nth_perfect_power(1e8) #=> 9956760243243489
say nth_perfect_power(1e9) #=> 997995681331086244
When k is given, it returns the n-th k-perfect-power.
nth_powerfree
nth_powerfree(n, k=2)
Returns the n-th k-powerfree number.
say nth_powerfree(1e14, 2) #=> 164493406685659
say nth_powerfree(1e14, 3) #=> 120205690315927
say nth_powerfree(1e14, 4) #=> 108232323371116
nth_powerful
nth_powerful(n, k=2)
Returns the n-th k-powerful (or k-full) number.
say nth_powerful(1e4, 2) #=> 23002083
say nth_powerful(1e4, 3) #=> 16720797973
nth_rough
nth_rough(n, k)
Returns the n-th k-rough integer.
A number is considered k-rough (or k-resilient) if all of its prime factors are greater than or equal to k. This is the inverse of the rough_count function.
Returns NaN if n <= 0.
nth_smooth
nth_smooth(n, k)
Returns the n-th k-smooth integer (a Hamming number if k=3).
A number is considered k-smooth if all of its prime factors are less than or equal to k. This is the inverse of the smooth_count function.
Returns NaN if n <= 0 or k <= 1.
nth_squarefree
nth_squarefree(n)
Returns the n-th squarefree number. (OEIS A005117)
say nth_squarefree(1e14) #=> 164493406685659
nth_squarefull
n.nth_squarefull
Returns the n-th squarefull (or 2-full) number.
nth_tau_inverse
nth_tau_inverse(n, k)
Returns the n-th number with exactly k divisors.
say {|n| nth_tau_inverse(n, n) }.map(1..20) #=> OEIS: A073916
perfect_power
n.perfect_power
Returns the largest power k of n for which there exists an integer r, such that: n = r^k.
say perfect_power(15**5) #=> 5
perfect_power_count
perfect_power_count(n)
perfect_power_count(n,k)
Returns the count of perfect powers <= n.
say perfect_power_count(10**6) #=> 1111
say perfect_power_count(10**20) #=> 10004650118
When k is provided, it returns the number of k-powers <= n.
perfect_power_sum
perfect_power_sum(n)
perfect_power_sum(n,k)
Returns the sum of perfect powers <= n.
say perfect_power_sum(10**6) #=> 361590619
say perfect_power_sum(10**20) #=> 333449517656248628022493884999
When k is provided, it returns the sum of k-powers <= n.
power_count
k.power_count(n)
k.power_count(a,b)
Returns the number of k-th power positive integers in <= n, or in the range a..b.
power_part
k.power_part(n)
Returns the largest k-th power dividing n.
say 2.power_part(n) # largest square dividing n
say 3.power_part(n) # largest cube dividing n
power_sum
k.power_sum(n)
k.power_sum(a,b)
Returns the sum of k-th power positive integers <= n, or in the range a..b.
powerfree
k.powerfree(n)
k.powerfree(a, b)
Returns an array with the k-powerfree <= n, or in the range a..b.
say 2.powerfree(50) # squarefree numbers <= 50
say 3.powerfree(50, 100) # cubefree numbers in the range 50..100
powerfree_count
k.powerfree_count(n)
k.powerfree_count(a,b)
It efficiently counts the number of k-powerfree numbers <= n, or in the range a..b:
say 3.powerfree_count(100) #=> count of cubefree numbers <= 100
say 3.powerfree_count(50, 100) #=> count of cubefree numbers in the range 50..100
powerfree_each
k.powerfree_each(n, { ... })
k.powerfree_each(a, b, { ... })
Iterates over the k-powerfree numbers <= n, or in the range a..b.
2.powerfree_each(100, {|n| say n }) # iterate over squarefree numbers <= 100
3.powerfree_each(50, 100, {|n| say n }) # iterate over cubefree numbers in the range 50..100
Aliases: each_powerfree
powerfree_kernel
k.powerfree_kernel(n)
Returns the largest k-powerfree divisor of n.
say 2.powerfree_kernel(n) # rad(n)
say 3.powerfree_kernel(n) # largest cubefree number dividing n (OEIS: A007948)
powerfree_part
k.powerfree_part(n)
Returns the k-powerfree part of n.
say 30.of { 2.powerfree_part(_) } # squarefree part (OEIS: A007913)
say 30.of { 3.powerfree_part(_) } # cubefree part (OEIS: A050985)
powerfree_part_sum
k.powerfree_part_sum(n)
k.powerfree_part_sum(a,b)
Returns the sum of the k-powerfree parts of integers <= n or in the range a..b:
say 2.powerfree_part_sum(100) # sum of squarefree part of n for n <= 100
say 3.powerfree_part_sum(50, 100) # sum of cubefree part of n for n in the range 50..100
powerfree_sum
k.powerfree_sum(n)
k.powerfree_sum(a,b)
Returns the sum of k-powerfree numbers <= n or in the range a..b:
say 2.powerfree_sum(100) # sum of squarefree numbers <= 100
say 3.powerfree_sum(50, 100) # sum of cubefree numbers in the range 50..100
powerful
k.powerful(n)
k.powerful(a,b)
Returns an array with the k-powerful (or k-full) numbers <= n, or in the range a..b.
say 2.powerful(100) #=> 2-powerful numbers <= 100
say 2.powerful(50, 100) #=> 2-powerful numbers in the range 50..100
powerful_count
k.powerful_count(n)
k.powerful_count(a,b)
Returns the number of k-powerful (or k-full) numbers <= n, or in the range a..b.
say 2.powerful_count(100) #=> count of 2-powerful numbers <= 100
say 2.powerful_count(50, 100) #=> count of 2-powerful numbers in the range 50..100
powerful_each
k.powerful_each(n, { ... })
k.powerful_each(a, b, { ... })
Iterates over the k-powerful numbers <= n, or in the range a..b.
2.powerful_each(100, {|n| say n }) # iterate over 2-powerful numbers <= 100
2.powerful_each(50, 100, {|n| say n }) # iterate over 2-powerful numbers in the range 50..100
Aliases: each_powerful
powerful_part
k.powerful_part(n)
The k-powerful part of n: largest k-powerful number dividing n.
say 2.powerful_part(n) # squarefull part of n (OEIS: A057521)
say 3.powerful_part(n) # cubefull part of n (OEIS: A360540)
powerful_sum
k.powerful_sum(n)
k.powerful_sum(a,b)
Returns the sum of k-powerful (or k-full) numbers <= n, or in the range a..b.
say 2.powerful_sum(100) #=> sum of 2-powerful numbers <= 100
say 2.powerful_sum(50, 100) #=> sum of 2-powerful numbers in the range 50..100
prev_composite
prev_composite(n)
Returns the previous composite number smaller than n.
prev_composites
n.prev_composites(start)
Returns an array with n consecutive decreasing composite numbers starting from start.
say 5.prev_composites(10) #=> [10, 9, 8, 6, 4]
say 5.prev_composites(97) #=> [96, 95, 94, 93, 92]
prev_cubefree
n.prev_cubefree
Returns the previous cubefree number smaller than n.
prev_cubefull
n.prev_cubefull
Returns the previous cubefull or (3-full) number smaller than n.
prev_noncubefree
n.prev_noncubefree
Returns the previous noncubefree number smaller than n.
prev_nonpowerfree
n.prev_nonpowerfree(k)
Returns the previous k-nonpowerfree number smaller than n.
prev_nonsquarefree
n.prev_nonsquarefree
Returns the previous nonsquarefree number smaller than n.
prev_perfect_power
prev_perfect_power(n)
prev_perfect_power(n,k)
Returns the previous perfect power smaller than n.
say prev_perfect_power(1e6) #=> 998001
When k is given, it returns the previous k-perfect-power smaller than n.
say prev_perfect_power(1e6,3) #=> 970299
prev_pow
n.prev_pow(b)
Returns the previous perfect power smaller than n, with base b. Returns NaN when n is <= 1.
say 65.prev_pow(2) #=> 64
say 64.prev_pow(2) #=> 32
Aliases: prev_power
prev_powerfree
n.prev_powerfree(k=2)
Returns the previous k-powerfree number smaller than n.
prev_powerful
n.prev_powerful(k=2)
Returns the previous k-powerful (or k-full) number smaller than n.
prev_rough(n, k)
Returns the largest k-rough integer strictly less than n.
Returns NaN if n <= 1.
prev_smooth(n, k)
Returns the largest k-smooth integer strictly less than n.
Returns NaN if n <= 1.
prev_squarefree
n.prev_squarefree
Returns the previous squarefree number smaller than n.
prev_squarefull
n.prev_squarefull
Returns the previous squarefull (or 2-full) number smaller than n.
primitive_part
n.primitive_part(f)
Returns the primitive part of f(n), for n > 0, such that:
a(n) = primitive part of f(n)
f(n) = Product_{d|n} a(d)
Example:
func f(n) { n.fib }
func a(n) { n.primitive_part(f) }
say 20.of { a(_) }
say 20.of { f(_) }
say 20.of { .divisors.prod {|d| a(d) } }
primorial
n.primorial
Returns the product of the primes less than or equal to n.
say primorial(5) #=> 30 (2*3*5)
say primorial(8) #=> 210 (2*3*5*7)
primorial_deflation
n.primorial_deflation
Primorial deflation of n, satisfying:
primorial_inflation(primorial_deflation(n)) = n
Defined as:
primorial_deflation(n) = A319626(n)/A319627(n)
primorial_inflation
n.primorial_inflation
Primorial inflation of n.
Defined as:
primorial_inflation(n) = n.factor.prod {|p| primorial(p) }
primorial_inflation(n) = A108951(n)
The method also accepts n to be a fraction, which is computed as:
primorial_inflation(a/b) = primorial_inflation(a)/primorial_inflation(b)
rough_count
k.rough_count(n)
k.rough_count(a,b)
Returns the count of k-rough numbers <= n, or in the range a..b.
say 97.rough_count(1e6) #=> 122005
say 23.rough_count(1e9) #=> 171024023
Also works with arbitrarily large n:
say 43.rough_count(1e34) #=> 1450936704022016442012254601096989
rough_divisors
k.rough_divisors(n)
Returns an array with the divisors of n that are k-rough.
Equivalent with (but more efficient):
n.divisors.grep { .is_rough(k) }
rough_part
k.rough_part(n)
It returns the k-rough part of n that contains all the prime factors p|n such that p >= k.
say 15.of {|n| 3.rough_part(n!) } #=> OEIS: A049606
smooth_count
k.smooth_count(n)
k.smooth_count(a,b)
Returns the count of k-smooth numbers <= n, or in the range a..b.
say 30.of {|n| 13.smooth_count(10**n) } #=> OEIS: A106629
smooth_divisors
k.smooth_divisors(n)
Returns an array with the divisors of n that are k-smooth.
Equivalent with (but more efficient):
n.divisors.grep { .is_smooth(k) }
smooth_numbers
smooth_numbers(limit, [p1,p2,...])
smooth_numbers(limit, [p1,p2,...], {|n,p| ... })
Returns an array containing all the smooth numbers that factorize over the given array of primes.
say smooth_numbers(100, [2,3,5]) # 5-smooth numbers <= 100
An optional block can be provided, which is called with two arguments, n and p, where p is the current prime and n is a smooth number that is a multiple of p. If the block returns true, then the number n will be included in the returned array.
# 5-smooth numbers <= 100 that are squarefree
say smooth_numbers(100, [2,3,5], {|n,p| n.valuation(p) < 2 })
# 5-smooth numbers <= 100 that are cubefree
say smooth_numbers(100, [2,3,5], {|n,p| n.valuation(p) < 3 })
smooth_part
k.smooth_part(n)
It efficiently returns the largest divisor of n that is k-smooth.
say 20.of {|n| 3.smooth_part(n!) } #=> OEIS: A118381
square_part
square_part(n)
Largest square dividing n. (OEIS A008833)
say 30.of { .square_part } #=> OEIS: A008833
squarefree
squarefree(n)
squarefree(a,b)
Returns an array with the squarefree numbers <= n, or in the range a..b.
# Squarefree numbers in the interval [100, 200]
say squarefree(100, 200)
# Squarefree numbers <= 100
say squarefree(100)
squarefree_count
squarefree_count(n)
squarefree_count(a,b)
Returns the count of squarefree integers <= n, or in the range a..b.
# The number of squarefree integers between 10^5 and 10^6
say squarefree_count(10**5, 10**6) # 547132
# The number of squarefree integers <= 2^40
say squarefree_count(2**40) # 668422917419
Aliases: square_free_count
squarefree_each
n.squarefree_each {...}
squarefree_each(a,b,{...})
Iterates over the squarefree numbers in a given range.
# Iterate over the squarefree numbers in the interval [100, 200]
squarefree_each(100, 200, {|n|
say n
})
# Iterate over the squarefree numbers <= 100
100.squarefree_each {|n|
say n
}
Aliases: each_squarefree
squarefree_sum
squarefree_sum(n)
squarefree_sum(a,b)
Returns the sum of squarefree numbers <= n or in the range a..b. (OEIS A066779)
say squarefree_sum(1e12) #=> 303963551353876732927386
say squarefree_sum(1e13) #=> 30396355090144154315002969
squarefull
squarefull(n)
squarefull(a,b)
Returns an array with the squarefull numbers <= n, or in the range a..b.
squarefull_count
squarefull_count(n)
squarefull_count(a,b)
Returns the count of squarefull numbers <= n, or in the range a..b.
squarefull_each
n.squarefull_each { ... }
squarefull_each(a, b, { ... })
Iterates over the squarefull (or 2-full) numbers <= n, or in the range a..b.
Aliases: each_squarefull
squarefull_part
squarefull_part(n)
Largest divisor of n that is a squarefull (2-powerful) number. (OEIS A057521)
squarefull_sum
squarefull_sum(n)
squarefull_sum(a,b)
Returns the sum of squarefull numbers <= n, or in the range a..b.
squares_r
squares_r(n, k=2)
The sum of squares function r_k(n) returns the number of ways of representing n as a sum of k squares.
say 30.of { .squares_r(2) } # OEIS: A004018
say 30.of { .squares_r(3) } # OEIS: A005875
say 30.of { .squares_r(4) } # OEIS: A000118
Aliases: sum_of_squares_count
superprimorial
superprimorial(n)
Returns the product of first n primorials. (OEIS A006939)
say 10.of { .superprimorial } #=> OEIS: A006939
RANDOM NUMBERS
irand
irand(n)
irand(a,b)
Returns a cryptographically-secure pseudorandom integer in the range 0..n (all inclusive), or in the range a..b (all inclusive).
If a is greater than b, the returned integer will be in the range b..a.
irand(10) # a pseudorandom integer in the interval [0, 10]
irand(10, 20) # a pseudorandom integer in the interval [10, 20]
The underlying CSPRNG is ISAAC-32.
miller_rabin_random
n.miller_rabin_random(k)
Return true if n passes the Miller-Rabin primality test with k random bases.
rand
rand(n)
rand(a,b)
Returns a pseudorandom floating-point in the interval [0,n), or in the interval [a,b).
random_bytes
n.random_bytes
Returns an array with n random values between 0 and 255.
random_maurer_nbit_prime
random_maurer_nbit_prime(n)
Generate a random n-bit Marurer prime.
Aliases: random_nbit_maurer_prime
random_nbit_prime
random_nbit_prime(n)
Returns a cryptographically-secure random n-bit prime.
say random_nbit_prime(128) #=> 128-bit random prime
random_nbit_safe_prime
random_nbit_safe_prime(n)
Returns a random n-bit safe-prime.
say random_nbit_safe_prime(512) #=> 512-bit safe prime
Provided by Math::Prime::Util::GMP >= 0.52.
random_nbit_strong_prime
random_nbit_strong_prime(n)
Generate a random n-bit strong prime number.
Aliases: random_strong_nbit_prime
random_ndigit_prime
random_ndigit_prime(n)
Returns a random n-digit prime.
say random_ndigit_prime(100) # 100-digit random prime
random_prime
random_prime(n)
random_prime(a,b)
Returns a cryptographically-secure random prime <= n, or in [a,b].
say random_prime(100) #=> Random prime in [2, 100]
say random_prime(100, 200) #=> Random prime in [100, 200]
random_string
n.random_string
Returns a string with n random characters (bytes).
seed
seed(n)
Re-seed the rand() function. The value for n can be any arbitrary large integer.
urand
urand(n)
urand(a, b)
Given a positive integer n, returns a cryptographically-secure pseudorandom unsigned integer smaller than n.
say urand(100) # pseudorandom integer in [0,99]
When two arguments are given, returns a uniform pseudorandom unsigned integer in the range [a,b] (inclusive on both ends).
say urand(100, 110) # pseudorandom integer in [100, 110]
Both arguments must be nonnegative. If a is greater than b, then will return a pseudorandom integer in the range [b,a].
The underlying CSPRNG is ISAAC-32.
Aliases: urandomm
useed
iseed(n)
useed(n)
Takes a nonnegative integer n, which is used to seed the internal CSPRNG (currently, ISAAC-32) used for random functions, such as irand, urand and the random prime functions.
For good security, n should be at least an 128-bit random integer.
Internally, the value of n is converted into a binary string, SHA-512 hashed and expanded into a 8192-bit key.
NUMERIC PREDICATES & UTILITY
eval
eval(x,v)
Returns back x.
is_float
x.is_float
Returns true if x is stored as a floating-point number.
is_inf
x.is_inf
Returns true if x equals positive infinity (Inf).
is_int
x.is_int
Returns true if x is an integer.
is_mone
x.is_mone
Returns true if x equals -1.
is_nan
x.is_nan
Returns true if x holds the Not-a-Number special value (NaN).
is_neg
x.is_neg
Returns true if x is negative.
Aliases: is_negative
is_ninf
x.is_ninf
Returns true if x equals negative infinity (-Inf).
is_one
n.is_one
Returns true when n equals 1.
is_pos
x.is_pos
Returns true when x is a positive integer.
Aliases: is_positive
is_rat
x.is_rat
Returns true if x is a rational number.
is_zero
x.is_zero
Returns true when x equals 0.