B
    [}                 @   s   d dl mZmZmZ d dlmZmZmZmZm	Z	m
Z
mZmZmZmZ d dlmZmZmZmZmZmZmZmZmZmZmZmZ dddZd	d
 Zdde fddZdS )    )absolute_importdivisionprint_function)
AndGtLtAbsDummyooTupleSymbolFunctionPow)
AssignmentAddAugmentedAssignment	CodeBlockDeclarationFunctionDefinitionPrintReturnScopeWhileVariablePointerreal-q=NFc             C   s  |dkrt  }t}d}ndd }|j}|  | | }	t||	t||g}
|r~t||gd|j|}|
d |g|
dd  }
tt	||}t
t|ttdg}|dk	r|pt d	d
}t|d}|t
| |
t|d t|t||}t|t|
 }||g }|t| S )aX   Generates an AST for Newton-Raphson method (a root-finding algorithm).

    Returns an abstract syntax tree (AST) based on ``sympy.codegen.ast`` for Netwon's
    method of root-finding.

    Parameters
    ==========

    expr : expression
    wrt : Symbol
        With respect to, i.e. what is the variable.
    atol : number or expr
        Absolute tolerance (stopping criterion)
    delta : Symbol
        Will be a ``Dummy`` if ``None``.
    debug : bool
        Whether to print convergence information during iterations
    itermax : number or expr
        Maximum number of iterations.
    counter : Symbol
        Will be a ``Dummy`` if ``None``.

    Examples
    ========

    >>> from sympy import symbols, cos
    >>> from sympy.codegen.ast import Assignment
    >>> from sympy.codegen.algorithms import newtons_method
    >>> x, dx, atol = symbols('x dx atol')
    >>> expr = cos(x) - x**3
    >>> algo = newtons_method(expr, x, atol, dx)
    >>> algo.has(Assignment(dx, -expr/expr.diff(x)))
    True

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Newton%27s_method

    Ndeltac             S   s   | S )N )xr   r   7lib/python3.7/site-packages/sympy/codegen/algorithms.py<lambda>;   s    z newtons_method.<locals>.<lambda>z{0}=%12.5g {1}=%12.5g\nr      )typevalueT)Zinteger)r	   r   nameZdiffr   r   r   formatr   r   r   r   r   r
   Zdeducedappendr   r   r   r   )exprwrtZatolr   debugZitermaxZcounterZWrapperZname_dZ
delta_exprZwhl_bdyZprntZreqdeclarsZ	v_counterZwhlZblckr   r   r   newtons_method   s,    +
r+   c             C   s(   t | tr| jj} nt | tr$| j} | S )N)
isinstancer   Zvariablesymbolr   )argr   r   r   
_symbol_ofP   s
    


r/   Znewtonc             K   s   |dkr|f}dd |D }| dd}|dkrLtd|j }| |rLd}t| |fd|i||}t|trx|j}| j	
tdd |D }	|	rtdd	tt|	 td
d |D }
t|t|}tt||
||dS )a   Generates an AST for a function implementing the Newton-Raphson method.

    Parameters
    ==========

    expr : expression
    wrt : Symbol
        With respect to, i.e. what is the variable
    params : iterable of symbols
        Symbols appearing in expr that are taken as constants during the iterations
        (these will be accepted as parameters to the generated function).
    func_name : str
        Name of the generated function.
    attrs : Tuple
        Attribute instances passed as ``attrs`` to ``FunctionDefinition``.
    \*\*kwargs :
        Keyword arguments passed to :func:`sympy.codegen.algorithms.newtons_method`.

    Examples
    ========

    >>> from sympy import symbols, cos
    >>> from sympy.codegen.algorithms import newtons_method_function
    >>> from sympy.codegen.pyutils import render_as_module
    >>> from sympy.core.compatibility import exec_
    >>> x = symbols('x')
    >>> expr = cos(x) - x**3
    >>> func = newtons_method_function(expr, x)
    >>> py_mod = render_as_module(func)  # source code as string
    >>> namespace = {}
    >>> exec_(py_mod, namespace, namespace)
    >>> res = eval('newton(0.5)', namespace)
    >>> abs(res - 0.865474033102) < 1e-12
    True

    See also
    ========
    - sympy.codegen.ast.newtons_method

    Nc             S   s*   i | ]"}t |trtd |jj |jqS )z(*%s))r,   r   r   r-   r$   ).0pr   r   r   
<dictcomp>   s   z+newtons_method_function.<locals>.<dictcomp>r   Zd_c             s   s   | ]}t |V  qd S )N)r/   )r0   r1   r   r   r   	<genexpr>   s    z*newtons_method_function.<locals>.<genexpr>zMissing symbols in params: %sz, c             s   s   | ]}t |tV  qd S )N)r   r   )r0   r1   r   r   r   r3      s    )attrs)popr   r$   Zhasr+   Zxreplacer,   r   bodyZfree_symbols
differenceset
ValueErrorjoinmapstrtupler   r   r   r   )r'   r(   ZparamsZ	func_namer4   kwargsZpointer_subsr   ZalgoZnot_in_paramsr*   r6   r   r   r   newtons_method_functionX   s$    )

r?   )r   NFNN)Z
__future__r   r   r   Zsympyr   r   r   r   r	   r
   r   r   r   r   Zsympy.codegen.astr   r   r   r   r   r   r   r   r   r   r   r   r+   r/   r?   r   r   r   r   <module>   s   08 
D