Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

r""" 

Generic numerical approximation function 

""" 

  

#***************************************************************************** 

# Copyright (C) 2016 Jeroen Demeyer <jdemeyer@cage.ugent.be> 

# 

# This program is free software: you can redistribute it and/or modify 

# it under the terms of the GNU General Public License as published by 

# the Free Software Foundation, either version 2 of the License, or 

# (at your option) any later version. 

# http://www.gnu.org/licenses/ 

#***************************************************************************** 

  

from sage.structure.parent cimport Parent 

from sage.structure.element cimport parent 

cdef Parent CDF 

from sage.rings.all import RealField, ComplexField, CDF 

  

  

def numerical_approx_generic(x, prec): 

""" 

Generic implementation of ``numerical_approx`` using coercion or 

conversion to a real or complex field. 

  

EXAMPLES:: 

  

sage: from sage.arith.numerical_approx import numerical_approx_generic 

sage: numerical_approx_generic(pi, 20) 

3.1416 

sage: numerical_approx_generic(int(42), 20) 

42.000 

sage: numerical_approx_generic(float(4.2), 20) 

4.2000 

""" 

P = parent(x) 

  

cdef Parent RR = RealField(prec) 

cmap = RR.coerce_map_from(P) 

if cmap is not None: 

return cmap(x) 

  

cdef Parent CC = ComplexField(prec) 

cmap = CC.coerce_map_from(P) 

if cmap is not None: 

return cmap(x) 

  

# Coercion didn't work: there are 3 possibilities: 

# (1) There is a coercion possible to a lower precision 

# (2) There is a conversion but no coercion 

# (3) The type doesn't convert at all 

  

# Figure out input precision to check for case (1) 

try: 

inprec = x.prec() 

except AttributeError: 

if prec > 53 and CDF.has_coerce_map_from(P): 

# If we can coerce to CDF, assume input precision was 53 bits 

inprec = 53 

else: 

# Otherwise, assume precision wasn't the issue 

inprec = prec 

  

if prec > inprec: 

raise TypeError("cannot approximate to a precision of %s bits, use at most %s bits" % (prec, inprec)) 

  

# The issue is not precision, try conversion instead 

try: 

return RR(x) 

except (TypeError, ValueError): 

return CC(x)