-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpartial_sums_of_core_function.sf
56 lines (47 loc) · 1.2 KB
/
partial_sums_of_core_function.sf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#!/usr/bin/ruby
# Sub-linear algorithm for computing partial sums of the core(n) function.
# OEIS sequence:
# https://oeis.org/A069891
# Sequence A069891(10^n):
# S(10^1) = 38
# S(10^2) = 3233
# S(10^3) = 328322
# S(10^4) = 32926441
# S(10^5) = 3289873890
# S(10^6) = 328984021545
# S(10^7) = 32898872196712
# S(10^8) = 3289866649713946
# S(10^9) = 328986818422458525
# S(10^10) = 32898680588469254505
# S(10^11) = 3289868138800129869623
func squarefree_sum(n) { # A066779
var sum = 0
n.isqrt.each_squarefree {|k|
sum += (moebius(k) * k*k * faulhaber(idiv(n, k*k), 1))
}
return sum
}
func core_partial_sum(n) { # A069891
n.dirichlet_sum(
{|k| k.is_square ? 1 : 0 },
{|k| abs(k*mu(k)) },
{|k| k.isqrt },
{|k| squarefree_sum(k) },
)
}
func f(n) { # A046970
n.factor_prod {|p|
1 - p*p
}
}
func core_partial_sum_faster(n) { # A069891
sum(1..n.isqrt, {|k|
f(k) * faulhaber(idiv(n, k*k), 1)
})
}
say core_partial_sum(10**5) #=> 3289873890
say core_partial_sum_faster(10**5) #=> 3289873890
assert_eq(
100.of(core_partial_sum),
100.of(core_partial_sum_faster)
)