
    bi                     P    d dl Z d dlmZmZ d dlZd dlmZ ddlmZ  G d d      Z	y)    N)TupleUnion   )randn_tensorc                      e Zd ZdZ	 	 	 	 	 	 ddedededededefdZd	 Z	e
d
        Zdeedf   deeej                  f   dededededej                   fdZdej                   dej                   dej                   dej                   fdZdej                   dededej&                  dej                  dej(                  fdZy)FreeInitMixinzMixin class for FreeInit.	num_itersuse_fast_samplingmethodorderspatial_stop_frequencytemporal_stop_frequencyc                 X    || _         || _        || _        || _        || _        || _        y)a(  Enables the FreeInit mechanism as in https://huggingface.co/papers/2312.07537.

        This implementation has been adapted from the [official repository](https://github.com/TianxingWu/FreeInit).

        Args:
            num_iters (`int`, *optional*, defaults to `3`):
                Number of FreeInit noise re-initialization iterations.
            use_fast_sampling (`bool`, *optional*, defaults to `False`):
                Whether or not to speedup sampling procedure at the cost of probably lower quality results. Enables the
                "Coarse-to-Fine Sampling" strategy, as mentioned in the paper, if set to `True`.
            method (`str`, *optional*, defaults to `butterworth`):
                Must be one of `butterworth`, `ideal` or `gaussian` to use as the filtering method for the FreeInit low
                pass filter.
            order (`int`, *optional*, defaults to `4`):
                Order of the filter used in `butterworth` method. Larger values lead to `ideal` method behaviour
                whereas lower values lead to `gaussian` method behaviour.
            spatial_stop_frequency (`float`, *optional*, defaults to `0.25`):
                Normalized stop frequency for spatial dimensions. Must be between 0 to 1. Referred to as `d_s` in the
                original implementation.
            temporal_stop_frequency (`float`, *optional*, defaults to `0.25`):
                Normalized stop frequency for temporal dimensions. Must be between 0 to 1. Referred to as `d_t` in the
                original implementation.
        N)_free_init_num_iters_free_init_use_fast_sampling_free_init_method_free_init_order!_free_init_spatial_stop_frequency"_free_init_temporal_stop_frequency)selfr	   r
   r   r   r   r   s          ^/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/diffusers/pipelines/free_init_utils.pyenable_free_initzFreeInitMixin.enable_free_init   s5    @ %.!,=)!' %1G.2I/    c                     d| _         y)z+Disables the FreeInit mechanism if enabled.N)r   r   s    r   disable_free_initzFreeInitMixin.disable_free_initB   s
    $(!r   c                 :    t        | d      xr | j                  d uS )Nr   )hasattrr   r   s    r   free_init_enabledzFreeInitMixin.free_init_enabledF   s!    t34^9R9RZ^9^^r   shape.devicefilter_typereturnc           	         |d   |d   |d   }	}}t        j                  |      }
dk(  s|dk(  r|
S |dk(  rfd}n!|dk(  rfd}n|d	k(  rfd
}nt        d      t        |      D ]c  }t        |      D ]S  }t        |	      D ]C  }|z  d|z  |z  dz
  z  dz  d|z  |z  dz
  dz  z   d|z  |	z  dz
  dz  z   } ||      |
d|||f<   E U e |
j	                  |      S )zLReturns the FreeInit filter based on filter type and other input conditions.r   butterworthc                 &    dd| dz  z  z  z   z  S )N   r    )xr   r   s    r   retrieve_maskz?FreeInitMixin._get_free_init_freq_filter.<locals>.retrieve_mask]   s#    A%;Q%>!>5 HHIIr   gaussianc                 F    t        j                  dddz  z  z  | z        S )Nr'   r   )mathexpr,   r   s    r   r-   z?FreeInitMixin._get_free_init_freq_filter.<locals>.retrieve_maska   s'    xxa*@!*C&C Dq HIIr   idealc                     | dz  k  rdS dS )Nr   r*   r   r+   r2   s    r   r-   z?FreeInitMixin._get_free_init_freq_filter.<locals>.retrieve_maske   s    !7!!;;qBBr   z;`filter_type` must be one of gaussian, butterworth or idealr   r*   .)torchzerosNotImplementedErrorrangeto)r   r    r!   r"   r   r   r   timeheightwidthmaskr-   thwd_squares       ``          r   _get_free_init_freq_filterz(FreeInitMixin._get_free_init_freq_filterJ   s>    $BirE"Ief{{5!!Q&*AQ*FK-'JJ&JG#C &&cddt 	AA6] Au AA03JJqSTuW[|^_O_`effq56>A-!34q55=1,23 
 *7x)@DaA&AA	A wwvr   r,   noiselow_pass_filterc                 V   t        j                  |d      }t        j                  |d      }t        j                  |d      }t        j                  |d      }d|z
  }||z  }||z  }||z   }	t        j                  |	d      }	t        j                  |	d      j
                  }
|
S )zNoise reinitialization.)r%   r&   r'   )dimr*   )fftfftnfftshift	ifftshiftifftnreal)r   r,   rC   rD   x_freq
noise_freqhigh_pass_filter
x_freq_lownoise_freq_highx_freq_mixedx_mixeds              r   _apply_freq_filterz FreeInitMixin._apply_freq_filterv   s     !.f,7XXe6
\\*,?
 .o-
$'77!O3 }}\|D))Ll;@@r   latentsfree_init_iterationnum_inference_stepsdtype	generatorc                    |dk(  r%|j                         j                         | _        n6|j                  }dg|dd  }| j	                  ||| j
                  | j                  | j                  | j                        }	| j                  j                  j                  dz
  }
t        j                  |d   f|
      j                         }| j                  j                  || j                  |j!                  |            j!                  t        j"                        }t%        |||t        j"                        }| j'                  |||	      }|j!                  |      }| j(                  r(t+        dt-        || j.                  z  |dz   z              }|dkD  r| j                  j1                  ||       || j                  j2                  fS )	Nr   r*   )r    r!   r"   r   r   r   )original_samplesrC   	timesteps)rX   )r    rY   r!   rX   )rD   )r!   )detachclone_free_init_initial_noiser    rB   r   r   r   r   	schedulerconfignum_train_timestepsr5   fulllong	add_noiser9   float32r   rT   r   maxintr   set_timestepsr\   )r   rU   rV   rW   r!   rX   rY   latent_shapefree_init_filter_shapefree_init_freq_filtercurrent_diffuse_timestepdiffuse_timestepsz_tz_rands                 r   _apply_free_initzFreeInitMixin._apply_free_init   s    !#,3NN,<,B,B,DD)"==L&'%;,qr*:%;"$($C$C, 22++'+'M'M(,(O(O %D %! (,~~'<'<'P'PST'T$ %

LO+=?W X ] ] _..**!(0M0MYjYmYmntYu + bu}}b%  ""#mm	F --c6K`-aGjj'G ,,"%3*T-F-FFJ]`aJabc# "NN(()<V(L0000r   N)   Fr(            ?rt   )__name__
__module____qualname____doc__rh   boolstrfloatr   r   propertyr   r   r   r5   rX   TensorrB   rT   r!   	Generatorrq   r+   r   r   r   r      se   $ "'#(,)-%J%J  %J 	%J
 %J !&%J "'%JN) _ _*S#X* c5;;&'* 	*
 * !&* "'* 
*XELL  X]XdXd iniuiu (1111 !11 !	11
 11 {{11 ??11r   r   )
r0   typingr   r   r5   	torch.fftrG   utils.torch_utilsr   r   r+   r   r   <module>r      s"        ,c1 c1r   