



from typing import Optional, Tuple

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

from transformers import FLAX_MODEL_MAPPING, FlaxCLIPVisionModel
from transformers.modeling_flax_utils import FlaxPreTrainedModel
from transformers.models.clip.modeling_flax_clip import FlaxCLIPOutput
from transformers.utils import logging


a_								=   logging.get_logger(__name__)



class 	__lowerCAmelCase       (		nn.Module				):
 lowerCAmelCase__       =					42
 lowerCAmelCase__       =					jnp.floataa




 def     lowerCamelCase (  self			):



    '''simple docstring'''
    __lowerCamelCase  							=      self.config.text_config
    __lowerCamelCase  							=      self.config.vision_config

    __lowerCamelCase  							=      self.config.projection_dim
    __lowerCamelCase  							=      text_config.hidden_size
    __lowerCamelCase  							=      vision_config.hidden_size

    __lowerCamelCase  							=      FLAX_MODEL_MAPPING[self.config.text_config.__class__].module_class
    __lowerCamelCase  							=      FLAX_MODEL_MAPPING.get(self.config.vision_config.__class__		,			__UpperCAmelCase			).module_class

    __lowerCamelCase  							=      text_module(__UpperCAmelCase		,			dtype=self.dtype			)
    __lowerCamelCase  							=      vision_module(__UpperCAmelCase		,			dtype=self.dtype			)

    __lowerCamelCase  							=      nn.Dense(
        self.projection_dim		,			dtype=self.dtype		,			kernel_init=jax.nn.initializers.normal(0.02			)		,			use_bias=__UpperCAmelCase		,			)
    __lowerCamelCase  							=      nn.Dense(
        self.projection_dim		,			dtype=self.dtype		,			kernel_init=jax.nn.initializers.normal(0.02			)		,			use_bias=__UpperCAmelCase		,			)
    __lowerCamelCase  							=      self.param('''logit_scale'''		,			jax.nn.initializers.ones		,			[]			)




 def __call__(  self		,			__UpperCAmelCase=None		,			__UpperCAmelCase=None		,			__UpperCAmelCase=None		,			__UpperCAmelCase=None		,			__UpperCAmelCase=None		,			__UpperCAmelCase = True		,			__UpperCAmelCase=None		,			__UpperCAmelCase=None		,			__UpperCAmelCase=None		,			):



    '''simple docstring'''
    __lowerCamelCase  							=      return_dict if return_dict is not None else self.config.return_dict

    __lowerCamelCase  							=      self.vision_model(
        pixel_values=__UpperCAmelCase		,			deterministic=__UpperCAmelCase		,			output_attentions=__UpperCAmelCase		,			output_hidden_states=__UpperCAmelCase		,			return_dict=__UpperCAmelCase		,			)

    __lowerCamelCase  							=      self.text_model(
        input_ids=__UpperCAmelCase		,			attention_mask=__UpperCAmelCase		,			token_type_ids=__UpperCAmelCase		,			position_ids=__UpperCAmelCase		,			deterministic=__UpperCAmelCase		,			output_attentions=__UpperCAmelCase		,			output_hidden_states=__UpperCAmelCase		,			return_dict=__UpperCAmelCase		,			)

    __lowerCamelCase  							=      vision_outputs[1]
    __lowerCamelCase  							=      self.visual_projection(__UpperCAmelCase			)

    __lowerCamelCase  							=      text_outputs[1]
    __lowerCamelCase  							=      self.text_projection(__UpperCAmelCase			)

    # normalized features
    __lowerCamelCase  							=      image_embeds / jnp.linalg.norm(__UpperCAmelCase		,			axis=-1		,			keepdims=__UpperCAmelCase			)
    __lowerCamelCase  							=      text_embeds / jnp.linalg.norm(__UpperCAmelCase		,			axis=-1		,			keepdims=__UpperCAmelCase			)

    # cosine similarity as logits
    __lowerCamelCase  							=      jnp.exp(self.logit_scale			)
    __lowerCamelCase  							=      jnp.matmul(__UpperCAmelCase		,			image_embeds.T			) * logit_scale
    __lowerCamelCase  							=      logits_per_text.T

    if not return_dict:
       return (logits_per_image, logits_per_text, text_embeds, image_embeds, text_outputs, vision_outputs)

    return FlaxCLIPOutput(
        logits_per_image=__UpperCAmelCase		,			logits_per_text=__UpperCAmelCase		,			text_embeds=__UpperCAmelCase		,			image_embeds=__UpperCAmelCase		,			text_model_output=__UpperCAmelCase		,			vision_model_output=__UpperCAmelCase		,			)



class 	__lowerCAmelCase       (		lowerCAmelCase__				):
 lowerCAmelCase__       =					HybridCLIPConfig
 lowerCAmelCase__       =					FlaxHybridCLIPModule




 def __init__(  self		,			__UpperCAmelCase		,			__UpperCAmelCase = None		,			__UpperCAmelCase = 0		,			__UpperCAmelCase = jnp.floataa		,			**__UpperCAmelCase		,			):



    '''simple docstring'''
    if input_shape is None:
       __lowerCamelCase  							=      ((1, 1), (1, config.vision_config.image_size, config.vision_config.image_size, 3))

    __lowerCamelCase  							=      self.module_class(config=__UpperCAmelCase		,			dtype=__UpperCAmelCase		,			**__UpperCAmelCase			)
    super().__init__(__UpperCAmelCase		,			__UpperCAmelCase		,			input_shape=__UpperCAmelCase		,			seed=__UpperCAmelCase		,			dtype=__UpperCAmelCase			)




 def     lowerCamelCase (  self		,			__UpperCAmelCase		,			__UpperCAmelCase		,			__UpperCAmelCase = None			):



    '''simple docstring'''
    # init input tensor
    __lowerCamelCase  							=      jnp.zeros(input_shape[0]		,			dtype='''i4'''			)
    __lowerCamelCase  							=      jnp.broadcast_to(jnp.arange(jnp.atleast_ad(__UpperCAmelCase			).shape[-1]			)		,			input_shape[0]			)
    __lowerCamelCase  							=      jnp.ones_like(__UpperCAmelCase			)
    __lowerCamelCase  							=      jnp.ones_like(__UpperCAmelCase			)

    __lowerCamelCase  							=      jax.random.normal(__UpperCAmelCase		,			input_shape[1]			)

    __lowerCamelCase							,__lowerCamelCase  							=      jax.random.split(__UpperCAmelCase			)
    __lowerCamelCase  							=      {'''params''': params_rng, '''dropout''': dropout_rng}

    return self.module.init(__UpperCAmelCase		,			__UpperCAmelCase		,			__UpperCAmelCase		,			__UpperCAmelCase		,			__UpperCAmelCase		,			__UpperCAmelCase			)["params"]




 def __call__(  self		,			__UpperCAmelCase		,			__UpperCAmelCase		,			__UpperCAmelCase=None		,			__UpperCAmelCase=None		,			__UpperCAmelCase=None		,			__UpperCAmelCase = None		,			__UpperCAmelCase = None		,			__UpperCAmelCase = False		,			__UpperCAmelCase = None		,			__UpperCAmelCase = None		,			__UpperCAmelCase = None		,			):



    '''simple docstring'''
    __lowerCamelCase  							=      output_attentions if output_attentions is not None else self.config.output_attentions
    __lowerCamelCase  							=      (
        output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
    )
    __lowerCamelCase  							=      return_dict if return_dict is not None else self.config.return_dict

    if position_ids is None:
       __lowerCamelCase  							=      jnp.broadcast_to(jnp.arange(jnp.atleast_ad(__UpperCAmelCase			).shape[-1]			)		,			input_ids.shape			)

    if token_type_ids is None:
       __lowerCamelCase  							=      jnp.zeros_like(__UpperCAmelCase			)

    if attention_mask is None:
       __lowerCamelCase  							=      jnp.ones_like(__UpperCAmelCase			)

    # Handle any PRNG if needed
    __lowerCamelCase  							=      {}
    if dropout_rng is not None:
       __lowerCamelCase  							=      dropout_rng

    return self.module.apply(
        {'''params''': params or self.params}		,			jnp.array(__UpperCAmelCase		,			dtype='''i4'''			)		,			jnp.array(__UpperCAmelCase		,			dtype=jnp.floataa			)		,			jnp.array(__UpperCAmelCase		,			dtype='''i4'''			)		,			jnp.array(__UpperCAmelCase		,			dtype='''i4'''			)		,			jnp.array(__UpperCAmelCase		,			dtype='''i4'''			)		,			not train		,			__UpperCAmelCase		,			__UpperCAmelCase		,			__UpperCAmelCase		,			rngs=__UpperCAmelCase		,			)




 def     lowerCamelCase (  self		,			__UpperCAmelCase		,			__UpperCAmelCase=None		,			__UpperCAmelCase=None		,			__UpperCAmelCase=None		,			__UpperCAmelCase = None		,			__UpperCAmelCase = None		,			__UpperCAmelCase=False		,			):



    '''simple docstring'''
    if position_ids is None:
       __lowerCamelCase  							=      jnp.broadcast_to(jnp.arange(jnp.atleast_ad(__UpperCAmelCase			).shape[-1]			)		,			input_ids.shape			)

    if token_type_ids is None:
       __lowerCamelCase  							=      jnp.zeros_like(__UpperCAmelCase			)

    if attention_mask is None:
       __lowerCamelCase  							=      jnp.ones_like(__UpperCAmelCase			)

    # Handle any PRNG if needed
    __lowerCamelCase  							=      {}
    if dropout_rng is not None:
       __lowerCamelCase  							=      dropout_rng

    def _get_features(__UpperCAmelCase		,			__UpperCAmelCase		,			__UpperCAmelCase		,			__UpperCAmelCase		,			__UpperCAmelCase		,			__UpperCAmelCase			):
       __lowerCamelCase  							=      module.text_model(
           input_ids=__UpperCAmelCase		,			attention_mask=__UpperCAmelCase		,			position_ids=__UpperCAmelCase		,			token_type_ids=__UpperCAmelCase		,			deterministic=__UpperCAmelCase		,			)
       __lowerCamelCase  							=      text_outputs[1]
       __lowerCamelCase  							=      module.text_projection(__UpperCAmelCase			)
       return text_features

    return self.module.apply(
        {'''params''': params or self.params}		,			jnp.array(__UpperCAmelCase		,			dtype='''i4'''			)		,			jnp.array(__UpperCAmelCase		,			dtype='''i4'''			)		,			jnp.array(__UpperCAmelCase		,			dtype='''i4'''			)		,			jnp.array(__UpperCAmelCase		,			dtype='''i4'''			)		,			not train		,			method=_get_features		,			rngs=__UpperCAmelCase		,			)




 def     lowerCamelCase (  self		,			__UpperCAmelCase		,			__UpperCAmelCase = None		,			__UpperCAmelCase = None		,			__UpperCAmelCase=False			):



    '''simple docstring'''
    __lowerCamelCase  							=      {}
    if dropout_rng is not None:
       __lowerCamelCase  							=      dropout_rng

    def _get_features(__UpperCAmelCase		,			__UpperCAmelCase		,			__UpperCAmelCase			):
       __lowerCamelCase  							=      module.vision_model(pixel_values=__UpperCAmelCase		,			deterministic=__UpperCAmelCase			)
       __lowerCamelCase  							=      vision_outputs[1]  # pooled_output
       __lowerCamelCase  							=      module.visual_projection(__UpperCAmelCase			)
       return image_features

    return self.module.apply(
        {'''params''': params or self.params}		,			jnp.array(__UpperCAmelCase		,			dtype=jnp.floataa			)		,			not train		,			method=_get_features		,			rngs=__UpperCAmelCase		,			)




 @classmethod
 def     lowerCamelCase (  cls		,			__UpperCAmelCase = None		,			__UpperCAmelCase = None		,			*__UpperCAmelCase		,			**__UpperCAmelCase		,			):



    '''simple docstring'''
    __lowerCamelCase  							=      {
        argument[len('''text_'''			) :]: value for argument, value in kwargs.items() if argument.startswith('''text_'''			)
    }

    __lowerCamelCase  							=      {
        argument[len('''vision_'''			) :]: value for argument, value in kwargs.items() if argument.startswith('''vision_'''			)
    }

    # remove text, vision kwargs from kwargs
    for key in kwargs_text.keys():
       del kwargs["text_" + key]
    for key in kwargs_vision.keys():
       del kwargs["vision_" + key]

    # Load and initialize the text and vision model
    __lowerCamelCase  							=      kwargs_text.pop('''model'''		,			__UpperCAmelCase			)
    if text_model is None:
       assert (
           text_model_name_or_path is not None
       ), "If `model` is not defined as an argument, a `text_model_name_or_path` has to be defined"
       from transformers import FlaxAutoModel

       if "config" not in kwargs_text:
          from transformers import AutoConfig

          __lowerCamelCase  							=      AutoConfig.from_pretrained(__UpperCAmelCase			)
          __lowerCamelCase  							=      text_config

       __lowerCamelCase  							=      FlaxAutoModel.from_pretrained(__UpperCAmelCase		,			*__UpperCAmelCase		,			**__UpperCAmelCase			)

    __lowerCamelCase  							=      kwargs_vision.pop('''model'''		,			__UpperCAmelCase			)
    if vision_model is None:
       assert (
           vision_model_name_or_path is not None
       ), "If `model` is not defined as an argument, a `vision_model_name_or_path` has to be defined"
       from transformers import FlaxAutoModel

       if "config" not in kwargs_vision:
          from transformers import AutoConfig

          __lowerCamelCase  							=      AutoConfig.from_pretrained(__UpperCAmelCase			)
          __lowerCamelCase  							=      vision_config

       __lowerCamelCase  							=      FlaxAutoModel.from_pretrained(__UpperCAmelCase		,			*__UpperCAmelCase		,			**__UpperCAmelCase			)

    # instantiate config with corresponding kwargs
    __lowerCamelCase  							=      kwargs.pop('''dtype'''		,			jnp.floataa			)
    __lowerCamelCase  							=      HybridCLIPConfig.from_text_vision_configs(text_model.config		,			vision_model.config		,			**__UpperCAmelCase			)

    # init model
    __lowerCamelCase  							=      cls(__UpperCAmelCase		,			*__UpperCAmelCase		,			dtype=__UpperCAmelCase		,			**__UpperCAmelCase			)

    if vision_config.model_type == "clip":
       __lowerCamelCase  							=      vision_model.params['''vision_model''']
       __lowerCamelCase  							=      vision_model.params['''visual_projection''']['''kernel''']
    else:
       __lowerCamelCase  							=      vision_model.params

    __lowerCamelCase  							=      text_model.params

    return model











import math



class 	__lowerCAmelCase       :




 def __init__(  self		,			__UpperCAmelCase		,			__UpperCAmelCase		,			__UpperCAmelCase		,			__UpperCAmelCase			):



    '''simple docstring'''
    __lowerCamelCase  							=      x
    __lowerCamelCase  							=      y
    __lowerCamelCase  							=      step_size
    __lowerCamelCase  							=      function_to_optimize




 def     lowerCamelCase (  self			):



    '''simple docstring'''
    return self.function(self.x		,			self.y			)




 def     lowerCamelCase (  self			):



    '''simple docstring'''
    __lowerCamelCase  							=      self.step_size
    return [
        SearchProblem(__UpperCAmelCase		,			__UpperCAmelCase		,			__UpperCAmelCase		,			self.function			)
        for x, y in (
            (self.x - step_size, self.y - step_size),
            (self.x - step_size, self.y),
            (self.x - step_size, self.y + step_size),
            (self.x, self.y - step_size),
            (self.x, self.y + step_size),
            (self.x + step_size, self.y - step_size),
            (self.x + step_size, self.y),
            (self.x + step_size, self.y + step_size),
        )
    ]




 def __hash__(  self			):



    '''simple docstring'''
    return hash(str(self			)			)




 def __eq__(  self		,			__UpperCAmelCase			):



    '''simple docstring'''
    if isinstance(__UpperCAmelCase		,			__UpperCAmelCase			):
       return hash(str(self			)			) == hash(str(__UpperCAmelCase			)			)
    return False




 def __str__(  self			):



    '''simple docstring'''
    return F"""x: {self.x} y: {self.y}"""





def 						a__     (						_UpperCamelCase     :	Tuple	,_UpperCamelCase     :	bool = True	,_UpperCamelCase     :	float = math.inf	,_UpperCamelCase     :	float = -math.inf	,_UpperCamelCase     :	float = math.inf	,_UpperCamelCase     :	float = -math.inf	,_UpperCamelCase     :	bool = False	,_UpperCamelCase     :	int = 1_00_00	,):
   __lowerCamelCase  							=      search_prob
   __lowerCamelCase  							=      []  # list to store the current score at each iteration
   __lowerCamelCase  							=      0
   __lowerCamelCase  							=      False
   __lowerCamelCase  							=      set()
   while not solution_found and iterations < max_iter:
      visited.add(_UpperCamelCase							)
      iterations += 1
      __lowerCamelCase  							=      current_state.score()
      scores.append(_UpperCamelCase							)
      __lowerCamelCase  							=      current_state.get_neighbors()
      __lowerCamelCase  							=      -math.inf
      __lowerCamelCase  							=      math.inf
      __lowerCamelCase  							=      None  # to hold the next best neighbor
      for neighbor in neighbors:
         if neighbor in visited:
            continue  # do not want to visit the same state again
         if (
             neighbor.x > max_x
             or neighbor.x < min_x
             or neighbor.y > max_y
             or neighbor.y < min_y
         ):
            continue  # neighbor outside our bounds
         __lowerCamelCase  							=      neighbor.score() - current_score
         if find_max:  # finding max
            # going to direction with greatest ascent
            if change > max_change and change > 0:
               __lowerCamelCase  							=      change
               __lowerCamelCase  							=      neighbor
         else:  # finding min
            # to direction with greatest descent
            if change < min_change and change < 0:
               __lowerCamelCase  							=      change
               __lowerCamelCase  							=      neighbor
      if next_state is not None:
         # we found at least one neighbor which improved the current state
         __lowerCamelCase  							=      next_state
      else:
         # since we have no neighbor that improves the solution we stop the search
         __lowerCamelCase  							=      True

   if visualization:
      from matplotlib import pyplot as plt

      plt.plot(range(_UpperCamelCase							)	,_UpperCamelCase							)
      plt.xlabel('''Iterations'''							)
      plt.ylabel('''Function values'''							)
      plt.show()

   return current_state


if __name__ == "__main__":
  import doctest

  doctest.testmod()





  def 						a__     (						_UpperCamelCase     :	Union[str, Any]	,_UpperCamelCase     :	Union[str, Any]							):
     return (x**2) + (y**2)

  # starting the problem with initial coordinates (3, 4)
  a_								=   SearchProblem(x=3, y=4, step_size=1, function_to_optimize=test_fa)
  a_								=   hill_climbing(prob, find_max=False)
  print(
      """The minimum score for f(x, y) = x^2 + y^2 found via hill climbing: """
      f"{local_min.score()}"
  )

  # starting the problem with initial coordinates (12, 47)
  a_								=   SearchProblem(x=12, y=47, step_size=1, function_to_optimize=test_fa)
  a_								=   hill_climbing(
      prob, find_max=False, max_x=100, min_x=5, max_y=50, min_y=-5, visualization=True
  )
  print(
      """The minimum score for f(x, y) = x^2 + y^2 with the domain 100 > x > 5 """
      f"and 50 > y > - 5 found via hill climbing: {local_min.score()}"
  )





  def 						a__     (						_UpperCamelCase     :	int	,_UpperCamelCase     :	Dict							):
     return (3 * x**2) - (6 * y)

  a_								=   SearchProblem(x=3, y=4, step_size=1, function_to_optimize=test_fa)
  a_								=   hill_climbing(prob, find_max=True)





  print(
      """The maximum score for f(x, y) = x^2 + y^2 found via hill climbing: """
      f"{local_min.score()}"
  )






