U
    ªÊ¹js  ã                   @   s&   d dl Z d dlmZ G dd„ dƒZdS )é    N)ÚOptionalc                   @   s�   e Zd ZdZdZdZddd„Zddejfe	e
ej ejejd	œd
d„Zdejfe	e
ej ejejdœdd„Zdd„ Zdd„ Zdd„ Zdd„ ZdS )ÚSobolEnginea  
    The :class:`torch.quasirandom.SobolEngine` is an engine for generating
    (scrambled) Sobol sequences. Sobol sequences are an example of low
    discrepancy quasi-random sequences.

    This implementation of an engine for Sobol sequences is capable of
    sampling sequences up to a maximum dimension of 21201. It uses direction
    numbers from https://web.maths.unsw.edu.au/~fkuo/sobol/ obtained using the
    search criterion D(6) up to the dimension 21201. This is the recommended
    choice by the authors.

    References:
      - Art B. Owen. Scrambling Sobol and Niederreiter-Xing points.
        Journal of Complexity, 14(4):466-489, December 1998.

      - I. M. Sobol. The distribution of points in a cube and the accurate
        evaluation of integrals.
        Zh. Vychisl. Mat. i Mat. Phys., 7:784-802, 1967.

    Args:
        dimension (Int): The dimensionality of the sequence to be drawn
        scramble (bool, optional): Setting this to ``True`` will produce
                                   scrambled Sobol sequences. Scrambling is
                                   capable of producing better Sobol
                                   sequences. Default: ``False``.
        seed (Int, optional): This is the seed for the scrambling. The seed
                              of the random number generator is set to this,
                              if specified. Otherwise, it uses a random seed.
                              Default: ``None``

    Examples::

        >>> # xdoctest: +SKIP("unseeded random state")
        >>> soboleng = torch.quasirandom.SobolEngine(dimension=5)
        >>> soboleng.draw(3)
        tensor([[0.0000, 0.0000, 0.0000, 0.0000, 0.0000],
                [0.5000, 0.5000, 0.5000, 0.5000, 0.5000],
                [0.7500, 0.2500, 0.2500, 0.2500, 0.7500]])
    é   iÑR  FNc                 C   sÄ   || j ks|dk r$td| j › d�ƒ‚|| _|| _|| _t d¡}tj|| j|tj	d�| _
t | j
| j¡ | js†tj| j|tj	d�| _n|  ¡  | jjtjd�| _| jd| j   dd¡| _d	| _d S )
Né   z9Supported range of dimensionality for SobolEngine is [1, ú]Úcpu)ÚdeviceÚdtype)Zmemory_formaté   éÿÿÿÿr   )ÚMAXDIMÚ
ValueErrorÚseedÚscrambleÚ	dimensionÚtorchr   ZzerosÚMAXBITÚlongÚ
sobolstateZ_sobol_engine_initialize_state_ÚshiftÚ	_scrambleÚcloneZcontiguous_formatÚquasiZreshapeÚ_first_pointÚnum_generated)Úselfr   r   r   r   © r   úP/var/www/html/bwave/python/venv/lib/python3.8/site-packages/torch/quasirandom.pyÚ__init__0   s    
zSobolEngine.__init__r   )ÚnÚoutr	   Úreturnc                 C   s´   | j dkr^|dkr | j |¡}q†tj| j|d | j| j| j |d�\}| _tj| j|fdd�}n(tj| j|| j| j| j d |d�\}| _|  j |7  _ |dk	r°| 	|¡ 
|¡ |S |S )at  
        Function to draw a sequence of :attr:`n` points from a Sobol sequence.
        Note that the samples are dependent on the previous samples. The size
        of the result is :math:`(n, dimension)`.

        Args:
            n (Int, optional): The length of sequence of points to draw.
                               Default: 1
            out (Tensor, optional): The output tensor
            dtype (:class:`torch.dtype`, optional): the desired data type of the
                                                    returned tensor.
                                                    Default: ``torch.float32``
        r   r   )r	   éþÿÿÿ)ÚdimN)r   r   Útor   Z_sobol_engine_drawr   r   r   ÚcatZ
resize_as_Úcopy_)r   r   r    r	   Úresultr   r   r   ÚdrawG   s2    
     ÿ     ÿzSobolEngine.draw)Úmr    r	   r!   c              
   C   sX   d| }| j | }||d @ dksHtd| j › d| j › d|› d|› d�	ƒ‚| j|||d	�S )
aR  
        Function to draw a sequence of :attr:`2**m` points from a Sobol sequence.
        Note that the samples are dependent on the previous samples. The size
        of the result is :math:`(2**m, dimension)`.

        Args:
            m (Int): The (base2) exponent of the number of points to draw.
            out (Tensor, optional): The output tensor
            dtype (:class:`torch.dtype`, optional): the desired data type of the
                                                    returned tensor.
                                                    Default: ``torch.float32``
        r
   r   r   zFThe balance properties of Sobol' points require n to be a power of 2. z0 points have been previously generated, then: n=z+2**ú=zH. If you still want to do this, please use 'SobolEngine.draw()' instead.)r   r    r	   )r   r   r(   )r   r)   r    r	   r   Ztotal_nr   r   r   Ú
draw_base2k   s
    
&zSobolEngine.draw_base2c                 C   s   | j  | j¡ d| _| S )zF
        Function to reset the ``SobolEngine`` to base state.
        r   )r   r&   r   r   )r   r   r   r   Úreset„   s    zSobolEngine.resetc                 C   sZ   | j dkr*t | j|d | j| j| j ¡ nt | j|| j| j| j d ¡ |  j |7  _ | S )a  
        Function to fast-forward the state of the ``SobolEngine`` by
        :attr:`n` steps. This is equivalent to drawing :attr:`n` samples
        without using the samples.

        Args:
            n (Int): The number of steps to fast-forward by.
        r   r   )r   r   Z_sobol_engine_ff_r   r   r   )r   r   r   r   r   Úfast_forwardŒ   s
    	
 zSobolEngine.fast_forwardc                 C   s¦   d }| j d k	r"t ¡ }| | j ¡ t d¡}tjd| j| jf||d�}t |t 	dtj
d| j|d�¡¡| _| j| j| jf}tjd|||d� ¡ }t | j|| j¡ d S )Nr   r
   )r   Ú	generatorr   )r   )r   r   Ú	GeneratorZmanual_seedr   Úrandintr   r   ÚmvÚpowZaranger   ZtrilZ_sobol_engine_scramble_r   )r   Úgr   Z
shift_intsZltm_dimsZltmr   r   r   r   œ   s    

$zSobolEngine._scramblec                 C   sT   d| j › �g}| jr|dg7 }| jd k	r:|d| j› �g7 }| jjd d |¡ d S )Nz
dimension=zscramble=Truezseed=ú(z, ú))r   r   r   Ú	__class__Ú__name__Újoin)r   Z
fmt_stringr   r   r   Ú__repr__®   s    

zSobolEngine.__repr__)FN)r7   Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   Zfloat32Úintr   ZTensorr	   r(   r+   r,   r-   r   r9   r   r   r   r   r      s(   '
ÿ ÿ$ÿ ÿr   )r   Útypingr   r   r   r   r   r   Ú<module>   s   