



'''simple docstring'''






import mpmath  # for roots of unity
import numpy as np

class 							a__:







    def __init__(				self			:  Optional[Any]						,      __snake_case			:  List[Any]=None						,      __snake_case			:  str=None     ):
      # Input as list
      a						: Union[str, Any]					       =					list(poly_a or [0]     )[:]
      a						: Tuple					       =					list(poly_b or [0]     )[:]

      # Remove leading zero coefficients
      while self.polyA[-1] == 0:
        self.polyA.pop()
      a						: Union[str, Any]					       =					len(self.polyA     )

      while self.polyB[-1] == 0:
        self.polyB.pop()
      a						: Tuple					       =					len(self.polyB     )

      # Add 0 to make lengths equal a power of 2
      a						: Optional[Any]					       =					int(
          2 ** np.ceil(np.loga(len(self.polyA     ) + len(self.polyB     ) - 1     )     )     )

      while len(self.polyA     ) < self.c_max_length:
        self.polyA.append(0     )
      while len(self.polyB     ) < self.c_max_length:
        self.polyB.append(0     )
      # A complex root used for the fourier transform
      a						: List[Any]					       =					complex(mpmath.root(x=1						,      n=self.c_max_length						,      k=1     )     )

      # The product
      a						: Tuple					       =					self.__multiply()







    def       lowercase_	(				self			:  str						,      __snake_case			:  Any     ):
      a						: Optional[int]					       =					[[x] for x in self.polyA] if which == 'A' else [[x] for x in self.polyB]
      # Corner case
      if len(__snake_case     ) <= 1:
        return dft[0]
      #
      a						: int					       =					self.c_max_length // 2
      while next_ncol > 0:
        a						: int					       =					[[] for i in range(__snake_case     )]
        a						: int					       =					self.root**next_ncol

        # First half of next step
        a						: List[Any]					       =					1
        for j in range(self.c_max_length // (next_ncol * 2)     ):
          for i in range(__snake_case     ):
            new_dft[i].append(dft[i][j] + current_root * dft[i + next_ncol][j]     )
          current_root *= root
        # Second half of next step
        a						: Tuple					       =					1
        for j in range(self.c_max_length // (next_ncol * 2)     ):
          for i in range(__snake_case     ):
            new_dft[i].append(dft[i][j] - current_root * dft[i + next_ncol][j]     )
          current_root *= root
        # Update
        a						: Any					       =					new_dft
        a						: List[str]					       =					next_ncol // 2
      return dft[0]







    def       lowercase_	(				self			:  str     ):
      a						: Dict					       =					self.__dft('A'     )
      a						: Dict					       =					self.__dft('B'     )
      a						: Union[str, Any]					       =					[[dft_a[i] * dft_b[i] for i in range(self.c_max_length     )]]
      del dft_a
      del dft_b

      # Corner Case
      if len(inverce_c[0]     ) <= 1:
        return inverce_c[0]
      # Inverse DFT
      a						: Optional[int]					       =					2
      while next_ncol <= self.c_max_length:
        a						: Tuple					       =					[[] for i in range(__snake_case     )]
        a						: Any					       =					self.root ** (next_ncol // 2)
        a						: str					       =					1
        # First half of next step
        for j in range(self.c_max_length // next_ncol     ):
          for i in range(next_ncol // 2     ):
            # Even positions
            new_inverse_c[i].append(
                (
                    inverce_c[i][j]
                    + inverce_c[i][j + self.c_max_length // next_ncol]
                )
                / 2     )
            # Odd positions
            new_inverse_c[i + next_ncol // 2].append(
                (
                    inverce_c[i][j]
                    - inverce_c[i][j + self.c_max_length // next_ncol]
                )
                / (2 * current_root)     )
          current_root *= root
        # Update
        a						: List[Any]					       =					new_inverse_c
        next_ncol *= 2
      # Unpack
      a						: Union[str, Any]					       =					[round(x[0].real						,      8     ) + round(x[0].imag						,      8     ) * 1J for x in inverce_c]

      # Remove leading 0's
      while inverce_c[-1] == 0:
        inverce_c.pop()
      return inverce_c







    def __str__(				self			:  Optional[int]     ):
      a						: Any					       =					'A = ' + ' + '.join(
          F"""{coef}*x^{i}""" for coef, i in enumerate(self.polyA[: self.len_A]     )     )
      a						: Tuple					       =					'B = ' + ' + '.join(
          F"""{coef}*x^{i}""" for coef, i in enumerate(self.polyB[: self.len_B]     )     )
      a						: Any					       =					'A*B = ' + ' + '.join(
          F"""{coef}*x^{i}""" for coef, i in enumerate(self.product     )     )

      return F"""{a}\n{b}\n{c}"""


# Unit tests
if __name__ == "__main__":
     import doctest

     doctest.testmod()




'''simple docstring'''






from typing import Optional, Tuple, Union

import flax
import flax.linen as nn
import jax
import jax.numpy as jnp
from flax.core.frozen_dict import FrozenDict

from ..configuration_utils import ConfigMixin, flax_register_to_config
from ..utils import BaseOutput
from .embeddings_flax import FlaxTimestepEmbedding, FlaxTimesteps
from .modeling_flax_utils import FlaxModelMixin
from .unet_ad_blocks_flax import (
    FlaxCrossAttnDownBlockaD,
    FlaxCrossAttnUpBlockaD,
    FlaxDownBlockaD,
    FlaxUNetMidBlockaDCrossAttn,
    FlaxUpBlockaD,
)

@flax.struct.dataclass
class 							a__( lowerCamelCase__     ):
    lowercase__			=   42

@flax_register_to_config
class 							a__( nn.Module		,			lowerCamelCase__		,			lowerCamelCase__     ):
    lowercase__			=   32
    lowercase__			=   4
    lowercase__			=   4
    lowercase__			=   (
        "CrossAttnDownBlock2D",
        "CrossAttnDownBlock2D",
        "CrossAttnDownBlock2D",
        "DownBlock2D",
    )
    lowercase__			=   ("UpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D")
    lowercase__			=   False
    lowercase__			=   (3_20, 6_40, 12_80, 12_80)
    lowercase__			=   2
    lowercase__			=   8
    lowercase__			=   None
    lowercase__			=   12_80
    lowercase__			=   0.0
    lowercase__			=   False
    lowercase__			=   jnp.floataa
    lowercase__			=   True
    lowercase__			=   0
    lowercase__			=   False







    def       lowercase_	(				self			:  List[Any]						,      __snake_case			:  jax.random.KeyArray     ):
      # init input tensors
      a						: Dict					       =					(1, self.in_channels, self.sample_size, self.sample_size)
      a						: str					       =					jnp.zeros(__snake_case						,      dtype=jnp.floataa     )
      a						: Union[str, Any]					       =					jnp.ones((1,)						,      dtype=jnp.intaa     )
      a						: List[Any]					       =					jnp.zeros((1, 1, self.cross_attention_dim)						,      dtype=jnp.floataa     )

      a       ,     a						: Optional[int]					       =					jax.random.split(__snake_case     )
      a						: Any					       =					{'params': params_rng, 'dropout': dropout_rng}

      return self.init(__snake_case						,      __snake_case						,      __snake_case						,      __snake_case     )["params"]







    def       lowercase_	(				self			:  Union[str, Any]     ):
      a						: int					       =					self.block_out_channels
      a						: Tuple					       =					block_out_channels[0] * 4

      if self.num_attention_heads is not None:
        raise ValueError(
            'At the moment it is not possible to define the number of attention heads via `num_attention_heads` because of a naming issue as described in https://github.com/huggingface/diffusers/issues/2011#issuecomment-1547958131. Passing `num_attention_heads` will only be supported in diffusers v0.19.'     )

      # If `num_attention_heads` is not defined (which is the case for most models)
      # it will default to `attention_head_dim`. This looks weird upon first reading it and it is.
      # The reason for this behavior is to correct for incorrectly named variables that were introduced
      # when this library was created. The incorrect naming was only discovered much later in https://github.com/huggingface/diffusers/issues/2011#issuecomment-1547958131
      # Changing `attention_head_dim` to `num_attention_heads` for 40,000+ configurations is too backwards breaking
      # which is why we correct for the naming here.
      a						: str					       =					self.num_attention_heads or self.attention_head_dim

      # input
      a						: List[Any]					       =					nn.Conv(
          block_out_channels[0]						,      kernel_size=(3, 3)						,      strides=(1, 1)						,      padding=((1, 1), (1, 1))						,      dtype=self.dtype						,      )

      # time
      a						: List[str]					       =					FlaxTimesteps(
          block_out_channels[0]						,      flip_sin_to_cos=self.flip_sin_to_cos						,      freq_shift=self.config.freq_shift     )
      a						: Optional[int]					       =					FlaxTimestepEmbedding(__snake_case						,      dtype=self.dtype     )

      a						: Optional[Any]					       =					self.only_cross_attention
      if isinstance(__snake_case						,      __snake_case     ):
        a						: int					       =					(only_cross_attention,) * len(self.down_block_types     )

      if isinstance(__snake_case						,      __snake_case     ):
        a						: str					       =					(num_attention_heads,) * len(self.down_block_types     )

      # down
      a						: int					       =					[]
      a						: Dict					       =					block_out_channels[0]
      for i, down_block_type in enumerate(self.down_block_types     ):
        a						: List[Any]					       =					output_channel
        a						: Dict					       =					block_out_channels[i]
        a						: Union[str, Any]					       =					i == len(__snake_case     ) - 1

        if down_block_type == "CrossAttnDownBlock2D":
          a						: Dict					       =					FlaxCrossAttnDownBlockaD(
              in_channels=__snake_case						,      out_channels=__snake_case						,      dropout=self.dropout						,      num_layers=self.layers_per_block						,      num_attention_heads=num_attention_heads[i]						,      add_downsample=not is_final_block						,      use_linear_projection=self.use_linear_projection						,      only_cross_attention=only_cross_attention[i]						,      use_memory_efficient_attention=self.use_memory_efficient_attention						,      dtype=self.dtype						,      )
        else:
          a						: List[str]					       =					FlaxDownBlockaD(
              in_channels=__snake_case						,      out_channels=__snake_case						,      dropout=self.dropout						,      num_layers=self.layers_per_block						,      add_downsample=not is_final_block						,      dtype=self.dtype						,      )

        down_blocks.append(__snake_case     )
      a						: Dict					       =					down_blocks

      # mid
      a						: Union[str, Any]					       =					FlaxUNetMidBlockaDCrossAttn(
          in_channels=block_out_channels[-1]						,      dropout=self.dropout						,      num_attention_heads=num_attention_heads[-1]						,      use_linear_projection=self.use_linear_projection						,      use_memory_efficient_attention=self.use_memory_efficient_attention						,      dtype=self.dtype						,      )

      # up
      a						: List[Any]					       =					[]
      a						: Dict					       =					list(reversed(__snake_case     )     )
      a						: List[str]					       =					list(reversed(__snake_case     )     )
      a						: List[str]					       =					list(reversed(__snake_case     )     )
      a						: Optional[int]					       =					reversed_block_out_channels[0]
      for i, up_block_type in enumerate(self.up_block_types     ):
        a						: Dict					       =					output_channel
        a						: Dict					       =					reversed_block_out_channels[i]
        a						: Dict					       =					reversed_block_out_channels[min(i + 1						,      len(__snake_case     ) - 1     )]

        a						: List[Any]					       =					i == len(__snake_case     ) - 1

        if up_block_type == "CrossAttnUpBlock2D":
          a						: List[Any]					       =					FlaxCrossAttnUpBlockaD(
              in_channels=__snake_case						,      out_channels=__snake_case						,      prev_output_channel=__snake_case						,      num_layers=self.layers_per_block + 1						,      num_attention_heads=reversed_num_attention_heads[i]						,      add_upsample=not is_final_block						,      dropout=self.dropout						,      use_linear_projection=self.use_linear_projection						,      only_cross_attention=only_cross_attention[i]						,      use_memory_efficient_attention=self.use_memory_efficient_attention						,      dtype=self.dtype						,      )
        else:
          a						: Dict					       =					FlaxUpBlockaD(
              in_channels=__snake_case						,      out_channels=__snake_case						,      prev_output_channel=__snake_case						,      num_layers=self.layers_per_block + 1						,      add_upsample=not is_final_block						,      dropout=self.dropout						,      dtype=self.dtype						,      )

        up_blocks.append(__snake_case     )
        a						: Dict					       =					output_channel
      a						: int					       =					up_blocks

      # out
      a						: int					       =					nn.GroupNorm(num_groups=32						,      epsilon=1e-5     )
      a						: Any					       =					nn.Conv(
          self.out_channels						,      kernel_size=(3, 3)						,      strides=(1, 1)						,      padding=((1, 1), (1, 1))						,      dtype=self.dtype						,      )







    def __call__(				self			:  Optional[Any]						,      __snake_case			:  Dict						,      __snake_case			:  List[str]						,      __snake_case			:  Tuple						,      __snake_case			:  Dict=None						,      __snake_case			:  Any=None						,      __snake_case			:  bool = True						,      __snake_case			:  bool = False						,      ):
      # 1. time
      if not isinstance(__snake_case						,      jnp.ndarray     ):
        a						: Tuple					       =					jnp.array([timesteps]						,      dtype=jnp.intaa     )
      elif isinstance(__snake_case						,      jnp.ndarray     ) and len(timesteps.shape     ) == 0:
        a						: Tuple					       =					timesteps.astype(dtype=jnp.floataa     )
        a						: Optional[int]					       =					jnp.expand_dims(__snake_case						,      0     )

      a						: Optional[Any]					       =					self.time_proj(__snake_case     )
      a						: Optional[int]					       =					self.time_embedding(__snake_case     )

      # 2. pre-process
      a						: str					       =					jnp.transpose(__snake_case						,      (0, 2, 3, 1)     )
      a						: Optional[int]					       =					self.conv_in(__snake_case     )

      # 3. down
      a						: Optional[Any]					       =					(sample,)
      for down_block in self.down_blocks:
        if isinstance(__snake_case						,      __snake_case     ):
          a       ,     a						: Any					       =					down_block(__snake_case						,      __snake_case						,      __snake_case						,      deterministic=not train     )
        else:
          a       ,     a						: Optional[Any]					       =					down_block(__snake_case						,      __snake_case						,      deterministic=not train     )
        down_block_res_samples += res_samples

      if down_block_additional_residuals is not None:
        a						: Tuple					       =					()

        for down_block_res_sample, down_block_additional_residual in zip(
            __snake_case						,      __snake_case     ):
          down_block_res_sample += down_block_additional_residual
          new_down_block_res_samples += (down_block_res_sample,)

        a						: Tuple					       =					new_down_block_res_samples

      # 4. mid
      a						: int					       =					self.mid_block(__snake_case						,      __snake_case						,      __snake_case						,      deterministic=not train     )

      if mid_block_additional_residual is not None:
        sample += mid_block_additional_residual

      # 5. up
      for up_block in self.up_blocks:
        a						: int					       =					down_block_res_samples[-(self.layers_per_block + 1) :]
        a						: List[Any]					       =					down_block_res_samples[: -(self.layers_per_block + 1)]
        if isinstance(__snake_case						,      __snake_case     ):
          a						: Optional[int]					       =					up_block(
              __snake_case						,      temb=__snake_case						,      encoder_hidden_states=__snake_case						,      res_hidden_states_tuple=__snake_case						,      deterministic=not train						,      )
        else:
          a						: Optional[Any]					       =					up_block(__snake_case						,      temb=__snake_case						,      res_hidden_states_tuple=__snake_case						,      deterministic=not train     )

        # 6. post-process
      a						: Any					       =					self.conv_norm_out(__snake_case     )
      a						: List[str]					       =					nn.silu(__snake_case     )
      a						: Optional[int]					       =					self.conv_out(__snake_case     )
      a						: Any					       =					jnp.transpose(__snake_case						,      (0, 3, 1, 2)     )

      if not return_dict:
        return (sample,)

      return FlaxUNetaDConditionOutput(sample=__snake_case     )