You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

63 lines
1.5 KiB

5 years ago
  1. '''
  2. Created on Dec 14, 2011
  3. @author: pablocelayes
  4. '''
  5. def rational_to_contfrac(x,y):
  6. '''
  7. Converts a rational x/y fraction into
  8. a list of partial quotients [a0, ..., an]
  9. '''
  10. a = x//y
  11. pquotients = [a]
  12. while a * y != x:
  13. x,y = y,x-a*y
  14. a = x//y
  15. pquotients.append(a)
  16. return pquotients
  17. #TODO: efficient method that calculates convergents on-the-go, without doing partial quotients first
  18. def convergents_from_contfrac(frac):
  19. '''
  20. computes the list of convergents
  21. using the list of partial quotients
  22. '''
  23. convs = [];
  24. for i in range(len(frac)):
  25. convs.append(contfrac_to_rational(frac[0:i]))
  26. return convs
  27. def contfrac_to_rational (frac):
  28. '''Converts a finite continued fraction [a0, ..., an]
  29. to an x/y rational.
  30. '''
  31. if len(frac) == 0:
  32. return (0,1)
  33. num = frac[-1]
  34. denom = 1
  35. for _ in range(-2,-len(frac)-1,-1):
  36. num, denom = frac[_]*num+denom, num
  37. return (num,denom)
  38. def test1():
  39. '''
  40. Verify that the basic continued-fraction manipulation stuff works.
  41. '''
  42. testnums = [(1, 1), (1, 2), (5, 15), (27, 73), (73, 27)]
  43. for r in testnums:
  44. (num, denom) = r
  45. print('rational number:')
  46. print(r)
  47. contfrac = rational_to_contfrac (num, denom)
  48. print('continued fraction:')
  49. print(contfrac)
  50. print('convergents:')
  51. print(convergents_from_contfrac(contfrac))
  52. print('***********************************')
  53. if __name__ == "__main__":
  54. test1()