U
    L?h/                     @   s   d dl mZ d dlmZ d dlmZ d dlmZ d dlm	Z	 d dl
mZ d dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZ dd ZdddZdd ZdddZdd Zdd Zdd ZdS )    Tuple)Basic)Expr)AppliedUndef)
Relational)Dummy)sympify)BooleanFunction)ImageSet)	FiniteSet)Indexedc                 C   sr   t | tttfs| g} tdd | D r.t S t jdd | D  }|jdd | D  }|ppt jdd | D  S )a  Returns the free symbols of a symbolic expression.

    If the expression contains any of these elements, assume that they are
    the "free symbols" of the expression:

    * indexed objects
    * applied undefined function (useful for sympy.physics.mechanics module)
    c                 s   s   | ]}t |V  qd S Ncallable.0e r   F/var/www/html/venv/lib/python3.8/site-packages/sympy/plotting/utils.py	<genexpr>   s     z$_get_free_symbols.<locals>.<genexpr>c                 S   s   g | ]}| tqS r   )atomsr   r   r   r   r   
<listcomp>   s     z%_get_free_symbols.<locals>.<listcomp>c                 S   s   g | ]}| tqS r   )r   r   r   r   r   r   r      s     c                 S   s   g | ]
}|j qS r   free_symbolsr   r   r   r   r      s     )
isinstancelisttuplesetallunion)exprsfreer   r   r   _get_free_symbols   s    	r#   
   c                    sH   |  t}|D ]4}t| t fddtd|D  }| ||} q| S )a  Extract numerical solutions from a set solution (computed by solveset,
    linsolve, nonlinsolve). Often, it is not trivial do get something useful
    out of them.

    Parameters
    ==========

    n : int, optional
        In order to replace ImageSet with FiniteSet, an iterator is created
        for each ImageSet contained in `set_sol`, starting from 0 up to `n`.
        Default value: 10.
    c                    s   g | ]}t  qS r   )next)r   nitr   r   r   1   s     z$extract_solution.<locals>.<listcomp>r   )findr   iterr   rangesubs)Zset_solr&   ZimagesZimsr   r'   r   extract_solution!   s    
r.   c                 C   s   t | tr| S t| } t| D ]f\}}t |ttfrLtt|ddi| |< qt |ttfst	|s|j
jdkrxt |trt|| |< q| S )a  This function recursively loop over the arguments passed to the plot
    functions: the sympify function will be applied to all arguments except
    those of type string/dict.

    Generally, users can provide the following arguments to a plot function:

    expr, range1 [tuple, opt], ..., label [str, opt], rendering_kw [dict, opt]

    `expr, range1, ...` can be sympified, whereas `label, rendering_kw` can't.
    In particular, whenever a special character like $, {, }, ... is used in
    the `label`, sympify will raise an error.
    r	   FZVector)r   r   r   	enumerater   r   _plot_sympifystrdictr   	__class____name__r   r	   )argsiar   r   r   r0   6   s    

r0    Nc                 C   sZ  dd }t | }|dk	r&|| }t||krTtdd| dt|| t||krttdt||f t dd	 |D }t|t|krtd
t||k r||}|t kr|D ]}	|||	 qt	|t| D ]}
||t
  qt||krVt dd	 |D }t||dkrVtdd| d| |S )a  This function does two things:

    1. Check if the number of free symbols is in agreement with the type of
       plot chosen. For example, plot() requires 1 free symbol;
       plot3d() requires 2 free symbols.
    2. Sometime users create plots without providing ranges for the variables.
       Here we create the necessary ranges.

    Parameters
    ==========

    exprs : iterable
        The expressions from which to extract the free symbols
    ranges : iterable
        The limiting ranges provided by the user
    npar : int
        The number of free symbols required by the plot functions.
        For example,
        npar=1 for plot, npar=2 for plot3d, ...
    params : dict
        A dictionary mapping symbols to parameters for interactive plot.
    c                 S   s   t | ddS )Nir$   r   )symbolr   r   r   <lambda>l       z _create_ranges.<locals>.<lambda>NzToo many free symbols.
zExpected {} free symbols.
zReceived {}: {}z)Too many ranges. Received %s, expected %sc                 S   s   g | ]}|d  qS r   r   r   rr   r   r   r   ~   s     z"_create_ranges.<locals>.<listcomp>z$Multiple ranges with the same symbolc                 S   s   g | ]}|d  qS r<   r   r=   r   r   r   r      s     r   z>Incompatible free symbols of the expressions with the ranges.
z$Free symbols in the expressions: {}
zFree symbols in the ranges: {})r#   
differencekeyslen
ValueErrorformatr   r    appendr+   r   )r!   rangesnparlabelparamsZget_default_ranger   Zrfssymbolsr-   r6   r   r   r   _create_rangesU   sJ    

rJ   c                 C   sR   t | toPt| dkoPt | jd t oP| jd joPt | jd t oP| jd jS )zUA range is defined as (symbol, start, end). start and end should
    be numbers.
             )r   r   rA   r5   r1   Z	is_number)r>   r   r   r   	_is_range   s    



rN   c                  G   sx   dd | D }dd | D }|s$dn|d }dd | D }|sBdn|d }dd | D }dd t | |D }||||fS )	a  Given a list/tuple of arguments previously processed by _plot_sympify()
    and/or _check_arguments(), separates and returns its components:
    expressions, ranges, label and rendering keywords.

    Examples
    ========

    >>> from sympy import cos, sin, symbols
    >>> from sympy.plotting.utils import _plot_sympify, _unpack_args
    >>> x, y = symbols('x, y')
    >>> args = (sin(x), (x, -10, 10), "f1")
    >>> args = _plot_sympify(args)
    >>> _unpack_args(*args)
    ([sin(x)], [(x, -10, 10)], 'f1', None)

    >>> args = (sin(x**2 + y**2), (x, -2, 2), (y, -3, 3), "f2")
    >>> args = _plot_sympify(args)
    >>> _unpack_args(*args)
    ([sin(x**2 + y**2)], [(x, -2, 2), (y, -3, 3)], 'f2', None)

    >>> args = (sin(x + y), cos(x - y), x + y, (x, -2, 2), (y, -3, 3), "f3")
    >>> args = _plot_sympify(args)
    >>> _unpack_args(*args)
    ([sin(x + y), cos(x - y), x + y], [(x, -2, 2), (y, -3, 3)], 'f3', None)
    c                 S   s   g | ]}t |r|qS r   rN   r   tr   r   r   r      s      z _unpack_args.<locals>.<listcomp>c                 S   s   g | ]}t |tr|qS r   r   r1   rP   r   r   r   r      s     
 Nr   c                 S   s   g | ]}t |tr|qS r   r   r2   rP   r   r   r   r      s     
 c                 S   s,   g | ]$}t |p$t|ttfp$|d k qS r   )rN   r   r1   r2   r   r7   r   r   r   r      s     c                 S   s   g | ]\}}|r|qS r   r   )r   r7   br   r   r   r      s      )zip)r5   rE   labelsrG   rendering_kwresultsr!   r   r   r   _unpack_args   s    rZ   c                    s6  | sg S g }| dd}tdd | d| D rt|  \}}}}	t jdd |D  }
t|||||}|dkrt||krt|f}|D ]6}t|t	t
tf}|r|fn|}|||||	f qnlt|  \}}}}	|r|gng }t|t| |	dk	rt|	nd }|dkr"| d|  n| }t|d tttfsB|g}|D ] d	d  D }|sb|}d
d  D }|s~| }dd  D }t|dkr|	n|d } fddt|D  t }
tdd  D r|
jdd  D  }
t||krt ||d|}|sdn|d }| |||f qF|S )a,  Checks the arguments and converts into tuples of the
    form (exprs, ranges, label, rendering_kw).

    Parameters
    ==========

    args
        The arguments provided to the plot functions
    nexpr
        The number of sub-expression forming an expression to be plotted.
        For example:
        nexpr=1 for plot.
        nexpr=2 for plot_parametric: a curve is represented by a tuple of two
            elements.
        nexpr=1 for plot3d.
        nexpr=3 for plot3d_parametric_line: a curve is represented by a tuple
            of three elements.
    npar
        The number of free symbols required by the plot functions. For example,
        npar=1 for plot, npar=2 for plot3d, ...
    **kwargs :
        keyword arguments passed to the plotting function. It will be used to
        verify if ``params`` has ben provided.

    Examples
    ========

    .. plot::
       :context: reset
       :format: doctest
       :include-source: True

       >>> from sympy import cos, sin, symbols
       >>> from sympy.plotting.plot import _check_arguments
       >>> x = symbols('x')
       >>> _check_arguments([cos(x), sin(x)], 2, 1)
       [(cos(x), sin(x), (x, -10, 10), None, None)]

       >>> _check_arguments([cos(x), sin(x), "test"], 2, 1)
       [(cos(x), sin(x), (x, -10, 10), 'test', None)]

       >>> _check_arguments([cos(x), sin(x), "test", {"a": 0, "b": 1}], 2, 1)
       [(cos(x), sin(x), (x, -10, 10), 'test', {'a': 0, 'b': 1})]

       >>> _check_arguments([x, x**2], 1, 1)
       [(x, (x, -10, 10), None, None), (x**2, (x, -10, 10), None, None)]
    rH   Nc                 s   s   | ]}t |tttfV  qd S r   )r   r   r   r
   rT   r   r   r   r     s     z#_check_arguments.<locals>.<genexpr>c                 S   s   g | ]
}|j qS r   r   r   r   r   r   r   	  s     z$_check_arguments.<locals>.<listcomp>rL   r   c                 S   s   g | ]}t |tr|qS r   rR   rT   r   r   r   r   /  s     
 c                 S   s   g | ]}t |r|qS r   rO   rT   r   r   r   r   2  s      c                 S   s   g | ]}t |tr|qS r   rS   rT   r   r   r   r   5  s     
 c                    s   g | ]} | qS r   r   )r   r6   argr   r   r   :  s     c                 s   s   | ]}t | V  qd S r   r   rT   r   r   r   r   <  s     c                 S   s   g | ]
}|j qS r   r   rT   r   r   r   r   =  s     r8   )getr   rZ   r   r    rJ   rA   r   r   r   r   r
   rD   r   r   copyr+   )r5   ZnexprrF   kwargsoutputrH   r!   rE   rG   rX   r   exprZis_exprr   _rW   r&   new_argslr>   Zrend_kwr   r[   r   _check_arguments   sR    0
re   )r$   )r8   N)Zsympy.core.containersr   Zsympy.core.basicr   Zsympy.core.exprr   Zsympy.core.functionr   Zsympy.core.relationalr   Zsympy.core.symbolr   Zsympy.core.sympifyr	   Zsympy.logic.boolalgr
   Zsympy.sets.fancysetsr   Zsympy.sets.setsr   Zsympy.tensor.indexedr   r#   r.   r0   rJ   rN   rZ   re   r   r   r   r   <module>   s"   

F&