o
    Eb                     @   s  d Z ddlZddlmZ g dZdd Zdd Zd	d
 Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd ZG dd deZe Zdd ZG dd  d eZe Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d* Zd+d, Zd-d. Zd/d0 ZG d1d2 d2eZe ZG d3d4 d4eZ e  Z!dS )5zI Collection of Model instances for use with the odrpack fitting package.
    N)Model)r   exponentialmultilinear	unilinear	quadratic
polynomialc                 C   s:   | d | dd  }}|j d df|_ ||| jdd S Nr      Zaxis)shapesum)Bxab r   3/usr/lib/python3/dist-packages/scipy/odr/_models.py_lin_fcn
   s   r   c                 C   s>   t |jd t}t || f}| jd |jd f|_|S N)nponesr   floatconcatenateZravel)r   r   r   resr   r   r   _lin_fjb   s   r   c                 C   s:   | dd  }t j||jd f|jd  dd}|j|_|S )Nr	   r   r   r
   )r   repeatr   )r   r   r   r   r   r   _lin_fjd   s   "r   c                 C   s4   t | jjdkr| jjd }nd}t|d ftS N   r   r	   )lenr   r   r   r   r   )datamr   r   r   _lin_est   s   r#   c                 C   sD   | d | dd  }}|j d df|_ |tj|t|| dd S r   r   r   r   power)r   r   powersr   r   r   r   r   	_poly_fcn,   s   r'   c                 C   s@   t t |jd tt ||jf}| jd |jd f|_|S r   )r   r   r   r   r   r%   Zflat)r   r   r&   r   r   r   r   _poly_fjacb3   s
   r(   c                 C   sB   | dd  }|j d df|_ || }tj|t||d  ddS )Nr	   r   r
   r$   )r   r   r&   r   r   r   r   _poly_fjacd:   s   r)   c                 C   s   | d t | d |  S Nr   r	   r   expr   r   r   r   r   _exp_fcnC      r.   c                 C   s   | d t | d |  S )Nr	   r+   r-   r   r   r   _exp_fjdG   r/   r0   c                 C   sB   t t |jd t|t | d |  f}d|jd f|_|S )Nr   r	   r   )r   r   r   r   r   r,   )r   r   r   r   r   r   _exp_fjbK   s   .r1   c                 C   s   t ddgS )N      ?)r   Zarrayr!   r   r   r   _exp_estQ      r4   c                           e Zd ZdZ fddZ  ZS )_MultilinearModela  
    Arbitrary-dimensional linear model

    This model is defined by :math:`y=\beta_0 + \sum_{i=1}^m \beta_i x_i`

    Examples
    --------
    We can calculate orthogonal distance regression with an arbitrary
    dimensional linear model:

    >>> from scipy import odr
    >>> x = np.linspace(0.0, 5.0)
    >>> y = 10.0 + 5.0 * x
    >>> data = odr.Data(x, y)
    >>> odr_obj = odr.ODR(data, odr.multilinear)
    >>> output = odr_obj.run()
    >>> print(output.beta)
    [10.  5.]

    c              	      "   t  jttttddddd d S )NzArbitrary-dimensional Linearz y = B_0 + Sum[i=1..m, B_i * x_i]z&$y=\beta_0 + \sum_{i=1}^m \beta_i x_i$nameZequZTeXequ)fjacbfjacdestimatemeta)super__init__r   r   r   r#   self	__class__r   r   r@   k      
z_MultilinearModel.__init____name__
__module____qualname____doc__r@   __classcell__r   r   rC   r   r7   V   s    r7   c                 C   sx   t | }|jdkrt d|d }t|df|_t|d }|fdd}tttt||fdd|d  d|d  dd	S )
a  
    Factory function for a general polynomial model.

    Parameters
    ----------
    order : int or sequence
        If an integer, it becomes the order of the polynomial to fit. If
        a sequence of numbers, then these are the explicit powers in the
        polynomial.
        A constant term (power 0) is always included, so don't include 0.
        Thus, polynomial(n) is equivalent to polynomial(range(1, n+1)).

    Returns
    -------
    polynomial : Model instance
        Model instance.

    Examples
    --------
    We can fit an input data using orthogonal distance regression (ODR) with
    a polynomial model:

    >>> import matplotlib.pyplot as plt
    >>> from scipy import odr
    >>> x = np.linspace(0.0, 5.0)
    >>> y = np.sin(x)
    >>> poly_model = odr.polynomial(3)  # using third order polynomial model
    >>> data = odr.Data(x, y)
    >>> odr_obj = odr.ODR(data, poly_model)
    >>> output = odr_obj.run()  # running ODR fitting
    >>> poly = np.poly1d(output.beta[::-1])
    >>> poly_y = poly(x)
    >>> plt.plot(x, y, label="input data")
    >>> plt.plot(x, poly_y, label="polynomial ODR")
    >>> plt.legend()
    >>> plt.show()

    r   r	   c                 S   s   t |ftS )N)r   r   r   )r!   len_betar   r   r   	_poly_est   r5   zpolynomial.<locals>._poly_estzSorta-general Polynomialz$y = B_0 + Sum[i=1..%s, B_i * (x**i)]z)$y=\beta_0 + \sum_{i=1}^{%s} \beta_i x^i$r9   )r<   r;   r=   
extra_argsr>   )	r   Zasarrayr   Zaranger    r   r'   r)   r(   )Zorderr&   rL   rM   r   r   r   r   v   s   
(

r   c                       r6   )_ExponentialModela  
    Exponential model

    This model is defined by :math:`y=\beta_0 + e^{\beta_1 x}`

    Examples
    --------
    We can calculate orthogonal distance regression with an exponential model:

    >>> from scipy import odr
    >>> x = np.linspace(0.0, 5.0)
    >>> y = -10.0 + np.exp(0.5*x)
    >>> data = odr.Data(x, y)
    >>> odr_obj = odr.ODR(data, odr.exponential)
    >>> output = odr_obj.run()
    >>> print(output.beta)
    [-10.    0.5]

    c              	      r8   )NZExponentialzy= B_0 + exp(B_1 * x)z$y=\beta_0 + e^{\beta_1 x}$r9   r<   r;   r=   r>   )r?   r@   r.   r0   r1   r4   rA   rC   r   r   r@         
z_ExponentialModel.__init__rF   r   r   rC   r   rO          rO   c                 C   s   || d  | d  S r*   r   r-   r   r   r   _unilin   s   rS   c                 C   s   t |jt| d  S )Nr   )r   r   r   r   r-   r   r   r   _unilin_fjd   s   rT   c                 C   s(   t |t |jtf}d|j |_|S )N)r   r   r   r   r   r   r   r   Z_retr   r   r   _unilin_fjb   s   rW   c                 C      dS )N)r2   r2   r   r3   r   r   r   _unilin_est      rY   c                 C   s    ||| d  | d   | d  S )Nr   r	   r   r   r-   r   r   r   
_quadratic   s    r[   c                 C   s   d| | d  | d  S r   r   r-   r   r   r   	_quad_fjd   s   r\   c                 C   s.   t || |t |jtf}d|j |_|S )N)   rU   rV   r   r   r   	_quad_fjb   s   r^   c                 C   rX   )N)r2   r2   r2   r   r3   r   r   r   	_quad_est   rZ   r_   c                       r6   )_UnilinearModela  
    Univariate linear model

    This model is defined by :math:`y = \beta_0 x + \beta_1`

    Examples
    --------
    We can calculate orthogonal distance regression with an unilinear model:

    >>> from scipy import odr
    >>> x = np.linspace(0.0, 5.0)
    >>> y = 1.0 * x + 2.0
    >>> data = odr.Data(x, y)
    >>> odr_obj = odr.ODR(data, odr.unilinear)
    >>> output = odr_obj.run()
    >>> print(output.beta)
    [1. 2.]

    c              	      r8   )NzUnivariate Linearzy = B_0 * x + B_1z$y = \beta_0 x + \beta_1$r9   rP   )r?   r@   rS   rT   rW   rY   rA   rC   r   r   r@     rQ   z_UnilinearModel.__init__rF   r   r   rC   r   r`      rR   r`   c                       r6   )_QuadraticModela  
    Quadratic model

    This model is defined by :math:`y = \beta_0 x^2 + \beta_1 x + \beta_2`

    Examples
    --------
    We can calculate orthogonal distance regression with a quadratic model:

    >>> from scipy import odr
    >>> x = np.linspace(0.0, 5.0)
    >>> y = 1.0 * x ** 2 + 2.0 * x + 3.0
    >>> data = odr.Data(x, y)
    >>> odr_obj = odr.ODR(data, odr.quadratic)
    >>> output = odr_obj.run()
    >>> print(output.beta)
    [1. 2. 3.]

    c              	      r8   )NZ	Quadraticzy = B_0*x**2 + B_1*x + B_2z&$y = \beta_0 x^2 + \beta_1 x + \beta_2r9   rP   )r?   r@   r[   r\   r^   r_   rA   rC   r   r   r@   *  rE   z_QuadraticModel.__init__rF   r   r   rC   r   ra     rR   ra   )"rJ   Znumpyr   Zscipy.odr._odrpackr   __all__r   r   r   r#   r'   r(   r)   r.   r0   r1   r4   r7   r   r   rO   r   rS   rT   rW   rY   r[   r\   r^   r_   r`   r   ra   r   r   r   r   r   <module>   s@    	<
