# Path: tensorflow_constrained_optimization/python/train/constrained_optimizer.py
# class Formulation(tf.Module):
# class ConstrainedOptimizerV1(tf.compat.v1.train.Optimizer):
# class ConstrainedOptimizerV2(tf.keras.optimizers.Optimizer):
#   def __init__(self, name=None):
#   def state(self):
#   def create_state(self, num_constraints):
#   def is_state_created(self):
#   def get_loss_fn(self, minimization_problem):
#   def __init__(self,
#                formulation,
#                optimizer,
#                num_constraints=None,
#                constraint_optimizer=None,
#                name="ConstrainedOptimizerV1"):
#   def num_constraints(self):
#   def num_constraints(self, num_constraints):
#   def variables(self):
#   def trainable_variables(self):
#   def non_trainable_variables(self):
#   def compute_gradients(self,
#                         loss,
#                         var_list=None,
#                         gate_gradients=tf.compat.v1.train.Optimizer.GATE_OP,
#                         aggregation_method=None,
#                         colocate_gradients_with_ops=False,
#                         grad_loss=None):
#   def _create_slots(self, var_list):
#   def _prepare(self):
#   def _apply_dense(self, gradient, variable, *args, **kwargs):
#   def _apply_sparse(self, gradient, variable, *args, **kwargs):
#   def _resource_apply_dense(self, gradient, handle, *args, **kwargs):
#   def _resource_apply_sparse(self, gradient, handle, *args, **kwargs):
#   def __init__(self,
#                formulation,
#                optimizer,
#                num_constraints=None,
#                constraint_optimizer=None,
#                name="ConstrainedOptimizerV2"):
#   def num_constraints(self):
#   def num_constraints(self, num_constraints):
#   def variables(self):
#   def trainable_variables(self):
#   def non_trainable_variables(self):
#   def get_gradients(self, loss, params):
#   def _split_var_list(self, var_list):
#   def _compute_gradients(self, loss, var_list, grad_loss=None, tape=None):
#   def _create_slots(self, var_list):
#   def _prepare(self, var_list):
#   def _create_hypers(self):
#   def get_config(self):
#   def _resource_apply_dense(self, gradient, handle, *args, **kwargs):
#   def _resource_apply_sparse(self, gradient, handle, *args, **kwargs):


import numpy as np
import tensorflow as tf
from tensorflow_constrained_optimization.python.train import constrained_optimizer

    Args:
      optimizer: `tf.compat.v1.train.Optimizer`, used to optimize the objective
        and proxy_constraints portion of `ConstrainedMinimizationProblem`. If
        constraint_optimizer is not provided, this will also be used to optimize
        the Lagrange multipliers.
      num_constraints: optional int, the number of constraints in the
        `ConstrainedMinimizationProblem` that will eventually be minimized. If
        this argument is provided, then the internal state will be created
        inside this constructor. Otherwise, it will be created inside the
        num_constraints setter or, if that isn't called, it will be created in
        first call to minimize() or compute_gradients().
      constraint_optimizer: optional `tf.compat.v1.train.Optimizer`, used to
        optimize the Lagrange multipliers.
      maximum_multiplier_radius: float, an optional upper bound to impose on the
        sum of the Lagrange multipliers.
      name: as in `ConstrainedOptimizerV1`.

    Raises:
      ValueError: if the maximum_multiplier_radius parameter is non-positive.
    """
    super(LagrangianOptimizerV1, self).__init__(
        _LagrangianFormulation(
            maximum_multiplier_radius=maximum_multiplier_radius),
        optimizer=optimizer,
        num_constraints=num_constraints,
        constraint_optimizer=constraint_optimizer,
        name=name)



# Path: tensorflow_constrained_optimization/python/train/constrained_optimizer.py
# class Formulation(tf.Module):
# class ConstrainedOptimizerV1(tf.compat.v1.train.Optimizer):
# class ConstrainedOptimizerV2(tf.keras.optimizers.Optimizer):
#   def __init__(self, name=None):
#   def state(self):
#   def create_state(self, num_constraints):
#   def is_state_created(self):
#   def get_loss_fn(self, minimization_problem):
#   def __init__(self,
#                formulation,
#                optimizer,
#                num_constraints=None,
#                constraint_optimizer=None,
#                name="ConstrainedOptimizerV1"):
#   def num_constraints(self):
#   def num_constraints(self, num_constraints):
#   def variables(self):
#   def trainable_variables(self):
#   def non_trainable_variables(self):
#   def compute_gradients(self,
#                         loss,
#                         var_list=None,
#                         gate_gradients=tf.compat.v1.train.Optimizer.GATE_OP,
#                         aggregation_method=None,
#                         colocate_gradients_with_ops=False,
#                         grad_loss=None):
#   def _create_slots(self, var_list):
#   def _prepare(self):
#   def _apply_dense(self, gradient, variable, *args, **kwargs):
#   def _apply_sparse(self, gradient, variable, *args, **kwargs):
#   def _resource_apply_dense(self, gradient, handle, *args, **kwargs):
#   def _resource_apply_sparse(self, gradient, handle, *args, **kwargs):
#   def __init__(self,
#                formulation,
#                optimizer,
#                num_constraints=None,
#                constraint_optimizer=None,
#                name="ConstrainedOptimizerV2"):
#   def num_constraints(self):
#   def num_constraints(self, num_constraints):
#   def variables(self):
#   def trainable_variables(self):
#   def non_trainable_variables(self):
#   def get_gradients(self, loss, params):
#   def _split_var_list(self, var_list):
#   def _compute_gradients(self, loss, var_list, grad_loss=None, tape=None):
#   def _create_slots(self, var_list):
#   def _prepare(self, var_list):
#   def _create_hypers(self):
#   def get_config(self):
#   def _resource_apply_dense(self, gradient, handle, *args, **kwargs):
#   def _resource_apply_sparse(self, gradient, handle, *args, **kwargs):


# Path: tensorflow_constrained_optimization/python/train/lagrangian_optimizer.py
import numpy as np
import tensorflow as tf
from tensorflow_constrained_optimization.python.train import constrained_optimizer


    Args:
      optimizer: `tf.compat.v1.train.Optimizer`, used to optimize the objective
        and proxy_constraints portion of `ConstrainedMinimizationProblem`. If
        constraint_optimizer is not provided, this will also be used to optimize
        the Lagrange multipliers.
      num_constraints: optional int, the number of constraints in the
        `ConstrainedMinimizationProblem` that will eventually be minimized. If
        this argument is provided, then the internal state will be created
        inside this constructor. Otherwise, it will be created inside the
        num_constraints setter or, if that isn't called, it will be created in
        first call to minimize() or compute_gradients().
      constraint_optimizer: optional `tf.compat.v1.train.Optimizer`, used to
        optimize the Lagrange multipliers.
      maximum_multiplier_radius: float, an optional upper bound to impose on the
        sum of the Lagrange multipliers.
      name: as in `ConstrainedOptimizerV1`.

    Raises:
      ValueError: if the maximum_multiplier_radius parameter is non-positive.
    """
    super(LagrangianOptimizerV1, self).__init__(
        _LagrangianFormulation(
            maximum_multiplier_radius=maximum_multiplier_radius),
        optimizer=optimizer,
        num_constraints=num_constraints,
        constraint_optimizer=constraint_optimizer,
        name=name)



class LagrangianOptimizerV2(constrained_optimizer.ConstrainedOptimizerV2):