pyoculus.solvers.manifold
Functions
|
Compute stable and unstable eigenvalues/eigenvectors of a fixed point. |
- pyoculus.solvers.manifold.eig(jacobian)
Compute stable and unstable eigenvalues/eigenvectors of a fixed point.
This function calculates the eigenvalues and eigenvectors of a given Jacobian matrix and separates them into stable and unstable components based on their magnitudes.
- Parameters:
jacobian (np.ndarray) – A 2x2 Jacobian matrix at the fixed point.
- Returns:
lambda_s (float): The stable eigenvalue (\(\vert\lambda\vert < 1\)) vector_s (np.ndarray): The corresponding stable eigenvector lambda_u (float): The unstable eigenvalue (\(\vert\lambda\vert > 1\)) vector_u (np.ndarray): The corresponding unstable eigenvector
- Return type:
tuple
Examples
>>> J = np.array([[1.5, 0.5], [0.5, 2.0]]) >>> lambda_s, v_s, lambda_u, v_u = eig(J)
- class pyoculus.solvers.manifold.Clinic(manifold: Manifold, eps_s: float, eps_u: float, n_s: int, n_u: int)
A class representing the trajectory of a homoclinic/heteroclinic point.
This class handles the computation and storage of a heteroclinic/homoclinic trajectory, which represent intersections between stable and unstable manifolds of fixed points.
- Parameters:
manifold – The
Manifoldobject associated to the fixed points and map analyzed.eps_s (float) – Initial distance in the linear regime along stable manifold direction.
eps_u (float) – Initial distance in the linear regime along unstable manifold direction.
n_s (int) – Number of iterations to apply to the intersection closest to the stable fixed point.
n_u (int) – Number of iterations to apply to the intersection closest to the unstable fixed point.
- eps_s
Distance parameter along stable manifold.
- Type:
float
- eps_u
Distance parameter along unstable manifold.
- Type:
float
- nint_s
Number of stable iterations.
- Type:
int
- nint_u
Number of unstable iterations.
- Type:
int
- _fundamental_segments
Fundamental domain bounds.
- Type:
dict
- _trajectory
Computed clinic orbit.
- Type:
np.ndarray
- _path_s
Stable manifold path.
- Type:
np.ndarray
- _path_u
Unstable manifold path.
- Type:
np.ndarray
- _xend_s
End point on stable manifold.
- Type:
np.ndarray
- _xend_u
End point on unstable manifold.
- Type:
np.ndarray
- classmethod from_guess(manifold: Manifold, eps_s: float, eps_u: float, n_s: int, n_u: int, ERR=0.001, **kwargs)
Search a homo/hetero-clinic point.
This function attempts to find the intersection point of the stable and unstable manifolds by iteratively adjusting the provided epsilon guesses using scipy root-finding algorithm.
- Parameters:
guess_eps_s (float) – Initial guess for the stable manifold epsilon.
guess_eps_u (float) – Initial guess for the unstable manifold epsilon.
**kwargs – Additional keyword arguments. - root_args (dict): Arguments to pass to the root-finding function. - ERR (float): Error tolerance for verifying the linear regime (default: 1e-3). - n_s (int): Number of times the map needs to be applied for the stable manifold. - n_u (int): Number of times the map needs to be applied for the unstable manifold.
- Returns:
A tuple containing the found epsilon values for the stable and unstable manifolds (eps_s, eps_u).
- Return type:
tuple
- classmethod with_deflation(manifold: Manifold, eps_s: float, eps_u: float, n_s: int, n_u: int, **kwargs)
find a clinic point using a deflation method and bounds to remove previously found clinic points.
- property trajectory
Get the complete trajectory of the clinic point.
Computes the trajectory by integrating along stable and unstable manifolds if not already calculated.
- Returns:
Array containing the orbit from unstable to stable fixed point.
- Return type:
np.ndarray
- property x_end_s
Get the endpoint on the stable manifold.
- Returns:
Coordinates of the end point on stable manifold.
- Return type:
np.ndarray
- property x_end_u
Get the endpoint on the unstable manifold.
- Returns:
Coordinates of the end point on unstable manifold.
- Return type:
np.ndarray
- property fundamental_segments
Get the fundamental domain boundaries.
- Returns:
Contains ‘stable’ and ‘unstable’ segment bounds.
- Return type:
dict
- class pyoculus.solvers.manifold.ClinicSet(manifold: Manifold)
A collection of homoclinics/heteroclinics with unstable (\(>_u\)) ordering.
This class manages multiple
Clinicobjects, maintaining their ordering and ensuring proper fundamental domain representation. It uses the first clinic added to manage the fundamental domain boundaries.- Parameters:
manifold – The
Manifoldobject associated to the fixed points and the map analyzed.
- _clinics_list
List of Clinic objects.
- Type:
list
- fundamental_segments
Fundamental domain boundaries.
- Type:
dict
- nint_pair
Default iteration numbers (n_s, n_u).
- Type:
tuple
- total_number_of_points
Return the total number of points in the fundamental clinic trajectory.
- stable_segment
Return the stable segment of the fundamental domain.
- unstable_segment
Return the unstable segment of the fundamental domain.
- record_clinic()
Add a new clinic point to the collection.
- reset()
Clear all stored clinics.
- is_empty()
Check if the clinic set is empty.
Examples
>>> a_manifold = Manifold(...) >>> clinic_set = ClinicSet(a_manifold) >>> clinic_set.record_clinic(myclinic)
- property size: int
Number of clinic points in the set.
- property is_empty: bool
Check if the clinic set is empty.
- property total_number_of_points
the number of elements in the fundamental clinic trajectory
- property stable_segment
the stable segment of the fundamental domain
- property unstable_segment
the stable segment of the fundamental domain
- property stable_epsilons
return the stable epsilons of the clinics, including the end of the fundamental section
- property unstable_epsilons
return the unstable epsilons of the clinics, including the end of the fundamental section
- property stable_shifts
return the stable shifts of the clinics
- property unstable_shifts
return the unstable shifts of the clinics (excluding the clinic defining the fundamental section)
- property first_epsilons
return the stable and unstable epsilons of the first clinic in the set
- record_clinic(clinic: Clinic, **kwargs) bool
Record a new clinic point in the fundamental domain.
Creates and stores a new
Clinicobject after converting the given parameters to their fundamental domain representation.- Parameters:
eps_s (float) – Initial distance along stable manifold.
eps_u (float) – Initial distance along unstable manifold.
n_s (int) – Number of iterations for stable manifold.
n_u (int) – Number of iterations for unstable manifold.
**kwargs – Additional keyword arguments: tol (float, optional): Tolerance for comparing epsilon values. Defaults to 1e-2.
- Returns:
True if the clinic was successfully added, False otherwise.
- Return type:
bool
Note
If this is the first clinic point, it establishes the fundamental domain boundaries. Otherwise, parameters are converted to their fundamental domain representation.
- order()
Order the homo/hetero-clinic points with the induced linear ordering of the unstable manifold >_u.
- reset()
remove all known clinics and start afresh.
- class pyoculus.solvers.manifold.Manifold(map: <module 'pyoculus.maps.base_map' from '/home/runner/work/pyoculus/pyoculus/pyoculus/maps/base_map.py'>, fixedpoint_1: ~pyoculus.solvers.fixed_point.FixedPoint, fixedpoint_2: ~pyoculus.solvers.fixed_point.FixedPoint = None, dir1: str | float | ~numpy.ndarray[tuple[~typing.Any, ...], ~numpy.dtype[~numpy._typing._array_like._ScalarT]] = None, dir2: str = None, first_stable: bool = None)
Class for computing and analyzing a tangle composed of one stable and one unstable manifold of fixed points.
This class handles the computation of stable and unstable manifolds for fixed points, including finding homoclinic/heteroclinic intersections and calculating the turnstile flux of the tangle.
We need to resolve some duplicity to determine the direction in which to follow the manifolds of each x-point (M*v=e.v. * v => M*-v = -e.v. * v), this is done with the ‘dir’ keywords.
- Parameters:
map (maps.base_map) – The map defining the dynamical system.
fixedpoint_1 (FixedPoint) – First fixed point to consider.
fixedpoint_2 (FixedPoint, optional) – Second fixed point to consider if the manifolds go from one to the other.
dir1 (str, optional) – Direction if type == str, can be (‘+’ or ‘-’) to multiply eigenvector of the Jacobian. if type == float, approximate angle (with respect of the x-axis) of the manifold to follow if type == np.ndarray, the (approximate) vector of the manifold to follow
dir2 (str, optional) – Direction if type == str, can be (‘+’ or ‘-’) for the second manifold. if type == float, approximate angle (with respect of the x-axis) of the manifold to follow if type == np.ndarray, the (approximate) vector of the manifold to follow
first_stable (bool, optional) – Whether to follow the stable or unstable manifold departing from the first fixed point. Defaults to True.
- fixedpoint_1
First fixed point.
- Type:
- fixedpoint_2
Second fixed point.
- Type:
- rfp_s
Stable fixed point coordinates.
- Type:
np.ndarray
- rfp_u
Unstable fixed point coordinates.
- Type:
np.ndarray
- vector_s
Stable eigenvector.
- Type:
np.ndarray
- vector_u
Unstable eigenvector.
- Type:
np.ndarray
- lambda_s
Stable eigenvalue.
- Type:
float
- lambda_u
Unstable eigenvalue.
- Type:
float
- stable
Stable manifold points.
- Type:
np.array
- unstable
Unstable manifold points.
- Type:
np.array
- turnstile_areas
Turnstile areas of the tangle.
- Type:
np.array
- choose()
Choose the stable and unstable directions for the manifold.
- show_directions()
Plot the fixed points and their stable/unstable directions.
- show_current_directions()
Plot the current stable and unstable directions.
- error_linear_regime()
Metric to evaluate if a point is in the linear regime of a fixed point.
- start_config()
Compute a starting configuration for the manifold drawing.
- find_epsilon()
Find the epsilon that lies in the linear regime.
- compute_manifold()
Compute the stable or unstable manifold.
- compute()
Compute the stable and unstable manifolds.
- plot()
Plot the stable and unstable manifolds.
- find_N()
Find the number of times the map needs to be applied for the stable and unstable points to cross.
- find_clinic_single()
Find a single homoclinic/heteroclinic intersection.
- find_clinic()
Find all homoclinic/heteroclinic intersections.
- compute_turnstile_areas()
Compute the turnstile areas of the tangle.
- Raises:
TypeError – If fixed points are not FixedPoint instances.
ValueError – If fixed points are not successfully computed.
- choose(dir_1: Literal['+', '-'] | float | Iterable, dir_2: Literal['+', '-'] | float | Iterable, first_stable: bool) None
Choose manifold stable and unstable directions to define your
Manifoldproblem.You must choose directions away from the fixed point in which the manifolds actually intersect. The good orientation is the one for which you could create the manifold by going away from the fixed point. Be carefull to this point, otherwise other manifold computations such as clinic finding will fail.
Hint: Use
Manifold.show_directions()to help you choose here. This plot shows the fixed points and the stable eigenvector (and its negative) in green, the unstable eigenvector (and it’s negative) in red.- Parameters:
dir_1 (str) – ‘+’ or ‘-’ for the stable direction.
dir_2 (str) – ‘+’ or ‘-’ for the unstable direction.
first_stable (bool) – Whether to follow the stable or unstable manifold from the first point.
- classmethod show_directions(fp_1: FixedPoint, fp_2: FixedPoint, **kwargs) tuple[Figure, Axes]
Plot fixed points and their stable/unstable directions.
Helper function to plot the fixed points and their stable and unstable direction. Usefull to look at which direction need to be considered for the inner and outer manifolds before creating a class and analyzed them.
- Parameters:
fp_1 (FixedPoint) – First fixed point.
fp_2 (FixedPoint) – Second fixed point.
**kwargs – Optional visualization parameters: pcolors (list): Colors for fixed points. vcolors (list): Colors for eigenvectors. vscale (int): Scale for eigenvectors. dvtext (float): Text distance as fraction.
- Returns:
(figure, axis) matplotlib objects.
- Return type:
tuple
- show_current_directions(vscale=0.2, vcolors=None, **kwargs)
Plot the current stable and unstable directions.
- Parameters:
**kwargs – Optional visualization parameters: vcolors (list): Colors for eigenvectors. vscale (int): Scale for the eigenvectors. dvtext (float): Text distance as fraction.
- Returns:
(figure, axis) matplotlib objects.
- Return type:
tuple
- property first_epsilons
return the stable and unstable epsilons of the first clinic in the set
- error_linear_regime(epsilon: float, rfp: ndarray, eigenvector: ndarray, direction: int = 1) float
Calculate error in linear regime approximation.
Metric to estimate if the point rfp + epsilon * eigenvector is in the linear regime of rfp point.
- Parameters:
epsilon (float) – Distance from fixed point.
rfp (np.ndarray) – Fixed point coordinates.
eigenvector (np.ndarray) – Eigenvector to check.
direction (int, optional) – Integration direction. Defaults to 1.
- Returns:
Error metric for linear approximation.
- Return type:
float
- start_config(epsilon, rfp, eigenvalue, eigenvector, neps, direction=1)
Compute a starting configuration for the manifold drawing. It takes a point in the linear regime and devide the interval from the point to its evolution after one nfp into neps points. The interval is computed geometrically.
- Parameters:
epsilon (float) – initial epsilon
rfp (np.array) – fixed point
eigenvalue (float) – eigenvalue of the fixed point
eigenvector (np.array) – eigenvector of the fixed point
neps (int) – number of points
direction (int) – direction of the integration (1 for forward, -1 for backward)
- Returns:
array of starting points (shape (neps, 2))
- Return type:
np.array
- find_epsilon(which: str, eps_guess=0.001)
Find the epsilon that lies in the linear regime.
- compute_manifold(which: str, eps=None, **kwargs)
Compute the stable or unstable manifold.
- Parameters:
eps (float) – epsilon in the stable or unstable direction
compute_stable (bool) – whether to compute the stable or unstable manifold
- Keyword Arguments:
eps_guess (float) – guess for epsilon (if eps is not given)
neps (int) – number of points in the starting configuration
nint (int) – number of intersections
- Returns:
array of points on the manifold
- Return type:
np.array
- compute(eps_s=None, eps_u=None, **kwargs)
Computation of the stable and unstable manifolds.
- Parameters:
eps_s (float) – epsilon in the stable direction.
eps_u (float) – epsilon in the unstable direction
- Keyword Arguments:
eps_guess_s (float) – guess for epsilon in the stable direction (if eps_s is not given)
eps_guess_u (float) – guess for epsilon in the unstable direction (if eps_u is not given)
neps_s (int) – number of points in the starting configuration for the stable part
neps_u (int) – number of points in the starting configuration for the unstable part
nint_s (int) – number of evolutions of the initial segments for the stable part
nint_u (int) – number of evolutions of the initial segments for the unstable part
- Returns:
A tuple containing two np.array of points, the first one for the stable manifold and the second one for the unstable manifold.
- Return type:
tuple
- get_lobe_boundary(lobe_number, neps=40, which_section: int = 1)
Compute the boundary of the lobe with the given number (counted from the unstable manifold).
The Manifold class must have a computed at least one clinic, preferrably all of them. The boundary of the lobe is computed by mapping the part of the fundamental section of the unstable manifold between two clinic trajecories lobe_number times, and mapping the section of the stable manifold between two clinictrajectories in the reverse direction (clinic_points-lobe_number) times.
which_section determines which of the two sections of the fundamental domain to use.
- plot_lobe_boundary(lobe_number, neps=40, which_section: int = 1, **kwargs)
Plot the boundary of the lobe with the given number (counted from the unstable manifold).
The Manifold class must have a computed at least one clinic, preferrably all of them. The boundary of the lobe is computed by mapping the part of the fundamental section of the unstable manifold between two clinic trajecories lobe_number times, and mapping the section of the stable manifold between two clinictrajectories in the reverse direction (clinic_points-lobe_number) times.
- plot_filled_lobe(lobe_number, neps=40, which_section: int = 1, **kwargs)
Plot the filled lobe with the given number (counted from the unstable manifold).
The Manifold class must have a computed at least one clinic, preferrably all of them. The boundary of the lobe is computed by mapping the part of the fundamental section of the unstable manifold between two clinic trajecories lobe_number times, and mapping the section of the stable manifold between two clinictrajectories in the reverse direction (clinic_points-lobe_number) times.
- plot(which='both', stepsize_limit=None, **kwargs)
Plot the stable and/or unstable manifolds.
kwargs: which (str): which manifold to plot. Can be ‘stable’, ‘unstable’ or ‘both’. stepsize_limit =
Other kwargs are givent to the plot.
Specific extra plots: rm_points (int): remove the last rm_points points of the manifold.
- plot_manifold_copies(which='both', stepsize_limit=None, **kwargs)
plot the images of the manifolds as they appear arount the other islands of the chain, using the periodicity of the fixed points.
- find_N(eps_s: float, eps_u: float)
Find the number of times the map needs to be applied for the stable and unstable points to cross.
This method evolves the initial stable \(x_s = x^\star + \varepsilon_s\textbf{e}_s\) and unstable \(x_u = x^\star + \varepsilon_u\textbf{e}_u\) points until they cross. They are alternatively evolved once and when the initial direction is reversed, the number of iterations is returned.
- Parameters:
eps_s (float, optional) – Initial \(\varepsilon_s\) along the stable manifold direction. Defaults to 1e-3.
eps_u (float, optional) – Initial \(\varepsilon_u\) along the unstable manifold direction. Defaults to 1e-3.
- Returns:
- A tuple containing two integers:
n_s (int): Number of iterations for the stable manifold.
n_u (int): Number of iterations for the unstable manifold.
- Return type:
tuple
- find_clinic_single(guess_eps_s, guess_eps_u, n_s=None, n_u=None, reset_clinics=False, nretry=1, ERR=0.001, **kwargs)
Search a homo/hetero-clinic point.
This function attempts to find the intersection point of the stable and unstable manifolds by iteratively adjusting the provided epsilon guesses using scipy root-finding algorithm.
- Parameters:
guess_eps_s (float) – Initial guess for the stable manifold epsilon.
guess_eps_u (float) – Initial guess for the unstable manifold epsilon.
- kwargs: Additional keyword arguments.
n_s (int): Number of times the map needs to be applied for the stable manifold.
n_u (int): Number of times the map needs to be applied for the unstable manifold.
reset_clinics: replace all clinics and make this clinic the fundamental segment.
nretry: retry by jittering the epsilon guesses n times
ERR (float): Error tolerance for verifying the linear regime (default: 1e-3).
- **kwargs
- root_args (dict): Arguments to pass to the root-finding function.
suggested: {‘jac’:True/False} integrated jacobian or FD for step {‘options’:{‘factor’:1e-3}} takes smaller steps when jac is ill.
- Returns:
A tuple containing the found epsilon values for the stable and unstable manifolds (eps_s, eps_u).
- Return type:
tuple
- find_other_clinic_test(shift_in_stable: float, shift_in_unstable: float = None, nretry=1, **kwargs)
bla
- find_other_clinic(shift_in_stable: float, shift_in_unstable: float = None, nretry=1, **kwargs)
Find another clinic trajectory if the Manifold already has a fundamental segment. Starts the clinic trajectory finding with one less total step by shifting the start points Args: shift_in_stable: point in the stable fundamental segment to start the search from, 0 is from the same point
as the first trajectory, 1 is shifted to the end.
shift_in_unstable (optional): point in the unstable fundamental segment to start the search from, if not given same as shift_in_stable.
- find_clinics(first_guess_eps_s, first_guess_eps_u, n_points=None, reset_clinics=True, **kwargs)
Args:
- plot_clinics(**kwargs)
Plot the clinic trajectories.
- integrate(x_many, nintersect, direction=1)
Integrate a set of points x_many for nintersect times in the direction specified. Robust to integration failures and has fixed return shape.
Returns an array of shape (nintersect, len(x_many), _map.dimension).
- save(path)
save the manifold object to a .pkl file
- classmethod load(path)
load the manifold object from a .pkl file
- save_mf_quasr(path)
save the manifold object for a Stellerator field in a .pkl file
- load_mf_quasr(path)
load the payload saved by save_mf_quasr into the current instance.