o
    h                     @   sT   d dl Z d dlZd dlmZ d dlmZmZ d dlmZ G dd deZ	dd Z
dS )	    N)cached_property)array_namespace	np_compat)NestedFixedRulec                   @   s2   e Zd ZdZdddZedd Zed	d
 ZdS )GenzMalikCubaturea  
    Genz-Malik cubature.

    Genz-Malik is only defined for integrals of dimension >= 2.

    Parameters
    ----------
    ndim : int
        The spatial dimension of the integrand.

    xp : array_namespace, optional
        The namespace for the node and weight arrays. Default is None, where NumPy is
        used.

    Attributes
    ----------
    higher : Cubature
        Higher-order rule.

    lower : Cubature
        Lower-order rule.

    References
    ----------
    .. [1] A.C. Genz, A.A. Malik, Remarks on algorithm 006: An adaptive algorithm for
        numerical integration over an N-dimensional rectangular region, Journal of
        Computational and Applied Mathematics, Volume 6, Issue 4, 1980, Pages 295-302,
        ISSN 0377-0427, https://doi.org/10.1016/0771-050X(80)90039-X.

    Examples
    --------
    Evaluate a 3D integral:

    >>> import numpy as np
    >>> from scipy.integrate import cubature
    >>> from scipy.integrate._rules import GenzMalikCubature
    >>> def f(x):
    ...     # f(x) = cos(x_1) + cos(x_2) + cos(x_3)
    ...     return np.sum(np.cos(x), axis=-1)
    >>> rule = GenzMalikCubature(3) # Use 3D Genz-Malik
    >>> a, b = np.array([0, 0, 0]), np.array([1, 1, 1])
    >>> rule.estimate(f, a, b) # True value 3*sin(1), approximately 2.5244
     np.float64(2.5244129547230862)
    >>> rule.estimate_error(f, a, b)
     np.float64(1.378269656626685e-06)
          Nc                 C   sZ   |dk rt d|dks|dkrtd|| _|| _|| _|d u r#t}t|d| _d S )N   z1Genz-Malik cubature is only defined for ndim >= 2r   r   zKGenz-Malik cubature is currently only supportedfor degree=7, lower_degree=5r   )	
ValueErrorNotImplementedErrorndimdegreelower_degreer   r   emptyxp)selfr   r   r   r    r   V/var/www/vscode/kcb/lib/python3.10/site-packages/scipy/integrate/_rules/_genz_malik.py__init__;   s   zGenzMalikCubature.__init__c                 C   sh  t d}t d}t d}t d}td| j gt|fd| jd   t| fd| jd   t|fd| jd   t| fd| jd   t||fd| jd   t|| fd| jd   t| | fd| jd   tj|| f| jd	}dd| jd  | j  d| j  }| jjt	t
| | jjd}| j|| j|f}|j}d| j d	d
| j  d| jd    d }d| j d d }	d| j dd| j   d }
d| j d }d}| j| jj|gd | jjd| jj|	gd| j  | jjd| jj|
gd| j  | jjd| jj|gd| jd  | j  | jjd| jj|gd| j  | jjdg}||fS )NPuPu??g5P?r      r	   )repeatdtypei2  i#  i  iL  i  i  i  gSgQτ?gbM?)mathsqrt	itertoolschainr   _distinct_permutationsproductr   asarraylistzipfloat64reshapeTconcat)r   l_2l_3l_4l_5its
nodes_sizenodesw_1w_2w_3w_4w_5weightsr   r   r   nodes_and_weightsL   sN   




"
(z#GenzMalikCubature.nodes_and_weightsc                 C   s  t d}t d}t d}td| j gt|fd| jd   t| fd| jd   t|fd| jd   t| fd| jd   t||fd| jd   t|| fd| jd   t| | fd| jd   }dd| jd  | j  }| jjtt	| | jj
d}| j|| j|f}|j}d| j dd| j  d	| jd    d }d| j d
 }d| j dd| j   d }	d| j d }
| j| jj|gd | jj
d| jj|gd| j  | jj
d| jj|	gd| j  | jj
d| jj|
gd| jd  | j  | jj
dg}||fS )Nr   r   r   r   r	   r   i  i  2   gQA!?i	  d   i  g>쎡?)r   r   r   r   r   r    r   r"   r#   r$   r%   r&   r'   r(   )r   r)   r*   r+   r-   r.   r/   r0   r1   r2   r3   r5   r   r   r   lower_nodes_and_weights   s>   



*
z)GenzMalikCubature.lower_nodes_and_weights)r   r   N)__name__
__module____qualname____doc__r   r   r6   r9   r   r   r   r   r      s    
/
7r   c                 c   s    t | }t|}	 t|V  t|d ddD ]}|| ||d  k r% nqdS t|d |dD ]}|| || k r< nq0|| || ||< ||< |d|| d ||d d< q
)zM
    Find the number of distinct permutations of elements of `iterable`.
    Tr	   r   N)sortedlentuplerange)iterableitemssizeijr   r   r   r       s"   
r    )r   r   	functoolsr   scipy._lib._array_apir   r   scipy.integrate._rulesr   r   r    r   r   r   r   <module>   s     )