/ src / gmpy2_square.c
gmpy2_square.c
  1  /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2   * gmpy2_square.c                                                             *
  3   * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  4   * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision   *
  5   * libraries.                                                              *
  6   *                                                                         *
  7   * Copyright 2000 - 2009 Alex Martelli                                     *
  8   *                                                                         *
  9   * Copyright 2008 - 2021 Case Van Horsen                                   *
 10   *                                                                         *
 11   * This file is part of GMPY2.                                             *
 12   *                                                                         *
 13   * GMPY2 is free software: you can redistribute it and/or modify it under  *
 14   * the terms of the GNU Lesser General Public License as published by the  *
 15   * Free Software Foundation, either version 3 of the License, or (at your  *
 16   * option) any later version.                                              *
 17   *                                                                         *
 18   * GMPY2 is distributed in the hope that it will be useful, but WITHOUT    *
 19   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or   *
 20   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public    *
 21   * License for more details.                                               *
 22   *                                                                         *
 23   * You should have received a copy of the GNU Lesser General Public        *
 24   * License along with GMPY2; if not, see <http://www.gnu.org/licenses/>    *
 25   * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 26  
 27  /* Public API
 28   * ==========
 29   * The following function is available as part of GMPY2's C API. A NULL value
 30   * for context implies the function should use the currently active context.
 31   *
 32   *   GMPy_Number_Square(Number, Number, context|NULL)
 33   *
 34   * Private API
 35   * ===========
 36   *   GMPy_Integer_Square(Integer, Integer, context|NULL)
 37   *   GMPy_Rational_Square(Rational, Rational, context|NULL)
 38   *   GMPy_Real_Square(Real, Real, context|NULL)
 39   *   GMPy_Complex_Square(Complex, Complex, context|NULL)
 40   *
 41   *   GMPy_Context_Square(context, args)
 42   *
 43   */
 44  
 45  static PyObject *
 46  _GMPy_MPZ_Square(PyObject *x, CTXT_Object *context)
 47  {
 48      MPZ_Object *result = NULL;
 49  
 50      if (!(result = GMPy_MPZ_New(context))) {
 51          return NULL;
 52      }
 53  
 54      mpz_mul(result->z, MPZ(x), MPZ(x));
 55      return (PyObject*)result;
 56  }
 57  
 58  static PyObject *
 59  GMPy_Integer_Square(PyObject *x, CTXT_Object *context)
 60  {
 61      PyObject *result, *tempx;
 62  
 63      if (!(tempx = (PyObject*)GMPy_MPZ_From_Integer(x, context))) {
 64          return NULL;
 65      }
 66  
 67      result = _GMPy_MPZ_Square(tempx, context);
 68      Py_DECREF(tempx);
 69      return result;
 70  }
 71  
 72  static PyObject *
 73  _GMPy_MPQ_Square(PyObject *x, CTXT_Object *context)
 74  {
 75      MPQ_Object *result;
 76  
 77      if (!(result = GMPy_MPQ_New(context))) {
 78          return NULL;
 79      }
 80  
 81      mpq_mul(result->q, MPQ(x), MPQ(x));
 82      return (PyObject*)result;
 83  }
 84  
 85  static PyObject *
 86  GMPy_Rational_Square(PyObject *x, CTXT_Object *context)
 87  {
 88      PyObject *result, *tempx;
 89  
 90      if (!(tempx = (PyObject*)GMPy_MPQ_From_Rational(x, context))) {
 91          return NULL;
 92      }
 93  
 94      result = _GMPy_MPQ_Square(tempx, context);
 95      Py_DECREF(tempx);
 96      return result;
 97  }
 98  
 99  static PyObject *
100  _GMPy_MPFR_Square(PyObject *x, CTXT_Object *context)
101  {
102      MPFR_Object *result;
103  
104      CHECK_CONTEXT(context);
105  
106      if (!(result = GMPy_MPFR_New(0, context))) {
107          return NULL;
108      }
109  
110      mpfr_clear_flags();
111  
112      mpfr_sqr(result->f, MPFR(x), GET_MPFR_ROUND(context));
113      _GMPy_MPFR_Cleanup(&result, context);
114      return (PyObject*)result;
115  }
116  
117  static PyObject *
118  GMPy_Real_Square(PyObject *x, CTXT_Object *context)
119  {
120      PyObject *result, *tempx;
121  
122      CHECK_CONTEXT(context);
123  
124      if (!(tempx = (PyObject*)GMPy_MPFR_From_Real(x, 1, context))) {
125          return NULL;
126      }
127  
128      result = _GMPy_MPFR_Square(tempx, context);
129      Py_DECREF(tempx);
130      return result;
131  }
132  
133  static PyObject *
134  _GMPy_MPC_Square(PyObject *x, CTXT_Object *context)
135  {
136      MPC_Object *result;
137  
138      CHECK_CONTEXT(context);
139  
140      if (!(result = GMPy_MPC_New(0, 0, context))) {
141          return NULL;
142      }
143  
144      mpc_sqr(result->c, MPC(x), GET_MPC_ROUND(context));
145      _GMPy_MPC_Cleanup(&result, context);
146      return (PyObject*)result;
147  }
148  static PyObject *
149  GMPy_Complex_Square(PyObject *x, CTXT_Object *context)
150  {
151      PyObject *result, *tempx;
152  
153      CHECK_CONTEXT(context);
154  
155      if (!(tempx = (PyObject*)GMPy_MPC_From_Complex(x, 1, 1, context))) {
156          return NULL;
157      }
158  
159      result = _GMPy_MPC_Square(tempx, context);
160      Py_DECREF(tempx);
161      return result;
162  }
163  
164  PyDoc_STRVAR(GMPy_doc_function_square,
165  "square(x) -> number\n\n"
166  "Return x * x. If x is an integer, then the result is an 'mpz'.\n"
167  "If x is a rational, then the result is an 'mpq'. If x is a float,\n"
168  "then the result is an 'mpfr'. If x is a complex number, then the\n"
169  "result is an 'mpc'.");
170  
171  PyDoc_STRVAR(GMPy_doc_context_square,
172  "context.square(x) -> number\n\n"
173  "Return x * x. If x is an integer, then the result is an 'mpz'.\n"
174  "If x is a rational, then the result is an 'mpq'. If x is a float,\n"
175  "then the result is an 'mpfr'. If x is a complex number, then the\n"
176  "result is an 'mpc'.");
177  
178  static PyObject *
179  GMPy_Number_Square(PyObject *x, CTXT_Object *context)
180  {
181      if (MPZ_Check(x))
182          return _GMPy_MPZ_Square(x, context);
183  
184      if (MPQ_Check(x))
185          return _GMPy_MPQ_Square(x, context);
186  
187      if (MPFR_Check(x))
188          return _GMPy_MPFR_Square(x, context);
189  
190      if (MPC_Check(x))
191          return _GMPy_MPC_Square(x, context);
192  
193      if (IS_INTEGER(x))
194          return GMPy_Integer_Square(x, context);
195  
196      if (IS_RATIONAL(x))
197          return GMPy_Rational_Square(x, context);
198  
199      if (IS_REAL(x))
200          return GMPy_Real_Square(x, context);
201  
202      if (IS_COMPLEX(x))
203          return GMPy_Complex_Square(x, context);
204  
205      TYPE_ERROR("square() argument type not supported");
206      return NULL;
207  }
208  
209  static PyObject *
210  GMPy_Context_Square(PyObject *self, PyObject *other)
211  {
212      CTXT_Object *context = NULL;
213  
214      if (self && CTXT_Check(self)) {
215          context = (CTXT_Object*)self;
216      }
217      else {
218          CHECK_CONTEXT(context);
219      }
220  
221      return GMPy_Number_Square(other, context);
222  }
223