a
    <b%                     @   s   d Z ddlmZmZ ddlmZ ddlmZ ddlm	Z	m
Z
 ddlmZmZmZ ddlmZ ddlmZmZ dd	lmZmZ dd
lmZmZmZ ddlmZ ddlmZ dd Zdd Z dd Z!dd Z"dd Z#dS )aO  
This module contains the implementation of the 2nd_hypergeometric hint for
dsolve. This is an incomplete implementation of the algorithm described in [1].
The algorithm solves 2nd order linear ODEs of the form

.. math:: y'' + A(x) y' + B(x) y = 0\text{,}

where `A` and `B` are rational functions. The algorithm should find any
solution of the form

.. math:: y = P(x) _pF_q(..; ..;\frac{\alpha x^k + \beta}{\gamma x^k + \delta})\text{,}

where pFq is any of 2F1, 1F1 or 0F1 and `P` is an "arbitrary function".
Currently only the 2F1 case is implemented in SymPy but the other cases are
described in the paper and could be implemented in future (contributions
welcome!).

References
==========

.. [1] L. Chan, E.S. Cheb-Terrab, Non-Liouvillian solutions for second order
       linear ODEs, (2004).
       https://arxiv.org/abs/math-ph/0402063
    )SPow)expand)Eq)SymbolWild)expsqrthyper)Integral)rootsgcd)cancelfactor)collectsimplify
logcombine)	powdenest)get_numbered_constantsc                 C   sZ  |j d }||}td|||||dgd}td|||||dgd}td|||||dgd}|||d ||  ||  }t| ||d|||g|}|rtdd | D s|  \}	}
t|	} t| ||d|||g|}|rR|| dkrRt	|| ||  }t	|| ||  }||gS g S d S )	Nr   a3   )excludeb3c3c                 s   s   | ]}|  V  qd S )N)Zis_polynomial).0val r   p/Users/vegardjervell/Documents/master/model/venv/lib/python3.9/site-packages/sympy/solvers/ode/hypergeometric.py	<genexpr>1       z+match_2nd_hypergeometric.<locals>.<genexpr>)
argsdiffr   r   matchallvaluesas_numer_denomr   r   )eqfuncxZdfr   r   r   ZdeqrndABr   r   r   match_2nd_hypergeometric'   s*    

    $r.   c              	      s  |j d tt| d | d d  | }ttd | tdd  }| \}}tt|}tt|} fdd  |f} |f}|| |}	t	|	}
tt
t||
d  tdd  |
 d  dd}ttt|td|
  dd}| \}}t |f}|j }g }g }|D ]}|r4t|tr|| d  |tt| d  d  n.|| d  |tt| d  q4|  t||d	kr||
|d	d
S d S d S )Nr   r         c                    sx   dh}| D ]h}| r
t|trF| d krF|| d  q
|krb|| d  q
| |j q
|S )Nr   r0   )has
isinstancer   as_base_expaddupdater    )num_powr   _power_countingr(   r   r   r9   N   s    
z3equivalence_hypergeometric.<locals>._power_countingTforce2F1)I0k
sing_pointtype)r    r   r   r!   r   r%   r   r   r5   r   r   subsmaxr1   r2   r   appendr3   listr   keyssortequivalence)r,   r-   r'   ZI1ZJ1r6   ZdemZpow_numZpow_demr7   r>   r=   max_num_powZdem_argsr?   dem_powargr   r8   r   equivalence_hypergeometric>   s<    
& 


4(& rK   c           "      C   s  |j d }td}td}td}td}td}	td}
td}td	}td
}td}|| d || d  |d  dd| | | d| |   |  ||d   d|d  |d d   }|ddgkrg }| | | | || ||  g}tdD ]D}|t|k r*|t|| ||  q|td||  d q| |d  }| |d  }|}t|dkr||d |  |d |d   }|| | || |  }|||}|||}|||}t|}|||  || |  }t|||||||}n|}|}| ||} | ||d  } t	| } |d d|dddi}|
 \}}|d |	d d |dd|
  | |
|	 |
|	   d||d  i}|ttt| | |d |gdd g }|d |dfD ]}|t|| ||  qdt	td|d j  }|ts4ttt|d |}t	t|d jd }|t	t|d |d  |d j d|   }|| d }|| d } t|t| t|||dd}!|!S )Nr   abctsr)   alphabetagammadeltar0   r   r/      F)evaluater<   )rL   rM   rN   r>   mobiusr@   )r    r   rangelenrC   r   rA   r   r!   r   r%   r5   r   r   r	   lhsr1   r   minrD   r   r   )"Ir>   r?   r'   r(   rL   rM   rN   rO   rP   r)   rQ   rR   rS   rT   r=   ZeqsZsing_eqsiZ_betaZ_deltaZ_gammaZmobZdict_IZI0_numZI0_demZdict_I0keyZ_cZ_s_rZ_a_bZrnr   r   r   match_2nd_2F1_hypergeometric   sh    
h" "@(.ra   c              	   C   s   | dkr"|ddgg dfv rdS nj| dkrP|g dg dddgddgfv rdS n<| dkr|g dddgg dddgdgddgddgfv rdS d S )Nr   )r   r   r   r<   r0   )r0   r   r   r   )r0   r0   r   r   )rH   rI   r   r   r   rG      s     0rG   c                 C   s"  |j d }ddlm} ddlm} t| dd\}}|d }|d }	|d }
|d	 }d }|
jd
kr|t||	g|
g| |t||
 d |	|
 d gd|
 g| |d|
    }n|
dkr8tt	t||	 d  | |
 |d |  ||t||	g|
g|d  |t||	g|
g| }|t||	g|
g| ||  }n||
| |	 jd
kr|t||	gd| |	 |
 gd|  |t|
| |
|	 gd|
 | |	 gd|  d| |
| |	    }|r|d }t
d|| }||	 d | |
 ||| }|||d | |||||   }||d | |||d  }t	ttt|d|  |dd}|||d }||||d  }||||d  }|jst|d |}t	t|dd}t|| ||d  d d   | }t||}|S t|||d  d d   | }t||}|S )Nr   )hyperexpand)r   r   )r6   rL   rM   rN   r,   Fr0   rW   Tr:   r>   )r    Zsympy.simplify.hyperexpandrb   sympy.polys.polytoolsr   r   
is_integerr
   r   r   r   r!   rA   r   r   is_zeror   )r&   r'   Zmatch_objectr(   rb   r   ZC0ZC1rL   rM   rN   r,   Zsoly2rA   ZdtdxZ_BZ_Aee1r   r   r   get_sol_2F1_hypergeometric   sF    

P
^ h * "&
"
ri   N)$__doc__Z
sympy.corer   r   Zsympy.core.functionr   Zsympy.core.relationalr   Zsympy.core.symbolr   r   Zsympy.functionsr   r	   r
   Zsympy.integralsr   Zsympy.polysr   r   rc   r   r   Zsympy.simplifyr   r   r   Zsympy.simplify.powsimpr   Zsympy.solvers.ode.oder   r.   rK   ra   rG   ri   r   r   r   r   <module>   s    AK