
    MZd                     <    d Z ddlmZmZ ddlmZ ddlmZ d Zd Z	y)z
Recurrences
    )Ssympify)iterable)as_intc                 P   | st         j                  S t        |       st        d      t        |      st        d      t	        |      }|dk  rt        d      | D cg c]  }t        |       }}|D cg c]  }t        |       }}t        |      }t        |      |kD  rt        d      |t         j                  g|t        |      z
  z  z  }||k  r||   S t        t        ||      |      D cg c]
  \  }}||z   }	}}t        |	dd |	d         S c c}w c c}w c c}}w )a	  
    Evaluation of univariate linear recurrences of homogeneous type
    having coefficients independent of the recurrence variable.

    Parameters
    ==========

    coeffs : iterable
        Coefficients of the recurrence
    init : iterable
        Initial values of the recurrence
    n : Integer
        Point of evaluation for the recurrence

    Notes
    =====

    Let `y(n)` be the recurrence of given type, ``c`` be the sequence
    of coefficients, ``b`` be the sequence of initial/base values of the
    recurrence and ``k`` (equal to ``len(c)``) be the order of recurrence.
    Then,

    .. math :: y(n) = \begin{cases} b_n & 0 \le n < k \\
        c_0 y(n-1) + c_1 y(n-2) + \cdots + c_{k-1} y(n-k) & n \ge k
        \end{cases}

    Let `x_0, x_1, \ldots, x_n` be a sequence and consider the transformation
    that maps each polynomial `f(x)` to `T(f(x))` where each power `x^i` is
    replaced by the corresponding value `x_i`. The sequence is then a solution
    of the recurrence if and only if `T(x^i p(x)) = 0` for each `i \ge 0` where
    `p(x) = x^k - c_0 x^(k-1) - \cdots - c_{k-1}` is the characteristic
    polynomial.

    Then `T(f(x)p(x)) = 0` for each polynomial `f(x)` (as it is a linear
    combination of powers `x^i`). Now, if `x^n` is congruent to
    `g(x) = a_0 x^0 + a_1 x^1 + \cdots + a_{k-1} x^{k-1}` modulo `p(x)`, then
    `T(x^n) = x_n` is equal to
    `T(g(x)) = a_0 x_0 + a_1 x_1 + \cdots + a_{k-1} x_{k-1}`.

    Computation of `x^n`,
    given `x^k = c_0 x^{k-1} + c_1 x^{k-2} + \cdots + c_{k-1}`
    is performed using exponentiation by squaring (refer to [1_]) with
    an additional reduction step performed to retain only first `k` powers
    of `x` in the representation of `x^n`.

    Examples
    ========

    >>> from sympy.discrete.recurrences import linrec
    >>> from sympy.abc import x, y, z

    >>> linrec(coeffs=[1, 1], init=[0, 1], n=10)
    55

    >>> linrec(coeffs=[1, 1], init=[x, y], n=10)
    34*x + 55*y

    >>> linrec(coeffs=[x, y], init=[0, 1], n=5)
    x**2*y + x*(x**3 + 2*x*y) + y**2

    >>> linrec(coeffs=[1, 2, 3, 0, 0, 4], init=[x, y, z], n=16)
    13576*x + 5676*y + 2356*z

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Exponentiation_by_squaring
    .. [2] https://en.wikipedia.org/w/index.php?title=Modular_exponentiation&section=6#Matrices

    See Also
    ========

    sympy.polys.agca.extensions.ExtensionElement.__pow__

    z6Expected a sequence of coefficients for the recurrencezFExpected a sequence of values for the initialization of the recurrencer   z@Point of evaluation of recurrence must be a non-negative integerzECount of initial values should not exceed the order of the recurrenceN)r   Zeror   	TypeErrorr   
ValueErrorr   lenziplinrec_coeffssum)
coeffsinitnargcbkuvtermss
             </usr/lib/python3/dist-packages/sympy/discrete/recurrences.pylinrecr   
   s<   Z vvF * + 	+ D> - . 	. 	q	A1u / 0 	0 "((#(A(!%&#&A&AA
1vz 2 3 	3 	
affXq3q6z""1ut q!!4a89TQQqS9E9uSbz59%% 	)& :s   D6D4D"c                 J     t                fdfd |      S )a  
    Compute the coefficients of n'th term in linear recursion
    sequence defined by c.

    `x^k = c_0 x^{k-1} + c_1 x^{k-2} + \cdots + c_{k-1}`.

    It computes the coefficients by using binary exponentiation.
    This function is used by `linrec` and `_eval_pow_by_cayley`.

    Parameters
    ==========

    c = coefficients of the divisor polynomial
    n = exponent of x, so dividend is x^n

    c                 l   t         j                  gdt        |       z  dz
  |z   z  }t        |       D ].  \  }}t        |       D ]  \  }}|||z   |z   xx   ||z  z  cc<    0 t	        t        |      dz
  dz
  d      D ].  }t	              D ]  }|||z
  dz
  xx   ||   |   z  z  cc<     0 |d  S )N      r   )r   r	   r   	enumeraterange)	r   offsetwipjqr   r   s	          r   _square_and_reducez)linrec_coeffs.<locals>._square_and_reduce   s     VVHaAhlV+,aL 	)DAq!! )1&1*q.!QqS(!)	) s1vz1q5"- 	*A1X *!a%!)!QqT	)*	* !u    c                     | k  rAt         j                  g| z  t         j                  gz   t         j                  g| z
  dz
  z  z   S   | dz        | dz        S )Nr   r   )r   r	   One)r   _final_coeffsr(   r   s    r   r,   z$linrec_coeffs.<locals>._final_coeffs   sY    
 q5FF8A:'166(AEAI*>>>%mAF&;QUCCr)   )r   )r   r   r,   r(   r   s   ` @@@r   r   r   w   s&    $ 	AA"D r)   N)
__doc__
sympy.corer   r   sympy.utilities.iterablesr   sympy.utilities.miscr   r   r    r)   r   <module>r2      s!    " . 'j&Z/r)   