bertini.nag_algorithm

nag_algorithms

class bertini.nag_algorithm.AlgorithmMetaData((object)arg1)

Bases: instance

__init__((object)arg1) → None
property elapsed_time

None( (bertini._pybertini.nag_algorithms.AlgorithmMetaData)arg1) -> object

classmethod from_dict(mapping)

Build a config from a dict (default-constructs, then update()).

property number_path_failures

None( (bertini._pybertini.nag_algorithms.AlgorithmMetaData)arg1) -> int

property number_path_successes

None( (bertini._pybertini.nag_algorithms.AlgorithmMetaData)arg1) -> int

property number_paths_tracked

None( (bertini._pybertini.nag_algorithms.AlgorithmMetaData)arg1) -> int

set(**kwargs)

Set one or more fields at once; returns self so calls can chain.

Numeric fields accept strings (e.g. max_step_size=”0.05”), which are converted exactly to multiprecision values. Raises AttributeError on an unknown/misspelled field name.

property start_time

None( (bertini._pybertini.nag_algorithms.AlgorithmMetaData)arg1) -> object

to_dict()

The config’s fields as an ordinary dict of {name: value}.

update(**kwargs)

Set one or more fields at once; returns self so calls can chain.

Numeric fields accept strings (e.g. max_step_size=”0.05”), which are converted exactly to multiprecision values. Raises AttributeError on an unknown/misspelled field name.

class bertini.nag_algorithm.AnyZeroDim

Bases: instance

Raises an exception This class cannot be instantiated from Python

__init__()

Raises an exception This class cannot be instantiated from Python

class bertini.nag_algorithm.AutoRetrackConfig((object)arg1)

Bases: instance

__init__((object)arg1) → None
classmethod from_dict(mapping)

Build a config from a dict (default-constructs, then update()).

property midpath_decrease_tolerance_factor

Factor by which tracking tolerances are tightened when retracking after the midpath check detects a path crossing.

set(**kwargs)

Set one or more fields at once; returns self so calls can chain.

Numeric fields accept strings (e.g. max_step_size=”0.05”), which are converted exactly to multiprecision values. Raises AttributeError on an unknown/misspelled field name.

to_dict()

The config’s fields as an ordinary dict of {name: value}.

update(**kwargs)

Set one or more fields at once; returns self so calls can chain.

Numeric fields accept strings (e.g. max_step_size=”0.05”), which are converted exactly to multiprecision values. Raises AttributeError on an unknown/misspelled field name.

class bertini.nag_algorithm.EndgameBoundaryMetaDataDoublePrec((object)arg1)

Bases: instance

__init__((object)arg1) → None
classmethod from_dict(mapping)

Build a config from a dict (default-constructs, then update()).

property last_used_stepsize

None( (bertini._pybertini.nag_algorithms.EndgameBoundaryMetaDataDoublePrec)arg1) -> float

property path_point

None( (bertini._pybertini.nag_algorithms.EndgameBoundaryMetaDataDoublePrec)arg1) -> object

set(**kwargs)

Set one or more fields at once; returns self so calls can chain.

Numeric fields accept strings (e.g. max_step_size=”0.05”), which are converted exactly to multiprecision values. Raises AttributeError on an unknown/misspelled field name.

property success_code

None( (bertini._pybertini.nag_algorithms.EndgameBoundaryMetaDataDoublePrec)arg1) -> bertini._pybertini.tracking.SuccessCode

to_dict()

The config’s fields as an ordinary dict of {name: value}.

update(**kwargs)

Set one or more fields at once; returns self so calls can chain.

Numeric fields accept strings (e.g. max_step_size=”0.05”), which are converted exactly to multiprecision values. Raises AttributeError on an unknown/misspelled field name.

class bertini.nag_algorithm.EndgameBoundaryMetaDataMultiPrec((object)arg1)

Bases: instance

__init__((object)arg1) → None
classmethod from_dict(mapping)

Build a config from a dict (default-constructs, then update()).

property last_used_stepsize

None( (bertini._pybertini.nag_algorithms.EndgameBoundaryMetaDataMultiPrec)arg1) -> bertini._pybertini.multiprec.real_mp

property path_point

None( (bertini._pybertini.nag_algorithms.EndgameBoundaryMetaDataMultiPrec)arg1) -> object

set(**kwargs)

Set one or more fields at once; returns self so calls can chain.

Numeric fields accept strings (e.g. max_step_size=”0.05”), which are converted exactly to multiprecision values. Raises AttributeError on an unknown/misspelled field name.

property success_code

None( (bertini._pybertini.nag_algorithms.EndgameBoundaryMetaDataMultiPrec)arg1) -> bertini._pybertini.tracking.SuccessCode

to_dict()

The config’s fields as an ordinary dict of {name: value}.

update(**kwargs)

Set one or more fields at once; returns self so calls can chain.

Numeric fields accept strings (e.g. max_step_size=”0.05”), which are converted exactly to multiprecision values. Raises AttributeError on an unknown/misspelled field name.

class bertini.nag_algorithm.HomotopySolverCauchyAdaptivePrecision((object)arg1, (bertini._pybertini.system.System)target, (UserStartSystem)start, (bertini._pybertini.system.System)homotopy)

Bases: AnyZeroDim

__init__((object)arg1, (bertini._pybertini.system.System)target, (UserStartSystem)start, (bertini._pybertini.system.System)homotopy) → None
add_observer((object)self, (object)observer) → None :

Attach an observer to this observable object

all_solutions((HomotopySolverCauchyAdaptivePrecision)self[, (bool)user_coords=True]) → bertini._pybertini.container.ListOfVectorComplexVariablePrecision :

get ALL the computed solutions, one per tracked path (finite, at-infinity, and failed alike). by default they are in the coordinates of YOUR variables (dehomogenized, depatched). pass user_coords=False to decline, getting the solver’s internal coordinates instead: homogenized, lying on the target system’s patch – the representation to use for continuing work. the container is computed at most once per solve; repeated calls and indexing do not recompute it. for the filtered view see solutions(); for the at-infinity ones see infinite_solutions.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

config_names()

The keyword names accepted by configure() for this owner, its tracker and its endgame.

config_types((HomotopySolverCauchyAdaptivePrecision)self) → list :

List the configuration struct classes this object accepts.

configure(**kwargs)

Change settings on this owner’s configs in one call.

Each keyword names a config (e.g. stepping, newton, tolerances); its value is either a dict of fields to change, or a ready config object.

tracker.configure(stepping={‘max_step_size’: 0.1},

newton={‘max_num_newton_iterations’: 2})

Returns self.

default_point_match_tolerance((HomotopySolverCauchyAdaptivePrecision)arg1) → float :

the default infinity-norm tolerance metadata_for() uses when you omit tol: the solver’s final_tolerance (the accuracy each endpoint is computed to). Since metadata_for matches against representatives – which are at least the same-point clustering tolerance apart – this tight default still resolves a fed-back solution to itself while making an ambiguous match structurally impossible.

endgame_boundary_metadata((HomotopySolverCauchyAdaptivePrecision)arg1) → MidpathCheckReport :

get the MidpathCheckReport from the path-crossing check at the endgame boundary: how many crossings were detected, which paths, how many re-track attempts were made, and whether the check ultimately passed

endgame_boundary_solutions((HomotopySolverCauchyAdaptivePrecision)arg1) → bertini._pybertini.container.ListOfEGBoundaryMetaData_MultiPrec :

get the solutions (per-path point data) at the endgame boundary, where regular tracking switches to the endgame

finite_solutions((HomotopySolverCauchyAdaptivePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the FINITE solutions: successful endpoints the solver calls finite (is_finite applies endpoint_finite_threshold). includes singular, nonsingular, and real solutions alike. merge_multiplicities=True (default) collapses each multiple solution to one representative. user coordinates by default; user_coords=False for internal coordinates.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

get_config((HomotopySolverCauchyAdaptivePrecision)self, (object)config_type) → object :

Return a copy of this object’s stored configuration struct of the given class.

The named config, by class (TolerancesConfig) or by short name ('tolerances',

as config_names() lists them).

Either may belong to this object’s tracker or endgame rather than to the object itself (solver.get_config('stepping'), solver.get_config(EndgameConfig)); it is fetched from whichever holds it, so every name config_names() lists can be asked for.

get_endgame((HomotopySolverCauchyAdaptivePrecision)arg1) → bertini._pybertini.endgame.AMPCauchyEndgame :

get a mutable reference to the Endgame being used

get_settings(as_dict=False)

This owner’s whole configuration as a carryable dict.

By default (as_dict=False) the value is {config_name: config} – each a copy of one of the owner’s configs (e.g. {'stepping': SteppingConfig(...), 'tolerances': TolerancesConfig(...)}), keyed by the short names config_names() lists. The configs are independent copies (and picklable), so the dict is a plain Python value you can stash, tweak, and apply to other owners – the way to carry one set of tracking settings across a series of related solves:

settings = first_solver.get_settings()
next_solver.set_settings(settings)

Pass as_dict=True for the flat, human-readable view instead: one {field_name: value} dict across ALL configs (field names are unique across an owner’s configs, so there is no collision). That form drops the struct layer nobody wants to poke at, and round-trips through set:

flat = solver.get_settings(as_dict=True)   # {'final_tolerance': ..., 'max_step_size': ..., ...}
other.set(**flat)

(The config-keyed default is kept because set_settings consumes it; use whichever fits.) See set_settings() for applying the config-keyed form back.

get_tracker((HomotopySolverCauchyAdaptivePrecision)arg1) → bertini._pybertini.tracking.AMPTracker :

get a mutable reference to the Tracker being used

infinite_solutions((HomotopySolverCauchyAdaptivePrecision)self[, (bool)user_coords=True]) → list :

the solutions AT INFINITY: endpoints not classified finite (is_finite is False). these are the paths the endgame resolved as diverging – its GoingToInfinity / SecurityMaxNormReached verdict, or a successful endpoint whose dehomogenized infinity norm exceeds endpoint_finite_threshold. the complement of finite_solutions within all_solutions. NOTE a path that FAILED before the endgame also has is_finite False (its point is not a real solution at infinity); inspect solution_metadata()/report() to tell a true divergence from a tracking failure.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

metadata_for((HomotopySolverCauchyAdaptivePrecision)self, (numpy.ndarray)point[, (float)tol=-1.0[, (bool)coincident=False[, (bool)user_coords=True[, (bool)representatives_only=True]]]]) → object :

the SolutionMetaData for the solution matching point (issue #302). Matches by the infinity-norm tolerance tol (see is_distinct_up_to) against the multiplicity REPRESENTATIVES – one candidate per distinct solution. tol is OPTIONAL: omit it (or pass a non-positive value) to use default_point_match_tolerance() (the solver’s final_tolerance). Because representatives are at least the same-point tolerance apart and the default window is smaller, a pt taken straight from solutions() / real_solutions() / etc. (which return representatives) matches its own representative back and is NEVER reported ambiguous – feed a solver result straight back in and it Just Works. The return type NEVER depends on the point’s multiplicity: by default returns exactly ONE record – the multiplicity-cluster representative (it carries .multiplicity, so you still learn m). coincident=True instead ALWAYS returns a LIST of every coincident copy’s record (their per-path condition number / residual / precision), length 1 for a simple root. representatives_only=False matches against EVERY endpoint including non-representative multiplicity copies – a debugging view, rarely what you want. Raises if no solution matches within tol, or (only for a deliberately coarse tol) if the point matches more than one distinct cluster. point is in user coordinates unless user_coords=False. Accepts any numpy array of the solver’s complex type – which is exactly what the solution lists return.

nonsingular_solutions((HomotopySolverCauchyAdaptivePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the NONSINGULAR finite solutions (simple, well-conditioned roots). (Nonsingular solutions are simple, so merge_multiplicities is a no-op; kept for a uniform signature.)

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

nonsolutions((HomotopySolverCauchyAdaptivePrecision)self[, (bool)user_coords=True]) → list :

the NONSOLUTIONS: finite, successful endpoints that are NOT solutions of the target system – the extraneous nonsolutions a squared-up over-determined system introduces (empty otherwise). Excluded from finite_solutions/real/singular; a regeneration cascade reads these to discard them.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

num_paths((HomotopySolverCauchyAdaptivePrecision)self) → int :

How many paths this solve has to answer – the start system’s start point count. Known once a solve has begun its setup, which is before the first path event, and 0 before that.

num_paths_never_started((HomotopySolverCauchyAdaptivePrecision)self) → int :

How many paths the last solve() never began, because it was stopped first.

num_paths_recalled((HomotopySolverCauchyAdaptivePrecision)self) → int :

How many paths the last solve() recalled from the records instead of computing (0 on a fresh solve; num_paths on a full memo hit).

real_solutions((HomotopySolverCauchyAdaptivePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the REAL finite solutions (is_real applies the configured tolerance). merge_multiplicities=True (default) collapses each multiple solution to one representative.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

record_to((HomotopySolverCauchyAdaptivePrecision)self, (str)directory) → None :

Attach a structured output directory at the given path: this solve records every path as it completes (durable, plain-text, see the directory’s README.txt) and consults the records before computing – an identical ask (same system, settings, seed) recalls from the records instead of re-tracking, so a crashed solve resumes by simply calling solve() again. Recording is ON BY DEFAULT with no code at all: an unattached solver records to the ambient directory (BERTINI_RECORDS_DIR, else ./bertini_output; the value ‘none’ switches records off). record_to chooses the directory explicitly and always wins over the ambient resolution.

records_path((HomotopySolverCauchyAdaptivePrecision)self) → object :

The attached output directory’s path, or None when not recording.

records_run_id((HomotopySolverCauchyAdaptivePrecision)self) → str :

This solve’s run id in the records (empty until a recording solve() runs). Points are referenced as {run, index} pairs; this is the run half.

remove_observer((object)self, (object)observer) → None :

Remove an observer to this observable object

report((HomotopySolverCauchyAdaptivePrecision)arg1) → SolveReport :

a concise end-of-solve diagnostic summary (a SolveReport): how every path ended up – finite solutions, diverged, or FAILED (by named reason) – plus singular/real counts, max condition number, the path-crossing outcome, and all_paths_resolved. print(solver.report()) for a human-readable summary; a count alone can hide a path the tracker silently lost.

result()

This solve’s SolveResult: the finite solutions plus the records ticket (run id, directory, recall count), read from the solver’s own recorded state.

A bare solver.solve() already returns this; result() re-derives it (call it after solve()) if you did not keep the return value.

same_point_tolerance((HomotopySolverCauchyAdaptivePrecision)arg1) → float :

the same-point (clustering) tolerance, final_tolerance * same_point_tolerance_multiplier: the looser tolerance the solver uses to decide two endpoints are the SAME solution and cluster them into one multiplicity (and that metadata_for(coincident=True) uses to gather a cluster’s copies).

set(**fields)

Set config fields on this owner by NAME, each routed to whichever config owns it.

You never name the config struct:

solver.update(final_tolerance="1e-11",          # -> TolerancesConfig
              max_num_crossed_path_resolve_attempts=3)   # -> ZeroDimConfig

Strings work for every numeric field (converted exactly). A field that none of this owner’s configs has raises AttributeError with the valid names – so a typo, or trying to set a tracker field on the algorithm (or vice versa), never silently does nothing. Returns self, so calls chain. To set a whole config at once, or to name the config explicitly, use configure().

set_config((HomotopySolverCauchyAdaptivePrecision)self, (TolerancesConfig)config) → None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (HomotopySolverCauchyAdaptivePrecision)self, (PostProcessingConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (HomotopySolverCauchyAdaptivePrecision)self, (ZeroDimConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (HomotopySolverCauchyAdaptivePrecision)self, (AutoRetrackConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (HomotopySolverCauchyAdaptivePrecision)self, (RecordsConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (HomotopySolverCauchyAdaptivePrecision)self, (MidPathConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

Store a configuration struct, on this object or on whichever of its tracker and

endgame owns that config’s type.

set_recorded_start_provenance((HomotopySolverCauchyAdaptivePrecision)self, (str)refs_json, (str)start_identity) → None :

Declare where this solve’s start points came from, for the records: a JSON array with one reference object per path ({‘kind’:’point_ref’,’run’:…,’index’:…} for a chain from a prior run, {‘kind’:’given_ref’,’given’:…,’index’:…} for external data), plus an identity string for the start data (it joins the ask: same homotopy, different starts = different computation). Call before solve().

set_settings(settings, strict=False)

Apply a settings dict (from get_settings()) onto this owner. Returns self.

settings is {config_name: config} (or {config_name: {field: value}}). By default only the configs this owner actually has are applied and the rest are skipped – so a bundle carried from one solver drops cleanly onto another whose config set differs (e.g. a different precision model, or a different algorithm stage). Pass strict=True to instead raise on any key this owner does not have.

singular_solutions((HomotopySolverCauchyAdaptivePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the SINGULAR finite solutions (multiple or ill-conditioned roots). merge_multiplicities=True (default) collapses each multiple solution to one representative.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

solution_metadata((HomotopySolverCauchyAdaptivePrecision)arg1) → bertini._pybertini.container.ListOfSolutionMetaData_MultiPrec :

get the metadata for the solutions at the target time

solutions((HomotopySolverCauchyAdaptivePrecision)self[, (bool)singular=True[, (bool)real=True[, (bool)nonreal=True[, (bool)nonsingular=True[, (bool)infinite=False[, (bool)nonsolution=False[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]]]]]]]) → list :

the solutions, filtered by category (returns points, not metadata). By DEFAULT every finite genuine solution – real and complex, simple and multiple – and nothing else. Each keyword toggles a category: singular / nonsingular select by conditioning, real / nonreal by realness (a finite solution is returned only if BOTH its conditioning class and its realness class are enabled), infinite=True also returns the at-infinity endpoints, and nonsolution=True also returns the nonsolutions. E.g. solutions(real=False) -> complex finite solutions only; solutions(singular=False) -> nonsingular finite solutions; solutions(infinite=True) adds the divergent paths. merge_multiplicities=True (the DEFAULT) collapses a multiplicity-m solution to its single representative (pass False to get all m coincident copies). user_coords=False gives the solver’s internal coordinates. See also real_solutions / nonsingular_solutions / singular_solutions / infinite_solutions / nonsolutions for the common single-category views, and all_solutions for the raw per-path list.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

solve((HomotopySolverCauchyAdaptivePrecision)arg1[, (object)communicator=None]) → None :

Run the zero-dim algorithm. Pass an mpi4py communicator for parallel execution.

Settings: pass config fields either as a dict (settings={‘final_tolerance’: 1e-13}) or by keyword (solve(final_tolerance=1e-13)); each is applied via set() before solving, so make/set/solve becomes a single call. communicator= is reserved for MPI (never a setting).

show_progress=True (the default) reports how far the solve has got. It draws nothing unless the solve runs past a few seconds AND stderr is a terminal, so scripts, pipelines and test runs see nothing; pass show_progress=False to be certain of silence.

Returns a bertini.records.SolveResult – the finite solutions plus this solve’s records ticket (run id, directory, recall count), read from the solver’s own records (the solver records itself, on by default). Drop it freely: solver.result() re-derives it, and the records hold the truth.

target_system((HomotopySolverCauchyAdaptivePrecision)arg1) → bertini._pybertini.system.System :

get the prepared target system: the homogenized, auto-patched clone of the system you supplied. its patch is the one internal-coordinate solutions lie on; use its dehomogenize_point/homogenize_point/variable_ordering to move between representations.

to_classic_input((HomotopySolverCauchyAdaptivePrecision)self, (bertini._pybertini.system.System)system) → str :

emit a complete Bertini 1 classic input file (CONFIG + INPUT) for the given natural system, using THIS solver’s tracking settings for the CONFIG: precision mode (mptype), ODE predictor, tolerances (before/during endgame, final), the full step-size cadence, max Newton iterations, and the crossed-path resolve cap. The system you pass supplies INPUT – pass the natural (un-homogenized) system you constructed the solver from, since the solver homogenizes and patches its internal copy. Use this to re-run the exact same problem with the exact same knobs in Bertini 1 for cross-validation (the random start system aside). For sweeping settings without a solver, see system.to_classic_input(**kwargs).

to_dataframe(*, user_coords=True, omit_infinite=True, merge_multiplicities=True, group=None)

The solve as a pandas DataFrame – one row per solution, the “database of solutions”.

Columns are solution – the whole solution point, kept in a single cell – then every per-solution metadata field (is_finite, is_real, is_singular, multiplicity, condition_number, endgame_success_code, max_precision_used, …), and finally system, a reference to the (target) system these solutions satisfy (so rows accumulated from several solves stay identifiable). Each category is then a one-line filter, e.g. df[df.is_real & ~df.is_singular] (nonsingular real) or df[~df.is_finite] (at infinity).

The solution cell is an independent copy of the solution vector (a numpy array of Python complex for a double solve, of bertini.complex_mp for a multiprecision one, so no precision is lost). Coordinates are deliberately not exploded into x0, x1, ... columns; split them yourself if you want them, e.g. df['x'] = [v[0] for v in df.solution].

Parameters:
  • user_coords (bool) – Coordinates in YOUR variables (dehomogenized; default), or the solver’s internal homogenized on-patch coordinates when False – the same choice as all_solutions().

  • omit_infinite (bool) – Drop the endpoints not classified finite (is_finite False) – the at-infinity and failed paths. True by default, so the frame holds just the genuine finite solutions; pass False to get every tracked path (their coordinate cells may be empty/NaN).

  • merge_multiplicities (bool) – Collapse a multiplicity-m solution – which the solver returns as m coincident endpoints – to its single representative row (multiplicity still records m). True by default. Pass False to keep every endpoint, including the m-1 duplicate copies. The grouping is the solver’s own (the C++ clustering that computes multiplicity), read off multiplicity_representative; this does not re-cluster.

  • group (VariableGroup or int, optional) – Project each solution onto one variable group – the solution cell then holds only that group’s coordinates (Cluster G). Pass the VariableGroup object or its 0-based FIFO index. None (default) keeps the whole point.

Returns:

One row per solution; the solution cell is a copied vector whose elements are Python complex for a double-precision solve and bertini.complex_mp for a multiprecision one (kept native, so no precision is lost).

Return type:

pandas.DataFrame

Notes

pandas is an optional dependency; this raises ImportError if it is absent. The point accessors – all_solutions(), finite_solutions(), solution_metadata() – are the no-pandas path.

update(**fields)

Set config fields on this owner by NAME, each routed to whichever config owns it.

You never name the config struct:

solver.update(final_tolerance="1e-11",          # -> TolerancesConfig
              max_num_crossed_path_resolve_attempts=3)   # -> ZeroDimConfig

Strings work for every numeric field (converted exactly). A field that none of this owner’s configs has raises AttributeError with the valid names – so a typo, or trying to set a tracker field on the algorithm (or vice versa), never silently does nothing. Returns self, so calls chain. To set a whole config at once, or to name the config explicitly, use configure().

was_stopped_early((HomotopySolverCauchyAdaptivePrecision)self) → bool :

Was the last solve() stopped before it finished – by Ctrl-C, or by request_stop()? If so the results are a PARTIAL set: paths in flight were abandoned and read SuccessCode.ExternallyTerminated, paths not yet begun still read NeverStarted, and every count derived from them describes only what was tracked. Re-running the same solve recalls the finished paths from the records and tracks only the rest.

class bertini.nag_algorithm.HomotopySolverCauchyDoublePrecision((object)arg1, (bertini._pybertini.system.System)target, (UserStartSystem)start, (bertini._pybertini.system.System)homotopy)

Bases: AnyZeroDim

__init__((object)arg1, (bertini._pybertini.system.System)target, (UserStartSystem)start, (bertini._pybertini.system.System)homotopy) → None
add_observer((object)self, (object)observer) → None :

Attach an observer to this observable object

all_solutions((HomotopySolverCauchyDoublePrecision)self[, (bool)user_coords=True]) → bertini._pybertini.container.ListOfVectorComplexDoublePrecision :

get ALL the computed solutions, one per tracked path (finite, at-infinity, and failed alike). by default they are in the coordinates of YOUR variables (dehomogenized, depatched). pass user_coords=False to decline, getting the solver’s internal coordinates instead: homogenized, lying on the target system’s patch – the representation to use for continuing work. the container is computed at most once per solve; repeated calls and indexing do not recompute it. for the filtered view see solutions(); for the at-infinity ones see infinite_solutions.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

config_names()

The keyword names accepted by configure() for this owner, its tracker and its endgame.

config_types((HomotopySolverCauchyDoublePrecision)self) → list :

List the configuration struct classes this object accepts.

configure(**kwargs)

Change settings on this owner’s configs in one call.

Each keyword names a config (e.g. stepping, newton, tolerances); its value is either a dict of fields to change, or a ready config object.

tracker.configure(stepping={‘max_step_size’: 0.1},

newton={‘max_num_newton_iterations’: 2})

Returns self.

default_point_match_tolerance((HomotopySolverCauchyDoublePrecision)arg1) → float :

the default infinity-norm tolerance metadata_for() uses when you omit tol: the solver’s final_tolerance (the accuracy each endpoint is computed to). Since metadata_for matches against representatives – which are at least the same-point clustering tolerance apart – this tight default still resolves a fed-back solution to itself while making an ambiguous match structurally impossible.

endgame_boundary_metadata((HomotopySolverCauchyDoublePrecision)arg1) → MidpathCheckReport :

get the MidpathCheckReport from the path-crossing check at the endgame boundary: how many crossings were detected, which paths, how many re-track attempts were made, and whether the check ultimately passed

endgame_boundary_solutions((HomotopySolverCauchyDoublePrecision)arg1) → bertini._pybertini.container.ListOfEGBoundaryMetaData_DoublePrec :

get the solutions (per-path point data) at the endgame boundary, where regular tracking switches to the endgame

finite_solutions((HomotopySolverCauchyDoublePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the FINITE solutions: successful endpoints the solver calls finite (is_finite applies endpoint_finite_threshold). includes singular, nonsingular, and real solutions alike. merge_multiplicities=True (default) collapses each multiple solution to one representative. user coordinates by default; user_coords=False for internal coordinates.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

get_config((HomotopySolverCauchyDoublePrecision)self, (object)config_type) → object :

Return a copy of this object’s stored configuration struct of the given class.

The named config, by class (TolerancesConfig) or by short name ('tolerances',

as config_names() lists them).

Either may belong to this object’s tracker or endgame rather than to the object itself (solver.get_config('stepping'), solver.get_config(EndgameConfig)); it is fetched from whichever holds it, so every name config_names() lists can be asked for.

get_endgame((HomotopySolverCauchyDoublePrecision)arg1) → bertini._pybertini.endgame.FixedDoubleCauchyEndgame :

get a mutable reference to the Endgame being used

get_settings(as_dict=False)

This owner’s whole configuration as a carryable dict.

By default (as_dict=False) the value is {config_name: config} – each a copy of one of the owner’s configs (e.g. {'stepping': SteppingConfig(...), 'tolerances': TolerancesConfig(...)}), keyed by the short names config_names() lists. The configs are independent copies (and picklable), so the dict is a plain Python value you can stash, tweak, and apply to other owners – the way to carry one set of tracking settings across a series of related solves:

settings = first_solver.get_settings()
next_solver.set_settings(settings)

Pass as_dict=True for the flat, human-readable view instead: one {field_name: value} dict across ALL configs (field names are unique across an owner’s configs, so there is no collision). That form drops the struct layer nobody wants to poke at, and round-trips through set:

flat = solver.get_settings(as_dict=True)   # {'final_tolerance': ..., 'max_step_size': ..., ...}
other.set(**flat)

(The config-keyed default is kept because set_settings consumes it; use whichever fits.) See set_settings() for applying the config-keyed form back.

get_tracker((HomotopySolverCauchyDoublePrecision)arg1) → bertini._pybertini.tracking.DoublePrecisionTracker :

get a mutable reference to the Tracker being used

infinite_solutions((HomotopySolverCauchyDoublePrecision)self[, (bool)user_coords=True]) → list :

the solutions AT INFINITY: endpoints not classified finite (is_finite is False). these are the paths the endgame resolved as diverging – its GoingToInfinity / SecurityMaxNormReached verdict, or a successful endpoint whose dehomogenized infinity norm exceeds endpoint_finite_threshold. the complement of finite_solutions within all_solutions. NOTE a path that FAILED before the endgame also has is_finite False (its point is not a real solution at infinity); inspect solution_metadata()/report() to tell a true divergence from a tracking failure.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

metadata_for((HomotopySolverCauchyDoublePrecision)self, (numpy.ndarray)point[, (float)tol=-1.0[, (bool)coincident=False[, (bool)user_coords=True[, (bool)representatives_only=True]]]]) → object :

the SolutionMetaData for the solution matching point (issue #302). Matches by the infinity-norm tolerance tol (see is_distinct_up_to) against the multiplicity REPRESENTATIVES – one candidate per distinct solution. tol is OPTIONAL: omit it (or pass a non-positive value) to use default_point_match_tolerance() (the solver’s final_tolerance). Because representatives are at least the same-point tolerance apart and the default window is smaller, a pt taken straight from solutions() / real_solutions() / etc. (which return representatives) matches its own representative back and is NEVER reported ambiguous – feed a solver result straight back in and it Just Works. The return type NEVER depends on the point’s multiplicity: by default returns exactly ONE record – the multiplicity-cluster representative (it carries .multiplicity, so you still learn m). coincident=True instead ALWAYS returns a LIST of every coincident copy’s record (their per-path condition number / residual / precision), length 1 for a simple root. representatives_only=False matches against EVERY endpoint including non-representative multiplicity copies – a debugging view, rarely what you want. Raises if no solution matches within tol, or (only for a deliberately coarse tol) if the point matches more than one distinct cluster. point is in user coordinates unless user_coords=False. Accepts any numpy array of the solver’s complex type – which is exactly what the solution lists return.

nonsingular_solutions((HomotopySolverCauchyDoublePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the NONSINGULAR finite solutions (simple, well-conditioned roots). (Nonsingular solutions are simple, so merge_multiplicities is a no-op; kept for a uniform signature.)

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

nonsolutions((HomotopySolverCauchyDoublePrecision)self[, (bool)user_coords=True]) → list :

the NONSOLUTIONS: finite, successful endpoints that are NOT solutions of the target system – the extraneous nonsolutions a squared-up over-determined system introduces (empty otherwise). Excluded from finite_solutions/real/singular; a regeneration cascade reads these to discard them.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

num_paths((HomotopySolverCauchyDoublePrecision)self) → int :

How many paths this solve has to answer – the start system’s start point count. Known once a solve has begun its setup, which is before the first path event, and 0 before that.

num_paths_never_started((HomotopySolverCauchyDoublePrecision)self) → int :

How many paths the last solve() never began, because it was stopped first.

num_paths_recalled((HomotopySolverCauchyDoublePrecision)self) → int :

How many paths the last solve() recalled from the records instead of computing (0 on a fresh solve; num_paths on a full memo hit).

real_solutions((HomotopySolverCauchyDoublePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the REAL finite solutions (is_real applies the configured tolerance). merge_multiplicities=True (default) collapses each multiple solution to one representative.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

record_to((HomotopySolverCauchyDoublePrecision)self, (str)directory) → None :

Attach a structured output directory at the given path: this solve records every path as it completes (durable, plain-text, see the directory’s README.txt) and consults the records before computing – an identical ask (same system, settings, seed) recalls from the records instead of re-tracking, so a crashed solve resumes by simply calling solve() again. Recording is ON BY DEFAULT with no code at all: an unattached solver records to the ambient directory (BERTINI_RECORDS_DIR, else ./bertini_output; the value ‘none’ switches records off). record_to chooses the directory explicitly and always wins over the ambient resolution.

records_path((HomotopySolverCauchyDoublePrecision)self) → object :

The attached output directory’s path, or None when not recording.

records_run_id((HomotopySolverCauchyDoublePrecision)self) → str :

This solve’s run id in the records (empty until a recording solve() runs). Points are referenced as {run, index} pairs; this is the run half.

remove_observer((object)self, (object)observer) → None :

Remove an observer to this observable object

report((HomotopySolverCauchyDoublePrecision)arg1) → SolveReport :

a concise end-of-solve diagnostic summary (a SolveReport): how every path ended up – finite solutions, diverged, or FAILED (by named reason) – plus singular/real counts, max condition number, the path-crossing outcome, and all_paths_resolved. print(solver.report()) for a human-readable summary; a count alone can hide a path the tracker silently lost.

result()

This solve’s SolveResult: the finite solutions plus the records ticket (run id, directory, recall count), read from the solver’s own recorded state.

A bare solver.solve() already returns this; result() re-derives it (call it after solve()) if you did not keep the return value.

same_point_tolerance((HomotopySolverCauchyDoublePrecision)arg1) → float :

the same-point (clustering) tolerance, final_tolerance * same_point_tolerance_multiplier: the looser tolerance the solver uses to decide two endpoints are the SAME solution and cluster them into one multiplicity (and that metadata_for(coincident=True) uses to gather a cluster’s copies).

set(**fields)

Set config fields on this owner by NAME, each routed to whichever config owns it.

You never name the config struct:

solver.update(final_tolerance="1e-11",          # -> TolerancesConfig
              max_num_crossed_path_resolve_attempts=3)   # -> ZeroDimConfig

Strings work for every numeric field (converted exactly). A field that none of this owner’s configs has raises AttributeError with the valid names – so a typo, or trying to set a tracker field on the algorithm (or vice versa), never silently does nothing. Returns self, so calls chain. To set a whole config at once, or to name the config explicitly, use configure().

set_config((HomotopySolverCauchyDoublePrecision)self, (TolerancesConfig)config) → None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (HomotopySolverCauchyDoublePrecision)self, (PostProcessingConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (HomotopySolverCauchyDoublePrecision)self, (ZeroDimConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (HomotopySolverCauchyDoublePrecision)self, (AutoRetrackConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (HomotopySolverCauchyDoublePrecision)self, (RecordsConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (HomotopySolverCauchyDoublePrecision)self, (MidPathConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

Store a configuration struct, on this object or on whichever of its tracker and

endgame owns that config’s type.

set_recorded_start_provenance((HomotopySolverCauchyDoublePrecision)self, (str)refs_json, (str)start_identity) → None :

Declare where this solve’s start points came from, for the records: a JSON array with one reference object per path ({‘kind’:’point_ref’,’run’:…,’index’:…} for a chain from a prior run, {‘kind’:’given_ref’,’given’:…,’index’:…} for external data), plus an identity string for the start data (it joins the ask: same homotopy, different starts = different computation). Call before solve().

set_settings(settings, strict=False)

Apply a settings dict (from get_settings()) onto this owner. Returns self.

settings is {config_name: config} (or {config_name: {field: value}}). By default only the configs this owner actually has are applied and the rest are skipped – so a bundle carried from one solver drops cleanly onto another whose config set differs (e.g. a different precision model, or a different algorithm stage). Pass strict=True to instead raise on any key this owner does not have.

singular_solutions((HomotopySolverCauchyDoublePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the SINGULAR finite solutions (multiple or ill-conditioned roots). merge_multiplicities=True (default) collapses each multiple solution to one representative.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

solution_metadata((HomotopySolverCauchyDoublePrecision)arg1) → bertini._pybertini.container.ListOfSolutionMetaData_DoublePrec :

get the metadata for the solutions at the target time

solutions((HomotopySolverCauchyDoublePrecision)self[, (bool)singular=True[, (bool)real=True[, (bool)nonreal=True[, (bool)nonsingular=True[, (bool)infinite=False[, (bool)nonsolution=False[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]]]]]]]) → list :

the solutions, filtered by category (returns points, not metadata). By DEFAULT every finite genuine solution – real and complex, simple and multiple – and nothing else. Each keyword toggles a category: singular / nonsingular select by conditioning, real / nonreal by realness (a finite solution is returned only if BOTH its conditioning class and its realness class are enabled), infinite=True also returns the at-infinity endpoints, and nonsolution=True also returns the nonsolutions. E.g. solutions(real=False) -> complex finite solutions only; solutions(singular=False) -> nonsingular finite solutions; solutions(infinite=True) adds the divergent paths. merge_multiplicities=True (the DEFAULT) collapses a multiplicity-m solution to its single representative (pass False to get all m coincident copies). user_coords=False gives the solver’s internal coordinates. See also real_solutions / nonsingular_solutions / singular_solutions / infinite_solutions / nonsolutions for the common single-category views, and all_solutions for the raw per-path list.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

solve((HomotopySolverCauchyDoublePrecision)arg1[, (object)communicator=None]) → None :

Run the zero-dim algorithm. Pass an mpi4py communicator for parallel execution.

Settings: pass config fields either as a dict (settings={‘final_tolerance’: 1e-13}) or by keyword (solve(final_tolerance=1e-13)); each is applied via set() before solving, so make/set/solve becomes a single call. communicator= is reserved for MPI (never a setting).

show_progress=True (the default) reports how far the solve has got. It draws nothing unless the solve runs past a few seconds AND stderr is a terminal, so scripts, pipelines and test runs see nothing; pass show_progress=False to be certain of silence.

Returns a bertini.records.SolveResult – the finite solutions plus this solve’s records ticket (run id, directory, recall count), read from the solver’s own records (the solver records itself, on by default). Drop it freely: solver.result() re-derives it, and the records hold the truth.

target_system((HomotopySolverCauchyDoublePrecision)arg1) → bertini._pybertini.system.System :

get the prepared target system: the homogenized, auto-patched clone of the system you supplied. its patch is the one internal-coordinate solutions lie on; use its dehomogenize_point/homogenize_point/variable_ordering to move between representations.

to_classic_input((HomotopySolverCauchyDoublePrecision)self, (bertini._pybertini.system.System)system) → str :

emit a complete Bertini 1 classic input file (CONFIG + INPUT) for the given natural system, using THIS solver’s tracking settings for the CONFIG: precision mode (mptype), ODE predictor, tolerances (before/during endgame, final), the full step-size cadence, max Newton iterations, and the crossed-path resolve cap. The system you pass supplies INPUT – pass the natural (un-homogenized) system you constructed the solver from, since the solver homogenizes and patches its internal copy. Use this to re-run the exact same problem with the exact same knobs in Bertini 1 for cross-validation (the random start system aside). For sweeping settings without a solver, see system.to_classic_input(**kwargs).

to_dataframe(*, user_coords=True, omit_infinite=True, merge_multiplicities=True, group=None)

The solve as a pandas DataFrame – one row per solution, the “database of solutions”.

Columns are solution – the whole solution point, kept in a single cell – then every per-solution metadata field (is_finite, is_real, is_singular, multiplicity, condition_number, endgame_success_code, max_precision_used, …), and finally system, a reference to the (target) system these solutions satisfy (so rows accumulated from several solves stay identifiable). Each category is then a one-line filter, e.g. df[df.is_real & ~df.is_singular] (nonsingular real) or df[~df.is_finite] (at infinity).

The solution cell is an independent copy of the solution vector (a numpy array of Python complex for a double solve, of bertini.complex_mp for a multiprecision one, so no precision is lost). Coordinates are deliberately not exploded into x0, x1, ... columns; split them yourself if you want them, e.g. df['x'] = [v[0] for v in df.solution].

Parameters:
  • user_coords (bool) – Coordinates in YOUR variables (dehomogenized; default), or the solver’s internal homogenized on-patch coordinates when False – the same choice as all_solutions().

  • omit_infinite (bool) – Drop the endpoints not classified finite (is_finite False) – the at-infinity and failed paths. True by default, so the frame holds just the genuine finite solutions; pass False to get every tracked path (their coordinate cells may be empty/NaN).

  • merge_multiplicities (bool) – Collapse a multiplicity-m solution – which the solver returns as m coincident endpoints – to its single representative row (multiplicity still records m). True by default. Pass False to keep every endpoint, including the m-1 duplicate copies. The grouping is the solver’s own (the C++ clustering that computes multiplicity), read off multiplicity_representative; this does not re-cluster.

  • group (VariableGroup or int, optional) – Project each solution onto one variable group – the solution cell then holds only that group’s coordinates (Cluster G). Pass the VariableGroup object or its 0-based FIFO index. None (default) keeps the whole point.

Returns:

One row per solution; the solution cell is a copied vector whose elements are Python complex for a double-precision solve and bertini.complex_mp for a multiprecision one (kept native, so no precision is lost).

Return type:

pandas.DataFrame

Notes

pandas is an optional dependency; this raises ImportError if it is absent. The point accessors – all_solutions(), finite_solutions(), solution_metadata() – are the no-pandas path.

update(**fields)

Set config fields on this owner by NAME, each routed to whichever config owns it.

You never name the config struct:

solver.update(final_tolerance="1e-11",          # -> TolerancesConfig
              max_num_crossed_path_resolve_attempts=3)   # -> ZeroDimConfig

Strings work for every numeric field (converted exactly). A field that none of this owner’s configs has raises AttributeError with the valid names – so a typo, or trying to set a tracker field on the algorithm (or vice versa), never silently does nothing. Returns self, so calls chain. To set a whole config at once, or to name the config explicitly, use configure().

was_stopped_early((HomotopySolverCauchyDoublePrecision)self) → bool :

Was the last solve() stopped before it finished – by Ctrl-C, or by request_stop()? If so the results are a PARTIAL set: paths in flight were abandoned and read SuccessCode.ExternallyTerminated, paths not yet begun still read NeverStarted, and every count derived from them describes only what was tracked. Re-running the same solve recalls the finished paths from the records and tracks only the rest.

class bertini.nag_algorithm.HomotopySolverCauchyFixedMultiplePrecision((object)arg1, (bertini._pybertini.system.System)target, (UserStartSystem)start, (bertini._pybertini.system.System)homotopy)

Bases: AnyZeroDim

__init__((object)arg1, (bertini._pybertini.system.System)target, (UserStartSystem)start, (bertini._pybertini.system.System)homotopy) → None
add_observer((object)self, (object)observer) → None :

Attach an observer to this observable object

all_solutions((HomotopySolverCauchyFixedMultiplePrecision)self[, (bool)user_coords=True]) → bertini._pybertini.container.ListOfVectorComplexVariablePrecision :

get ALL the computed solutions, one per tracked path (finite, at-infinity, and failed alike). by default they are in the coordinates of YOUR variables (dehomogenized, depatched). pass user_coords=False to decline, getting the solver’s internal coordinates instead: homogenized, lying on the target system’s patch – the representation to use for continuing work. the container is computed at most once per solve; repeated calls and indexing do not recompute it. for the filtered view see solutions(); for the at-infinity ones see infinite_solutions.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

config_names()

The keyword names accepted by configure() for this owner, its tracker and its endgame.

config_types((HomotopySolverCauchyFixedMultiplePrecision)self) → list :

List the configuration struct classes this object accepts.

configure(**kwargs)

Change settings on this owner’s configs in one call.

Each keyword names a config (e.g. stepping, newton, tolerances); its value is either a dict of fields to change, or a ready config object.

tracker.configure(stepping={‘max_step_size’: 0.1},

newton={‘max_num_newton_iterations’: 2})

Returns self.

default_point_match_tolerance((HomotopySolverCauchyFixedMultiplePrecision)arg1) → float :

the default infinity-norm tolerance metadata_for() uses when you omit tol: the solver’s final_tolerance (the accuracy each endpoint is computed to). Since metadata_for matches against representatives – which are at least the same-point clustering tolerance apart – this tight default still resolves a fed-back solution to itself while making an ambiguous match structurally impossible.

endgame_boundary_metadata((HomotopySolverCauchyFixedMultiplePrecision)arg1) → MidpathCheckReport :

get the MidpathCheckReport from the path-crossing check at the endgame boundary: how many crossings were detected, which paths, how many re-track attempts were made, and whether the check ultimately passed

endgame_boundary_solutions((HomotopySolverCauchyFixedMultiplePrecision)arg1) → bertini._pybertini.container.ListOfEGBoundaryMetaData_MultiPrec :

get the solutions (per-path point data) at the endgame boundary, where regular tracking switches to the endgame

finite_solutions((HomotopySolverCauchyFixedMultiplePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the FINITE solutions: successful endpoints the solver calls finite (is_finite applies endpoint_finite_threshold). includes singular, nonsingular, and real solutions alike. merge_multiplicities=True (default) collapses each multiple solution to one representative. user coordinates by default; user_coords=False for internal coordinates.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

get_config((HomotopySolverCauchyFixedMultiplePrecision)self, (object)config_type) → object :

Return a copy of this object’s stored configuration struct of the given class.

The named config, by class (TolerancesConfig) or by short name ('tolerances',

as config_names() lists them).

Either may belong to this object’s tracker or endgame rather than to the object itself (solver.get_config('stepping'), solver.get_config(EndgameConfig)); it is fetched from whichever holds it, so every name config_names() lists can be asked for.

get_endgame((HomotopySolverCauchyFixedMultiplePrecision)arg1) → bertini._pybertini.endgame.FixedMultipleCauchyEndgame :

get a mutable reference to the Endgame being used

get_settings(as_dict=False)

This owner’s whole configuration as a carryable dict.

By default (as_dict=False) the value is {config_name: config} – each a copy of one of the owner’s configs (e.g. {'stepping': SteppingConfig(...), 'tolerances': TolerancesConfig(...)}), keyed by the short names config_names() lists. The configs are independent copies (and picklable), so the dict is a plain Python value you can stash, tweak, and apply to other owners – the way to carry one set of tracking settings across a series of related solves:

settings = first_solver.get_settings()
next_solver.set_settings(settings)

Pass as_dict=True for the flat, human-readable view instead: one {field_name: value} dict across ALL configs (field names are unique across an owner’s configs, so there is no collision). That form drops the struct layer nobody wants to poke at, and round-trips through set:

flat = solver.get_settings(as_dict=True)   # {'final_tolerance': ..., 'max_step_size': ..., ...}
other.set(**flat)

(The config-keyed default is kept because set_settings consumes it; use whichever fits.) See set_settings() for applying the config-keyed form back.

get_tracker((HomotopySolverCauchyFixedMultiplePrecision)arg1) → bertini._pybertini.tracking.MultiplePrecisionTracker :

get a mutable reference to the Tracker being used

infinite_solutions((HomotopySolverCauchyFixedMultiplePrecision)self[, (bool)user_coords=True]) → list :

the solutions AT INFINITY: endpoints not classified finite (is_finite is False). these are the paths the endgame resolved as diverging – its GoingToInfinity / SecurityMaxNormReached verdict, or a successful endpoint whose dehomogenized infinity norm exceeds endpoint_finite_threshold. the complement of finite_solutions within all_solutions. NOTE a path that FAILED before the endgame also has is_finite False (its point is not a real solution at infinity); inspect solution_metadata()/report() to tell a true divergence from a tracking failure.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

metadata_for((HomotopySolverCauchyFixedMultiplePrecision)self, (numpy.ndarray)point[, (float)tol=-1.0[, (bool)coincident=False[, (bool)user_coords=True[, (bool)representatives_only=True]]]]) → object :

the SolutionMetaData for the solution matching point (issue #302). Matches by the infinity-norm tolerance tol (see is_distinct_up_to) against the multiplicity REPRESENTATIVES – one candidate per distinct solution. tol is OPTIONAL: omit it (or pass a non-positive value) to use default_point_match_tolerance() (the solver’s final_tolerance). Because representatives are at least the same-point tolerance apart and the default window is smaller, a pt taken straight from solutions() / real_solutions() / etc. (which return representatives) matches its own representative back and is NEVER reported ambiguous – feed a solver result straight back in and it Just Works. The return type NEVER depends on the point’s multiplicity: by default returns exactly ONE record – the multiplicity-cluster representative (it carries .multiplicity, so you still learn m). coincident=True instead ALWAYS returns a LIST of every coincident copy’s record (their per-path condition number / residual / precision), length 1 for a simple root. representatives_only=False matches against EVERY endpoint including non-representative multiplicity copies – a debugging view, rarely what you want. Raises if no solution matches within tol, or (only for a deliberately coarse tol) if the point matches more than one distinct cluster. point is in user coordinates unless user_coords=False. Accepts any numpy array of the solver’s complex type – which is exactly what the solution lists return.

nonsingular_solutions((HomotopySolverCauchyFixedMultiplePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the NONSINGULAR finite solutions (simple, well-conditioned roots). (Nonsingular solutions are simple, so merge_multiplicities is a no-op; kept for a uniform signature.)

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

nonsolutions((HomotopySolverCauchyFixedMultiplePrecision)self[, (bool)user_coords=True]) → list :

the NONSOLUTIONS: finite, successful endpoints that are NOT solutions of the target system – the extraneous nonsolutions a squared-up over-determined system introduces (empty otherwise). Excluded from finite_solutions/real/singular; a regeneration cascade reads these to discard them.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

num_paths((HomotopySolverCauchyFixedMultiplePrecision)self) → int :

How many paths this solve has to answer – the start system’s start point count. Known once a solve has begun its setup, which is before the first path event, and 0 before that.

num_paths_never_started((HomotopySolverCauchyFixedMultiplePrecision)self) → int :

How many paths the last solve() never began, because it was stopped first.

num_paths_recalled((HomotopySolverCauchyFixedMultiplePrecision)self) → int :

How many paths the last solve() recalled from the records instead of computing (0 on a fresh solve; num_paths on a full memo hit).

real_solutions((HomotopySolverCauchyFixedMultiplePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the REAL finite solutions (is_real applies the configured tolerance). merge_multiplicities=True (default) collapses each multiple solution to one representative.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

record_to((HomotopySolverCauchyFixedMultiplePrecision)self, (str)directory) → None :

Attach a structured output directory at the given path: this solve records every path as it completes (durable, plain-text, see the directory’s README.txt) and consults the records before computing – an identical ask (same system, settings, seed) recalls from the records instead of re-tracking, so a crashed solve resumes by simply calling solve() again. Recording is ON BY DEFAULT with no code at all: an unattached solver records to the ambient directory (BERTINI_RECORDS_DIR, else ./bertini_output; the value ‘none’ switches records off). record_to chooses the directory explicitly and always wins over the ambient resolution.

records_path((HomotopySolverCauchyFixedMultiplePrecision)self) → object :

The attached output directory’s path, or None when not recording.

records_run_id((HomotopySolverCauchyFixedMultiplePrecision)self) → str :

This solve’s run id in the records (empty until a recording solve() runs). Points are referenced as {run, index} pairs; this is the run half.

remove_observer((object)self, (object)observer) → None :

Remove an observer to this observable object

report((HomotopySolverCauchyFixedMultiplePrecision)arg1) → SolveReport :

a concise end-of-solve diagnostic summary (a SolveReport): how every path ended up – finite solutions, diverged, or FAILED (by named reason) – plus singular/real counts, max condition number, the path-crossing outcome, and all_paths_resolved. print(solver.report()) for a human-readable summary; a count alone can hide a path the tracker silently lost.

result()

This solve’s SolveResult: the finite solutions plus the records ticket (run id, directory, recall count), read from the solver’s own recorded state.

A bare solver.solve() already returns this; result() re-derives it (call it after solve()) if you did not keep the return value.

same_point_tolerance((HomotopySolverCauchyFixedMultiplePrecision)arg1) → float :

the same-point (clustering) tolerance, final_tolerance * same_point_tolerance_multiplier: the looser tolerance the solver uses to decide two endpoints are the SAME solution and cluster them into one multiplicity (and that metadata_for(coincident=True) uses to gather a cluster’s copies).

set(**fields)

Set config fields on this owner by NAME, each routed to whichever config owns it.

You never name the config struct:

solver.update(final_tolerance="1e-11",          # -> TolerancesConfig
              max_num_crossed_path_resolve_attempts=3)   # -> ZeroDimConfig

Strings work for every numeric field (converted exactly). A field that none of this owner’s configs has raises AttributeError with the valid names – so a typo, or trying to set a tracker field on the algorithm (or vice versa), never silently does nothing. Returns self, so calls chain. To set a whole config at once, or to name the config explicitly, use configure().

set_config((HomotopySolverCauchyFixedMultiplePrecision)self, (TolerancesConfig)config) → None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (HomotopySolverCauchyFixedMultiplePrecision)self, (PostProcessingConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (HomotopySolverCauchyFixedMultiplePrecision)self, (ZeroDimConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (HomotopySolverCauchyFixedMultiplePrecision)self, (AutoRetrackConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (HomotopySolverCauchyFixedMultiplePrecision)self, (RecordsConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (HomotopySolverCauchyFixedMultiplePrecision)self, (MidPathConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

Store a configuration struct, on this object or on whichever of its tracker and

endgame owns that config’s type.

set_recorded_start_provenance((HomotopySolverCauchyFixedMultiplePrecision)self, (str)refs_json, (str)start_identity) → None :

Declare where this solve’s start points came from, for the records: a JSON array with one reference object per path ({‘kind’:’point_ref’,’run’:…,’index’:…} for a chain from a prior run, {‘kind’:’given_ref’,’given’:…,’index’:…} for external data), plus an identity string for the start data (it joins the ask: same homotopy, different starts = different computation). Call before solve().

set_settings(settings, strict=False)

Apply a settings dict (from get_settings()) onto this owner. Returns self.

settings is {config_name: config} (or {config_name: {field: value}}). By default only the configs this owner actually has are applied and the rest are skipped – so a bundle carried from one solver drops cleanly onto another whose config set differs (e.g. a different precision model, or a different algorithm stage). Pass strict=True to instead raise on any key this owner does not have.

singular_solutions((HomotopySolverCauchyFixedMultiplePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the SINGULAR finite solutions (multiple or ill-conditioned roots). merge_multiplicities=True (default) collapses each multiple solution to one representative.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

solution_metadata((HomotopySolverCauchyFixedMultiplePrecision)arg1) → bertini._pybertini.container.ListOfSolutionMetaData_MultiPrec :

get the metadata for the solutions at the target time

solutions((HomotopySolverCauchyFixedMultiplePrecision)self[, (bool)singular=True[, (bool)real=True[, (bool)nonreal=True[, (bool)nonsingular=True[, (bool)infinite=False[, (bool)nonsolution=False[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]]]]]]]) → list :

the solutions, filtered by category (returns points, not metadata). By DEFAULT every finite genuine solution – real and complex, simple and multiple – and nothing else. Each keyword toggles a category: singular / nonsingular select by conditioning, real / nonreal by realness (a finite solution is returned only if BOTH its conditioning class and its realness class are enabled), infinite=True also returns the at-infinity endpoints, and nonsolution=True also returns the nonsolutions. E.g. solutions(real=False) -> complex finite solutions only; solutions(singular=False) -> nonsingular finite solutions; solutions(infinite=True) adds the divergent paths. merge_multiplicities=True (the DEFAULT) collapses a multiplicity-m solution to its single representative (pass False to get all m coincident copies). user_coords=False gives the solver’s internal coordinates. See also real_solutions / nonsingular_solutions / singular_solutions / infinite_solutions / nonsolutions for the common single-category views, and all_solutions for the raw per-path list.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

solve((HomotopySolverCauchyFixedMultiplePrecision)arg1[, (object)communicator=None]) → None :

Run the zero-dim algorithm. Pass an mpi4py communicator for parallel execution.

Settings: pass config fields either as a dict (settings={‘final_tolerance’: 1e-13}) or by keyword (solve(final_tolerance=1e-13)); each is applied via set() before solving, so make/set/solve becomes a single call. communicator= is reserved for MPI (never a setting).

show_progress=True (the default) reports how far the solve has got. It draws nothing unless the solve runs past a few seconds AND stderr is a terminal, so scripts, pipelines and test runs see nothing; pass show_progress=False to be certain of silence.

Returns a bertini.records.SolveResult – the finite solutions plus this solve’s records ticket (run id, directory, recall count), read from the solver’s own records (the solver records itself, on by default). Drop it freely: solver.result() re-derives it, and the records hold the truth.

target_system((HomotopySolverCauchyFixedMultiplePrecision)arg1) → bertini._pybertini.system.System :

get the prepared target system: the homogenized, auto-patched clone of the system you supplied. its patch is the one internal-coordinate solutions lie on; use its dehomogenize_point/homogenize_point/variable_ordering to move between representations.

to_classic_input((HomotopySolverCauchyFixedMultiplePrecision)self, (bertini._pybertini.system.System)system) → str :

emit a complete Bertini 1 classic input file (CONFIG + INPUT) for the given natural system, using THIS solver’s tracking settings for the CONFIG: precision mode (mptype), ODE predictor, tolerances (before/during endgame, final), the full step-size cadence, max Newton iterations, and the crossed-path resolve cap. The system you pass supplies INPUT – pass the natural (un-homogenized) system you constructed the solver from, since the solver homogenizes and patches its internal copy. Use this to re-run the exact same problem with the exact same knobs in Bertini 1 for cross-validation (the random start system aside). For sweeping settings without a solver, see system.to_classic_input(**kwargs).

to_dataframe(*, user_coords=True, omit_infinite=True, merge_multiplicities=True, group=None)

The solve as a pandas DataFrame – one row per solution, the “database of solutions”.

Columns are solution – the whole solution point, kept in a single cell – then every per-solution metadata field (is_finite, is_real, is_singular, multiplicity, condition_number, endgame_success_code, max_precision_used, …), and finally system, a reference to the (target) system these solutions satisfy (so rows accumulated from several solves stay identifiable). Each category is then a one-line filter, e.g. df[df.is_real & ~df.is_singular] (nonsingular real) or df[~df.is_finite] (at infinity).

The solution cell is an independent copy of the solution vector (a numpy array of Python complex for a double solve, of bertini.complex_mp for a multiprecision one, so no precision is lost). Coordinates are deliberately not exploded into x0, x1, ... columns; split them yourself if you want them, e.g. df['x'] = [v[0] for v in df.solution].

Parameters:
  • user_coords (bool) – Coordinates in YOUR variables (dehomogenized; default), or the solver’s internal homogenized on-patch coordinates when False – the same choice as all_solutions().

  • omit_infinite (bool) – Drop the endpoints not classified finite (is_finite False) – the at-infinity and failed paths. True by default, so the frame holds just the genuine finite solutions; pass False to get every tracked path (their coordinate cells may be empty/NaN).

  • merge_multiplicities (bool) – Collapse a multiplicity-m solution – which the solver returns as m coincident endpoints – to its single representative row (multiplicity still records m). True by default. Pass False to keep every endpoint, including the m-1 duplicate copies. The grouping is the solver’s own (the C++ clustering that computes multiplicity), read off multiplicity_representative; this does not re-cluster.

  • group (VariableGroup or int, optional) – Project each solution onto one variable group – the solution cell then holds only that group’s coordinates (Cluster G). Pass the VariableGroup object or its 0-based FIFO index. None (default) keeps the whole point.

Returns:

One row per solution; the solution cell is a copied vector whose elements are Python complex for a double-precision solve and bertini.complex_mp for a multiprecision one (kept native, so no precision is lost).

Return type:

pandas.DataFrame

Notes

pandas is an optional dependency; this raises ImportError if it is absent. The point accessors – all_solutions(), finite_solutions(), solution_metadata() – are the no-pandas path.

update(**fields)

Set config fields on this owner by NAME, each routed to whichever config owns it.

You never name the config struct:

solver.update(final_tolerance="1e-11",          # -> TolerancesConfig
              max_num_crossed_path_resolve_attempts=3)   # -> ZeroDimConfig

Strings work for every numeric field (converted exactly). A field that none of this owner’s configs has raises AttributeError with the valid names – so a typo, or trying to set a tracker field on the algorithm (or vice versa), never silently does nothing. Returns self, so calls chain. To set a whole config at once, or to name the config explicitly, use configure().

was_stopped_early((HomotopySolverCauchyFixedMultiplePrecision)self) → bool :

Was the last solve() stopped before it finished – by Ctrl-C, or by request_stop()? If so the results are a PARTIAL set: paths in flight were abandoned and read SuccessCode.ExternallyTerminated, paths not yet begun still read NeverStarted, and every count derived from them describes only what was tracked. Re-running the same solve recalls the finished paths from the records and tracks only the rest.

class bertini.nag_algorithm.HomotopySolverPowerSeriesAdaptivePrecision((object)arg1, (bertini._pybertini.system.System)target, (UserStartSystem)start, (bertini._pybertini.system.System)homotopy)

Bases: AnyZeroDim

__init__((object)arg1, (bertini._pybertini.system.System)target, (UserStartSystem)start, (bertini._pybertini.system.System)homotopy) → None
add_observer((object)self, (object)observer) → None :

Attach an observer to this observable object

all_solutions((HomotopySolverPowerSeriesAdaptivePrecision)self[, (bool)user_coords=True]) → bertini._pybertini.container.ListOfVectorComplexVariablePrecision :

get ALL the computed solutions, one per tracked path (finite, at-infinity, and failed alike). by default they are in the coordinates of YOUR variables (dehomogenized, depatched). pass user_coords=False to decline, getting the solver’s internal coordinates instead: homogenized, lying on the target system’s patch – the representation to use for continuing work. the container is computed at most once per solve; repeated calls and indexing do not recompute it. for the filtered view see solutions(); for the at-infinity ones see infinite_solutions.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

config_names()

The keyword names accepted by configure() for this owner, its tracker and its endgame.

config_types((HomotopySolverPowerSeriesAdaptivePrecision)self) → list :

List the configuration struct classes this object accepts.

configure(**kwargs)

Change settings on this owner’s configs in one call.

Each keyword names a config (e.g. stepping, newton, tolerances); its value is either a dict of fields to change, or a ready config object.

tracker.configure(stepping={‘max_step_size’: 0.1},

newton={‘max_num_newton_iterations’: 2})

Returns self.

default_point_match_tolerance((HomotopySolverPowerSeriesAdaptivePrecision)arg1) → float :

the default infinity-norm tolerance metadata_for() uses when you omit tol: the solver’s final_tolerance (the accuracy each endpoint is computed to). Since metadata_for matches against representatives – which are at least the same-point clustering tolerance apart – this tight default still resolves a fed-back solution to itself while making an ambiguous match structurally impossible.

endgame_boundary_metadata((HomotopySolverPowerSeriesAdaptivePrecision)arg1) → MidpathCheckReport :

get the MidpathCheckReport from the path-crossing check at the endgame boundary: how many crossings were detected, which paths, how many re-track attempts were made, and whether the check ultimately passed

endgame_boundary_solutions((HomotopySolverPowerSeriesAdaptivePrecision)arg1) → bertini._pybertini.container.ListOfEGBoundaryMetaData_MultiPrec :

get the solutions (per-path point data) at the endgame boundary, where regular tracking switches to the endgame

finite_solutions((HomotopySolverPowerSeriesAdaptivePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the FINITE solutions: successful endpoints the solver calls finite (is_finite applies endpoint_finite_threshold). includes singular, nonsingular, and real solutions alike. merge_multiplicities=True (default) collapses each multiple solution to one representative. user coordinates by default; user_coords=False for internal coordinates.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

get_config((HomotopySolverPowerSeriesAdaptivePrecision)self, (object)config_type) → object :

Return a copy of this object’s stored configuration struct of the given class.

The named config, by class (TolerancesConfig) or by short name ('tolerances',

as config_names() lists them).

Either may belong to this object’s tracker or endgame rather than to the object itself (solver.get_config('stepping'), solver.get_config(EndgameConfig)); it is fetched from whichever holds it, so every name config_names() lists can be asked for.

get_endgame((HomotopySolverPowerSeriesAdaptivePrecision)arg1) → bertini._pybertini.endgame.AMPPowerSeriesEndgame :

get a mutable reference to the Endgame being used

get_settings(as_dict=False)

This owner’s whole configuration as a carryable dict.

By default (as_dict=False) the value is {config_name: config} – each a copy of one of the owner’s configs (e.g. {'stepping': SteppingConfig(...), 'tolerances': TolerancesConfig(...)}), keyed by the short names config_names() lists. The configs are independent copies (and picklable), so the dict is a plain Python value you can stash, tweak, and apply to other owners – the way to carry one set of tracking settings across a series of related solves:

settings = first_solver.get_settings()
next_solver.set_settings(settings)

Pass as_dict=True for the flat, human-readable view instead: one {field_name: value} dict across ALL configs (field names are unique across an owner’s configs, so there is no collision). That form drops the struct layer nobody wants to poke at, and round-trips through set:

flat = solver.get_settings(as_dict=True)   # {'final_tolerance': ..., 'max_step_size': ..., ...}
other.set(**flat)

(The config-keyed default is kept because set_settings consumes it; use whichever fits.) See set_settings() for applying the config-keyed form back.

get_tracker((HomotopySolverPowerSeriesAdaptivePrecision)arg1) → bertini._pybertini.tracking.AMPTracker :

get a mutable reference to the Tracker being used

infinite_solutions((HomotopySolverPowerSeriesAdaptivePrecision)self[, (bool)user_coords=True]) → list :

the solutions AT INFINITY: endpoints not classified finite (is_finite is False). these are the paths the endgame resolved as diverging – its GoingToInfinity / SecurityMaxNormReached verdict, or a successful endpoint whose dehomogenized infinity norm exceeds endpoint_finite_threshold. the complement of finite_solutions within all_solutions. NOTE a path that FAILED before the endgame also has is_finite False (its point is not a real solution at infinity); inspect solution_metadata()/report() to tell a true divergence from a tracking failure.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

metadata_for((HomotopySolverPowerSeriesAdaptivePrecision)self, (numpy.ndarray)point[, (float)tol=-1.0[, (bool)coincident=False[, (bool)user_coords=True[, (bool)representatives_only=True]]]]) → object :

the SolutionMetaData for the solution matching point (issue #302). Matches by the infinity-norm tolerance tol (see is_distinct_up_to) against the multiplicity REPRESENTATIVES – one candidate per distinct solution. tol is OPTIONAL: omit it (or pass a non-positive value) to use default_point_match_tolerance() (the solver’s final_tolerance). Because representatives are at least the same-point tolerance apart and the default window is smaller, a pt taken straight from solutions() / real_solutions() / etc. (which return representatives) matches its own representative back and is NEVER reported ambiguous – feed a solver result straight back in and it Just Works. The return type NEVER depends on the point’s multiplicity: by default returns exactly ONE record – the multiplicity-cluster representative (it carries .multiplicity, so you still learn m). coincident=True instead ALWAYS returns a LIST of every coincident copy’s record (their per-path condition number / residual / precision), length 1 for a simple root. representatives_only=False matches against EVERY endpoint including non-representative multiplicity copies – a debugging view, rarely what you want. Raises if no solution matches within tol, or (only for a deliberately coarse tol) if the point matches more than one distinct cluster. point is in user coordinates unless user_coords=False. Accepts any numpy array of the solver’s complex type – which is exactly what the solution lists return.

nonsingular_solutions((HomotopySolverPowerSeriesAdaptivePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the NONSINGULAR finite solutions (simple, well-conditioned roots). (Nonsingular solutions are simple, so merge_multiplicities is a no-op; kept for a uniform signature.)

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

nonsolutions((HomotopySolverPowerSeriesAdaptivePrecision)self[, (bool)user_coords=True]) → list :

the NONSOLUTIONS: finite, successful endpoints that are NOT solutions of the target system – the extraneous nonsolutions a squared-up over-determined system introduces (empty otherwise). Excluded from finite_solutions/real/singular; a regeneration cascade reads these to discard them.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

num_paths((HomotopySolverPowerSeriesAdaptivePrecision)self) → int :

How many paths this solve has to answer – the start system’s start point count. Known once a solve has begun its setup, which is before the first path event, and 0 before that.

num_paths_never_started((HomotopySolverPowerSeriesAdaptivePrecision)self) → int :

How many paths the last solve() never began, because it was stopped first.

num_paths_recalled((HomotopySolverPowerSeriesAdaptivePrecision)self) → int :

How many paths the last solve() recalled from the records instead of computing (0 on a fresh solve; num_paths on a full memo hit).

real_solutions((HomotopySolverPowerSeriesAdaptivePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the REAL finite solutions (is_real applies the configured tolerance). merge_multiplicities=True (default) collapses each multiple solution to one representative.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

record_to((HomotopySolverPowerSeriesAdaptivePrecision)self, (str)directory) → None :

Attach a structured output directory at the given path: this solve records every path as it completes (durable, plain-text, see the directory’s README.txt) and consults the records before computing – an identical ask (same system, settings, seed) recalls from the records instead of re-tracking, so a crashed solve resumes by simply calling solve() again. Recording is ON BY DEFAULT with no code at all: an unattached solver records to the ambient directory (BERTINI_RECORDS_DIR, else ./bertini_output; the value ‘none’ switches records off). record_to chooses the directory explicitly and always wins over the ambient resolution.

records_path((HomotopySolverPowerSeriesAdaptivePrecision)self) → object :

The attached output directory’s path, or None when not recording.

records_run_id((HomotopySolverPowerSeriesAdaptivePrecision)self) → str :

This solve’s run id in the records (empty until a recording solve() runs). Points are referenced as {run, index} pairs; this is the run half.

remove_observer((object)self, (object)observer) → None :

Remove an observer to this observable object

report((HomotopySolverPowerSeriesAdaptivePrecision)arg1) → SolveReport :

a concise end-of-solve diagnostic summary (a SolveReport): how every path ended up – finite solutions, diverged, or FAILED (by named reason) – plus singular/real counts, max condition number, the path-crossing outcome, and all_paths_resolved. print(solver.report()) for a human-readable summary; a count alone can hide a path the tracker silently lost.

result()

This solve’s SolveResult: the finite solutions plus the records ticket (run id, directory, recall count), read from the solver’s own recorded state.

A bare solver.solve() already returns this; result() re-derives it (call it after solve()) if you did not keep the return value.

same_point_tolerance((HomotopySolverPowerSeriesAdaptivePrecision)arg1) → float :

the same-point (clustering) tolerance, final_tolerance * same_point_tolerance_multiplier: the looser tolerance the solver uses to decide two endpoints are the SAME solution and cluster them into one multiplicity (and that metadata_for(coincident=True) uses to gather a cluster’s copies).

set(**fields)

Set config fields on this owner by NAME, each routed to whichever config owns it.

You never name the config struct:

solver.update(final_tolerance="1e-11",          # -> TolerancesConfig
              max_num_crossed_path_resolve_attempts=3)   # -> ZeroDimConfig

Strings work for every numeric field (converted exactly). A field that none of this owner’s configs has raises AttributeError with the valid names – so a typo, or trying to set a tracker field on the algorithm (or vice versa), never silently does nothing. Returns self, so calls chain. To set a whole config at once, or to name the config explicitly, use configure().

set_config((HomotopySolverPowerSeriesAdaptivePrecision)self, (TolerancesConfig)config) → None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (HomotopySolverPowerSeriesAdaptivePrecision)self, (PostProcessingConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (HomotopySolverPowerSeriesAdaptivePrecision)self, (ZeroDimConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (HomotopySolverPowerSeriesAdaptivePrecision)self, (AutoRetrackConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (HomotopySolverPowerSeriesAdaptivePrecision)self, (RecordsConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (HomotopySolverPowerSeriesAdaptivePrecision)self, (MidPathConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

Store a configuration struct, on this object or on whichever of its tracker and

endgame owns that config’s type.

set_recorded_start_provenance((HomotopySolverPowerSeriesAdaptivePrecision)self, (str)refs_json, (str)start_identity) → None :

Declare where this solve’s start points came from, for the records: a JSON array with one reference object per path ({‘kind’:’point_ref’,’run’:…,’index’:…} for a chain from a prior run, {‘kind’:’given_ref’,’given’:…,’index’:…} for external data), plus an identity string for the start data (it joins the ask: same homotopy, different starts = different computation). Call before solve().

set_settings(settings, strict=False)

Apply a settings dict (from get_settings()) onto this owner. Returns self.

settings is {config_name: config} (or {config_name: {field: value}}). By default only the configs this owner actually has are applied and the rest are skipped – so a bundle carried from one solver drops cleanly onto another whose config set differs (e.g. a different precision model, or a different algorithm stage). Pass strict=True to instead raise on any key this owner does not have.

singular_solutions((HomotopySolverPowerSeriesAdaptivePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the SINGULAR finite solutions (multiple or ill-conditioned roots). merge_multiplicities=True (default) collapses each multiple solution to one representative.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

solution_metadata((HomotopySolverPowerSeriesAdaptivePrecision)arg1) → bertini._pybertini.container.ListOfSolutionMetaData_MultiPrec :

get the metadata for the solutions at the target time

solutions((HomotopySolverPowerSeriesAdaptivePrecision)self[, (bool)singular=True[, (bool)real=True[, (bool)nonreal=True[, (bool)nonsingular=True[, (bool)infinite=False[, (bool)nonsolution=False[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]]]]]]]) → list :

the solutions, filtered by category (returns points, not metadata). By DEFAULT every finite genuine solution – real and complex, simple and multiple – and nothing else. Each keyword toggles a category: singular / nonsingular select by conditioning, real / nonreal by realness (a finite solution is returned only if BOTH its conditioning class and its realness class are enabled), infinite=True also returns the at-infinity endpoints, and nonsolution=True also returns the nonsolutions. E.g. solutions(real=False) -> complex finite solutions only; solutions(singular=False) -> nonsingular finite solutions; solutions(infinite=True) adds the divergent paths. merge_multiplicities=True (the DEFAULT) collapses a multiplicity-m solution to its single representative (pass False to get all m coincident copies). user_coords=False gives the solver’s internal coordinates. See also real_solutions / nonsingular_solutions / singular_solutions / infinite_solutions / nonsolutions for the common single-category views, and all_solutions for the raw per-path list.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

solve((HomotopySolverPowerSeriesAdaptivePrecision)arg1[, (object)communicator=None]) → None :

Run the zero-dim algorithm. Pass an mpi4py communicator for parallel execution.

Settings: pass config fields either as a dict (settings={‘final_tolerance’: 1e-13}) or by keyword (solve(final_tolerance=1e-13)); each is applied via set() before solving, so make/set/solve becomes a single call. communicator= is reserved for MPI (never a setting).

show_progress=True (the default) reports how far the solve has got. It draws nothing unless the solve runs past a few seconds AND stderr is a terminal, so scripts, pipelines and test runs see nothing; pass show_progress=False to be certain of silence.

Returns a bertini.records.SolveResult – the finite solutions plus this solve’s records ticket (run id, directory, recall count), read from the solver’s own records (the solver records itself, on by default). Drop it freely: solver.result() re-derives it, and the records hold the truth.

target_system((HomotopySolverPowerSeriesAdaptivePrecision)arg1) → bertini._pybertini.system.System :

get the prepared target system: the homogenized, auto-patched clone of the system you supplied. its patch is the one internal-coordinate solutions lie on; use its dehomogenize_point/homogenize_point/variable_ordering to move between representations.

to_classic_input((HomotopySolverPowerSeriesAdaptivePrecision)self, (bertini._pybertini.system.System)system) → str :

emit a complete Bertini 1 classic input file (CONFIG + INPUT) for the given natural system, using THIS solver’s tracking settings for the CONFIG: precision mode (mptype), ODE predictor, tolerances (before/during endgame, final), the full step-size cadence, max Newton iterations, and the crossed-path resolve cap. The system you pass supplies INPUT – pass the natural (un-homogenized) system you constructed the solver from, since the solver homogenizes and patches its internal copy. Use this to re-run the exact same problem with the exact same knobs in Bertini 1 for cross-validation (the random start system aside). For sweeping settings without a solver, see system.to_classic_input(**kwargs).

to_dataframe(*, user_coords=True, omit_infinite=True, merge_multiplicities=True, group=None)

The solve as a pandas DataFrame – one row per solution, the “database of solutions”.

Columns are solution – the whole solution point, kept in a single cell – then every per-solution metadata field (is_finite, is_real, is_singular, multiplicity, condition_number, endgame_success_code, max_precision_used, …), and finally system, a reference to the (target) system these solutions satisfy (so rows accumulated from several solves stay identifiable). Each category is then a one-line filter, e.g. df[df.is_real & ~df.is_singular] (nonsingular real) or df[~df.is_finite] (at infinity).

The solution cell is an independent copy of the solution vector (a numpy array of Python complex for a double solve, of bertini.complex_mp for a multiprecision one, so no precision is lost). Coordinates are deliberately not exploded into x0, x1, ... columns; split them yourself if you want them, e.g. df['x'] = [v[0] for v in df.solution].

Parameters:
  • user_coords (bool) – Coordinates in YOUR variables (dehomogenized; default), or the solver’s internal homogenized on-patch coordinates when False – the same choice as all_solutions().

  • omit_infinite (bool) – Drop the endpoints not classified finite (is_finite False) – the at-infinity and failed paths. True by default, so the frame holds just the genuine finite solutions; pass False to get every tracked path (their coordinate cells may be empty/NaN).

  • merge_multiplicities (bool) – Collapse a multiplicity-m solution – which the solver returns as m coincident endpoints – to its single representative row (multiplicity still records m). True by default. Pass False to keep every endpoint, including the m-1 duplicate copies. The grouping is the solver’s own (the C++ clustering that computes multiplicity), read off multiplicity_representative; this does not re-cluster.

  • group (VariableGroup or int, optional) – Project each solution onto one variable group – the solution cell then holds only that group’s coordinates (Cluster G). Pass the VariableGroup object or its 0-based FIFO index. None (default) keeps the whole point.

Returns:

One row per solution; the solution cell is a copied vector whose elements are Python complex for a double-precision solve and bertini.complex_mp for a multiprecision one (kept native, so no precision is lost).

Return type:

pandas.DataFrame

Notes

pandas is an optional dependency; this raises ImportError if it is absent. The point accessors – all_solutions(), finite_solutions(), solution_metadata() – are the no-pandas path.

update(**fields)

Set config fields on this owner by NAME, each routed to whichever config owns it.

You never name the config struct:

solver.update(final_tolerance="1e-11",          # -> TolerancesConfig
              max_num_crossed_path_resolve_attempts=3)   # -> ZeroDimConfig

Strings work for every numeric field (converted exactly). A field that none of this owner’s configs has raises AttributeError with the valid names – so a typo, or trying to set a tracker field on the algorithm (or vice versa), never silently does nothing. Returns self, so calls chain. To set a whole config at once, or to name the config explicitly, use configure().

was_stopped_early((HomotopySolverPowerSeriesAdaptivePrecision)self) → bool :

Was the last solve() stopped before it finished – by Ctrl-C, or by request_stop()? If so the results are a PARTIAL set: paths in flight were abandoned and read SuccessCode.ExternallyTerminated, paths not yet begun still read NeverStarted, and every count derived from them describes only what was tracked. Re-running the same solve recalls the finished paths from the records and tracks only the rest.

class bertini.nag_algorithm.HomotopySolverPowerSeriesDoublePrecision((object)arg1, (bertini._pybertini.system.System)target, (UserStartSystem)start, (bertini._pybertini.system.System)homotopy)

Bases: AnyZeroDim

__init__((object)arg1, (bertini._pybertini.system.System)target, (UserStartSystem)start, (bertini._pybertini.system.System)homotopy) → None
add_observer((object)self, (object)observer) → None :

Attach an observer to this observable object

all_solutions((HomotopySolverPowerSeriesDoublePrecision)self[, (bool)user_coords=True]) → bertini._pybertini.container.ListOfVectorComplexDoublePrecision :

get ALL the computed solutions, one per tracked path (finite, at-infinity, and failed alike). by default they are in the coordinates of YOUR variables (dehomogenized, depatched). pass user_coords=False to decline, getting the solver’s internal coordinates instead: homogenized, lying on the target system’s patch – the representation to use for continuing work. the container is computed at most once per solve; repeated calls and indexing do not recompute it. for the filtered view see solutions(); for the at-infinity ones see infinite_solutions.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

config_names()

The keyword names accepted by configure() for this owner, its tracker and its endgame.

config_types((HomotopySolverPowerSeriesDoublePrecision)self) → list :

List the configuration struct classes this object accepts.

configure(**kwargs)

Change settings on this owner’s configs in one call.

Each keyword names a config (e.g. stepping, newton, tolerances); its value is either a dict of fields to change, or a ready config object.

tracker.configure(stepping={‘max_step_size’: 0.1},

newton={‘max_num_newton_iterations’: 2})

Returns self.

default_point_match_tolerance((HomotopySolverPowerSeriesDoublePrecision)arg1) → float :

the default infinity-norm tolerance metadata_for() uses when you omit tol: the solver’s final_tolerance (the accuracy each endpoint is computed to). Since metadata_for matches against representatives – which are at least the same-point clustering tolerance apart – this tight default still resolves a fed-back solution to itself while making an ambiguous match structurally impossible.

endgame_boundary_metadata((HomotopySolverPowerSeriesDoublePrecision)arg1) → MidpathCheckReport :

get the MidpathCheckReport from the path-crossing check at the endgame boundary: how many crossings were detected, which paths, how many re-track attempts were made, and whether the check ultimately passed

endgame_boundary_solutions((HomotopySolverPowerSeriesDoublePrecision)arg1) → bertini._pybertini.container.ListOfEGBoundaryMetaData_DoublePrec :

get the solutions (per-path point data) at the endgame boundary, where regular tracking switches to the endgame

finite_solutions((HomotopySolverPowerSeriesDoublePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the FINITE solutions: successful endpoints the solver calls finite (is_finite applies endpoint_finite_threshold). includes singular, nonsingular, and real solutions alike. merge_multiplicities=True (default) collapses each multiple solution to one representative. user coordinates by default; user_coords=False for internal coordinates.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

get_config((HomotopySolverPowerSeriesDoublePrecision)self, (object)config_type) → object :

Return a copy of this object’s stored configuration struct of the given class.

The named config, by class (TolerancesConfig) or by short name ('tolerances',

as config_names() lists them).

Either may belong to this object’s tracker or endgame rather than to the object itself (solver.get_config('stepping'), solver.get_config(EndgameConfig)); it is fetched from whichever holds it, so every name config_names() lists can be asked for.

get_endgame((HomotopySolverPowerSeriesDoublePrecision)arg1) → bertini._pybertini.endgame.FixedDoublePowerSeriesEndgame :

get a mutable reference to the Endgame being used

get_settings(as_dict=False)

This owner’s whole configuration as a carryable dict.

By default (as_dict=False) the value is {config_name: config} – each a copy of one of the owner’s configs (e.g. {'stepping': SteppingConfig(...), 'tolerances': TolerancesConfig(...)}), keyed by the short names config_names() lists. The configs are independent copies (and picklable), so the dict is a plain Python value you can stash, tweak, and apply to other owners – the way to carry one set of tracking settings across a series of related solves:

settings = first_solver.get_settings()
next_solver.set_settings(settings)

Pass as_dict=True for the flat, human-readable view instead: one {field_name: value} dict across ALL configs (field names are unique across an owner’s configs, so there is no collision). That form drops the struct layer nobody wants to poke at, and round-trips through set:

flat = solver.get_settings(as_dict=True)   # {'final_tolerance': ..., 'max_step_size': ..., ...}
other.set(**flat)

(The config-keyed default is kept because set_settings consumes it; use whichever fits.) See set_settings() for applying the config-keyed form back.

get_tracker((HomotopySolverPowerSeriesDoublePrecision)arg1) → bertini._pybertini.tracking.DoublePrecisionTracker :

get a mutable reference to the Tracker being used

infinite_solutions((HomotopySolverPowerSeriesDoublePrecision)self[, (bool)user_coords=True]) → list :

the solutions AT INFINITY: endpoints not classified finite (is_finite is False). these are the paths the endgame resolved as diverging – its GoingToInfinity / SecurityMaxNormReached verdict, or a successful endpoint whose dehomogenized infinity norm exceeds endpoint_finite_threshold. the complement of finite_solutions within all_solutions. NOTE a path that FAILED before the endgame also has is_finite False (its point is not a real solution at infinity); inspect solution_metadata()/report() to tell a true divergence from a tracking failure.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

metadata_for((HomotopySolverPowerSeriesDoublePrecision)self, (numpy.ndarray)point[, (float)tol=-1.0[, (bool)coincident=False[, (bool)user_coords=True[, (bool)representatives_only=True]]]]) → object :

the SolutionMetaData for the solution matching point (issue #302). Matches by the infinity-norm tolerance tol (see is_distinct_up_to) against the multiplicity REPRESENTATIVES – one candidate per distinct solution. tol is OPTIONAL: omit it (or pass a non-positive value) to use default_point_match_tolerance() (the solver’s final_tolerance). Because representatives are at least the same-point tolerance apart and the default window is smaller, a pt taken straight from solutions() / real_solutions() / etc. (which return representatives) matches its own representative back and is NEVER reported ambiguous – feed a solver result straight back in and it Just Works. The return type NEVER depends on the point’s multiplicity: by default returns exactly ONE record – the multiplicity-cluster representative (it carries .multiplicity, so you still learn m). coincident=True instead ALWAYS returns a LIST of every coincident copy’s record (their per-path condition number / residual / precision), length 1 for a simple root. representatives_only=False matches against EVERY endpoint including non-representative multiplicity copies – a debugging view, rarely what you want. Raises if no solution matches within tol, or (only for a deliberately coarse tol) if the point matches more than one distinct cluster. point is in user coordinates unless user_coords=False. Accepts any numpy array of the solver’s complex type – which is exactly what the solution lists return.

nonsingular_solutions((HomotopySolverPowerSeriesDoublePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the NONSINGULAR finite solutions (simple, well-conditioned roots). (Nonsingular solutions are simple, so merge_multiplicities is a no-op; kept for a uniform signature.)

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

nonsolutions((HomotopySolverPowerSeriesDoublePrecision)self[, (bool)user_coords=True]) → list :

the NONSOLUTIONS: finite, successful endpoints that are NOT solutions of the target system – the extraneous nonsolutions a squared-up over-determined system introduces (empty otherwise). Excluded from finite_solutions/real/singular; a regeneration cascade reads these to discard them.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

num_paths((HomotopySolverPowerSeriesDoublePrecision)self) → int :

How many paths this solve has to answer – the start system’s start point count. Known once a solve has begun its setup, which is before the first path event, and 0 before that.

num_paths_never_started((HomotopySolverPowerSeriesDoublePrecision)self) → int :

How many paths the last solve() never began, because it was stopped first.

num_paths_recalled((HomotopySolverPowerSeriesDoublePrecision)self) → int :

How many paths the last solve() recalled from the records instead of computing (0 on a fresh solve; num_paths on a full memo hit).

real_solutions((HomotopySolverPowerSeriesDoublePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the REAL finite solutions (is_real applies the configured tolerance). merge_multiplicities=True (default) collapses each multiple solution to one representative.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

record_to((HomotopySolverPowerSeriesDoublePrecision)self, (str)directory) → None :

Attach a structured output directory at the given path: this solve records every path as it completes (durable, plain-text, see the directory’s README.txt) and consults the records before computing – an identical ask (same system, settings, seed) recalls from the records instead of re-tracking, so a crashed solve resumes by simply calling solve() again. Recording is ON BY DEFAULT with no code at all: an unattached solver records to the ambient directory (BERTINI_RECORDS_DIR, else ./bertini_output; the value ‘none’ switches records off). record_to chooses the directory explicitly and always wins over the ambient resolution.

records_path((HomotopySolverPowerSeriesDoublePrecision)self) → object :

The attached output directory’s path, or None when not recording.

records_run_id((HomotopySolverPowerSeriesDoublePrecision)self) → str :

This solve’s run id in the records (empty until a recording solve() runs). Points are referenced as {run, index} pairs; this is the run half.

remove_observer((object)self, (object)observer) → None :

Remove an observer to this observable object

report((HomotopySolverPowerSeriesDoublePrecision)arg1) → SolveReport :

a concise end-of-solve diagnostic summary (a SolveReport): how every path ended up – finite solutions, diverged, or FAILED (by named reason) – plus singular/real counts, max condition number, the path-crossing outcome, and all_paths_resolved. print(solver.report()) for a human-readable summary; a count alone can hide a path the tracker silently lost.

result()

This solve’s SolveResult: the finite solutions plus the records ticket (run id, directory, recall count), read from the solver’s own recorded state.

A bare solver.solve() already returns this; result() re-derives it (call it after solve()) if you did not keep the return value.

same_point_tolerance((HomotopySolverPowerSeriesDoublePrecision)arg1) → float :

the same-point (clustering) tolerance, final_tolerance * same_point_tolerance_multiplier: the looser tolerance the solver uses to decide two endpoints are the SAME solution and cluster them into one multiplicity (and that metadata_for(coincident=True) uses to gather a cluster’s copies).

set(**fields)

Set config fields on this owner by NAME, each routed to whichever config owns it.

You never name the config struct:

solver.update(final_tolerance="1e-11",          # -> TolerancesConfig
              max_num_crossed_path_resolve_attempts=3)   # -> ZeroDimConfig

Strings work for every numeric field (converted exactly). A field that none of this owner’s configs has raises AttributeError with the valid names – so a typo, or trying to set a tracker field on the algorithm (or vice versa), never silently does nothing. Returns self, so calls chain. To set a whole config at once, or to name the config explicitly, use configure().

set_config((HomotopySolverPowerSeriesDoublePrecision)self, (TolerancesConfig)config) → None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (HomotopySolverPowerSeriesDoublePrecision)self, (PostProcessingConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (HomotopySolverPowerSeriesDoublePrecision)self, (ZeroDimConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (HomotopySolverPowerSeriesDoublePrecision)self, (AutoRetrackConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (HomotopySolverPowerSeriesDoublePrecision)self, (RecordsConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (HomotopySolverPowerSeriesDoublePrecision)self, (MidPathConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

Store a configuration struct, on this object or on whichever of its tracker and

endgame owns that config’s type.

set_recorded_start_provenance((HomotopySolverPowerSeriesDoublePrecision)self, (str)refs_json, (str)start_identity) → None :

Declare where this solve’s start points came from, for the records: a JSON array with one reference object per path ({‘kind’:’point_ref’,’run’:…,’index’:…} for a chain from a prior run, {‘kind’:’given_ref’,’given’:…,’index’:…} for external data), plus an identity string for the start data (it joins the ask: same homotopy, different starts = different computation). Call before solve().

set_settings(settings, strict=False)

Apply a settings dict (from get_settings()) onto this owner. Returns self.

settings is {config_name: config} (or {config_name: {field: value}}). By default only the configs this owner actually has are applied and the rest are skipped – so a bundle carried from one solver drops cleanly onto another whose config set differs (e.g. a different precision model, or a different algorithm stage). Pass strict=True to instead raise on any key this owner does not have.

singular_solutions((HomotopySolverPowerSeriesDoublePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the SINGULAR finite solutions (multiple or ill-conditioned roots). merge_multiplicities=True (default) collapses each multiple solution to one representative.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

solution_metadata((HomotopySolverPowerSeriesDoublePrecision)arg1) → bertini._pybertini.container.ListOfSolutionMetaData_DoublePrec :

get the metadata for the solutions at the target time

solutions((HomotopySolverPowerSeriesDoublePrecision)self[, (bool)singular=True[, (bool)real=True[, (bool)nonreal=True[, (bool)nonsingular=True[, (bool)infinite=False[, (bool)nonsolution=False[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]]]]]]]) → list :

the solutions, filtered by category (returns points, not metadata). By DEFAULT every finite genuine solution – real and complex, simple and multiple – and nothing else. Each keyword toggles a category: singular / nonsingular select by conditioning, real / nonreal by realness (a finite solution is returned only if BOTH its conditioning class and its realness class are enabled), infinite=True also returns the at-infinity endpoints, and nonsolution=True also returns the nonsolutions. E.g. solutions(real=False) -> complex finite solutions only; solutions(singular=False) -> nonsingular finite solutions; solutions(infinite=True) adds the divergent paths. merge_multiplicities=True (the DEFAULT) collapses a multiplicity-m solution to its single representative (pass False to get all m coincident copies). user_coords=False gives the solver’s internal coordinates. See also real_solutions / nonsingular_solutions / singular_solutions / infinite_solutions / nonsolutions for the common single-category views, and all_solutions for the raw per-path list.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

solve((HomotopySolverPowerSeriesDoublePrecision)arg1[, (object)communicator=None]) → None :

Run the zero-dim algorithm. Pass an mpi4py communicator for parallel execution.

Settings: pass config fields either as a dict (settings={‘final_tolerance’: 1e-13}) or by keyword (solve(final_tolerance=1e-13)); each is applied via set() before solving, so make/set/solve becomes a single call. communicator= is reserved for MPI (never a setting).

show_progress=True (the default) reports how far the solve has got. It draws nothing unless the solve runs past a few seconds AND stderr is a terminal, so scripts, pipelines and test runs see nothing; pass show_progress=False to be certain of silence.

Returns a bertini.records.SolveResult – the finite solutions plus this solve’s records ticket (run id, directory, recall count), read from the solver’s own records (the solver records itself, on by default). Drop it freely: solver.result() re-derives it, and the records hold the truth.

target_system((HomotopySolverPowerSeriesDoublePrecision)arg1) → bertini._pybertini.system.System :

get the prepared target system: the homogenized, auto-patched clone of the system you supplied. its patch is the one internal-coordinate solutions lie on; use its dehomogenize_point/homogenize_point/variable_ordering to move between representations.

to_classic_input((HomotopySolverPowerSeriesDoublePrecision)self, (bertini._pybertini.system.System)system) → str :

emit a complete Bertini 1 classic input file (CONFIG + INPUT) for the given natural system, using THIS solver’s tracking settings for the CONFIG: precision mode (mptype), ODE predictor, tolerances (before/during endgame, final), the full step-size cadence, max Newton iterations, and the crossed-path resolve cap. The system you pass supplies INPUT – pass the natural (un-homogenized) system you constructed the solver from, since the solver homogenizes and patches its internal copy. Use this to re-run the exact same problem with the exact same knobs in Bertini 1 for cross-validation (the random start system aside). For sweeping settings without a solver, see system.to_classic_input(**kwargs).

to_dataframe(*, user_coords=True, omit_infinite=True, merge_multiplicities=True, group=None)

The solve as a pandas DataFrame – one row per solution, the “database of solutions”.

Columns are solution – the whole solution point, kept in a single cell – then every per-solution metadata field (is_finite, is_real, is_singular, multiplicity, condition_number, endgame_success_code, max_precision_used, …), and finally system, a reference to the (target) system these solutions satisfy (so rows accumulated from several solves stay identifiable). Each category is then a one-line filter, e.g. df[df.is_real & ~df.is_singular] (nonsingular real) or df[~df.is_finite] (at infinity).

The solution cell is an independent copy of the solution vector (a numpy array of Python complex for a double solve, of bertini.complex_mp for a multiprecision one, so no precision is lost). Coordinates are deliberately not exploded into x0, x1, ... columns; split them yourself if you want them, e.g. df['x'] = [v[0] for v in df.solution].

Parameters:
  • user_coords (bool) – Coordinates in YOUR variables (dehomogenized; default), or the solver’s internal homogenized on-patch coordinates when False – the same choice as all_solutions().

  • omit_infinite (bool) – Drop the endpoints not classified finite (is_finite False) – the at-infinity and failed paths. True by default, so the frame holds just the genuine finite solutions; pass False to get every tracked path (their coordinate cells may be empty/NaN).

  • merge_multiplicities (bool) – Collapse a multiplicity-m solution – which the solver returns as m coincident endpoints – to its single representative row (multiplicity still records m). True by default. Pass False to keep every endpoint, including the m-1 duplicate copies. The grouping is the solver’s own (the C++ clustering that computes multiplicity), read off multiplicity_representative; this does not re-cluster.

  • group (VariableGroup or int, optional) – Project each solution onto one variable group – the solution cell then holds only that group’s coordinates (Cluster G). Pass the VariableGroup object or its 0-based FIFO index. None (default) keeps the whole point.

Returns:

One row per solution; the solution cell is a copied vector whose elements are Python complex for a double-precision solve and bertini.complex_mp for a multiprecision one (kept native, so no precision is lost).

Return type:

pandas.DataFrame

Notes

pandas is an optional dependency; this raises ImportError if it is absent. The point accessors – all_solutions(), finite_solutions(), solution_metadata() – are the no-pandas path.

update(**fields)

Set config fields on this owner by NAME, each routed to whichever config owns it.

You never name the config struct:

solver.update(final_tolerance="1e-11",          # -> TolerancesConfig
              max_num_crossed_path_resolve_attempts=3)   # -> ZeroDimConfig

Strings work for every numeric field (converted exactly). A field that none of this owner’s configs has raises AttributeError with the valid names – so a typo, or trying to set a tracker field on the algorithm (or vice versa), never silently does nothing. Returns self, so calls chain. To set a whole config at once, or to name the config explicitly, use configure().

was_stopped_early((HomotopySolverPowerSeriesDoublePrecision)self) → bool :

Was the last solve() stopped before it finished – by Ctrl-C, or by request_stop()? If so the results are a PARTIAL set: paths in flight were abandoned and read SuccessCode.ExternallyTerminated, paths not yet begun still read NeverStarted, and every count derived from them describes only what was tracked. Re-running the same solve recalls the finished paths from the records and tracks only the rest.

class bertini.nag_algorithm.HomotopySolverPowerSeriesFixedMultiplePrecision((object)arg1, (bertini._pybertini.system.System)target, (UserStartSystem)start, (bertini._pybertini.system.System)homotopy)

Bases: AnyZeroDim

__init__((object)arg1, (bertini._pybertini.system.System)target, (UserStartSystem)start, (bertini._pybertini.system.System)homotopy) → None
add_observer((object)self, (object)observer) → None :

Attach an observer to this observable object

all_solutions((HomotopySolverPowerSeriesFixedMultiplePrecision)self[, (bool)user_coords=True]) → bertini._pybertini.container.ListOfVectorComplexVariablePrecision :

get ALL the computed solutions, one per tracked path (finite, at-infinity, and failed alike). by default they are in the coordinates of YOUR variables (dehomogenized, depatched). pass user_coords=False to decline, getting the solver’s internal coordinates instead: homogenized, lying on the target system’s patch – the representation to use for continuing work. the container is computed at most once per solve; repeated calls and indexing do not recompute it. for the filtered view see solutions(); for the at-infinity ones see infinite_solutions.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

config_names()

The keyword names accepted by configure() for this owner, its tracker and its endgame.

config_types((HomotopySolverPowerSeriesFixedMultiplePrecision)self) → list :

List the configuration struct classes this object accepts.

configure(**kwargs)

Change settings on this owner’s configs in one call.

Each keyword names a config (e.g. stepping, newton, tolerances); its value is either a dict of fields to change, or a ready config object.

tracker.configure(stepping={‘max_step_size’: 0.1},

newton={‘max_num_newton_iterations’: 2})

Returns self.

default_point_match_tolerance((HomotopySolverPowerSeriesFixedMultiplePrecision)arg1) → float :

the default infinity-norm tolerance metadata_for() uses when you omit tol: the solver’s final_tolerance (the accuracy each endpoint is computed to). Since metadata_for matches against representatives – which are at least the same-point clustering tolerance apart – this tight default still resolves a fed-back solution to itself while making an ambiguous match structurally impossible.

endgame_boundary_metadata((HomotopySolverPowerSeriesFixedMultiplePrecision)arg1) → MidpathCheckReport :

get the MidpathCheckReport from the path-crossing check at the endgame boundary: how many crossings were detected, which paths, how many re-track attempts were made, and whether the check ultimately passed

endgame_boundary_solutions((HomotopySolverPowerSeriesFixedMultiplePrecision)arg1) → bertini._pybertini.container.ListOfEGBoundaryMetaData_MultiPrec :

get the solutions (per-path point data) at the endgame boundary, where regular tracking switches to the endgame

finite_solutions((HomotopySolverPowerSeriesFixedMultiplePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the FINITE solutions: successful endpoints the solver calls finite (is_finite applies endpoint_finite_threshold). includes singular, nonsingular, and real solutions alike. merge_multiplicities=True (default) collapses each multiple solution to one representative. user coordinates by default; user_coords=False for internal coordinates.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

get_config((HomotopySolverPowerSeriesFixedMultiplePrecision)self, (object)config_type) → object :

Return a copy of this object’s stored configuration struct of the given class.

The named config, by class (TolerancesConfig) or by short name ('tolerances',

as config_names() lists them).

Either may belong to this object’s tracker or endgame rather than to the object itself (solver.get_config('stepping'), solver.get_config(EndgameConfig)); it is fetched from whichever holds it, so every name config_names() lists can be asked for.

get_endgame((HomotopySolverPowerSeriesFixedMultiplePrecision)arg1) → bertini._pybertini.endgame.FixedMultiplePowerSeriesEndgame :

get a mutable reference to the Endgame being used

get_settings(as_dict=False)

This owner’s whole configuration as a carryable dict.

By default (as_dict=False) the value is {config_name: config} – each a copy of one of the owner’s configs (e.g. {'stepping': SteppingConfig(...), 'tolerances': TolerancesConfig(...)}), keyed by the short names config_names() lists. The configs are independent copies (and picklable), so the dict is a plain Python value you can stash, tweak, and apply to other owners – the way to carry one set of tracking settings across a series of related solves:

settings = first_solver.get_settings()
next_solver.set_settings(settings)

Pass as_dict=True for the flat, human-readable view instead: one {field_name: value} dict across ALL configs (field names are unique across an owner’s configs, so there is no collision). That form drops the struct layer nobody wants to poke at, and round-trips through set:

flat = solver.get_settings(as_dict=True)   # {'final_tolerance': ..., 'max_step_size': ..., ...}
other.set(**flat)

(The config-keyed default is kept because set_settings consumes it; use whichever fits.) See set_settings() for applying the config-keyed form back.

get_tracker((HomotopySolverPowerSeriesFixedMultiplePrecision)arg1) → bertini._pybertini.tracking.MultiplePrecisionTracker :

get a mutable reference to the Tracker being used

infinite_solutions((HomotopySolverPowerSeriesFixedMultiplePrecision)self[, (bool)user_coords=True]) → list :

the solutions AT INFINITY: endpoints not classified finite (is_finite is False). these are the paths the endgame resolved as diverging – its GoingToInfinity / SecurityMaxNormReached verdict, or a successful endpoint whose dehomogenized infinity norm exceeds endpoint_finite_threshold. the complement of finite_solutions within all_solutions. NOTE a path that FAILED before the endgame also has is_finite False (its point is not a real solution at infinity); inspect solution_metadata()/report() to tell a true divergence from a tracking failure.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

metadata_for((HomotopySolverPowerSeriesFixedMultiplePrecision)self, (numpy.ndarray)point[, (float)tol=-1.0[, (bool)coincident=False[, (bool)user_coords=True[, (bool)representatives_only=True]]]]) → object :

the SolutionMetaData for the solution matching point (issue #302). Matches by the infinity-norm tolerance tol (see is_distinct_up_to) against the multiplicity REPRESENTATIVES – one candidate per distinct solution. tol is OPTIONAL: omit it (or pass a non-positive value) to use default_point_match_tolerance() (the solver’s final_tolerance). Because representatives are at least the same-point tolerance apart and the default window is smaller, a pt taken straight from solutions() / real_solutions() / etc. (which return representatives) matches its own representative back and is NEVER reported ambiguous – feed a solver result straight back in and it Just Works. The return type NEVER depends on the point’s multiplicity: by default returns exactly ONE record – the multiplicity-cluster representative (it carries .multiplicity, so you still learn m). coincident=True instead ALWAYS returns a LIST of every coincident copy’s record (their per-path condition number / residual / precision), length 1 for a simple root. representatives_only=False matches against EVERY endpoint including non-representative multiplicity copies – a debugging view, rarely what you want. Raises if no solution matches within tol, or (only for a deliberately coarse tol) if the point matches more than one distinct cluster. point is in user coordinates unless user_coords=False. Accepts any numpy array of the solver’s complex type – which is exactly what the solution lists return.

nonsingular_solutions((HomotopySolverPowerSeriesFixedMultiplePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the NONSINGULAR finite solutions (simple, well-conditioned roots). (Nonsingular solutions are simple, so merge_multiplicities is a no-op; kept for a uniform signature.)

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

nonsolutions((HomotopySolverPowerSeriesFixedMultiplePrecision)self[, (bool)user_coords=True]) → list :

the NONSOLUTIONS: finite, successful endpoints that are NOT solutions of the target system – the extraneous nonsolutions a squared-up over-determined system introduces (empty otherwise). Excluded from finite_solutions/real/singular; a regeneration cascade reads these to discard them.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

num_paths((HomotopySolverPowerSeriesFixedMultiplePrecision)self) → int :

How many paths this solve has to answer – the start system’s start point count. Known once a solve has begun its setup, which is before the first path event, and 0 before that.

num_paths_never_started((HomotopySolverPowerSeriesFixedMultiplePrecision)self) → int :

How many paths the last solve() never began, because it was stopped first.

num_paths_recalled((HomotopySolverPowerSeriesFixedMultiplePrecision)self) → int :

How many paths the last solve() recalled from the records instead of computing (0 on a fresh solve; num_paths on a full memo hit).

real_solutions((HomotopySolverPowerSeriesFixedMultiplePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the REAL finite solutions (is_real applies the configured tolerance). merge_multiplicities=True (default) collapses each multiple solution to one representative.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

record_to((HomotopySolverPowerSeriesFixedMultiplePrecision)self, (str)directory) → None :

Attach a structured output directory at the given path: this solve records every path as it completes (durable, plain-text, see the directory’s README.txt) and consults the records before computing – an identical ask (same system, settings, seed) recalls from the records instead of re-tracking, so a crashed solve resumes by simply calling solve() again. Recording is ON BY DEFAULT with no code at all: an unattached solver records to the ambient directory (BERTINI_RECORDS_DIR, else ./bertini_output; the value ‘none’ switches records off). record_to chooses the directory explicitly and always wins over the ambient resolution.

records_path((HomotopySolverPowerSeriesFixedMultiplePrecision)self) → object :

The attached output directory’s path, or None when not recording.

records_run_id((HomotopySolverPowerSeriesFixedMultiplePrecision)self) → str :

This solve’s run id in the records (empty until a recording solve() runs). Points are referenced as {run, index} pairs; this is the run half.

remove_observer((object)self, (object)observer) → None :

Remove an observer to this observable object

report((HomotopySolverPowerSeriesFixedMultiplePrecision)arg1) → SolveReport :

a concise end-of-solve diagnostic summary (a SolveReport): how every path ended up – finite solutions, diverged, or FAILED (by named reason) – plus singular/real counts, max condition number, the path-crossing outcome, and all_paths_resolved. print(solver.report()) for a human-readable summary; a count alone can hide a path the tracker silently lost.

result()

This solve’s SolveResult: the finite solutions plus the records ticket (run id, directory, recall count), read from the solver’s own recorded state.

A bare solver.solve() already returns this; result() re-derives it (call it after solve()) if you did not keep the return value.

same_point_tolerance((HomotopySolverPowerSeriesFixedMultiplePrecision)arg1) → float :

the same-point (clustering) tolerance, final_tolerance * same_point_tolerance_multiplier: the looser tolerance the solver uses to decide two endpoints are the SAME solution and cluster them into one multiplicity (and that metadata_for(coincident=True) uses to gather a cluster’s copies).

set(**fields)

Set config fields on this owner by NAME, each routed to whichever config owns it.

You never name the config struct:

solver.update(final_tolerance="1e-11",          # -> TolerancesConfig
              max_num_crossed_path_resolve_attempts=3)   # -> ZeroDimConfig

Strings work for every numeric field (converted exactly). A field that none of this owner’s configs has raises AttributeError with the valid names – so a typo, or trying to set a tracker field on the algorithm (or vice versa), never silently does nothing. Returns self, so calls chain. To set a whole config at once, or to name the config explicitly, use configure().

set_config((HomotopySolverPowerSeriesFixedMultiplePrecision)self, (TolerancesConfig)config) → None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (HomotopySolverPowerSeriesFixedMultiplePrecision)self, (PostProcessingConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (HomotopySolverPowerSeriesFixedMultiplePrecision)self, (ZeroDimConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (HomotopySolverPowerSeriesFixedMultiplePrecision)self, (AutoRetrackConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (HomotopySolverPowerSeriesFixedMultiplePrecision)self, (RecordsConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (HomotopySolverPowerSeriesFixedMultiplePrecision)self, (MidPathConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

Store a configuration struct, on this object or on whichever of its tracker and

endgame owns that config’s type.

set_recorded_start_provenance((HomotopySolverPowerSeriesFixedMultiplePrecision)self, (str)refs_json, (str)start_identity) → None :

Declare where this solve’s start points came from, for the records: a JSON array with one reference object per path ({‘kind’:’point_ref’,’run’:…,’index’:…} for a chain from a prior run, {‘kind’:’given_ref’,’given’:…,’index’:…} for external data), plus an identity string for the start data (it joins the ask: same homotopy, different starts = different computation). Call before solve().

set_settings(settings, strict=False)

Apply a settings dict (from get_settings()) onto this owner. Returns self.

settings is {config_name: config} (or {config_name: {field: value}}). By default only the configs this owner actually has are applied and the rest are skipped – so a bundle carried from one solver drops cleanly onto another whose config set differs (e.g. a different precision model, or a different algorithm stage). Pass strict=True to instead raise on any key this owner does not have.

singular_solutions((HomotopySolverPowerSeriesFixedMultiplePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the SINGULAR finite solutions (multiple or ill-conditioned roots). merge_multiplicities=True (default) collapses each multiple solution to one representative.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

solution_metadata((HomotopySolverPowerSeriesFixedMultiplePrecision)arg1) → bertini._pybertini.container.ListOfSolutionMetaData_MultiPrec :

get the metadata for the solutions at the target time

solutions((HomotopySolverPowerSeriesFixedMultiplePrecision)self[, (bool)singular=True[, (bool)real=True[, (bool)nonreal=True[, (bool)nonsingular=True[, (bool)infinite=False[, (bool)nonsolution=False[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]]]]]]]) → list :

the solutions, filtered by category (returns points, not metadata). By DEFAULT every finite genuine solution – real and complex, simple and multiple – and nothing else. Each keyword toggles a category: singular / nonsingular select by conditioning, real / nonreal by realness (a finite solution is returned only if BOTH its conditioning class and its realness class are enabled), infinite=True also returns the at-infinity endpoints, and nonsolution=True also returns the nonsolutions. E.g. solutions(real=False) -> complex finite solutions only; solutions(singular=False) -> nonsingular finite solutions; solutions(infinite=True) adds the divergent paths. merge_multiplicities=True (the DEFAULT) collapses a multiplicity-m solution to its single representative (pass False to get all m coincident copies). user_coords=False gives the solver’s internal coordinates. See also real_solutions / nonsingular_solutions / singular_solutions / infinite_solutions / nonsolutions for the common single-category views, and all_solutions for the raw per-path list.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

solve((HomotopySolverPowerSeriesFixedMultiplePrecision)arg1[, (object)communicator=None]) → None :

Run the zero-dim algorithm. Pass an mpi4py communicator for parallel execution.

Settings: pass config fields either as a dict (settings={‘final_tolerance’: 1e-13}) or by keyword (solve(final_tolerance=1e-13)); each is applied via set() before solving, so make/set/solve becomes a single call. communicator= is reserved for MPI (never a setting).

show_progress=True (the default) reports how far the solve has got. It draws nothing unless the solve runs past a few seconds AND stderr is a terminal, so scripts, pipelines and test runs see nothing; pass show_progress=False to be certain of silence.

Returns a bertini.records.SolveResult – the finite solutions plus this solve’s records ticket (run id, directory, recall count), read from the solver’s own records (the solver records itself, on by default). Drop it freely: solver.result() re-derives it, and the records hold the truth.

target_system((HomotopySolverPowerSeriesFixedMultiplePrecision)arg1) → bertini._pybertini.system.System :

get the prepared target system: the homogenized, auto-patched clone of the system you supplied. its patch is the one internal-coordinate solutions lie on; use its dehomogenize_point/homogenize_point/variable_ordering to move between representations.

to_classic_input((HomotopySolverPowerSeriesFixedMultiplePrecision)self, (bertini._pybertini.system.System)system) → str :

emit a complete Bertini 1 classic input file (CONFIG + INPUT) for the given natural system, using THIS solver’s tracking settings for the CONFIG: precision mode (mptype), ODE predictor, tolerances (before/during endgame, final), the full step-size cadence, max Newton iterations, and the crossed-path resolve cap. The system you pass supplies INPUT – pass the natural (un-homogenized) system you constructed the solver from, since the solver homogenizes and patches its internal copy. Use this to re-run the exact same problem with the exact same knobs in Bertini 1 for cross-validation (the random start system aside). For sweeping settings without a solver, see system.to_classic_input(**kwargs).

to_dataframe(*, user_coords=True, omit_infinite=True, merge_multiplicities=True, group=None)

The solve as a pandas DataFrame – one row per solution, the “database of solutions”.

Columns are solution – the whole solution point, kept in a single cell – then every per-solution metadata field (is_finite, is_real, is_singular, multiplicity, condition_number, endgame_success_code, max_precision_used, …), and finally system, a reference to the (target) system these solutions satisfy (so rows accumulated from several solves stay identifiable). Each category is then a one-line filter, e.g. df[df.is_real & ~df.is_singular] (nonsingular real) or df[~df.is_finite] (at infinity).

The solution cell is an independent copy of the solution vector (a numpy array of Python complex for a double solve, of bertini.complex_mp for a multiprecision one, so no precision is lost). Coordinates are deliberately not exploded into x0, x1, ... columns; split them yourself if you want them, e.g. df['x'] = [v[0] for v in df.solution].

Parameters:
  • user_coords (bool) – Coordinates in YOUR variables (dehomogenized; default), or the solver’s internal homogenized on-patch coordinates when False – the same choice as all_solutions().

  • omit_infinite (bool) – Drop the endpoints not classified finite (is_finite False) – the at-infinity and failed paths. True by default, so the frame holds just the genuine finite solutions; pass False to get every tracked path (their coordinate cells may be empty/NaN).

  • merge_multiplicities (bool) – Collapse a multiplicity-m solution – which the solver returns as m coincident endpoints – to its single representative row (multiplicity still records m). True by default. Pass False to keep every endpoint, including the m-1 duplicate copies. The grouping is the solver’s own (the C++ clustering that computes multiplicity), read off multiplicity_representative; this does not re-cluster.

  • group (VariableGroup or int, optional) – Project each solution onto one variable group – the solution cell then holds only that group’s coordinates (Cluster G). Pass the VariableGroup object or its 0-based FIFO index. None (default) keeps the whole point.

Returns:

One row per solution; the solution cell is a copied vector whose elements are Python complex for a double-precision solve and bertini.complex_mp for a multiprecision one (kept native, so no precision is lost).

Return type:

pandas.DataFrame

Notes

pandas is an optional dependency; this raises ImportError if it is absent. The point accessors – all_solutions(), finite_solutions(), solution_metadata() – are the no-pandas path.

update(**fields)

Set config fields on this owner by NAME, each routed to whichever config owns it.

You never name the config struct:

solver.update(final_tolerance="1e-11",          # -> TolerancesConfig
              max_num_crossed_path_resolve_attempts=3)   # -> ZeroDimConfig

Strings work for every numeric field (converted exactly). A field that none of this owner’s configs has raises AttributeError with the valid names – so a typo, or trying to set a tracker field on the algorithm (or vice versa), never silently does nothing. Returns self, so calls chain. To set a whole config at once, or to name the config explicitly, use configure().

was_stopped_early((HomotopySolverPowerSeriesFixedMultiplePrecision)self) → bool :

Was the last solve() stopped before it finished – by Ctrl-C, or by request_stop()? If so the results are a PARTIAL set: paths in flight were abandoned and read SuccessCode.ExternallyTerminated, paths not yet begun still read NeverStarted, and every count derived from them describes only what was tracked. Re-running the same solve recalls the finished paths from the records and tracks only the rest.

class bertini.nag_algorithm.MidPathConfig((object)arg1)

Bases: instance

__init__((object)arg1) → None
classmethod from_dict(mapping)

Build a config from a dict (default-constructs, then update()).

property same_point_tolerance

Tolerance used by the midpath check to detect two paths that have crossed (become the same point) partway through tracking, which signals a need to retrack.

set(**kwargs)

Set one or more fields at once; returns self so calls can chain.

Numeric fields accept strings (e.g. max_step_size=”0.05”), which are converted exactly to multiprecision values. Raises AttributeError on an unknown/misspelled field name.

to_dict()

The config’s fields as an ordinary dict of {name: value}.

update(**kwargs)

Set one or more fields at once; returns self so calls can chain.

Numeric fields accept strings (e.g. max_step_size=”0.05”), which are converted exactly to multiprecision values. Raises AttributeError on an unknown/misspelled field name.

class bertini.nag_algorithm.MidpathCheckReport((object)arg1)

Bases: instance

__init__((object)arg1) → None
property crossed_path_indices

Indices of the paths flagged as crossed on the first check.

property num_crossings_detected

Number of crossed paths found on the FIRST check, before any re-tracking.

property num_resolve_attempts

How many re-track attempts were actually performed.

property passed

Did the final midpath check pass (no path crossings remained)? False means one or more crossings were left unresolved and the affected solutions may be wrong.

class bertini.nag_algorithm.PostProcessingConfig((object)arg1)

Bases: instance

__init__((object)arg1) → None
property condition_number_threshold

Bertini 1’s CondNumThreshold. An endpoint is classified singular if it is the endpoint of multiple paths (multiplicity > 1), or if its spectral-norm condition-number estimate exceeds this value. Default 1e8.

property endpoint_finite_threshold

Bertini 1’s EndpointFiniteThreshold. An endpoint is classified at infinity if the infinity norm of its dehomogenized coordinates exceeds this value. Default 1e5.

classmethod from_dict(mapping)

Build a config from a dict (default-constructs, then update()).

property real_threshold

Bertini 1’s ImagThreshold. A (dehomogenized) endpoint is classified real if the infinity norm of its coordinates’ imaginary parts is below this. Default 1e-8.

property same_point_tolerance_multiplier

two endpoints are the same point (raising multiplicity) when the infinity norm of the difference of their dehomogenized coordinates is below final_tolerance * same_point_tolerance_multiplier. Default 10.

Type:

Bertini 1’s EndpointSameThreshold. A multiplier (>= 1) on final_tolerance

set(**kwargs)

Set one or more fields at once; returns self so calls can chain.

Numeric fields accept strings (e.g. max_step_size=”0.05”), which are converted exactly to multiprecision values. Raises AttributeError on an unknown/misspelled field name.

to_dict()

The config’s fields as an ordinary dict of {name: value}.

update(**kwargs)

Set one or more fields at once; returns self so calls can chain.

Numeric fields accept strings (e.g. max_step_size=”0.05”), which are converted exactly to multiprecision values. Raises AttributeError on an unknown/misspelled field name.

class bertini.nag_algorithm.RecallPolicy

Bases: enum

Which recorded outcomes of an identical ask count as already answered when it is solved again. A path record is reusable when the run that would reuse it asks no more of that path than the run that produced it: a completed path (success, divergence, a failure under settings that are part of the ask) always qualifies; an abandoned one – stopped, or cut off by a wall-clock limit – was ended for a reason kept out of the ask, so whether to reuse it is your call. Nothing: track every path fresh (observers, benchmarking, re-verification). Completed (the default): reuse completed paths, re-track abandoned ones – except one cut off by a wall-clock limit no smaller than the current per-path limit, which is reused; an interrupted path is always re-tracked. Everything: reuse every recorded outcome as recorded.

Completed = bertini._pybertini.nag_algorithms.RecallPolicy.Completed
Everything = bertini._pybertini.nag_algorithms.RecallPolicy.Everything
Nothing = bertini._pybertini.nag_algorithms.RecallPolicy.Nothing
names = {'Completed': bertini._pybertini.nag_algorithms.RecallPolicy.Completed, 'Everything': bertini._pybertini.nag_algorithms.RecallPolicy.Everything, 'Nothing': bertini._pybertini.nag_algorithms.RecallPolicy.Nothing}
values = {0: bertini._pybertini.nag_algorithms.RecallPolicy.Nothing, 1: bertini._pybertini.nag_algorithms.RecallPolicy.Completed, 2: bertini._pybertini.nag_algorithms.RecallPolicy.Everything}
class bertini.nag_algorithm.RecordsConfig((object)arg1)

Bases: instance

How a recording solver uses the records it finds: not what to compute, but what already-recorded work counts as done. Its own config because the question is the same for every algorithm that records paths. Transient: nothing here is part of a run’s identity/digest.

__init__((object)arg1) → None
classmethod from_dict(mapping)

Build a config from a dict (default-constructs, then update()).

property recall

True means Completed, False means Nothing – force a fresh track even when the paths are recorded, e.g. to run path observers, benchmark the solve, or re-verify a run; the fresh track is still recorded. No effect when nothing is recorded.

Type:

Which recorded outcomes of an identical ask already in the records directory are used in place of tracking

Type:

a RecallPolicy (default RecallPolicy.Completed). A bool is accepted too

set(**kwargs)

Set one or more fields at once; returns self so calls can chain.

Numeric fields accept strings (e.g. max_step_size=”0.05”), which are converted exactly to multiprecision values. Raises AttributeError on an unknown/misspelled field name.

to_dict()

The config’s fields as an ordinary dict of {name: value}.

update(**kwargs)

Set one or more fields at once; returns self so calls can chain.

Numeric fields accept strings (e.g. max_step_size=”0.05”), which are converted exactly to multiprecision values. Raises AttributeError on an unknown/misspelled field name.

class bertini.nag_algorithm.RegenerationConfig((object)arg1)

Bases: instance

__init__((object)arg1) → None
classmethod from_dict(mapping)

Build a config from a dict (default-constructs, then update()).

property higher_dimension_check

Whether to test for, and remove, points lying on higher-dimensional components during regeneration.

property remove_infinite_endpoints

Whether endpoints found to be at infinity during regeneration start-point buildup are discarded. Set True if you are not interested in solutions at infinity.

set(**kwargs)

Set one or more fields at once; returns self so calls can chain.

Numeric fields accept strings (e.g. max_step_size=”0.05”), which are converted exactly to multiprecision values. Raises AttributeError on an unknown/misspelled field name.

property slice_final_tolerance

Final tolerance to track the slice move to, using the endgame (Bertini 1 SliceFinalTol).

property slice_newton_before_endgame

Slice-moving tracking tolerance before the endgame (Bertini 1 SliceTolBeforeEG). Separate from TolerancesConfig.newton_before_endgame, which governs the main tracking.

property slice_newton_during_endgame

Slice-moving tracking tolerance during the endgame (Bertini 1 SliceTolDuringEG).

property start_level

The regeneration level at which to begin.

to_dict()

The config’s fields as an ordinary dict of {name: value}.

update(**kwargs)

Set one or more fields at once; returns self so calls can chain.

Numeric fields accept strings (e.g. max_step_size=”0.05”), which are converted exactly to multiprecision values. Raises AttributeError on an unknown/misspelled field name.

class bertini.nag_algorithm.SharpeningConfig((object)arg1)

Bases: instance

__init__((object)arg1) → None
classmethod from_dict(mapping)

Build a config from a dict (default-constructs, then update()).

property function_residual_tolerance

A function value is considered zero if its magnitude is smaller than this.

property ratio_tolerance

A value is considered zero if the ratio of two different approximations is smaller than this.

set(**kwargs)

Set one or more fields at once; returns self so calls can chain.

Numeric fields accept strings (e.g. max_step_size=”0.05”), which are converted exactly to multiprecision values. Raises AttributeError on an unknown/misspelled field name.

property sharpendigits

How many digits should be correct after sharpening a solution.

to_dict()

The config’s fields as an ordinary dict of {name: value}.

update(**kwargs)

Set one or more fields at once; returns self so calls can chain.

Numeric fields accept strings (e.g. max_step_size=”0.05”), which are converted exactly to multiprecision values. Raises AttributeError on an unknown/misspelled field name.

class bertini.nag_algorithm.Slice((object)arg1)

Bases: instance

A linear slice: a stack of linear forms M [x ; 1] that cuts a positive-dimensional component down to witness points. The linear part of a witness set.

A slice is a Python sequence of its linear forms:

  • len(slice) – the number of forms (the slice’s dimension).

  • slice[i] (integer) – the i-th form’s coefficient vector (1-D, length num_variables+1). Iterating yields these vectors. A single linear form is a vector.

  • slice[i:j] / slice[[i, j]] – a sub-Slice (a sub-collection of forms).

  • slice.coefficients() – the whole augmented coefficient matrix, always 2-D (num_forms, num_variables+1).

The vector view vs the matrix view is named (element index vs slice / coefficients), never inferred from the form count – so it is stable regardless of the binding library’s shape conventions (docs/adr/0033).

A slice does NOT own homogenization – the system does. slice.add_to(system) appends the forms to a system (folding the constant onto the homogenizing variable if the system was homogenized); slice.as_system() returns a standalone System of just the forms. Build slices with Slice.random_complex / Slice.random_real / Slice.from_coefficients (or bertini.bertini.Slice.from_coefficients for exact numpy/list coefficients).

__init__((object)arg1) → None
add_to((Slice)self, (bertini._pybertini.system.System)system) → None :

add this slice’s linear forms to a System as a linear-forms block

as_system((Slice)self) → bertini._pybertini.system.System :

a standalone System whose functions are exactly this slice’s linear forms

coefficients()

The augmented coefficient matrix of the slice’s linear forms – always 2-D.

Shape (num_forms, num_variables + 1): one row per linear form, the trailing column carrying each form’s constant term. This holds even for a single-form slice, where the underlying binding library would otherwise hand back a 1-D array (eigenpy collapses a one-row matrix). The 2-D shape is part of this accessor’s contract – ours, not the binding’s – so it is stable across binding libraries; see docs/adr/0033. For one form’s coefficient vector, index an element: slice[i].

Examples

>>> import bertini
>>> import bertini
>>> x, y = bertini.Variable('x'), bertini.Variable('y')
>>> bertini.Slice.from_coefficients([[2, 3, 1]], [x, y]).coefficients().shape
(1, 3)
concatenate((Slice)self, (Slice)other) → Slice :

a new slice stacking this slice’s forms on top of other’s (both on the same variables)

dimension((Slice)self) → int :

the dimension of the slice – the number of linear forms

eval((Slice)self, (numpy.ndarray)x) → numpy.ndarray :

evaluate the linear forms at x, in double precision

eval( (Slice)self, (numpy.ndarray)x) -> numpy.ndarray :

evaluate the linear forms at x, in multiple precision

classmethod from_coefficients(coefficients, variables, homogeneous=False)

Build a Slice from an exact augmented coefficient matrix.

coefficients is an (m x n+1) array/list of EXACT values (see bertini.coefficient(); Python floats are refused) – one row per linear form, the trailing column being each form’s constant term (give 0 there for a homogeneous slice). variables is the length-n vector of variables the slice is over (a plain list/iterable of Variable, or a VariableGroup).

Returns a bertini.Slice. Its rows are ready-made factors for a products-of-linears block (see bertini.System.add_slices_as_products()):

s = bertini.Slice.from_coefficients([[2, 1, -1]], [x, y])   # 2x + y - 1 = 0
head((Slice)self, (int)m) → Slice :

a new slice over the same variables, built from the first m linear forms

is_homogeneous((Slice)self) → bool :

whether the slice was authored without constant terms

num_variables((Slice)self) → int :

the number of variables the slice is a function of

precision((Slice)self) → int :

get the current working precision of the slice

precision( (Slice)self, (int)precision) -> None :

set the working precision of the slice

classmethod random_complex(variables, dim, homogeneous=False, orthogonal=True)

Make a random complex slice of dim linear forms over variables (a VariableGroup or a flat list of Variables). homogeneous=True zeroes the constant column; orthogonal=True (default) orthonormalizes the coefficient block.

classmethod random_real(variables, dim, homogeneous=False, orthogonal=True)

Make a random real slice of dim linear forms over variables (a VariableGroup or a flat list of Variables). homogeneous=True zeroes the constant column; orthogonal=True (default) orthonormalizes the coefficient block.

rows((Slice)self, (list)indices) → Slice :

a new slice over the same variables, built from the chosen linear forms

tail((Slice)self, (int)m) → Slice :

a new slice over the same variables, built from the last m linear forms

classmethod through_point(variables, point, dim=1, coefficients=None, real=False, orthogonal=True, homogeneous=False)

Build a Slice through a given point – the one place to do this.

variables is the vector of variables the slice is over (a VariableGroup or a flat list of Variable). point is the point every linear form must vanish at – a length-num_variables vector of EXACT values (see bertini.coefficient(); Python floats are refused).

With coefficients=None (the default) a random block of dim linear forms is generated (complex, or real if real=True; orthonormalized when orthogonal) and anchored so it passes through point:

s = bertini.Slice.through_point([x, y], pt)          # a random line through pt

Pass coefficients (a bare dim x num_variables block of EXACT values, NOT augmented) to use exactly those directional coefficients; dim/real/orthogonal are then ignored.

homogeneous=True builds a projective slice through point (each form a.x = 0 with a.point = 0); it is random-only, so it cannot be combined with an explicit coefficients.

Returns a bertini.Slice.

to_classic_input(**kwargs)

Emit this slice’s linear forms as a Bertini 1 classic input file (see System.to_classic_input).

class bertini.nag_algorithm.SolutionMetaDataDoublePrec((object)arg1)

Bases: instance

__init__((object)arg1) → None
property accuracy_digits

floor(-log10(accuracy_estimate_internal_coords)), clamped to [0, precision_digits]. Read with precision_digits as ‘computed in N digits, good to M of them’.

Type:

How many digits of this solution are trustworthy (a digit count), from the convergence agreement

property accuracy_estimate

read accuracy_estimate_internal_coords or accuracy_estimate_user_coords.

Type:

Retired in 4.0

property accuracy_estimate_internal_coords

see accuracy_digits. For the error in your own variables, read accuracy_estimate_user_coords.

Type:

The distance between the endgame’s last two approximations of the root, in the solver’s INTERNAL coordinates (homogenized, on the patch). This is the quantity the endgame compares with final_tolerance to decide it has converged. It does not grow with the scale of the solution, so it reads as a number of correct digits

property accuracy_estimate_user_coords

an absolute error, in the units of your variables. A solution of order 1000 with six correct digits has about 1e-3 here. It is measured in the infinity norm, so the largest coordinate sets it and a small coordinate of the same point has fewer correct digits of its own.

Type:

The distance between the endgame’s last two approximations of the root, in YOUR coordinates (dehomogenized)

property condition_number

The latest estimate of the condition number (spectral norm) near the endpoint. Used, together with multiplicity, to classify the endpoint as singular.

property crossing_unresolved

Whether this path was flagged as crossing another at the endgame boundary and the crossing was NOT resolved by re-tracking. Its success codes may still read Success, but the solver has warned that this endpoint may be wrong; check this before building on the endpoint. See endgame_boundary_metadata() for the whole-solve report.

property cycle_num

The cycle number used by the endgame’s extrapolation.

property endgame_success_code

The SuccessCode from the endgame. 0 means Success; anything else means the path did not converge to a finite solution (e.g. GoingToInfinity, SecurityMaxNormReached).

property final_time_used

The last time value this path reached. For a successful path, the endgame’s latest time (at or near the target). For a path that did not succeed, in either stage, the time the tracker was at when it stopped – read with latest_path_point, the point it was at.

classmethod from_dict(mapping)

Build a config from a dict (default-constructs, then update()).

property function_residual

Infinity norm of the target system evaluated at the endpoint.

property is_finite

the infinity norm of its dehomogenized coordinates is at most PostProcessingConfig.endpoint_finite_threshold. False also for paths the endgame flagged as diverging.

Type:

Whether the endpoint is finite (not at infinity)

property is_nonsolution

a finite, successful point that is not a solution of the target system – the extraneous nonsolutions introduced when ZeroDimSolver squares up an over-determined system. Orthogonal to is_finite; excluded from the finite/real/singular solution accessors and surfaced by nonsolutions(). Load-bearing for regeneration cascades.

Type:

Whether the endpoint is a NONSOLUTION

property is_real

Whether the (dehomogenized) endpoint is real, i.e. the infinity norm of its coordinates’ imaginary parts is below PostProcessingConfig.real_threshold. Only meaningful for finite, successful endpoints.

property is_singular

multiplicity > 1, or the condition-number estimate exceeds PostProcessingConfig.condition_number_threshold. Only meaningful for successful endpoints.

Type:

Whether the endpoint is singular

property latest_path_point

the last point reached on a path that did NOT succeed – whether it failed, was stopped, or ran out of budget, in either stage – in the solver’s internal coordinates. Read with final_time_used, which holds the matching time. Empty for a successful path (its endpoint is the solution itself) and for a path never started. On a Cauchy endgame the point may lie on a sample circle rather than on the real segment to the target.

Type:

Where the tracker was when it gave up

property max_precision_used

The highest precision (in digits) used anywhere while tracking this path. For a fixed-precision solve this is simply that precision.

property multiplicity

How many paths ended at this same point (1 for a simple solution). Computed by comparing dehomogenized endpoints with the infinity norm against final_tolerance * same_point_tolerance_multiplier.

property multiplicity_representative

For a multiplicity-m solution the solver returns m coincident endpoints; exactly one of them is the chosen representative (True) and the other m-1 are duplicates (False). Use it to collapse a multiple solution to a single row – which is what ZeroDim.to_dataframe() does by default (merge_multiplicities=True). Simple solutions and at-infinity/failed endpoints are each their own representative (True).

property newton_residual

The latest Newton step norm near the endpoint.

property num_failed_steps

Predictor-corrector steps that failed and were retried with a smaller step on this path, pre-endgame tracking and endgame together. Many failed steps means the path was hard.

property num_successful_steps

Predictor-corrector steps that succeeded on this path, pre-endgame tracking and endgame together.

property path_index

Index of the start path that produced this solution.

property path_time_seconds

pre-endgame tracking plus endgame.

Type:

Wall-clock time (seconds) to execute this whole path

property pre_endgame_success_code

The SuccessCode from tracking this path up to the endgame boundary. 0 means Success.

property precision_changed

Whether precision was increased while tracking this path (adaptive precision only).

property precision_digits

The working precision (in digits) the endgame finished this solution in. For an adaptive solve, this is DoublePrecision (~16) for a path that stayed in the hardware-double fast lane, and the higher mpfr precision for a path that had to escalate.

set(**kwargs)

Set one or more fields at once; returns self so calls can chain.

Numeric fields accept strings (e.g. max_step_size=”0.05”), which are converted exactly to multiprecision values. Raises AttributeError on an unknown/misspelled field name.

property singular_values

The singular values of the (homogenized, patched) target system’s Jacobian at the endpoint, largest first, at the endpoint’s own precision; condition_number is the first over the last. Read a numerical rank from it at a tolerance of your choosing – no single tolerance suits every endpoint, so none is applied here. Empty for a path whose endgame did not succeed.

property solution_index

Index of this solution in the solution list.

property time_of_first_prec_increase

The time value at which precision first increased on this path (adaptive precision only).

to_dict()

The config’s fields as an ordinary dict of {name: value}.

update(**kwargs)

Set one or more fields at once; returns self so calls can chain.

Numeric fields accept strings (e.g. max_step_size=”0.05”), which are converted exactly to multiprecision values. Raises AttributeError on an unknown/misspelled field name.

property wall_clock_limit_seconds

The per-path wall-clock budget (seconds) in force when this path ran, from the solver’s max_path_wall_clock_duration; 0 means there was none. Recorded with the path, so a later run can tell whether it is asking more patience of an abandoned path than the run that abandoned it.

class bertini.nag_algorithm.SolutionMetaDataMultiPrec((object)arg1)

Bases: instance

__init__((object)arg1) → None
property accuracy_digits

floor(-log10(accuracy_estimate_internal_coords)), clamped to [0, precision_digits]. Read with precision_digits as ‘computed in N digits, good to M of them’.

Type:

How many digits of this solution are trustworthy (a digit count), from the convergence agreement

property accuracy_estimate

read accuracy_estimate_internal_coords or accuracy_estimate_user_coords.

Type:

Retired in 4.0

property accuracy_estimate_internal_coords

see accuracy_digits. For the error in your own variables, read accuracy_estimate_user_coords.

Type:

The distance between the endgame’s last two approximations of the root, in the solver’s INTERNAL coordinates (homogenized, on the patch). This is the quantity the endgame compares with final_tolerance to decide it has converged. It does not grow with the scale of the solution, so it reads as a number of correct digits

property accuracy_estimate_user_coords

an absolute error, in the units of your variables. A solution of order 1000 with six correct digits has about 1e-3 here. It is measured in the infinity norm, so the largest coordinate sets it and a small coordinate of the same point has fewer correct digits of its own.

Type:

The distance between the endgame’s last two approximations of the root, in YOUR coordinates (dehomogenized)

property condition_number

The latest estimate of the condition number (spectral norm) near the endpoint. Used, together with multiplicity, to classify the endpoint as singular.

property crossing_unresolved

Whether this path was flagged as crossing another at the endgame boundary and the crossing was NOT resolved by re-tracking. Its success codes may still read Success, but the solver has warned that this endpoint may be wrong; check this before building on the endpoint. See endgame_boundary_metadata() for the whole-solve report.

property cycle_num

The cycle number used by the endgame’s extrapolation.

property endgame_success_code

The SuccessCode from the endgame. 0 means Success; anything else means the path did not converge to a finite solution (e.g. GoingToInfinity, SecurityMaxNormReached).

property final_time_used

The last time value this path reached. For a successful path, the endgame’s latest time (at or near the target). For a path that did not succeed, in either stage, the time the tracker was at when it stopped – read with latest_path_point, the point it was at.

classmethod from_dict(mapping)

Build a config from a dict (default-constructs, then update()).

property function_residual

Infinity norm of the target system evaluated at the endpoint.

property is_finite

the infinity norm of its dehomogenized coordinates is at most PostProcessingConfig.endpoint_finite_threshold. False also for paths the endgame flagged as diverging.

Type:

Whether the endpoint is finite (not at infinity)

property is_nonsolution

a finite, successful point that is not a solution of the target system – the extraneous nonsolutions introduced when ZeroDimSolver squares up an over-determined system. Orthogonal to is_finite; excluded from the finite/real/singular solution accessors and surfaced by nonsolutions(). Load-bearing for regeneration cascades.

Type:

Whether the endpoint is a NONSOLUTION

property is_real

Whether the (dehomogenized) endpoint is real, i.e. the infinity norm of its coordinates’ imaginary parts is below PostProcessingConfig.real_threshold. Only meaningful for finite, successful endpoints.

property is_singular

multiplicity > 1, or the condition-number estimate exceeds PostProcessingConfig.condition_number_threshold. Only meaningful for successful endpoints.

Type:

Whether the endpoint is singular

property latest_path_point

the last point reached on a path that did NOT succeed – whether it failed, was stopped, or ran out of budget, in either stage – in the solver’s internal coordinates. Read with final_time_used, which holds the matching time. Empty for a successful path (its endpoint is the solution itself) and for a path never started. On a Cauchy endgame the point may lie on a sample circle rather than on the real segment to the target.

Type:

Where the tracker was when it gave up

property max_precision_used

The highest precision (in digits) used anywhere while tracking this path. For a fixed-precision solve this is simply that precision.

property multiplicity

How many paths ended at this same point (1 for a simple solution). Computed by comparing dehomogenized endpoints with the infinity norm against final_tolerance * same_point_tolerance_multiplier.

property multiplicity_representative

For a multiplicity-m solution the solver returns m coincident endpoints; exactly one of them is the chosen representative (True) and the other m-1 are duplicates (False). Use it to collapse a multiple solution to a single row – which is what ZeroDim.to_dataframe() does by default (merge_multiplicities=True). Simple solutions and at-infinity/failed endpoints are each their own representative (True).

property newton_residual

The latest Newton step norm near the endpoint.

property num_failed_steps

Predictor-corrector steps that failed and were retried with a smaller step on this path, pre-endgame tracking and endgame together. Many failed steps means the path was hard.

property num_successful_steps

Predictor-corrector steps that succeeded on this path, pre-endgame tracking and endgame together.

property path_index

Index of the start path that produced this solution.

property path_time_seconds

pre-endgame tracking plus endgame.

Type:

Wall-clock time (seconds) to execute this whole path

property pre_endgame_success_code

The SuccessCode from tracking this path up to the endgame boundary. 0 means Success.

property precision_changed

Whether precision was increased while tracking this path (adaptive precision only).

property precision_digits

The working precision (in digits) the endgame finished this solution in. For an adaptive solve, this is DoublePrecision (~16) for a path that stayed in the hardware-double fast lane, and the higher mpfr precision for a path that had to escalate.

set(**kwargs)

Set one or more fields at once; returns self so calls can chain.

Numeric fields accept strings (e.g. max_step_size=”0.05”), which are converted exactly to multiprecision values. Raises AttributeError on an unknown/misspelled field name.

property singular_values

The singular values of the (homogenized, patched) target system’s Jacobian at the endpoint, largest first, at the endpoint’s own precision; condition_number is the first over the last. Read a numerical rank from it at a tolerance of your choosing – no single tolerance suits every endpoint, so none is applied here. Empty for a path whose endgame did not succeed.

property solution_index

Index of this solution in the solution list.

property time_of_first_prec_increase

The time value at which precision first increased on this path (adaptive precision only).

to_dict()

The config’s fields as an ordinary dict of {name: value}.

update(**kwargs)

Set one or more fields at once; returns self so calls can chain.

Numeric fields accept strings (e.g. max_step_size=”0.05”), which are converted exactly to multiprecision values. Raises AttributeError on an unknown/misspelled field name.

property wall_clock_limit_seconds

The per-path wall-clock budget (seconds) in force when this path ran, from the solver’s max_path_wall_clock_duration; 0 means there was none. Recorded with the path, so a later run can tell whether it is asking more patience of an abandoned path than the run that abandoned it.

class bertini.nag_algorithm.SolveReport((object)arg1)

Bases: instance

__init__((object)arg1) → None
property all_paths_resolved

True iff no path failed and no crossing was left unresolved – the solve is trustworthy.

property failures_by_reason

count} of how the failed paths ended.

Type:

Dict {SuccessCode

property max_condition_number

Largest condition number among the finite solutions.

property max_precision_used

Highest working precision (digits) any path needed.

property midpath

The MidpathCheckReport from the path-crossing check.

property num_diverged

Number of paths that diverged to infinity – a result, not a failure.

property num_failed

Number of paths the tracker could not resolve – each one a possibly-missing solution.

property num_finite_endpoints

Raw number of finite, successful endpoints (before collapsing multiplicities).

property num_finite_solutions

Number of DISTINCT finite solutions (multiple roots counted once).

property num_paths_tracked

Total number of paths tracked (the start-system / Bezout count).

property num_real

Number of finite solutions flagged real.

property num_singular

Number of finite solutions flagged singular (multiple or ill-conditioned).

class bertini.nag_algorithm.StartSystemFactory

Bases: instance

Opaque factory that builds a start system for a ZeroDim solver. Get one from start_system_factory(StartSystemType.X) and pass it as the solver’s second constructor arg.

Raises an exception This class cannot be instantiated from Python

__init__()

Raises an exception This class cannot be instantiated from Python

class bertini.nag_algorithm.StartSystemType

Bases: enum

Which start system a ZeroDim solver builds: total_degree_binomial (the default for 1-homogeneous systems), total_degree_linear_product, or mhomogeneous. User homotopies use nag_algorithm.user_homotopy(…) instead.

mhomogeneous = bertini._pybertini.nag_algorithms.StartSystemType.mhomogeneous
names = {'mhomogeneous': bertini._pybertini.nag_algorithms.StartSystemType.mhomogeneous, 'total_degree_binomial': bertini._pybertini.nag_algorithms.StartSystemType.total_degree_binomial, 'total_degree_linear_product': bertini._pybertini.nag_algorithms.StartSystemType.total_degree_linear_product}
total_degree_binomial = bertini._pybertini.nag_algorithms.StartSystemType.total_degree_binomial
total_degree_linear_product = bertini._pybertini.nag_algorithms.StartSystemType.total_degree_linear_product
values = {0: bertini._pybertini.nag_algorithms.StartSystemType.total_degree_linear_product, 1: bertini._pybertini.nag_algorithms.StartSystemType.total_degree_binomial, 2: bertini._pybertini.nag_algorithms.StartSystemType.mhomogeneous}
class bertini.nag_algorithm.TolerancesConfig((object)arg1)

Bases: instance

__init__((object)arg1) → None
classmethod from_dict(mapping)

Build a config from a dict (default-constructs, then update()).

property newton_before_endgame

Tracking (Newton) tolerance used while tracking before the endgame begins. Tighten this if paths drift together or are missed.

property newton_during_endgame

Tracking (Newton) tolerance used during the endgame.

set(**kwargs)

Set one or more fields at once; returns self so calls can chain.

Numeric fields accept strings (e.g. max_step_size=”0.05”), which are converted exactly to multiprecision values. Raises AttributeError on an unknown/misspelled field name.

to_dict()

The config’s fields as an ordinary dict of {name: value}.

update(**kwargs)

Set one or more fields at once; returns self so calls can chain.

Numeric fields accept strings (e.g. max_step_size=”0.05”), which are converted exactly to multiprecision values. Raises AttributeError on an unknown/misspelled field name.

class bertini.nag_algorithm.UserStartSystem((object)arg1, (bertini._pybertini.system.System)arg2, (list)arg3) → object :

Bases: instance

A start system that is simply a list of start points you already have (e.g. solutions from an earlier solve), to be tracked through a homotopy you constructed. Built for you by nag_algorithm.user_homotopy(…).

UserStartSystem(target_system, start_points): start_points is a list of vectors.

__init__((object)arg1, (bertini._pybertini.system.System)arg2, (list)arg3) → object :

UserStartSystem(target_system, start_points): start_points is a list of vectors.

num_start_points((UserStartSystem)arg1) → int
class bertini.nag_algorithm.ZeroDimConfig((object)arg1)

Bases: instance

__init__((object)arg1) → None
property endgame_boundary

The time value at which tracking stops and the endgame takes over.

classmethod from_dict(mapping)

Build a config from a dict (default-constructs, then update()).

property initial_ambient_precision

The working precision (digits) each path starts at. Read at the start of every path, so setting it on an existing solver takes effect on the next solve. Part of the run’s identity.

property max_num_crossed_path_resolve_attempts

How many times to re-track crossed paths (with tightened settings) at the endgame boundary before giving up. 0 = detect and report only, do not re-track. Default 2.

property max_path_wall_clock_duration

a budget says how long to wait for an answer, not what the answer is. How a later run treats a path abandoned under a budget is RecallPolicy’s business. Wall-clock time is machine-dependent; the recorded stamp is the machine-independent account.

Type:

Wall-clock budget for EACH path, in seconds; 0 (the default) means none. A path that has not finished when its budget runs out is abandoned between steps with SuccessCode.WallClockLimitReached, stamped with where it got to (latest_path_point, final_time_used, the step counts), and recorded with this limit. Not part of the run’s identity

property max_solve_wall_clock_duration

was_stopped_early() is True, abandoned paths read ExternallyTerminated, unstarted ones NeverStarted, and a later solve of the same ask re-tracks them. The per-path budget is the finer tool (it guarantees progress path by path); this one is for thinking in terms of the whole call. Not applied to the MPI solve.

Type:

Wall-clock budget for the WHOLE solve() call, in seconds; 0 (the default) means none. Once it runs out no further path is started and any path in flight is abandoned between steps, and the solve reads exactly as if you had pressed Ctrl-C

property num_threads

the heavy tracking runs in C++ with the GIL released.

Type:

Worker threads tracking paths, in a standalone solve and on each MPI rank. 0 = auto (every CPU this process may run on), 1 = serial (no thread pool), N = N threads. The BERTINI_NUM_THREADS environment variable overrides this. Threading needs no MPI and no free-threaded Python

property path_variable_name

The name given to the homotopy’s path variable. Read when the solver BUILDS its homotopy, so set it on a config you hand to a constructor. Setting it on a solver that already built one does not rename that homotopy’s path variable – the name is part of the run’s identity, so the two would then disagree; build a new solver instead. (If the name collides with one of your variables the solver mangles it to keep them apart, so the homotopy’s actual path variable may differ from what you asked for.)

set(**kwargs)

Set one or more fields at once; returns self so calls can chain.

Numeric fields accept strings (e.g. max_step_size=”0.05”), which are converted exactly to multiprecision values. Raises AttributeError on an unknown/misspelled field name.

property start_time

The time value at which the homotopy starts (where the start solutions live).

property target_time

The time value the homotopy tracks to (where the solutions of interest live).

to_dict()

The config’s fields as an ordinary dict of {name: value}.

update(**kwargs)

Set one or more fields at once; returns self so calls can chain.

Numeric fields accept strings (e.g. max_step_size=”0.05”), which are converted exactly to multiprecision values. Raises AttributeError on an unknown/misspelled field name.

class bertini.nag_algorithm.ZeroDimSolverCauchyAdaptivePrecision((object)arg1, (bertini._pybertini.system.System)arg2)

Bases: AnyZeroDim

__init__( (object)arg1, (bertini._pybertini.system.System)system, (StartSystemFactory)start_factory) -> None

__init__((object)arg1, (bertini._pybertini.system.System)arg2) → None

__init__( (object)arg1, (bertini._pybertini.system.System)system, (StartSystemFactory)start_factory) -> None

add_observer((object)self, (object)observer) → None :

Attach an observer to this observable object

all_solutions((ZeroDimSolverCauchyAdaptivePrecision)self[, (bool)user_coords=True]) → bertini._pybertini.container.ListOfVectorComplexVariablePrecision :

get ALL the computed solutions, one per tracked path (finite, at-infinity, and failed alike). by default they are in the coordinates of YOUR variables (dehomogenized, depatched). pass user_coords=False to decline, getting the solver’s internal coordinates instead: homogenized, lying on the target system’s patch – the representation to use for continuing work. the container is computed at most once per solve; repeated calls and indexing do not recompute it. for the filtered view see solutions(); for the at-infinity ones see infinite_solutions.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

config_names()

The keyword names accepted by configure() for this owner, its tracker and its endgame.

config_types((ZeroDimSolverCauchyAdaptivePrecision)self) → list :

List the configuration struct classes this object accepts.

configure(**kwargs)

Change settings on this owner’s configs in one call.

Each keyword names a config (e.g. stepping, newton, tolerances); its value is either a dict of fields to change, or a ready config object.

tracker.configure(stepping={‘max_step_size’: 0.1},

newton={‘max_num_newton_iterations’: 2})

Returns self.

default_point_match_tolerance((ZeroDimSolverCauchyAdaptivePrecision)arg1) → float :

the default infinity-norm tolerance metadata_for() uses when you omit tol: the solver’s final_tolerance (the accuracy each endpoint is computed to). Since metadata_for matches against representatives – which are at least the same-point clustering tolerance apart – this tight default still resolves a fed-back solution to itself while making an ambiguous match structurally impossible.

endgame_boundary_metadata((ZeroDimSolverCauchyAdaptivePrecision)arg1) → MidpathCheckReport :

get the MidpathCheckReport from the path-crossing check at the endgame boundary: how many crossings were detected, which paths, how many re-track attempts were made, and whether the check ultimately passed

endgame_boundary_solutions((ZeroDimSolverCauchyAdaptivePrecision)arg1) → bertini._pybertini.container.ListOfEGBoundaryMetaData_MultiPrec :

get the solutions (per-path point data) at the endgame boundary, where regular tracking switches to the endgame

finite_solutions((ZeroDimSolverCauchyAdaptivePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the FINITE solutions: successful endpoints the solver calls finite (is_finite applies endpoint_finite_threshold). includes singular, nonsingular, and real solutions alike. merge_multiplicities=True (default) collapses each multiple solution to one representative. user coordinates by default; user_coords=False for internal coordinates.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

get_config((ZeroDimSolverCauchyAdaptivePrecision)self, (object)config_type) → object :

Return a copy of this object’s stored configuration struct of the given class.

The named config, by class (TolerancesConfig) or by short name ('tolerances',

as config_names() lists them).

Either may belong to this object’s tracker or endgame rather than to the object itself (solver.get_config('stepping'), solver.get_config(EndgameConfig)); it is fetched from whichever holds it, so every name config_names() lists can be asked for.

get_endgame((ZeroDimSolverCauchyAdaptivePrecision)arg1) → bertini._pybertini.endgame.AMPCauchyEndgame :

get a mutable reference to the Endgame being used

get_settings(as_dict=False)

This owner’s whole configuration as a carryable dict.

By default (as_dict=False) the value is {config_name: config} – each a copy of one of the owner’s configs (e.g. {'stepping': SteppingConfig(...), 'tolerances': TolerancesConfig(...)}), keyed by the short names config_names() lists. The configs are independent copies (and picklable), so the dict is a plain Python value you can stash, tweak, and apply to other owners – the way to carry one set of tracking settings across a series of related solves:

settings = first_solver.get_settings()
next_solver.set_settings(settings)

Pass as_dict=True for the flat, human-readable view instead: one {field_name: value} dict across ALL configs (field names are unique across an owner’s configs, so there is no collision). That form drops the struct layer nobody wants to poke at, and round-trips through set:

flat = solver.get_settings(as_dict=True)   # {'final_tolerance': ..., 'max_step_size': ..., ...}
other.set(**flat)

(The config-keyed default is kept because set_settings consumes it; use whichever fits.) See set_settings() for applying the config-keyed form back.

get_tracker((ZeroDimSolverCauchyAdaptivePrecision)arg1) → bertini._pybertini.tracking.AMPTracker :

get a mutable reference to the Tracker being used

infinite_solutions((ZeroDimSolverCauchyAdaptivePrecision)self[, (bool)user_coords=True]) → list :

the solutions AT INFINITY: endpoints not classified finite (is_finite is False). these are the paths the endgame resolved as diverging – its GoingToInfinity / SecurityMaxNormReached verdict, or a successful endpoint whose dehomogenized infinity norm exceeds endpoint_finite_threshold. the complement of finite_solutions within all_solutions. NOTE a path that FAILED before the endgame also has is_finite False (its point is not a real solution at infinity); inspect solution_metadata()/report() to tell a true divergence from a tracking failure.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

metadata_for((ZeroDimSolverCauchyAdaptivePrecision)self, (numpy.ndarray)point[, (float)tol=-1.0[, (bool)coincident=False[, (bool)user_coords=True[, (bool)representatives_only=True]]]]) → object :

the SolutionMetaData for the solution matching point (issue #302). Matches by the infinity-norm tolerance tol (see is_distinct_up_to) against the multiplicity REPRESENTATIVES – one candidate per distinct solution. tol is OPTIONAL: omit it (or pass a non-positive value) to use default_point_match_tolerance() (the solver’s final_tolerance). Because representatives are at least the same-point tolerance apart and the default window is smaller, a pt taken straight from solutions() / real_solutions() / etc. (which return representatives) matches its own representative back and is NEVER reported ambiguous – feed a solver result straight back in and it Just Works. The return type NEVER depends on the point’s multiplicity: by default returns exactly ONE record – the multiplicity-cluster representative (it carries .multiplicity, so you still learn m). coincident=True instead ALWAYS returns a LIST of every coincident copy’s record (their per-path condition number / residual / precision), length 1 for a simple root. representatives_only=False matches against EVERY endpoint including non-representative multiplicity copies – a debugging view, rarely what you want. Raises if no solution matches within tol, or (only for a deliberately coarse tol) if the point matches more than one distinct cluster. point is in user coordinates unless user_coords=False. Accepts any numpy array of the solver’s complex type – which is exactly what the solution lists return.

nonsingular_solutions((ZeroDimSolverCauchyAdaptivePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the NONSINGULAR finite solutions (simple, well-conditioned roots). (Nonsingular solutions are simple, so merge_multiplicities is a no-op; kept for a uniform signature.)

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

nonsolutions((ZeroDimSolverCauchyAdaptivePrecision)self[, (bool)user_coords=True]) → list :

the NONSOLUTIONS: finite, successful endpoints that are NOT solutions of the target system – the extraneous nonsolutions a squared-up over-determined system introduces (empty otherwise). Excluded from finite_solutions/real/singular; a regeneration cascade reads these to discard them.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

num_paths((ZeroDimSolverCauchyAdaptivePrecision)self) → int :

How many paths this solve has to answer – the start system’s start point count. Known once a solve has begun its setup, which is before the first path event, and 0 before that.

num_paths_never_started((ZeroDimSolverCauchyAdaptivePrecision)self) → int :

How many paths the last solve() never began, because it was stopped first.

num_paths_recalled((ZeroDimSolverCauchyAdaptivePrecision)self) → int :

How many paths the last solve() recalled from the records instead of computing (0 on a fresh solve; num_paths on a full memo hit).

randomization_matrix((ZeroDimSolverCauchyAdaptivePrecision)arg1) → numpy.ndarray :

The exact n x N coefficient matrix used to square up an over-determined system (empty if the system was already square).

real_solutions((ZeroDimSolverCauchyAdaptivePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the REAL finite solutions (is_real applies the configured tolerance). merge_multiplicities=True (default) collapses each multiple solution to one representative.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

record_to((ZeroDimSolverCauchyAdaptivePrecision)self, (str)directory) → None :

Attach a structured output directory at the given path: this solve records every path as it completes (durable, plain-text, see the directory’s README.txt) and consults the records before computing – an identical ask (same system, settings, seed) recalls from the records instead of re-tracking, so a crashed solve resumes by simply calling solve() again. Recording is ON BY DEFAULT with no code at all: an unattached solver records to the ambient directory (BERTINI_RECORDS_DIR, else ./bertini_output; the value ‘none’ switches records off). record_to chooses the directory explicitly and always wins over the ambient resolution.

records_path((ZeroDimSolverCauchyAdaptivePrecision)self) → object :

The attached output directory’s path, or None when not recording.

records_run_id((ZeroDimSolverCauchyAdaptivePrecision)self) → str :

This solve’s run id in the records (empty until a recording solve() runs). Points are referenced as {run, index} pairs; this is the run half.

remove_observer((object)self, (object)observer) → None :

Remove an observer to this observable object

report((ZeroDimSolverCauchyAdaptivePrecision)arg1) → SolveReport :

a concise end-of-solve diagnostic summary (a SolveReport): how every path ended up – finite solutions, diverged, or FAILED (by named reason) – plus singular/real counts, max condition number, the path-crossing outcome, and all_paths_resolved. print(solver.report()) for a human-readable summary; a count alone can hide a path the tracker silently lost.

result()

This solve’s SolveResult: the finite solutions plus the records ticket (run id, directory, recall count), read from the solver’s own recorded state.

A bare solver.solve() already returns this; result() re-derives it (call it after solve()) if you did not keep the return value.

same_point_tolerance((ZeroDimSolverCauchyAdaptivePrecision)arg1) → float :

the same-point (clustering) tolerance, final_tolerance * same_point_tolerance_multiplier: the looser tolerance the solver uses to decide two endpoints are the SAME solution and cluster them into one multiplicity (and that metadata_for(coincident=True) uses to gather a cluster’s copies).

set(**fields)

Set config fields on this owner by NAME, each routed to whichever config owns it.

You never name the config struct:

solver.update(final_tolerance="1e-11",          # -> TolerancesConfig
              max_num_crossed_path_resolve_attempts=3)   # -> ZeroDimConfig

Strings work for every numeric field (converted exactly). A field that none of this owner’s configs has raises AttributeError with the valid names – so a typo, or trying to set a tracker field on the algorithm (or vice versa), never silently does nothing. Returns self, so calls chain. To set a whole config at once, or to name the config explicitly, use configure().

set_config((ZeroDimSolverCauchyAdaptivePrecision)self, (TolerancesConfig)config) → None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (ZeroDimSolverCauchyAdaptivePrecision)self, (PostProcessingConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (ZeroDimSolverCauchyAdaptivePrecision)self, (ZeroDimConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (ZeroDimSolverCauchyAdaptivePrecision)self, (AutoRetrackConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (ZeroDimSolverCauchyAdaptivePrecision)self, (RecordsConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (ZeroDimSolverCauchyAdaptivePrecision)self, (MidPathConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

Store a configuration struct, on this object or on whichever of its tracker and

endgame owns that config’s type.

set_recorded_start_provenance((ZeroDimSolverCauchyAdaptivePrecision)self, (str)refs_json, (str)start_identity) → None :

Declare where this solve’s start points came from, for the records: a JSON array with one reference object per path ({‘kind’:’point_ref’,’run’:…,’index’:…} for a chain from a prior run, {‘kind’:’given_ref’,’given’:…,’index’:…} for external data), plus an identity string for the start data (it joins the ask: same homotopy, different starts = different computation). Call before solve().

set_settings(settings, strict=False)

Apply a settings dict (from get_settings()) onto this owner. Returns self.

settings is {config_name: config} (or {config_name: {field: value}}). By default only the configs this owner actually has are applied and the rest are skipped – so a bundle carried from one solver drops cleanly onto another whose config set differs (e.g. a different precision model, or a different algorithm stage). Pass strict=True to instead raise on any key this owner does not have.

singular_solutions((ZeroDimSolverCauchyAdaptivePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the SINGULAR finite solutions (multiple or ill-conditioned roots). merge_multiplicities=True (default) collapses each multiple solution to one representative.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

solution_metadata((ZeroDimSolverCauchyAdaptivePrecision)arg1) → bertini._pybertini.container.ListOfSolutionMetaData_MultiPrec :

get the metadata for the solutions at the target time

solutions((ZeroDimSolverCauchyAdaptivePrecision)self[, (bool)singular=True[, (bool)real=True[, (bool)nonreal=True[, (bool)nonsingular=True[, (bool)infinite=False[, (bool)nonsolution=False[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]]]]]]]) → list :

the solutions, filtered by category (returns points, not metadata). By DEFAULT every finite genuine solution – real and complex, simple and multiple – and nothing else. Each keyword toggles a category: singular / nonsingular select by conditioning, real / nonreal by realness (a finite solution is returned only if BOTH its conditioning class and its realness class are enabled), infinite=True also returns the at-infinity endpoints, and nonsolution=True also returns the nonsolutions. E.g. solutions(real=False) -> complex finite solutions only; solutions(singular=False) -> nonsingular finite solutions; solutions(infinite=True) adds the divergent paths. merge_multiplicities=True (the DEFAULT) collapses a multiplicity-m solution to its single representative (pass False to get all m coincident copies). user_coords=False gives the solver’s internal coordinates. See also real_solutions / nonsingular_solutions / singular_solutions / infinite_solutions / nonsolutions for the common single-category views, and all_solutions for the raw per-path list.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

solve((ZeroDimSolverCauchyAdaptivePrecision)arg1[, (object)communicator=None]) → None :

Run the zero-dim algorithm. Pass an mpi4py communicator for parallel execution.

Settings: pass config fields either as a dict (settings={‘final_tolerance’: 1e-13}) or by keyword (solve(final_tolerance=1e-13)); each is applied via set() before solving, so make/set/solve becomes a single call. communicator= is reserved for MPI (never a setting).

show_progress=True (the default) reports how far the solve has got. It draws nothing unless the solve runs past a few seconds AND stderr is a terminal, so scripts, pipelines and test runs see nothing; pass show_progress=False to be certain of silence.

Returns a bertini.records.SolveResult – the finite solutions plus this solve’s records ticket (run id, directory, recall count), read from the solver’s own records (the solver records itself, on by default). Drop it freely: solver.result() re-derives it, and the records hold the truth.

target_system((ZeroDimSolverCauchyAdaptivePrecision)arg1) → bertini._pybertini.system.System :

get the prepared target system: the homogenized, auto-patched clone of the system you supplied. its patch is the one internal-coordinate solutions lie on; use its dehomogenize_point/homogenize_point/variable_ordering to move between representations.

to_classic_input((ZeroDimSolverCauchyAdaptivePrecision)self, (bertini._pybertini.system.System)system) → str :

emit a complete Bertini 1 classic input file (CONFIG + INPUT) for the given natural system, using THIS solver’s tracking settings for the CONFIG: precision mode (mptype), ODE predictor, tolerances (before/during endgame, final), the full step-size cadence, max Newton iterations, and the crossed-path resolve cap. The system you pass supplies INPUT – pass the natural (un-homogenized) system you constructed the solver from, since the solver homogenizes and patches its internal copy. Use this to re-run the exact same problem with the exact same knobs in Bertini 1 for cross-validation (the random start system aside). For sweeping settings without a solver, see system.to_classic_input(**kwargs).

to_dataframe(*, user_coords=True, omit_infinite=True, merge_multiplicities=True, group=None)

The solve as a pandas DataFrame – one row per solution, the “database of solutions”.

Columns are solution – the whole solution point, kept in a single cell – then every per-solution metadata field (is_finite, is_real, is_singular, multiplicity, condition_number, endgame_success_code, max_precision_used, …), and finally system, a reference to the (target) system these solutions satisfy (so rows accumulated from several solves stay identifiable). Each category is then a one-line filter, e.g. df[df.is_real & ~df.is_singular] (nonsingular real) or df[~df.is_finite] (at infinity).

The solution cell is an independent copy of the solution vector (a numpy array of Python complex for a double solve, of bertini.complex_mp for a multiprecision one, so no precision is lost). Coordinates are deliberately not exploded into x0, x1, ... columns; split them yourself if you want them, e.g. df['x'] = [v[0] for v in df.solution].

Parameters:
  • user_coords (bool) – Coordinates in YOUR variables (dehomogenized; default), or the solver’s internal homogenized on-patch coordinates when False – the same choice as all_solutions().

  • omit_infinite (bool) – Drop the endpoints not classified finite (is_finite False) – the at-infinity and failed paths. True by default, so the frame holds just the genuine finite solutions; pass False to get every tracked path (their coordinate cells may be empty/NaN).

  • merge_multiplicities (bool) – Collapse a multiplicity-m solution – which the solver returns as m coincident endpoints – to its single representative row (multiplicity still records m). True by default. Pass False to keep every endpoint, including the m-1 duplicate copies. The grouping is the solver’s own (the C++ clustering that computes multiplicity), read off multiplicity_representative; this does not re-cluster.

  • group (VariableGroup or int, optional) – Project each solution onto one variable group – the solution cell then holds only that group’s coordinates (Cluster G). Pass the VariableGroup object or its 0-based FIFO index. None (default) keeps the whole point.

Returns:

One row per solution; the solution cell is a copied vector whose elements are Python complex for a double-precision solve and bertini.complex_mp for a multiprecision one (kept native, so no precision is lost).

Return type:

pandas.DataFrame

Notes

pandas is an optional dependency; this raises ImportError if it is absent. The point accessors – all_solutions(), finite_solutions(), solution_metadata() – are the no-pandas path.

update(**fields)

Set config fields on this owner by NAME, each routed to whichever config owns it.

You never name the config struct:

solver.update(final_tolerance="1e-11",          # -> TolerancesConfig
              max_num_crossed_path_resolve_attempts=3)   # -> ZeroDimConfig

Strings work for every numeric field (converted exactly). A field that none of this owner’s configs has raises AttributeError with the valid names – so a typo, or trying to set a tracker field on the algorithm (or vice versa), never silently does nothing. Returns self, so calls chain. To set a whole config at once, or to name the config explicitly, use configure().

was_randomized((ZeroDimSolverCauchyAdaptivePrecision)arg1) → bool :

True if the supplied system was over-determined and was squared up by randomization (so the extraneous solutions the squaring introduces have been filtered out of finite_solutions). False for a square system.

was_stopped_early((ZeroDimSolverCauchyAdaptivePrecision)self) → bool :

Was the last solve() stopped before it finished – by Ctrl-C, or by request_stop()? If so the results are a PARTIAL set: paths in flight were abandoned and read SuccessCode.ExternallyTerminated, paths not yet begun still read NeverStarted, and every count derived from them describes only what was tracked. Re-running the same solve recalls the finished paths from the records and tracks only the rest.

class bertini.nag_algorithm.ZeroDimSolverCauchyDoublePrecision((object)arg1, (bertini._pybertini.system.System)arg2)

Bases: AnyZeroDim

__init__( (object)arg1, (bertini._pybertini.system.System)system, (StartSystemFactory)start_factory) -> None

__init__((object)arg1, (bertini._pybertini.system.System)arg2) → None

__init__( (object)arg1, (bertini._pybertini.system.System)system, (StartSystemFactory)start_factory) -> None

add_observer((object)self, (object)observer) → None :

Attach an observer to this observable object

all_solutions((ZeroDimSolverCauchyDoublePrecision)self[, (bool)user_coords=True]) → bertini._pybertini.container.ListOfVectorComplexDoublePrecision :

get ALL the computed solutions, one per tracked path (finite, at-infinity, and failed alike). by default they are in the coordinates of YOUR variables (dehomogenized, depatched). pass user_coords=False to decline, getting the solver’s internal coordinates instead: homogenized, lying on the target system’s patch – the representation to use for continuing work. the container is computed at most once per solve; repeated calls and indexing do not recompute it. for the filtered view see solutions(); for the at-infinity ones see infinite_solutions.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

config_names()

The keyword names accepted by configure() for this owner, its tracker and its endgame.

config_types((ZeroDimSolverCauchyDoublePrecision)self) → list :

List the configuration struct classes this object accepts.

configure(**kwargs)

Change settings on this owner’s configs in one call.

Each keyword names a config (e.g. stepping, newton, tolerances); its value is either a dict of fields to change, or a ready config object.

tracker.configure(stepping={‘max_step_size’: 0.1},

newton={‘max_num_newton_iterations’: 2})

Returns self.

default_point_match_tolerance((ZeroDimSolverCauchyDoublePrecision)arg1) → float :

the default infinity-norm tolerance metadata_for() uses when you omit tol: the solver’s final_tolerance (the accuracy each endpoint is computed to). Since metadata_for matches against representatives – which are at least the same-point clustering tolerance apart – this tight default still resolves a fed-back solution to itself while making an ambiguous match structurally impossible.

endgame_boundary_metadata((ZeroDimSolverCauchyDoublePrecision)arg1) → MidpathCheckReport :

get the MidpathCheckReport from the path-crossing check at the endgame boundary: how many crossings were detected, which paths, how many re-track attempts were made, and whether the check ultimately passed

endgame_boundary_solutions((ZeroDimSolverCauchyDoublePrecision)arg1) → bertini._pybertini.container.ListOfEGBoundaryMetaData_DoublePrec :

get the solutions (per-path point data) at the endgame boundary, where regular tracking switches to the endgame

finite_solutions((ZeroDimSolverCauchyDoublePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the FINITE solutions: successful endpoints the solver calls finite (is_finite applies endpoint_finite_threshold). includes singular, nonsingular, and real solutions alike. merge_multiplicities=True (default) collapses each multiple solution to one representative. user coordinates by default; user_coords=False for internal coordinates.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

get_config((ZeroDimSolverCauchyDoublePrecision)self, (object)config_type) → object :

Return a copy of this object’s stored configuration struct of the given class.

The named config, by class (TolerancesConfig) or by short name ('tolerances',

as config_names() lists them).

Either may belong to this object’s tracker or endgame rather than to the object itself (solver.get_config('stepping'), solver.get_config(EndgameConfig)); it is fetched from whichever holds it, so every name config_names() lists can be asked for.

get_endgame((ZeroDimSolverCauchyDoublePrecision)arg1) → bertini._pybertini.endgame.FixedDoubleCauchyEndgame :

get a mutable reference to the Endgame being used

get_settings(as_dict=False)

This owner’s whole configuration as a carryable dict.

By default (as_dict=False) the value is {config_name: config} – each a copy of one of the owner’s configs (e.g. {'stepping': SteppingConfig(...), 'tolerances': TolerancesConfig(...)}), keyed by the short names config_names() lists. The configs are independent copies (and picklable), so the dict is a plain Python value you can stash, tweak, and apply to other owners – the way to carry one set of tracking settings across a series of related solves:

settings = first_solver.get_settings()
next_solver.set_settings(settings)

Pass as_dict=True for the flat, human-readable view instead: one {field_name: value} dict across ALL configs (field names are unique across an owner’s configs, so there is no collision). That form drops the struct layer nobody wants to poke at, and round-trips through set:

flat = solver.get_settings(as_dict=True)   # {'final_tolerance': ..., 'max_step_size': ..., ...}
other.set(**flat)

(The config-keyed default is kept because set_settings consumes it; use whichever fits.) See set_settings() for applying the config-keyed form back.

get_tracker((ZeroDimSolverCauchyDoublePrecision)arg1) → bertini._pybertini.tracking.DoublePrecisionTracker :

get a mutable reference to the Tracker being used

infinite_solutions((ZeroDimSolverCauchyDoublePrecision)self[, (bool)user_coords=True]) → list :

the solutions AT INFINITY: endpoints not classified finite (is_finite is False). these are the paths the endgame resolved as diverging – its GoingToInfinity / SecurityMaxNormReached verdict, or a successful endpoint whose dehomogenized infinity norm exceeds endpoint_finite_threshold. the complement of finite_solutions within all_solutions. NOTE a path that FAILED before the endgame also has is_finite False (its point is not a real solution at infinity); inspect solution_metadata()/report() to tell a true divergence from a tracking failure.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

metadata_for((ZeroDimSolverCauchyDoublePrecision)self, (numpy.ndarray)point[, (float)tol=-1.0[, (bool)coincident=False[, (bool)user_coords=True[, (bool)representatives_only=True]]]]) → object :

the SolutionMetaData for the solution matching point (issue #302). Matches by the infinity-norm tolerance tol (see is_distinct_up_to) against the multiplicity REPRESENTATIVES – one candidate per distinct solution. tol is OPTIONAL: omit it (or pass a non-positive value) to use default_point_match_tolerance() (the solver’s final_tolerance). Because representatives are at least the same-point tolerance apart and the default window is smaller, a pt taken straight from solutions() / real_solutions() / etc. (which return representatives) matches its own representative back and is NEVER reported ambiguous – feed a solver result straight back in and it Just Works. The return type NEVER depends on the point’s multiplicity: by default returns exactly ONE record – the multiplicity-cluster representative (it carries .multiplicity, so you still learn m). coincident=True instead ALWAYS returns a LIST of every coincident copy’s record (their per-path condition number / residual / precision), length 1 for a simple root. representatives_only=False matches against EVERY endpoint including non-representative multiplicity copies – a debugging view, rarely what you want. Raises if no solution matches within tol, or (only for a deliberately coarse tol) if the point matches more than one distinct cluster. point is in user coordinates unless user_coords=False. Accepts any numpy array of the solver’s complex type – which is exactly what the solution lists return.

nonsingular_solutions((ZeroDimSolverCauchyDoublePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the NONSINGULAR finite solutions (simple, well-conditioned roots). (Nonsingular solutions are simple, so merge_multiplicities is a no-op; kept for a uniform signature.)

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

nonsolutions((ZeroDimSolverCauchyDoublePrecision)self[, (bool)user_coords=True]) → list :

the NONSOLUTIONS: finite, successful endpoints that are NOT solutions of the target system – the extraneous nonsolutions a squared-up over-determined system introduces (empty otherwise). Excluded from finite_solutions/real/singular; a regeneration cascade reads these to discard them.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

num_paths((ZeroDimSolverCauchyDoublePrecision)self) → int :

How many paths this solve has to answer – the start system’s start point count. Known once a solve has begun its setup, which is before the first path event, and 0 before that.

num_paths_never_started((ZeroDimSolverCauchyDoublePrecision)self) → int :

How many paths the last solve() never began, because it was stopped first.

num_paths_recalled((ZeroDimSolverCauchyDoublePrecision)self) → int :

How many paths the last solve() recalled from the records instead of computing (0 on a fresh solve; num_paths on a full memo hit).

randomization_matrix((ZeroDimSolverCauchyDoublePrecision)arg1) → numpy.ndarray :

The exact n x N coefficient matrix used to square up an over-determined system (empty if the system was already square).

real_solutions((ZeroDimSolverCauchyDoublePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the REAL finite solutions (is_real applies the configured tolerance). merge_multiplicities=True (default) collapses each multiple solution to one representative.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

record_to((ZeroDimSolverCauchyDoublePrecision)self, (str)directory) → None :

Attach a structured output directory at the given path: this solve records every path as it completes (durable, plain-text, see the directory’s README.txt) and consults the records before computing – an identical ask (same system, settings, seed) recalls from the records instead of re-tracking, so a crashed solve resumes by simply calling solve() again. Recording is ON BY DEFAULT with no code at all: an unattached solver records to the ambient directory (BERTINI_RECORDS_DIR, else ./bertini_output; the value ‘none’ switches records off). record_to chooses the directory explicitly and always wins over the ambient resolution.

records_path((ZeroDimSolverCauchyDoublePrecision)self) → object :

The attached output directory’s path, or None when not recording.

records_run_id((ZeroDimSolverCauchyDoublePrecision)self) → str :

This solve’s run id in the records (empty until a recording solve() runs). Points are referenced as {run, index} pairs; this is the run half.

remove_observer((object)self, (object)observer) → None :

Remove an observer to this observable object

report((ZeroDimSolverCauchyDoublePrecision)arg1) → SolveReport :

a concise end-of-solve diagnostic summary (a SolveReport): how every path ended up – finite solutions, diverged, or FAILED (by named reason) – plus singular/real counts, max condition number, the path-crossing outcome, and all_paths_resolved. print(solver.report()) for a human-readable summary; a count alone can hide a path the tracker silently lost.

result()

This solve’s SolveResult: the finite solutions plus the records ticket (run id, directory, recall count), read from the solver’s own recorded state.

A bare solver.solve() already returns this; result() re-derives it (call it after solve()) if you did not keep the return value.

same_point_tolerance((ZeroDimSolverCauchyDoublePrecision)arg1) → float :

the same-point (clustering) tolerance, final_tolerance * same_point_tolerance_multiplier: the looser tolerance the solver uses to decide two endpoints are the SAME solution and cluster them into one multiplicity (and that metadata_for(coincident=True) uses to gather a cluster’s copies).

set(**fields)

Set config fields on this owner by NAME, each routed to whichever config owns it.

You never name the config struct:

solver.update(final_tolerance="1e-11",          # -> TolerancesConfig
              max_num_crossed_path_resolve_attempts=3)   # -> ZeroDimConfig

Strings work for every numeric field (converted exactly). A field that none of this owner’s configs has raises AttributeError with the valid names – so a typo, or trying to set a tracker field on the algorithm (or vice versa), never silently does nothing. Returns self, so calls chain. To set a whole config at once, or to name the config explicitly, use configure().

set_config((ZeroDimSolverCauchyDoublePrecision)self, (TolerancesConfig)config) → None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (ZeroDimSolverCauchyDoublePrecision)self, (PostProcessingConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (ZeroDimSolverCauchyDoublePrecision)self, (ZeroDimConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (ZeroDimSolverCauchyDoublePrecision)self, (AutoRetrackConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (ZeroDimSolverCauchyDoublePrecision)self, (RecordsConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (ZeroDimSolverCauchyDoublePrecision)self, (MidPathConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

Store a configuration struct, on this object or on whichever of its tracker and

endgame owns that config’s type.

set_recorded_start_provenance((ZeroDimSolverCauchyDoublePrecision)self, (str)refs_json, (str)start_identity) → None :

Declare where this solve’s start points came from, for the records: a JSON array with one reference object per path ({‘kind’:’point_ref’,’run’:…,’index’:…} for a chain from a prior run, {‘kind’:’given_ref’,’given’:…,’index’:…} for external data), plus an identity string for the start data (it joins the ask: same homotopy, different starts = different computation). Call before solve().

set_settings(settings, strict=False)

Apply a settings dict (from get_settings()) onto this owner. Returns self.

settings is {config_name: config} (or {config_name: {field: value}}). By default only the configs this owner actually has are applied and the rest are skipped – so a bundle carried from one solver drops cleanly onto another whose config set differs (e.g. a different precision model, or a different algorithm stage). Pass strict=True to instead raise on any key this owner does not have.

singular_solutions((ZeroDimSolverCauchyDoublePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the SINGULAR finite solutions (multiple or ill-conditioned roots). merge_multiplicities=True (default) collapses each multiple solution to one representative.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

solution_metadata((ZeroDimSolverCauchyDoublePrecision)arg1) → bertini._pybertini.container.ListOfSolutionMetaData_DoublePrec :

get the metadata for the solutions at the target time

solutions((ZeroDimSolverCauchyDoublePrecision)self[, (bool)singular=True[, (bool)real=True[, (bool)nonreal=True[, (bool)nonsingular=True[, (bool)infinite=False[, (bool)nonsolution=False[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]]]]]]]) → list :

the solutions, filtered by category (returns points, not metadata). By DEFAULT every finite genuine solution – real and complex, simple and multiple – and nothing else. Each keyword toggles a category: singular / nonsingular select by conditioning, real / nonreal by realness (a finite solution is returned only if BOTH its conditioning class and its realness class are enabled), infinite=True also returns the at-infinity endpoints, and nonsolution=True also returns the nonsolutions. E.g. solutions(real=False) -> complex finite solutions only; solutions(singular=False) -> nonsingular finite solutions; solutions(infinite=True) adds the divergent paths. merge_multiplicities=True (the DEFAULT) collapses a multiplicity-m solution to its single representative (pass False to get all m coincident copies). user_coords=False gives the solver’s internal coordinates. See also real_solutions / nonsingular_solutions / singular_solutions / infinite_solutions / nonsolutions for the common single-category views, and all_solutions for the raw per-path list.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

solve((ZeroDimSolverCauchyDoublePrecision)arg1[, (object)communicator=None]) → None :

Run the zero-dim algorithm. Pass an mpi4py communicator for parallel execution.

Settings: pass config fields either as a dict (settings={‘final_tolerance’: 1e-13}) or by keyword (solve(final_tolerance=1e-13)); each is applied via set() before solving, so make/set/solve becomes a single call. communicator= is reserved for MPI (never a setting).

show_progress=True (the default) reports how far the solve has got. It draws nothing unless the solve runs past a few seconds AND stderr is a terminal, so scripts, pipelines and test runs see nothing; pass show_progress=False to be certain of silence.

Returns a bertini.records.SolveResult – the finite solutions plus this solve’s records ticket (run id, directory, recall count), read from the solver’s own records (the solver records itself, on by default). Drop it freely: solver.result() re-derives it, and the records hold the truth.

target_system((ZeroDimSolverCauchyDoublePrecision)arg1) → bertini._pybertini.system.System :

get the prepared target system: the homogenized, auto-patched clone of the system you supplied. its patch is the one internal-coordinate solutions lie on; use its dehomogenize_point/homogenize_point/variable_ordering to move between representations.

to_classic_input((ZeroDimSolverCauchyDoublePrecision)self, (bertini._pybertini.system.System)system) → str :

emit a complete Bertini 1 classic input file (CONFIG + INPUT) for the given natural system, using THIS solver’s tracking settings for the CONFIG: precision mode (mptype), ODE predictor, tolerances (before/during endgame, final), the full step-size cadence, max Newton iterations, and the crossed-path resolve cap. The system you pass supplies INPUT – pass the natural (un-homogenized) system you constructed the solver from, since the solver homogenizes and patches its internal copy. Use this to re-run the exact same problem with the exact same knobs in Bertini 1 for cross-validation (the random start system aside). For sweeping settings without a solver, see system.to_classic_input(**kwargs).

to_dataframe(*, user_coords=True, omit_infinite=True, merge_multiplicities=True, group=None)

The solve as a pandas DataFrame – one row per solution, the “database of solutions”.

Columns are solution – the whole solution point, kept in a single cell – then every per-solution metadata field (is_finite, is_real, is_singular, multiplicity, condition_number, endgame_success_code, max_precision_used, …), and finally system, a reference to the (target) system these solutions satisfy (so rows accumulated from several solves stay identifiable). Each category is then a one-line filter, e.g. df[df.is_real & ~df.is_singular] (nonsingular real) or df[~df.is_finite] (at infinity).

The solution cell is an independent copy of the solution vector (a numpy array of Python complex for a double solve, of bertini.complex_mp for a multiprecision one, so no precision is lost). Coordinates are deliberately not exploded into x0, x1, ... columns; split them yourself if you want them, e.g. df['x'] = [v[0] for v in df.solution].

Parameters:
  • user_coords (bool) – Coordinates in YOUR variables (dehomogenized; default), or the solver’s internal homogenized on-patch coordinates when False – the same choice as all_solutions().

  • omit_infinite (bool) – Drop the endpoints not classified finite (is_finite False) – the at-infinity and failed paths. True by default, so the frame holds just the genuine finite solutions; pass False to get every tracked path (their coordinate cells may be empty/NaN).

  • merge_multiplicities (bool) – Collapse a multiplicity-m solution – which the solver returns as m coincident endpoints – to its single representative row (multiplicity still records m). True by default. Pass False to keep every endpoint, including the m-1 duplicate copies. The grouping is the solver’s own (the C++ clustering that computes multiplicity), read off multiplicity_representative; this does not re-cluster.

  • group (VariableGroup or int, optional) – Project each solution onto one variable group – the solution cell then holds only that group’s coordinates (Cluster G). Pass the VariableGroup object or its 0-based FIFO index. None (default) keeps the whole point.

Returns:

One row per solution; the solution cell is a copied vector whose elements are Python complex for a double-precision solve and bertini.complex_mp for a multiprecision one (kept native, so no precision is lost).

Return type:

pandas.DataFrame

Notes

pandas is an optional dependency; this raises ImportError if it is absent. The point accessors – all_solutions(), finite_solutions(), solution_metadata() – are the no-pandas path.

update(**fields)

Set config fields on this owner by NAME, each routed to whichever config owns it.

You never name the config struct:

solver.update(final_tolerance="1e-11",          # -> TolerancesConfig
              max_num_crossed_path_resolve_attempts=3)   # -> ZeroDimConfig

Strings work for every numeric field (converted exactly). A field that none of this owner’s configs has raises AttributeError with the valid names – so a typo, or trying to set a tracker field on the algorithm (or vice versa), never silently does nothing. Returns self, so calls chain. To set a whole config at once, or to name the config explicitly, use configure().

was_randomized((ZeroDimSolverCauchyDoublePrecision)arg1) → bool :

True if the supplied system was over-determined and was squared up by randomization (so the extraneous solutions the squaring introduces have been filtered out of finite_solutions). False for a square system.

was_stopped_early((ZeroDimSolverCauchyDoublePrecision)self) → bool :

Was the last solve() stopped before it finished – by Ctrl-C, or by request_stop()? If so the results are a PARTIAL set: paths in flight were abandoned and read SuccessCode.ExternallyTerminated, paths not yet begun still read NeverStarted, and every count derived from them describes only what was tracked. Re-running the same solve recalls the finished paths from the records and tracks only the rest.

class bertini.nag_algorithm.ZeroDimSolverCauchyFixedMultiplePrecision((object)arg1, (bertini._pybertini.system.System)arg2)

Bases: AnyZeroDim

__init__( (object)arg1, (bertini._pybertini.system.System)system, (StartSystemFactory)start_factory) -> None

__init__((object)arg1, (bertini._pybertini.system.System)arg2) → None

__init__( (object)arg1, (bertini._pybertini.system.System)system, (StartSystemFactory)start_factory) -> None

add_observer((object)self, (object)observer) → None :

Attach an observer to this observable object

all_solutions((ZeroDimSolverCauchyFixedMultiplePrecision)self[, (bool)user_coords=True]) → bertini._pybertini.container.ListOfVectorComplexVariablePrecision :

get ALL the computed solutions, one per tracked path (finite, at-infinity, and failed alike). by default they are in the coordinates of YOUR variables (dehomogenized, depatched). pass user_coords=False to decline, getting the solver’s internal coordinates instead: homogenized, lying on the target system’s patch – the representation to use for continuing work. the container is computed at most once per solve; repeated calls and indexing do not recompute it. for the filtered view see solutions(); for the at-infinity ones see infinite_solutions.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

config_names()

The keyword names accepted by configure() for this owner, its tracker and its endgame.

config_types((ZeroDimSolverCauchyFixedMultiplePrecision)self) → list :

List the configuration struct classes this object accepts.

configure(**kwargs)

Change settings on this owner’s configs in one call.

Each keyword names a config (e.g. stepping, newton, tolerances); its value is either a dict of fields to change, or a ready config object.

tracker.configure(stepping={‘max_step_size’: 0.1},

newton={‘max_num_newton_iterations’: 2})

Returns self.

default_point_match_tolerance((ZeroDimSolverCauchyFixedMultiplePrecision)arg1) → float :

the default infinity-norm tolerance metadata_for() uses when you omit tol: the solver’s final_tolerance (the accuracy each endpoint is computed to). Since metadata_for matches against representatives – which are at least the same-point clustering tolerance apart – this tight default still resolves a fed-back solution to itself while making an ambiguous match structurally impossible.

endgame_boundary_metadata((ZeroDimSolverCauchyFixedMultiplePrecision)arg1) → MidpathCheckReport :

get the MidpathCheckReport from the path-crossing check at the endgame boundary: how many crossings were detected, which paths, how many re-track attempts were made, and whether the check ultimately passed

endgame_boundary_solutions((ZeroDimSolverCauchyFixedMultiplePrecision)arg1) → bertini._pybertini.container.ListOfEGBoundaryMetaData_MultiPrec :

get the solutions (per-path point data) at the endgame boundary, where regular tracking switches to the endgame

finite_solutions((ZeroDimSolverCauchyFixedMultiplePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the FINITE solutions: successful endpoints the solver calls finite (is_finite applies endpoint_finite_threshold). includes singular, nonsingular, and real solutions alike. merge_multiplicities=True (default) collapses each multiple solution to one representative. user coordinates by default; user_coords=False for internal coordinates.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

get_config((ZeroDimSolverCauchyFixedMultiplePrecision)self, (object)config_type) → object :

Return a copy of this object’s stored configuration struct of the given class.

The named config, by class (TolerancesConfig) or by short name ('tolerances',

as config_names() lists them).

Either may belong to this object’s tracker or endgame rather than to the object itself (solver.get_config('stepping'), solver.get_config(EndgameConfig)); it is fetched from whichever holds it, so every name config_names() lists can be asked for.

get_endgame((ZeroDimSolverCauchyFixedMultiplePrecision)arg1) → bertini._pybertini.endgame.FixedMultipleCauchyEndgame :

get a mutable reference to the Endgame being used

get_settings(as_dict=False)

This owner’s whole configuration as a carryable dict.

By default (as_dict=False) the value is {config_name: config} – each a copy of one of the owner’s configs (e.g. {'stepping': SteppingConfig(...), 'tolerances': TolerancesConfig(...)}), keyed by the short names config_names() lists. The configs are independent copies (and picklable), so the dict is a plain Python value you can stash, tweak, and apply to other owners – the way to carry one set of tracking settings across a series of related solves:

settings = first_solver.get_settings()
next_solver.set_settings(settings)

Pass as_dict=True for the flat, human-readable view instead: one {field_name: value} dict across ALL configs (field names are unique across an owner’s configs, so there is no collision). That form drops the struct layer nobody wants to poke at, and round-trips through set:

flat = solver.get_settings(as_dict=True)   # {'final_tolerance': ..., 'max_step_size': ..., ...}
other.set(**flat)

(The config-keyed default is kept because set_settings consumes it; use whichever fits.) See set_settings() for applying the config-keyed form back.

get_tracker((ZeroDimSolverCauchyFixedMultiplePrecision)arg1) → bertini._pybertini.tracking.MultiplePrecisionTracker :

get a mutable reference to the Tracker being used

infinite_solutions((ZeroDimSolverCauchyFixedMultiplePrecision)self[, (bool)user_coords=True]) → list :

the solutions AT INFINITY: endpoints not classified finite (is_finite is False). these are the paths the endgame resolved as diverging – its GoingToInfinity / SecurityMaxNormReached verdict, or a successful endpoint whose dehomogenized infinity norm exceeds endpoint_finite_threshold. the complement of finite_solutions within all_solutions. NOTE a path that FAILED before the endgame also has is_finite False (its point is not a real solution at infinity); inspect solution_metadata()/report() to tell a true divergence from a tracking failure.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

metadata_for((ZeroDimSolverCauchyFixedMultiplePrecision)self, (numpy.ndarray)point[, (float)tol=-1.0[, (bool)coincident=False[, (bool)user_coords=True[, (bool)representatives_only=True]]]]) → object :

the SolutionMetaData for the solution matching point (issue #302). Matches by the infinity-norm tolerance tol (see is_distinct_up_to) against the multiplicity REPRESENTATIVES – one candidate per distinct solution. tol is OPTIONAL: omit it (or pass a non-positive value) to use default_point_match_tolerance() (the solver’s final_tolerance). Because representatives are at least the same-point tolerance apart and the default window is smaller, a pt taken straight from solutions() / real_solutions() / etc. (which return representatives) matches its own representative back and is NEVER reported ambiguous – feed a solver result straight back in and it Just Works. The return type NEVER depends on the point’s multiplicity: by default returns exactly ONE record – the multiplicity-cluster representative (it carries .multiplicity, so you still learn m). coincident=True instead ALWAYS returns a LIST of every coincident copy’s record (their per-path condition number / residual / precision), length 1 for a simple root. representatives_only=False matches against EVERY endpoint including non-representative multiplicity copies – a debugging view, rarely what you want. Raises if no solution matches within tol, or (only for a deliberately coarse tol) if the point matches more than one distinct cluster. point is in user coordinates unless user_coords=False. Accepts any numpy array of the solver’s complex type – which is exactly what the solution lists return.

nonsingular_solutions((ZeroDimSolverCauchyFixedMultiplePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the NONSINGULAR finite solutions (simple, well-conditioned roots). (Nonsingular solutions are simple, so merge_multiplicities is a no-op; kept for a uniform signature.)

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

nonsolutions((ZeroDimSolverCauchyFixedMultiplePrecision)self[, (bool)user_coords=True]) → list :

the NONSOLUTIONS: finite, successful endpoints that are NOT solutions of the target system – the extraneous nonsolutions a squared-up over-determined system introduces (empty otherwise). Excluded from finite_solutions/real/singular; a regeneration cascade reads these to discard them.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

num_paths((ZeroDimSolverCauchyFixedMultiplePrecision)self) → int :

How many paths this solve has to answer – the start system’s start point count. Known once a solve has begun its setup, which is before the first path event, and 0 before that.

num_paths_never_started((ZeroDimSolverCauchyFixedMultiplePrecision)self) → int :

How many paths the last solve() never began, because it was stopped first.

num_paths_recalled((ZeroDimSolverCauchyFixedMultiplePrecision)self) → int :

How many paths the last solve() recalled from the records instead of computing (0 on a fresh solve; num_paths on a full memo hit).

randomization_matrix((ZeroDimSolverCauchyFixedMultiplePrecision)arg1) → numpy.ndarray :

The exact n x N coefficient matrix used to square up an over-determined system (empty if the system was already square).

real_solutions((ZeroDimSolverCauchyFixedMultiplePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the REAL finite solutions (is_real applies the configured tolerance). merge_multiplicities=True (default) collapses each multiple solution to one representative.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

record_to((ZeroDimSolverCauchyFixedMultiplePrecision)self, (str)directory) → None :

Attach a structured output directory at the given path: this solve records every path as it completes (durable, plain-text, see the directory’s README.txt) and consults the records before computing – an identical ask (same system, settings, seed) recalls from the records instead of re-tracking, so a crashed solve resumes by simply calling solve() again. Recording is ON BY DEFAULT with no code at all: an unattached solver records to the ambient directory (BERTINI_RECORDS_DIR, else ./bertini_output; the value ‘none’ switches records off). record_to chooses the directory explicitly and always wins over the ambient resolution.

records_path((ZeroDimSolverCauchyFixedMultiplePrecision)self) → object :

The attached output directory’s path, or None when not recording.

records_run_id((ZeroDimSolverCauchyFixedMultiplePrecision)self) → str :

This solve’s run id in the records (empty until a recording solve() runs). Points are referenced as {run, index} pairs; this is the run half.

remove_observer((object)self, (object)observer) → None :

Remove an observer to this observable object

report((ZeroDimSolverCauchyFixedMultiplePrecision)arg1) → SolveReport :

a concise end-of-solve diagnostic summary (a SolveReport): how every path ended up – finite solutions, diverged, or FAILED (by named reason) – plus singular/real counts, max condition number, the path-crossing outcome, and all_paths_resolved. print(solver.report()) for a human-readable summary; a count alone can hide a path the tracker silently lost.

result()

This solve’s SolveResult: the finite solutions plus the records ticket (run id, directory, recall count), read from the solver’s own recorded state.

A bare solver.solve() already returns this; result() re-derives it (call it after solve()) if you did not keep the return value.

same_point_tolerance((ZeroDimSolverCauchyFixedMultiplePrecision)arg1) → float :

the same-point (clustering) tolerance, final_tolerance * same_point_tolerance_multiplier: the looser tolerance the solver uses to decide two endpoints are the SAME solution and cluster them into one multiplicity (and that metadata_for(coincident=True) uses to gather a cluster’s copies).

set(**fields)

Set config fields on this owner by NAME, each routed to whichever config owns it.

You never name the config struct:

solver.update(final_tolerance="1e-11",          # -> TolerancesConfig
              max_num_crossed_path_resolve_attempts=3)   # -> ZeroDimConfig

Strings work for every numeric field (converted exactly). A field that none of this owner’s configs has raises AttributeError with the valid names – so a typo, or trying to set a tracker field on the algorithm (or vice versa), never silently does nothing. Returns self, so calls chain. To set a whole config at once, or to name the config explicitly, use configure().

set_config((ZeroDimSolverCauchyFixedMultiplePrecision)self, (TolerancesConfig)config) → None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (ZeroDimSolverCauchyFixedMultiplePrecision)self, (PostProcessingConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (ZeroDimSolverCauchyFixedMultiplePrecision)self, (ZeroDimConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (ZeroDimSolverCauchyFixedMultiplePrecision)self, (AutoRetrackConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (ZeroDimSolverCauchyFixedMultiplePrecision)self, (RecordsConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (ZeroDimSolverCauchyFixedMultiplePrecision)self, (MidPathConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

Store a configuration struct, on this object or on whichever of its tracker and

endgame owns that config’s type.

set_recorded_start_provenance((ZeroDimSolverCauchyFixedMultiplePrecision)self, (str)refs_json, (str)start_identity) → None :

Declare where this solve’s start points came from, for the records: a JSON array with one reference object per path ({‘kind’:’point_ref’,’run’:…,’index’:…} for a chain from a prior run, {‘kind’:’given_ref’,’given’:…,’index’:…} for external data), plus an identity string for the start data (it joins the ask: same homotopy, different starts = different computation). Call before solve().

set_settings(settings, strict=False)

Apply a settings dict (from get_settings()) onto this owner. Returns self.

settings is {config_name: config} (or {config_name: {field: value}}). By default only the configs this owner actually has are applied and the rest are skipped – so a bundle carried from one solver drops cleanly onto another whose config set differs (e.g. a different precision model, or a different algorithm stage). Pass strict=True to instead raise on any key this owner does not have.

singular_solutions((ZeroDimSolverCauchyFixedMultiplePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the SINGULAR finite solutions (multiple or ill-conditioned roots). merge_multiplicities=True (default) collapses each multiple solution to one representative.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

solution_metadata((ZeroDimSolverCauchyFixedMultiplePrecision)arg1) → bertini._pybertini.container.ListOfSolutionMetaData_MultiPrec :

get the metadata for the solutions at the target time

solutions((ZeroDimSolverCauchyFixedMultiplePrecision)self[, (bool)singular=True[, (bool)real=True[, (bool)nonreal=True[, (bool)nonsingular=True[, (bool)infinite=False[, (bool)nonsolution=False[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]]]]]]]) → list :

the solutions, filtered by category (returns points, not metadata). By DEFAULT every finite genuine solution – real and complex, simple and multiple – and nothing else. Each keyword toggles a category: singular / nonsingular select by conditioning, real / nonreal by realness (a finite solution is returned only if BOTH its conditioning class and its realness class are enabled), infinite=True also returns the at-infinity endpoints, and nonsolution=True also returns the nonsolutions. E.g. solutions(real=False) -> complex finite solutions only; solutions(singular=False) -> nonsingular finite solutions; solutions(infinite=True) adds the divergent paths. merge_multiplicities=True (the DEFAULT) collapses a multiplicity-m solution to its single representative (pass False to get all m coincident copies). user_coords=False gives the solver’s internal coordinates. See also real_solutions / nonsingular_solutions / singular_solutions / infinite_solutions / nonsolutions for the common single-category views, and all_solutions for the raw per-path list.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

solve((ZeroDimSolverCauchyFixedMultiplePrecision)arg1[, (object)communicator=None]) → None :

Run the zero-dim algorithm. Pass an mpi4py communicator for parallel execution.

Settings: pass config fields either as a dict (settings={‘final_tolerance’: 1e-13}) or by keyword (solve(final_tolerance=1e-13)); each is applied via set() before solving, so make/set/solve becomes a single call. communicator= is reserved for MPI (never a setting).

show_progress=True (the default) reports how far the solve has got. It draws nothing unless the solve runs past a few seconds AND stderr is a terminal, so scripts, pipelines and test runs see nothing; pass show_progress=False to be certain of silence.

Returns a bertini.records.SolveResult – the finite solutions plus this solve’s records ticket (run id, directory, recall count), read from the solver’s own records (the solver records itself, on by default). Drop it freely: solver.result() re-derives it, and the records hold the truth.

target_system((ZeroDimSolverCauchyFixedMultiplePrecision)arg1) → bertini._pybertini.system.System :

get the prepared target system: the homogenized, auto-patched clone of the system you supplied. its patch is the one internal-coordinate solutions lie on; use its dehomogenize_point/homogenize_point/variable_ordering to move between representations.

to_classic_input((ZeroDimSolverCauchyFixedMultiplePrecision)self, (bertini._pybertini.system.System)system) → str :

emit a complete Bertini 1 classic input file (CONFIG + INPUT) for the given natural system, using THIS solver’s tracking settings for the CONFIG: precision mode (mptype), ODE predictor, tolerances (before/during endgame, final), the full step-size cadence, max Newton iterations, and the crossed-path resolve cap. The system you pass supplies INPUT – pass the natural (un-homogenized) system you constructed the solver from, since the solver homogenizes and patches its internal copy. Use this to re-run the exact same problem with the exact same knobs in Bertini 1 for cross-validation (the random start system aside). For sweeping settings without a solver, see system.to_classic_input(**kwargs).

to_dataframe(*, user_coords=True, omit_infinite=True, merge_multiplicities=True, group=None)

The solve as a pandas DataFrame – one row per solution, the “database of solutions”.

Columns are solution – the whole solution point, kept in a single cell – then every per-solution metadata field (is_finite, is_real, is_singular, multiplicity, condition_number, endgame_success_code, max_precision_used, …), and finally system, a reference to the (target) system these solutions satisfy (so rows accumulated from several solves stay identifiable). Each category is then a one-line filter, e.g. df[df.is_real & ~df.is_singular] (nonsingular real) or df[~df.is_finite] (at infinity).

The solution cell is an independent copy of the solution vector (a numpy array of Python complex for a double solve, of bertini.complex_mp for a multiprecision one, so no precision is lost). Coordinates are deliberately not exploded into x0, x1, ... columns; split them yourself if you want them, e.g. df['x'] = [v[0] for v in df.solution].

Parameters:
  • user_coords (bool) – Coordinates in YOUR variables (dehomogenized; default), or the solver’s internal homogenized on-patch coordinates when False – the same choice as all_solutions().

  • omit_infinite (bool) – Drop the endpoints not classified finite (is_finite False) – the at-infinity and failed paths. True by default, so the frame holds just the genuine finite solutions; pass False to get every tracked path (their coordinate cells may be empty/NaN).

  • merge_multiplicities (bool) – Collapse a multiplicity-m solution – which the solver returns as m coincident endpoints – to its single representative row (multiplicity still records m). True by default. Pass False to keep every endpoint, including the m-1 duplicate copies. The grouping is the solver’s own (the C++ clustering that computes multiplicity), read off multiplicity_representative; this does not re-cluster.

  • group (VariableGroup or int, optional) – Project each solution onto one variable group – the solution cell then holds only that group’s coordinates (Cluster G). Pass the VariableGroup object or its 0-based FIFO index. None (default) keeps the whole point.

Returns:

One row per solution; the solution cell is a copied vector whose elements are Python complex for a double-precision solve and bertini.complex_mp for a multiprecision one (kept native, so no precision is lost).

Return type:

pandas.DataFrame

Notes

pandas is an optional dependency; this raises ImportError if it is absent. The point accessors – all_solutions(), finite_solutions(), solution_metadata() – are the no-pandas path.

update(**fields)

Set config fields on this owner by NAME, each routed to whichever config owns it.

You never name the config struct:

solver.update(final_tolerance="1e-11",          # -> TolerancesConfig
              max_num_crossed_path_resolve_attempts=3)   # -> ZeroDimConfig

Strings work for every numeric field (converted exactly). A field that none of this owner’s configs has raises AttributeError with the valid names – so a typo, or trying to set a tracker field on the algorithm (or vice versa), never silently does nothing. Returns self, so calls chain. To set a whole config at once, or to name the config explicitly, use configure().

was_randomized((ZeroDimSolverCauchyFixedMultiplePrecision)arg1) → bool :

True if the supplied system was over-determined and was squared up by randomization (so the extraneous solutions the squaring introduces have been filtered out of finite_solutions). False for a square system.

was_stopped_early((ZeroDimSolverCauchyFixedMultiplePrecision)self) → bool :

Was the last solve() stopped before it finished – by Ctrl-C, or by request_stop()? If so the results are a PARTIAL set: paths in flight were abandoned and read SuccessCode.ExternallyTerminated, paths not yet begun still read NeverStarted, and every count derived from them describes only what was tracked. Re-running the same solve recalls the finished paths from the records and tracks only the rest.

class bertini.nag_algorithm.ZeroDimSolverPowerSeriesAdaptivePrecision((object)arg1, (bertini._pybertini.system.System)arg2)

Bases: AnyZeroDim

__init__( (object)arg1, (bertini._pybertini.system.System)system, (StartSystemFactory)start_factory) -> None

__init__((object)arg1, (bertini._pybertini.system.System)arg2) → None

__init__( (object)arg1, (bertini._pybertini.system.System)system, (StartSystemFactory)start_factory) -> None

add_observer((object)self, (object)observer) → None :

Attach an observer to this observable object

all_solutions((ZeroDimSolverPowerSeriesAdaptivePrecision)self[, (bool)user_coords=True]) → bertini._pybertini.container.ListOfVectorComplexVariablePrecision :

get ALL the computed solutions, one per tracked path (finite, at-infinity, and failed alike). by default they are in the coordinates of YOUR variables (dehomogenized, depatched). pass user_coords=False to decline, getting the solver’s internal coordinates instead: homogenized, lying on the target system’s patch – the representation to use for continuing work. the container is computed at most once per solve; repeated calls and indexing do not recompute it. for the filtered view see solutions(); for the at-infinity ones see infinite_solutions.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

config_names()

The keyword names accepted by configure() for this owner, its tracker and its endgame.

config_types((ZeroDimSolverPowerSeriesAdaptivePrecision)self) → list :

List the configuration struct classes this object accepts.

configure(**kwargs)

Change settings on this owner’s configs in one call.

Each keyword names a config (e.g. stepping, newton, tolerances); its value is either a dict of fields to change, or a ready config object.

tracker.configure(stepping={‘max_step_size’: 0.1},

newton={‘max_num_newton_iterations’: 2})

Returns self.

default_point_match_tolerance((ZeroDimSolverPowerSeriesAdaptivePrecision)arg1) → float :

the default infinity-norm tolerance metadata_for() uses when you omit tol: the solver’s final_tolerance (the accuracy each endpoint is computed to). Since metadata_for matches against representatives – which are at least the same-point clustering tolerance apart – this tight default still resolves a fed-back solution to itself while making an ambiguous match structurally impossible.

endgame_boundary_metadata((ZeroDimSolverPowerSeriesAdaptivePrecision)arg1) → MidpathCheckReport :

get the MidpathCheckReport from the path-crossing check at the endgame boundary: how many crossings were detected, which paths, how many re-track attempts were made, and whether the check ultimately passed

endgame_boundary_solutions((ZeroDimSolverPowerSeriesAdaptivePrecision)arg1) → bertini._pybertini.container.ListOfEGBoundaryMetaData_MultiPrec :

get the solutions (per-path point data) at the endgame boundary, where regular tracking switches to the endgame

finite_solutions((ZeroDimSolverPowerSeriesAdaptivePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the FINITE solutions: successful endpoints the solver calls finite (is_finite applies endpoint_finite_threshold). includes singular, nonsingular, and real solutions alike. merge_multiplicities=True (default) collapses each multiple solution to one representative. user coordinates by default; user_coords=False for internal coordinates.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

get_config((ZeroDimSolverPowerSeriesAdaptivePrecision)self, (object)config_type) → object :

Return a copy of this object’s stored configuration struct of the given class.

The named config, by class (TolerancesConfig) or by short name ('tolerances',

as config_names() lists them).

Either may belong to this object’s tracker or endgame rather than to the object itself (solver.get_config('stepping'), solver.get_config(EndgameConfig)); it is fetched from whichever holds it, so every name config_names() lists can be asked for.

get_endgame((ZeroDimSolverPowerSeriesAdaptivePrecision)arg1) → bertini._pybertini.endgame.AMPPowerSeriesEndgame :

get a mutable reference to the Endgame being used

get_settings(as_dict=False)

This owner’s whole configuration as a carryable dict.

By default (as_dict=False) the value is {config_name: config} – each a copy of one of the owner’s configs (e.g. {'stepping': SteppingConfig(...), 'tolerances': TolerancesConfig(...)}), keyed by the short names config_names() lists. The configs are independent copies (and picklable), so the dict is a plain Python value you can stash, tweak, and apply to other owners – the way to carry one set of tracking settings across a series of related solves:

settings = first_solver.get_settings()
next_solver.set_settings(settings)

Pass as_dict=True for the flat, human-readable view instead: one {field_name: value} dict across ALL configs (field names are unique across an owner’s configs, so there is no collision). That form drops the struct layer nobody wants to poke at, and round-trips through set:

flat = solver.get_settings(as_dict=True)   # {'final_tolerance': ..., 'max_step_size': ..., ...}
other.set(**flat)

(The config-keyed default is kept because set_settings consumes it; use whichever fits.) See set_settings() for applying the config-keyed form back.

get_tracker((ZeroDimSolverPowerSeriesAdaptivePrecision)arg1) → bertini._pybertini.tracking.AMPTracker :

get a mutable reference to the Tracker being used

infinite_solutions((ZeroDimSolverPowerSeriesAdaptivePrecision)self[, (bool)user_coords=True]) → list :

the solutions AT INFINITY: endpoints not classified finite (is_finite is False). these are the paths the endgame resolved as diverging – its GoingToInfinity / SecurityMaxNormReached verdict, or a successful endpoint whose dehomogenized infinity norm exceeds endpoint_finite_threshold. the complement of finite_solutions within all_solutions. NOTE a path that FAILED before the endgame also has is_finite False (its point is not a real solution at infinity); inspect solution_metadata()/report() to tell a true divergence from a tracking failure.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

metadata_for((ZeroDimSolverPowerSeriesAdaptivePrecision)self, (numpy.ndarray)point[, (float)tol=-1.0[, (bool)coincident=False[, (bool)user_coords=True[, (bool)representatives_only=True]]]]) → object :

the SolutionMetaData for the solution matching point (issue #302). Matches by the infinity-norm tolerance tol (see is_distinct_up_to) against the multiplicity REPRESENTATIVES – one candidate per distinct solution. tol is OPTIONAL: omit it (or pass a non-positive value) to use default_point_match_tolerance() (the solver’s final_tolerance). Because representatives are at least the same-point tolerance apart and the default window is smaller, a pt taken straight from solutions() / real_solutions() / etc. (which return representatives) matches its own representative back and is NEVER reported ambiguous – feed a solver result straight back in and it Just Works. The return type NEVER depends on the point’s multiplicity: by default returns exactly ONE record – the multiplicity-cluster representative (it carries .multiplicity, so you still learn m). coincident=True instead ALWAYS returns a LIST of every coincident copy’s record (their per-path condition number / residual / precision), length 1 for a simple root. representatives_only=False matches against EVERY endpoint including non-representative multiplicity copies – a debugging view, rarely what you want. Raises if no solution matches within tol, or (only for a deliberately coarse tol) if the point matches more than one distinct cluster. point is in user coordinates unless user_coords=False. Accepts any numpy array of the solver’s complex type – which is exactly what the solution lists return.

nonsingular_solutions((ZeroDimSolverPowerSeriesAdaptivePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the NONSINGULAR finite solutions (simple, well-conditioned roots). (Nonsingular solutions are simple, so merge_multiplicities is a no-op; kept for a uniform signature.)

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

nonsolutions((ZeroDimSolverPowerSeriesAdaptivePrecision)self[, (bool)user_coords=True]) → list :

the NONSOLUTIONS: finite, successful endpoints that are NOT solutions of the target system – the extraneous nonsolutions a squared-up over-determined system introduces (empty otherwise). Excluded from finite_solutions/real/singular; a regeneration cascade reads these to discard them.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

num_paths((ZeroDimSolverPowerSeriesAdaptivePrecision)self) → int :

How many paths this solve has to answer – the start system’s start point count. Known once a solve has begun its setup, which is before the first path event, and 0 before that.

num_paths_never_started((ZeroDimSolverPowerSeriesAdaptivePrecision)self) → int :

How many paths the last solve() never began, because it was stopped first.

num_paths_recalled((ZeroDimSolverPowerSeriesAdaptivePrecision)self) → int :

How many paths the last solve() recalled from the records instead of computing (0 on a fresh solve; num_paths on a full memo hit).

randomization_matrix((ZeroDimSolverPowerSeriesAdaptivePrecision)arg1) → numpy.ndarray :

The exact n x N coefficient matrix used to square up an over-determined system (empty if the system was already square).

real_solutions((ZeroDimSolverPowerSeriesAdaptivePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the REAL finite solutions (is_real applies the configured tolerance). merge_multiplicities=True (default) collapses each multiple solution to one representative.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

record_to((ZeroDimSolverPowerSeriesAdaptivePrecision)self, (str)directory) → None :

Attach a structured output directory at the given path: this solve records every path as it completes (durable, plain-text, see the directory’s README.txt) and consults the records before computing – an identical ask (same system, settings, seed) recalls from the records instead of re-tracking, so a crashed solve resumes by simply calling solve() again. Recording is ON BY DEFAULT with no code at all: an unattached solver records to the ambient directory (BERTINI_RECORDS_DIR, else ./bertini_output; the value ‘none’ switches records off). record_to chooses the directory explicitly and always wins over the ambient resolution.

records_path((ZeroDimSolverPowerSeriesAdaptivePrecision)self) → object :

The attached output directory’s path, or None when not recording.

records_run_id((ZeroDimSolverPowerSeriesAdaptivePrecision)self) → str :

This solve’s run id in the records (empty until a recording solve() runs). Points are referenced as {run, index} pairs; this is the run half.

remove_observer((object)self, (object)observer) → None :

Remove an observer to this observable object

report((ZeroDimSolverPowerSeriesAdaptivePrecision)arg1) → SolveReport :

a concise end-of-solve diagnostic summary (a SolveReport): how every path ended up – finite solutions, diverged, or FAILED (by named reason) – plus singular/real counts, max condition number, the path-crossing outcome, and all_paths_resolved. print(solver.report()) for a human-readable summary; a count alone can hide a path the tracker silently lost.

result()

This solve’s SolveResult: the finite solutions plus the records ticket (run id, directory, recall count), read from the solver’s own recorded state.

A bare solver.solve() already returns this; result() re-derives it (call it after solve()) if you did not keep the return value.

same_point_tolerance((ZeroDimSolverPowerSeriesAdaptivePrecision)arg1) → float :

the same-point (clustering) tolerance, final_tolerance * same_point_tolerance_multiplier: the looser tolerance the solver uses to decide two endpoints are the SAME solution and cluster them into one multiplicity (and that metadata_for(coincident=True) uses to gather a cluster’s copies).

set(**fields)

Set config fields on this owner by NAME, each routed to whichever config owns it.

You never name the config struct:

solver.update(final_tolerance="1e-11",          # -> TolerancesConfig
              max_num_crossed_path_resolve_attempts=3)   # -> ZeroDimConfig

Strings work for every numeric field (converted exactly). A field that none of this owner’s configs has raises AttributeError with the valid names – so a typo, or trying to set a tracker field on the algorithm (or vice versa), never silently does nothing. Returns self, so calls chain. To set a whole config at once, or to name the config explicitly, use configure().

set_config((ZeroDimSolverPowerSeriesAdaptivePrecision)self, (TolerancesConfig)config) → None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (ZeroDimSolverPowerSeriesAdaptivePrecision)self, (PostProcessingConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (ZeroDimSolverPowerSeriesAdaptivePrecision)self, (ZeroDimConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (ZeroDimSolverPowerSeriesAdaptivePrecision)self, (AutoRetrackConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (ZeroDimSolverPowerSeriesAdaptivePrecision)self, (RecordsConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (ZeroDimSolverPowerSeriesAdaptivePrecision)self, (MidPathConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

Store a configuration struct, on this object or on whichever of its tracker and

endgame owns that config’s type.

set_recorded_start_provenance((ZeroDimSolverPowerSeriesAdaptivePrecision)self, (str)refs_json, (str)start_identity) → None :

Declare where this solve’s start points came from, for the records: a JSON array with one reference object per path ({‘kind’:’point_ref’,’run’:…,’index’:…} for a chain from a prior run, {‘kind’:’given_ref’,’given’:…,’index’:…} for external data), plus an identity string for the start data (it joins the ask: same homotopy, different starts = different computation). Call before solve().

set_settings(settings, strict=False)

Apply a settings dict (from get_settings()) onto this owner. Returns self.

settings is {config_name: config} (or {config_name: {field: value}}). By default only the configs this owner actually has are applied and the rest are skipped – so a bundle carried from one solver drops cleanly onto another whose config set differs (e.g. a different precision model, or a different algorithm stage). Pass strict=True to instead raise on any key this owner does not have.

singular_solutions((ZeroDimSolverPowerSeriesAdaptivePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the SINGULAR finite solutions (multiple or ill-conditioned roots). merge_multiplicities=True (default) collapses each multiple solution to one representative.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

solution_metadata((ZeroDimSolverPowerSeriesAdaptivePrecision)arg1) → bertini._pybertini.container.ListOfSolutionMetaData_MultiPrec :

get the metadata for the solutions at the target time

solutions((ZeroDimSolverPowerSeriesAdaptivePrecision)self[, (bool)singular=True[, (bool)real=True[, (bool)nonreal=True[, (bool)nonsingular=True[, (bool)infinite=False[, (bool)nonsolution=False[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]]]]]]]) → list :

the solutions, filtered by category (returns points, not metadata). By DEFAULT every finite genuine solution – real and complex, simple and multiple – and nothing else. Each keyword toggles a category: singular / nonsingular select by conditioning, real / nonreal by realness (a finite solution is returned only if BOTH its conditioning class and its realness class are enabled), infinite=True also returns the at-infinity endpoints, and nonsolution=True also returns the nonsolutions. E.g. solutions(real=False) -> complex finite solutions only; solutions(singular=False) -> nonsingular finite solutions; solutions(infinite=True) adds the divergent paths. merge_multiplicities=True (the DEFAULT) collapses a multiplicity-m solution to its single representative (pass False to get all m coincident copies). user_coords=False gives the solver’s internal coordinates. See also real_solutions / nonsingular_solutions / singular_solutions / infinite_solutions / nonsolutions for the common single-category views, and all_solutions for the raw per-path list.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

solve((ZeroDimSolverPowerSeriesAdaptivePrecision)arg1[, (object)communicator=None]) → None :

Run the zero-dim algorithm. Pass an mpi4py communicator for parallel execution.

Settings: pass config fields either as a dict (settings={‘final_tolerance’: 1e-13}) or by keyword (solve(final_tolerance=1e-13)); each is applied via set() before solving, so make/set/solve becomes a single call. communicator= is reserved for MPI (never a setting).

show_progress=True (the default) reports how far the solve has got. It draws nothing unless the solve runs past a few seconds AND stderr is a terminal, so scripts, pipelines and test runs see nothing; pass show_progress=False to be certain of silence.

Returns a bertini.records.SolveResult – the finite solutions plus this solve’s records ticket (run id, directory, recall count), read from the solver’s own records (the solver records itself, on by default). Drop it freely: solver.result() re-derives it, and the records hold the truth.

target_system((ZeroDimSolverPowerSeriesAdaptivePrecision)arg1) → bertini._pybertini.system.System :

get the prepared target system: the homogenized, auto-patched clone of the system you supplied. its patch is the one internal-coordinate solutions lie on; use its dehomogenize_point/homogenize_point/variable_ordering to move between representations.

to_classic_input((ZeroDimSolverPowerSeriesAdaptivePrecision)self, (bertini._pybertini.system.System)system) → str :

emit a complete Bertini 1 classic input file (CONFIG + INPUT) for the given natural system, using THIS solver’s tracking settings for the CONFIG: precision mode (mptype), ODE predictor, tolerances (before/during endgame, final), the full step-size cadence, max Newton iterations, and the crossed-path resolve cap. The system you pass supplies INPUT – pass the natural (un-homogenized) system you constructed the solver from, since the solver homogenizes and patches its internal copy. Use this to re-run the exact same problem with the exact same knobs in Bertini 1 for cross-validation (the random start system aside). For sweeping settings without a solver, see system.to_classic_input(**kwargs).

to_dataframe(*, user_coords=True, omit_infinite=True, merge_multiplicities=True, group=None)

The solve as a pandas DataFrame – one row per solution, the “database of solutions”.

Columns are solution – the whole solution point, kept in a single cell – then every per-solution metadata field (is_finite, is_real, is_singular, multiplicity, condition_number, endgame_success_code, max_precision_used, …), and finally system, a reference to the (target) system these solutions satisfy (so rows accumulated from several solves stay identifiable). Each category is then a one-line filter, e.g. df[df.is_real & ~df.is_singular] (nonsingular real) or df[~df.is_finite] (at infinity).

The solution cell is an independent copy of the solution vector (a numpy array of Python complex for a double solve, of bertini.complex_mp for a multiprecision one, so no precision is lost). Coordinates are deliberately not exploded into x0, x1, ... columns; split them yourself if you want them, e.g. df['x'] = [v[0] for v in df.solution].

Parameters:
  • user_coords (bool) – Coordinates in YOUR variables (dehomogenized; default), or the solver’s internal homogenized on-patch coordinates when False – the same choice as all_solutions().

  • omit_infinite (bool) – Drop the endpoints not classified finite (is_finite False) – the at-infinity and failed paths. True by default, so the frame holds just the genuine finite solutions; pass False to get every tracked path (their coordinate cells may be empty/NaN).

  • merge_multiplicities (bool) – Collapse a multiplicity-m solution – which the solver returns as m coincident endpoints – to its single representative row (multiplicity still records m). True by default. Pass False to keep every endpoint, including the m-1 duplicate copies. The grouping is the solver’s own (the C++ clustering that computes multiplicity), read off multiplicity_representative; this does not re-cluster.

  • group (VariableGroup or int, optional) – Project each solution onto one variable group – the solution cell then holds only that group’s coordinates (Cluster G). Pass the VariableGroup object or its 0-based FIFO index. None (default) keeps the whole point.

Returns:

One row per solution; the solution cell is a copied vector whose elements are Python complex for a double-precision solve and bertini.complex_mp for a multiprecision one (kept native, so no precision is lost).

Return type:

pandas.DataFrame

Notes

pandas is an optional dependency; this raises ImportError if it is absent. The point accessors – all_solutions(), finite_solutions(), solution_metadata() – are the no-pandas path.

update(**fields)

Set config fields on this owner by NAME, each routed to whichever config owns it.

You never name the config struct:

solver.update(final_tolerance="1e-11",          # -> TolerancesConfig
              max_num_crossed_path_resolve_attempts=3)   # -> ZeroDimConfig

Strings work for every numeric field (converted exactly). A field that none of this owner’s configs has raises AttributeError with the valid names – so a typo, or trying to set a tracker field on the algorithm (or vice versa), never silently does nothing. Returns self, so calls chain. To set a whole config at once, or to name the config explicitly, use configure().

was_randomized((ZeroDimSolverPowerSeriesAdaptivePrecision)arg1) → bool :

True if the supplied system was over-determined and was squared up by randomization (so the extraneous solutions the squaring introduces have been filtered out of finite_solutions). False for a square system.

was_stopped_early((ZeroDimSolverPowerSeriesAdaptivePrecision)self) → bool :

Was the last solve() stopped before it finished – by Ctrl-C, or by request_stop()? If so the results are a PARTIAL set: paths in flight were abandoned and read SuccessCode.ExternallyTerminated, paths not yet begun still read NeverStarted, and every count derived from them describes only what was tracked. Re-running the same solve recalls the finished paths from the records and tracks only the rest.

class bertini.nag_algorithm.ZeroDimSolverPowerSeriesDoublePrecision((object)arg1, (bertini._pybertini.system.System)arg2)

Bases: AnyZeroDim

__init__( (object)arg1, (bertini._pybertini.system.System)system, (StartSystemFactory)start_factory) -> None

__init__((object)arg1, (bertini._pybertini.system.System)arg2) → None

__init__( (object)arg1, (bertini._pybertini.system.System)system, (StartSystemFactory)start_factory) -> None

add_observer((object)self, (object)observer) → None :

Attach an observer to this observable object

all_solutions((ZeroDimSolverPowerSeriesDoublePrecision)self[, (bool)user_coords=True]) → bertini._pybertini.container.ListOfVectorComplexDoublePrecision :

get ALL the computed solutions, one per tracked path (finite, at-infinity, and failed alike). by default they are in the coordinates of YOUR variables (dehomogenized, depatched). pass user_coords=False to decline, getting the solver’s internal coordinates instead: homogenized, lying on the target system’s patch – the representation to use for continuing work. the container is computed at most once per solve; repeated calls and indexing do not recompute it. for the filtered view see solutions(); for the at-infinity ones see infinite_solutions.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

config_names()

The keyword names accepted by configure() for this owner, its tracker and its endgame.

config_types((ZeroDimSolverPowerSeriesDoublePrecision)self) → list :

List the configuration struct classes this object accepts.

configure(**kwargs)

Change settings on this owner’s configs in one call.

Each keyword names a config (e.g. stepping, newton, tolerances); its value is either a dict of fields to change, or a ready config object.

tracker.configure(stepping={‘max_step_size’: 0.1},

newton={‘max_num_newton_iterations’: 2})

Returns self.

default_point_match_tolerance((ZeroDimSolverPowerSeriesDoublePrecision)arg1) → float :

the default infinity-norm tolerance metadata_for() uses when you omit tol: the solver’s final_tolerance (the accuracy each endpoint is computed to). Since metadata_for matches against representatives – which are at least the same-point clustering tolerance apart – this tight default still resolves a fed-back solution to itself while making an ambiguous match structurally impossible.

endgame_boundary_metadata((ZeroDimSolverPowerSeriesDoublePrecision)arg1) → MidpathCheckReport :

get the MidpathCheckReport from the path-crossing check at the endgame boundary: how many crossings were detected, which paths, how many re-track attempts were made, and whether the check ultimately passed

endgame_boundary_solutions((ZeroDimSolverPowerSeriesDoublePrecision)arg1) → bertini._pybertini.container.ListOfEGBoundaryMetaData_DoublePrec :

get the solutions (per-path point data) at the endgame boundary, where regular tracking switches to the endgame

finite_solutions((ZeroDimSolverPowerSeriesDoublePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the FINITE solutions: successful endpoints the solver calls finite (is_finite applies endpoint_finite_threshold). includes singular, nonsingular, and real solutions alike. merge_multiplicities=True (default) collapses each multiple solution to one representative. user coordinates by default; user_coords=False for internal coordinates.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

get_config((ZeroDimSolverPowerSeriesDoublePrecision)self, (object)config_type) → object :

Return a copy of this object’s stored configuration struct of the given class.

The named config, by class (TolerancesConfig) or by short name ('tolerances',

as config_names() lists them).

Either may belong to this object’s tracker or endgame rather than to the object itself (solver.get_config('stepping'), solver.get_config(EndgameConfig)); it is fetched from whichever holds it, so every name config_names() lists can be asked for.

get_endgame((ZeroDimSolverPowerSeriesDoublePrecision)arg1) → bertini._pybertini.endgame.FixedDoublePowerSeriesEndgame :

get a mutable reference to the Endgame being used

get_settings(as_dict=False)

This owner’s whole configuration as a carryable dict.

By default (as_dict=False) the value is {config_name: config} – each a copy of one of the owner’s configs (e.g. {'stepping': SteppingConfig(...), 'tolerances': TolerancesConfig(...)}), keyed by the short names config_names() lists. The configs are independent copies (and picklable), so the dict is a plain Python value you can stash, tweak, and apply to other owners – the way to carry one set of tracking settings across a series of related solves:

settings = first_solver.get_settings()
next_solver.set_settings(settings)

Pass as_dict=True for the flat, human-readable view instead: one {field_name: value} dict across ALL configs (field names are unique across an owner’s configs, so there is no collision). That form drops the struct layer nobody wants to poke at, and round-trips through set:

flat = solver.get_settings(as_dict=True)   # {'final_tolerance': ..., 'max_step_size': ..., ...}
other.set(**flat)

(The config-keyed default is kept because set_settings consumes it; use whichever fits.) See set_settings() for applying the config-keyed form back.

get_tracker((ZeroDimSolverPowerSeriesDoublePrecision)arg1) → bertini._pybertini.tracking.DoublePrecisionTracker :

get a mutable reference to the Tracker being used

infinite_solutions((ZeroDimSolverPowerSeriesDoublePrecision)self[, (bool)user_coords=True]) → list :

the solutions AT INFINITY: endpoints not classified finite (is_finite is False). these are the paths the endgame resolved as diverging – its GoingToInfinity / SecurityMaxNormReached verdict, or a successful endpoint whose dehomogenized infinity norm exceeds endpoint_finite_threshold. the complement of finite_solutions within all_solutions. NOTE a path that FAILED before the endgame also has is_finite False (its point is not a real solution at infinity); inspect solution_metadata()/report() to tell a true divergence from a tracking failure.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

metadata_for((ZeroDimSolverPowerSeriesDoublePrecision)self, (numpy.ndarray)point[, (float)tol=-1.0[, (bool)coincident=False[, (bool)user_coords=True[, (bool)representatives_only=True]]]]) → object :

the SolutionMetaData for the solution matching point (issue #302). Matches by the infinity-norm tolerance tol (see is_distinct_up_to) against the multiplicity REPRESENTATIVES – one candidate per distinct solution. tol is OPTIONAL: omit it (or pass a non-positive value) to use default_point_match_tolerance() (the solver’s final_tolerance). Because representatives are at least the same-point tolerance apart and the default window is smaller, a pt taken straight from solutions() / real_solutions() / etc. (which return representatives) matches its own representative back and is NEVER reported ambiguous – feed a solver result straight back in and it Just Works. The return type NEVER depends on the point’s multiplicity: by default returns exactly ONE record – the multiplicity-cluster representative (it carries .multiplicity, so you still learn m). coincident=True instead ALWAYS returns a LIST of every coincident copy’s record (their per-path condition number / residual / precision), length 1 for a simple root. representatives_only=False matches against EVERY endpoint including non-representative multiplicity copies – a debugging view, rarely what you want. Raises if no solution matches within tol, or (only for a deliberately coarse tol) if the point matches more than one distinct cluster. point is in user coordinates unless user_coords=False. Accepts any numpy array of the solver’s complex type – which is exactly what the solution lists return.

nonsingular_solutions((ZeroDimSolverPowerSeriesDoublePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the NONSINGULAR finite solutions (simple, well-conditioned roots). (Nonsingular solutions are simple, so merge_multiplicities is a no-op; kept for a uniform signature.)

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

nonsolutions((ZeroDimSolverPowerSeriesDoublePrecision)self[, (bool)user_coords=True]) → list :

the NONSOLUTIONS: finite, successful endpoints that are NOT solutions of the target system – the extraneous nonsolutions a squared-up over-determined system introduces (empty otherwise). Excluded from finite_solutions/real/singular; a regeneration cascade reads these to discard them.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

num_paths((ZeroDimSolverPowerSeriesDoublePrecision)self) → int :

How many paths this solve has to answer – the start system’s start point count. Known once a solve has begun its setup, which is before the first path event, and 0 before that.

num_paths_never_started((ZeroDimSolverPowerSeriesDoublePrecision)self) → int :

How many paths the last solve() never began, because it was stopped first.

num_paths_recalled((ZeroDimSolverPowerSeriesDoublePrecision)self) → int :

How many paths the last solve() recalled from the records instead of computing (0 on a fresh solve; num_paths on a full memo hit).

randomization_matrix((ZeroDimSolverPowerSeriesDoublePrecision)arg1) → numpy.ndarray :

The exact n x N coefficient matrix used to square up an over-determined system (empty if the system was already square).

real_solutions((ZeroDimSolverPowerSeriesDoublePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the REAL finite solutions (is_real applies the configured tolerance). merge_multiplicities=True (default) collapses each multiple solution to one representative.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

record_to((ZeroDimSolverPowerSeriesDoublePrecision)self, (str)directory) → None :

Attach a structured output directory at the given path: this solve records every path as it completes (durable, plain-text, see the directory’s README.txt) and consults the records before computing – an identical ask (same system, settings, seed) recalls from the records instead of re-tracking, so a crashed solve resumes by simply calling solve() again. Recording is ON BY DEFAULT with no code at all: an unattached solver records to the ambient directory (BERTINI_RECORDS_DIR, else ./bertini_output; the value ‘none’ switches records off). record_to chooses the directory explicitly and always wins over the ambient resolution.

records_path((ZeroDimSolverPowerSeriesDoublePrecision)self) → object :

The attached output directory’s path, or None when not recording.

records_run_id((ZeroDimSolverPowerSeriesDoublePrecision)self) → str :

This solve’s run id in the records (empty until a recording solve() runs). Points are referenced as {run, index} pairs; this is the run half.

remove_observer((object)self, (object)observer) → None :

Remove an observer to this observable object

report((ZeroDimSolverPowerSeriesDoublePrecision)arg1) → SolveReport :

a concise end-of-solve diagnostic summary (a SolveReport): how every path ended up – finite solutions, diverged, or FAILED (by named reason) – plus singular/real counts, max condition number, the path-crossing outcome, and all_paths_resolved. print(solver.report()) for a human-readable summary; a count alone can hide a path the tracker silently lost.

result()

This solve’s SolveResult: the finite solutions plus the records ticket (run id, directory, recall count), read from the solver’s own recorded state.

A bare solver.solve() already returns this; result() re-derives it (call it after solve()) if you did not keep the return value.

same_point_tolerance((ZeroDimSolverPowerSeriesDoublePrecision)arg1) → float :

the same-point (clustering) tolerance, final_tolerance * same_point_tolerance_multiplier: the looser tolerance the solver uses to decide two endpoints are the SAME solution and cluster them into one multiplicity (and that metadata_for(coincident=True) uses to gather a cluster’s copies).

set(**fields)

Set config fields on this owner by NAME, each routed to whichever config owns it.

You never name the config struct:

solver.update(final_tolerance="1e-11",          # -> TolerancesConfig
              max_num_crossed_path_resolve_attempts=3)   # -> ZeroDimConfig

Strings work for every numeric field (converted exactly). A field that none of this owner’s configs has raises AttributeError with the valid names – so a typo, or trying to set a tracker field on the algorithm (or vice versa), never silently does nothing. Returns self, so calls chain. To set a whole config at once, or to name the config explicitly, use configure().

set_config((ZeroDimSolverPowerSeriesDoublePrecision)self, (TolerancesConfig)config) → None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (ZeroDimSolverPowerSeriesDoublePrecision)self, (PostProcessingConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (ZeroDimSolverPowerSeriesDoublePrecision)self, (ZeroDimConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (ZeroDimSolverPowerSeriesDoublePrecision)self, (AutoRetrackConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (ZeroDimSolverPowerSeriesDoublePrecision)self, (RecordsConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (ZeroDimSolverPowerSeriesDoublePrecision)self, (MidPathConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

Store a configuration struct, on this object or on whichever of its tracker and

endgame owns that config’s type.

set_recorded_start_provenance((ZeroDimSolverPowerSeriesDoublePrecision)self, (str)refs_json, (str)start_identity) → None :

Declare where this solve’s start points came from, for the records: a JSON array with one reference object per path ({‘kind’:’point_ref’,’run’:…,’index’:…} for a chain from a prior run, {‘kind’:’given_ref’,’given’:…,’index’:…} for external data), plus an identity string for the start data (it joins the ask: same homotopy, different starts = different computation). Call before solve().

set_settings(settings, strict=False)

Apply a settings dict (from get_settings()) onto this owner. Returns self.

settings is {config_name: config} (or {config_name: {field: value}}). By default only the configs this owner actually has are applied and the rest are skipped – so a bundle carried from one solver drops cleanly onto another whose config set differs (e.g. a different precision model, or a different algorithm stage). Pass strict=True to instead raise on any key this owner does not have.

singular_solutions((ZeroDimSolverPowerSeriesDoublePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the SINGULAR finite solutions (multiple or ill-conditioned roots). merge_multiplicities=True (default) collapses each multiple solution to one representative.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

solution_metadata((ZeroDimSolverPowerSeriesDoublePrecision)arg1) → bertini._pybertini.container.ListOfSolutionMetaData_DoublePrec :

get the metadata for the solutions at the target time

solutions((ZeroDimSolverPowerSeriesDoublePrecision)self[, (bool)singular=True[, (bool)real=True[, (bool)nonreal=True[, (bool)nonsingular=True[, (bool)infinite=False[, (bool)nonsolution=False[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]]]]]]]) → list :

the solutions, filtered by category (returns points, not metadata). By DEFAULT every finite genuine solution – real and complex, simple and multiple – and nothing else. Each keyword toggles a category: singular / nonsingular select by conditioning, real / nonreal by realness (a finite solution is returned only if BOTH its conditioning class and its realness class are enabled), infinite=True also returns the at-infinity endpoints, and nonsolution=True also returns the nonsolutions. E.g. solutions(real=False) -> complex finite solutions only; solutions(singular=False) -> nonsingular finite solutions; solutions(infinite=True) adds the divergent paths. merge_multiplicities=True (the DEFAULT) collapses a multiplicity-m solution to its single representative (pass False to get all m coincident copies). user_coords=False gives the solver’s internal coordinates. See also real_solutions / nonsingular_solutions / singular_solutions / infinite_solutions / nonsolutions for the common single-category views, and all_solutions for the raw per-path list.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

solve((ZeroDimSolverPowerSeriesDoublePrecision)arg1[, (object)communicator=None]) → None :

Run the zero-dim algorithm. Pass an mpi4py communicator for parallel execution.

Settings: pass config fields either as a dict (settings={‘final_tolerance’: 1e-13}) or by keyword (solve(final_tolerance=1e-13)); each is applied via set() before solving, so make/set/solve becomes a single call. communicator= is reserved for MPI (never a setting).

show_progress=True (the default) reports how far the solve has got. It draws nothing unless the solve runs past a few seconds AND stderr is a terminal, so scripts, pipelines and test runs see nothing; pass show_progress=False to be certain of silence.

Returns a bertini.records.SolveResult – the finite solutions plus this solve’s records ticket (run id, directory, recall count), read from the solver’s own records (the solver records itself, on by default). Drop it freely: solver.result() re-derives it, and the records hold the truth.

target_system((ZeroDimSolverPowerSeriesDoublePrecision)arg1) → bertini._pybertini.system.System :

get the prepared target system: the homogenized, auto-patched clone of the system you supplied. its patch is the one internal-coordinate solutions lie on; use its dehomogenize_point/homogenize_point/variable_ordering to move between representations.

to_classic_input((ZeroDimSolverPowerSeriesDoublePrecision)self, (bertini._pybertini.system.System)system) → str :

emit a complete Bertini 1 classic input file (CONFIG + INPUT) for the given natural system, using THIS solver’s tracking settings for the CONFIG: precision mode (mptype), ODE predictor, tolerances (before/during endgame, final), the full step-size cadence, max Newton iterations, and the crossed-path resolve cap. The system you pass supplies INPUT – pass the natural (un-homogenized) system you constructed the solver from, since the solver homogenizes and patches its internal copy. Use this to re-run the exact same problem with the exact same knobs in Bertini 1 for cross-validation (the random start system aside). For sweeping settings without a solver, see system.to_classic_input(**kwargs).

to_dataframe(*, user_coords=True, omit_infinite=True, merge_multiplicities=True, group=None)

The solve as a pandas DataFrame – one row per solution, the “database of solutions”.

Columns are solution – the whole solution point, kept in a single cell – then every per-solution metadata field (is_finite, is_real, is_singular, multiplicity, condition_number, endgame_success_code, max_precision_used, …), and finally system, a reference to the (target) system these solutions satisfy (so rows accumulated from several solves stay identifiable). Each category is then a one-line filter, e.g. df[df.is_real & ~df.is_singular] (nonsingular real) or df[~df.is_finite] (at infinity).

The solution cell is an independent copy of the solution vector (a numpy array of Python complex for a double solve, of bertini.complex_mp for a multiprecision one, so no precision is lost). Coordinates are deliberately not exploded into x0, x1, ... columns; split them yourself if you want them, e.g. df['x'] = [v[0] for v in df.solution].

Parameters:
  • user_coords (bool) – Coordinates in YOUR variables (dehomogenized; default), or the solver’s internal homogenized on-patch coordinates when False – the same choice as all_solutions().

  • omit_infinite (bool) – Drop the endpoints not classified finite (is_finite False) – the at-infinity and failed paths. True by default, so the frame holds just the genuine finite solutions; pass False to get every tracked path (their coordinate cells may be empty/NaN).

  • merge_multiplicities (bool) – Collapse a multiplicity-m solution – which the solver returns as m coincident endpoints – to its single representative row (multiplicity still records m). True by default. Pass False to keep every endpoint, including the m-1 duplicate copies. The grouping is the solver’s own (the C++ clustering that computes multiplicity), read off multiplicity_representative; this does not re-cluster.

  • group (VariableGroup or int, optional) – Project each solution onto one variable group – the solution cell then holds only that group’s coordinates (Cluster G). Pass the VariableGroup object or its 0-based FIFO index. None (default) keeps the whole point.

Returns:

One row per solution; the solution cell is a copied vector whose elements are Python complex for a double-precision solve and bertini.complex_mp for a multiprecision one (kept native, so no precision is lost).

Return type:

pandas.DataFrame

Notes

pandas is an optional dependency; this raises ImportError if it is absent. The point accessors – all_solutions(), finite_solutions(), solution_metadata() – are the no-pandas path.

update(**fields)

Set config fields on this owner by NAME, each routed to whichever config owns it.

You never name the config struct:

solver.update(final_tolerance="1e-11",          # -> TolerancesConfig
              max_num_crossed_path_resolve_attempts=3)   # -> ZeroDimConfig

Strings work for every numeric field (converted exactly). A field that none of this owner’s configs has raises AttributeError with the valid names – so a typo, or trying to set a tracker field on the algorithm (or vice versa), never silently does nothing. Returns self, so calls chain. To set a whole config at once, or to name the config explicitly, use configure().

was_randomized((ZeroDimSolverPowerSeriesDoublePrecision)arg1) → bool :

True if the supplied system was over-determined and was squared up by randomization (so the extraneous solutions the squaring introduces have been filtered out of finite_solutions). False for a square system.

was_stopped_early((ZeroDimSolverPowerSeriesDoublePrecision)self) → bool :

Was the last solve() stopped before it finished – by Ctrl-C, or by request_stop()? If so the results are a PARTIAL set: paths in flight were abandoned and read SuccessCode.ExternallyTerminated, paths not yet begun still read NeverStarted, and every count derived from them describes only what was tracked. Re-running the same solve recalls the finished paths from the records and tracks only the rest.

class bertini.nag_algorithm.ZeroDimSolverPowerSeriesFixedMultiplePrecision((object)arg1, (bertini._pybertini.system.System)arg2)

Bases: AnyZeroDim

__init__( (object)arg1, (bertini._pybertini.system.System)system, (StartSystemFactory)start_factory) -> None

__init__((object)arg1, (bertini._pybertini.system.System)arg2) → None

__init__( (object)arg1, (bertini._pybertini.system.System)system, (StartSystemFactory)start_factory) -> None

add_observer((object)self, (object)observer) → None :

Attach an observer to this observable object

all_solutions((ZeroDimSolverPowerSeriesFixedMultiplePrecision)self[, (bool)user_coords=True]) → bertini._pybertini.container.ListOfVectorComplexVariablePrecision :

get ALL the computed solutions, one per tracked path (finite, at-infinity, and failed alike). by default they are in the coordinates of YOUR variables (dehomogenized, depatched). pass user_coords=False to decline, getting the solver’s internal coordinates instead: homogenized, lying on the target system’s patch – the representation to use for continuing work. the container is computed at most once per solve; repeated calls and indexing do not recompute it. for the filtered view see solutions(); for the at-infinity ones see infinite_solutions.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

config_names()

The keyword names accepted by configure() for this owner, its tracker and its endgame.

config_types((ZeroDimSolverPowerSeriesFixedMultiplePrecision)self) → list :

List the configuration struct classes this object accepts.

configure(**kwargs)

Change settings on this owner’s configs in one call.

Each keyword names a config (e.g. stepping, newton, tolerances); its value is either a dict of fields to change, or a ready config object.

tracker.configure(stepping={‘max_step_size’: 0.1},

newton={‘max_num_newton_iterations’: 2})

Returns self.

default_point_match_tolerance((ZeroDimSolverPowerSeriesFixedMultiplePrecision)arg1) → float :

the default infinity-norm tolerance metadata_for() uses when you omit tol: the solver’s final_tolerance (the accuracy each endpoint is computed to). Since metadata_for matches against representatives – which are at least the same-point clustering tolerance apart – this tight default still resolves a fed-back solution to itself while making an ambiguous match structurally impossible.

endgame_boundary_metadata((ZeroDimSolverPowerSeriesFixedMultiplePrecision)arg1) → MidpathCheckReport :

get the MidpathCheckReport from the path-crossing check at the endgame boundary: how many crossings were detected, which paths, how many re-track attempts were made, and whether the check ultimately passed

endgame_boundary_solutions((ZeroDimSolverPowerSeriesFixedMultiplePrecision)arg1) → bertini._pybertini.container.ListOfEGBoundaryMetaData_MultiPrec :

get the solutions (per-path point data) at the endgame boundary, where regular tracking switches to the endgame

finite_solutions((ZeroDimSolverPowerSeriesFixedMultiplePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the FINITE solutions: successful endpoints the solver calls finite (is_finite applies endpoint_finite_threshold). includes singular, nonsingular, and real solutions alike. merge_multiplicities=True (default) collapses each multiple solution to one representative. user coordinates by default; user_coords=False for internal coordinates.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

get_config((ZeroDimSolverPowerSeriesFixedMultiplePrecision)self, (object)config_type) → object :

Return a copy of this object’s stored configuration struct of the given class.

The named config, by class (TolerancesConfig) or by short name ('tolerances',

as config_names() lists them).

Either may belong to this object’s tracker or endgame rather than to the object itself (solver.get_config('stepping'), solver.get_config(EndgameConfig)); it is fetched from whichever holds it, so every name config_names() lists can be asked for.

get_endgame((ZeroDimSolverPowerSeriesFixedMultiplePrecision)arg1) → bertini._pybertini.endgame.FixedMultiplePowerSeriesEndgame :

get a mutable reference to the Endgame being used

get_settings(as_dict=False)

This owner’s whole configuration as a carryable dict.

By default (as_dict=False) the value is {config_name: config} – each a copy of one of the owner’s configs (e.g. {'stepping': SteppingConfig(...), 'tolerances': TolerancesConfig(...)}), keyed by the short names config_names() lists. The configs are independent copies (and picklable), so the dict is a plain Python value you can stash, tweak, and apply to other owners – the way to carry one set of tracking settings across a series of related solves:

settings = first_solver.get_settings()
next_solver.set_settings(settings)

Pass as_dict=True for the flat, human-readable view instead: one {field_name: value} dict across ALL configs (field names are unique across an owner’s configs, so there is no collision). That form drops the struct layer nobody wants to poke at, and round-trips through set:

flat = solver.get_settings(as_dict=True)   # {'final_tolerance': ..., 'max_step_size': ..., ...}
other.set(**flat)

(The config-keyed default is kept because set_settings consumes it; use whichever fits.) See set_settings() for applying the config-keyed form back.

get_tracker((ZeroDimSolverPowerSeriesFixedMultiplePrecision)arg1) → bertini._pybertini.tracking.MultiplePrecisionTracker :

get a mutable reference to the Tracker being used

infinite_solutions((ZeroDimSolverPowerSeriesFixedMultiplePrecision)self[, (bool)user_coords=True]) → list :

the solutions AT INFINITY: endpoints not classified finite (is_finite is False). these are the paths the endgame resolved as diverging – its GoingToInfinity / SecurityMaxNormReached verdict, or a successful endpoint whose dehomogenized infinity norm exceeds endpoint_finite_threshold. the complement of finite_solutions within all_solutions. NOTE a path that FAILED before the endgame also has is_finite False (its point is not a real solution at infinity); inspect solution_metadata()/report() to tell a true divergence from a tracking failure.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

metadata_for((ZeroDimSolverPowerSeriesFixedMultiplePrecision)self, (numpy.ndarray)point[, (float)tol=-1.0[, (bool)coincident=False[, (bool)user_coords=True[, (bool)representatives_only=True]]]]) → object :

the SolutionMetaData for the solution matching point (issue #302). Matches by the infinity-norm tolerance tol (see is_distinct_up_to) against the multiplicity REPRESENTATIVES – one candidate per distinct solution. tol is OPTIONAL: omit it (or pass a non-positive value) to use default_point_match_tolerance() (the solver’s final_tolerance). Because representatives are at least the same-point tolerance apart and the default window is smaller, a pt taken straight from solutions() / real_solutions() / etc. (which return representatives) matches its own representative back and is NEVER reported ambiguous – feed a solver result straight back in and it Just Works. The return type NEVER depends on the point’s multiplicity: by default returns exactly ONE record – the multiplicity-cluster representative (it carries .multiplicity, so you still learn m). coincident=True instead ALWAYS returns a LIST of every coincident copy’s record (their per-path condition number / residual / precision), length 1 for a simple root. representatives_only=False matches against EVERY endpoint including non-representative multiplicity copies – a debugging view, rarely what you want. Raises if no solution matches within tol, or (only for a deliberately coarse tol) if the point matches more than one distinct cluster. point is in user coordinates unless user_coords=False. Accepts any numpy array of the solver’s complex type – which is exactly what the solution lists return.

nonsingular_solutions((ZeroDimSolverPowerSeriesFixedMultiplePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the NONSINGULAR finite solutions (simple, well-conditioned roots). (Nonsingular solutions are simple, so merge_multiplicities is a no-op; kept for a uniform signature.)

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

nonsolutions((ZeroDimSolverPowerSeriesFixedMultiplePrecision)self[, (bool)user_coords=True]) → list :

the NONSOLUTIONS: finite, successful endpoints that are NOT solutions of the target system – the extraneous nonsolutions a squared-up over-determined system introduces (empty otherwise). Excluded from finite_solutions/real/singular; a regeneration cascade reads these to discard them.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

num_paths((ZeroDimSolverPowerSeriesFixedMultiplePrecision)self) → int :

How many paths this solve has to answer – the start system’s start point count. Known once a solve has begun its setup, which is before the first path event, and 0 before that.

num_paths_never_started((ZeroDimSolverPowerSeriesFixedMultiplePrecision)self) → int :

How many paths the last solve() never began, because it was stopped first.

num_paths_recalled((ZeroDimSolverPowerSeriesFixedMultiplePrecision)self) → int :

How many paths the last solve() recalled from the records instead of computing (0 on a fresh solve; num_paths on a full memo hit).

randomization_matrix((ZeroDimSolverPowerSeriesFixedMultiplePrecision)arg1) → numpy.ndarray :

The exact n x N coefficient matrix used to square up an over-determined system (empty if the system was already square).

real_solutions((ZeroDimSolverPowerSeriesFixedMultiplePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the REAL finite solutions (is_real applies the configured tolerance). merge_multiplicities=True (default) collapses each multiple solution to one representative.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

record_to((ZeroDimSolverPowerSeriesFixedMultiplePrecision)self, (str)directory) → None :

Attach a structured output directory at the given path: this solve records every path as it completes (durable, plain-text, see the directory’s README.txt) and consults the records before computing – an identical ask (same system, settings, seed) recalls from the records instead of re-tracking, so a crashed solve resumes by simply calling solve() again. Recording is ON BY DEFAULT with no code at all: an unattached solver records to the ambient directory (BERTINI_RECORDS_DIR, else ./bertini_output; the value ‘none’ switches records off). record_to chooses the directory explicitly and always wins over the ambient resolution.

records_path((ZeroDimSolverPowerSeriesFixedMultiplePrecision)self) → object :

The attached output directory’s path, or None when not recording.

records_run_id((ZeroDimSolverPowerSeriesFixedMultiplePrecision)self) → str :

This solve’s run id in the records (empty until a recording solve() runs). Points are referenced as {run, index} pairs; this is the run half.

remove_observer((object)self, (object)observer) → None :

Remove an observer to this observable object

report((ZeroDimSolverPowerSeriesFixedMultiplePrecision)arg1) → SolveReport :

a concise end-of-solve diagnostic summary (a SolveReport): how every path ended up – finite solutions, diverged, or FAILED (by named reason) – plus singular/real counts, max condition number, the path-crossing outcome, and all_paths_resolved. print(solver.report()) for a human-readable summary; a count alone can hide a path the tracker silently lost.

result()

This solve’s SolveResult: the finite solutions plus the records ticket (run id, directory, recall count), read from the solver’s own recorded state.

A bare solver.solve() already returns this; result() re-derives it (call it after solve()) if you did not keep the return value.

same_point_tolerance((ZeroDimSolverPowerSeriesFixedMultiplePrecision)arg1) → float :

the same-point (clustering) tolerance, final_tolerance * same_point_tolerance_multiplier: the looser tolerance the solver uses to decide two endpoints are the SAME solution and cluster them into one multiplicity (and that metadata_for(coincident=True) uses to gather a cluster’s copies).

set(**fields)

Set config fields on this owner by NAME, each routed to whichever config owns it.

You never name the config struct:

solver.update(final_tolerance="1e-11",          # -> TolerancesConfig
              max_num_crossed_path_resolve_attempts=3)   # -> ZeroDimConfig

Strings work for every numeric field (converted exactly). A field that none of this owner’s configs has raises AttributeError with the valid names – so a typo, or trying to set a tracker field on the algorithm (or vice versa), never silently does nothing. Returns self, so calls chain. To set a whole config at once, or to name the config explicitly, use configure().

set_config((ZeroDimSolverPowerSeriesFixedMultiplePrecision)self, (TolerancesConfig)config) → None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (ZeroDimSolverPowerSeriesFixedMultiplePrecision)self, (PostProcessingConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (ZeroDimSolverPowerSeriesFixedMultiplePrecision)self, (ZeroDimConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (ZeroDimSolverPowerSeriesFixedMultiplePrecision)self, (AutoRetrackConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (ZeroDimSolverPowerSeriesFixedMultiplePrecision)self, (RecordsConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

set_config( (ZeroDimSolverPowerSeriesFixedMultiplePrecision)self, (MidPathConfig)config) -> None :

Store one of this object’s configuration structs (dispatched by the config’s type).

Store a configuration struct, on this object or on whichever of its tracker and

endgame owns that config’s type.

set_recorded_start_provenance((ZeroDimSolverPowerSeriesFixedMultiplePrecision)self, (str)refs_json, (str)start_identity) → None :

Declare where this solve’s start points came from, for the records: a JSON array with one reference object per path ({‘kind’:’point_ref’,’run’:…,’index’:…} for a chain from a prior run, {‘kind’:’given_ref’,’given’:…,’index’:…} for external data), plus an identity string for the start data (it joins the ask: same homotopy, different starts = different computation). Call before solve().

set_settings(settings, strict=False)

Apply a settings dict (from get_settings()) onto this owner. Returns self.

settings is {config_name: config} (or {config_name: {field: value}}). By default only the configs this owner actually has are applied and the rest are skipped – so a bundle carried from one solver drops cleanly onto another whose config set differs (e.g. a different precision model, or a different algorithm stage). Pass strict=True to instead raise on any key this owner does not have.

singular_solutions((ZeroDimSolverPowerSeriesFixedMultiplePrecision)self[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]) → list :

the SINGULAR finite solutions (multiple or ill-conditioned roots). merge_multiplicities=True (default) collapses each multiple solution to one representative.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

solution_metadata((ZeroDimSolverPowerSeriesFixedMultiplePrecision)arg1) → bertini._pybertini.container.ListOfSolutionMetaData_MultiPrec :

get the metadata for the solutions at the target time

solutions((ZeroDimSolverPowerSeriesFixedMultiplePrecision)self[, (bool)singular=True[, (bool)real=True[, (bool)nonreal=True[, (bool)nonsingular=True[, (bool)infinite=False[, (bool)nonsolution=False[, (bool)user_coords=True[, (bool)merge_multiplicities=True]]]]]]]]) → list :

the solutions, filtered by category (returns points, not metadata). By DEFAULT every finite genuine solution – real and complex, simple and multiple – and nothing else. Each keyword toggles a category: singular / nonsingular select by conditioning, real / nonreal by realness (a finite solution is returned only if BOTH its conditioning class and its realness class are enabled), infinite=True also returns the at-infinity endpoints, and nonsolution=True also returns the nonsolutions. E.g. solutions(real=False) -> complex finite solutions only; solutions(singular=False) -> nonsingular finite solutions; solutions(infinite=True) adds the divergent paths. merge_multiplicities=True (the DEFAULT) collapses a multiplicity-m solution to its single representative (pass False to get all m coincident copies). user_coords=False gives the solver’s internal coordinates. See also real_solutions / nonsingular_solutions / singular_solutions / infinite_solutions / nonsolutions for the common single-category views, and all_solutions for the raw per-path list.

group=<VariableGroup or 0-based FIFO index>: project each returned point onto that variable group – return only its coordinates (Cluster G). Default None keeps the whole point.

solve((ZeroDimSolverPowerSeriesFixedMultiplePrecision)arg1[, (object)communicator=None]) → None :

Run the zero-dim algorithm. Pass an mpi4py communicator for parallel execution.

Settings: pass config fields either as a dict (settings={‘final_tolerance’: 1e-13}) or by keyword (solve(final_tolerance=1e-13)); each is applied via set() before solving, so make/set/solve becomes a single call. communicator= is reserved for MPI (never a setting).

show_progress=True (the default) reports how far the solve has got. It draws nothing unless the solve runs past a few seconds AND stderr is a terminal, so scripts, pipelines and test runs see nothing; pass show_progress=False to be certain of silence.

Returns a bertini.records.SolveResult – the finite solutions plus this solve’s records ticket (run id, directory, recall count), read from the solver’s own records (the solver records itself, on by default). Drop it freely: solver.result() re-derives it, and the records hold the truth.

target_system((ZeroDimSolverPowerSeriesFixedMultiplePrecision)arg1) → bertini._pybertini.system.System :

get the prepared target system: the homogenized, auto-patched clone of the system you supplied. its patch is the one internal-coordinate solutions lie on; use its dehomogenize_point/homogenize_point/variable_ordering to move between representations.

to_classic_input((ZeroDimSolverPowerSeriesFixedMultiplePrecision)self, (bertini._pybertini.system.System)system) → str :

emit a complete Bertini 1 classic input file (CONFIG + INPUT) for the given natural system, using THIS solver’s tracking settings for the CONFIG: precision mode (mptype), ODE predictor, tolerances (before/during endgame, final), the full step-size cadence, max Newton iterations, and the crossed-path resolve cap. The system you pass supplies INPUT – pass the natural (un-homogenized) system you constructed the solver from, since the solver homogenizes and patches its internal copy. Use this to re-run the exact same problem with the exact same knobs in Bertini 1 for cross-validation (the random start system aside). For sweeping settings without a solver, see system.to_classic_input(**kwargs).

to_dataframe(*, user_coords=True, omit_infinite=True, merge_multiplicities=True, group=None)

The solve as a pandas DataFrame – one row per solution, the “database of solutions”.

Columns are solution – the whole solution point, kept in a single cell – then every per-solution metadata field (is_finite, is_real, is_singular, multiplicity, condition_number, endgame_success_code, max_precision_used, …), and finally system, a reference to the (target) system these solutions satisfy (so rows accumulated from several solves stay identifiable). Each category is then a one-line filter, e.g. df[df.is_real & ~df.is_singular] (nonsingular real) or df[~df.is_finite] (at infinity).

The solution cell is an independent copy of the solution vector (a numpy array of Python complex for a double solve, of bertini.complex_mp for a multiprecision one, so no precision is lost). Coordinates are deliberately not exploded into x0, x1, ... columns; split them yourself if you want them, e.g. df['x'] = [v[0] for v in df.solution].

Parameters:
  • user_coords (bool) – Coordinates in YOUR variables (dehomogenized; default), or the solver’s internal homogenized on-patch coordinates when False – the same choice as all_solutions().

  • omit_infinite (bool) – Drop the endpoints not classified finite (is_finite False) – the at-infinity and failed paths. True by default, so the frame holds just the genuine finite solutions; pass False to get every tracked path (their coordinate cells may be empty/NaN).

  • merge_multiplicities (bool) – Collapse a multiplicity-m solution – which the solver returns as m coincident endpoints – to its single representative row (multiplicity still records m). True by default. Pass False to keep every endpoint, including the m-1 duplicate copies. The grouping is the solver’s own (the C++ clustering that computes multiplicity), read off multiplicity_representative; this does not re-cluster.

  • group (VariableGroup or int, optional) – Project each solution onto one variable group – the solution cell then holds only that group’s coordinates (Cluster G). Pass the VariableGroup object or its 0-based FIFO index. None (default) keeps the whole point.

Returns:

One row per solution; the solution cell is a copied vector whose elements are Python complex for a double-precision solve and bertini.complex_mp for a multiprecision one (kept native, so no precision is lost).

Return type:

pandas.DataFrame

Notes

pandas is an optional dependency; this raises ImportError if it is absent. The point accessors – all_solutions(), finite_solutions(), solution_metadata() – are the no-pandas path.

update(**fields)

Set config fields on this owner by NAME, each routed to whichever config owns it.

You never name the config struct:

solver.update(final_tolerance="1e-11",          # -> TolerancesConfig
              max_num_crossed_path_resolve_attempts=3)   # -> ZeroDimConfig

Strings work for every numeric field (converted exactly). A field that none of this owner’s configs has raises AttributeError with the valid names – so a typo, or trying to set a tracker field on the algorithm (or vice versa), never silently does nothing. Returns self, so calls chain. To set a whole config at once, or to name the config explicitly, use configure().

was_randomized((ZeroDimSolverPowerSeriesFixedMultiplePrecision)arg1) → bool :

True if the supplied system was over-determined and was squared up by randomization (so the extraneous solutions the squaring introduces have been filtered out of finite_solutions). False for a square system.

was_stopped_early((ZeroDimSolverPowerSeriesFixedMultiplePrecision)self) → bool :

Was the last solve() stopped before it finished – by Ctrl-C, or by request_stop()? If so the results are a PARTIAL set: paths in flight were abandoned and read SuccessCode.ExternallyTerminated, paths not yet begun still read NeverStarted, and every count derived from them describes only what was tracked. Re-running the same solve recalls the finished paths from the records and tracks only the rest.

bertini.nag_algorithm.start_system_factory((StartSystemType)which) → StartSystemFactory :

start_system_factory(which): the start-system factory for a StartSystemType, to pass as the second argument of a ZeroDim solver constructor (the default constructor uses total_degree_linear_product).

bertini.nag_algorithm.ZeroDimSolver(system, *, endgame='powerseries', mptype='adaptive', startsystem='infer', precision=None, settings=None, **field_settings)[source]

Construct a zero-dim solver by name, with friendly defaults.

ZeroDimSolver(system) is the Cauchy endgame in adaptive precision with the start system inferred from the system’s variable-group structure – total degree for a single affine group, multihomogeneous otherwise – so a multi-group (e.g. eigenvalue) system gets MHom automatically rather than an over-counting total-degree start. Override any piece with a string:

ZeroDimSolver(system, endgame='cauchy', mptype='amp', startsystem='mhom')

Config settings may be applied at construction (via set) so no separate set() is needed before solving – either as a dict (ZeroDimSolver(sys, settings={'final_tolerance': 1e-13})) or by keyword (ZeroDimSolver(sys, final_tolerance=1e-13)); the same go to solve(...) too.

Parameters:
  • system (the polynomial System to solve.)

  • endgame ('powerseries' (default, matching Bertini 1; ADR-0058) or 'cauchy'.)

  • mptype (the precision MODEL – 'double', 'multiple', or 'adaptive' ('amp', the default).)

  • precision (the number of DIGITS (an int), applied via bertini.default_precision at) – construction – meaningful for 'multiple'/'adaptive' ('double' is always 16). A string here is the deprecated old spelling of mptype and warns.

  • startsystem ('infer' (default – choose from the variable-group structure, matching the) – C++ blackbox), or force it with 'binomial' / 'linearproduct' / 'mhom'. To run from a homotopy you built yourself with given start points, use HomotopySolver / straight_line_homotopy() instead (their construction needs the homotopy and start points, not just a system).

  • solver. (Returns a solver; call .solve() then .all_solutions() as for any zero-dim)

Examples

The default infers the start system; strings pick the rest:

>>> import bertini
>>> from bertini.nag_algorithm import ZeroDimSolver
>>> x = bertini.Variable('x')
>>> sys = bertini.System()
>>> sys.add_variable_group(bertini.VariableGroup([x]))
>>> sys.add_function(x * x - 1)
>>> type(ZeroDimSolver(sys)).__name__
'ZeroDimSolverCauchyAdaptivePrecision'
>>> type(ZeroDimSolver(sys, mptype='amp', startsystem='mhom')).__name__
'ZeroDimSolverCauchyAdaptivePrecision'
>>> solver = ZeroDimSolver(sys, mptype='adaptive')   # robust path
>>> solver.solve()
>>> solver.all_solutions()
bertini.nag_algorithm.HomotopySolver(homotopy, start_points, target=None, *, mptype='adaptive', precision=None, endgame='powerseries', amp_config=None)[source]

Track a homotopy you constructed, from a list of start points you already have (e.g. the solutions of an earlier solve) – the continuation primitive (parameter-homotopy workflow).

This reuses the entire tracking pipeline (pre-endgame tracking, the midpath check, the endgame, post-processing); it differs from ZeroDimSolver() only in that the homotopy and the start points are supplied, not generated.

Parameters:
  • homotopy (System or StraightLineHomotopy) – The homotopy to track, with a path variable; tracked from the start time (default 1) down to 0. Its t=1 slice must vanish at the given start_points. Pass the record straight_line_homotopy() returns and the target comes with it.

  • start_points (iterable of vectors) – The start points (at the start time). An earlier solve’s all_solutions() works directly when the variable coordinates line up (e.g. an affine homotopy). Each point may be a list, tuple, or numpy array; coordinates may be multiprecision scalars (complex_mp / real_mp), Python or numpy numbers, or constant symbolic nodes – they are all coerced to multiprecision for you. (Start points are transported values, refined by the tracker, so double-precision input is fine here.)

  • target (System, optional) – The system the solutions satisfy at t=0 – used for dehomogenize / residual and for the solver’s consistency check. It must NOT have a path variable. Optional only when homotopy is a StraightLineHomotopy, which carries its own.

  • mptype ({'adaptive', 'double', 'multiple'}) – The precision MODEL; ‘adaptive’ (default) is the robust path. Adaptive precision needs a degree bound, so it is refused for a homotopy that is not polynomial unless you supply amp_config; such a homotopy tracks at fixed precision without any of this.

  • amp_config (AMPConfig, optional) – An adaptive-precision configuration to install on the tracker instead of the one derived from the system. This is how an analytic homotopy gets adaptive precision: the derivation needs a degree the system does not have, so you choose jacobian_eval_error_bound and function_eval_error_bound yourself. Ignored unless mptype is ‘adaptive’.

  • precision (int, optional) – The number of DIGITS, applied via bertini.default_precision at construction. A string here is the deprecated old spelling of mptype and warns.

  • endgame ({'cauchy', 'powerseries'}) – Which endgame handles the singular endpoints.

Returns:

Call .solve() then .all_solutions() as for any solver.

Return type:

solver

Notes

Whether the homotopy is projective is settled where it was built – see straight_line_homotopy(), which projectivizes by default. This function only tracks what it is given. Start points written in your own (affine) coordinates are lifted onto the homotopy’s patch for you, so an earlier affine solve’s solutions feed a projective homotopy directly.

bertini.nag_algorithm.user_homotopy(homotopy, start_points, target=None, *, mptype='adaptive', precision=None, endgame='powerseries')[source]

Thin forwarder to HomotopySolver(), kept for back-compatibility.

bertini.nag_algorithm.straight_line_homotopy(target, start, *, fixed=None, path_variable='t', gamma=None, projectivize=True)[source]

Build a straight-line continuation problem: the homotopy, and the systems at both ends.

The deformation is linear in the rows that move:

H = [ fixed's rows ;  (1-t)*target_rows + gamma*t*start_rows ]

At t=1 the moving rows are gamma*start_rows, so the start points are the solutions of the returned .start; at t=0 they are target_rows, so the answers solve the returned .target. With no fixed this is the whole system deforming, the ordinary straight-line homotopy. With fixed it is the regeneration / moving-slice construction: those rows are held, evaluated once rather than blended, and carry no path-variable dependence at all – they contribute exactly zero to dH/dt, which is both cheaper and the mathematically honest statement of what is moving.

Nothing to concatenate: the builder assembles both end systems in the same row order as the homotopy, which is the part that is easy to get backwards by hand:

b = nag_algorithm.straight_line_homotopy(target_rows, start_rows, fixed=fixed)
pts = nag_algorithm.ZeroDimSolver(b.start).solve().solutions
solver = nag_algorithm.HomotopySolver(b.homotopy, pts, b.target)
solver.solve()

This also works when a system carries a structured evaluation block – a products-of-linears start built with add_products_of_linears(), say. Such a block cannot be fused by System node arithmetic, which would silently drop it, so systems are combined with a blend block that evaluates whole Systems; the same construction the zero-dim solver uses for its own generated start systems (ADR-0020).

Parameters:
  • target (System, Slice, or list of nodes) – The rows reached at t=0 – a complete system when there is no fixed, or just the moving rows when there is. A list of functions is taken over fixed’s variable structure.

  • start (System, Slice, or list of nodes) – The rows at t=1, up to gamma, in the same form as target.

  • fixed (System, Slice, or None) – Rows held throughout the deformation, carrying no path-variable dependence. None (default) means the whole system deforms.

  • path_variable (str) – Name of the path variable t added to the homotopy (default 't').

  • gamma (node, int or None) –

    The gamma coefficient. None (default) draws a random one – the gamma trick, which is what makes the path generic, so leave it alone unless you have a reason. Pass an exact node (from bertini.coefficient()) off the real axis for a reproducible path.

    Pass 1 for a coefficient-parameter homotopy, where the deformation is a path in parameter space and no gamma belongs in it: then start is a generic member of the family, solved once and reused for any number of targets that share it. Its coefficients should be genuinely generic (random complex), which is what keeps the straight path off the (measure-zero) singular locus.

  • projectivize (bool, default True) –

    Homogenize and patch target and start before combining them, so the homotopy is tracked over projective coordinates and infinity is an ordinary place a path can reach instead of somewhere it runs off to. This is what ZeroDimSolver() does with the systems it builds for itself. It works on clones, so the systems you pass are untouched, and HomotopySolver() brings your affine target and start points into the homotopy’s coordinates for you. Pass False to build the homotopy affinely exactly as written – the right choice when the affine coordinates are the point, as in all-real tracking.

    The two must be in the SAME coordinates to begin with: mixing a projective system with an affine one is refused rather than quietly repaired.

Returns:

The homotopy and the systems at both ends.

Return type:

StraightLineHomotopy

bertini.nag_algorithm.parameter_sweep(make_system, generic_parameters, target_parameters, *, collect=None, comm=None, mptype='adaptive', endgame='powerseries')[source]

Solve a whole family of systems that differ only in their coefficients.

This is the parameter homotopy workhorse: pay for the hard ab-initio solve once, at a generic parameter value, then reach every parameter point you actually care about by cheap tracking that reuses those start solutions. It is also the unit of parallelism – the points are independent, so pass an MPI communicator and the sweep spreads across the ranks for you.

Parameters:
  • make_system (callable) – make_system(parameters) -> bertini.System. Must return systems of the SAME shape every call – same variables and same monomials – with only the coefficient values depending on parameters. (Until first-class coefficient parameters land, this factory is how you say “the same system at a different parameter value”.)

  • generic_parameters – The parameter value for the one-time generic solve. For robustness this should be generic – random complex values – so the straight-line coefficient path to each target avoids the measure-zero singular locus.

  • target_parameters (iterable) – The parameter values you want solved. Results line up with this order.

  • collect (callable, optional) – collect(solver) -> value. If given, each solved point is reduced to collect(solver) and the return is the list of those values (instead of the solvers). Required when comm is given – solver objects cannot cross MPI ranks, so what is gathered must be a picklable value (e.g. a solution count, or solver.to_dataframe()).

  • comm (mpi4py communicator, optional) – If given, target_parameters is split across the ranks (each rank solves the generic once, then tracks its slice – with the path tracking inside each solve threaded across the rank’s cores, set with BERTINI_NUM_THREADS). The collected results are gathered and every rank returns the full list in the original order. This is the two-level model: MPI across parameter points, threads across paths – one extra argument, no manual scatter/gather.

  • mptype – Passed through to the solves (see ZeroDim()).

  • endgame – Passed through to the solves (see ZeroDim()).

Returns:

  • list, one entry per ``target_parameters`` (the solved ZeroDim solvers, or – if)

  • collect is given – the collect(solver) values. A solver exposes .all_solutions(),

  • .solution_metadata() and .to_dataframe() (let the solver do the real/finite

  • classification – don’t redo it by hand).

Examples

Serial / threaded (threads are automatic – a solve uses all cores by default):

solvers = parameter_sweep(make_system, generic, targets)
counts  = [positive_real_count(s) for s in solvers]

Across MPI ranks, threads within – the user-facing MPI code is just comm= and collect=:

from mpi4py import MPI
counts = parameter_sweep(make_system, generic, targets,
                         collect=positive_real_count, comm=MPI.COMM_WORLD)
# every rank now holds the full `counts` list, in `targets` order
class bertini.nag_algorithm.SolutionPathCollector((object)arg1)[source]

Bases: CustomObserver

Collects each solution path of a ZeroDim solve into its own time series.

Usage:

a = SolutionPathCollector()
solver.add_observer(a)
solver.solve()
for path in a.series:          # one tracking.PathDataCollector per solution path
    t, z = path.times(), path.points()
    ...
__init__((object)arg1) → None[source]
Observe(event)[source]