| 1 | | """ |
| 2 | | Field of real quad double numbers. These are deprecated. |
| 3 | | |
| 4 | | sage: RQDF(1) |
| 5 | | doctest:...: DeprecationWarning: RQDF is deprecated; use RealField(212) instead. |
| 6 | | 1.000000000000000000000000000000000000000000000000000000000000000 |
| 7 | | |
| 8 | | Quad double numbers allow us to represent real numbers with 212 bits |
| 9 | | (or 64 decimal digits) of accuracy. Computation of special functions |
| 10 | | is extremely fast in this field, and arithmetic is slightly faster |
| 11 | | than arithmetic in the MPFR real field. |
| 12 | | Bloh |
| 13 | | EXAMPLES: |
| 14 | | RQDF numbers can be mixed with RDF and MPFR reals, Integers, |
| 15 | | Rationals, etc.: |
| 16 | | sage: RQDF( 123.2) + RR (1.0) |
| 17 | | 124.200000000000 |
| 18 | | sage: RQDF( 12.2) + RDF (0.56) |
| 19 | | 12.76 |
| 20 | | sage: RQDF( 12.2) + (9) |
| 21 | | 21.19999999999999928945726423989981412887573242187500000000000000 |
| 22 | | sage: RQDF( 12.2) + (9/3) |
| 23 | | 15.19999999999999928945726423989981412887573242187500000000000000 |
| 24 | | |
| 25 | | Note that the result will always be coerced to the field |
| 26 | | with the lowest precision: |
| 27 | | sage: RR = RealField (300) |
| 28 | | sage: RQDF(123.2) * RR (.543) |
| 29 | | 66.89760000000000154329882207093760371208190917968750000000000000 |
| 30 | | |
| 31 | | Mixing of symbolic an quad double elements: |
| 32 | | sage: a = RQDF(2) / log(10); a |
| 33 | | 2.00000000000000000000000000000000000000000000000000000000000000/log(10) |
| 34 | | sage: parent(a) |
| 35 | | Symbolic Ring |
| 36 | | |
| 37 | | Note that the following numerical imprecision is caused by passing via Maxima: |
| 38 | | sage: RQDF(a) |
| 39 | | 0.86858896380650365530225783783321016458879401160733313222890756... |
| 40 | | """ |
| 41 | | |
| 42 | | |
| 43 | | #***************************************************************************** |
| 44 | | # |
| 45 | | # Sage: System for Algebra and Geometry Experimentation |
| 46 | | # |
| 47 | | # Copyright (C) 2007 didier deshommes <dfdeshom@gmail.com> |
| 48 | | # |
| 49 | | # Distributed under the terms of the GNU General Public License (GPL) |
| 50 | | # |
| 51 | | # This code is distributed in the hope that it will be useful, |
| 52 | | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 53 | | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 54 | | # General Public License for more details. |
| 55 | | # |
| 56 | | # The full text of the GPL is available at: |
| 57 | | # |
| 58 | | # http://www.gnu.org/licenses/ |
| 59 | | #***************************************************************************** |
| 60 | | |
| 61 | | include '../ext/cdefs.pxi' |
| 62 | | include '../ext/interrupt.pxi' |
| 63 | | |
| 64 | | |
| 65 | | from sage.libs.mpfr cimport * |
| 66 | | |
| 67 | | from sage.rings.integer cimport Integer |
| 68 | | from sage.rings.rational cimport Rational |
| 69 | | from sage.rings.real_mpfr cimport RealNumber, RealField |
| 70 | | from sage.rings.integer_ring import ZZ |
| 71 | | from sage.rings.rational_field import QQ |
| 72 | | |
| 73 | | from sage.structure.parent_base cimport ParentWithBase |
| 74 | | from sage.structure.coerce_maps import NamedConvertMap |
| 75 | | |
| 76 | | import operator |
| 77 | | |
| 78 | | cdef extern from "solaris_fix.h": pass |
| 79 | | |
| 80 | | from sage.misc.sage_eval import sage_eval |
| 81 | | |
| 82 | | # if we don't import anything, cython complains with |
| 83 | | # "undeclared name not builtin: sage" |
| 84 | | import sage.rings |
| 85 | | |
| 86 | | from sage.rings.real_double import RealDoubleElement |
| 87 | | |
| 88 | | _R = None |
| 89 | | cpdef RR(): |
| 90 | | global _R |
| 91 | | if _R is None: |
| 92 | | from real_mpfr import RealField |
| 93 | | _R = RealField(212) |
| 94 | | return _R |
| 95 | | |
| 96 | | cdef qd *qd_from_mpz(mpz_t z): |
| 97 | | cdef double d[4] |
| 98 | | cdef int i |
| 99 | | cdef mpz_t cur, res |
| 100 | | # The most significant double |
| 101 | | d[0] = mpz_get_d(z) |
| 102 | | if isinf(d[0]): |
| 103 | | d[0] = INFINITY |
| 104 | | return qd_from_double(d[0]) |
| 105 | | |
| 106 | | if not finite(d[0]): |
| 107 | | d[0] = NAN |
| 108 | | return qd_from_double(d[0]) |
| 109 | | mpz_init(cur) |
| 110 | | mpz_init(res) |
| 111 | | mpz_set_d(cur, d[0]) |
| 112 | | mpz_sub(res, z, cur) |
| 113 | | # now we repeatedly find the most significant part of the remainder |
| 114 | | for i from 1 <= i < 4: |
| 115 | | d[i] = mpz_get_d(res) |
| 116 | | mpz_set_d(cur, d[i]) |
| 117 | | mpz_sub(res, res, cur) |
| 118 | | mpz_clear(cur) |
| 119 | | mpz_clear(res) |
| 120 | | return qd_from_qd(d[0], d[1], d[2], d[3]) |
| 121 | | |
| 122 | | cdef qd *qd_from_mpfr(mpfr_t rr): |
| 123 | | cdef double d[4] |
| 124 | | cdef int i |
| 125 | | cdef mpfr_t cur, res |
| 126 | | cdef int isnan |
| 127 | | isnan = 0 |
| 128 | | # The most significant double |
| 129 | | # We use GMP_RNDN here, which guarantees an exact |
| 130 | | # conversion if prec(rr) <= 4*53+3=215. |
| 131 | | d[0] = mpfr_get_d(rr, GMP_RNDN) |
| 132 | | mpfr_init2(cur, 53) |
| 133 | | mpfr_init2(res, mpfr_get_prec(rr)) |
| 134 | | mpfr_set_d(cur, d[0], GMP_RNDN) |
| 135 | | mpfr_sub(res, rr, cur, GMP_RNDN) |
| 136 | | # now we repeatedly find the most significant part of the remainder |
| 137 | | for i from 1 <= i < 4: |
| 138 | | d[i] = mpfr_get_d(res, GMP_RNDN) |
| 139 | | mpfr_set_d(cur, d[i], GMP_RNDN) |
| 140 | | mpfr_sub(res, res, cur, GMP_RNDN) |
| 141 | | mpfr_clear(cur) |
| 142 | | mpfr_clear(res) |
| 143 | | # check if result is nan |
| 144 | | if 0 == d[0]: return qd_from_qd(0.0, 0.0, 0.0, 0.0) |
| 145 | | for i from 0 <= i < 3: |
| 146 | | if d[i] == d[i+1]: isnan += 1 |
| 147 | | |
| 148 | | if 3 == isnan: |
| 149 | | return qd_from_double(NAN) |
| 150 | | else: |
| 151 | | return qd_from_qd(d[0], d[1], d[2], d[3]) |
| 152 | | |
| 153 | | cdef class RealQuadDoubleField_class(Field): |
| 154 | | """ |
| 155 | | An approximation to a real number using quad double precision |
| 156 | | floating point numbers. Answers derived from calculations with |
| 157 | | such approximations may differ from what they would be if those |
| 158 | | calculations were performed with true real numbers. This is due |
| 159 | | to the rounding errors inherent to finite precision calculations. |
| 160 | | """ |
| 161 | | def __init__(self): |
| 162 | | self._populate_coercion_lists_(coerce_list=[RealField(213)], embedding=NamedConvertMap(self, RealField(212), '_mpfr_')) |
| 163 | | |
| 164 | | def __dealloc__(self): |
| 165 | | pass |
| 166 | | |
| 167 | | cpdef bint is_exact(self) except -2: |
| 168 | | return False |
| 169 | | |
| 170 | | cdef _an_element_c_impl(self): # override this in Cython |
| 171 | | return self(1.23) |
| 172 | | |
| 173 | | def _latex_(self): |
| 174 | | return "\\Bold{R}" |
| 175 | | |
| 176 | | def __repr__(self): |
| 177 | | """ |
| 178 | | Print out this real quad double field. |
| 179 | | |
| 180 | | EXAMPLES: |
| 181 | | sage: RQDF |
| 182 | | Real Quad Double Field |
| 183 | | |
| 184 | | """ |
| 185 | | return "Real Quad Double Field" |
| 186 | | |
| 187 | | def __cmp__(self, x): |
| 188 | | """ |
| 189 | | EXAMPLES: |
| 190 | | sage: RQDF == 1 |
| 191 | | False |
| 192 | | sage: RQDF == RealQuadDoubleField() |
| 193 | | True |
| 194 | | |
| 195 | | """ |
| 196 | | if PY_TYPE_CHECK(x, RealQuadDoubleField_class): |
| 197 | | return 0 |
| 198 | | return cmp(type(self), type(x)) |
| 199 | | |
| 200 | | def _element_constructor_(self, x): |
| 201 | | """ |
| 202 | | Create a real quad double using x. |
| 203 | | |
| 204 | | EXAMPLES: |
| 205 | | sage: RQDF (-1) |
| 206 | | -1.000000000000000000000000000000000000000000000000000000000000000 |
| 207 | | |
| 208 | | sage: RQDF (-1/3) |
| 209 | | -0.333333333333333333333333333333333333333333333333333333333333333 |
| 210 | | |
| 211 | | sage: RQDF('-0.33333333333333333333') |
| 212 | | -0.333333333333333333330000000000000000000000000000000000000000000 |
| 213 | | |
| 214 | | """ |
| 215 | | if PY_TYPE_CHECK(x, QuadDoubleElement): |
| 216 | | return x |
| 217 | | elif hasattr(x,'_real_rqdf_'): |
| 218 | | return x._real_rqdf_(self) |
| 219 | | return QuadDoubleElement(x) |
| 220 | | |
| 221 | | def _magma_init_(self, magma): |
| 222 | | r""" |
| 223 | | Return a string representation of self in the Magma language. |
| 224 | | |
| 225 | | EXAMPLES: |
| 226 | | sage: magma(RQDF) # optional |
| 227 | | Real field of precision 63 |
| 228 | | sage: floor(RR(log(2**212, 10))) |
| 229 | | 63 |
| 230 | | """ |
| 231 | | return "RealField(%s : Bits := true)" % self.prec() |
| 232 | | |
| 233 | | def prec(self): |
| 234 | | """ |
| 235 | | Return the precision of this real quad double field (to be more |
| 236 | | similar to RealField). Always returns 212. |
| 237 | | |
| 238 | | EXAMPLES: |
| 239 | | sage: RQDF.prec() |
| 240 | | 212 |
| 241 | | """ |
| 242 | | return 212 |
| 243 | | |
| 244 | | def gen(self, i=0): |
| 245 | | """ |
| 246 | | Return the generator of the field. |
| 247 | | |
| 248 | | EXAMPLES: |
| 249 | | sage: RQDF.gen() |
| 250 | | 1.000000000000000000000000000000000000000000000000000000000000000 |
| 251 | | |
| 252 | | """ |
| 253 | | if i == 0: |
| 254 | | return self(int(1)) |
| 255 | | else: |
| 256 | | raise IndexError |
| 257 | | |
| 258 | | def ngens(self): |
| 259 | | """ |
| 260 | | Return the number of generators of the field. |
| 261 | | |
| 262 | | EXAMPLES: |
| 263 | | sage: RQDF.ngens() |
| 264 | | 1 |
| 265 | | """ |
| 266 | | return 1 |
| 267 | | |
| 268 | | def gens(self): |
| 269 | | """ |
| 270 | | Returns a list of the generators of this field |
| 271 | | |
| 272 | | EXAMPLES: |
| 273 | | sage: RQDF.gens() |
| 274 | | [1.000000000000000000000000000000000000000000000000000000000000000] |
| 275 | | |
| 276 | | """ |
| 277 | | return [self.gen()] |
| 278 | | |
| 279 | | def construction(self): |
| 280 | | """ |
| 281 | | Returns the functorial construction of self, namely, completion of |
| 282 | | the rational numbers with respect to the prime at $\infinity$. |
| 283 | | |
| 284 | | Also preserves other information that makes this field unique |
| 285 | | (i.e. the Real Quad Double Field). |
| 286 | | |
| 287 | | EXAMPLES: |
| 288 | | sage: c, S = RQDF.construction(); S |
| 289 | | Rational Field |
| 290 | | sage: RQDF == c(S) |
| 291 | | True |
| 292 | | """ |
| 293 | | from sage.categories.pushout import CompletionFunctor |
| 294 | | return (CompletionFunctor(sage.rings.infinity.Infinity, |
| 295 | | 212, |
| 296 | | {'type': 'RQDF'}), |
| 297 | | sage.rings.rational_field.QQ) |
| 298 | | |
| 299 | | cpdef _coerce_map_from_(self, R): |
| 300 | | """ |
| 301 | | Canonical coercion of x to the real quad double field. |
| 302 | | |
| 303 | | The rings that canonically coerce to the real quad double field are: |
| 304 | | * the real quad double field itself |
| 305 | | * int, long, integer, and rational rings |
| 306 | | * the mpfr real field, if its precision is at least 212 bits |
| 307 | | * anything that canonically coerces to the mpfr real field. |
| 308 | | |
| 309 | | EXAMPLES: |
| 310 | | sage: RQDF._coerce_(1/2) |
| 311 | | 0.500000000000000000000000000000000000000000000000000000000000000 |
| 312 | | sage: RQDF._coerce_(26) |
| 313 | | 26.00000000000000000000000000000000000000000000000000000000000000 |
| 314 | | sage: RQDF._coerce_(26r) |
| 315 | | 26.00000000000000000000000000000000000000000000000000000000000000 |
| 316 | | |
| 317 | | sage: RR = RealField (300) |
| 318 | | sage: RQDF._coerce_(RR('0.245465643523545656345356677563')) |
| 319 | | 0.245465643523545656345356677563000000000000000000000000000000000 |
| 320 | | """ |
| 321 | | if R in (int, long, ZZ, QQ): |
| 322 | | return True |
| 323 | | |
| 324 | | if isinstance(R, RealField): |
| 325 | | return R.prec() > 212 |
| 326 | | |
| 327 | | def name(self): |
| 328 | | return "QuadDoubleField" |
| 329 | | |
| 330 | | def __hash__(self): |
| 331 | | return hash(self.name()) |
| 332 | | |
| 333 | | def pi(self): |
| 334 | | """ |
| 335 | | Returns pi |
| 336 | | |
| 337 | | EXAMPLES: |
| 338 | | sage: RQDF.pi() |
| 339 | | 3.141592653589793238462643383279502884197169399375105820974944592 |
| 340 | | sage: RQDF.pi().sqrt()/2 |
| 341 | | 0.886226925452758013649083741670572591398774728061193564106903895 |
| 342 | | |
| 343 | | """ |
| 344 | | cdef qd z |
| 345 | | return QuadDoubleElement((z._pi.x[0], z._pi.x[1], z._pi.x[2], z._pi.x[3])) |
| 346 | | |
| 347 | | def log2(self): |
| 348 | | """ |
| 349 | | Returns log(2) |
| 350 | | |
| 351 | | EXAMPLES: |
| 352 | | sage: RQDF.log2() |
| 353 | | 0.693147180559945309417232121458176568075500134360255254120680009 |
| 354 | | """ |
| 355 | | cdef qd z |
| 356 | | return QuadDoubleElement((z._log2.x[0], z._log2.x[1], z._log2.x[2], z._log2.x[3])) |
| 357 | | |
| 358 | | def e(self): |
| 359 | | """ |
| 360 | | Returns the natural log constant E |
| 361 | | |
| 362 | | EXAMPLES: |
| 363 | | sage: RQDF.e() |
| 364 | | 2.718281828459045235360287471352662497757247093699959574966967628 |
| 365 | | """ |
| 366 | | cdef qd z |
| 367 | | return QuadDoubleElement((z._e.x[0], z._e.x[1], z._e.x[2], z._e.x[3])) |
| 368 | | |
| 369 | | def NaN(self): |
| 370 | | """ |
| 371 | | Returns NaN |
| 372 | | |
| 373 | | EXAMPLES: |
| 374 | | sage: RQDF.NaN() |
| 375 | | 'NaN' |
| 376 | | """ |
| 377 | | return "NaN" |
| 378 | | |
| 379 | | def random_element(self,x=0,y=1): |
| 380 | | """ |
| 381 | | Generate a random quad double between x and y |
| 382 | | RQDF.random_element() -- random real number between 0 and 1 |
| 383 | | RQDF.random_element(n) -- return an real number between 0 and n-1, inclusive. |
| 384 | | RQDF.random_element(min, max) -- return a real number between min and max-1, inclusive. |
| 385 | | |
| 386 | | EXAMPLES: |
| 387 | | sage: RQDF.random_element(-10,10) |
| 388 | | 2.070062766573917070526967401926937175104037963758214054970605794 |
| 389 | | |
| 390 | | sage: RQDF.random_element(10) |
| 391 | | 1.876986321449735379165332456424771674656237391205272916375069342 |
| 392 | | |
| 393 | | sage: [RQDF.random_element(10) for _ in range(5)] |
| 394 | | [8.084281420673943787229609237458327203934426138730686265930328254, |
| 395 | | 8.806298363947585826181224013949012875074955779827726577990392512, |
| 396 | | 9.475217302151261462676501400096032242004946644547518035714857940, |
| 397 | | 2.629993393648438854368552598518628332583301315453134053887857396, |
| 398 | | 1.946435375426485270381085392826467583700841913266187372985425003] |
| 399 | | |
| 400 | | """ |
| 401 | | # Switch to generating random numbers through MPFR (to make |
| 402 | | # the numbers work with Sage's global random number seeds). |
| 403 | | # Unfortunately, this takes about 3 times as long |
| 404 | | # as the c_qd_rand() code that's commented out below, but |
| 405 | | # I think it's worth it. (15 microseconds vs. 5 microseconds, |
| 406 | | # on my laptop.) |
| 407 | | return RQDF(RR().random_element(y, x)) |
| 408 | | # cdef QuadDoubleElement res, upper, lower |
| 409 | | # res = QuadDoubleElement(0) |
| 410 | | # upper = self(x) |
| 411 | | # lower = self(y) |
| 412 | | # c_qd_rand(res.initptr.x) |
| 413 | | # return (upper-lower)*res + lower |
| 414 | | |
| 415 | | cdef class QuadDoubleElement(FieldElement): |
| 416 | | """ |
| 417 | | A floating point approximation to a real number using quad |
| 418 | | double precision. Answers derived from calculations with such |
| 419 | | approximations may differ from what they would be if those |
| 420 | | calculations were performed with true real numbers. This is due |
| 421 | | to the rounding errors inherent to finite precision calculations. |
| 422 | | """ |
| 423 | | cdef _new(self): |
| 424 | | cdef QuadDoubleElement q |
| 425 | | q = PY_NEW(QuadDoubleElement) |
| 426 | | q.initptr = new_qd_real() |
| 427 | | return q |
| 428 | | |
| 429 | | cdef _new_c(self, qd a): |
| 430 | | cdef QuadDoubleElement q |
| 431 | | q = PY_NEW(QuadDoubleElement) |
| 432 | | q.initptr = qd_from_qd(a.x[0],a.x[1],a.x[2],a.x[3]) |
| 433 | | return q |
| 434 | | |
| 435 | | def __dealloc__(self): |
| 436 | | cdef unsigned int cw |
| 437 | | fpu_fix_start(&cw) |
| 438 | | delete(self.initptr) |
| 439 | | fpu_fix_end(&cw) |
| 440 | | pass |
| 441 | | |
| 442 | | def __cinit__(self, x=None): |
| 443 | | # explicit cast required for C++ |
| 444 | | self._parent = <ParentWithBase> _RQDF |
| 445 | | from sage.misc.misc import deprecation |
| 446 | | deprecation('RQDF is deprecated; use RealField(212) instead.') |
| 447 | | |
| 448 | | def __init__(self, x): |
| 449 | | """ |
| 450 | | Create a quad double real number. A quad double real number is |
| 451 | | an unevaluated sum of 4 IEEE double numbers, capable of representing |
| 452 | | at least 212 bits of significand. The quad double number |
| 453 | | $(a_0,a_1,a_2,a_3)$ represents the exact sum $a=a_0+a_1+a_2+a_3$, |
| 454 | | where $a_0$ is the most significant component. |
| 455 | | |
| 456 | | EXAMPLES: |
| 457 | | sage: RQDF('1.1111111111100001111111011') |
| 458 | | 1.111111111110000111111101100000000000000000000000000000000000000 |
| 459 | | sage: RQDF(124/34) |
| 460 | | 3.647058823529411764705882352941176470588235294117647058823529412 |
| 461 | | sage: RQDF(12434) |
| 462 | | 12434.00000000000000000000000000000000000000000000000000000000000 |
| 463 | | sage: RQDF(2^60 + 9 ) |
| 464 | | 1.15292150460684698500000000000000000000000000000000000000000000e18 |
| 465 | | |
| 466 | | You can also create a quad double number from a 4-tuple: |
| 467 | | sage: w= (2432323.0r,2.323e-12r,4.3423e-34r,-2.323e-52r) |
| 468 | | sage: RQDF(w) |
| 469 | | 2432323.000000000002323000000000000098074113547887953405079397297 |
| 470 | | |
| 471 | | or from RDF and MPFR reals: |
| 472 | | sage: RQDF(RDF(3434.34342)) |
| 473 | | 3434.343420000000151048880070447921752929687500000000000000000000 |
| 474 | | sage: RQDF(RR(1091.34342)) |
| 475 | | 1091.343419999999923675204627215862274169921875000000000000000000 |
| 476 | | sage: RR = RealField (300) |
| 477 | | sage: RQDF(RR('1091.34342')) |
| 478 | | 1091.343420000000000000000000000000000000000000000000000000000000 |
| 479 | | """ |
| 480 | | self._set(x) |
| 481 | | |
| 482 | | cdef _set(self, x): |
| 483 | | cdef unsigned int cw |
| 484 | | fpu_fix_start(&cw) |
| 485 | | cdef qd *n,*d |
| 486 | | |
| 487 | | if PY_TYPE_CHECK(x, RealNumber): |
| 488 | | self.initptr = qd_from_mpfr((<RealNumber>x).value) |
| 489 | | |
| 490 | | elif PY_TYPE_CHECK(x, int): |
| 491 | | self.initptr = qd_from_int(x) |
| 492 | | |
| 493 | | elif PY_TYPE_CHECK(x, Integer): |
| 494 | | self.initptr = qd_from_mpz((<Integer>x).value) |
| 495 | | |
| 496 | | elif PY_TYPE_CHECK(x, Rational): |
| 497 | | n = qd_from_mpz(mpq_numref((<Rational>x).value)) |
| 498 | | d = qd_from_mpz(mpq_denref((<Rational>x).value)) |
| 499 | | self.initptr = new_qd_real() |
| 500 | | c_qd_div(n.x,d.x,self.initptr.x) |
| 501 | | |
| 502 | | elif PY_TYPE_CHECK(x, RealDoubleElement) or PY_TYPE_CHECK(x, float): |
| 503 | | self.initptr = qd_from_double(x) |
| 504 | | |
| 505 | | elif PY_TYPE_CHECK(x, QuadDoubleElement): |
| 506 | | n = (<QuadDoubleElement>x).initptr |
| 507 | | self.initptr = qd_from_qd(n.x[0],n.x[1],n.x[2],n.x[3]) |
| 508 | | |
| 509 | | elif PY_TYPE_CHECK(x, long) or PY_TYPE_CHECK(x, str): |
| 510 | | s = str(x) |
| 511 | | _sig_on |
| 512 | | self.initptr = qd_from_str(s) |
| 513 | | _sig_off |
| 514 | | |
| 515 | | elif PY_TYPE_CHECK(x, tuple): |
| 516 | | _sig_on |
| 517 | | self.initptr = qd_from_qd(float(x[0]),float(x[1]), |
| 518 | | float(x[2]),float(x[3])) |
| 519 | | _sig_off |
| 520 | | |
| 521 | | else: |
| 522 | | self._set(RR()(x)) |
| 523 | | |
| 524 | | fpu_fix_end(&cw) |
| 525 | | |
| 526 | | def get_doubles(self): |
| 527 | | """ |
| 528 | | Return the 4 doubles that constitute this quad double real number |
| 529 | | |
| 530 | | EXAMPLES: |
| 531 | | sage: w= RQDF('1.34435343435344446376457677898097745635222') |
| 532 | | sage: t=w.get_doubles () |
| 533 | | sage: RQDF (t) |
| 534 | | 1.344353434353444463764576778980977456352220000000000000000000000 |
| 535 | | sage: RQDF (t) == w |
| 536 | | True |
| 537 | | """ |
| 538 | | return (self.initptr.x[0], self.initptr.x[1], |
| 539 | | self.initptr.x[2], self.initptr.x[3]) |
| 540 | | |
| 541 | | def prec(self): |
| 542 | | """ |
| 543 | | Return the precision of this real quad double element. Always returns 212. |
| 544 | | |
| 545 | | EXAMPLES: |
| 546 | | sage: RQDF(0).prec() |
| 547 | | 212 |
| 548 | | """ |
| 549 | | return 212 |
| 550 | | |
| 551 | | def real(self): |
| 552 | | """ |
| 553 | | Returns itself |
| 554 | | |
| 555 | | EXAMPLES: |
| 556 | | sage: w=RQDF(2) ; w.real() |
| 557 | | 2.000000000000000000000000000000000000000000000000000000000000000 |
| 558 | | """ |
| 559 | | return self |
| 560 | | |
| 561 | | def imag(self): |
| 562 | | """ |
| 563 | | Returns the imaginary part of this number (ie 0). |
| 564 | | |
| 565 | | EXAMPLES: |
| 566 | | sage: w=RQDF(2) |
| 567 | | sage: w.imag() == 0 |
| 568 | | True |
| 569 | | """ |
| 570 | | return QuadDoubleElement(0) |
| 571 | | |
| 572 | | def __complex__(self): |
| 573 | | """ |
| 574 | | Returns self as a complex number |
| 575 | | EXAMPLES: |
| 576 | | sage: w=RQDF(2) |
| 577 | | sage: complex(w) |
| 578 | | (2+0j) |
| 579 | | |
| 580 | | """ |
| 581 | | return complex(float(self)) |
| 582 | | |
| 583 | | def __reduce__(self): |
| 584 | | """ |
| 585 | | EXAMPLES: |
| 586 | | sage: s = dumps(RQDF('7.123456789')) |
| 587 | | sage: loads(s) |
| 588 | | 7.123456789000000000000000000000000000000000000000000000000000000 |
| 589 | | """ |
| 590 | | doubles = self.get_doubles() |
| 591 | | return QuadDoubleElement,(doubles,) |
| 592 | | |
| 593 | | |
| 594 | | |
| 595 | | def __str__(self): |
| 596 | | return self.str() |
| 597 | | |
| 598 | | def __repr__(self): |
| 599 | | return self.str() |
| 600 | | |
| 601 | | def __str_no_scientific(self): |
| 602 | | """ |
| 603 | | Returns a string representation of this number |
| 604 | | """ |
| 605 | | cdef int MAX_DIGITS |
| 606 | | cdef char *s |
| 607 | | cdef int point_index |
| 608 | | result = '' |
| 609 | | MAX_DIGITS = 64 |
| 610 | | |
| 611 | | # A negative number |
| 612 | | if self.initptr.x[0] < 0.0: |
| 613 | | result += '-' |
| 614 | | |
| 615 | | s = <char*>PyMem_Malloc(MAX_DIGITS+1) |
| 616 | | s[MAX_DIGITS]=0 |
| 617 | | _sig_on |
| 618 | | self.initptr.to_digits(s,point_index,MAX_DIGITS) |
| 619 | | _sig_off |
| 620 | | |
| 621 | | t = str(s) |
| 622 | | PyMem_Free(s) |
| 623 | | |
| 624 | | # If this number is < 0 |
| 625 | | if point_index < 0: |
| 626 | | point_index = - point_index |
| 627 | | result += '0.' |
| 628 | | |
| 629 | | # The value of point_index gives how many |
| 630 | | # additional zeroes there might be after the dot |
| 631 | | for i in range(1,point_index): result += '0' |
| 632 | | result += t[:63] |
| 633 | | return result |
| 634 | | |
| 635 | | # we always want to print the number with exactly 63 digits after |
| 636 | | # the dot |
| 637 | | result += t[:point_index+1] + '.' + t[point_index+1:63+point_index+1] |
| 638 | | |
| 639 | | return result |
| 640 | | |
| 641 | | def __str_scientific(self,precision=63): |
| 642 | | """ |
| 643 | | Returns this number in scientific notation. |
| 644 | | """ |
| 645 | | cdef char *s |
| 646 | | s = <char*>PyMem_Malloc(precision+8) # See docs for write() |
| 647 | | _sig_on |
| 648 | | self.initptr.write(s,precision,0,0) |
| 649 | | _sig_off |
| 650 | | t = str(s) |
| 651 | | PyMem_Free(s) |
| 652 | | return t |
| 653 | | |
| 654 | | def str(self): |
| 655 | | """ |
| 656 | | Returns the string representation of self. |
| 657 | | |
| 658 | | If this number is less than $10^12$ and greater than $10^-12$, |
| 659 | | it is printed normally. |
| 660 | | |
| 661 | | Otherwise, it is printed in scientific notation |
| 662 | | |
| 663 | | EXAMPLES: |
| 664 | | sage: r= RQDF('222222222224.00000000001111111111') ; r |
| 665 | | 222222222224.0000000000111111111100000000000000000000000000000000 |
| 666 | | sage: r= RQDF('2222222222245.00000000001111111111') ; r |
| 667 | | 2.22222222224500000000001111111111000000000000000000000000000000e12 |
| 668 | | sage: r= RQDF('0.00000000001111111111') ; r |
| 669 | | 0.0000000000111111111100000000000000000000000000000000000000000000000000000 |
| 670 | | sage: r= RQDF('-0.00000000001111111111') ; r |
| 671 | | -0.0000000000111111111100000000000000000000000000000000000000000000000000000 |
| 672 | | sage: RQDF(-10)/RQDF(0) |
| 673 | | -inf |
| 674 | | sage: RQDF(10.1)/RQDF(0) |
| 675 | | inf |
| 676 | | sage: RQDF(0)/RQDF(0) |
| 677 | | NaN |
| 678 | | """ |
| 679 | | # 10**12 is used as the cutoff because that is how RDF handles |
| 680 | | # large numbers |
| 681 | | cdef double x = self.initptr.x[0] |
| 682 | | if self.is_infinity(): |
| 683 | | if x < 0: return "-inf" |
| 684 | | return "inf" |
| 685 | | if self.is_NaN(): return "NaN" |
| 686 | | cdef unsigned int cw |
| 687 | | fpu_fix_start(&cw) |
| 688 | | if 0.0 == x: |
| 689 | | result = self.__str_no_scientific() |
| 690 | | elif 1e-12 < x and x < 1e12: |
| 691 | | result = self.__str_no_scientific() |
| 692 | | elif -1e-12 > x and x > -1e12: |
| 693 | | result = self.__str_no_scientific() |
| 694 | | else: |
| 695 | | result = self.__str_scientific() |
| 696 | | fpu_fix_end(&cw) |
| 697 | | return result |
| 698 | | |
| 699 | | def parent(self): |
| 700 | | """ |
| 701 | | Returns the parent of this number |
| 702 | | |
| 703 | | EXAMPLES: |
| 704 | | sage: w=RQDF(-21.2) ; w.parent() |
| 705 | | Real Quad Double Field |
| 706 | | """ |
| 707 | | return self._parent |
| 708 | | |
| 709 | | def __copy__(self): |
| 710 | | """ |
| 711 | | Return copy of self, which since self is immutable, is just self. |
| 712 | | |
| 713 | | EXAMPLES: |
| 714 | | sage: w=RQDF('-21.2') ; copy(w) |
| 715 | | -21.20000000000000000000000000000000000000000000000000000000000000 |
| 716 | | """ |
| 717 | | return self |
| 718 | | |
| 719 | | def integer_part(self): |
| 720 | | """ |
| 721 | | If in decimal this number is written n.defg, returns n. |
| 722 | | |
| 723 | | EXAMPLES: |
| 724 | | sage: test = 253536646425647436353675786864535364746 |
| 725 | | sage: RQDF(test).integer_part() == test |
| 726 | | True |
| 727 | | |
| 728 | | """ |
| 729 | | if 0 == self: return Integer("0") |
| 730 | | cdef unsigned int cw |
| 731 | | fpu_fix_start(&cw) |
| 732 | | s = self.__str_no_scientific() |
| 733 | | num = s.split('.')[0] |
| 734 | | result = Integer(num) |
| 735 | | fpu_fix_end(&cw) |
| 736 | | return result |
| 737 | | |
| 738 | | ######################## |
| 739 | | # Basic Arithmetic |
| 740 | | ######################## |
| 741 | | def __invert__(self): |
| 742 | | """ |
| 743 | | Compute the multiplicative inverse of self. |
| 744 | | |
| 745 | | EXAMPLES: |
| 746 | | sage: w=RQDF(1/3) |
| 747 | | sage: 1/w |
| 748 | | 3.000000000000000000000000000000000000000000000000000000000000000 |
| 749 | | """ |
| 750 | | cdef QuadDoubleElement res |
| 751 | | cdef unsigned int cw |
| 752 | | fpu_fix_start(&cw) |
| 753 | | res = self._new() |
| 754 | | _sig_on |
| 755 | | c_qd_npwr(self.initptr.x,-1,res.initptr.x) |
| 756 | | fpu_fix_end(&cw) |
| 757 | | _sig_off |
| 758 | | return res |
| 759 | | |
| 760 | | cpdef ModuleElement _add_(self, ModuleElement right): |
| 761 | | """ |
| 762 | | Add two quad double numbers |
| 763 | | |
| 764 | | EXAMPLES: |
| 765 | | sage: RQDF(1/3) + RQDF(1) |
| 766 | | 1.333333333333333333333333333333333333333333333333333333333333333 |
| 767 | | """ |
| 768 | | cdef QuadDoubleElement res |
| 769 | | cdef unsigned int cw |
| 770 | | fpu_fix_start(&cw) |
| 771 | | res = self._new() |
| 772 | | c_qd_add(self.initptr.x,(<QuadDoubleElement>right).initptr.x,res.initptr.x) |
| 773 | | fpu_fix_end(&cw) |
| 774 | | return res |
| 775 | | |
| 776 | | cpdef ModuleElement _sub_(self, ModuleElement right): |
| 777 | | """ |
| 778 | | Subtract two quad double numbers |
| 779 | | |
| 780 | | EXAMPLES: |
| 781 | | sage: RQDF(1/3) - RQDF(1) |
| 782 | | -0.666666666666666666666666666666666666666666666666666666666666666 |
| 783 | | """ |
| 784 | | cdef QuadDoubleElement res |
| 785 | | cdef unsigned int cw |
| 786 | | fpu_fix_start(&cw) |
| 787 | | res = self._new() |
| 788 | | c_qd_sub(self.initptr.x,(<QuadDoubleElement>right).initptr.x,res.initptr.x) |
| 789 | | fpu_fix_end(&cw) |
| 790 | | return res |
| 791 | | |
| 792 | | cpdef RingElement _mul_(self, RingElement right): |
| 793 | | """ |
| 794 | | Multiply two quad double numbers |
| 795 | | |
| 796 | | EXAMPLES: |
| 797 | | sage: RQDF('1.3') * RQDF(10) |
| 798 | | 13.00000000000000000000000000000000000000000000000000000000000000 |
| 799 | | """ |
| 800 | | cdef QuadDoubleElement res |
| 801 | | cdef unsigned int cw |
| 802 | | fpu_fix_start(&cw) |
| 803 | | res = self._new() |
| 804 | | c_qd_mul(self.initptr.x,(<QuadDoubleElement>right).initptr.x,res.initptr.x) |
| 805 | | fpu_fix_end(&cw) |
| 806 | | return res |
| 807 | | |
| 808 | | cpdef RingElement _div_(self, RingElement right): |
| 809 | | """ |
| 810 | | Divide two quad double numbers |
| 811 | | |
| 812 | | EXAMPLES: |
| 813 | | sage: RQDF(1/3) / RQDF(100) |
| 814 | | 0.00333333333333333333333333333333333333333333333333333333333333333 |
| 815 | | """ |
| 816 | | cdef QuadDoubleElement res |
| 817 | | cdef unsigned int cw |
| 818 | | fpu_fix_start(&cw) |
| 819 | | res = self._new() |
| 820 | | c_qd_div(self.initptr.x,(<QuadDoubleElement>right).initptr.x,res.initptr.x) |
| 821 | | fpu_fix_end(&cw) |
| 822 | | return res |
| 823 | | |
| 824 | | cpdef ModuleElement _neg_(self): |
| 825 | | """ |
| 826 | | Negates a quad double number. |
| 827 | | |
| 828 | | EXAMPLES: |
| 829 | | sage: -RQDF('0.056') |
| 830 | | -0.0560000000000000000000000000000000000000000000000000000000000000 |
| 831 | | """ |
| 832 | | cdef QuadDoubleElement res |
| 833 | | cdef unsigned int cw |
| 834 | | fpu_fix_start(&cw) # This might not be needed here. |
| 835 | | res = self._new() |
| 836 | | c_qd_neg(self.initptr.x,res.initptr.x) |
| 837 | | fpu_fix_end(&cw) |
| 838 | | return res |
| 839 | | |
| 840 | | def __abs__(self): |
| 841 | | """ |
| 842 | | Returns the absolute value of a quad double number. |
| 843 | | |
| 844 | | EXAMPLES: |
| 845 | | sage: abs(RQDF('-0.45')) |
| 846 | | 0.450000000000000000000000000000000000000000000000000000000000000 |
| 847 | | """ |
| 848 | | cdef QuadDoubleElement res |
| 849 | | cdef unsigned int cw |
| 850 | | fpu_fix_start(&cw) |
| 851 | | res = self._new() |
| 852 | | c_qd_abs(self.initptr.x,res.initptr.x) |
| 853 | | fpu_fix_end(&cw) |
| 854 | | return res |
| 855 | | |
| 856 | | def __lshift__(self, n): |
| 857 | | """ |
| 858 | | LShifting a quad double is not supported |
| 859 | | """ |
| 860 | | raise TypeError, "unsupported operand type(s) for <<: '%s' and '%s'"%(type(self), type(n)) |
| 861 | | |
| 862 | | def __rshift__(self, n): |
| 863 | | """ |
| 864 | | RShifting a quad double is not supported |
| 865 | | """ |
| 866 | | raise TypeError, "unsupported operand type(s) for >>: '%s' and '%s'"%(type(self), type(n)) |
| 867 | | |
| 868 | | def multiplicative_order(self): |
| 869 | | """ |
| 870 | | Returns the multiplicative order of self |
| 871 | | |
| 872 | | EXAMPLES: |
| 873 | | sage: w=RQDF(-1) |
| 874 | | sage: w.multiplicative_order() |
| 875 | | -1 |
| 876 | | sage: w=RQDF(1) |
| 877 | | sage: w.multiplicative_order() |
| 878 | | 1 |
| 879 | | sage: w=RQDF(0) |
| 880 | | sage: w.multiplicative_order() |
| 881 | | +Infinity |
| 882 | | |
| 883 | | """ |
| 884 | | if self == 1: return 1 |
| 885 | | if self == -1: return -1 |
| 886 | | return sage.rings.infinity.infinity |
| 887 | | |
| 888 | | |
| 889 | | ################### |
| 890 | | # Rounding etc |
| 891 | | ################### |
| 892 | | |
| 893 | | def round(self): |
| 894 | | """ |
| 895 | | Given real number x, rounds up if fractional part is greater than .5, |
| 896 | | rounds down if fractional part is lesser than .5. |
| 897 | | EXAMPLES: |
| 898 | | sage: RQDF(0.49).round() |
| 899 | | 0.000000000000000000000000000000000000000000000000000000000000000 |
| 900 | | sage: RQDF(0.51).round() |
| 901 | | 1.000000000000000000000000000000000000000000000000000000000000000 |
| 902 | | """ |
| 903 | | cdef QuadDoubleElement res |
| 904 | | cdef unsigned int cw |
| 905 | | fpu_fix_start(&cw) |
| 906 | | res = self._new() |
| 907 | | if self.frac() < 0.5: |
| 908 | | _sig_on |
| 909 | | c_qd_floor(self.initptr.x,res.initptr.x) |
| 910 | | fpu_fix_end(&cw) |
| 911 | | _sig_off |
| 912 | | return res |
| 913 | | |
| 914 | | _sig_on |
| 915 | | c_qd_ceil(self.initptr.x,res.initptr.x) |
| 916 | | fpu_fix_end(&cw) |
| 917 | | _sig_off |
| 918 | | return res |
| 919 | | |
| 920 | | |
| 921 | | def floor(self): |
| 922 | | """ |
| 923 | | Returns the floor of this number |
| 924 | | |
| 925 | | EXAMPLES: |
| 926 | | sage: RQDF(2.99).floor() |
| 927 | | 2 |
| 928 | | sage: RQDF(2.00).floor() |
| 929 | | 2 |
| 930 | | sage: RQDF(-5/2).floor() |
| 931 | | -3 |
| 932 | | """ |
| 933 | | cdef QuadDoubleElement res |
| 934 | | cdef unsigned int cw |
| 935 | | fpu_fix_start(&cw) |
| 936 | | res = self._new() |
| 937 | | c_qd_floor(self.initptr.x,res.initptr.x) |
| 938 | | fpu_fix_end(&cw) |
| 939 | | return res.integer_part() |
| 940 | | |
| 941 | | def ceil(self): |
| 942 | | """ |
| 943 | | Returns the ceiling of this number, as an integer. |
| 944 | | |
| 945 | | EXAMPLES: |
| 946 | | sage: RQDF(2.99).ceil() |
| 947 | | 3 |
| 948 | | sage: RQDF(2.00).ceil() |
| 949 | | 2 |
| 950 | | sage: RQDF(-5/2).ceil() |
| 951 | | -2 |
| 952 | | sage: type(RQDF(-5/2).ceil()) |
| 953 | | <type 'sage.rings.integer.Integer'> |
| 954 | | """ |
| 955 | | cdef QuadDoubleElement res |
| 956 | | cdef unsigned int cw |
| 957 | | fpu_fix_start(&cw) |
| 958 | | res = self._new() |
| 959 | | c_qd_ceil(self.initptr.x,res.initptr.x) |
| 960 | | fpu_fix_end(&cw) |
| 961 | | return res.integer_part() |
| 962 | | |
| 963 | | def ceiling(self): |
| 964 | | """ |
| 965 | | EXAMPLES: |
| 966 | | sage: RQDF('2.000000000001').ceiling() |
| 967 | | 3 |
| 968 | | """ |
| 969 | | return self.ceil() |
| 970 | | |
| 971 | | def trunc(self): |
| 972 | | """ |
| 973 | | Truncates this number (returns integer part). |
| 974 | | |
| 975 | | EXAMPLES: |
| 976 | | sage: RQDF(2.99).trunc() |
| 977 | | 2.000000000000000000000000000000000000000000000000000000000000000 |
| 978 | | sage: RQDF(-2.00).trunc() |
| 979 | | -2.000000000000000000000000000000000000000000000000000000000000000 |
| 980 | | sage: RQDF(0.00).trunc() |
| 981 | | 0.000000000000000000000000000000000000000000000000000000000000000 |
| 982 | | """ |
| 983 | | return QuadDoubleElement(self.floor()) |
| 984 | | |
| 985 | | |
| 986 | | def frac(self): |
| 987 | | """ |
| 988 | | frac returns a real number > -1 and < 1. that satisfies the |
| 989 | | relation: |
| 990 | | x = x.trunc() + x.frac() |
| 991 | | |
| 992 | | EXAMPLES: |
| 993 | | sage: RQDF('2.99').frac() |
| 994 | | 0.990000000000000000000000000000000000000000000000000000000000000 |
| 995 | | sage: RQDF(2.50).frac() |
| 996 | | 0.500000000000000000000000000000000000000000000000000000000000000 |
| 997 | | sage: RQDF('-2.79').frac() |
| 998 | | -0.790000000000000000000000000000000000000000000000000000000000000 |
| 999 | | """ |
| 1000 | | return self - self.integer_part() |
| 1001 | | |
| 1002 | | |
| 1003 | | ########################################### |
| 1004 | | # Conversions |
| 1005 | | ########################################### |
| 1006 | | |
| 1007 | | def __float__(self): |
| 1008 | | """ |
| 1009 | | Returns the floating-point value of this number |
| 1010 | | |
| 1011 | | EXAMPLES: |
| 1012 | | sage: w = RQDF('-23.79'); w |
| 1013 | | -23.79000000000000000000000000000000000000000000000000000000000000 |
| 1014 | | sage: float(w) |
| 1015 | | -23.789999999999999 |
| 1016 | | """ |
| 1017 | | cdef double d |
| 1018 | | cdef unsigned int cw |
| 1019 | | fpu_fix_start(&cw) |
| 1020 | | d = qd_to_double(qd_deref(self.initptr)) |
| 1021 | | fpu_fix_end(&cw) |
| 1022 | | return d |
| 1023 | | |
| 1024 | | def _rpy_(self): |
| 1025 | | """ |
| 1026 | | Returns self.__float__() for rpy to convert into the |
| 1027 | | appropriate R object. |
| 1028 | | |
| 1029 | | EXAMPLES: |
| 1030 | | sage: n = RQDF(2.0) |
| 1031 | | sage: n._rpy_() |
| 1032 | | 2.0 |
| 1033 | | sage: type(n._rpy_()) |
| 1034 | | <type 'float'> |
| 1035 | | """ |
| 1036 | | return self.__float__() |
| 1037 | | |
| 1038 | | def __int__(self): |
| 1039 | | """ |
| 1040 | | Returns integer truncation of this real number. |
| 1041 | | |
| 1042 | | EXAMPLES: |
| 1043 | | sage: w = RQDF('-23.79'); w |
| 1044 | | -23.79000000000000000000000000000000000000000000000000000000000000 |
| 1045 | | sage: int(w) |
| 1046 | | -23 |
| 1047 | | """ |
| 1048 | | cdef int i |
| 1049 | | cdef unsigned int cw |
| 1050 | | fpu_fix_start(&cw) |
| 1051 | | i = qd_to_int(qd_deref(self.initptr)) |
| 1052 | | fpu_fix_end(&cw) |
| 1053 | | return i |
| 1054 | | |
| 1055 | | def __long__(self): |
| 1056 | | """ |
| 1057 | | Returns long integer truncation of this real number. |
| 1058 | | |
| 1059 | | EXAMPLES: |
| 1060 | | sage: w = RQDF.pi(); w |
| 1061 | | 3.141592653589793238462643383279502884197169399375105820974944592 |
| 1062 | | sage: long(w) |
| 1063 | | 3L |
| 1064 | | """ |
| 1065 | | return long(self.__int__()) |
| 1066 | | |
| 1067 | | |
| 1068 | | def _real_double_(self, R): |
| 1069 | | """ |
| 1070 | | EXAMPLES: |
| 1071 | | sage: w = RQDF.e(); w |
| 1072 | | 2.718281828459045235360287471352662497757247093699959574966967628 |
| 1073 | | sage: RDF(w) |
| 1074 | | 2.71828182846 |
| 1075 | | sage: w._real_double_(RDF) |
| 1076 | | 2.71828182846 |
| 1077 | | """ |
| 1078 | | return R(float(self)) |
| 1079 | | |
| 1080 | | def _mpfr_(self, RealField R): |
| 1081 | | """ |
| 1082 | | TESTS: |
| 1083 | | sage: w = RQDF('2.345001').sqrt(); w |
| 1084 | | 1.531339609622894852128128425884749978483262262653204338472911277 |
| 1085 | | sage: RealField(212)(w) |
| 1086 | | 1.53133960962289485212812842588474997848326226265320433847291128 |
| 1087 | | |
| 1088 | | sage: RR(RQDF('324324.0098736633445565765349760000276353865')) |
| 1089 | | 324324.009873663 |
| 1090 | | sage: R200 = RealField (200) |
| 1091 | | sage: R200(RQDF('324324.0098736633445565765349760000276353865')) |
| 1092 | | 324324.00987366334455657653497600002763538650000000000000000 |
| 1093 | | |
| 1094 | | sage: w = RQDF('2.345001').sqrt(); w |
| 1095 | | 1.531339609622894852128128425884749978483262262653204338472911277 |
| 1096 | | sage: RealField(212)(w) |
| 1097 | | 1.53133960962289485212812842588474997848326226265320433847291128 |
| 1098 | | sage: RealField(250)(w) |
| 1099 | | 1.5313396096228948521281284258847499784832622626532043384729112767048720070 |
| 1100 | | """ |
| 1101 | | cdef int i |
| 1102 | | cdef mpfr_t curr |
| 1103 | | cdef mpfr_rnd_t rnd = (<RealField>R).rnd |
| 1104 | | cdef RealNumber rr = R() |
| 1105 | | mpfr_set_d(rr.value, self.initptr.x[0], rnd) |
| 1106 | | mpfr_init2(curr, 53) |
| 1107 | | for i from 1 <= i < 4: |
| 1108 | | mpfr_set_d(curr, self.initptr.x[i], rnd) |
| 1109 | | mpfr_add(rr.value, rr.value, curr, rnd) |
| 1110 | | mpfr_clear(curr) |
| 1111 | | return rr |
| 1112 | | |
| 1113 | | def _complex_double_(self, C): |
| 1114 | | """ |
| 1115 | | EXAMPLES: |
| 1116 | | sage: RQDF(-1)._complex_double_(CDF) |
| 1117 | | -1.0 |
| 1118 | | sage: CDF(RQDF(-1)) |
| 1119 | | -1.0 |
| 1120 | | """ |
| 1121 | | return C(float(self)) |
| 1122 | | |
| 1123 | | def _complex_mpfr_field_(self, K): |
| 1124 | | """ |
| 1125 | | EXAMPLES: |
| 1126 | | sage: w = RQDF('2.345001').sqrt(); w |
| 1127 | | 1.531339609622894852128128425884749978483262262653204338472911277 |
| 1128 | | sage: w._complex_mpfr_field_(ComplexField(212)) |
| 1129 | | 1.53133960962289485212812842588474997848326226265320433847291128 |
| 1130 | | sage: ComplexField(212)(w) |
| 1131 | | 1.53133960962289485212812842588474997848326226265320433847291128 |
| 1132 | | """ |
| 1133 | | return K(repr(self)) |
| 1134 | | |
| 1135 | | def _pari_(self): |
| 1136 | | """ |
| 1137 | | Return the PARI real number corresponding to self. |
| 1138 | | |
| 1139 | | EXAMPLES: |
| 1140 | | sage: w = RQDF('2').sqrt(); w |
| 1141 | | 1.414213562373095048801688724209698078569671875376948073176679738 |
| 1142 | | sage: x = w._pari_() |
| 1143 | | |
| 1144 | | Note that x appears to have lower precision: |
| 1145 | | sage: x |
| 1146 | | 1.41421356237310 |
| 1147 | | |
| 1148 | | In fact it doesn't. |
| 1149 | | sage: pari.set_real_precision(64) |
| 1150 | | 15 |
| 1151 | | sage: x |
| 1152 | | 1.414213562373095048801688724209698078569671875376948073176679738 |
| 1153 | | |
| 1154 | | Set the precision in PARI back. |
| 1155 | | sage: pari.set_real_precision(15) |
| 1156 | | 64 |
| 1157 | | """ |
| 1158 | | return sage.libs.pari.all.pari.new_with_bits_prec(repr(self), 212) |
| 1159 | | |
| 1160 | | |
| 1161 | | ########################################### |
| 1162 | | # Comparisons: ==, !=, <, <=, >, >= |
| 1163 | | ########################################### |
| 1164 | | |
| 1165 | | def is_NaN(self): |
| 1166 | | """ |
| 1167 | | Returns True if self is NaN |
| 1168 | | |
| 1169 | | EXAMPLES: |
| 1170 | | sage: w=RQDF(9) |
| 1171 | | sage: w.is_NaN() |
| 1172 | | False |
| 1173 | | |
| 1174 | | sage: w=RQDF(-10)/RQDF(0) |
| 1175 | | sage: (0*w).is_NaN() |
| 1176 | | True |
| 1177 | | sage: (RQDF(0)/0).is_NaN() |
| 1178 | | True |
| 1179 | | sage: w=RQDF(-10)/RQDF(0) |
| 1180 | | sage: (w/w).is_NaN() |
| 1181 | | True |
| 1182 | | sage: (w-w).is_NaN() |
| 1183 | | True |
| 1184 | | """ |
| 1185 | | return qd_is_nan(qd_deref(self.initptr)) |
| 1186 | | |
| 1187 | | def is_infinity(self): |
| 1188 | | """ |
| 1189 | | Returns True if self is infinifty |
| 1190 | | |
| 1191 | | EXAMPLES: |
| 1192 | | sage: w=RQDF(32)/RQDF(0) ; w.is_infinity() |
| 1193 | | True |
| 1194 | | sage: w=RQDF(-10)/RQDF(0) ; w.is_infinity() |
| 1195 | | True |
| 1196 | | sage: w=RQDF(1<<2900000) |
| 1197 | | sage: w.is_infinity () |
| 1198 | | True |
| 1199 | | """ |
| 1200 | | return qd_is_inf(qd_deref(self.initptr)) |
| 1201 | | |
| 1202 | | def is_positive_infinity(self): |
| 1203 | | """ |
| 1204 | | Returns True if this number is positive infinity |
| 1205 | | |
| 1206 | | EXAMPLES: |
| 1207 | | sage: r=RQDF(13)/RQDF(0) |
| 1208 | | sage: r.is_positive_infinity () |
| 1209 | | True |
| 1210 | | """ |
| 1211 | | cdef double x = self.initptr.x[0] |
| 1212 | | if self.is_infinity() and x > 0 : |
| 1213 | | return True |
| 1214 | | return False |
| 1215 | | |
| 1216 | | def is_negative_infinity(self): |
| 1217 | | """ |
| 1218 | | Returns True if this number is negative infinity |
| 1219 | | |
| 1220 | | EXAMPLES: |
| 1221 | | sage: r=RQDF(-13)/RQDF(0) |
| 1222 | | sage: r.is_negative_infinity () |
| 1223 | | True |
| 1224 | | sage: r=RQDF(0) |
| 1225 | | sage: r.is_negative_infinity () |
| 1226 | | False |
| 1227 | | """ |
| 1228 | | cdef double x = self.initptr.x[0] |
| 1229 | | if self.is_infinity() and x < 0 : |
| 1230 | | return True |
| 1231 | | return False |
| 1232 | | |
| 1233 | | def __richcmp__(left, right, int op): |
| 1234 | | return (<Element>left)._richcmp(right, op) |
| 1235 | | |
| 1236 | | cdef int _cmp_c_impl(left, Element right) except -2: |
| 1237 | | """ |
| 1238 | | Compares 2 quad double numbers |
| 1239 | | |
| 1240 | | Returns True if self is NaN |
| 1241 | | EXAMPLES: |
| 1242 | | sage: RQDF('3233') > RQDF('323') |
| 1243 | | True |
| 1244 | | sage: RQDF('-3233') > RQDF('323') |
| 1245 | | False |
| 1246 | | sage: RQDF('-3233') == RQDF('-3233') |
| 1247 | | True |
| 1248 | | """ |
| 1249 | | cdef int i |
| 1250 | | c_qd_comp(left.initptr.x,(<QuadDoubleElement>right).initptr.x,&i) |
| 1251 | | return i |
| 1252 | | |
| 1253 | | ############################ |
| 1254 | | # Special Functions |
| 1255 | | ############################ |
| 1256 | | |
| 1257 | | def sqrt(self, extend=True, all=False): |
| 1258 | | """ |
| 1259 | | The square root function. |
| 1260 | | |
| 1261 | | INPUT: |
| 1262 | | extend -- bool (default: True); if True, return |
| 1263 | | a square root in a complex field if necessary |
| 1264 | | if self is negative; otherwise raise a ValueError |
| 1265 | | all -- bool (default: False); if True, return a list |
| 1266 | | of all square roots. |
| 1267 | | |
| 1268 | | EXAMPLES: |
| 1269 | | sage: RQDF('-3233').sqrt() |
| 1270 | | 56.8594759033179974315326998383777083570361710615905085284278958*I |
| 1271 | | sage: RQDF('-4').sqrt() |
| 1272 | | 2.00000000000000000000000000000000000000000000000000000000000000*I |
| 1273 | | sage: RQDF('4.1234').sqrt() |
| 1274 | | 2.030615670184784130018521630263322574805816770689719741871597292 |
| 1275 | | sage: w = RQDF(2).sqrt(); w |
| 1276 | | 1.414213562373095048801688724209698078569671875376948073176679738 |
| 1277 | | sage: RealField(212)(2).sqrt() |
| 1278 | | 1.41421356237309504880168872420969807856967187537694807317667974 |
| 1279 | | sage: w = RQDF(-2).sqrt(); w |
| 1280 | | 1.41421356237309504880168872420969807856967187537694807317667974*I |
| 1281 | | sage: w = RQDF('2.345001').sqrt(); w |
| 1282 | | 1.531339609622894852128128425884749978483262262653204338472911277 |
| 1283 | | sage: w = RQDF(2).sqrt(all=True); w |
| 1284 | | [1.414213562373095048801688724209698078569671875376948073176679738, |
| 1285 | | -1.414213562373095048801688724209698078569671875376948073176679738] |
| 1286 | | |
| 1287 | | sage: RQDF(-2).sqrt(extend=False) |
| 1288 | | Traceback (most recent call last): |
| 1289 | | ... |
| 1290 | | ValueError: negative number -2.000000000000000000000000000000000000000000000000000000000000000 does not have a square root in the real quad double field |
| 1291 | | """ |
| 1292 | | if self.initptr.x[0] ==0: |
| 1293 | | if all: |
| 1294 | | return [self] |
| 1295 | | else: |
| 1296 | | return self |
| 1297 | | elif self.initptr.x[0] > 0: |
| 1298 | | z = self._square_root() |
| 1299 | | if all: |
| 1300 | | return [z, -z] |
| 1301 | | return z |
| 1302 | | |
| 1303 | | |
| 1304 | | if not extend: |
| 1305 | | raise ValueError, "negative number %s does not have a square root in the real quad double field"%self |
| 1306 | | |
| 1307 | | from sage.rings.complex_field import ComplexField |
| 1308 | | return ComplexField(212)(self).sqrt(all=all) |
| 1309 | | |
| 1310 | | |
| 1311 | | def _square_root(self): |
| 1312 | | """ |
| 1313 | | Return a square root of self. A real number will always be |
| 1314 | | returned (though it will be NaN if self is negative). |
| 1315 | | |
| 1316 | | Use self.sqrt() to get a complex number if self is negative. |
| 1317 | | |
| 1318 | | EXAMPLES: |
| 1319 | | sage: RQDF('4')._square_root() |
| 1320 | | 2.000000000000000000000000000000000000000000000000000000000000000 |
| 1321 | | sage: RQDF('-4')._square_root() |
| 1322 | | NaN |
| 1323 | | """ |
| 1324 | | cdef QuadDoubleElement res |
| 1325 | | cdef unsigned int cw |
| 1326 | | fpu_fix_start(&cw) |
| 1327 | | res = self._new() |
| 1328 | | if self.initptr.x[0] > 0: |
| 1329 | | c_qd_sqrt(self.initptr.x, res.initptr.x) |
| 1330 | | fpu_fix_end(&cw) |
| 1331 | | return res |
| 1332 | | else: |
| 1333 | | res = self._new_c(self.initptr._nan) |
| 1334 | | fpu_fix_end(&cw) |
| 1335 | | return res |
| 1336 | | |
| 1337 | | def cube_root(self): |
| 1338 | | """ |
| 1339 | | Return the cubic root (defined over the real numbers) of self. |
| 1340 | | |
| 1341 | | EXAMPLES: |
| 1342 | | sage: r = RQDF(125.0); r.cube_root() |
| 1343 | | 5.000000000000000000000000000000000000000000000000000000000000000 |
| 1344 | | sage: RQDF('-8').cube_root() |
| 1345 | | -2.000000000000000000000000000000000000000000000000000000000000000 |
| 1346 | | """ |
| 1347 | | return self.nth_root(3) |
| 1348 | | |
| 1349 | | |
| 1350 | | def nth_root(self, int n): |
| 1351 | | """ |
| 1352 | | Returns the $n^{th}$ root of self. |
| 1353 | | Returns NaN if self is negative and $n$ is even. |
| 1354 | | |
| 1355 | | EXAMPLES: |
| 1356 | | sage: r = RQDF(125.0); r.nth_root(3) |
| 1357 | | 5.000000000000000000000000000000000000000000000000000000000000000 |
| 1358 | | sage: r.nth_root(5) |
| 1359 | | 2.626527804403767236455131266496479582115662802810898530034436330 |
| 1360 | | sage: RQDF('-4987').nth_root(2) |
| 1361 | | NaN |
| 1362 | | """ |
| 1363 | | |
| 1364 | | cdef QuadDoubleElement res |
| 1365 | | cdef double neg[4] |
| 1366 | | cdef unsigned int cw |
| 1367 | | fpu_fix_start(&cw) |
| 1368 | | res = self._new() |
| 1369 | | _sig_on |
| 1370 | | if self.initptr.is_negative() and n % 2 == 1: |
| 1371 | | c_qd_neg(self.initptr.x, neg) |
| 1372 | | c_qd_nroot(neg, n, res.initptr.x) |
| 1373 | | c_qd_neg(res.initptr.x, res.initptr.x) |
| 1374 | | else: |
| 1375 | | c_qd_nroot(self.initptr.x, n, res.initptr.x) |
| 1376 | | fpu_fix_end(&cw) |
| 1377 | | _sig_off |
| 1378 | | return res |
| 1379 | | |
| 1380 | | def __pow(self, n, modulus): |
| 1381 | | cdef QuadDoubleElement res, n2 |
| 1382 | | cdef unsigned int cw |
| 1383 | | fpu_fix_start(&cw) |
| 1384 | | res = self._new() |
| 1385 | | _sig_on |
| 1386 | | c_qd_npwr(self.initptr.x, n, res.initptr.x) |
| 1387 | | fpu_fix_end(&cw) |
| 1388 | | _sig_off |
| 1389 | | return res |
| 1390 | | |
| 1391 | | def __pow__(self,n,d): |
| 1392 | | """ |
| 1393 | | Compute self raised to the power of exponent. |
| 1394 | | |
| 1395 | | EXAMPLES: |
| 1396 | | sage: a = RQDF('1.23456') |
| 1397 | | sage: a^20 |
| 1398 | | 67.64629770385396909318545781437142167431212492061816351749107831 |
| 1399 | | sage: RQDF (2)^3.2 |
| 1400 | | 9.18958683997628 |
| 1401 | | """ |
| 1402 | | if not isinstance(n,(Integer, int)): |
| 1403 | | res = n * self.log() |
| 1404 | | res = res.exp() |
| 1405 | | else: |
| 1406 | | res = self.__pow(n,d) |
| 1407 | | return res |
| 1408 | | |
| 1409 | | def log(self): |
| 1410 | | """ |
| 1411 | | Returns the log of this number. |
| 1412 | | |
| 1413 | | Returns NaN is self is negative,a nd minus infinity if self is 0. |
| 1414 | | |
| 1415 | | EXAMPLES: |
| 1416 | | sage: RQDF(2).log() |
| 1417 | | 0.693147180559945309417232121458176568075500134360255254120680009 |
| 1418 | | sage: RQDF(0).log() |
| 1419 | | -inf |
| 1420 | | sage: RQDF(-1).log() |
| 1421 | | NaN |
| 1422 | | """ |
| 1423 | | cdef QuadDoubleElement res |
| 1424 | | cdef unsigned int cw |
| 1425 | | fpu_fix_start(&cw) |
| 1426 | | if self.initptr.x[0] < 0.0: |
| 1427 | | res = self._new_c(self.initptr._nan) |
| 1428 | | elif self.initptr.x[0] == 0.0: |
| 1429 | | res = self._new() |
| 1430 | | res.initptr = qd_from_double(-INFINITY) |
| 1431 | | else: |
| 1432 | | res = self._new() |
| 1433 | | _sig_on |
| 1434 | | c_qd_log(self.initptr.x,res.initptr.x) |
| 1435 | | _sig_off |
| 1436 | | fpu_fix_end(&cw) |
| 1437 | | |
| 1438 | | return res |
| 1439 | | |
| 1440 | | def log10(self): |
| 1441 | | """ |
| 1442 | | Returns log to the base 10 of self |
| 1443 | | |
| 1444 | | Returns NaN is self is negative,a nd minus infinity if self is 0. |
| 1445 | | |
| 1446 | | EXAMPLES: |
| 1447 | | sage: r = RQDF(16); r.log10() |
| 1448 | | 1.204119982655924780854955578897972107072759525848434165241709845 |
| 1449 | | sage: r.log() / RQDF(log(10)) |
| 1450 | | 1.204119982655924780854955578897972107072759525848434165241709844 |
| 1451 | | sage: r = RQDF('-16.0'); r.log10() |
| 1452 | | NaN |
| 1453 | | |
| 1454 | | """ |
| 1455 | | cdef QuadDoubleElement res |
| 1456 | | cdef unsigned int cw |
| 1457 | | fpu_fix_start(&cw) |
| 1458 | | if self.initptr.x[0] < 0.0: |
| 1459 | | res = self._new_c(self.initptr._nan) |
| 1460 | | elif self.initptr.x[0] == 0.0: |
| 1461 | | res = self._new() |
| 1462 | | res.initptr = qd_from_double(-INFINITY) |
| 1463 | | else: |
| 1464 | | res = self._new() |
| 1465 | | _sig_on |
| 1466 | | c_qd_log10(self.initptr.x,res.initptr.x) |
| 1467 | | _sig_off |
| 1468 | | fpu_fix_end(&cw) |
| 1469 | | |
| 1470 | | return res |
| 1471 | | |
| 1472 | | def exp(self): |
| 1473 | | r""" |
| 1474 | | Returns $e^\code{self}$ |
| 1475 | | |
| 1476 | | EXAMPLES: |
| 1477 | | sage: r = RQDF(0.0) ; r.exp() |
| 1478 | | 1.000000000000000000000000000000000000000000000000000000000000000 |
| 1479 | | sage: RQDF('-32.3').exp() |
| 1480 | | 9.38184458849865778521574138078207776624385053667970865778536257e-15 |
| 1481 | | sage: r = RQDF('16.0'); |
| 1482 | | sage: r.log().exp() == r |
| 1483 | | True |
| 1484 | | """ |
| 1485 | | cdef QuadDoubleElement res |
| 1486 | | cdef unsigned int cw |
| 1487 | | fpu_fix_start(&cw) |
| 1488 | | res = self._new() |
| 1489 | | _sig_on |
| 1490 | | c_qd_exp(self.initptr.x,res.initptr.x) |
| 1491 | | _sig_off |
| 1492 | | fpu_fix_end(&cw) |
| 1493 | | return res |
| 1494 | | |
| 1495 | | def cos(self): |
| 1496 | | """ |
| 1497 | | Returns the cosine of this number |
| 1498 | | |
| 1499 | | EXAMPLES: |
| 1500 | | sage: t=RQDF(pi/2) |
| 1501 | | sage: t.cos() |
| 1502 | | -2.84867032372793962424197268086858714626628975008598348988393400e-65 |
| 1503 | | sage: t.cos()^2 + t.sin()^2 |
| 1504 | | 1.000000000000000000000000000000000000000000000000000000000000000 |
| 1505 | | """ |
| 1506 | | cdef QuadDoubleElement res |
| 1507 | | cdef unsigned int cw |
| 1508 | | fpu_fix_start(&cw) |
| 1509 | | res = self._new() |
| 1510 | | _sig_on |
| 1511 | | c_qd_cos(self.initptr.x,res.initptr.x) |
| 1512 | | fpu_fix_end(&cw) |
| 1513 | | _sig_off |
| 1514 | | return res |
| 1515 | | |
| 1516 | | def sin(self): |
| 1517 | | """ |
| 1518 | | Returns the sine of this number |
| 1519 | | |
| 1520 | | EXAMPLES: |
| 1521 | | sage: RQDF(pi).sin() |
| 1522 | | -5.69734064745587924848394536173717429253257950017196697976786799e-65 |
| 1523 | | """ |
| 1524 | | cdef QuadDoubleElement res |
| 1525 | | cdef unsigned int cw |
| 1526 | | fpu_fix_start(&cw) |
| 1527 | | res = self._new() |
| 1528 | | _sig_on |
| 1529 | | c_qd_sin(self.initptr.x,res.initptr.x) |
| 1530 | | fpu_fix_end(&cw) |
| 1531 | | _sig_off |
| 1532 | | return res |
| 1533 | | |
| 1534 | | def tan(self): |
| 1535 | | """ |
| 1536 | | Returns the tangent of this number |
| 1537 | | |
| 1538 | | EXAMPLES: |
| 1539 | | sage: q = RQDF(pi/3) |
| 1540 | | sage: q.tan() |
| 1541 | | 1.732050807568877293527446341505872366942805253810380628055806980 |
| 1542 | | sage: q = RQDF(pi/6) |
| 1543 | | sage: q.tan() |
| 1544 | | 0.577350269189625764509148780501957455647601751270126876018602326 |
| 1545 | | """ |
| 1546 | | cdef QuadDoubleElement res |
| 1547 | | cdef unsigned int cw |
| 1548 | | fpu_fix_start(&cw) |
| 1549 | | res = self._new() |
| 1550 | | _sig_on |
| 1551 | | c_qd_tan(self.initptr.x,res.initptr.x) |
| 1552 | | fpu_fix_end(&cw) |
| 1553 | | _sig_off |
| 1554 | | return res |
| 1555 | | |
| 1556 | | def sincos(self): |
| 1557 | | """ |
| 1558 | | Returns a pair consisting of the sine and cosine. |
| 1559 | | |
| 1560 | | EXAMPLES: |
| 1561 | | sage: t = RQDF(pi/6) |
| 1562 | | sage: t.sincos() |
| 1563 | | (0.500000000000000000000000000000000000000000000000000000000000000, 0.866025403784438646763723170752936183471402626905190314027903489) |
| 1564 | | """ |
| 1565 | | return self.sin(), self.cos() |
| 1566 | | |
| 1567 | | def arccos(self): |
| 1568 | | """ |
| 1569 | | Returns the inverse cosine of this number |
| 1570 | | |
| 1571 | | EXAMPLES: |
| 1572 | | sage: q = RQDF(pi/3) |
| 1573 | | sage: i = q.cos() |
| 1574 | | sage: q |
| 1575 | | 1.047197551196597746154214461093167628065723133125035273658314864 |
| 1576 | | sage: i.arccos() |
| 1577 | | 1.047197551196597746154214461093167628065723133125035273658314864 |
| 1578 | | """ |
| 1579 | | cdef QuadDoubleElement res |
| 1580 | | cdef unsigned int cw |
| 1581 | | fpu_fix_start(&cw) |
| 1582 | | res = self._new() |
| 1583 | | _sig_on |
| 1584 | | c_qd_acos(self.initptr.x,res.initptr.x) |
| 1585 | | fpu_fix_end(&cw) |
| 1586 | | _sig_off |
| 1587 | | return res |
| 1588 | | |
| 1589 | | def arcsin(self): |
| 1590 | | """ |
| 1591 | | Returns the inverse sine of this number |
| 1592 | | |
| 1593 | | EXAMPLES: |
| 1594 | | sage: q = RQDF(pi/3) |
| 1595 | | sage: i = q.sin() |
| 1596 | | sage: q |
| 1597 | | 1.047197551196597746154214461093167628065723133125035273658314864 |
| 1598 | | sage: i.arcsin() |
| 1599 | | 1.047197551196597746154214461093167628065723133125035273658314864 |
| 1600 | | """ |
| 1601 | | cdef QuadDoubleElement res |
| 1602 | | cdef unsigned int cw |
| 1603 | | fpu_fix_start(&cw) |
| 1604 | | res = self._new() |
| 1605 | | _sig_on |
| 1606 | | c_qd_asin(self.initptr.x,res.initptr.x) |
| 1607 | | fpu_fix_end(&cw) |
| 1608 | | _sig_off |
| 1609 | | return res |
| 1610 | | |
| 1611 | | def arctan(self): |
| 1612 | | """ |
| 1613 | | Returns the inverse tangent of this number |
| 1614 | | |
| 1615 | | EXAMPLES: |
| 1616 | | sage: q = RQDF(pi/3) |
| 1617 | | sage: i = q.tan() |
| 1618 | | sage: q |
| 1619 | | 1.047197551196597746154214461093167628065723133125035273658314864 |
| 1620 | | sage: i.arctan() |
| 1621 | | 1.047197551196597746154214461093167628065723133125035273658314864 |
| 1622 | | """ |
| 1623 | | cdef QuadDoubleElement res |
| 1624 | | cdef unsigned int cw |
| 1625 | | fpu_fix_start(&cw) |
| 1626 | | res = self._new() |
| 1627 | | _sig_on |
| 1628 | | c_qd_atan(self.initptr.x,res.initptr.x) |
| 1629 | | fpu_fix_end(&cw) |
| 1630 | | _sig_off |
| 1631 | | return res |
| 1632 | | |
| 1633 | | def cosh(self): |
| 1634 | | """ |
| 1635 | | Returns the hyperbolic cosine of this number |
| 1636 | | |
| 1637 | | EXAMPLES: |
| 1638 | | sage: q = RQDF(pi/12) |
| 1639 | | sage: q.cosh() |
| 1640 | | 1.034465640095510565271865251179886560959831568117717546138668562 |
| 1641 | | """ |
| 1642 | | cdef QuadDoubleElement res |
| 1643 | | cdef unsigned int cw |
| 1644 | | fpu_fix_start(&cw) |
| 1645 | | res = self._new() |
| 1646 | | _sig_on |
| 1647 | | c_qd_cosh(self.initptr.x,res.initptr.x) |
| 1648 | | fpu_fix_end(&cw) |
| 1649 | | _sig_off |
| 1650 | | return res |
| 1651 | | |
| 1652 | | def sinh(self): |
| 1653 | | """ |
| 1654 | | Returns the hyperbolic sine of this number |
| 1655 | | |
| 1656 | | EXAMPLES: |
| 1657 | | sage: q = -RQDF(pi/12) |
| 1658 | | sage: q.sinh() |
| 1659 | | -0.264800227602270757698096543949405541727737186661923151601337995 |
| 1660 | | """ |
| 1661 | | cdef QuadDoubleElement res |
| 1662 | | cdef unsigned int cw |
| 1663 | | fpu_fix_start(&cw) |
| 1664 | | res = self._new() |
| 1665 | | _sig_on |
| 1666 | | c_qd_sinh(self.initptr.x,res.initptr.x) |
| 1667 | | fpu_fix_end(&cw) |
| 1668 | | _sig_off |
| 1669 | | return res |
| 1670 | | |
| 1671 | | def tanh(self): |
| 1672 | | """ |
| 1673 | | Returns the hyperbolic tangent of this number |
| 1674 | | |
| 1675 | | EXAMPLES: |
| 1676 | | sage: q = RQDF(pi/12) |
| 1677 | | sage: q.tanh() |
| 1678 | | 0.255977789245684539459617840766661476446446454939881314446181622 |
| 1679 | | """ |
| 1680 | | cdef QuadDoubleElement res |
| 1681 | | cdef unsigned int cw |
| 1682 | | fpu_fix_start(&cw) |
| 1683 | | res = self._new() |
| 1684 | | _sig_on |
| 1685 | | c_qd_tanh(self.initptr.x,res.initptr.x) |
| 1686 | | fpu_fix_end(&cw) |
| 1687 | | _sig_off |
| 1688 | | return res |
| 1689 | | |
| 1690 | | def arccosh(self): |
| 1691 | | """ |
| 1692 | | Returns the hyperbolic inverse cosine of this number |
| 1693 | | |
| 1694 | | EXAMPLES: |
| 1695 | | sage: q = RQDF(pi/2) |
| 1696 | | sage: i = q.cosh() ; i |
| 1697 | | 2.509178478658056782009995643269405948212024358148152274047975682 |
| 1698 | | sage: i.arccosh() |
| 1699 | | 1.570796326794896619231321691639751442098584699687552910487472296 |
| 1700 | | sage: q |
| 1701 | | 1.570796326794896619231321691639751442098584699687552910487472296 |
| 1702 | | """ |
| 1703 | | cdef QuadDoubleElement res |
| 1704 | | cdef unsigned int cw |
| 1705 | | fpu_fix_start(&cw) |
| 1706 | | res = self._new() |
| 1707 | | _sig_on |
| 1708 | | c_qd_acosh(self.initptr.x,res.initptr.x) |
| 1709 | | fpu_fix_end(&cw) |
| 1710 | | _sig_off |
| 1711 | | return res |
| 1712 | | |
| 1713 | | def arcsinh(self): |
| 1714 | | """ |
| 1715 | | Returns the hyperbolic inverse sine of this number |
| 1716 | | |
| 1717 | | EXAMPLES: |
| 1718 | | sage: q = RQDF(pi/2) |
| 1719 | | sage: i = q.sinh() ; i |
| 1720 | | 2.301298902307294873463040023434427178178146516516382665972839798 |
| 1721 | | sage: i.arcsinh() ; q |
| 1722 | | 1.570796326794896619231321691639751442098584699687552910487472296 |
| 1723 | | 1.570796326794896619231321691639751442098584699687552910487472296 |
| 1724 | | """ |
| 1725 | | cdef QuadDoubleElement res |
| 1726 | | cdef unsigned int cw |
| 1727 | | fpu_fix_start(&cw) |
| 1728 | | res = self._new() |
| 1729 | | _sig_on |
| 1730 | | c_qd_asinh(self.initptr.x,res.initptr.x) |
| 1731 | | fpu_fix_end(&cw) |
| 1732 | | _sig_off |
| 1733 | | return res |
| 1734 | | |
| 1735 | | def arctanh(self): |
| 1736 | | """ |
| 1737 | | Returns the hyperbolic inverse tangent of this number |
| 1738 | | |
| 1739 | | EXAMPLES: |
| 1740 | | sage: q = RQDF(pi/2) |
| 1741 | | sage: i = q.tanh() ; i |
| 1742 | | 0.917152335667274346373092921442618775367927148601088945343574124 |
| 1743 | | sage: i.arctanh() ; q |
| 1744 | | 1.570796326794896619231321691639751442098584699687552910487472291 |
| 1745 | | 1.570796326794896619231321691639751442098584699687552910487472296 |
| 1746 | | """ |
| 1747 | | cdef QuadDoubleElement res |
| 1748 | | cdef unsigned int cw |
| 1749 | | fpu_fix_start(&cw) |
| 1750 | | res = self._new() |
| 1751 | | _sig_on |
| 1752 | | c_qd_atanh(self.initptr.x,res.initptr.x) |
| 1753 | | fpu_fix_end(&cw) |
| 1754 | | _sig_off |
| 1755 | | return res |
| 1756 | | |
| 1757 | | def agm(self, other): |
| 1758 | | """ |
| 1759 | | Return the arithmetic-geometric mean of self and other. The |
| 1760 | | arithmetic-geometric mean is the common limit of the sequences |
| 1761 | | $u_n$ and $v_n$, where $u_0$ is self, $v_0$ is other, |
| 1762 | | $u_{n+1}$ is the arithmetic mean of $u_n$ and $v_n$, and |
| 1763 | | $v_{n+1}$ is the geometric mean of u_n and v_n. If any operand |
| 1764 | | is negative, the return value is \code{NaN}. |
| 1765 | | |
| 1766 | | EXAMPLES: |
| 1767 | | sage: RQDF(2).sqrt().agm(RQDF(3).sqrt()) |
| 1768 | | 1.569105802869322326985195456078256167313945200090173796316846190 |
| 1769 | | """ |
| 1770 | | R = RR() |
| 1771 | | return QuadDoubleElement(R(self).agm(R(other))) |
| 1772 | | |
| 1773 | | cdef RealQuadDoubleField_class _RQDF |
| 1774 | | _RQDF = RealQuadDoubleField_class() |
| 1775 | | |
| 1776 | | RQDF = _RQDF # external interface |
| 1777 | | |
| 1778 | | def RealQuadDoubleField(): |
| 1779 | | global _RQDF |
| 1780 | | return _RQDF |
| 1781 | | |
| 1782 | | def is_QuadDoubleElement(x): |
| 1783 | | return PY_TYPE_CHECK(x, QuadDoubleElement) |