
    
i                        S r SSKJr  SSKrSSKJr  SS jrSS jrSS jrSS	 jr	 S         SS
 jjr
 S         SS jjr S           SS jjrg)u  Wavelet-domain DCW primitives — the actual ``dcw_low``/``high``/``double``/``pix`` math.

Verbatim from the paper's reference implementation
(``AMAP-ML/DCW/FlowMatchEulerDiscreteScheduler.py``) but adapted to the
1-D temporal layout of ACE-Step latents (``[B, T, C]``):

* The reference operates on 2-D image latents with ``DWT2DForward``;
  ours uses ``DWT1DForward`` along the temporal axis after transposing
  ``[B, T, C] → [B, C, T]``.
* ``pytorch_wavelets`` zero-pads odd ``T`` to the next even before the
  filter bank, so the IDWT output is one sample longer than the input.
  We trim ``x_new[:, :, :out_T]`` so ACE-Step's odd-duration latents
  round-trip cleanly.
    )annotationsN   )WAVELET_CACHEc                B    U R                  SS5      R                  5       $ )z?Rearrange ACE-Step latents from ``[B, T, C]`` to ``[B, C, T]``.r      	transpose
contiguousxs    [/mnt/workspace/acestep.cpp/tests/../../ACE-Step-1.5/acestep/models/common/dcw_primitives.py_btc_to_bctr          ;;q!''))    c                B    U R                  SS5      R                  5       $ )zInverse of :func:`_btc_to_bct`.r   r   r   r   s    r   _bct_to_btcr      r   r   c                $    US:X  a  U $ XX-
  -  -   $ )u   Pixel/latent-space differential correction (no wavelet transform).

Matches the ``dcw_pix`` baseline in the DCW reference code — corrects
directly in latent space.  Useful as an ablation and as the fallback
on platforms without ``pytorch_wavelets``.
         )r   yscalers      r   dcw_pixr   !   s      }r   c                V   [         R                  " U R                  U R                  U5      nUc  gUu  pE[	        U R                  [        R                  5      5      n[	        UR                  [        R                  5      5      nU" U5      u  pU" U5      u  pXXXPR                  S   4$ )uU  Run DWT on both latents.

Returns ``(xl, xh, yl, yh, iwt, out_T)`` or ``None`` if the optional
``pytorch_wavelets`` dependency is missing.

``out_T`` is the original time length of ``x`` — we slice the IDWT
output back to this length because ``pytorch_wavelets`` pads odd-T
inputs up to the next even value before running the filter bank.
Nr   )	r   getdevicedtyper   totorchfloat32shape)r   r   waveletmodulesdwtiwtx_bcty_bctxlxhylyhs               r   	_dwt_pairr+   -   s     !''7;GHCU]]+,EU]]+,EZFBZFB23
**r   c                    US:X  a  U $ [        XU5      nUc  U $ Uu  pVpxpXRXW-
  -  -   nU	" XV45      n[        USS2SS2SU
24   5      R                  U R                  S9$ )uU  Apply differential correction to the low-frequency sub-band only.

Implements Eq. 18 / 20 of the DCW paper:

* ``xL, xH = DWT(x)``;  ``yL, yH = DWT(y)``
* ``xL ← xL + scaler · (xL − yL)``
* ``x_new = IDWT(xL, xH)``

Args:
    x: Current latent ``x_next`` after the sampler step, shape ``[B, T, C]``.
    y: Predicted clean sample ``denoised = x − v · t``, shape ``[B, T, C]``.
    scaler: Correction strength.  ``0`` short-circuits to identity.
    wavelet: PyWavelets basis, e.g. ``"haar"`` / ``"db4"`` / ``"sym8"``.

Returns:
    Corrected latent with the same shape and dtype as ``x``.
r   Nr   )r+   r   r   r   )r   r   r   r!   pairr'   r(   r)   _yhr$   out_Tx_news               r   dcw_lowr2   B   sx    ( }Q7#D|"&BBS	 	 BMEuQ6E6\*+..QWW.==r   c                   US:X  a  U $ [        XU5      nUc  U $ Uu  pVpxp[        XhSS9 VVs/ s H  u  pXX-
  -  -   PM     nnnU	" X]45      n[        USS2SS2SU
24   5      R                  U R                  S9$ s  snnf )zBApply differential correction to the high-frequency sub-band only.r   NTstrictr-   r+   zipr   r   r   )r   r   r   r!   r.   r'   r(   _ylr*   r$   r0   xhiyhixh_newr1   s                  r   dcw_highr<   a   s     }Q7#D|"&BCS9<RD9QR9QXScci((9QFREuQ6E6\*+..QWW.== Ss   A<c                :   US:X  a  US:X  a  U $ [        XU5      nUc  U $ Uu  pgppUS:w  a	  XbXh-
  -  -   nUS:w  a%  [        XySS9 VVs/ s H  u  pXX-
  -  -   PM     nnnU
" Xg45      n[        USS2SS2SU24   5      R                  U R                  S9$ s  snnf )zDApply differential correction to both low- and high-frequency bands.r   NTr4   r-   r6   )r   r   
low_scalerhigh_scalerr!   r.   r'   r(   r)   r*   r$   r0   r9   r:   r1   s                  r   
dcw_doubler@   p   s     S[C/Q7#D|!%BBCS((c>A"QU>VW>V(#c39-->VWMEuQ6E6\*+..QWW.== Xs   B)r   torch.TensorreturnrA   )r   rA   r   rA   r   floatrB   rA   )r   rA   r   rA   r!   str)haar)
r   rA   r   rA   r   rC   r!   rD   rB   rA   )r   rA   r   rA   r>   rC   r?   rC   r!   rD   rB   rA   )__doc__
__future__r   r   
dcw_loaderr   r   r   r   r+   r2   r<   r@   r   r   r   <module>rI      s    #  %*
*
	 +, EK>>$>.3>>A>>@ EK>>$>.3>>A>>( >>> > 	>
 > >r   