Move term erase methods into private.
[piranha:mainline.git] / src / core / base_classes / base_series_probe.h
1 /***************************************************************************
2  *   Copyright (C) 2007, 2008 by Francesco Biscani   *
3  *   bluescarni@gmail.com   *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20
21 #ifndef PIRANHA_BASE_SERIES_PROBE_H
22 #define PIRANHA_BASE_SERIES_PROBE_H
23
24 #include <cmath> // For std::abs.
25
26 #include "../exceptions.h"
27 #include "../mp.h"
28 #include "../null_type.h"
29 #include "base_series_def.h"
30
31 #define derived_const_cast static_cast<Derived const *>(this)
32 #define derived_cast static_cast<Derived *>(this)
33
34 namespace piranha
35 {
36         template <__PIRANHA_BASE_SERIES_TP_DECL>
37         inline bool toolbox<base_series<__PIRANHA_BASE_SERIES_TP> >::is_single_cf() const
38         {
39                 return (length() == 1 && begin()->m_key.is_unity());
40         }
41
42         template <__PIRANHA_BASE_SERIES_TP_DECL>
43         template <class ArgsTuple>
44         inline double toolbox<base_series<__PIRANHA_BASE_SERIES_TP> >::base_norm(const ArgsTuple &args_tuple) const
45         {
46                 const const_iterator it_f = end();
47                 double retval = 0;
48                 for (const_iterator it = begin(); it != it_f; ++it) {
49                         retval += it->m_cf.norm(args_tuple) * it->m_key.norm(args_tuple);
50                 }
51                 return retval;
52         }
53
54         template <__PIRANHA_BASE_SERIES_TP_DECL>
55         template <class ArgsTuple>
56         inline typename toolbox<base_series<__PIRANHA_BASE_SERIES_TP> >::eval_type
57                 toolbox<base_series<__PIRANHA_BASE_SERIES_TP> >::base_eval(const double &t, const ArgsTuple &args_tuple) const
58         {
59                 const const_iterator it_f = end();
60                 eval_type retval(0);
61                 for (const_iterator it = begin(); it != it_f; ++it) {
62                         eval_type tmp(it->m_cf.eval(t, args_tuple));
63                         tmp *= it->m_key.eval(t, args_tuple);
64                         retval += tmp;
65                 }
66                 return retval;
67         }
68
69         /// Return the number of terms of the series.
70         template <__PIRANHA_BASE_SERIES_TP_DECL>
71         inline typename toolbox<base_series<__PIRANHA_BASE_SERIES_TP> >::size_type toolbox<base_series<__PIRANHA_BASE_SERIES_TP> >::length() const
72         {
73                 return m_container.size();
74         }
75
76         /// Is series empty?
77         template <__PIRANHA_BASE_SERIES_TP_DECL>
78         inline bool toolbox<base_series<__PIRANHA_BASE_SERIES_TP> >::empty() const
79         {
80                 return m_container.empty();
81         }
82
83         /// Number of atoms in the series.
84         template <__PIRANHA_BASE_SERIES_TP_DECL>
85         inline typename toolbox<base_series<__PIRANHA_BASE_SERIES_TP> >::size_type toolbox<base_series<__PIRANHA_BASE_SERIES_TP> >::atoms() const
86         {
87                 size_type retval = 0;
88                 const const_iterator it_f = end();
89                 for (const_iterator it = begin(); it != it_f; ++it) {
90                         retval += it->m_cf.atoms() + it->m_key.atoms();
91                 }
92                 return retval;
93         }
94
95         /// Test for equality.
96         /**
97          * Please note that this method has no knowledge about arguments: all comparisons performed here on coefficients and keys
98          * assume that the arguments tuples of this and other have been merged.
99          */
100         template <__PIRANHA_BASE_SERIES_TP_DECL>
101         inline bool toolbox<base_series<__PIRANHA_BASE_SERIES_TP> >::base_equal_to(const Derived &other) const
102         {
103                 if (length() != other.length()) {
104                         return false;
105                 }
106                 const const_iterator it_f = end(), it_f_other = other.end();
107                 for (const_iterator it = begin(); it != it_f; ++it) {
108                         const_iterator it_other(other.find_term(*it));
109                         if (it_other == it_f_other || !(it_other->m_cf == it->m_cf)) {
110                                 return false;
111                         }
112                 }
113                 return true;
114         }
115
116         template <__PIRANHA_BASE_SERIES_TP_DECL>
117         template <class Number>
118         inline bool toolbox<base_series<__PIRANHA_BASE_SERIES_TP> >::generic_numerical_comparison(const Number &x) const
119         {
120                 // Use std::abs() to cope with complex numbers. In case of mp classes this could throw value_error,
121                 // so handle this.
122                 try {
123                         if (std::abs(x) == 0) {
124                                 return empty();
125                         }
126                 } catch (const value_error &) {
127                         // Don't do anything, continue the flow.
128                 }
129                 if (!is_single_cf()) {
130                         return false;
131                 }
132                 return (begin()->m_cf == x);
133         }
134
135         template <__PIRANHA_BASE_SERIES_TP_DECL>
136         inline bool toolbox<base_series<__PIRANHA_BASE_SERIES_TP> >::base_equal_to(const double &x) const
137         {
138                 return generic_numerical_comparison(x);
139         }
140
141         template <__PIRANHA_BASE_SERIES_TP_DECL>
142         inline bool toolbox<base_series<__PIRANHA_BASE_SERIES_TP> >::base_equal_to(const mp_rational &q) const
143         {
144                 return generic_numerical_comparison(q);
145         }
146
147         template <__PIRANHA_BASE_SERIES_TP_DECL>
148         inline bool toolbox<base_series<__PIRANHA_BASE_SERIES_TP> >::base_equal_to(const mp_integer &z) const
149         {
150                 return generic_numerical_comparison(z);
151         }
152 }
153
154 #undef derived_const_cast
155 #undef derived_cast
156
157 #endif