# Path: jaxopt/implicit_diff.py

# 
# Path: jaxopt/_src/test_util.py
# def ridge_solver(X, y, lam):
# def ridge_solver_jac(X, y, lam, eps=1e-4):
# def lasso_skl(X, y, lam, tol=1e-5, fit_intercept=False):
# def lasso_skl_jac(X, y, lam, tol=1e-5, fit_intercept=False, eps=1e-4):
# def enet_skl(X, y, params_prox, tol=1e-5, fit_intercept=False):
# def enet_skl_jac(X, y, params_prox, tol=1e-5, fit_intercept=False, eps=1e-5):
# def multitask_lasso_skl(X, Y, lam, tol=1e-5):
# def logreg_skl(X, y, lam, tol=1e-5, fit_intercept=False,
#                penalty="l2", multiclass=True):
#   def _reshape_coef(coef):
# def logreg_skl_jac(X, y, lam, tol=1e-5, fit_intercept=False, penalty="l2",
#                    multiclass=True, eps=1e-5):
# def multiclass_linear_svm_skl(X, y, lam, tol=1e-5):
# def multiclass_linear_svm_skl_jac(X, y, lam, tol=1e-5, eps=1e-5):
# def lsq_linear_osp(X, y, bounds, tol=1e-10, max_iter=None):
# def lsq_linear_cube_osp(X, y, l, tol=1e-10, max_iter=None):
# def lsq_linear_cube_osp_jac(X, y, l, eps=1e-5, tol=1e-10, max_iter=None):
# def check_states_have_same_types(state1, state2):
# def _canonicalize_dtype(x64_enabled, dtype):
# def canonicalize_dtype(dtype):
# def _dtype(x):
# def default_tolerance():
# def tolerance(dtype, tol=None):
# def device_under_test():
# def _assert_numpy_allclose(a, b, atol=None, rtol=None, err_msg=''):
# def is_sequence(x):
#   def assertArraysEqual(self, x, y, *, check_dtypes=True, err_msg=''):
#   def assertArraysAllClose(self, x, y, *, check_dtypes=True, atol=None,
#                            rtol=None, err_msg=''):
#   def assertDtypesMatch(self, x, y, *, canonicalize_dtypes=True):
#   def assertAllClose(self, x, y, *, check_dtypes=True, atol=None, rtol=None,
#                      canonicalize_dtypes=True, err_msg=''):
#   XX = jnp.dot(X.T, X)
#   I = jnp.eye(X.shape[1])
# class JaxoptTestCase(parameterized.TestCase):


import functools
import jax
import jax.numpy as jnp
from absl.testing import absltest
from absl.testing import parameterized
from jaxopt import implicit_diff as idf
from jaxopt._src import test_util
from sklearn import datasets
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.







def ridge_objective(params, lam, X, y):
  residuals = jnp.dot(X, params) - y
  return 0.5 * jnp.mean(residuals ** 2) + 0.5 * lam * jnp.sum(params ** 2)


# def ridge_solver(init_params, lam, X, y):
def ridge_solver(init_params, lam, X, y):
  del init_params  # not used
  XX = jnp.dot(X.T, X)
  Xy = jnp.dot(X.T, y)
  I = jnp.eye(X.shape[1])
  return jnp.linalg.solve(XX + lam * len(y) * I, Xy)


def ridge_solver_with_kwargs(init_params, **kw):
  return ridge_solver(init_params, kw['lam'], kw['X'], kw['y'])



# Path: jaxopt/implicit_diff.py

# 
# Path: jaxopt/_src/test_util.py
# def ridge_solver(X, y, lam):
# def ridge_solver_jac(X, y, lam, eps=1e-4):
# def lasso_skl(X, y, lam, tol=1e-5, fit_intercept=False):
# def lasso_skl_jac(X, y, lam, tol=1e-5, fit_intercept=False, eps=1e-4):
# def enet_skl(X, y, params_prox, tol=1e-5, fit_intercept=False):
# def enet_skl_jac(X, y, params_prox, tol=1e-5, fit_intercept=False, eps=1e-5):
# def multitask_lasso_skl(X, Y, lam, tol=1e-5):
# def logreg_skl(X, y, lam, tol=1e-5, fit_intercept=False,
#                penalty="l2", multiclass=True):
#   def _reshape_coef(coef):
# def logreg_skl_jac(X, y, lam, tol=1e-5, fit_intercept=False, penalty="l2",
#                    multiclass=True, eps=1e-5):
# def multiclass_linear_svm_skl(X, y, lam, tol=1e-5):
# def multiclass_linear_svm_skl_jac(X, y, lam, tol=1e-5, eps=1e-5):
# def lsq_linear_osp(X, y, bounds, tol=1e-10, max_iter=None):
# def lsq_linear_cube_osp(X, y, l, tol=1e-10, max_iter=None):
# def lsq_linear_cube_osp_jac(X, y, l, eps=1e-5, tol=1e-10, max_iter=None):
# def check_states_have_same_types(state1, state2):
# def _canonicalize_dtype(x64_enabled, dtype):
# def canonicalize_dtype(dtype):
# def _dtype(x):
# def default_tolerance():
# def tolerance(dtype, tol=None):
# def device_under_test():
# def _assert_numpy_allclose(a, b, atol=None, rtol=None, err_msg=''):
# def is_sequence(x):
#   def assertArraysEqual(self, x, y, *, check_dtypes=True, err_msg=''):
#   def assertArraysAllClose(self, x, y, *, check_dtypes=True, atol=None,
#                            rtol=None, err_msg=''):
#   def assertDtypesMatch(self, x, y, *, canonicalize_dtypes=True):
#   def assertAllClose(self, x, y, *, check_dtypes=True, atol=None, rtol=None,
#                      canonicalize_dtypes=True, err_msg=''):
#   XX = jnp.dot(X.T, X)
#   I = jnp.eye(X.shape[1])
# class JaxoptTestCase(parameterized.TestCase):


# Path: tests/implicit_diff_test.py
import functools
import jax
import jax.numpy as jnp
from absl.testing import absltest
from absl.testing import parameterized
from jaxopt import implicit_diff as idf
from jaxopt._src import test_util
from sklearn import datasets

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.







def ridge_objective(params, lam, X, y):
  residuals = jnp.dot(X, params) - y
  return 0.5 * jnp.mean(residuals ** 2) + 0.5 * lam * jnp.sum(params ** 2)


# def ridge_solver(init_params, lam, X, y):
def ridge_solver(init_params, lam, X, y):
  del init_params  # not used
  XX = jnp.dot(X.T, X)
  Xy = jnp.dot(X.T, y)
  I = jnp.eye(X.shape[1])
  return jnp.linalg.solve(XX + lam * len(y) * I, Xy)


def ridge_solver_with_kwargs(init_params, **kw):
  return ridge_solver(init_params, kw['lam'], kw['X'], kw['y'])



class ImplicitDiffTest(test_util.JaxoptTestCase):