-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfaulhaber_s_formula.sf
40 lines (31 loc) · 1.02 KB
/
faulhaber_s_formula.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
#!/usr/bin/ruby
# The formula for calculating the sum of consecutive
# numbers raised to a given power, such as:
# 1^p + 2^p + 3^p + ... + n^p
# where p is a positive integer.
# See also:
# https://en.wikipedia.org/wiki/Faulhaber%27s_formula
# The Faulhaber's formula
# See: https://en.wikipedia.org/wiki/Faulhaber%27s_formula
func faulhaber_formula (n, p) {
sum(0..p, {|k|
binomial(p + 1, k) * bernoulli(k) * n**(p + 1 - k)
}) / (p+1)
}
# Alternate expression using Bernoulli polynomials
# See: https://en.wikipedia.org/wiki/Faulhaber%27s_formula#Alternate_expressions
func bernoulli_polynomials (n, x) {
sum(0..n, {|k|
binomial(n, k) * bernoulli(n - k) * x**k
})
}
func faulhaber_formula_2 (n, p) {
(bernoulli_polynomials(p + 1, n) - bernoulli(p + 1)) / (p + 1)
}
for p in (0..20) {
var n = 100.irand
var r = faulhaber_formula(n, p)
assert_eq(r, faulhaber_formula_2(n, p))
assert_eq(r, n.faulhaber_sum(p)) # built-in
printf("faulhaber_#{p}(%2d) = %s\n", n, r)
}