epsearch package

class epsearch.BoundaryGenerator(*args, **kwargs)[source]

Bases: Protocol[TKey, TNumber_co_]

A protocol for boundary generators.

keys_to_values(keys: Sequence[TKey], /) Sequence[TNumber_co_][source]

Get the final candidates.

Parameters:

keys (Sequence[TKey]) – The keys of the final candidates.

Returns:

The final candidates.

Return type:

Sequence[TNumber_co_]

class epsearch.Circle(*, radius: float, center: complex)[source]

Bases: object

A circle.

center: complex

The center of the circle.

radius: float

The radius of the circle.

class epsearch.CirclesBoundary(*, center: complex, radius: float, radius_min: float, n_points: int, extra_ratio: float = 0.1)[source]

Bases: BoundaryGenerator[Circle, complex]

Divide-and-conquer search using circles.

The circles circumscribe the rectangular region. The search region is a square [Re center - radius/sqrt(2), Re center + radius/sqrt(2)] x [Im center - radius/sqrt(2), Im center + radius/sqrt(2)].

Parameters:
  • center (complex) – The center of the circle.

  • radius (float) – The radius of the circle.

  • radius_min (float) – The radius threshold to stop the recursion.

  • n_points (int) – The number of points on the circle.

  • extra_ratio (float, optional) – The extra ratio to enlarge the circle to avoid the corners of the square to be missed, by default 0.1. Must be positive or zero.

center: complex
extra_ratio: float
keys_to_values(keys: Sequence[Circle], /) Sequence[complex][source]

Get the final candidates.

Parameters:

keys (Sequence[Circle]) – The keys of the final candidates.

Returns:

The final candidates.

Return type:

Sequence[complex]

n_points: int
radius: float
radius_min: float
class epsearch.Cycles(*, cycles: list[ndarray[tuple[int, int], dtype[TNumber]]], graph: DiGraph, eigvals: ndarray[tuple[int, int], dtype[TNumber]], incomplete_eigvals: MaskedArray[tuple[int, int], dtype[TNumber]])[source]

Bases: Generic[TNumber]

Cycles of the eigenvalues.

property connected_cycles: list[ndarray[tuple[int], dtype[TNumber]]]

List of connected sequences of eigenvalues of length num_cycles.

Prdered by length in descending order same as self.cycles of shape (cycle_length, num_points).

property cycle_lengths: list[int]

Lengths of the cycles in descending order, same as self.cycles.

cycles: list[ndarray[tuple[int, int], dtype[TNumber]]]

Cycles of the eigenvalues of length num_cycles.

Ordered by length in descending order of shape (cycle_length, num_points).

eigvals: ndarray[tuple[int, int], dtype[TNumber]]

Continuous eigenvalues of shape (num_complete_eigenvalues, num_points).

graph: DiGraph

Graph of the cycles. If eigvals[i, -1] ~ eigvals[j, 0], then there is an edge from i to j.

incomplete_eigvals: MaskedArray[tuple[int, int], dtype[TNumber]]

Continuous eigenvalues of shape (num_eigenvalues, num_points) with some NaN values.

property max_cycle_length: int

Maximum length of the cycles.

class epsearch.FindExceptionalPointsRecursivelyResult(*, boundaries: Mapping[TKey, Sequence[TNumber]], eigvals: Mapping[TKey, Sequence[Sequence[TNumber]]], cycles: Mapping[TKey, Cycles[TNumber]], generations: Mapping[TKey, int], keys: Sequence[TKey], branching_points: Sequence[TNumber], f_boundary: BoundaryGenerator[TKey, TNumber])[source]

Bases: Generic[TKey, TNumber]

The result of the recursive search.

boundaries: Mapping[TKey, Sequence[TNumber]]

The boundaries returned by the boundary generator.

branching_points: Sequence[TNumber]

The branching points found.

cycles: Mapping[TKey, Cycles[TNumber]]

The cycles for each boundary.

eigvals: Mapping[TKey, Sequence[Sequence[TNumber]]]

The eigenvalues for each boundary.

f_boundary: BoundaryGenerator[TKey, TNumber]
generations: Mapping[TKey, int]

The generation of each boundary.

keys: Sequence[TKey]

The keys of the final candidates.

plot(text_contour_integral: bool = True, text_additional: Callable[[Cycles[TNumber]], str] | None = None, set_limits: bool = True) None[source]

Plot the boundaries and the eigenvalues.

class epsearch.Rect(*, half_size: complex, center: complex)[source]

Bases: object

center: complex
half_size: complex
property radius: float
class epsearch.RectsBoundary(*, center: complex, half_size: complex, half_size_min: complex, n_points_per_side: int, extra_ratio: float = 0.1)[source]

Bases: BoundaryGenerator[Rect, complex]

Divide-and-conquer search using rectangles.

Parameters:
  • center (complex) – The center of the rectangle.

  • half_size (complex) – The half size of the rectangle (width/2 + 1j * height/2).

  • half_size_min (complex) – The half size threshold to stop the recursion.

  • n_points_per_side (int) – The number of points per side on the rectangle.

  • extra_ratio (float, optional) – The extra ratio to enlarge the rectangle to avoid the corners to be missed, by default 0.1. Must be positive or zero.

center: complex
extra_ratio: float
half_size: complex
half_size_min: complex
keys_to_values(keys: Sequence[Rect], /) Sequence[complex][source]

Get the final candidates.

Parameters:

keys (Sequence[TKey]) – The keys of the final candidates.

Returns:

The final candidates.

Return type:

Sequence[TNumber_co_]

n_points_per_side: int
epsearch.find_branching_points_recursively(f_eigvals: Callable[[Sequence[TNumber]], Sequence[Sequence[TNumber]]], f_boundary: BoundaryGenerator[TKey, TNumber], /, *, f_go_further: Callable[[Cycles[TNumber]], bool] | None = None, f_final: Callable[[Cycles[TNumber]], bool] | None = None, f_plot: Callable[[int | None, int | None], None] | None = None, eigvals_analytic: bool = True, rtol_analytic: float | None = None, depth_first: bool = False, depth_first_and_break: bool = False) FindExceptionalPointsRecursivelyResult[TKey, TNumber][source]

Search for branching points recursively.

Parameters:
  • f_eigvals (Callable[[Sequence[TNumber]], Sequence[Sequence[TNumber]]]) – A function that takes a batch of parameters and returns the eigenvalues.

  • f_boundary (BoundaryGenerator[TKey]) – A function that takes the mapping key and whether a branching point is found inside the boundary, and returns the new boundaries

  • f_go_further (Callable[[Cycles[TNumber]], bool], optional) – A function that takes the cycles and returns whether to go further, by default None

  • f_final (Callable[[Cycles[TNumber]], bool], optional) – A function that takes the cycles and returns whether the boundary is final, by default None

  • f_plot (Callable[[int | None, int | None], None], optional) – A function that takes the iteration number and boundary key and plots the boundaries, by default None

  • eigvals_analytic (bool, optional) – Whether the eigenvalues are supposed to be analytic on the region except for the branching points, by default True. If True, the function will check if the eigenvalues follow Cauchy’s integral formula as well.

  • rtol_analytic (float, optional) – The relative tolerance for the analytic check, by default None.

  • depth_first (bool, optional) – Whether to use depth-first search for finding branching points, by default False. If True, the search will be depth-first, otherwise it will be breadth-first.

  • depth_first_and_break (bool, optional) – Whether to use depth-first search and break when the first branching point is found, by default False. If True, the search will be depth-first and will break when the first branching point is found.

Returns:

The branching points.

Return type:

FindExceptionalPointsRecursivelyResult[TKey]

epsearch.find_branching_points_recursively_hybrid(f_eigvals: Callable[[Sequence[TNumber]], Sequence[Sequence[TNumber]]], f_boundary: BoundaryGenerator[Circle, TNumber], /, f_plot: Callable[[int | None, int | None], None] | None = None, rtol_analytic: float | None = None, ssh_kwargs: SSHKwargs | None = None, scipy_kwargs: Any | None = None, method: Literal['ssh', 'scipy'] = 'scipy', depth_first: bool = False, depth_first_and_break: bool = False) FindExceptionalPointsRecursivelyResult[Circle, TNumber][source]

Search for branching points recursively.

Parameters:
  • f_eigvals (Callable[[Sequence[TNumber]], Sequence[Sequence[TNumber]]]) – A function that takes a batch of parameters and returns the eigenvalues.

  • f_boundary (BoundaryGenerator[Circle]) – A function that takes the mapping key and whether a branching point is found inside the boundary, and returns the new boundaries

  • f_plot (Callable[[int | None, int | None], None], optional) – A function that takes the iteration number and boundary key and plots the boundaries, by default None

  • rtol_analytic (float, optional) – The relative tolerance for the analytic check, by default None.

  • ssh_kwargs (SSHKwargs, optional) – Keyword arguments for the Sakurai-Sugiura method.

  • scipy_kwargs (Any, optional) – Keyword arguments for the scipy root-finding method.

  • method (Literal["ssh", "scipy"], optional) – The method to use for finding branching points, by default “scipy”. If “ssh”, the Sakurai-Sugiura method is used. If “scipy”, scipy’s root-finding method is used.

  • depth_first (bool, optional) – Whether to use depth-first search for finding branching points, by default False. If True, the search will be depth-first, otherwise it will be breadth-first.

  • depth_first_and_break (bool, optional) – Whether to use depth-first search and break when the first branching point is found, by default False. If True, the search will be depth-first and will break when the first branching point is found.

Returns:

The branching points.

Return type:

FindExceptionalPointsRecursivelyResult[Circle]

epsearch.get_cycles(eigvals: Sequence[Sequence[TNumber]] | ndarray[tuple[int, int], dtype[TNumber]], /, *, decompose_threshold_diff_factor: float = 2, decompose_threshold_rate: float = 0.5) Cycles[TNumber][source]

Get cycles from the eigenvalues for each point.

Parameters:
  • eigvals (Sequence[Sequence[TNumber]] | np.ndarray[tuple[int, int], np.dtype[TNumber]]) – A (ordered) sequence which contains the eigenvalues for each point.

  • decompose_threshold_diff_factor (float, optional) – If the rate of elements which are closer than max(mean difference) * decompose_threshold_diff_factor is higher than decompose_threshold_rate, the cycle is decomposed, by default 0.5.

  • decompose_threshold_rate (float, optional) – If the rate of elements which are closer than max(mean difference) * decompose_threshold_diff_factor is higher than decompose_threshold_rate, the cycle is decomposed, by default 0.5.

Returns:

Whether there is a branching inside the boundary.

Return type:

bool