Kernel Quantum Probability Library
The KQP library aims at providing tools for working with quantums probabilities
kqp.hpp
1 /*
2  This file is part of the Kernel Quantum Probability library (KQP).
3 
4  KQP is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  KQP is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with KQP. If not, see <http://www.gnu.org/licenses/>.
16  */
17 #ifndef __KQP_H__
18 #define __KQP_H__
19 
20 // Disable warnings for non used typedefs
21 #ifndef __clang__
22 #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
23 #endif
24 
25 #ifdef EIGEN_CORE_H
26  #error "kqp.hpp should be included before any Eigen source"
27 #endif
28 
29 #include <iostream>
30 
31 namespace Eigen {
32  template<typename Scalar> class Identity;
33 }
34 #define EIGEN_MATRIXBASE_PLUGIN <kqp/eigen_matrixbase_plugin.h.inc>
35 #define EIGEN_MATRIX_PLUGIN <kqp/eigen_matrix_plugin.h.inc>
36 #define EIGEN_SPARSEMATRIX_PLUGIN <kqp/eigen_sparse_matrix_plugin.h.inc>
37 
38 // Define move operators if needed:
39 // * clang with libstdc++
40 #if (defined(__clang__) && defined(__GLIBCXX__))
41 namespace std {
42  inline namespace _kqp {
43  template<class _Ty>
44  struct _Remove_reference
45  { // remove reference
46  typedef _Ty _Type;
47  };
48 
49  template<class _Ty>
50  struct _Remove_reference<_Ty&>
51  { // remove reference
52  typedef _Ty _Type;
53  };
54 
55  template<class _Ty>
56  struct _Remove_reference<_Ty&&>
57  { // remove rvalue reference
58  typedef _Ty _Type;
59  };
60 
61  template<class _Ty> inline
62  typename _Remove_reference<_Ty>::_Type&&
63  move(_Ty&& _Arg)
64  { // forward _Arg as movable
65  return ((typename _Remove_reference<_Ty>::_Type&&)_Arg);
66  }
67  template<class S>
68  S&& forward(typename _Remove_reference<S>::type& a) noexcept
69  {
70  return static_cast<S&&>(a);
71  }
72  }
73 }
74 #endif
75 
76 namespace Eigen {
77  template<typename Scalar> class Identity;
78 }
79 
80 
81 #include "Eigen/Core"
82 
83 
84 
85 #include <boost/format.hpp>
86 #include <boost/lexical_cast.hpp>
87 #include <boost/shared_ptr.hpp>
88 #include <string>
89 #include <complex>
90 #include "cxxabi.h"
91 
92 
93 
94 #ifndef NOLOGGING
95 #include "log4cxx/logger.h"
96 #endif
97 
98 // GCC specifics
99 #if defined(__GNUC__)
100 #define KQP_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
101 #if KQP_GCC_VERSION < 407000
102 #define override
103 #endif // GCC < 4.7
104 #endif // GCC
105 
106 
107 #include <kqp/exceptions.hpp>
108 
109 #
110 # define NEW_SHARED(T,...) boost::shared_ptr<T>(T(__VA_ARGS__))
111 
112 #
113 # define KQP_REAL_OF(Scalar) typename Eigen::NumTraits<Scalar>::Real
114 
115 #
116 # define KQP_MATRIX(Scalar) Eigen::Matrix<Scalar, Dynamic, Dynamic>
117 
118 #
119 # define KQP_VECTOR(Scalar) Eigen::Matrix<Scalar, Dynamic, 1>
120 
121 
122 
123 #
124 # define KQP_DEMANGLEP(x) (x ? kqp::demangle(typeid(x)) : kqp::demangle(typeid(*x)))
125 
126 #
127 # define KQP_DEMANGLE(x) kqp::demangle(typeid(x))
128 
129 #
130 # define KQP_XSTRING_IT(x) #x
131 
132 #
133 # define KQP_STRING_IT(x) KQP_XSTRING_IT(x)
134 
135 
136  // ---- LOGGING MACROS ---
137 
138 # ifdef NOLOGGING
139 
140 # define DEFINE_LOGGER(logger, loggerName)
141 # define KQP_LOG_DEBUG(name,message)
142 # define KQP_LOG_DEBUG_S(name,message)
143 # define KQP_LOG_INFO(name,message)
144 # define KQP_LOG_WARN(name,message)
145 # define KQP_LOG_ERROR(name,message)
146 # define KQP_LOG_ASSERT(name,condition,message)
147 
148 # // Check logger level
149 # define KQP_IS_DEBUG_ENABLED(name) false
150 # define KQP_IS_INFO_ENABLED(name) false
151 # define KQP_IS_WARN_ENABLED(name) false
152 # define KQP_IS_ERROR_ENABLED(name) false
153 
154 #
155 # define KQP_THROW_EXCEPTION(type, message) BOOST_THROW_EXCEPTION(boost::enable_error_info(type()) << errinfo_message(message))
156 
157 
158 
159 #else // We do some logging
160 
161 
162 # define KQP_IS_TRACE_ENABLED(name) (name->isTraceEnabled())
163 # define KQP_IS_DEBUG_ENABLED(name) (name->isDebugEnabled())
164 # define KQP_IS_INFO_ENABLED(name) (name->isInfoEnabled())
165 # define KQP_IS_WARN_ENABLED(name) (name->isWarnEnabled())
166 # define KQP_IS_ERROR_ENABLED(name) (name->isErrorEnabled())
167 
168 # // We define the logger
169 # define DEFINE_LOGGER(loggerId, loggerName) namespace { log4cxx::LoggerPtr loggerId(log4cxx::Logger::getLogger(loggerName)); }
170 
171 # // * Note * Use the if (false) construct to compile code; the code optimizer
172 # // is able to remove the corresponding code, so it does change
173 # // the speed
174  // * Note * We fully skip trace messages when NDEBUG is defined
175 
176 # ifndef NDEBUG
177 
178 
179 #
180 # define KQP_M_NDEBUG(x)
181 # define KQP_M_DEBUG(x) x
182 
183 #
184 # define KQP_LOG_TRACE(name,message) { kqp::Logger::prepare(); LOG4CXX_DEBUG(name, message); }
185 
186 #
188 #
189 # define KQP_THROW_EXCEPTION(type, message) { \
190  KQP_LOG_ERROR(kqp::main_logger(), "[Exception " << KQP_DEMANGLE(type()) << "] " << message); \
191  abort(); }
192 
193 # else // No DEBUG
194 
195 # define KQP_M_NDEBUG(x) x
196 # define KQP_M_DEBUG(x)
197 
198 #
199 # define KQP_THROW_EXCEPTION(type, message) BOOST_THROW_EXCEPTION(boost::enable_error_info(type()) << errinfo_message(message))
200 
201 #
202 # define KQP_LOG_TRACE(name,message) { if (false) { LOG4CXX_DEBUG(name, message) }}
203 
204 #endif // ELSE
205 
206 
207 #define KQP_LOG_DEBUG(name,message) { kqp::Logger::prepare(); LOG4CXX_DEBUG(name, message); }
208 #define KQP_LOG_INFO(name,message) { kqp::Logger::prepare(); LOG4CXX_INFO(name, message); }
209 #define KQP_LOG_WARN(name,message) { kqp::Logger::prepare(); LOG4CXX_WARN(name, message); }
210 #define KQP_LOG_ERROR(name,message) { kqp::Logger::prepare(); LOG4CXX_ERROR(name, message); }
211 
212 #define KQP_LOG_ASSERT(name,condition,message) \
213  { if (!(condition)) { \
214  KQP_THROW_EXCEPTION(kqp::assertion_exception, (boost::format("Assert failed [%s]: %s") %KQP_STRING_IT(condition) %message).str()); \
215  }}
216 
217 #include <kqp/logging.hpp>
218 
219 #endif // ndef(NOLOGGING)
220 
221 // --- Helper macros for logging
222 
223 #define KQP_THROW_EXCEPTION_F(type, message, arguments) KQP_THROW_EXCEPTION(type, (boost::format(message) arguments).str())
224 
225 #define KQP_LOG_TRACE_F(name,message,args) KQP_LOG_TRACE(name, (boost::format(message) args))
226 #define KQP_LOG_DEBUG_F(name,message,args) KQP_LOG_DEBUG(name, (boost::format(message) args))
227 #define KQP_LOG_INFO_F(name,message,args) KQP_LOG_INFO(name, (boost::format(message) args))
228 #define KQP_LOG_WARN_F(name,message,args) KQP_LOG_WARN(name, (boost::format(message) args))
229 #define KQP_LOG_ERROR_F(name,message,args) KQP_LOG_ERROR(name, (boost::format(message) args))
230 #define KQP_LOG_ASSERT_F(name,condition,message,args) KQP_LOG_ASSERT(name,condition,(boost::format(message) args).str())
231 #define KQP_LOG_DEBUG_S(name,message) LOG4CXX_DEBUG(name, "[" << KQP_DEMANGLE(*this) << "/" << this << "] " << message)
232 
233 
234 namespace kqp {
235 
236  // Using declarations
237  using Eigen::Dynamic;
238  using Eigen::Matrix;
239 
240  // The index type
241  typedef Eigen::DenseIndex Index;
242 
244  inline bool isNaN(double x) {
245  return !(x == x);
246  }
247 
248  inline bool isNaN(float x) {
249  return !(x == x);
250  }
251 
252  template<typename scalar> inline bool isNaN(const std::complex<scalar> &x) {
253  return !(std::real(x) == std::real(x)) || !(std::imag(x) == std::imag(x));
254  }
255 
256 
258  inline double epsilon() { return 1e-15; }
259 
260  inline std::string demangle(const std::type_info &x) {
261  // __cxa_demangle(const char* __mangled_name, char* __output_buffer, size_t* __length, int* __status);
262  static size_t size = 500;
263  static char *buffer = (char*)malloc(size * sizeof(char));
264  return abi::__cxa_demangle(x.name(), buffer, &size, 0);
265  }
266 
268  template <class T> std::string convert(const T &x) {
269  std::ostringstream strout;
270  strout << x;
271  return strout.str();
272  }
273 
274 
276  template<class T> T convert(const std::string &s) {
277  T x;
278  std::istringstream str_in(s);
279  if (!str_in) BOOST_THROW_EXCEPTION(errinfo_message("Bad input"));
280  else if (! (str_in >> x )) BOOST_THROW_EXCEPTION(errinfo_message("Bad input"));
281  return x;
282  }
283 
284  template<class T, class U> boost::shared_ptr<T> our_dynamic_cast(boost::shared_ptr<U> const & r) {
285  try {
286  return boost::dynamic_pointer_cast<T,U>(r);
287  } catch(std::exception &e) {
288  KQP_THROW_EXCEPTION_F(bad_cast_exception, "Bad cast from %s [%s] to %s",
289  %KQP_DEMANGLEP(r.get()) %KQP_DEMANGLE(U) %KQP_DEMANGLE(T));
290  }
291  }
292 
293 
294  template<class T, class U> T our_dynamic_cast(U &r) {
295  try {
296  return dynamic_cast<T>(r);
297  } catch(std::exception &e) {
298  KQP_THROW_EXCEPTION_F(bad_cast_exception, "Bad cast from %s [%s] to %s",
299  %KQP_DEMANGLE(r) %KQP_DEMANGLE(U) %KQP_DEMANGLE(T));
300  }
301  }
302 
303  template<class T, class U> T our_dynamic_cast(U *r) {
304  try {
305  return dynamic_cast<T>(r);
306  } catch(std::exception &e) {
307  KQP_THROW_EXCEPTION_F(bad_cast_exception, "Bad cast from %s [%s] to %s",
308  %KQP_DEMANGLE(r) %KQP_DEMANGLE(U) %KQP_DEMANGLE(T));
309  }
310  }
311 
312  template<typename T, typename U> inline T lexical_cast(U &u) {
313  try {
314  boost::lexical_cast<T>(u);
315  } catch(boost::bad_lexical_cast &e) {
316  KQP_THROW_EXCEPTION_F(boost::bad_lexical_cast, "Converting [%s] to type %s",
317  %u %KQP_DEMANGLE(T));
318  }
319  }
320 
321 
322 
323 } // NS kqp
324 
325 #endif