ó
    ˆ*£hEr  ã                   óô  • S r SSKJr  SSKJrJr  S r " S S\5      rSIS
 jr	SJS jr
S rS rS rS rS SS4S SS4S SS4S SS4S SS4S SS4S SS4S S S4S! S"S4S# S$S4S% S&S4S' S(S4S) S*S4S+ S,S4S- S.S4S/ S0S4S1 S2S4S3 S4S4S5 S6S4S7 S8S4S9 S:S4S; S<S4S= S>S4S? S@S4SA SBS4SC SDS4SE SFS4/r/ SSS	S	4SG jr\	\l	        \
\l
        \\l        \SH:X  a  SSKr\R&                  " 5         gg)Kzs
Implements the PSLQ algorithm for integer relation detection,
and derivative algorithms for constant recognition.
é   )Úxrange)Ú	int_typesÚ
sqrt_fixedc                 ó$   • U SUS-
  -  -   U-	  U-  $ ©Nr   © )ÚxÚprecs     ÚR/home/mande/repo/quber/.venv/lib/python3.13/site-packages/mpmath/identification.pyÚround_fixedr   
   s   € Ø�!�d˜1‘f‘+Ñ 4Ñ'¨DÑ0Ð0ó    c                   ó   • \ rS rSrSrg)ÚIdentificationMethodsé   r   N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__static_attributes__r   r   r   r   r      s   † Úr   r   Néè  Fc                 ó  • [        U5      nUS:  a  [        S5      eU R                  nUS:  a  [        S5      eU(       a  U[        SU5      -  S:  a  [	        S5        [        US-  5      nUc  U R                  S5      U* -  nOU R                  U5      nS	n	Xy-  nU(       a  [	        S
XpR                  U5      4-  5        U R                  X'5      nU(       d   eS/U V
s/ s H#  o R                  U R                  U
5      U5      PM%     sn
-   n[        S USS  5       5      nU(       d  [        S5      eX²S-  :  a  U(       a  [	        S5        g[        SU-  S-  U5      n0 n0 n0 n[        SUS-   5       H4  n[        SUS-   5       H  nUU:H  U-  =UUU4'   UUU4'   SUUU4'   M      M6     S/S/U-  -   n[        SUS-   5       H8  nSn[        UUS-   5       H  nUUU   S-  U-	  -  nM     [        UU5      UU'   M:     US   nUSS n[        SUS-   5       H  nUU   U-  U-  UU'   UU   U-  U-  UU'   M!     [        SUS-   5       H™  n[        US-   U5       H
  nSUUU4'   M     UUS-
  ::  a(  UU   (       a  UUS-      U-  UU   -  UUU4'   OSUUU4'   [        SU5       H8  nUU   UUS-      -  nU(       a  UU   * UU   -  U-  U-  UUU4'   M1  SUUU4'   M:     M›     [        SUS-   5       HÓ  n[        US-
  SS5       H¼  nUUU4   (       a  [        UUU4   U-  UUU4   -  U5      nOM.  UU   UUU   -  U-	  -   UU'   [        SUS-   5       H  nUUU4   UUUU4   -  U-	  -
  UUU4'   M     [        SUS-   5       H7  nUUU4   UUUU4   -  U-	  -
  UUU4'   UUU4   UUUU4   -  U-	  -   UUU4'   M9     M¾     MÕ     [        U5       GHä  nSnSn[        SU5       H0  nUUU4   nUU-  [        U5      -  UUS-
  -  -	  nUU:”  d  M,  UnUnM2     UUS-      UU   sUU'   UUS-   '   [        SUS-   5       H"  nUUS-   U4   UUU4   sUUU4'   UUS-   U4'   M$     [        SUS-   5       H"  nUUS-   U4   UUU4   sUUU4'   UUS-   U4'   M$     [        SUS-   5       H"  nUUUS-   4   UUU4   sUUU4'   UUUS-   4'   M$     UUS-
  ::  a�  [        UUU4   S-  UUUS-   4   S-  -   U-	  U5      nU(       d    GO³UUU4   U-  U-  nUUUS-   4   U-  U-  n[        UUS-   5       H>  nUUU4   nUUUS-   4   n UU-  UU -  -   U-	  UUU4'   U* U-  UU -  -   U-	  UUUS-   4'   M@     [        US-   US-   5       HÒ  n[        [        US-
  US-   5      SS5       H®  n [        UUU4   U-  UUU4   -  U5      nUU   UUU   -  U-	  -   UU'   [        SUS-   5       H  nUUU4   UUUU4   -  U-	  -
  UUU4'   M     [        SUS-   5       H7  nUUU4   UUUU4   -  U-	  -
  UUU4'   UUU4   UUUU4   -  U-	  -   UUU4'   M9     M°     MÔ     X7-  n![        SUS-   5       Hµ  n[        UU   5      n"U"U:  a’  [        SUS-   5       Vs/ s H   n[        [        UUU4   U5      U-	  5      PM"     n#n[        S U# 5       5      U:  aB  U(       a5  [	        SUX@R                  U"U R                  S5      U-  -  S5      4-  5        U#s  s  $ [        U"U!5      n!M·     [        S UR#                  5        5       5      n$U$(       a  SSU-  -  U$-  U-	  n%U%S-  n%OU R$                  n%U(       a6  [	        SUX@R                  U!U R                  S5      U-  -  S5      U%4-  5        U%U:¼  d  GMå    O   U(       a  [	        SWU4-  5        [	        SW%-  5        gs  sn
f ! [          a       GMm  f = fs  snf )az  
Given a vector of real numbers `x = [x_0, x_1, ..., x_n]`, ``pslq(x)``
uses the PSLQ algorithm to find a list of integers
`[c_0, c_1, ..., c_n]` such that

.. math ::

    |c_1 x_1 + c_2 x_2 + ... + c_n x_n| < \mathrm{tol}

and such that `\max |c_k| < \mathrm{maxcoeff}`. If no such vector
exists, :func:`~mpmath.pslq` returns ``None``. The tolerance defaults to
3/4 of the working precision.

**Examples**

Find rational approximations for `\pi`::

    >>> from mpmath import *
    >>> mp.dps = 15; mp.pretty = True
    >>> pslq([-1, pi], tol=0.01)
    [22, 7]
    >>> pslq([-1, pi], tol=0.001)
    [355, 113]
    >>> mpf(22)/7; mpf(355)/113; +pi
    3.14285714285714
    3.14159292035398
    3.14159265358979

Pi is not a rational number with denominator less than 1000::

    >>> pslq([-1, pi])
    >>>

To within the standard precision, it can however be approximated
by at least one rational number with denominator less than `10^{12}`::

    >>> p, q = pslq([-1, pi], maxcoeff=10**12)
    >>> print(p); print(q)
    238410049439
    75888275702
    >>> mpf(p)/q
    3.14159265358979

The PSLQ algorithm can be applied to long vectors. For example,
we can investigate the rational (in)dependence of integer square
roots::

    >>> mp.dps = 30
    >>> pslq([sqrt(n) for n in range(2, 5+1)])
    >>>
    >>> pslq([sqrt(n) for n in range(2, 6+1)])
    >>>
    >>> pslq([sqrt(n) for n in range(2, 8+1)])
    [2, 0, 0, 0, 0, 0, -1]

**Machin formulas**

A famous formula for `\pi` is Machin's,

.. math ::

    \frac{\pi}{4} = 4 \operatorname{acot} 5 - \operatorname{acot} 239

There are actually infinitely many formulas of this type. Two
others are

.. math ::

    \frac{\pi}{4} = \operatorname{acot} 1

    \frac{\pi}{4} = 12 \operatorname{acot} 49 + 32 \operatorname{acot} 57
        + 5 \operatorname{acot} 239 + 12 \operatorname{acot} 110443

We can easily verify the formulas using the PSLQ algorithm::

    >>> mp.dps = 30
    >>> pslq([pi/4, acot(1)])
    [1, -1]
    >>> pslq([pi/4, acot(5), acot(239)])
    [1, -4, 1]
    >>> pslq([pi/4, acot(49), acot(57), acot(239), acot(110443)])
    [1, -12, -32, 5, -12]

We could try to generate a custom Machin-like formula by running
the PSLQ algorithm with a few inverse cotangent values, for example
acot(2), acot(3) ... acot(10). Unfortunately, there is a linear
dependence among these values, resulting in only that dependence
being detected, with a zero coefficient for `\pi`::

    >>> pslq([pi] + [acot(n) for n in range(2,11)])
    [0, 1, -1, 0, 0, 0, -1, 0, 0, 0]

We get better luck by removing linearly dependent terms::

    >>> pslq([pi] + [acot(n) for n in range(2,11) if n not in (3, 5)])
    [1, -8, 0, 0, 4, 0, 0, 0]

In other words, we found the following formula::

    >>> 8*acot(2) - 4*acot(7)
    3.14159265358979323846264338328
    >>> +pi
    3.14159265358979323846264338328

**Algorithm**

This is a fairly direct translation to Python of the pseudocode given by
David Bailey, "The PSLQ Integer Relation Algorithm":
http://www.cecm.sfu.ca/organics/papers/bailey/paper/html/node3.html

The present implementation uses fixed-point instead of floating-point
arithmetic, since this is significantly (about 7x) faster.
é   zn cannot be less than 2é5   zprec cannot be less than 53é   z*Warning: precision for PSLQ may be too lowg      è?Né<   zPSLQ using prec %i and tol %sc              3   ó8   #   • U  H  n[        U5      v •  M     g 7f©N©Úabs)Ú.0Úxxs     r   Ú	<genexpr>Úpslq.<locals>.<genexpr>§   s   é € Ð'¢˜2Œs�2�wˆw¢ùó   ‚r   z)PSLQ requires a vector of nonzero numberséd   z#STOPPING: (one number is too small)é   é   é    éÿÿÿÿc              3   ó8   #   • U  H  n[        U5      v •  M     g 7fr   r   )r    Úvs     r   r"   r#     s   é € Ð+¢s !”s˜1—v�v¢sùr$   z'FOUND relation at iter %i/%i, error: %sc              3   ó8   #   • U  H  n[        U5      v •  M     g 7fr   r   )r    Úhs     r   r"   r#   '  s   é € Ð1¢j ”c˜!—f�f¢jùr$   z%i/%i:  Error: %8s   Norm: %szCANCELLING after step %i/%i.z2Could not find an integer relation. Norm bound: %s)ÚlenÚ
ValueErrorr
   ÚmaxÚprintÚintÚmpfÚconvertÚnstrÚto_fixedÚminr   r   Úranger   r   ÚZeroDivisionErrorÚvaluesÚinf)&Úctxr	   ÚtolÚmaxcoeffÚmaxstepsÚverboseÚnr
   ÚtargetÚextraÚxkÚminxÚgÚAÚBÚHÚiÚjÚsÚkÚtÚyÚsjj1ÚREPÚmÚszmaxr-   ÚszÚt0Út1Út2Út3Út4Úbest_errÚerrÚvecÚrecnormÚnorms&                                         r   Úpslqr_      s‰	  € ôf 	ˆA‹€AØˆ1ƒuÜÐ2Ó3Ð3ð �8‰8€DØˆbƒyÜÐ6Ó7Ð7æ�4œ3˜q ›8Ñ# aÓ'ÜÐ:Ô;ä�˜‘Ó€Fà
�{Ø�g‰g�a‹j˜F˜7Ñ#‰à�k‰k˜#Óˆà€EØ�M€DæÜÐ-°·x±xÀ³}Ð0EÑEÔFà
�,‰,�sÓ
!€CÞ€Jˆ3ð 
ˆ¹AÓ>ºA°b—,‘,˜sŸw™w r›{¨DÖ1¹AÑ>Ñ>€Aô Ñ'  1 2¡Ó'Ó'€DÞÜÐDÓEÐEØ�3‰hƒÞÜÐ7Ô8Øä�A�t‘G˜a‘< Ó&€AØ
€AØ
€AØ
€Aô �A�q˜‘sŽ^ˆÜ˜˜1˜Q™3–ˆAØ  !™t¨™nÐ,ˆAˆa�ˆc‰F�Q�q˜�s‘VØˆAˆa�ˆc‹Fó  ñ ð
 
ˆ�!��q‘Ñ€AÜ�A�q˜‘sŽ^ˆØˆÜ˜˜1˜Q™3–ˆAØ�!�A‘$˜‘'˜T‘/Ñ"ŠAñ  ä˜!˜TÓ"ˆˆ!‹ñ	 ð
 	
ˆ!‰€AØ	‰!ˆ€AÜ�A�q˜‘sŽ^ˆØ�!‘˜‘ Ñ"ˆˆ!‰Ø�!‘˜‘ Ñ"ˆˆ!‹ñ ô �A�q˜‘sŽ^ˆÜ˜˜!™˜Q–ˆAØˆAˆa�ˆc‹Fñ  à��!‘‹8Ø��tØ˜A˜a™C™& D™.¨Q¨q©TÑ1��!�A�#’à��!�A�#‘Ü�q˜!–ˆAØ�Q‘4˜˜!˜A™#™‘;ˆDÞØ˜a™D˜5  1¡™:¨Ñ,¨tÑ3��!�A�#“à��!�A�#“ó ñ ô �A�q˜‘sŽ^ˆÜ˜˜!™˜Q Ö#ˆAà��1��vÜ  1 Q 3¡¨4¡°!°A°a°C±&Ñ 8¸$Ó?‘ñ Ø�Q‘4˜1˜Q˜q™T™6 T™>Ñ*ˆAˆa‰DÜ˜A˜q ™s–^�Ø˜1˜Q˜3™ 1 Q q¨ s¡V¡8¨tÑ#3Ñ4��!�A�#“ñ $ä˜A˜q ™s–^�Ø˜1˜Q˜3™ 1 Q q¨ s¡V¡8¨tÑ#3Ñ4��!�A�#‘Ø˜1˜Q˜3™ 1 Q q¨ s¡V¡8¨tÑ#3Ñ4��!�A�#“ó $ó $ñ ô �X�ˆàˆØˆÜ�q˜!–ˆAØ�!�A�#‘ˆAØ�Q‘$œ˜Q›‘- T¨1¨Q©3¡ZÑ0ˆBØ�E�zØ�Ø’ñ ð ˜˜1™‘v˜q ™tˆˆˆ!‰ˆa��!‘‰fÜ˜˜!˜A™#–ˆA°1°Q°q±S¸°U±8¸Q¸qÀ¸s¹VÐ 0  ! A #¡¨¨!¨A©#¨a¨%«‘Ü˜˜!˜A™#–ˆA°1°Q°q±S¸°U±8¸Q¸qÀ¸s¹VÐ 0  ! A #¡¨¨!¨A©#¨a¨%«‘Ü˜˜!˜A™#–ˆA°1°Q°q¸±s°U±8¸Q¸qÀ¸s¹VÐ 0  ! A #¡¨¨!¨A¨a©C¨%«‘à��A‘‹:Ü˜Q˜q ˜s™V Q™Y¨¨1¨Q¨q©S¨5©°1©Ñ4°tÑ;¸TÓBˆBö ÚØ�A�a�C‘&˜D‘. RÑ'ˆBØ�A�a˜‘c�E‘(˜dÑ" rÑ)ˆBÜ˜A˜q ™s–^�Ø�q˜�s‘V�Ø�q˜˜1™�u‘X�Ø˜R™%  2¡™+¨$Ñ.��!�A�#‘Ø˜C ™F 2 b¡5™L¨TÑ1��!�A�a‘C�%“ñ	 $ô ˜˜!™˜Q˜q™SÖ!ˆAÜœC  !¡ Q q¡S›M¨1¨bÖ1�ðÜ# Q q¨ s¡V¨t¡^°a¸¸!¸±fÑ$<¸dÓC�Að ˜‘t  ! A¡$¡¨4Ñ/Ñ0��!‘Ü  1 Q¡3ž�AØ˜q ˜s™V q¨¨1¨Q¨3©¡x°4Ñ'7Ñ8�A�a˜�c“Fñ (ä  1 Q¡3ž�AØ˜q ˜s™V q¨¨1¨Q¨3©¡x°4Ñ'7Ñ8�A�a˜�c‘FØ˜q ˜s™V q¨¨1¨Q¨3©¡x°4Ñ'7Ñ8�A�a˜�c“Fó (ó 2ñ "ð& ‘>ˆÜ˜˜1˜Q™3–ˆAÜ�a˜‘d“)ˆCà�S‹yô �a˜˜!™”óÚð CD”sœ; q¨¨1¨¡v¨tÓ4¸Ñ<Ö=Ùð ð äÑ+¡sÓ+Ó+¨hÓ6ÞÜÐGØ  (¯H©H°S¸3¿7¹7À1»:ÀtÑ;KÑ5KÈQÓ,OÐPñQô Rà”JÜ˜3 Ó)ŠHñ  ô  Ñ1 a§h¡h¤jÓ1Ó1ˆÞØ˜1˜T™6‘] wÑ.°4Ñ7ˆDØ�S‰L‰Dà—7‘7ˆDÞÜÐ1Ø�h§¡¨°C·G±G¸A³JÀÑ4DÑ)DÀaÓ HÈ$ÐOñPô Qà�8ÖÙñ[ ö\ ÜÐ,°°X¨Ñ>Ô?ÜÐBÀTÑIÔJØùòc ?øôH )ó Üðüò(s   Ã"*_/Ö:_4Ú''`ß4
`	à`	c                 ó  • U R                  U5      nUS:  a  [        S5      eUS:X  a  SS/$ U R                  S5      /n[        SUS-   5       H6  nUR                  X-  5        U R                  " U40 UD6nUc  M.  USSS2   s  $    g)a¹  
``findpoly(x, n)`` returns the coefficients of an integer
polynomial `P` of degree at most `n` such that `P(x) \approx 0`.
If no polynomial having `x` as a root can be found,
:func:`~mpmath.findpoly` returns ``None``.

:func:`~mpmath.findpoly` works by successively calling :func:`~mpmath.pslq` with
the vectors `[1, x]`, `[1, x, x^2]`, `[1, x, x^2, x^3]`, ...,
`[1, x, x^2, .., x^n]` as input. Keyword arguments given to
:func:`~mpmath.findpoly` are forwarded verbatim to :func:`~mpmath.pslq`. In
particular, you can specify a tolerance for `P(x)` with ``tol``
and a maximum permitted coefficient size with ``maxcoeff``.

For large values of `n`, it is recommended to run :func:`~mpmath.findpoly`
at high precision; preferably 50 digits or more.

**Examples**

By default (degree `n = 1`), :func:`~mpmath.findpoly` simply finds a linear
polynomial with a rational root::

    >>> from mpmath import *
    >>> mp.dps = 15; mp.pretty = True
    >>> findpoly(0.7)
    [-10, 7]

The generated coefficient list is valid input to ``polyval`` and
``polyroots``::

    >>> nprint(polyval(findpoly(phi, 2), phi), 1)
    -2.0e-16
    >>> for r in polyroots(findpoly(phi, 2)):
    ...     print(r)
    ...
    -0.618033988749895
    1.61803398874989

Numbers of the form `m + n \sqrt p` for integers `(m, n, p)` are
solutions to quadratic equations. As we find here, `1+\sqrt 2`
is a root of the polynomial `x^2 - 2x - 1`::

    >>> findpoly(1+sqrt(2), 2)
    [1, -2, -1]
    >>> findroot(lambda x: x**2 - 2*x - 1, 1)
    2.4142135623731

Despite only containing square roots, the following number results
in a polynomial of degree 4::

    >>> findpoly(sqrt(2)+sqrt(3), 4)
    [1, 0, -10, 0, 1]

In fact, `x^4 - 10x^2 + 1` is the *minimal polynomial* of
`r = \sqrt 2 + \sqrt 3`, meaning that a rational polynomial of
lower degree having `r` as a root does not exist. Given sufficient
precision, :func:`~mpmath.findpoly` will usually find the correct
minimal polynomial of a given algebraic number.

**Non-algebraic numbers**

If :func:`~mpmath.findpoly` fails to find a polynomial with given
coefficient size and tolerance constraints, that means no such
polynomial exists.

We can verify that `\pi` is not an algebraic number of degree 3 with
coefficients less than 1000::

    >>> mp.dps = 15
    >>> findpoly(pi, 3)
    >>>

It is always possible to find an algebraic approximation of a number
using one (or several) of the following methods:

    1. Increasing the permitted degree
    2. Allowing larger coefficients
    3. Reducing the tolerance

One example of each method is shown below::

    >>> mp.dps = 15
    >>> findpoly(pi, 4)
    [95, -545, 863, -183, -298]
    >>> findpoly(pi, 3, maxcoeff=10000)
    [836, -1734, -2658, -457]
    >>> findpoly(pi, 3, tol=1e-7)
    [-4, 22, -29, -2]

It is unknown whether Euler's constant is transcendental (or even
irrational). We can use :func:`~mpmath.findpoly` to check that if is
an algebraic number, its minimal polynomial must have degree
at least 7 and a coefficient of magnitude at least 1000000::

    >>> mp.dps = 200
    >>> findpoly(euler, 6, maxcoeff=10**6, tol=1e-100, maxsteps=1000)
    >>>

Note that the high precision and strict tolerance is necessary
for such high-degree runs, since otherwise unwanted low-accuracy
approximations will be detected. It may also be necessary to set
maxsteps high to prevent a premature exit (before the coefficient
bound has been reached). Running with ``verbose=True`` to get an
idea what is happening can be useful.
r   zn cannot be less than 1r(   Nr)   )r3   r/   r8   Úappendr_   )r<   r	   rA   ÚkwargsÚxsrJ   Úas          r   Úfindpolyre   7  sŠ   € ðR 	�‰�‹
€AØˆ1ƒuÜÐ2Ó3Ð3ØˆAƒvØ�1ˆvˆØ
�'‰'�!‹*ˆ€BÜ�1�Q�q‘SŽ\ˆØ
�	‰	�!‘$ŒØ�HŠH�RÑ"˜6Ñ"ˆØ‹=Ø‘T�r�T‘7ŠNò	 r   c                 ób   • Xp2U(       a  X2U-  p2U(       a  M  US:w  a  X-  n X-  nUS:X  a  U $ X4$ r   r   )ÚpÚqr	   rO   s       r   Úfracgcdri   ¬  sB   € Ø€qÞ
Ø�a‘%ˆ1÷ ˆ!àˆAƒvØ	‰ˆØ	‰ˆØˆAƒvØˆØˆ4€Kr   c                 ó¦  • U S   nU SS  n / n[        [        U 5      5       H~  nX   nU(       d  M  [        U* U5      nX   S   nUS:X  a  SnOSU-   n[        U[        5      (       a  US:”  a  [        U5      U-   nOSU-  U-   nOSU-  U-   nUR                  U5        M€     SR                  U5      nS	U;   d  SU;   a  S
U-   S-   nU=(       d    S$ )Nr(   r   Ú1Ú Ú*z(%s)z(%s/%s)z + Ú+Ú(Ú)Ú0)r8   r.   ri   Ú
isinstancer   Ústrra   Újoin)	ÚrÚ	constantsrh   rL   rJ   rg   ÚzÚcsÚterms	            r   Ú
pslqstringrz   ·  sß   € Ø	ˆ!‰€AØ	ˆ!ˆ"ˆ€AØ
€AÜ”3�q“6Ž]ˆØ‰Dˆßˆ1Ü˜˜˜1“ˆAØ‘˜a‘ˆBØ�S‹yØ‘à˜2‘X�Ü˜!œY×'Ñ'Ø�q“5¤ Q£¨"¡™$Ø"(¨1¡*°Ñ!2™$à! A™¨Ñ+�Ø�H‰H�TŽNñ ð 	�
‰
�1‹€AØ
ˆaƒx�3˜!“8Ø�!‰G�c‰MˆØ�8�€Or   c                 óN  • U S   nU SS  n / n/ n[        [        U 5      5       H¯  nX   nU(       d  M  [        U* U5      nX   S   n[        U[        5      (       a>  [        U5      S:X  a  Un	OU< S[        U5      < 3n	X4/US:     R                  U	5        Mw  U< S[        US   5      < SUS   < S3n	X4/US   S:     R                  U	5        M±     SR                  U5      nSR                  U5      nU(       a  U(       a  SU< S	U< S3$ U(       a  U$ U(       a  S
U-  $ g )Nr(   r   z**z**(Ú/rp   rm   ro   z)/(z1/(%s))r8   r.   ri   rr   r   r   ra   rt   )
ru   rv   rh   ÚnumÚdenrJ   rg   rw   rx   rN   s
             r   Ú
prodstringr   Ï  s  € Ø	ˆ!‰€AØ	ˆ!ˆ"ˆ€AØ
€CØ
€CÜ”3�q“6Ž]ˆØ‰Dˆßˆ1Ü˜˜˜1“ˆAØ‘˜a‘ˆBÜ˜!œY×'Ñ'Ü�q“6˜Q“; B¡Û02´C¸µFÐ$; Ø�˜1˜Q™3‘×'Ñ'¨Ö*ã%'¬¨Q¨q©T®°A°a´DÐ9�Ø�˜1˜Q™4 ™6Ñ"×*Ñ*¨1Ö-ñ ð �(‰(�3‹-€CØ
�(‰(�3‹-€CÞ
�s«#«sÐ3Ð3Þ
�3ˆJÞ
�8˜c‘>Ð!€sr   c                 óì  • US:  a  U* U* U* pCnU* U R                  US-  SU-  U-  -
  5      -   SU-  -  nU* U R                  US-  SU-  U-  -
  5      -
  SU-  -  n[        XQ-
  5      [        Xa-
  5      :  a?  U(       a!  SU* < SUS-  SU-  U-  -
  < SSU-  < S3nU$ SS	U-  U-  < S
SU-  < S3n U$ U(       a!  SU* < SUS-  SU-  U-  -
  < SSU-  < S3nU$ SS	U-  U-  < S
SU-  < S3nU$ )Nr(   r   r&   z((z+sqrt(z))/rp   z(sqrt(éüÿÿÿz)/z-sqrt(z(-sqrt()Úsqrtr   )r<   rN   rd   ÚbÚcÚu1Úu2rL   s           r   Úquadraticstringr‡   æ  s"  € Øˆ1ƒuØ��A�2�q�bˆAˆØˆ"ˆS�X‰X�a˜‘d˜1˜Q™3˜q™5‘jÓ!Ñ
! A a¡CÑ	(€BØˆ"ˆS�X‰X�a˜‘d˜1˜Q™3˜q™5‘jÓ!Ñ
! A a¡CÑ	(€BÜ
ˆ2‰4ƒy”3�r‘t“9Óß¨A«2¨a°©d°1°Q±3°q±5¬j¸¸1¼Ð=ˆqð
 €Hð Ø&(¨¡d¨1¤f¨Q¨q¬SÐ1‰qð €H÷ ¨A«2¨a°©d°1°Q±3°q±5¬j¸¸1¼Ð=ˆqà€Hð Ø')¨!¡t¨A¤v¨a°¬cÐ2ˆqØ€Hr   c                 ó
   • X-  $ r   r   ©r<   r	   r„   s      r   Ú<lambda>rŠ   ÷  ó   € �1’3r   z$y/$cr(   c                 ó
   • X-  $ r   r   r‰   s      r   rŠ   rŠ   ø  r‹   r   z$c*$yc                 ó
   • X!-  $ r   r   r‰   s      r   rŠ   rŠ   ù  r‹   r   z$c/$yc                 ó   • X-  S-  $ ©Nr   r   r‰   s      r   rŠ   rŠ   ú  ó
   € �A‘C˜!’8r   zsqrt($y)/$cc                 ó   • X-  S-  $ r�   r   r‰   s      r   rŠ   rŠ   û  r�   r   z$c*sqrt($y)c                 ó   • X!-  S-  $ r�   r   r‰   s      r   rŠ   rŠ   ü  r�   r   z$c/sqrt($y)c                 ó   • X!S-  -  $ r�   r   r‰   s      r   rŠ   rŠ   ý  ó
   € �1˜‘T’6r   zsqrt($y)/sqrt($c)c                 ó   • US-  U-  $ r�   r   r‰   s      r   rŠ   rŠ   þ  s   € �1�a‘4˜’6r   zsqrt($c)*sqrt($y)c                 ó   • X!S-  -  $ r�   r   r‰   s      r   rŠ   rŠ   ÿ  r”   r   zsqrt($c)/sqrt($y)c                 ó(   • U R                  X-  5      $ r   ©r‚   r‰   s      r   rŠ   rŠ      ó   € �3—8‘8˜A™C”=r   z$y**2/$cc                 ó(   • U R                  X-  5      $ r   r˜   r‰   s      r   rŠ   rŠ     r™   r   z$c*$y**2c                 ó(   • U R                  X!-  5      $ r   r˜   r‰   s      r   rŠ   rŠ     r™   r   z$c/$y**2c                 ó(   • X R                  U5      -  $ r   r˜   r‰   s      r   rŠ   rŠ     ó   € �1—X‘X˜a“[’=r   z$y**2/$c**2c                 ó*   • U R                  U5      U-  $ r   r˜   r‰   s      r   rŠ   rŠ     s   € �3—8‘8˜A“;˜q’=r   z$c**2*$y**2c                 ó(   • X R                  U5      -  $ r   r˜   r‰   s      r   rŠ   rŠ     r�   r   z$c**2/$y**2c                 ó(   • U R                  X-  5      $ r   ©Úexpr‰   s      r   rŠ   rŠ     ó   € �3—7‘7˜1™3”<r   z
log($y)/$cc                 ó(   • U R                  X-  5      $ r   r¡   r‰   s      r   rŠ   rŠ     r£   r   z
$c*log($y)c                 ó(   • U R                  X!-  5      $ r   r¡   r‰   s      r   rŠ   rŠ     r£   r   z
$c/log($y)c                 ó(   • X R                  U5      -  $ r   r¡   r‰   s      r   rŠ   rŠ   	  ó   € �1—W‘W˜Q“Z’<r   z
log($y/$c)c                 ó*   • U R                  U5      U-  $ r   r¡   r‰   s      r   rŠ   rŠ   
  s   € �3—7‘7˜1“:˜a’<r   z
log($c*$y)c                 ó(   • X R                  U5      -  $ r   r¡   r‰   s      r   rŠ   rŠ     r§   r   z
log($c/$y)c                 ó(   • U R                  X-  5      $ r   ©Úlnr‰   s      r   rŠ   rŠ     ó   € �3—6‘6˜!™#”;r   z
exp($y)/$cc                 ó(   • U R                  X-  5      $ r   r«   r‰   s      r   rŠ   rŠ     r­   r   z
$c*exp($y)c                 ó(   • U R                  X!-  5      $ r   r«   r‰   s      r   rŠ   rŠ     r­   r   z
$c/exp($y)c                 ó(   • X R                  U5      -  $ r   r«   r‰   s      r   rŠ   rŠ     ó   € �1—V‘V˜A“Y’;r   z
exp($y/$c)c                 ó*   • U R                  U5      U-  $ r   r«   r‰   s      r   rŠ   rŠ     s   € �3—6‘6˜!“9˜Q’;r   z
exp($c*$y)c                 ó(   • X R                  U5      -  $ r   r«   r‰   s      r   rŠ   rŠ     r±   r   z
exp($c/$y)c           
      óÀ  ^ ^^^• / mUU4S jnT R                  U5      nUS:X  a  U(       a  S/$ gUS:  a<  T R                  U* X#XET5      nUc  U$ U(       a  U V	s/ s H  n	SU	-  PM
     sn	$ SU-  $ U(       a  T R                  U5      nOT R                  S-  nUn
U(       a�  [        U[        5      (       a?  [        UR                  5       5       VVs/ s H  u  p¼T R                  U5      U4PM     nnnO>[	        U 4S j[        T 5       5       5      nU Vs/ s H  n[        Xí5      U4PM     nnO/ nSU VVs/ s H  u  p¿UPM	     snn;  a  T R                  S5      S	4/U-   n[         GH²  u  nnnU GH£  u  nnU(       a  US	:X  a  M  U" T UU5      n[        U5      U
S
-  :”  d  [        U5      U:  a  MC  T R                  U/U Vs/ s H  nUS   PM
     sn-   X:5      nSn	Ub-  [        S U 5       5      U
::  a  US   (       a  [        UU5      n	OT R                  T R                  UUS
-  /X:5      nUbZ  [        U5      S:X  aK  US
   (       aA  Uu  nnn[        [        U5      [        U5      [        U5      5      U
::  a  [!        T UUUU5      n	U	(       ai  US	:X  a)  SU;   a#  UR#                  SU	5      R#                  SS5      n	O"UR#                  SU	5      R#                  SU5      n	U" U	5        U(       d	  TS   s  s  $ T(       d  GM˜  [%        S5        GM¦     GMµ     US:w  aû  / SQn/ nU HE  u  mn	['        UU 4S jU 5       5      (       a  M#  UR)                  T R+                  T5      U	45        MG     U Vs/ s H  nT R+                  U5      [-        U5      4PM!     snU-   nT R                  T R+                  U5      /U Vs/ s H  nUS   PM
     sn-   X:5      nUb>  [        S U 5       5      U
::  a(  US   (       a  U" [/        UU5      5        U(       d  TS   $ U(       a  [        T[        S9$ gs  sn	f s  snnf s  snf s  snnf s  snf s  snf s  snf )aÆ  
Given a real number `x`, ``identify(x)`` attempts to find an exact
formula for `x`. This formula is returned as a string. If no match
is found, ``None`` is returned. With ``full=True``, a list of
matching formulas is returned.

As a simple example, :func:`~mpmath.identify` will find an algebraic
formula for the golden ratio::

    >>> from mpmath import *
    >>> mp.dps = 15; mp.pretty = True
    >>> identify(phi)
    '((1+sqrt(5))/2)'

:func:`~mpmath.identify` can identify simple algebraic numbers and simple
combinations of given base constants, as well as certain basic
transformations thereof. More specifically, :func:`~mpmath.identify`
looks for the following:

    1. Fractions
    2. Quadratic algebraic numbers
    3. Rational linear combinations of the base constants
    4. Any of the above after first transforming `x` into `f(x)` where
       `f(x)` is `1/x`, `\sqrt x`, `x^2`, `\log x` or `\exp x`, either
       directly or with `x` or `f(x)` multiplied or divided by one of
       the base constants
    5. Products of fractional powers of the base constants and
       small integers

Base constants can be given as a list of strings representing mpmath
expressions (:func:`~mpmath.identify` will ``eval`` the strings to numerical
values and use the original strings for the output), or as a dict of
formula:value pairs.

In order not to produce spurious results, :func:`~mpmath.identify` should
be used with high precision; preferably 50 digits or more.

**Examples**

Simple identifications can be performed safely at standard
precision. Here the default recognition of rational, algebraic,
and exp/log of algebraic numbers is demonstrated::

    >>> mp.dps = 15
    >>> identify(0.22222222222222222)
    '(2/9)'
    >>> identify(1.9662210973805663)
    'sqrt(((24+sqrt(48))/8))'
    >>> identify(4.1132503787829275)
    'exp((sqrt(8)/2))'
    >>> identify(0.881373587019543)
    'log(((2+sqrt(8))/2))'

By default, :func:`~mpmath.identify` does not recognize `\pi`. At standard
precision it finds a not too useful approximation. At slightly
increased precision, this approximation is no longer accurate
enough and :func:`~mpmath.identify` more correctly returns ``None``::

    >>> identify(pi)
    '(2**(176/117)*3**(20/117)*5**(35/39))/(7**(92/117))'
    >>> mp.dps = 30
    >>> identify(pi)
    >>>

Numbers such as `\pi`, and simple combinations of user-defined
constants, can be identified if they are provided explicitly::

    >>> identify(3*pi-2*e, ['pi', 'e'])
    '(3*pi + (-2)*e)'

Here is an example using a dict of constants. Note that the
constants need not be "atomic"; :func:`~mpmath.identify` can just
as well express the given number in terms of expressions
given by formulas::

    >>> identify(pi+e, {'a':pi+2, 'b':2*e})
    '((-2) + 1*a + (1/2)*b)'

Next, we attempt some identifications with a set of base constants.
It is necessary to increase the precision a bit.

    >>> mp.dps = 50
    >>> base = ['sqrt(2)','pi','log(2)']
    >>> identify(0.25, base)
    '(1/4)'
    >>> identify(3*pi + 2*sqrt(2) + 5*log(2)/7, base)
    '(2*sqrt(2) + 3*pi + (5/7)*log(2))'
    >>> identify(exp(pi+2), base)
    'exp((2 + 1*pi))'
    >>> identify(1/(3+sqrt(2)), base)
    '((3/7) + (-1/7)*sqrt(2))'
    >>> identify(sqrt(2)/(3*pi+4), base)
    'sqrt(2)/(4 + 3*pi)'
    >>> identify(5**(mpf(1)/3)*pi*log(2)**2, base)
    '5**(1/3)*pi*log(2)**2'

An example of an erroneous solution being found when too low
precision is used::

    >>> mp.dps = 15
    >>> identify(1/(3*pi-4*e+sqrt(8)), ['pi', 'e', 'sqrt(2)'])
    '((11/25) + (-158/75)*pi + (76/75)*e + (44/15)*sqrt(2))'
    >>> mp.dps = 50
    >>> identify(1/(3*pi-4*e+sqrt(8)), ['pi', 'e', 'sqrt(2)'])
    '1/(3*pi + (-4)*e + 2*sqrt(2))'

**Finding approximate solutions**

The tolerance ``tol`` defaults to 3/4 of the working precision.
Lowering the tolerance is useful for finding approximate matches.
We can for example try to generate approximations for pi::

    >>> mp.dps = 15
    >>> identify(pi, tol=1e-2)
    '(22/7)'
    >>> identify(pi, tol=1e-3)
    '(355/113)'
    >>> identify(pi, tol=1e-10)
    '(5**(339/269))/(2**(64/269)*3**(13/269)*7**(92/269))'

With ``full=True``, and by supplying a few base constants,
``identify`` can generate almost endless lists of approximations
for any number (the output below has been truncated to show only
the first few)::

    >>> for p in identify(pi, ['e', 'catalan'], tol=1e-5, full=True):
    ...     print(p)
    ...  # doctest: +ELLIPSIS
    e/log((6 + (-4/3)*e))
    (3**3*5*e*catalan**2)/(2*7**2)
    sqrt(((-13) + 1*e + 22*catalan))
    log(((-6) + 24*e + 4*catalan)/e)
    exp(catalan*((-1/5) + (8/15)*e))
    catalan*(6 + (-6)*e + 15*catalan)
    sqrt((5 + 26*e + (-3)*catalan))/e
    e*sqrt(((-27) + 2*e + 25*catalan))
    log(((-1) + (-11)*e + 59*catalan))
    ((3/20) + (21/20)*e + (3/20)*catalan)
    ...

The numerical values are roughly as close to `\pi` as permitted by the
specified tolerance:

    >>> e/log(6-4*e/3)
    3.14157719846001
    >>> 135*e*catalan**2/98
    3.14166950419369
    >>> sqrt(e-13+22*catalan)
    3.14158000062992
    >>> log(24*e-6+4*catalan)-1
    3.14158791577159

**Symbolic processing**

The output formula can be evaluated as a Python expression.
Note however that if fractions (like '2/3') are present in
the formula, Python's :func:`~mpmath.eval()` may erroneously perform
integer division. Note also that the output is not necessarily
in the algebraically simplest form::

    >>> identify(sqrt(2))
    '(sqrt(8)/2)'

As a solution to both problems, consider using SymPy's
:func:`~mpmath.sympify` to convert the formula into a symbolic expression.
SymPy can be used to pretty-print or further simplify the formula
symbolically::

    >>> from sympy import sympify # doctest: +SKIP
    >>> sympify(identify(sqrt(2))) # doctest: +SKIP
    2**(1/2)

Sometimes :func:`~mpmath.identify` can simplify an expression further than
a symbolic algorithm::

    >>> from sympy import simplify # doctest: +SKIP
    >>> x = sympify('-1/(-3/2+(1/2)*5**(1/2))*(3/2-1/2*5**(1/2))**(1/2)') # doctest: +SKIP
    >>> x # doctest: +SKIP
    (3/2 - 5**(1/2)/2)**(-1/2)
    >>> x = simplify(x) # doctest: +SKIP
    >>> x # doctest: +SKIP
    2/(6 - 2*5**(1/2))**(1/2)
    >>> mp.dps = 30 # doctest: +SKIP
    >>> x = sympify(identify(x.evalf(30))) # doctest: +SKIP
    >>> x # doctest: +SKIP
    1/2 + 5**(1/2)/2

(In fact, this functionality is available directly in SymPy as the
function :func:`~mpmath.nsimplify`, which is essentially a wrapper for
:func:`~mpmath.identify`.)

**Miscellaneous issues and limitations**

The input `x` must be a real number. All base constants must be
positive real numbers and must not be rationals or rational linear
combinations of each other.

The worst-case computation time grows quickly with the number of
base constants. Already with 3 or 4 base constants,
:func:`~mpmath.identify` may require several seconds to finish. To search
for relations among a large number of constants, you should
consider using :func:`~mpmath.pslq` directly.

The extended transformations are applied to x, not the constants
separately. As a result, ``identify`` will for example be able to
recognize ``exp(2*pi+3)`` with ``pi`` given as a base constant, but
not ``2*exp(pi)+3``. It will be able to recognize the latter if
``exp(pi)`` is given explicitly as a base constant.

c                 óN   >• T(       a  [        SU 5        TR                  U 5        g )NzFound: )r1   ra   )rL   Ú	solutionsr@   s    €€r   ÚaddsolutionÚidentify.<locals>.addsolutionë  s   ø€ Þ”E˜) QÔ'Ø×Ñ˜Õr   r(   rq   Nz-(%s)gffffffæ?c              3   ó>   >#   • U  H  o[        TU5      4v •  M     g 7fr   )Úgetattr)r    Únamer<   s     €r   r"   Úidentify.<locals>.<genexpr>  s   øé € ÐLÂ8¸4¤G¨C°Ó$5Õ6Â8ùs   ƒr   rk   r   c              3   ó8   #   • U  H  n[        U5      v •  M     g 7fr   r   ©r    Úuws     r   r"   r¼     s   é € Ð$9²q°¤S¨§W W²qùr$   r'   z/$cz$yrl   z$cÚ.)r   r'   r   é   c           	   3   óœ   >#   • U  HA  n[        TR                  TR                  T5      TR                  U5      -  S 5      5      v •  MC     g7f)r   N)Úboolre   r¬   )r    rJ   rd   r<   s     €€r   r"   r¼   8  s9   øé € ÐPÊ%ÀQ”t˜CŸL™L¨¯©°«°3·6±6¸!³9Ñ)<¸QÓ?×@Ð@Ê%ùs   ƒA	Ac              3   ó8   #   • U  H  n[        U5      v •  M     g 7fr   r   r¾   s     r   r"   r¼   <  s   é € Ð 5²1¨R¤ R§ ²1ùr$   )Úkey)r3   ÚidentifyÚepsrr   ÚdictÚsortedÚitemsÚdirÚevalÚ
transformsr   r_   r0   rz   Úoner.   r‡   Úreplacer1   Úsumra   r¬   rs   r   ) r<   r	   rv   r=   r>   Úfullr@   r·   ÚsolrL   ÚMr»   r+   Ú	namespacerg   ÚvalueÚftÚftnÚredr„   ÚcnrN   rd   ru   rh   ÚaaÚbbÚccÚilogsÚlogsrJ   r¶   s    `     `               `        @r   rÆ   rÆ     sô  û€ ðj €Iöð 	�‰�‹
€Að 	ˆAƒvÞ˜˜�ØØˆ1ƒuØ�l‰l˜A˜2˜y¨x¸wÓGˆØ‰;ØˆJÞÙ'*Ó+¢s !�G˜A”I¡sÑ+Ð+à˜S‘=Ð æ
Ø�g‰g�c‹l‰à�g‰g�s‰lˆØ€AæÜ�i¤×&Ñ&Ü=CÀIÇOÁOÓDUÔ=VÔWÒ=V±	°˜#Ÿ'™' !›* dÓ+Ñ=VˆIÑWˆIäÔLÄ3ÀsÄ8ÓLÓLˆIÙ:CÓDº)°Qœ$˜qÓ,¨aÓ0¹)ˆIÐDˆIàˆ	ð 	©IÔ6ªI™=˜D“©IÒ6Ó6Ø—g‘g˜a“j #Ð&Ð'¨)Ñ3ˆ	÷ #˜
‰ˆˆC�Ü‰EˆAˆrÞ�r˜S“yÙÙ�3�q˜“ˆAä�1‹v˜˜1™‹}¤ A£¨£Ùà—‘˜!˜©iÓ8ªi¨  !¤©iÑ8Ñ8¸#ÓAˆAØˆAØ‰}¤Ñ$9±qÓ$9Ó!9¸QÓ!>À1ÀQÇ4Ü˜q )Ó,‘ð —H‘H˜cŸg™g q¨!¨Q©$Ð/°Ó8�Ø‘=¤S¨£V¨q£[°Q°q·TØ!"‘J�B˜˜BÜœ3˜r›7¤3 r£7¬3¨r«7Ó3°qÓ8Ü+¨C°°"°R¸Ó;˜ÞØ˜“9 %¨3£,ØŸ™ D¨!Ó,×4Ñ4°U¸BÓ?‘AàŸ™ D¨!Ó,×4Ñ4°T¸2Ó>�AÙ˜A”Þ I¨a¡LÔ0ç‰wÜ�c—
ô9 ñ #ð@ 	ˆAƒvâˆàˆÛ‰DˆAˆqÜÕPÉ%ÓP×PÓPØ—‘˜SŸV™V A›Y¨˜NÖ+ñ ñ -2Ó2ªE q�—‘˜“œ3˜q›6Ó"©EÑ2°TÑ9ˆØ�H‰H�c—f‘f˜Q“i�[±$Ó#7²$¨Q A a¤D±$Ñ#7Ñ7¸Ó@ˆØ‰=œSÑ 5±1Ó 5Ó5¸Ó:¸qÀ¿tÙœ
 1 dÓ+Ô,Þ 	¨!¡Ð,æÜ�i¤SÑ)Ð)àùòS ,ùó Xùò Eùó
 7ùò  9ùò> 3ùÚ#7s*   ÁP;ÃQ ÄQÄ;QÇQÍ?&QÏQ
Ú__main__)Nr   r%   F)r   )Ú__doc__Úlibmp.backendr   Úlibmpr   r   r   Úobjectr   r_   re   ri   rz   r   r‡   rÍ   rÆ   r   ÚdoctestÚtestmodr   r   r   Ú<module>ræ      s­  ðñõ
 "ß (ò1ô	˜Fô 	ôdôL	sòj	òò0"ò.ñ" ˜ Ð#Ù˜ Ð#Ù˜ Ð#Ù˜]¨AÐ.Ù˜]¨AÐ.Ù˜]¨AÐ.ÙÐ.°Ð2ÙÐ.°Ð2ÙÐ.°Ð2Ù  *¨aÐ0Ù  *¨aÐ0Ù  *¨aÐ0Ù  -°Ð3Ù  -°Ð3Ù  -°Ð3Ù ¨qÐ1Ù ¨qÐ1Ù ¨qÐ1Ù ¨qÐ1Ù ¨qÐ1Ù ¨qÐ1Ù ¨aÐ0Ù ¨aÐ0Ù ¨aÐ0Ù ¨aÐ0Ù ¨aÐ0Ù ¨aÐ0ð7€
ð<  " t°dÀØôoðb	 "Ð Ô Ø!)Ð Ô Ø!)Ð Ô ð ˆzÓÛØ‡O‚OÕð r   