+
    iEr                        R t ^RIHt ^RIHtHt R t ! R R]4      tRGR	 lt	RHR
 lt
R tR tR tR tR R^ 3R R^3R R^ 3R R^ 3R R^3R R^ 3R R^3R R^3R R ^3R! R"^ 3R# R$^3R% R&^ 3R' R(^3R) R*^3R+ R,^3R- R.^ 3R/ R0^3R1 R2^ 3R3 R4^3R5 R6^3R7 R8^ 3R9 R:^ 3R; R<^3R= R>^ 3R? R@^3RA RB^3RC RD^ 3.t. RRRR3RE lt]	]n	        ]
]n
        ]]n        ]RF8X  d   ^ RIt]P&                  ! 4        R# R# )Izs
Implements the PSLQ algorithm for integer relation detection,
and derivative algorithms for constant recognition.
)xrange)	int_types
sqrt_fixedc                 L    V ^V^,
          ,          ,           V,	          V,          #     )xprecs   &&u/Users/tonyclaw/.openclaw/workspace/skills/math-calculator/venv/lib/python3.14/site-packages/mpmath/identification.pyround_fixedr   
   s    !d1f+4'D00    c                       ] tR t^tRtR# )IdentificationMethodsr   N)__name__
__module____qualname____firstlineno____static_attributes__r   r   r   r   r      s    r   r   N  Fc                   \        V4      pV^8  d   \        R4      hV P                  pV^58  d   \        R4      hV'       d$   V\        ^V4      ,          ^8  d   \	        R4       \        VR,          4      pVf   V P                  ^4      V) ,          pMV P                  V4      p^<p	Wy,          pV'       d#   \	        RWpP                  V4      3,          4       V P                  W'4      pV'       g   Q hR.V U
u. uF#  qP                  V P                  V
4      V4      NK%  	  up
,           p\        R VR,           4       4      pV'       g   \        R	4      hW^d,          8  d   V'       d   \	        R
4       R# \        ^V,          ^,          V4      p/ p/ p/ p\        ^V^,           4       F<  p\        ^V^,           4       F"  pVV8H  V,          ;VVV3&   VVV3&   ^ VVV3&   K$  	  K>  	  R.^ .V,          ,           p\        ^V^,           4       FL  p^ p\        VV^,           4       F!  pVVV,          ^,          V,	          ,          pK#  	  \        VV4      VV&   KN  	  V^,          pVR,          p\        ^V^,           4       F7  pVV,          V,          V,          VV&   VV,          V,          V,          VV&   K9  	  \        ^V^,           4       F  p\        V^,           V4       F
  p^ VVV3&   K  	  VV^,
          8:  dB   VV,          '       d,   VV^,           ,          V,          VV,          ,          VVV3&   M^ VVV3&   \        ^V4       F]  pVV,          VV^,           ,          ,          pV'       d.   VV,          ) VV,          ,          V,          V,          VVV3&   KV  ^ VVV3&   K_  	  K  	  \        ^V^,           4       EFG  p\        V^,
          ^ R4       EF*  pVVV3,          '       d.   \        VVV3,          V,          VVV3,          ,          V4      pMKD  VV,          VVV,          ,          V,	          ,           VV&   \        ^V^,           4       F1  pVVV3,          VVVV3,          ,          V,	          ,
          VVV3&   K3  	  \        ^V^,           4       F_  pVVV3,          VVVV3,          ,          V,	          ,
          VVV3&   VVV3,          VVVV3,          ,          V,	          ,           VVV3&   Ka  	  EK-  	  EKJ  	  \        V4       EF  pRpRp\        ^V4       FI  pVVV3,          pVV,          \        V4      ,          VV^,
          ,          ,	          pVV8  g   KE  TpTpKK  	  VV^,           ,          VV,          uVV&   VV^,           &   \        ^V^,           4       F2  pVV^,           V3,          VVV3,          uVVV3&   VV^,           V3&   K4  	  \        ^V^,           4       F2  pVV^,           V3,          VVV3,          uVVV3&   VV^,           V3&   K4  	  \        ^V^,           4       F2  pVVV^,           3,          VVV3,          uVVV3&   VVV^,           3&   K4  	  VV^,
          8:  Ed   \        VVV3,          ^,          VVV^,           3,          ^,          ,           V,	          V4      pV'       g    EMVVV3,          V,          V,          pVVV^,           3,          V,          V,          p\        VV^,           4       Fn  pVVV3,          pVVV^,           3,          p VV,          VV ,          ,           V,	          VVV3&   V) V,          VV ,          ,           V,	          VVV^,           3&   Kp  	  \        V^,           V^,           4       EFE  p\        \        V^,
          V^,           4      ^ R4       EF  p \        VVV3,          V,          VVV3,          ,          V4      pTT,          TTT,          ,          T,	          ,           TT&   \        ^T^,           4       F1  pTTT3,          TTTT3,          ,          T,	          ,
          TTT3&   K3  	  \        ^T^,           4       F_  pTTT3,          TTTT3,          ,          T,	          ,
          TTT3&   TTT3,          TTTT3,          ,          T,	          ,           TTT3&   Ka  	  EK  	  EKH  	  W7,          p!\        ^V^,           4       F  p\        VV,          4      p"V"V8  d   \        ^V^,           4       Uu. uF(  p\        \        VVV3,          V4      V,	          4      NK*  	  p#p\        R V# 4       4      V8  dP   V'       dB   \	        RVW@P                  V"V P                  ^4      V,          ,          ^4      3,          4       V#u u # \        V"V!4      p!K  	  \        R VP#                  4        4       4      p$V$'       d)   ^^V,          ,          V$,          V,	          p%V%^d,          p%MV P$                  p%V'       dC   \	        RVW@P                  V!V P                  ^4      V,          ,          ^4      V%3,          4       V%V8  g   EK   M	  V'       d'   \	        RXV3,          4       \	        RX%,          4       R# u up
i   \          d      EK5  i ; iu upi )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 2zprec cannot be less than 53z*Warning: precision for PSLQ may be too lowg      ?NzPSLQ using prec %i and tol %sc              3   8   "   T F  p\        V4      x  K  	  R # 5iNabs).0xxs   & r   	<genexpr>pslq.<locals>.<genexpr>   s     '2s2ww   r   NNz)PSLQ requires a vector of nonzero numbersz#STOPPING: (one number is too small):NNNc              3   8   "   T F  p\        V4      x  K  	  R # 5ir   r   )r   vs   & r   r   r     s     +s!s1vvsr   z'FOUND relation at iter %i/%i, error: %sc              3   8   "   T F  p\        V4      x  K  	  R # 5ir   r   )r   hs   & r   r   r   '  s     1jc!ffjr   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   pslqrW      s	   f 	AA1u233 88Dby67743q8#a':;F
{ggajF7#kk#EMD-xx}0EEF
,,s
!CJ3 
A>Ab,,swwr{D1A>>A '2''DDEE3h78AtGa<&A
A
A
A Aqs^1Q3A !tn,AacFQqsVAacF   
 
!qAAqs^1Q3A!A$'T/"A  !T"!	 
 	
!A	!AAqs^!"!!"!  Aqs^!QAAacF  !8ttAaC&D.QqT1!A#!A#q!AQ4!A#;DaD51:,t3!A#!A#   Aqs^!Q#A1vv1Q34!AaC& 8$? Q41QqT6T>*AaDAqs^1Q31QqsV8t#34!A# $Aqs^1Q31QqsV8t#34!A#1Q31QqsV8t#34!A# $ $  Xq!A!A#AQ$Q-T1Q3Z0BEz  1vqt!a!f!A#A1QqSU8QqsV 0!A#!A#a%!A#A1QqSU8QqsV 0!A#!A#a%!A#A1QqsU8QqsV 0!A#!AaC%A:QqsVQY1QqS514t;TBB AaC&D.R'BAacE(d"r)BAqs^qsVq1uXR%2+$.!A#CF2b5LT1!AaC%	 $ !QqS!AC!QqSM1b1#QqsVt^a!f$<dCA t!A$4/0!1Q3AqsVq1Q3x4'78AacF (1Q3AqsVq1Q3x4'78AacFqsVq1Q3x4'78AacF ( 2 "& >1Q3Aad)CSy a! CDs;q1vt4<=  +s++h6G (HHS3771:t;K5KQ,OPQ RJ3)H    1ahhj111T6]w.47DSLD77D1hCGGAJ4D)Da H$OP Q8[ \ ,X>?BTIJc ?H ) (s   =)k*,k!.k5!k2	1k2	c                2   V P                  V4      pV^8  d   \        R4      hV^ 8X  d   ^^ .# V P                  ^4      .p\        ^V^,           4       F?  pVP                  W,          4       V P                  ! V3/ VB pVf   K3  VRRR1,          u # 	  R# )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.
zn cannot be less than 1Nr%   )r+   r'   r0   appendrW   )r4   r	   r9   kwargsxsrB   as   &&&,   r   findpolyr]   7  s    R 	
A1u233Av1v
''!*B1QqS\
		!$HHR"6"=TrT7N	 r   c                 r    Yr2V'       d   Y2V,          r2K  V^8w  d   W,          p W,          pV^8X  d   V # W3# r   r   )pqr	   rG   s   &&  r   fracgcdra     s;    q
a%1Av		Av4Kr   c                    V ^ ,          pV R,          p . p\        \        V 4      4       F  pW,          pV'       g   K  \        V) V4      pW,          ^,          pVR8X  d   RpM	RV,           p\        V\        4      '       d,   V^ 8  d   \        V4      V,           pM!RV,          V,           pMRV,          V,           pVP                  V4       K  	  RP                  V4      pRV9   g   RV9   d   R	V,           R
,           pT;'       g    R# )    r    1 *z(%s)z(%s/%s)z + +()0)r0   r&   ra   
isinstancer   strrY   join)	r	constantsr`   rD   rB   r_   zcsterms	   &&       r   
pslqstringrs     s    	!A	"A
A3q6]D11AaBSy2X!Y''q5Q"$"(1*!2$!A+HHTN  	

1A
ax3!8!GcM88Or   c                    V ^ ,          pV R,          p . p. p\        \        V 4      4       F  pW,          pV'       g   K  \        V) V4      pW,          ^,          p\        V\        4      '       dD   \        V4      ^8X  d   Tp	MV: R\        V4      : 2p	W4.V^ 8  ,          P                  V	4       K  V: R\        V^ ,          4      : RV^,          : R2p	W4.V^ ,          ^ 8  ,          P                  V	4       K  	  RP                  V4      pRP                  V4      pV'       d   V'       d   RV: RV: R2# V'       d   V# V'       d
   R	V,          # R
# )rc   r    z**z**(/ri   rf   rh   z)/(z1/(%s)N)r0   r&   ra   rk   r   r   rY   rm   )
rn   ro   r`   numdenrB   r_   rp   rq   rF   s
   &&        r   
prodstringrx     s   	!A	"A
C
C3q6]D11AaB!Y''q6Q;B02CF$;1Q3''*%'QqTAaDD91Q46"**1-  ((3-C
((3-C
ss#s33
3J
8c>!sr   c                    V^ 8  d	   V) V) V) rCpV) V P                  V^,          ^V,          V,          ,
          4      ,           ^V,          ,          pV) V P                  V^,          ^V,          V,          ,
          4      ,
          ^V,          ,          p\        WQ,
          4      \        Wa,
          4      8  da   V'       d6   RV) : RV^,          ^V,          V,          ,
          : R^V,          : R2pV# RR	V,          V,          : R^V,          : R2p V# V'       d6   RV) : RV^,          ^V,          V,          ,
          : R^V,          : R2pV# RR	V,          V,          : R^V,          : R2pV# )
rc   z((z+sqrt(z))/ri   z(sqrt(z)/z-sqrt(z(-sqrt()sqrtr   )r4   rF   r\   bcu1u2rD   s   &&&&&   r   quadraticstringr     s6   1uA2qbA"SXXad1Q3q5j!
!AaC	(B"SXXad1Q3q5j!
!AaC	(B
24y3rt91A2ad1Q3q5jj1=q
 H &(d1ffQqSS1q H 1A2ad1Q3q5jj1=qH ')!tAvvacc2qHr   c                     W,          # r   r   r4   r	   r}   s   &&&r   <lambda>r         13r   z$y/$cc                     W,          # r   r   r   s   &&&r   r   r     r   r   z$c*$yc                     W!,          # r   r   r   s   &&&r   r   r     r   r   z$c/$yc                      W,          ^,          #    r   r   s   &&&r   r   r     
    AC!8r   zsqrt($y)/$cc                      W,          ^,          # r   r   r   s   &&&r   r   r     r   r   z$c*sqrt($y)c                      W!,          ^,          # r   r   r   s   &&&r   r   r     r   r   z$c/sqrt($y)c                      W!^,          ,          # r   r   r   s   &&&r   r   r     
    1T6r   zsqrt($y)/sqrt($c)c                 "    V^,          V,          # r   r   r   s   &&&r   r   r     s    1a46r   zsqrt($c)*sqrt($y)c                      W!^,          ,          # r   r   r   s   &&&r   r   r     r   r   zsqrt($c)/sqrt($y)c                 0    V P                  W,          4      # r   r{   r   s   &&&r   r   r          388AC=r   z$y**2/$cc                 0    V P                  W,          4      # r   r   r   s   &&&r   r   r     r   r   z$c*$y**2c                 0    V P                  W!,          4      # r   r   r   s   &&&r   r   r     r   r   z$c/$y**2c                 0    W P                  V4      ,          # r   r   r   s   &&&r   r   r         1XXa[=r   z$y**2/$c**2c                 2    V P                  V4      V,          # r   r   r   s   &&&r   r   r     s    388A;q=r   z$c**2*$y**2c                 0    W P                  V4      ,          # r   r   r   s   &&&r   r   r     r   r   z$c**2/$y**2c                 0    V P                  W,          4      # r   expr   s   &&&r   r   r         37713<r   z
log($y)/$cc                 0    V P                  W,          4      # r   r   r   s   &&&r   r   r     r   r   z
$c*log($y)c                 0    V P                  W!,          4      # r   r   r   s   &&&r   r   r     r   r   z
$c/log($y)c                 0    W P                  V4      ,          # r   r   r   s   &&&r   r   r   	      1WWQZ<r   z
log($y/$c)c                 2    V P                  V4      V,          # r   r   r   s   &&&r   r   r   
  s    3771:a<r   z
log($c*$y)c                 0    W P                  V4      ,          # r   r   r   s   &&&r   r   r     r   r   z
log($c/$y)c                 0    V P                  W,          4      # r   lnr   s   &&&r   r   r         366!#;r   z
exp($y)/$cc                 0    V P                  W,          4      # r   r   r   s   &&&r   r   r     r   r   z
$c*exp($y)c                 0    V P                  W!,          4      # r   r   r   s   &&&r   r   r     r   r   z
$c/exp($y)c                 0    W P                  V4      ,          # r   r   r   s   &&&r   r   r         1VVAY;r   z
exp($y/$c)c                 2    V P                  V4      V,          # r   r   r   s   &&&r   r   r     s    366!9Q;r   z
exp($c*$y)c                 0    W P                  V4      ,          # r   r   r   s   &&&r   r   r     r   r   z
exp($c/$y)c           
     ~	  a aaa . oVV3R lpS P                  V4      pV^ 8X  d   V'       d   R.# R# V^ 8  dF   S P                  V) W#WES4      pVf   V# V'       d   V U	u. uF  p	RV	,          NK  	  up	# RV,          # V'       d   S P                  V4      pMS P                  R,          pTp
V'       d   \        V\        4      '       d?   \        VP                  4       4       UUu. uF  w  rS P                  V4      V3NK  	  pppM=\	        V 3R l\        S 4       4       4      pV Uu. uF  p\        W4      V3NK  	  ppM. p^V UUu. uF  w  rVNK	  	  upp9  d   S P                  ^4      R3.V,           p\         EF  w  pppV EF  w  ppV'       d
   VR8X  d   K  V! S VV4      p\        V4      V
^,          8  g   \        V4      V8  d   KK  S P                  V.V Uu. uF  pV^ ,          NK  	  up,           W:4      pRp	Ve4   \        R V 4       4      V
8:  d   V^ ,          '       d   \        VV4      p	MS P                  S P                  VV^,          .W:4      pVeb   \        V4      ^8X  dR   V^,          '       dC   Vw  ppp\        \        V4      \        V4      \        V4      4      V
8:  d   \!        S VVVV4      p	V	'       dq   VR8X  d+   R	V9   d$   VP#                  R
V	4      P#                  R	R4      p	M"VP#                  R
V	4      P#                  RV4      p	V! V	4       V'       g   S^ ,          u u # S'       g   EK  \%        R4       EK  	  EK  	  V^8w  Ed   . ROp. pV FF  w  op	\'        VV 3R lV 4       4      '       d   K$  VP)                  S P+                  S4      V	34       KH  	  V Uu. uF  pS P+                  V4      \-        V4      3NK!  	  upV,           pS P                  S P+                  V4      .V Uu. uF  pV^ ,          NK  	  up,           W:4      pVeJ   \        R V 4       4      V
8:  d3   V^ ,          '       d$   V! \/        VV4      4       V'       g
   S^ ,          # V'       d   \        S\        R7      # R# u up	i u uppi u upi u uppi u upi u upi u upi )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                 R   < S'       d   \        R V 4       SP                  V 4       R# )zFound: N)r)   rY   )rD   	solutionsr8   s   &r   addsolutionidentify.<locals>.addsolution  s    E)Q'r   rj   Nz-(%s)gffffff?c              3   >   <"   T F  q\        SV4      3x  K  	  R # 5ir   )getattr)r   namer4   s   & r   r   identify.<locals>.<genexpr>  s     L84GC$568s   rd   c              3   8   "   T F  p\        V4      x  K  	  R # 5ir   r   r   uws   & r   r   r     s     $9qSWWqr   z/$cz$yre   z$c.c           	   3      <"   T FE  p\        SP                  SP                  S4      SP                  V4      ,          ^4      4      x  KG  	  R# 5i)r   N)boolr]   r   )r   rB   r\   r4   s   & r   r   r   8  s9     P%QtCLL366!9)<Q?@@%s   AAc              3   8   "   T F  p\        V4      x  K  	  R # 5ir   r   r   s   & r   r   r   <  s      51RR1r   )key)r            )r+   identifyepsrk   dictsorteditemsdireval
transformsr   rW   r(   rs   oner&   r   replacer)   sumrY   r   rl   rx   ) r4   r	   ro   r5   r6   fullr8   r   solrD   Mr   r"   	namespacer_   valueftftnredr}   cnrF   r\   rn   r`   aabbccilogslogsrB   r   s    f&&&&&f               `        @r   r   r     s    j I 	
A 	Av1ullA2yxwG;J'*+s!GAIIs++S= 
ggclggslAi&&=CIOODU=VW=V	#''!*d+=VIWIL3s8LLI:CD)Q$q,a0)IDI	 	I6I=DI66ggaj#&')3	 #
CEArrSy3qA1v1}A!i8i!i88#AAA}$9q$9!9Q!>1Q44q), HHcggq!Q$/8=SVq[QqTT!"JBB3r73r73r73q8+C"R;9%3,D!,44UB?AD!,44T2>AAIaL0wc
9  #@ 	AvDAqP%PPPSVVAYN+  -22Eq3q6"E2T9HHcffQi[$#7$QAaDD$#77@=S 51 55:qtt
1d+,	!,iS))S , X E
 7  9> 3#7s*   !R(R,R%R*)R0%R5R:
__main__)Nr   d   Fr   )__doc__libmp.backendr   libmpr   r   r   objectr   rW   r]   ra   rs   rx   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07
<  "tdob	 "  !)  !)   zOO r   