Skip to content

Commit 2877f67

Browse files
committed
new file: Math/partial_sums_of_core_function.sf
1 parent d13d76b commit 2877f67

6 files changed

Lines changed: 97 additions & 34 deletions

Math/eisenstein_integers.sf

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ class Eisenstein(a, b) { # represents: a + b*w, where w = (-1 + i*sqrt(3))/2
1515
(a == c.a) && (b == c.b)
1616
}
1717

18+
method add (Number z) {
19+
Eisenstein(a+z, b)
20+
}
21+
1822
method add (Eisenstein z) {
1923
var (c,d) = (z.a, z.b)
2024
Eisenstein(a+c, b+d)
@@ -33,6 +37,10 @@ class Eisenstein(a, b) { # represents: a + b*w, where w = (-1 + i*sqrt(3))/2
3337
a*a - a*b + b*b
3438
}
3539

40+
method mul (Number z) {
41+
Eisenstein(a*z, b*z)
42+
}
43+
3644
method mul (Eisenstein z) {
3745
var (c,d) = (z.a, z.b)
3846
Eisenstein(a*c - b*d, b*c + a*d - b*d)
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#!/usr/bin/ruby
2+
3+
# Sub-linear algorithm for computing partial sums of the core(n) function.
4+
5+
# OEIS sequence:
6+
# https://oeis.org/A069891
7+
8+
# Sequence A069891(10^n):
9+
# S(10^1) = 38
10+
# S(10^2) = 3233
11+
# S(10^3) = 328322
12+
# S(10^4) = 32926441
13+
# S(10^5) = 3289873890
14+
# S(10^6) = 328984021545
15+
# S(10^7) = 32898872196712
16+
# S(10^8) = 3289866649713946
17+
# S(10^9) = 328986818422458525
18+
# S(10^10) = 32898680588469254505
19+
# S(10^11) = 3289868138800129869623
20+
21+
func squarefree_sum(n) { # A066779
22+
sum(1..n.isqrt, {|k|
23+
moebius(k) * k*k * faulhaber(idiv(n, k*k), 1)
24+
})
25+
}
26+
27+
func core_partial_sum(n) { # A069891
28+
n.dirichlet_sum(
29+
{|k| k.is_square ? 1 : 0 },
30+
{|k| abs(k*mu(k)) },
31+
{|k| k.isqrt },
32+
{|k| squarefree_sum(k) },
33+
)
34+
}
35+
36+
func f(n) { # A046970
37+
n.factor_prod {|p|
38+
1 - p*p
39+
}
40+
}
41+
42+
func core_partial_sum_faster(n) { # A069891
43+
sum(1..n.isqrt, {|k|
44+
f(k) * faulhaber(idiv(n, k*k), 1)
45+
})
46+
}
47+
48+
say core_partial_sum(10**5) #=> 3289873890
49+
say core_partial_sum_faster(10**5) #=> 3289873890
50+
51+
assert_eq(
52+
100.of(core_partial_sum),
53+
100.of(core_partial_sum_faster)
54+
)

Math/quadratic_integers.sf

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,66 +5,66 @@
55
# See also:
66
# https://en.wikipedia.org/wiki/Quadratic_integer
77

8-
class Quadratic(a, b, w = 2) { # represents: a + b*sqrt(w)
8+
class QuadraticInteger(a, b, w = 2) { # represents: a + b*sqrt(w)
99

1010
method to_s {
11-
"Quadratic(#{a}, #{b}, #{w})"
11+
"QuadraticInteger(#{a}, #{b}, #{w})"
1212
}
1313

14-
method ==(Quadratic c) {
14+
method ==(QuadraticInteger c) {
1515
(a == c.a) && (b == c.b) && (w == c.w)
1616
}
1717

1818
method conjugate {
19-
Quadratic(a, -b, w)
19+
QuadraticInteger(a, -b, w)
2020
}
2121

2222
method norm {
2323
a*a - w*b*b
2424
}
2525

2626
method add (Number c) {
27-
Quadratic(a+c, b, w)
27+
QuadraticInteger(a+c, b, w)
2828
}
2929

30-
method add (Quadratic z) {
30+
method add (QuadraticInteger z) {
3131
var (c,d) = (z.a, z.b)
32-
Quadratic(a+c, b+d, w)
32+
QuadraticInteger(a+c, b+d, w)
3333
}
3434

3535
__CLASS__.alias_method(:add, '+')
3636

3737
method sub (Number c) {
38-
Quadratic(a-c, b, w)
38+
QuadraticInteger(a-c, b, w)
3939
}
4040

41-
method sub (Quadratic z) {
41+
method sub (QuadraticInteger z) {
4242
var (c,d) = (z.a, z.b)
43-
Quadratic(a-c, b-d, w)
43+
QuadraticInteger(a-c, b-d, w)
4444
}
4545

4646
__CLASS__.alias_method(:sub, '-')
4747

4848
method mul (Number c) {
49-
Quadratic(a*c, b*c, w)
49+
QuadraticInteger(a*c, b*c, w)
5050
}
5151

52-
method mul (Quadratic z) {
52+
method mul (QuadraticInteger z) {
5353
var (c,d) = (z.a, z.b)
54-
Quadratic(a*c + b*d*w, a*d + b*c, w)
54+
QuadraticInteger(a*c + b*d*w, a*d + b*c, w)
5555
}
5656

5757
__CLASS__.alias_method(:mul, '*')
5858

5959
method mod (Number m) {
60-
Quadratic(a % m, b % m, w)
60+
QuadraticInteger(a % m, b % m, w)
6161
}
6262

6363
__CLASS__.alias_method(:mod, '%')
6464

6565
method pow(Number n) {
6666
var x = self
67-
var c = Quadratic(1, 0, w)
67+
var c = QuadraticInteger(1, 0, w)
6868

6969
for bit in (n.digits(2)) {
7070
c *= x if bit
@@ -79,7 +79,7 @@ class Quadratic(a, b, w = 2) { # represents: a + b*sqrt(w)
7979
method powmod(Number n, Number m) {
8080

8181
var x = self
82-
var c = Quadratic(1, 0, w)
82+
var c = QuadraticInteger(1, 0, w)
8383

8484
for bit in (n.digits(2)) {
8585
(c *= x) %= m if bit #=
@@ -100,11 +100,11 @@ func is_quadratic_pseudoprime (n, r=2) {
100100

101101
return true if (r <= 0)
102102

103-
var x = Quadratic(r, 1, r+2).powmod(n, n)
103+
var x = QuadraticInteger(r, 1, r+2).powmod(n, n)
104104

105105
x.a == r || return false
106106

107-
var y = Quadratic(r, -1, r+2).powmod(n, n)
107+
var y = QuadraticInteger(r, -1, r+2).powmod(n, n)
108108

109109
y.a == r || return false
110110

@@ -114,20 +114,20 @@ func is_quadratic_pseudoprime (n, r=2) {
114114
say is_quadratic_pseudoprime(43) #=> true
115115
say is_quadratic_pseudoprime(97) #=> true
116116

117-
with (Quadratic(1, 1, 2)) {|q|
117+
with (QuadraticInteger(1, 1, 2)) {|q|
118118
say 15.of { q.pow(_).a } #=> A001333
119119
say 15.of { q.pow(_).b } #=> A000129
120120
}
121121

122-
with (Quadratic(1, 1, 3)) {|q|
122+
with (QuadraticInteger(1, 1, 3)) {|q|
123123
say 15.of { q.pow(_).a } #=> A026150
124124
say 15.of { q.pow(_).b } #=> A002605
125125
}
126126

127127
var n = (274177-1)
128128
var m = (2**64 + 1)
129129

130-
with (Quadratic(3, 4, 2)) {|q|
130+
with (QuadraticInteger(3, 4, 2)) {|q|
131131
var r = q.powmod(n, m)
132132
say gcd(r.a-1, m) #=> 2741177
133133
say gcd(r.b, m) #=> 2741177
@@ -140,7 +140,7 @@ func is_gaussian_quadratic_pseudoprime(n) {
140140
return false if (n <= 1)
141141
return true if (n <= 3)
142142

143-
static x = Quadratic(1, -1, -2)
143+
static x = QuadraticInteger(1, -1, -2)
144144

145145
given (n%8) {
146146
when ([1,3]) {

Math/quaternion_integer_primality_test.sf

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,15 @@
2828
# 4765950001, 104510424961, 373523673601, 1240013784241, 4575844294561, 4866233601601
2929

3030
# See also:
31-
# https://en.wikipedia.org/wiki/Quaternion
31+
# https://en.wikipedia.org/wiki/QuaternionInteger
3232

33-
class Quaternion(a, b=0, c=0, d=0) {
33+
class QuaternionInteger(a, b=0, c=0, d=0) {
3434

3535
method to_s {
36-
"Quaternion(#{a}, #{b}, #{c}, #{d})"
36+
"QuaternionInteger(#{a}, #{b}, #{c}, #{d})"
3737
}
3838

39-
method ==(Quaternion z) {
39+
method ==(QuaternionInteger z) {
4040
(a == z.a) && (b == z.b) && (c == z.c) && (d == z.d)
4141
}
4242

@@ -62,7 +62,7 @@ class Quaternion(a, b=0, c=0, d=0) {
6262
)
6363
}
6464

65-
return Quaternion(a2,b2,c2,d2)
65+
return QuaternionInteger(a2,b2,c2,d2)
6666
}
6767
}
6868

@@ -79,13 +79,13 @@ func quaternion_primality_test(n, tries = 3) {
7979
return n.is_prime
8080
}
8181

82-
var z = Quaternion(a,b,c,d)
82+
var z = QuaternionInteger(a,b,c,d)
8383
var r = z.powmod(n,n)
8484

8585
(
8686
(r == z) ||
87-
(r == Quaternion(a)) ||
88-
(r == Quaternion(a, n-b, n-c, n-d))
87+
(r == QuaternionInteger(a)) ||
88+
(r == QuaternionInteger(a, n-b, n-c, n-d))
8989
) && (
9090
(tries > 0) ? __FUNC__(n, tries-1) : true
9191
)

Math/quaternion_integers.sf

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/ruby
1+
7#!/usr/bin/ruby
22

33
# Simple implementation of quaternion integers.
44

@@ -88,7 +88,7 @@ var m = (2**64 + 1)
8888

8989
with (Quaternion(2,3,4,5)) {|q|
9090
var r = q.powmod(n, m)
91-
say gcd(r.b, m) #=> 2741177
92-
say gcd(r.c, m) #=> 2741177
93-
say gcd(r.d, m) #=> 2741177
91+
say gcd(r.b, m) #=> 274177
92+
say gcd(r.c, m) #=> 274177
93+
say gcd(r.d, m) #=> 274177
9494
}

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,7 @@ A nice collection of day-to-day Sidef scripts.
355355
* [Order factorization method](./Math/order_factorization_method.sf)
356356
* [Ore's harmonic numbers](./Math/ore_s_harmonic_numbers.sf)
357357
* [Partial sums of 2 to the bigomega of n](./Math/partial_sums_of_2_to_the_bigomega_of_n.sf)
358+
* [Partial sums of core function](./Math/partial_sums_of_core_function.sf)
358359
* [Partial sums of dedekind psi function](./Math/partial_sums_of_dedekind_psi_function.sf)
359360
* [Partial sums of dedekind psi function recursive](./Math/partial_sums_of_dedekind_psi_function_recursive.sf)
360361
* [Partial sums of euler totient function](./Math/partial_sums_of_euler_totient_function.sf)

0 commit comments

Comments
 (0)