def test_max_likelihood_parameter_sign(data, no):
    def _modify_initial_parameters_mock(fd):
        return fd

    load_cycle_limit = 1e6
    if hasattr(data, "N_threshold"):
        load_cycle_limit = data.N_threshold
    fatdat = woehler.determine_fractures(data,
                                         load_cycle_limit=load_cycle_limit)
    ml = woehler.MaxLikeFull(fatigue_data=fatdat.fatigue_data)
    wl = ml.analyze()

    print("Data set number {}".format(no))
    print("Woehler parameters: {}".format(wl))

    def assert_positive_or_nan_but_not_zero(x):
        if np.isfinite(x):
            assert x >= 0
            assert not np.isclose(x, 0.0)

    assert_positive_or_nan_but_not_zero(wl['SD_50'])
    assert_positive_or_nan_but_not_zero(wl['1/TS'])
    assert_positive_or_nan_but_not_zero(wl['k_1'])
    assert_positive_or_nan_but_not_zero(wl['ND_50'])
    assert_positive_or_nan_but_not_zero(wl['1/TN'])
def test_max_likelihood_full_method_with_all_fixed_params():
    """
    Test of woehler curve parameters evaluation with the maximum likelihood method
    """
    fp = {
        'k_1': 15.7,
        '1/TN': 1.2,
        'SD_50': 280,
        '1/TS': 1.2,
        'ND_50': 10000000
    }
    fd = woehler.determine_fractures(data, 1e7).fatigue_data
    with pytest.raises(
            AttributeError,
            match=r'You need to leave at least one parameter empty!'):
        (woehler.MaxLikeFull(fd).analyze(fixed_parameters=fp))
def test_max_likelihood_one_mixed_horizon():
    expected = pd.Series({
        'SD_50': 489.3,
        '1/TS': 1.147,
        'k_1': 7.99,
        'ND_50': 541e3,
        '1/TN': 2.51
    }).sort_index()

    fd = woehler.determine_fractures(data_01, 1e7).fatigue_data
    ml = woehler.MaxLikeFull(fatigue_data=fd)
    with pytest.warns(UserWarning,
                      match=r"^.*less than two mixed load levels.*"):
        wc = ml.analyze().sort_index()
    bic = ml.bayesian_information_criterion()
    pd.testing.assert_index_equal(wc.index, expected.index)
    np.testing.assert_allclose(wc.to_numpy(), expected.to_numpy(), rtol=1e-1)
def test_max_likelihood_full_with_fixed_params():
    expected = pd.Series({
        'SD_50': 335,
        '1/TS': 1.19,
        'k_1': 8.0,
        'ND_50': 520000.,
        '1/TN': 6.0
    }).sort_index()

    fd = woehler.determine_fractures(data, 1e7).fatigue_data
    wc = (woehler.MaxLikeFull(fd).analyze(fixed_parameters={
        '1/TN': 6.0,
        'k_1': 8.0
    }).sort_index())
    pd.testing.assert_index_equal(wc.index, expected.index)
    np.testing.assert_allclose(wc.to_numpy(), expected.to_numpy(), rtol=1e-1)
    assert wc['1/TN'] == 6.0
    assert wc['k_1'] == 8.0
def test_woehler_max_likelihood_full_without_fixed_params():
    expected = pd.Series({
        'SD_50': 335,
        '1/TS': 1.19,
        'k_1': 6.94,
        'ND_50': 463000.,
        '1/TN': 4.7
    }).sort_index()

    bic = 45.35256860035525

    fd = woehler.determine_fractures(data, 1e7).fatigue_data
    we = woehler.MaxLikeFull(fd)
    wc = we.analyze().sort_index()
    pd.testing.assert_index_equal(wc.index, expected.index)
    np.testing.assert_allclose(wc.to_numpy(), expected.to_numpy(), rtol=1e-1)
    np.testing.assert_almost_equal(we.bayesian_information_criterion(),
                                   bic,
                                   decimal=2)
def test_woehler_max_likelihood_full_without_fixed_params_no_runouts():
    expected = pd.Series({
        'SD_50': 0,
        '1/TS': 1.,
        'k_1': 6.94,
        'ND_50': 4.4e30,
        '1/TN': 5.7
    }).sort_index()

    bic = np.inf

    fd = woehler.determine_fractures(data_no_runouts, 1e7).fatigue_data
    we = woehler.MaxLikeFull(fd)
    with pytest.warns(UserWarning, match=r"^.*no runouts are present.*"):
        wc = we.analyze().sort_index()
    pd.testing.assert_index_equal(wc.index, expected.index)
    np.testing.assert_allclose(wc.to_numpy(), expected.to_numpy(), rtol=1e-1)
    np.testing.assert_almost_equal(we.bayesian_information_criterion(),
                                   bic,
                                   decimal=2)
def test_max_likelihood_min_three_fractures_on_two_load_levels(invalid_data):
    fd = woehler.determine_fractures(invalid_data, 1e7).fatigue_data
    ml = woehler.MaxLikeFull(fatigue_data=fd)
    with pytest.raises(ValueError, match=r"^.*[N|n]eed at least.*"):
        ml.analyze()
def test_bic_without_analysis():
    fd = woehler.determine_fractures(data, 1e7).fatigue_data
    we = woehler.MaxLikeFull(fd)
    with pytest.raises(ValueError, match="^.*BIC.*"):
        we.bayesian_information_criterion()