# Path: tensorflow_constrained_optimization/python/graph_and_eager_test_case.py
# class _EagerPlaceholder(object):
# class _GraphWrappedSession(object):
# class _EagerWrappedSession(object):
# class GraphAndEagerTestCase(tf.test.TestCase):
#   def __init__(self):
#   def set(self, tensor):
#   def __call__(self):
#   def __init__(self, session):
#   def __enter__(self):
#   def __exit__(self, exc_type, exc_value, traceback):
#   def run(self, tensor, feed_dict=None):
#   def run_ops(self, callback, feed_dict=None):
#   def __init__(self):
#   def __enter__(self):
#   def __exit__(self, exc_type, exc_value, traceback):
#   def run(self, tensor, feed_dict=None):
#   def run_ops(self, callback, feed_dict=None):
#   def wrapped_placeholder(self, dtype, shape=None, name=None):
#   def wrapped_session(self):
# 
# Path: tensorflow_constrained_optimization/python/train/proxy_lagrangian_optimizer.py
# _EXTERNAL_REGRET_TYPE = "external"
# _SWAP_REGRET_TYPE = "swap"
# _ADDITIVE_UPDATE_TYPE = "additive"
# _MULTPILICATIVE_UPDATE_TYPE = "multiplicative"
# def _maximal_eigenvector_power_method(matrix,
#                                       epsilon=1e-6,
#                                       maximum_iterations=100):
#   def while_loop_condition(iteration, eigenvector, old_eigenvector):
#   def while_loop_body(iteration, eigenvector, old_eigenvector):
# def _project_distribution_wrt_euclidean_norm(distribution):
#   def while_loop_condition(iteration, distribution, inactive, old_inactive):
#   def while_loop_body(iteration, distribution, inactive, old_inactive):
# def _project_log_distribution_wrt_kl_divergence(log_distribution):
#   def __init__(self,
#                regret_type,
#                update_type,
#                minimum_multiplier_radius=None,
#                initial_multiplier_radius=None,
#                dual_scale=1.0,
#                variable_fn=tf.Variable):
#   def state(self):
#   def _project_state(self, state):
#   def create_state(self, num_constraints):
#   def is_state_created(self):
#   def _distribution(self, state):
#   def _state_gradient(self, zero_and_constraints, distribution):
#   def get_loss_fn(self, minimization_problem):
#     def loss_gradient_fn(objective, constraints, proxy_constraints, state):
#       def gradient_fn(output_gradient):
#     def partial_loss_gradient_fn():
# def create_proxy_lagrangian_loss(minimization_problem,
#                                  regret_type=_SWAP_REGRET_TYPE,
#                                  update_type=_MULTPILICATIVE_UPDATE_TYPE,
#                                  minimum_multiplier_radius=None,
#                                  initial_multiplier_radius=None,
#                                  dual_scale=1.0,
#                                  variable_fn=tf.Variable):
#   def __init__(self,
#                optimizer,
#                num_constraints=None,
#                constraint_optimizer=None,
#                regret_type=_SWAP_REGRET_TYPE,
#                update_type=_MULTPILICATIVE_UPDATE_TYPE,
#                minimum_multiplier_radius=None,
#                initial_multiplier_radius=None,
#                name="ProxyLagrangianOptimizerV1"):
#   def __init__(self,
#                optimizer,
#                num_constraints=None,
#                constraint_optimizer=None,
#                regret_type=_SWAP_REGRET_TYPE,
#                update_type=_MULTPILICATIVE_UPDATE_TYPE,
#                minimum_multiplier_radius=None,
#                initial_multiplier_radius=None,
#                name="ProxyLagrangianOptimizer"):
# class _ProxyLagrangianFormulation(constrained_optimizer.Formulation):
# class ProxyLagrangianOptimizerV1(constrained_optimizer.ConstrainedOptimizerV1):
# class ProxyLagrangianOptimizerV2(constrained_optimizer.ConstrainedOptimizerV2):
# 
# Path: tensorflow_constrained_optimization/python/train/test_util.py
# class ConstantMinimizationProblem(
#     constrained_minimization_problem.ConstrainedMinimizationProblem):
#   def __init__(self, constraints):
#   def objective(self):
#   def num_constraints(self):
#   def constraints(self):
#   def variables(self):


import numpy as np
import tensorflow as tf
from tensorflow_constrained_optimization.python import graph_and_eager_test_case
from tensorflow_constrained_optimization.python.train import proxy_lagrangian_optimizer
from tensorflow_constrained_optimization.python.train import test_util
        minimization_problem,
        expected_states,
        regret_type="external",
        update_type="multiplicative",
        initial_multiplier_radius=0.8)

  def test_additive_swap_proxy_lagrangian_optimizer(self):
    """Tests that the stochastic matrices update as expected."""
    minimization_problem = test_util.ConstantMinimizationProblem(
        np.array([0.6, -0.1, 0.4]))
    # Calculated using a numpy+python implementation of the algorithm.
    expected_states = [
        np.array([[1.0, 1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 0.0],
                  [0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0]]),
        np.array([[0.66666667, 1.0, 1.0, 1.0], [0.26666667, 0.0, 0.0, 0.0],
                  [0.0, 0.0, 0.0, 0.0], [0.06666667, 0.0, 0.0, 0.0]]),
        np.array([[0.41666667, 0.93333333, 1.0, 0.98333333],
                  [0.46666667, 0.05333333, 0.0,
                   0.01333333], [0.0, 0.0, 0.0, 0.0],
                  [0.11666667, 0.01333333, 0.0, 0.00333333]]),
    ]

    self._test_helper(
        minimization_problem,
        expected_states,
        regret_type="swap",
        update_type="additive")

  def test_multiplicative_swap_proxy_lagrangian_optimizer(self):
    """Tests that the stochastic matrices update as expected."""

# Path: tensorflow_constrained_optimization/python/graph_and_eager_test_case.py
# class _EagerPlaceholder(object):
# class _GraphWrappedSession(object):
# class _EagerWrappedSession(object):
# class GraphAndEagerTestCase(tf.test.TestCase):
#   def __init__(self):
#   def set(self, tensor):
#   def __call__(self):
#   def __init__(self, session):
#   def __enter__(self):
#   def __exit__(self, exc_type, exc_value, traceback):
#   def run(self, tensor, feed_dict=None):
#   def run_ops(self, callback, feed_dict=None):
#   def __init__(self):
#   def __enter__(self):
#   def __exit__(self, exc_type, exc_value, traceback):
#   def run(self, tensor, feed_dict=None):
#   def run_ops(self, callback, feed_dict=None):
#   def wrapped_placeholder(self, dtype, shape=None, name=None):
#   def wrapped_session(self):
# 
# Path: tensorflow_constrained_optimization/python/train/proxy_lagrangian_optimizer.py
# _EXTERNAL_REGRET_TYPE = "external"
# _SWAP_REGRET_TYPE = "swap"
# _ADDITIVE_UPDATE_TYPE = "additive"
# _MULTPILICATIVE_UPDATE_TYPE = "multiplicative"
# def _maximal_eigenvector_power_method(matrix,
#                                       epsilon=1e-6,
#                                       maximum_iterations=100):
#   def while_loop_condition(iteration, eigenvector, old_eigenvector):
#   def while_loop_body(iteration, eigenvector, old_eigenvector):
# def _project_distribution_wrt_euclidean_norm(distribution):
#   def while_loop_condition(iteration, distribution, inactive, old_inactive):
#   def while_loop_body(iteration, distribution, inactive, old_inactive):
# def _project_log_distribution_wrt_kl_divergence(log_distribution):
#   def __init__(self,
#                regret_type,
#                update_type,
#                minimum_multiplier_radius=None,
#                initial_multiplier_radius=None,
#                dual_scale=1.0,
#                variable_fn=tf.Variable):
#   def state(self):
#   def _project_state(self, state):
#   def create_state(self, num_constraints):
#   def is_state_created(self):
#   def _distribution(self, state):
#   def _state_gradient(self, zero_and_constraints, distribution):
#   def get_loss_fn(self, minimization_problem):
#     def loss_gradient_fn(objective, constraints, proxy_constraints, state):
#       def gradient_fn(output_gradient):
#     def partial_loss_gradient_fn():
# def create_proxy_lagrangian_loss(minimization_problem,
#                                  regret_type=_SWAP_REGRET_TYPE,
#                                  update_type=_MULTPILICATIVE_UPDATE_TYPE,
#                                  minimum_multiplier_radius=None,
#                                  initial_multiplier_radius=None,
#                                  dual_scale=1.0,
#                                  variable_fn=tf.Variable):
#   def __init__(self,
#                optimizer,
#                num_constraints=None,
#                constraint_optimizer=None,
#                regret_type=_SWAP_REGRET_TYPE,
#                update_type=_MULTPILICATIVE_UPDATE_TYPE,
#                minimum_multiplier_radius=None,
#                initial_multiplier_radius=None,
#                name="ProxyLagrangianOptimizerV1"):
#   def __init__(self,
#                optimizer,
#                num_constraints=None,
#                constraint_optimizer=None,
#                regret_type=_SWAP_REGRET_TYPE,
#                update_type=_MULTPILICATIVE_UPDATE_TYPE,
#                minimum_multiplier_radius=None,
#                initial_multiplier_radius=None,
#                name="ProxyLagrangianOptimizer"):
# class _ProxyLagrangianFormulation(constrained_optimizer.Formulation):
# class ProxyLagrangianOptimizerV1(constrained_optimizer.ConstrainedOptimizerV1):
# class ProxyLagrangianOptimizerV2(constrained_optimizer.ConstrainedOptimizerV2):
# 
# Path: tensorflow_constrained_optimization/python/train/test_util.py
# class ConstantMinimizationProblem(
#     constrained_minimization_problem.ConstrainedMinimizationProblem):
#   def __init__(self, constraints):
#   def objective(self):
#   def num_constraints(self):
#   def constraints(self):
#   def variables(self):


# Path: tensorflow_constrained_optimization/python/train/proxy_lagrangian_optimizer_test.py
import numpy as np
import tensorflow as tf
from tensorflow_constrained_optimization.python import graph_and_eager_test_case
from tensorflow_constrained_optimization.python.train import proxy_lagrangian_optimizer
from tensorflow_constrained_optimization.python.train import test_util

        minimization_problem,
        expected_states,
        regret_type="external",
        update_type="multiplicative",
        initial_multiplier_radius=0.8)

  def test_additive_swap_proxy_lagrangian_optimizer(self):
    """Tests that the stochastic matrices update as expected."""
    minimization_problem = test_util.ConstantMinimizationProblem(
        np.array([0.6, -0.1, 0.4]))
    # Calculated using a numpy+python implementation of the algorithm.
    expected_states = [
        np.array([[1.0, 1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 0.0],
                  [0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0]]),
        np.array([[0.66666667, 1.0, 1.0, 1.0], [0.26666667, 0.0, 0.0, 0.0],
                  [0.0, 0.0, 0.0, 0.0], [0.06666667, 0.0, 0.0, 0.0]]),
        np.array([[0.41666667, 0.93333333, 1.0, 0.98333333],
                  [0.46666667, 0.05333333, 0.0,
                   0.01333333], [0.0, 0.0, 0.0, 0.0],
                  [0.11666667, 0.01333333, 0.0, 0.00333333]]),
    ]

    self._test_helper(
        minimization_problem,
        expected_states,
        regret_type="swap",
        update_type="additive")

  def test_multiplicative_swap_proxy_lagrangian_optimizer(self):
    """Tests that the stochastic matrices update as expected."""

    minimization_problem = test_util.ConstantMinimizationProblem(