PageRenderTime 34ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/src/gmpy_mpc.h

http://gmpy.googlecode.com/
C Header | 330 lines | 239 code | 28 blank | 63 comment | 56 complexity | 7582549cea87f726f4a068b96652ce14 MD5 | raw file
Possible License(s): GPL-3.0, LGPL-3.0, LGPL-2.1
  1. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2. * gmpy_mpc.h *
  3. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  4. * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision *
  5. * libraries. *
  6. * *
  7. * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
  8. * 2008, 2009 Alex Martelli *
  9. * *
  10. * Copyright 2008, 2009, 2010, 2011, 2012, 2013 Case Van Horsen *
  11. * *
  12. * This file is part of GMPY2. *
  13. * *
  14. * GMPY2 is free software: you can redistribute it and/or modify it under *
  15. * the terms of the GNU Lesser General Public License as published by the *
  16. * Free Software Foundation, either version 3 of the License, or (at your *
  17. * option) any later version. *
  18. * *
  19. * GMPY2 is distributed in the hope that it will be useful, but WITHOUT *
  20. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
  21. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public *
  22. * License for more details. *
  23. * *
  24. * You should have received a copy of the GNU Lesser General Public *
  25. * License along with GMPY2; if not, see <http://www.gnu.org/licenses/> *
  26. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  27. #ifndef GMPY_MPC_H
  28. #define GMPY_MPC_H
  29. #ifdef __cplusplus
  30. extern "C" {
  31. #endif
  32. /* gmpy_mpc C API extension header file.
  33. *
  34. * Provide interface to the MPC (Multiple Precision Complex) library.
  35. *
  36. * Version 2.00, April 2011 (created) casevh
  37. *
  38. * This file is expected to be included from gmpy.h
  39. */
  40. #if defined(MS_WIN32) && defined(_MSC_VER)
  41. # pragma comment(lib,"mpc.lib")
  42. #endif
  43. typedef struct {
  44. PyObject_HEAD
  45. mpc_t c;
  46. Py_hash_t hash_cache;
  47. int rc;
  48. int round_mode;
  49. } PympcObject;
  50. static PyTypeObject Pympc_Type;
  51. #define Pympc_AS_MPC(obj) (((PympcObject *)(obj))->c)
  52. #define Pympc_Check(v) (((PyObject*)v)->ob_type == &Pympc_Type)
  53. /*
  54. * Define macros for comparing with zero, checking if either component is
  55. * 'nan' or 'inf', etc.
  56. */
  57. #define MPC_IS_ZERO_P(x) \
  58. (mpfr_zero_p(mpc_realref(Pympc_AS_MPC(x))) && \
  59. mpfr_zero_p(mpc_imagref(Pympc_AS_MPC(x))))
  60. #define MPC_IS_NAN_P(x) \
  61. (mpfr_nan_p(mpc_realref(Pympc_AS_MPC(x))) || \
  62. mpfr_nan_p(mpc_imagref(Pympc_AS_MPC(x))))
  63. #define MPC_IS_INF_P(x) \
  64. (mpfr_inf_p(mpc_realref(Pympc_AS_MPC(x))) || \
  65. mpfr_inf_p(mpc_imagref(Pympc_AS_MPC(x))))
  66. #define MPC_IS_FINITE_P(x) \
  67. (mpfr_number_p(mpc_realref(Pympc_AS_MPC(x))) && \
  68. mpfr_number_p(mpc_imagref(Pympc_AS_MPC(x))))
  69. /* Verify that an object is an mpc and that both components have valid exp */
  70. #define Pympc_CheckAndExp(v) \
  71. (Pympc_Check(v) && \
  72. (mpfr_zero_p(mpc_realref(Pympc_AS_MPC(v))) || \
  73. (mpfr_regular_p(mpc_realref(Pympc_AS_MPC(v))) && \
  74. ((mpc_realref(Pympc_AS_MPC(v))->_mpfr_exp >= context->ctx.emin)) && \
  75. ((mpc_realref(Pympc_AS_MPC(v))->_mpfr_exp <= context->ctx.emax)) \
  76. ) \
  77. ) && \
  78. (mpfr_zero_p(mpc_imagref(Pympc_AS_MPC(v))) || \
  79. (mpfr_regular_p(mpc_imagref(Pympc_AS_MPC(v))) && \
  80. ((mpc_imagref(Pympc_AS_MPC(v))->_mpfr_exp >= context->ctx.emin)) && \
  81. ((mpc_imagref(Pympc_AS_MPC(v))->_mpfr_exp <= context->ctx.emax)) \
  82. ) \
  83. ) \
  84. )
  85. #define MPC_CHECK_UNDERFLOW(mpct, msg) \
  86. if (MPC_IS_ZERO_P(mpct) && mpct->rc) { \
  87. context->ctx.underflow = 1; \
  88. if (context->ctx.trap_underflow) { \
  89. GMPY_UNDERFLOW(msg); \
  90. goto done; \
  91. } \
  92. }
  93. #define MPC_CHECK_OVERFLOW(mpct, msg) \
  94. if (MPC_IS_INF_P(mpct)) { \
  95. context->ctx.overflow = 1; \
  96. if (context->ctx.trap_overflow) { \
  97. GMPY_OVERFLOW(msg); \
  98. goto done; \
  99. } \
  100. }
  101. #define MPC_CHECK_INVALID(mpct, msg) \
  102. if (MPC_IS_NAN_P(mpct)) { \
  103. context->ctx.invalid = 1; \
  104. if (context->ctx.trap_invalid) { \
  105. GMPY_INVALID(msg); \
  106. goto done; \
  107. } \
  108. }
  109. #define MPC_CHECK_INEXACT(mpct, msg) \
  110. if (mpct->rc) { \
  111. context->ctx.inexact = 1; \
  112. if (context->ctx.trap_inexact) { \
  113. GMPY_INEXACT(msg); \
  114. goto done; \
  115. } \
  116. }
  117. #define MPC_CHECK_FLAGS(mpct, NAME) \
  118. MPC_CHECK_INVALID(mpct, "'mpc' invalid operation in "NAME); \
  119. MPC_CHECK_UNDERFLOW(mpct, "'mpc' underflow in "NAME); \
  120. MPC_CHECK_OVERFLOW(mpct, "'mpc' overflow in "NAME); \
  121. MPC_CHECK_INEXACT(mpct, "'mpc' inexact result in "NAME);
  122. #define MPC_SUBNORMALIZE(mpct) \
  123. if (context->ctx.subnormalize) { \
  124. int rcr, rci; \
  125. rcr = MPC_INEX_RE(mpct->rc); \
  126. rci = MPC_INEX_IM(mpct->rc); \
  127. rcr = mpfr_subnormalize(mpc_realref(mpct->c), rcr, GET_REAL_ROUND(context)); \
  128. rci = mpfr_subnormalize(mpc_imagref(mpct->c), rci, GET_IMAG_ROUND(context)); \
  129. mpct->rc = MPC_INEX(rcr, rci); \
  130. } \
  131. #define MPC_CLEANUP(mpct, NAME) \
  132. MPC_SUBNORMALIZE(mpct); \
  133. MPC_CHECK_FLAGS(mpct, NAME); \
  134. done:\
  135. if (PyErr_Occurred()) { \
  136. Py_DECREF((PyObject*)mpct); \
  137. mpct = NULL; \
  138. } \
  139. return (PyObject*)mpct;
  140. /*
  141. * Parses one, and only one, argument into "self" and converts it to an
  142. * mpc. Is faster, but not as generic, as using PyArg_ParseTuple. It
  143. * supports either gmpy.fname(z) or z.fname(). "self" must be decref'ed.
  144. * "msg" should be an error message that includes the function name and
  145. * describes the required arguments.
  146. */
  147. #define PARSE_ONE_MPC_ARGS(msg) \
  148. if(self && Pympc_Check(self)) { \
  149. if (PyTuple_GET_SIZE(args) != 0) { \
  150. TYPE_ERROR(msg); \
  151. return NULL; \
  152. } \
  153. if (Pympc_CheckAndExp(self)) { \
  154. Py_INCREF(self); \
  155. } \
  156. else { \
  157. if (!(self = (PyObject*)Pympc_From_Complex(self, 0, 0))) { \
  158. TYPE_ERROR(msg); \
  159. return NULL; \
  160. } \
  161. } \
  162. } \
  163. else { \
  164. if (PyTuple_GET_SIZE(args) != 1) { \
  165. TYPE_ERROR(msg); \
  166. return NULL; \
  167. } \
  168. self = PyTuple_GET_ITEM(args, 0);\
  169. if (Pympc_CheckAndExp(self)) { \
  170. Py_INCREF(self); \
  171. } \
  172. else { \
  173. if (!(self = (PyObject*)Pympc_From_Complex(self, 0, 0))) { \
  174. TYPE_ERROR(msg); \
  175. return NULL; \
  176. } \
  177. } \
  178. }
  179. /*
  180. * Parses one, and only one, argument into "self" and converts it to an
  181. * mpc. Is faster, but not as generic, as using PyArg_ParseTuple. It
  182. * supports either gmpy.fname(z) or z.fname(). "self" must be decref'ed.
  183. * "msg" should be an error message that includes the function name and
  184. * describes the required arguments. It assumes the functions is declared
  185. * as either METH_O or METH_NOARGS. It is faster than PARSE_ONE_MPFR and
  186. * passing a tuple as args.
  187. */
  188. #define PARSE_ONE_MPC_OTHER(msg) \
  189. if(self && Pympc_Check(self)) { \
  190. if (Pympc_CheckAndExp(self)) { \
  191. Py_INCREF(self); \
  192. } \
  193. else { \
  194. if (!(self = (PyObject*)Pympc_From_Complex(self, 0, 0))) { \
  195. TYPE_ERROR(msg); \
  196. return NULL; \
  197. } \
  198. } \
  199. } \
  200. else { \
  201. if (Pympc_CheckAndExp(other)) { \
  202. self = other; \
  203. Py_INCREF(self); \
  204. } \
  205. else { \
  206. if (!(self = (PyObject*)Pympc_From_Complex(other, 0, 0))) { \
  207. TYPE_ERROR(msg); \
  208. return NULL; \
  209. } \
  210. } \
  211. }
  212. /*
  213. * Parses two, and only two, arguments into "self" and "var" and converts
  214. * them both to mpC. Is faster, but not as generic, as using PyArg_ParseTuple.
  215. * It supports either gmpy.fname(f,f) or f.fname(f). "self" & "var" must be
  216. * decref'ed after use. "msg" should be an error message that includes the
  217. * function name and describes the required arguments. Replaces
  218. * SELF_MPF_ONE_ARG_CONVERTED(var).
  219. */
  220. #define PARSE_TWO_MPC_ARGS(var, msg) \
  221. if(self && Pympc_Check(self)) { \
  222. if (PyTuple_GET_SIZE(args) != 1) { \
  223. TYPE_ERROR(msg); \
  224. return NULL; \
  225. } \
  226. self = (PyObject*)Pympc_From_Complex(self, 0, 0); \
  227. var = (PyObject*)Pympc_From_Complex(PyTuple_GET_ITEM(args, 0), 0, 0); \
  228. } \
  229. else { \
  230. if (PyTuple_GET_SIZE(args) != 2) { \
  231. TYPE_ERROR(msg); \
  232. return NULL; \
  233. } \
  234. self = (PyObject*)Pympc_From_Complex(PyTuple_GET_ITEM(args, 0), 0, 0); \
  235. var = (PyObject*)Pympc_From_Complex(PyTuple_GET_ITEM(args, 1), 0, 0); \
  236. } \
  237. if (!self || !var) { \
  238. TYPE_ERROR(msg); \
  239. Py_XDECREF((PyObject*)var); \
  240. Py_XDECREF((PyObject*)self); \
  241. return NULL; \
  242. }
  243. static PyObject * Pympc_digits(PyObject *self, PyObject *args);
  244. static PyObject * Pygmpy_mpc(PyObject *self, PyObject *args, PyObject *kwargs);
  245. static PyObject * Pympc_format(PyObject *self, PyObject *args);
  246. static PyObject * Pympc_abs(PyObject *self);
  247. static PyObject * Pympc_neg(PympcObject *self);
  248. static PyObject * Pympc_pos(PympcObject *self);
  249. static PyObject * Pympc_sqr(PyObject* self, PyObject *other);
  250. static PyObject * Pympc_pow(PyObject *base, PyObject *exp, PyObject *m);
  251. static PyObject * Pympc_conjugate(PyObject *self, PyObject *args);
  252. static PyObject * Pympc_getprec_attrib(PympcObject *self, void *closure);
  253. static PyObject * Pympc_getrc_attrib(PympcObject *self, void *closure);
  254. static PyObject * Pympc_getimag_attrib(PympcObject *self, void *closure);
  255. static PyObject * Pympc_getreal_attrib(PympcObject *self, void *closure);
  256. static int Pympc_nonzero(PympcObject *self);
  257. static PyObject * Pympc_is_NAN(PyObject *self, PyObject *other);
  258. static PyObject * Pympc_is_ZERO(PyObject *self, PyObject *other);
  259. static PyObject * Pympc_is_INF(PyObject *self, PyObject *other);
  260. static PyObject * Pympc_is_FINITE(PyObject *self, PyObject *other);
  261. static PyObject * Pympc_phase(PyObject *self, PyObject *other);
  262. static PyObject * Pympc_norm(PyObject *self, PyObject *other);
  263. static PyObject * Pympc_polar(PyObject *self, PyObject *other);
  264. static PyObject * Pympc_rect(PyObject *self, PyObject *args);
  265. static PyObject * Pympc_proj(PyObject *self, PyObject *other);
  266. static PyObject * Pympc_log(PyObject *self, PyObject *other);
  267. static PyObject * Pympc_log10(PyObject *self, PyObject *other);
  268. static PyObject * Pympc_exp(PyObject *self, PyObject *other);
  269. static PyObject * Pympc_sin(PyObject *self, PyObject *other);
  270. static PyObject * Pympc_cos(PyObject *self, PyObject *other);
  271. static PyObject * Pympc_tan(PyObject *self, PyObject *other);
  272. static PyObject * Pympc_sinh(PyObject *self, PyObject *other);
  273. static PyObject * Pympc_cosh(PyObject *self, PyObject *other);
  274. static PyObject * Pympc_tanh(PyObject *self, PyObject *other);
  275. static PyObject * Pympc_asin(PyObject *self, PyObject *other);
  276. static PyObject * Pympc_acos(PyObject *self, PyObject *other);
  277. static PyObject * Pympc_atan(PyObject *self, PyObject *other);
  278. static PyObject * Pympc_asinh(PyObject *self, PyObject *other);
  279. static PyObject * Pympc_acosh(PyObject *self, PyObject *other);
  280. static PyObject * Pympc_atanh(PyObject *self, PyObject *other);
  281. static PyObject * Pympc_sqrt(PyObject *self, PyObject *other);
  282. static PyObject * Pympc_sin_cos(PyObject *self, PyObject *other);
  283. static PyObject * Pympc_fma(PyObject *self, PyObject *args);
  284. static PyObject * Pympc_fms(PyObject *self, PyObject *args);
  285. static PyObject * Pympc_div_2exp(PyObject *self, PyObject *args);
  286. static PyObject * Pympc_mul_2exp(PyObject *self, PyObject *args);
  287. static Py_hash_t Pympc_hash(PympcObject *self);
  288. static PyObject * Pympc_add_fast(PyObject *x, PyObject *y);
  289. static PyObject * Pympc_add(PyObject *self, PyObject *args);
  290. static PyObject * Pympc_sub_fast(PyObject *x, PyObject *y);
  291. static PyObject * Pympc_sub(PyObject *self, PyObject *args);
  292. static PyObject * Pympc_mul_fast(PyObject *x, PyObject *y);
  293. static PyObject * Pympc_mul(PyObject *self, PyObject *args);
  294. static PyObject * Pympc_truediv_fast(PyObject *x, PyObject *y);
  295. #ifdef PY2
  296. static PyObject * Pympc_div2_fast(PyObject *x, PyObject *y);
  297. #endif
  298. static PyObject * Pympc_div(PyObject *self, PyObject *args);
  299. #ifdef __cplusplus
  300. }
  301. #endif
  302. #endif