# Path: sksurv/linear_model/aft.py
# class IPCRidge(Ridge, SurvivalAnalysisMixin):
#     """Accelerated failure time model with inverse probability of censoring weights.
# 
#     This model assumes a regression model of the form
# 
#     .. math::
# 
#         \\log y = \\beta_0 + \\mathbf{X} \\beta + \\epsilon
# 
#     L2-shrinkage is applied to the coefficients :math:`\\beta` and
#     each sample is weighted by the inverse probability of censoring
#     to account for right censoring (under the assumption that
#     censoring is independent of the features, i.e., random censoring).
# 
#     See [1]_ for further description.
# 
#     Parameters
#     ----------
#     alpha : float, optional, default: 1.0
#         Small positive values of alpha improve the conditioning of the problem
#         and reduce the variance of the estimates.
# 
#     Attributes
#     ----------
#     coef_ : ndarray, shape = (n_features,)
#         Weight vector.
# 
#     n_features_in_ : int
#         Number of features seen during ``fit``.
# 
#     feature_names_in_ : ndarray of shape (`n_features_in_`,)
#         Names of features seen during ``fit``. Defined only when `X`
#         has feature names that are all strings.
# 
#     References
#     ----------
#     .. [1] W. Stute, "Consistent estimation under random censorship when covariables are
#            present", Journal of Multivariate Analysis, vol. 45, no. 1, pp. 89-103, 1993.
#            doi:10.1006/jmva.1993.1028.
#     """
#     def __init__(self, alpha=1.0, fit_intercept=True, normalize="deprecated",
#                  copy_X=True, max_iter=None, tol=1e-3, solver="auto"):
#         super().__init__(alpha=alpha, fit_intercept=fit_intercept,
#                          normalize=normalize, copy_X=copy_X,
#                          max_iter=max_iter, tol=tol, solver=solver)
# 
#     @property
#     def _predict_risk_score(self):
#         return False
# 
#     def fit(self, X, y):
#         """Build an accelerated failure time model.
# 
#         Parameters
#         ----------
#         X : array-like, shape = (n_samples, n_features)
#             Data matrix.
# 
#         y : structured array, shape = (n_samples,)
#             A structured array containing the binary event indicator
#             as first field, and time of event or time of censoring as
#             second field.
# 
#         Returns
#         -------
#         self
#         """
#         event, time = check_array_survival(X, y)
# 
#         weights = ipc_weights(event, time)
#         super().fit(X, numpy.log(time), sample_weight=weights)
# 
#         return self
# 
#     def predict(self, X):
#         """Predict using the linear accelerated failure time model.
# 
#         Parameters
#         ----------
#         X : {array-like, sparse matrix}, shape = (n_samples, n_features)
#             Samples.
# 
#         Returns
#         -------
#         C : array, shape = (n_samples,)
#             Returns predicted values on original scale (NOT log scale).
#         """
#         return numpy.exp(super().predict(X))
# 
#     def score(self, X, y, sample_weight=None):
#         return SurvivalAnalysisMixin.score(self, X, y)
# 
# Path: sksurv/testing.py
# def assert_cindex_almost_equal(event_indicator, event_time, estimate, expected):
#     result = concordance_index_censored(event_indicator, event_time, estimate)
#     assert_array_equal(result[1:], expected[1:])
#     concordant, discordant, tied_risk = result[1:4]
#     cc = (concordant + 0.5 * tied_risk) / (concordant + discordant + tied_risk)
#     assert_almost_equal(result[0], cc)
#     assert_almost_equal(result[0], expected[0])


import numpy
from numpy.testing import assert_array_almost_equal
from sksurv.linear_model import IPCRidge
from sksurv.testing import assert_cindex_almost_equal



class TestIPCRidge:

    @staticmethod
    def test_fit(make_whas500):
        whas500 = make_whas500()
        model = IPCRidge()
        model.fit(whas500.x, whas500.y)

        assert round(abs(model.intercept_ - 5.867520370855396), 7) == 0
        expected = numpy.array([0.168481, -0.24962, 2.185086, 0.53682, -0.514611, 0.09124,
                                0.613114, 0.480357, -0.055972, 0.238472, -0.127209, -0.144063,
                                -1.625081, -0.217591])
        assert_array_almost_equal(model.coef_, expected)

    @staticmethod
    def test_predict(make_whas500):
        whas500 = make_whas500()
        model = IPCRidge()
        model.fit(whas500.x[:400], whas500.y[:400])

        x_test = whas500.x[400:]
        y_test = whas500.y[400:]
        p = model.predict(x_test)

# Path: sksurv/linear_model/aft.py
# class IPCRidge(Ridge, SurvivalAnalysisMixin):
#     """Accelerated failure time model with inverse probability of censoring weights.
# 
#     This model assumes a regression model of the form
# 
#     .. math::
# 
#         \\log y = \\beta_0 + \\mathbf{X} \\beta + \\epsilon
# 
#     L2-shrinkage is applied to the coefficients :math:`\\beta` and
#     each sample is weighted by the inverse probability of censoring
#     to account for right censoring (under the assumption that
#     censoring is independent of the features, i.e., random censoring).
# 
#     See [1]_ for further description.
# 
#     Parameters
#     ----------
#     alpha : float, optional, default: 1.0
#         Small positive values of alpha improve the conditioning of the problem
#         and reduce the variance of the estimates.
# 
#     Attributes
#     ----------
#     coef_ : ndarray, shape = (n_features,)
#         Weight vector.
# 
#     n_features_in_ : int
#         Number of features seen during ``fit``.
# 
#     feature_names_in_ : ndarray of shape (`n_features_in_`,)
#         Names of features seen during ``fit``. Defined only when `X`
#         has feature names that are all strings.
# 
#     References
#     ----------
#     .. [1] W. Stute, "Consistent estimation under random censorship when covariables are
#            present", Journal of Multivariate Analysis, vol. 45, no. 1, pp. 89-103, 1993.
#            doi:10.1006/jmva.1993.1028.
#     """
#     def __init__(self, alpha=1.0, fit_intercept=True, normalize="deprecated",
#                  copy_X=True, max_iter=None, tol=1e-3, solver="auto"):
#         super().__init__(alpha=alpha, fit_intercept=fit_intercept,
#                          normalize=normalize, copy_X=copy_X,
#                          max_iter=max_iter, tol=tol, solver=solver)
# 
#     @property
#     def _predict_risk_score(self):
#         return False
# 
#     def fit(self, X, y):
#         """Build an accelerated failure time model.
# 
#         Parameters
#         ----------
#         X : array-like, shape = (n_samples, n_features)
#             Data matrix.
# 
#         y : structured array, shape = (n_samples,)
#             A structured array containing the binary event indicator
#             as first field, and time of event or time of censoring as
#             second field.
# 
#         Returns
#         -------
#         self
#         """
#         event, time = check_array_survival(X, y)
# 
#         weights = ipc_weights(event, time)
#         super().fit(X, numpy.log(time), sample_weight=weights)
# 
#         return self
# 
#     def predict(self, X):
#         """Predict using the linear accelerated failure time model.
# 
#         Parameters
#         ----------
#         X : {array-like, sparse matrix}, shape = (n_samples, n_features)
#             Samples.
# 
#         Returns
#         -------
#         C : array, shape = (n_samples,)
#             Returns predicted values on original scale (NOT log scale).
#         """
#         return numpy.exp(super().predict(X))
# 
#     def score(self, X, y, sample_weight=None):
#         return SurvivalAnalysisMixin.score(self, X, y)
# 
# Path: sksurv/testing.py
# def assert_cindex_almost_equal(event_indicator, event_time, estimate, expected):
#     result = concordance_index_censored(event_indicator, event_time, estimate)
#     assert_array_equal(result[1:], expected[1:])
#     concordant, discordant, tied_risk = result[1:4]
#     cc = (concordant + 0.5 * tied_risk) / (concordant + discordant + tied_risk)
#     assert_almost_equal(result[0], cc)
#     assert_almost_equal(result[0], expected[0])


# Path: tests/test_aft.py
import numpy
from numpy.testing import assert_array_almost_equal
from sksurv.linear_model import IPCRidge
from sksurv.testing import assert_cindex_almost_equal




class TestIPCRidge:

    @staticmethod
    def test_fit(make_whas500):
        whas500 = make_whas500()
        model = IPCRidge()
        model.fit(whas500.x, whas500.y)

        assert round(abs(model.intercept_ - 5.867520370855396), 7) == 0
        expected = numpy.array([0.168481, -0.24962, 2.185086, 0.53682, -0.514611, 0.09124,
                                0.613114, 0.480357, -0.055972, 0.238472, -0.127209, -0.144063,
                                -1.625081, -0.217591])
        assert_array_almost_equal(model.coef_, expected)

    @staticmethod
    def test_predict(make_whas500):
        whas500 = make_whas500()
        model = IPCRidge()
        model.fit(whas500.x[:400], whas500.y[:400])

        x_test = whas500.x[400:]
        y_test = whas500.y[400:]
        p = model.predict(x_test)

        assert_cindex_almost_equal(y_test['fstat'], y_test['lenfol'], -p,