]> www.ginac.de Git - ginac.git/blob - ginac/inifcns_zeta.cpp
a39d8e6aa1fd542c2e015a99e227c8ecb0f50ffb
[ginac.git] / ginac / inifcns_zeta.cpp
1 /** @file inifcns_zeta.cpp
2  *
3  *  Implementation of the Zeta-function and some related stuff. */
4
5 /*
6  *  GiNaC Copyright (C) 1999-2001 Johannes Gutenberg University Mainz, Germany
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 #include <vector>
24 #include <stdexcept>
25
26 #include "inifcns.h"
27 #include "constant.h"
28 #include "numeric.h"
29 #include "power.h"
30 #include "symbol.h"
31 #include "utils.h"
32
33 #ifndef NO_NAMESPACE_GINAC
34 namespace GiNaC {
35 #endif // ndef NO_NAMESPACE_GINAC
36
37 //////////
38 // Riemann's Zeta-function
39 //////////
40
41 static ex zeta1_evalf(const ex & x)
42 {
43         BEGIN_TYPECHECK
44                 TYPECHECK(x,numeric)
45         END_TYPECHECK(zeta(x))
46                 
47         return zeta(ex_to_numeric(x));
48 }
49
50 static ex zeta1_eval(const ex & x)
51 {
52         if (x.info(info_flags::numeric)) {
53                 numeric y = ex_to_numeric(x);
54                 // trap integer arguments:
55                 if (y.is_integer()) {
56                         if (y.is_zero())
57                                 return -_ex1_2();
58                         if (x.is_equal(_ex1()))
59                                 throw(std::domain_error("zeta(1): infinity"));
60                         if (x.info(info_flags::posint)) {
61                                 if (x.info(info_flags::odd))
62                                         return zeta(x).hold();
63                                 else
64                                         return abs(bernoulli(y))*pow(Pi,x)*pow(_num2(),y-_num1())/factorial(y);
65                         } else {
66                                 if (x.info(info_flags::odd))
67                                         return -bernoulli(_num1()-y)/(_num1()-y);
68                                 else
69                                         return _num0();
70                         }
71                 }
72         }
73         return zeta(x).hold();
74 }
75
76 static ex zeta1_deriv(const ex & x, unsigned deriv_param)
77 {
78         GINAC_ASSERT(deriv_param==0);
79         
80         return zeta(_ex1(), x);
81 }
82
83 const unsigned function_index_zeta1 =
84         function::register_new(function_options("zeta").
85                                eval_func(zeta1_eval).
86                                evalf_func(zeta1_evalf).
87                                derivative_func(zeta1_deriv).
88                                overloaded(2));
89
90 //////////
91 // Derivatives of Riemann's Zeta-function  zeta(0,x)==zeta(x)
92 //////////
93
94 static ex zeta2_eval(const ex & n, const ex & x)
95 {
96         if (n.info(info_flags::numeric)) {
97                 // zeta(0,x) -> zeta(x)
98                 if (n.is_zero())
99                         return zeta(x);
100         }
101         
102         return zeta(n, x).hold();
103 }
104
105 static ex zeta2_deriv(const ex & n, const ex & x, unsigned deriv_param)
106 {
107         GINAC_ASSERT(deriv_param<2);
108         
109         if (deriv_param==0) {
110                 // d/dn zeta(n,x)
111                 throw(std::logic_error("cannot diff zeta(n,x) with respect to n"));
112         }
113         // d/dx psi(n,x)
114         return zeta(n+1,x);
115 }
116
117 const unsigned function_index_zeta2 =
118         function::register_new(function_options("zeta").
119                                eval_func(zeta2_eval).
120                                derivative_func(zeta2_deriv).
121                                overloaded(2));
122
123 #ifndef NO_NAMESPACE_GINAC
124 } // namespace GiNaC
125 #endif // ndef NO_NAMESPACE_GINAC