Advertisement
OPiMedia

fibonacci_functions.py

Oct 9th, 2021
1,417
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.93 KB | None | 0 0
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3.  
  4. """
  5. fibonacci_functions.py
  6.  
  7. Checks some formulas on Fibonacci function and sums.
  8.  
  9. :license: GPLv3 --- Copyright (C) 2021 Olivier Pirson
  10. :author: Olivier Pirson --- http://www.opimedia.be/
  11. :version: October 9, 2021
  12. """
  13.  
  14. import sys
  15.  
  16. from typing import Callable
  17.  
  18.  
  19. def f(k: int, alpha: int, beta: int) -> int:
  20.     """
  21.    Returns f(k).
  22.  
  23.    Where f is such that:
  24.    f(0) = alpha
  25.    f(1) = beta
  26.    forall n: f(n + 2) = f(n + 1) + f(n)
  27.    """
  28.     assert k >= 0
  29.  
  30.     f_i = alpha  # f(i)
  31.     f_i_1 = beta  # f(i + 1)
  32.     for _ in range(k):
  33.         f_i, f_i_1 = f_i_1, f_i_1 + f_i
  34.  
  35.     return f_i
  36.  
  37.  
  38. def fibo(k: int) -> int:
  39.     """
  40.    Returns the number of Fibonacci F_k.
  41.  
  42.    https://oeis.org/A000045
  43.    """
  44.     if k < 0:
  45.         return fibo(-k) * (-1)**(1 - k % 2)
  46.  
  47.     f_i_1 = 1  # F_{i-1}
  48.     f_i = 0  # F_i
  49.     for _ in range(k):
  50.         f_i_1, f_i = f_i, f_i + f_i_1
  51.  
  52.     return f_i
  53.  
  54.  
  55. def lucas(k: int) -> int:
  56.     """
  57.    Returns the number of Lucas L_k.
  58.  
  59.    https://oeis.org/A000032
  60.    """
  61.     if k < 0:
  62.         return fibo(-k) * (-1)**(1 - k % 2)
  63.  
  64.     l_i_1 = -1  # L_{i-1}
  65.     l_i = 2  # L_i
  66.     for _ in range(k):
  67.         l_i_1, l_i = l_i, l_i + l_i_1
  68.  
  69.     return l_i
  70.  
  71.  
  72. def sum_f(k: int, f: Callable[[int], int]) -> int:
  73.     """Returns f(0) + ... + f(k - 1)."""
  74.     assert k >= 0
  75.  
  76.     s = 0
  77.     for i in range(k):
  78.         s += f(i)
  79.  
  80.     return s
  81.  
  82.  
  83. def s(k: int, alpha: int, beta: int) -> int:
  84.     """Returns f(0, alpha, beta) + ... + f(k - 1, alpha, beta)."""
  85.     assert k >= 0
  86.  
  87.     return f(k + 1, alpha, beta) - beta
  88.  
  89.  
  90. def main() -> None:
  91.     """Checks by assertions."""
  92.     assert fibo(-5) == 5
  93.     assert fibo(-4) == -3
  94.     assert fibo(-3) == 2
  95.     assert fibo(-2) == -1
  96.     assert fibo(-1) == 1
  97.     assert fibo(0) == 0
  98.     assert fibo(1) == 1
  99.     assert fibo(2) == 1
  100.     assert fibo(3) == 2
  101.     assert fibo(4) == 3
  102.     assert fibo(5) == 5
  103.  
  104.     assert lucas(0) == 2
  105.     assert lucas(1) == 1
  106.     assert lucas(2) == 3
  107.     assert lucas(3) == 4
  108.     assert lucas(4) == 7
  109.     assert lucas(5) == 11
  110.  
  111.     max_i = (int(sys.argv[1]) if len(sys.argv) > 1
  112.              else 100)
  113.  
  114.     for i in range(max_i + 1):
  115.         fibo_i_m1 = fibo(i - 1)
  116.         fibo_i = fibo(i)
  117.         fibo_i_p1 = fibo(i + 1)
  118.  
  119.         assert fibo_i_p1 == fibo_i + fibo_i_m1
  120.  
  121.         assert fibo_i == f(i, 0, 1)
  122.         assert fibo_i_p1 == f(i, 1, 1)
  123.         assert fibo_i_m1 == f(i, 1, 0)
  124.  
  125.         assert lucas(i) == f(i, 2, 1)
  126.  
  127.         assert sum_f(i, lambda n: 1) == i
  128.         assert sum_f(i, lambda n: n) == (i - 1) * i // 2
  129.  
  130.         assert sum_f(i, fibo) == fibo_i_p1 - 1
  131.  
  132.         assert f(i, 0, 0) == 0
  133.         assert f(i, 1, 1) == fibo_i_p1
  134.         assert f(i, 1, 0) == fibo_i_m1
  135.  
  136.         assert sum_f(i, lambda k: s(k, 0, 1)) == f(i + 2, 0, 1) - (i + 1)
  137.  
  138.         assert sum_f(i, lambda k: s(k, 1, 0)) == f(i + 2, 1, 0) - 1
  139.         assert sum_f(i, lambda k: s(k, 1, 0)) == sum_f(i, fibo)
  140.  
  141.         for alpha in range(-10, 11):
  142.             assert sum_f(i, lambda k: f(k, alpha, 0)) == f(i + 1, alpha, 0)
  143.  
  144.             for beta in range(-10, 11):
  145.                 assert f(0, alpha, beta) == alpha
  146.                 assert f(1, alpha, beta) == beta
  147.                 assert f(2, alpha, beta) == alpha + beta
  148.                 assert f(3, alpha, beta) == alpha + beta * 2
  149.                 assert f(4, alpha, beta) == alpha * 2 + beta * 3
  150.                 assert f(5, alpha, beta) == alpha * 3 + beta * 5
  151.  
  152.                 assert f(i, alpha, beta) == alpha * fibo_i_m1 + beta * fibo_i
  153.  
  154.                 sum_by_f = f(i + 1, alpha, beta) - beta
  155.  
  156.                 assert sum_f(i, lambda k: f(k, alpha, beta)) == sum_by_f
  157.                 assert s(i, alpha, beta) == sum_by_f
  158.                 assert (sum_f(i, lambda k: s(k, alpha, beta)) ==
  159.                         f(i + 2, alpha, beta) - alpha - beta * (i + 1))
  160.  
  161.  
  162. if __name__ == '__main__':
  163.     main()
  164.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement