Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

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

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

""" 

`q`-Bernoulli Numbers and Polynomials 

""" 

from sage.rings.integer_ring import ZZ 

from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing 

from sage.misc.cachefunc import cached_function 

  

  

@cached_function 

def q_bernoulli(m, p=None): 

r""" 

Compute Carlitz's `q`-analogue of the Bernoulli numbers. 

  

For every nonnegative integer `m`, the `q`-Bernoulli number 

`\beta_m` is a rational function of the indeterminate `q` whose 

value at `q=1` is the usual Bernoulli number `B_m`. 

  

INPUT: 

  

- `m` -- a nonnegative integer 

  

- `p` (default: ``None``) -- an optional value for `q` 

  

OUTPUT: 

  

A rational function of the indeterminate `q` (if `p` is ``None``) 

  

Otherwise, the rational function is evaluated at `p`. 

  

EXAMPLES:: 

  

sage: from sage.combinat.q_bernoulli import q_bernoulli 

sage: q_bernoulli(0) 

1 

sage: q_bernoulli(1) 

-1/(q + 1) 

sage: q_bernoulli(2) 

q/(q^3 + 2*q^2 + 2*q + 1) 

sage: all(q_bernoulli(i)(q=1) == bernoulli(i) for i in range(12)) 

True 

  

One can evaluate the rational function by giving a second argument:: 

  

sage: x = PolynomialRing(GF(2),'x').gen() 

sage: q_bernoulli(5,x) 

x/(x^6 + x^5 + x + 1) 

  

The function does not accept negative arguments:: 

  

sage: q_bernoulli(-1) 

Traceback (most recent call last): 

... 

ValueError: the argument must be a nonnegative integer 

  

REFERENCES: 

  

.. [Ca1948] Leonard Carlitz, "q-Bernoulli numbers and polynomials". Duke Math J. 15, 987-1000 (1948), :doi:`10.1215/S0012-7094-48-01588-9` 

  

.. [Ca1954] Leonard Carlitz, "q-Bernoulli and Eulerian numbers". Trans Am Soc. 76, 332-350 (1954), :doi:`10.1090/S0002-9947-1954-0060538-2` 

""" 

m = ZZ(m) 

if m < 0: 

raise ValueError("the argument must be a nonnegative integer") 

cdef int i 

q = PolynomialRing(ZZ, 'q').gen() 

result = (q - 1)**(1-m) * sum((-1)**(m-i)*m.binomial(i)*(i+1)/(q**(i+1)-1) 

for i in range(m + 1)) 

if p is None: 

return result 

else: 

return result(q=p) 

  

  

@cached_function 

def q_bernoulli_polynomial(m): 

r""" 

Compute Carlitz's `q`-analogue of the Bernoulli polynomials. 

  

For every nonnegative integer `m`, the `q`-Bernoulli polynomial 

is a polynomial in one variable `x` with coefficients in `\QQ(q)` whose 

value at `q=1` is the usual Bernoulli polynomial `B_m(x)`. 

  

The original `q`-Bernoulli polynomials introduced by Carlitz were 

polynomials in `q^y` with coefficients in `\QQ(q)`. This function returns 

these polynomials but expressed in the variable `x=(q^y-1)/(q-1)`. This 

allows to let `q=1` to recover the classical Bernoulli polynomials. 

  

INPUT: 

  

- `m` -- a nonnegative integer 

  

OUTPUT: 

  

A polynomial in one variable `x`. 

  

EXAMPLES:: 

  

sage: from sage.combinat.q_bernoulli import q_bernoulli_polynomial, q_bernoulli 

sage: q_bernoulli_polynomial(0) 

1 

sage: q_bernoulli_polynomial(1) 

(2/(q + 1))*x - 1/(q + 1) 

sage: x = q_bernoulli_polynomial(1).parent().gen() 

sage: all(q_bernoulli_polynomial(i)(q=1)==bernoulli_polynomial(x,i) for i in range(12)) 

True 

sage: all(q_bernoulli_polynomial(i)(x=0)==q_bernoulli(i) for i in range(12)) 

True 

  

The function does not accept negative arguments:: 

  

sage: q_bernoulli_polynomial(-1) 

Traceback (most recent call last): 

... 

ValueError: the argument must be a nonnegative integer 

  

REFERENCES: [Ca1948]_, [Ca1954]_ 

""" 

m = ZZ(m) 

if m < 0: 

raise ValueError("the argument must be a nonnegative integer") 

cdef int i 

R = PolynomialRing(ZZ, 'q') 

q = R.gen() 

x = PolynomialRing(R, 'x').gen() 

z = 1 + (q - 1) * x 

return sum(m.binomial(i) * x ** (m - i) * z ** i * q_bernoulli(i) 

for i in range(m + 1))