# Path: skyfield/api.py
# N = E = +1.0
# S = W = -1.0
# 
# Path: skyfield/searchlib.py
# def find_discrete(start_time, end_time, f, epsilon=EPSILON, num=12):
#     """Find the times at which a discrete function of time changes value.
# 
#     This routine is used to find instantaneous events like sunrise,
#     transits, and the seasons.  See :doc:`searches` for how to use it
#     yourself.
# 
#     """
#     ts = start_time.ts
#     jd0 = start_time.tt
#     jd1 = end_time.tt
#     if jd0 >= jd1:
#         raise ValueError('your start_time {0} is later than your end_time {1}'
#                          .format(start_time, end_time))
# 
#     step_days = getattr(f, 'step_days', None)
#     if step_days is None:
#         # Legacy "rough_period" attribute.
#         rough_period = getattr(f, 'rough_period', None)
#         if rough_period is None:
#             raise AttributeError('the function you have passed'
#                                  ' is missing a "step_days" attribute')
#         periods = (jd1 - jd0) / rough_period
#         if periods < 1.0:
#             periods = 1.0
#         sample_count = int(periods * num)
#     else:
#         # Insist on at least 2 samples even if the dates are less than
#         # step_days apart, so the range at least has endpoints.
#         sample_count = int((jd1 - jd0) / step_days) + 2
# 
#     jd = linspace(jd0, jd1, sample_count)
#     return _find_discrete(ts, jd, f, epsilon, num)
# 
# def find_maxima(start_time, end_time, f, epsilon=1.0 / DAY_S, num=12):
#     """Find the local maxima in the values returned by a function of time.
# 
#     This routine is used to find events like highest altitude and
#     maximum elongation.  See :doc:`searches` for how to use it yourself.
# 
#     """
#     #    @@       @@_@@       @@_@@_@@_@@
#     #   /  \     /     \     /           \
#     # @@    @@ @@       @@ @@             @@
#     # +1 -1    +1  0 -1    +1  0  0  0 -1    sd = sign(diff(y))
#     # -2       -1 -1       -1  0  0 -1       diff(sign(diff(y))
# 
#     ts = start_time.ts
#     jd0 = start_time.tt
#     jd1 = end_time.tt
# 
#     if jd0 >= jd1:
#         raise ValueError('start_time {0} is not earlier than end_time {1}'
#                          .format(start_time, end_time))
# 
#     # We find maxima by investigating every point that is higher than
#     # both points next to it.  This presents a problem: if the initial
#     # heights are, for example, [1.7, 1.1, 0.3, ...], there might be a
#     # maximum 1.8 hidden between the first two heights, but it would not
#     # meet the criteria for further investigation because we can't see
#     # whether the curve is on its way up or down to the left of 1.7.  So
#     # we put an extra point out beyond each end of our range, then
#     # filter our final result to remove maxima that fall outside the
#     # range.
#     step_days = getattr(f, 'step_days', None)
#     if step_days is None:
#         bump = f.rough_period / num
#         bumps = int((jd1 - jd0) / bump) + 3
#         jd = linspace(jd0 - bump, jd1 + bump, bumps)
#     else:
#         # Insist on at least 3 samples, even for very close dates; and
#         # add 2 more to stand outside the range.
#         steps = int((jd1 - jd0) / step_days) + 3
#         real_step = (jd1 - jd0) / steps
#         jd = linspace(jd0 - real_step, jd1 + real_step, steps + 2)
# 
#     end_alpha = linspace(0.0, 1.0, num)
#     start_alpha = end_alpha[::-1]
#     o = multiply.outer
# 
#     while True:
#         t = ts.tt_jd(jd)
#         y = f(t)
# 
#         # Since we start with equal intervals, they all should fall
#         # below epsilon at around the same time; so for efficiency we
#         # only test the first pair.
#         if t[1] - t[0] <= epsilon:
#             jd, y = _identify_maxima(jd, y)
# 
#             # Filter out maxima that fell slightly outside our bounds.
#             keepers = (jd >= jd0) & (jd <= jd1)
#             jd = jd[keepers]
#             y = y[keepers]
# 
#             # Keep only the first of several maxima that are separated
#             # by less than epsilon.
#             if len(jd):
#                 mask = concatenate(((True,), diff(jd) > epsilon))
#                 jd = jd[mask]
#                 y = y[mask]
# 
#             break
# 
#         left, right = _choose_brackets(y)
# 
#         if _trace is not None:
#             _trace((t, y, left, right))
# 
#         if not len(left):
#             # No maxima found.
#             jd = y = y[0:0]
#             break
# 
#         starts = jd.take(left)
#         ends = jd.take(right)
# 
#         jd = o(starts, start_alpha).flatten() + o(ends, end_alpha).flatten()
#         jd = _remove_adjacent_duplicates(jd)
# 
#     return ts.tt_jd(jd), _fix_numpy_deprecation(y)


import numpy as np
from assay import assert_raises
from skyfield.api import load
from skyfield.searchlib import find_discrete, find_maxima
"""Low-level tests of the almanac search routines."""



bump = 1e-5
epsilon = 1e-10

def make_t():

# Path: skyfield/api.py
# N = E = +1.0
# S = W = -1.0
# 
# Path: skyfield/searchlib.py
# def find_discrete(start_time, end_time, f, epsilon=EPSILON, num=12):
#     """Find the times at which a discrete function of time changes value.
# 
#     This routine is used to find instantaneous events like sunrise,
#     transits, and the seasons.  See :doc:`searches` for how to use it
#     yourself.
# 
#     """
#     ts = start_time.ts
#     jd0 = start_time.tt
#     jd1 = end_time.tt
#     if jd0 >= jd1:
#         raise ValueError('your start_time {0} is later than your end_time {1}'
#                          .format(start_time, end_time))
# 
#     step_days = getattr(f, 'step_days', None)
#     if step_days is None:
#         # Legacy "rough_period" attribute.
#         rough_period = getattr(f, 'rough_period', None)
#         if rough_period is None:
#             raise AttributeError('the function you have passed'
#                                  ' is missing a "step_days" attribute')
#         periods = (jd1 - jd0) / rough_period
#         if periods < 1.0:
#             periods = 1.0
#         sample_count = int(periods * num)
#     else:
#         # Insist on at least 2 samples even if the dates are less than
#         # step_days apart, so the range at least has endpoints.
#         sample_count = int((jd1 - jd0) / step_days) + 2
# 
#     jd = linspace(jd0, jd1, sample_count)
#     return _find_discrete(ts, jd, f, epsilon, num)
# 
# def find_maxima(start_time, end_time, f, epsilon=1.0 / DAY_S, num=12):
#     """Find the local maxima in the values returned by a function of time.
# 
#     This routine is used to find events like highest altitude and
#     maximum elongation.  See :doc:`searches` for how to use it yourself.
# 
#     """
#     #    @@       @@_@@       @@_@@_@@_@@
#     #   /  \     /     \     /           \
#     # @@    @@ @@       @@ @@             @@
#     # +1 -1    +1  0 -1    +1  0  0  0 -1    sd = sign(diff(y))
#     # -2       -1 -1       -1  0  0 -1       diff(sign(diff(y))
# 
#     ts = start_time.ts
#     jd0 = start_time.tt
#     jd1 = end_time.tt
# 
#     if jd0 >= jd1:
#         raise ValueError('start_time {0} is not earlier than end_time {1}'
#                          .format(start_time, end_time))
# 
#     # We find maxima by investigating every point that is higher than
#     # both points next to it.  This presents a problem: if the initial
#     # heights are, for example, [1.7, 1.1, 0.3, ...], there might be a
#     # maximum 1.8 hidden between the first two heights, but it would not
#     # meet the criteria for further investigation because we can't see
#     # whether the curve is on its way up or down to the left of 1.7.  So
#     # we put an extra point out beyond each end of our range, then
#     # filter our final result to remove maxima that fall outside the
#     # range.
#     step_days = getattr(f, 'step_days', None)
#     if step_days is None:
#         bump = f.rough_period / num
#         bumps = int((jd1 - jd0) / bump) + 3
#         jd = linspace(jd0 - bump, jd1 + bump, bumps)
#     else:
#         # Insist on at least 3 samples, even for very close dates; and
#         # add 2 more to stand outside the range.
#         steps = int((jd1 - jd0) / step_days) + 3
#         real_step = (jd1 - jd0) / steps
#         jd = linspace(jd0 - real_step, jd1 + real_step, steps + 2)
# 
#     end_alpha = linspace(0.0, 1.0, num)
#     start_alpha = end_alpha[::-1]
#     o = multiply.outer
# 
#     while True:
#         t = ts.tt_jd(jd)
#         y = f(t)
# 
#         # Since we start with equal intervals, they all should fall
#         # below epsilon at around the same time; so for efficiency we
#         # only test the first pair.
#         if t[1] - t[0] <= epsilon:
#             jd, y = _identify_maxima(jd, y)
# 
#             # Filter out maxima that fell slightly outside our bounds.
#             keepers = (jd >= jd0) & (jd <= jd1)
#             jd = jd[keepers]
#             y = y[keepers]
# 
#             # Keep only the first of several maxima that are separated
#             # by less than epsilon.
#             if len(jd):
#                 mask = concatenate(((True,), diff(jd) > epsilon))
#                 jd = jd[mask]
#                 y = y[mask]
# 
#             break
# 
#         left, right = _choose_brackets(y)
# 
#         if _trace is not None:
#             _trace((t, y, left, right))
# 
#         if not len(left):
#             # No maxima found.
#             jd = y = y[0:0]
#             break
# 
#         starts = jd.take(left)
#         ends = jd.take(right)
# 
#         jd = o(starts, start_alpha).flatten() + o(ends, end_alpha).flatten()
#         jd = _remove_adjacent_duplicates(jd)
# 
#     return ts.tt_jd(jd), _fix_numpy_deprecation(y)


# Path: skyfield/tests/test_almanac_searches.py
import numpy as np
from assay import assert_raises
from skyfield.api import load
from skyfield.searchlib import find_discrete, find_maxima

"""Low-level tests of the almanac search routines."""



bump = 1e-5
epsilon = 1e-10

def make_t():

    ts = load.timescale()