def test_lomb_scargle_regular_multi_freq():
    """Test Lomb-Scargle model features on regularly-sampled periodic data with
    multiple frequencies, each with a single harmonic. Estimated parameters
    should be very accurate in this case.
    """
    frequencies = WAVE_FREQS
    amplitudes = np.zeros((len(frequencies),4))
    amplitudes[:,0] = [4,2,1]
    phase = 0.1
    times, values, errors = regular_periodic(frequencies, amplitudes, phase)
    all_lomb = generate_features(times, values, errors, LOMB_SCARGLE_FEATS)

    for i, frequency in enumerate(frequencies):
        npt.assert_allclose(frequency,
                all_lomb['freq{}_freq'.format(i+1)])

    for (i,j), amplitude in np.ndenumerate(amplitudes):
        npt.assert_allclose(amplitude,
                all_lomb['freq{}_amplitude{}'.format(i+1,j+1)],
                rtol=5e-2, atol=5e-2)

    for i in [2,3]:
        npt.assert_allclose(amplitudes[i-1,0] / amplitudes[0,0],
                all_lomb['freq_amplitude_ratio_{}1'.format(i)], atol=2e-2)

    npt.assert_array_less(10., all_lomb['freq1_signif'])
def test_lomb_scargle_regular_multi_freq():
    """Test Lomb-Scargle model features on regularly-sampled periodic data with
    multiple frequencies, each with a single harmonic. Estimated parameters
    should be very accurate in this case.
    """
    frequencies = WAVE_FREQS
    amplitudes = np.zeros((len(frequencies), 4))
    amplitudes[:, 0] = [4, 2, 1]
    phase = 0.1
    times, values, errors = regular_periodic(frequencies, amplitudes, phase)
    all_lomb = generate_features(times, values, errors, LOMB_SCARGLE_FEATS)

    for i, frequency in enumerate(frequencies):
        npt.assert_allclose(frequency, all_lomb['freq{}_freq'.format(i + 1)])

    for (i, j), amplitude in np.ndenumerate(amplitudes):
        npt.assert_allclose(amplitude,
                            all_lomb['freq{}_amplitude{}'.format(i + 1,
                                                                 j + 1)],
                            rtol=5e-2,
                            atol=5e-2)

    for i in [2, 3]:
        npt.assert_allclose(amplitudes[i - 1, 0] / amplitudes[0, 0],
                            all_lomb['freq_amplitude_ratio_{}1'.format(i)],
                            atol=2e-2)

    npt.assert_array_less(10., all_lomb['freq1_signif'])
def test_lomb_scargle_regular_single_freq():
    """Test Lomb-Scargle model features on regularly-sampled periodic data with
    one frequency/multiple harmonics. Estimated parameters should be very
    accurate in this case.
    """
    frequencies = np.hstack((WAVE_FREQS[0], np.zeros(len(WAVE_FREQS)-1)))
    amplitudes = np.zeros((len(frequencies),4))
    amplitudes[0,:] = [8,4,2,1]
    phase = 0.1
    times, values, errors = regular_periodic(frequencies, amplitudes, phase)
    all_lomb = generate_features(times, values, errors, LOMB_SCARGLE_FEATS)

    # Only test the first (true) frequency; the rest correspond to noise
    npt.assert_allclose(all_lomb['freq1_freq'], frequencies[0])

    # Hard-coded value from previous solution
    npt.assert_allclose(0.001996007984, all_lomb['freq1_lambda'], rtol=1e-7)

    for (i,j), amplitude in np.ndenumerate(amplitudes):
        npt.assert_allclose(amplitude,
                all_lomb['freq{}_amplitude{}'.format(i+1,j+1)], rtol=1e-2,
                    atol=1e-2)

    # Only test the first (true) frequency; the rest correspond to noise
    for j in range(1, amplitudes.shape[1]):
        npt.assert_allclose(phase*j*(-1**j),
            all_lomb['freq1_rel_phase{}'.format(j+1)], rtol=1e-2, atol=1e-2)

    # Frequency ratio not relevant since there is only; only test amplitude/signif
    for i in [2,3]:
        npt.assert_allclose(0., all_lomb['freq_amplitude_ratio_{}1'.format(i)], atol=1e-3)

    npt.assert_array_less(10., all_lomb['freq1_signif'])

    # Only one frequency, so this should explain basically all the variance
    npt.assert_allclose(0., all_lomb['freq_varrat'], atol=5e-3)

    # Exactly periodic, so the same minima/maxima should reoccur
    npt.assert_allclose(0., all_lomb['freq_model_max_delta_mags'], atol=1e-6)
    npt.assert_allclose(0., all_lomb['freq_model_min_delta_mags'], atol=1e-6)

    # Linear trend should be zero since the signal is exactly sinusoidal
    npt.assert_allclose(0., all_lomb['linear_trend'], atol=1e-4)

    folded_times = times % 1./(frequencies[0]/2.)
    sort_indices = np.argsort(folded_times)
    folded_times = folded_times[sort_indices]
    folded_values = values[sort_indices]

    # Residuals from doubling period should be much higher
    npt.assert_array_less(10., all_lomb['medperc90_2p_p'])

    # Slopes should be the same for {un,}folded data; use unfolded for stability
    slopes = np.diff(values) / np.diff(times)
    npt.assert_allclose(np.percentile(slopes,10),
        all_lomb['fold2P_slope_10percentile'], rtol=1e-2)
    npt.assert_allclose(np.percentile(slopes,90),
        all_lomb['fold2P_slope_90percentile'], rtol=1e-2)
Example #4
0
def test_lomb_scargle_fast_regular():
    """Test gatspy's fast Lomb-Scargle period estimate on regularly-sampled
    periodic data.

    Note: this model fits only a single sinusoid with no additional harmonics,
    so we use only 1 frequency and 1 amplitude to generate test data.
    """
    frequencies = np.array([4])
    amplitudes = np.array([[1]])
    phase = 0.1
    times, values, errors = regular_periodic(frequencies, amplitudes, phase)
    f = generate_features(times, values, errors, ['period_fast'])

    npt.assert_allclose(f['period_fast'], 1. / frequencies[0], rtol=5e-4)
Example #5
0
def test_lomb_scargle_fast_regular():
    """Test gatspy's fast Lomb-Scargle period estimate on regularly-sampled
    periodic data.

    Note: this model fits only a single sinusoid with no additional harmonics,
    so we use only 1 frequency and 1 amplitude to generate test data.
    """
    frequencies = np.array([4])
    amplitudes = np.array([[1]])
    phase = 0.1
    times, values, errors = regular_periodic(frequencies, amplitudes, phase)
    f = generate_features(times, values, errors, ['period_fast'])

    npt.assert_allclose(f['period_fast'], 1. / frequencies[0], rtol=5e-4)
def test_lomb_scargle_linear_trend():
    frequencies = np.hstack((WAVE_FREQS[0], np.zeros(len(WAVE_FREQS)-1)))
    amplitudes = np.zeros((len(WAVE_FREQS),4))
    amplitudes[0,:] = [8,4,2,1]
    phase = 0.1
    slope = 0.5

    # Estimated trend should be almost exact for noiseless data
    times, values, errors = regular_periodic(frequencies, amplitudes, phase)
    values += slope * times
    all_lomb = generate_features(times, values, errors, LOMB_SCARGLE_FEATS)
    npt.assert_allclose(slope, all_lomb['linear_trend'], rtol=1e-3)

    # Should still be close to true trend when noise is present
    times, values, errors = irregular_periodic(frequencies, amplitudes, phase)
    values += slope * times
    values += np.random.normal(scale=1e-3, size=len(times))
    all_lomb = generate_features(times, values, errors, LOMB_SCARGLE_FEATS)
    npt.assert_allclose(slope, all_lomb['linear_trend'], rtol=1e-1)
def test_lomb_scargle_linear_trend():
    frequencies = np.hstack((WAVE_FREQS[0], np.zeros(len(WAVE_FREQS) - 1)))
    amplitudes = np.zeros((len(WAVE_FREQS), 4))
    amplitudes[0, :] = [8, 4, 2, 1]
    phase = 0.1
    slope = 0.5

    # Estimated trend should be almost exact for noiseless data
    times, values, errors = regular_periodic(frequencies, amplitudes, phase)
    values += slope * times
    all_lomb = generate_features(times, values, errors, LOMB_SCARGLE_FEATS)
    npt.assert_allclose(slope, all_lomb['linear_trend'], rtol=1e-3)

    # Should still be close to true trend when noise is present
    times, values, errors = irregular_periodic(frequencies, amplitudes, phase)
    values += slope * times
    values += np.random.normal(scale=1e-3, size=len(times))
    all_lomb = generate_features(times, values, errors, LOMB_SCARGLE_FEATS)
    npt.assert_allclose(slope, all_lomb['linear_trend'], rtol=1e-1)
def test_lomb_scargle_regular_single_freq():
    """Test Lomb-Scargle model features on regularly-sampled periodic data with
    one frequency/multiple harmonics. Estimated parameters should be very
    accurate in this case.
    """
    frequencies = np.hstack((WAVE_FREQS[0], np.zeros(len(WAVE_FREQS) - 1)))
    amplitudes = np.zeros((len(frequencies), 4))
    amplitudes[0, :] = [8, 4, 2, 1]
    phase = 0.1
    times, values, errors = regular_periodic(frequencies, amplitudes, phase)
    all_lomb = generate_features(times, values, errors, LOMB_SCARGLE_FEATS)

    # Only test the first (true) frequency; the rest correspond to noise
    npt.assert_allclose(all_lomb['freq1_freq'], frequencies[0])

    # Hard-coded value from previous solution
    npt.assert_allclose(0.001996007984, all_lomb['freq1_lambda'], rtol=1e-7)

    for (i, j), amplitude in np.ndenumerate(amplitudes):
        npt.assert_allclose(amplitude,
                            all_lomb['freq{}_amplitude{}'.format(i + 1,
                                                                 j + 1)],
                            rtol=1e-2,
                            atol=1e-2)

    # Only test the first (true) frequency; the rest correspond to noise
    for j in range(1, amplitudes.shape[1]):
        npt.assert_allclose(phase * j * (-1**j),
                            all_lomb['freq1_rel_phase{}'.format(j + 1)],
                            rtol=1e-2,
                            atol=1e-2)

    # Frequency ratio not relevant since there is only; only test amplitude/signif
    for i in [2, 3]:
        npt.assert_allclose(0.,
                            all_lomb['freq_amplitude_ratio_{}1'.format(i)],
                            atol=1e-3)

    npt.assert_array_less(10., all_lomb['freq1_signif'])

    # Only one frequency, so this should explain basically all the variance
    npt.assert_allclose(0., all_lomb['freq_varrat'], atol=5e-3)

    # Exactly periodic, so the same minima/maxima should reoccur
    npt.assert_allclose(0., all_lomb['freq_model_max_delta_mags'], atol=1e-6)
    npt.assert_allclose(0., all_lomb['freq_model_min_delta_mags'], atol=1e-6)

    # Linear trend should be zero since the signal is exactly sinusoidal
    npt.assert_allclose(0., all_lomb['linear_trend'], atol=1e-4)

    folded_times = times % 1. / (frequencies[0] / 2.)
    sort_indices = np.argsort(folded_times)
    folded_times = folded_times[sort_indices]
    folded_values = values[sort_indices]

    # Residuals from doubling period should be much higher
    npt.assert_array_less(10., all_lomb['medperc90_2p_p'])

    # Slopes should be the same for {un,}folded data; use unfolded for stability
    slopes = np.diff(values) / np.diff(times)
    npt.assert_allclose(np.percentile(slopes, 10),
                        all_lomb['fold2P_slope_10percentile'],
                        rtol=1e-2)
    npt.assert_allclose(np.percentile(slopes, 90),
                        all_lomb['fold2P_slope_90percentile'],
                        rtol=1e-2)