pylinkage package

Subpackages

Submodules

pylinkage.exceptions module

The exceptions module is a simple quick way to access the built-in exceptions.

Created on Wed Jun 16, 15:20:06 2021.

@author: HugoFara

pylinkage.exceptions.HypostaticError

alias of UnderconstrainedError

exception pylinkage.exceptions.NotCompletelyDefinedError(joint: Any, message: str = 'The joint is not completely defined!')

Bases: Exception

The linkage definition is incomplete.

exception pylinkage.exceptions.OptimizationError(message: str = 'Optimization failed')

Bases: Exception

Should be raised when the optimization process fails.

exception pylinkage.exceptions.UnbuildableError(joint: Any, message: str = 'Unable to solve constraints')

Bases: Exception

Should be raised when the constraints cannot be solved.

exception pylinkage.exceptions.UnderconstrainedError(linkage: Linkage | str, message: str = 'The linkage is under-constrained!')

Bases: Exception

The linkage is under-constrained and multiple solutions may exist.

Module contents

PyLinkage is a module to create, optimize and visualize linkages.

Please see the documentation at https://hugofara.github.io/pylinkage/. A copy of the documentation should have been distributed on your system in the docs/ folder.

Created on Thu Jun 10 21:30:52 2021

@author: HugoFara

class pylinkage.Crank(x: float | None = None, y: float | None = None, joint0: Joint | tuple[float, float] | None = None, distance: float | None = None, angle: float | None = None, name: str | None = None)

Bases: Joint

Define a crank (rotary driver) joint.

The crank rotates around its anchor point (joint0) at a constant angular velocity. It is the primary driver for linkage mechanisms.

angle: float | None
get_constraints() tuple[float | None]

Return the distance to the center of rotation.

r: float | None
reload(dt: float = 1) None

Make a step of crank using solver function.

Parameters:

dt – Fraction of steps to take (Default value = 1).

set_anchor0(joint: Joint | tuple[float, float], distance: float | None = None) None

First joint anchor and fixed distance.

Parameters:
  • joint – Joint to set as anchor.

  • distance – Distance from the joint. (Default value = None).

set_constraints(distance: float | None = None, *args: float | None) None

Set geometric constraints, only self.r is affected.

Parameters:
  • distance – Distance from the reference point. (Default value = None).

  • args – Unused, but preserves the object structure.

class pylinkage.Fixed(x: float | None = None, y: float | None = None, joint0: Joint | tuple[float, float] | None = None, joint1: Joint | tuple[float, float] | None = None, distance: float | None = None, angle: float | None = None, name: str | None = None)

Bases: Joint

Fixed joint - deterministic polar constraint.

The position is fully determined by: - joint0: Origin point - joint1: Reference point for angle measurement - r: Distance from joint0 - angle: Angle offset from the joint0→joint1 direction

Unlike Revolute (RRR dyad), this has a unique solution.

angle: float | None
get_constraints() tuple[float | None, float | None]

Return the constraining distance and angle parameters.

r: float | None
reload(dt: float = 1) None

Compute position using solver (deterministic constraint).

Parameters:

dt – Unused, but preserves the object structure.

set_anchor0(joint: Joint | tuple[float, float], distance: float | None = None, angle: float | None = None) None

First joint anchor and characteristics.

Parameters:
  • joint – Joint to set as anchor.

  • distance – Distance from the joint. (Default value = None).

  • angle – Angle in radians. (Default value = None).

set_anchor1(joint: Joint | tuple[float, float]) None

Second joint anchor.

Parameters:

joint – Joint to set as anchor.

set_constraints(distance: float | None = None, angle: float | None = None, *args: float | None) None

Set geometric constraints.

Parameters:
  • distance – Distance from joint0. (Default value = None).

  • angle – Angle in radians. (Default value = None).

  • args – Unused, but preserves the object structure.

pylinkage.HypostaticError

alias of UnderconstrainedError

class pylinkage.Linear(*args: object, **kwargs: object)

Bases: Prismatic

Deprecated alias for Prismatic joint.

Deprecated since version Use: Prismatic instead. The Linear name will be removed in a future version.

joint2: pl_joint.Joint | pl_joint.Static | None
revolute_radius: float | None
class pylinkage.Linkage(joints: Iterable[Joint], order: Iterable[Joint] | None = None, name: str | None = None)

Bases: object

A linkage is a set of Joint objects.

It is defined as a kinematic linkage. Coordinates are given relative to its own base.

compile() None

Prepare numba-optimized solver for fast simulation.

This converts the linkage structure into numeric arrays for use by the numba-compiled simulation loop. The compilation is done automatically on first call to step_fast(), but can be called explicitly to control when the overhead occurs.

The compiled solver is cached and reused until invalidated by changes to constraints (set_num_constraints) or structure.

classmethod from_dict(data: dict[str, Any]) Linkage

Create a linkage from a dictionary representation.

Args:

data: Dictionary containing linkage data (as produced by to_dict()).

Returns:

A new Linkage instance.

Example:
>>> data = linkage.to_dict()
>>> new_linkage = Linkage.from_dict(data)
classmethod from_json(path: str | Path) Linkage

Load a linkage from a JSON file.

Args:

path: Path to the JSON file.

Returns:

A new Linkage instance.

Example:
>>> linkage.to_json("my_linkage.json")
>>> loaded = Linkage.from_json("my_linkage.json")
get_coords() list[tuple[float | None, float | None]]

Return the positions of each element in the system.

get_num_constraints(flat: bool = True) list[float | None] | list[tuple[float | None, ...]]

Numeric constraints of this linkage.

Parameters:

flat – Whether to force one-dimensional representation of constraints. The default is True.

Returns:

List of geometric constraints.

get_rotation_period() int

The number of iterations to finish in the previous state.

Formally, it is the common denominator of all crank periods.

Returns:

Number of iterations with dt=1.

indeterminacy() int

Return the static indeterminacy degree of the linkage in 2D.

Uses a variant of the Gruebler-Kutzbach criterion for 2D planar mechanisms:

DOF = 3 * (n - 1) - kinematic_pairs + mobilities

Where:
  • n = number of bodies (including the ground/frame)

  • kinematic_pairs = sum of constraint DOFs removed by joints

  • mobilities = input degrees of freedom (e.g., from motors/cranks)

A positive return value indicates the mechanism is under-constrained, zero means it’s exactly constrained, and negative means it’s over-constrained.

Returns:

The indeterminacy degree (negative DOF when over-constrained).

Note:

This implementation is experimental and results should be verified for complex mechanisms. The algorithm counts bodies and constraints based on joint types (Static, Crank, Revolute, Fixed).

joints: tuple[Joint, ...]
name: str
rebuild(pos: Sequence[tuple[float | None, float | None]] | None = None) None

Redefine linkage joints and given initial positions to joints.

Parameters:

pos – Initial positions for each joint in self.joints. Coordinates do not need to be precise, they will allow us the best fitting position between all possible positions satisfying constraints. (Default value = None).

set_completely(dimensions: Iterable[float] | Iterable[tuple[float, ...]], positions: Sequence[tuple[float | None, float | None]], flat: bool = True) None

Set both dimension and initial positions.

Parameters:
  • dimensions – List of dimensions.

  • positions – Initial positions.

  • flat – If the dimensions are in “flat mode”. The default is True.

set_coords(coords: Sequence[tuple[float | None, float | None]]) None

Set coordinates for all joints of the linkage.

Parameters:

coords – Joint coordinates.

set_num_constraints(constraints: Iterable[float] | Iterable[tuple[float, ...]], flat: bool = True) None

Set numeric constraints for this linkage.

Numeric constraints are distances or angles between joints.

Note:

This invalidates any cached solver data. The next call to step_fast() will recompile the solver automatically.

Parameters:
  • constraints – Sequence of constraints to pass to the joints.

  • flat – If True, constraints should be a one-dimensional sequence of floats. If False, constraints should be a sequence of tuples of digits. Each element will be passed to the set_constraints method of each corresponding Joint. (Default value = True).

simulation(iterations: int | None = None, dt: float = 1) Simulation

Create a simulation context manager for the linkage.

This provides a convenient way to run and iterate over linkage simulations with automatic resource management.

Example:
>>> with linkage.simulation(iterations=100) as sim:
...     for step, coords in sim:
...         process(coords)
Parameters:
  • iterations – Number of iterations to run. If None, uses get_rotation_period().

  • dt – Time step for crank rotation. Default is 1.

Returns:

A Simulation context manager.

step(iterations: int | None = None, dt: float = 1) Generator[tuple[tuple[float | None, float | None], ...], None, None]

Make a step of the linkage.

Parameters:
  • iterations – Number of iterations to run across. If None, the default is self.get_rotation_period(). (Default value = None).

  • dt – Amount of rotation to turn the cranks by. All cranks rotate by their self.angle * dt. The default is 1. (Default value = 1).

Returns:

Iterable of the joints’ coordinates.

step_fast(iterations: int | None = None, dt: float = 1) ndarray[tuple[Any, ...], dtype[float64]]

Run simulation using numba-optimized solver.

This is significantly faster than step() for large iteration counts, as it avoids Python method call overhead in the hot loop.

The first call may be slower due to numba compilation (JIT warm-up). Subsequent calls will be fast.

Args:
iterations: Number of iterations to run. If None, uses

get_rotation_period(). (Default: None)

dt: Amount of rotation per step. Cranks rotate by their

angle * dt. (Default: 1)

Returns:

Array of shape (iterations, n_joints, 2) containing all joint positions at each step. Access individual step positions via trajectory[step_idx, joint_idx] which gives (x, y).

Note:

If any configuration becomes unbuildable during simulation, the corresponding positions will be NaN. Check for this with np.isnan(trajectory).any() or use solver.has_nan_positions().

Example:
>>> trajectory = linkage.step_fast(iterations=1000)
>>> print(trajectory.shape)  # (1000, n_joints, 2)
>>> # Get position of joint 2 at step 100:
>>> pos = trajectory[100, 2]  # (x, y)
to_dict() dict[str, Any]

Convert this linkage to a dictionary representation.

The dictionary can be used for serialization or reconstruction.

Returns:

Dictionary containing the linkage’s data including joints and solve order.

Example:
>>> data = linkage.to_dict()
>>> new_linkage = Linkage.from_dict(data)
to_json(path: str | Path) None

Save this linkage to a JSON file.

Args:

path: Path to the output JSON file.

Example:
>>> linkage.to_json("my_linkage.json")
>>> loaded = Linkage.from_json("my_linkage.json")
exception pylinkage.NotCompletelyDefinedError(joint: Any, message: str = 'The joint is not completely defined!')

Bases: Exception

The linkage definition is incomplete.

exception pylinkage.OptimizationError(message: str = 'Optimization failed')

Bases: Exception

Should be raised when the optimization process fails.

class pylinkage.Pivot(x: float = 0, y: float = 0, joint0: Joint | tuple[float, float] | None = None, joint1: Joint | tuple[float, float] | None = None, distance0: float | None = None, distance1: float | None = None, name: str | None = None)

Bases: Revolute

Revolute Joint definition.

Deprecated since version 0.6.0: This class has been deprecated in favor of Revolute which has a standard name. It will be removed in PyLinkage 0.7.0.

r0: float | None
r1: float | None
class pylinkage.Prismatic(x: float = 0, y: float = 0, joint0: Joint | tuple[float, float] | None = None, joint1: Joint | tuple[float, float] | None = None, joint2: Joint | tuple[float, float] | None = None, revolute_radius: float | None = None, name: str | None = None)

Bases: Joint

Prismatic joint (RRP dyad) - circle-line intersection.

The position is computed as the intersection of: - Circle: centered at joint0 with radius revolute_radius - Line: passing through joint1 and joint2

When two solutions exist, the nearest to the current position is chosen (hysteresis for continuity during simulation).

get_constraints() tuple[float | None]

Return the only distance constraint for this joint.

joint2: Joint | Static | None
reload(dt: float = 1) None

Compute position using solver (RRP dyad - circle-line).

Parameters:

dt – Unused, but preserves the object structure.

revolute_radius: float | None
set_constraints(distance0: float | None = None, *args: float | None) None

Set the only distance constraint for this joint.

Parameters:
  • distance0 – Distance from joint0. (Default value = None).

  • args – Unused, but preserves the object structure.

class pylinkage.Revolute(x: float = 0, y: float = 0, joint0: Joint | tuple[float, float] | None = None, joint1: Joint | tuple[float, float] | None = None, distance0: float | None = None, distance1: float | None = None, name: str | None = None)

Bases: Joint

Revolute joint (RRR dyad) - circle-circle intersection.

The position is computed as the intersection of two circles: - Circle 1: centered at joint0 with radius r0 - Circle 2: centered at joint1 with radius r1

When two solutions exist, the nearest to the current position is chosen (hysteresis for continuity during simulation).

circle(joint: Joint) tuple[float, float, float]

Return the first link between self and parent as a circle.

Parameters:

joint – Parent joint you want to use.

Returns:

Circle is a tuple (abscissa, ordinate, radius).

get_constraints() tuple[float | None, float | None]

Return the two constraining distances of this joint.

r0: float | None
r1: float | None
reload(dt: float = 1) None

Compute position using solver (RRR dyad - circle-circle).

Parameters:

dt – Unused, but preserves the object structure.

set_anchor0(joint: Joint | tuple[float, float], distance: float | None = None) None

Set the first anchor for this Joint.

Parameters:
  • joint – The joint to use as anchor.

  • distance – Distance to keep constant from the anchor. The default is None.

set_anchor1(joint: Joint | tuple[float, float], distance: float | None = None) None

Set the second anchor for this Joint.

Parameters:
  • joint – The joint to use as anchor.

  • distance – Distance to keep constant from the anchor. The default is None.

set_constraints(distance0: float | None = None, distance1: float | None = None, *args: float | None) None

Set geometric constraints.

Parameters:
  • distance0 – Distance to the first reference (Default value = None).

  • distance1 – Distance to the second reference (Default value = None).

  • args – Unused, but preserves the object structure.

class pylinkage.Simulation(linkage: Linkage, iterations: int | None = None, dt: float = 1)

Bases: object

Context manager for linkage simulation.

Provides a clean interface for iterating over linkage positions with automatic setup and teardown.

Example:
>>> with linkage.simulation(iterations=100) as sim:
...     for step, coords in sim:
...         # coords is a tuple of (x, y) for each joint
...         print(f"Step {step}: {coords}")
property iterations: int

Number of iterations for this simulation.

property linkage: Linkage

The linkage being simulated.

class pylinkage.Static(x: float = 0, y: float = 0, name: str | None = None)

Bases: Joint

Special case of Joint that should not move.

Mostly used for the frame.

get_constraints() tuple[()]

Return an empty tuple.

reload(dt: float = 1) None

Do nothing, for consistency only.

Parameters:

dt – Unused, but preserves the object structure.

set_anchor0(joint: Joint | tuple[float, float]) None

First joint anchor.

Parameters:

joint – Joint to set as anchor.

set_anchor1(joint: Joint | tuple[float, float]) None

Second joint anchor.

Parameters:

joint – Joint to set as anchor.

set_constraints(*args: float | None) None

Do nothing, for consistency only.

Parameters:

args – Unused.

exception pylinkage.UnbuildableError(joint: Any, message: str = 'Unable to solve constraints')

Bases: Exception

Should be raised when the constraints cannot be solved.

exception pylinkage.UnderconstrainedError(linkage: Linkage | str, message: str = 'The linkage is under-constrained!')

Bases: Exception

The linkage is under-constrained and multiple solutions may exist.

pylinkage.bounding_box(locus: Iterable[tuple[float, float]]) tuple[float, float, float, float]

Compute the bounding box of a locus.

Parameters:

locus – A list of points or any iterable with the same structure.

Returns:

Bounding box as (y_min, x_max, y_max, x_min).

pylinkage.circle_intersect(x1: float, y1: float, r1: float, x2: float, y2: float, r2: float, tol: float = 0.0) tuple[int, float, float, float, float]

Get the intersections of two circles.

Transcription of a Matt Woodhead program, method provided by Paul Bourke, 1997. http://paulbourke.net/geometry/circlesphere/.

Parameters:
  • x1 – X coordinate of first circle center.

  • y1 – Y coordinate of first circle center.

  • r1 – Radius of first circle.

  • x2 – X coordinate of second circle center.

  • y2 – Y coordinate of second circle center.

  • r2 – Radius of second circle.

  • tol – Distance under which two points are considered equal.

Returns:

Tuple of (n_intersections, x1, y1, x2, y2) where: - n=0: No intersection (other values undefined) - n=1: One intersection at (x1, y1) - n=2: Two intersections at (x1, y1) and (x2, y2) - n=3: Same circle (x1, y1, x2 are center and radius)

pylinkage.cyl_to_cart(radius: float, theta: float, ori_x: float = 0.0, ori_y: float = 0.0) tuple[float, float]

Convert polar coordinates into cartesian.

Parameters:
  • radius – Distance from origin.

  • theta – Angle starting from abscissa axis.

  • ori_x – Origin X coordinate (Default value = 0.0).

  • ori_y – Origin Y coordinate (Default value = 0.0).

Returns:

Cartesian coordinates (x, y).

pylinkage.generate_bounds(center: Iterable[float], min_ratio: float = 5, max_factor: float = 5) tuple[ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]]]

Simple function to generate bounds from a linkage.

Parameters:
  • center – 1-D sequence, often in the form of linkage.get_num_constraints().

  • min_ratio – Minimal compression ratio for the bounds. Minimal bounds will be of the shape center[x] / min_ratio. (Default value = 5).

  • max_factor – Dilation factor for the upper bounds. Maximal bounds will be of the shape center[x] * max_factor. (Default value = 5).

Raises:

OptimizationError – If min_ratio or max_factor are not positive.

pylinkage.intersection(obj_1: tuple[float, float] | tuple[float, float, float], obj_2: tuple[float, float] | tuple[float, float, float], tol: float = 0.0) tuple[float, float] | tuple[tuple[float, float], ...] | tuple[float, float, float] | None

Intersection of two arbitrary objects.

The input objects should be points or circles.

Parameters:
  • obj_1 – First point or circle (as tuple).

  • obj_2 – Second point or circle (as tuple).

  • tol – Absolute tolerance to use if provided.

Returns:

The intersection found, if any.

pylinkage.kinematic_default_test(func: Callable[[...], float], error_penalty: float) Callable[[Linkage, Iterable[float], JointPositions | None], float]

Standard run for any linkage before a complete fitness evaluation.

This decorator makes a kinematic simulation, before passing the loci to the decorated function.

Parameters:
  • func – Fitness function to be decorated.

  • error_penalty – Penalty value for unbuildable linkage. Common values include float(‘inf’) and 0.

pylinkage.kinematic_maximization(func: Callable[[...], float]) Callable[[Linkage, Iterable[float], JointPositions | None], float]

Standard run for any linkage before a complete fitness evaluation.

This decorator makes a kinematic simulation, before passing the loci to the decorated function. In case of error, the penalty value is -float(‘inf’).

Parameters:

func – Fitness function to be decorated.

pylinkage.kinematic_minimization(func: Callable[[...], float]) Callable[[Linkage, Iterable[float], JointPositions | None], float]

Standard run for any linkage before a complete fitness evaluation.

This decorator makes a kinematic simulation, before passing the loci to the decorated function. In case of error, the penalty value is float(‘inf’).

Parameters:

func – Fitness function to be decorated.

pylinkage.norm(x: float, y: float) float

Return the norm of a 2-dimensional vector.

Parameters:
  • x – X component.

  • y – Y component.

Returns:

Vector magnitude.

pylinkage.particle_swarm_optimization(eval_func: Callable[[Linkage, Sequence[float], JointPositions], float], linkage: Linkage, center: ~collections.abc.Sequence[float] | float | None = None, dimensions: int | None = None, n_particles: int = 100, leader: float = 3.0, follower: float = 0.1, inertia: float = 0.6, neighbors: int = 17, iters: int = 200, bounds: tuple[~collections.abc.Sequence[float], ~collections.abc.Sequence[float]] | None = None, order_relation: ~collections.abc.Callable[[float, float], float] = <built-in function max>, verbose: bool = True, **kwargs: ~typing.Any) list[Agent]

Particle Swarm Optimization wrapper for pyswarms.

This function is a simple wrapper to optimize a linkage using PSO. It will mainly call the LocalBestPSO function from pyswarms.single.

Parameters:
  • eval_func – The evaluation function. Input: (linkage, num_constraints, initial_coordinates). Output: score (float). The swarm will look for the HIGHEST score.

  • linkage – Linkage to be optimized. Make sure to give an optimized linkage for better results.

  • center – A list of initial dimensions. If None, dimensions will be generated randomly between bounds. The default is None.

  • dimensions – Number of dimensions of the swarm space, number of parameters. If None, it takes the value len(tuple(linkage.get_num_constraints())). The default is None.

  • n_particles – Number of particles in the swarm. The default is 100.

  • inertia – Inertia of each particle, w in pyswarms. The default is .3.

  • leader – Learning coefficient of each particle, c1 in pyswarms. The default is .2.

  • follower – Social coefficient, c2 in pyswarms. The default is .5.

  • neighbors – Number of neighbors to consider. The default is 17.

  • iters – Number of iterations to describe. The default is 200.

  • bounds – Bounds to the space, in format (lower_bound, upper_bound). (Default value = None).

  • order_relation – How to compare scores. There should not be anything else than the built-in max and min functions. The default is max.

  • verbose – The optimization state will be printed in the console if True. (Default value = True).

  • kwargs – keyword arguments to pass to pyswarm.local.single.LocalBestPSO.

Returns:

List of Agents: best score, best dimensions and initial positions.

Raises:

OptimizationError – If parameters are invalid or optimization fails.

pylinkage.plot_kinematic_linkage(linkage: Linkage, fig: Figure, axis: Axes, loci: Sequence[tuple[Coord, ...]], frames: int = 100, interval: float = 40) FuncAnimation

Plot a linkage with an animation.

Args:

linkage: The linkage to animate. fig: Figure to support the axes. axis: The subplot to draw on. loci: list of list of coordinates. frames: Number of frames to draw the linkage on. interval: Delay between frames in milliseconds.

Returns:

The animation object.

pylinkage.plot_static_linkage(linkage: Linkage, axis: Axes, loci: Iterable[tuple[Coord, ...]], locus_highlights: list[list[Coord]] | None = None, show_legend: bool = False) None

Plot a linkage without movement.

Args:

linkage: The linkage you want to see. axis: The graph we should draw on. loci: List of list of coordinates. They will be plotted. locus_highlights: If a list, should be a list of list of coordinates you

want to see highlighted.

show_legend: To add an automatic legend to the graph.

pylinkage.show_linkage(linkage: Linkage, save: bool = False, prev: Sequence[Coord] | None = None, loci: Sequence[tuple[Coord, ...]] | None = None, points: int = 100, iteration_factor: float = 1, title: str | None = None, duration: float = 5, fps: int = 24) FuncAnimation

Display results as an animated drawing.

Args:

linkage: The Linkage you want to draw. save: To save the animation. prev: Previous coordinates to use for linkage. loci: list of loci. points: Number of points to draw for a crank revolution.

Useless when loci are set.

iteration_factor: A simple way to subdivide the movement. The real

number of points will be points * iteration_factor.

title: Figure title. Defaults to str(len(ani)). duration: Animation duration (in seconds). fps: Number of frames per second for the output video.

Returns:

The animation object.

pylinkage.sqr_dist(x1: float, y1: float, x2: float, y2: float) float

Square of the distance between two points.

Faster than dist when only comparing distances.

Parameters:
  • x1 – X coordinate of first point.

  • y1 – Y coordinate of first point.

  • x2 – X coordinate of second point.

  • y2 – Y coordinate of second point.

Returns:

Squared distance.

pylinkage.swarm_tiled_repr(linkage: Linkage, swarm: tuple[int, Sequence[tuple[float, np.ndarray, Sequence[Coord]]]], fig: Figure, axes: np.ndarray, dimension_func: Callable[[np.ndarray], Sequence[float]] | None = None, points: int = 12, iteration_factor: float = 1) None

Show all the linkages in a swarm in tiled mode.

Args:

linkage: The original Linkage that will be MODIFIED. swarm: Tuple of (iteration_number, list_of_agents) where each agent is

(score, dimensions, initial_positions).

fig: Figure to support the axes. axes: The subplot to draw on. points: Number of steps to use for each Linkage. iteration_factor: A simple way to subdivide the movement. The real

number of points will be points * iteration_factor.

dimension_func: If you want a special formatting of dimensions from

agents before passing them to the linkage.

pylinkage.trials_and_errors_optimization(eval_func: Callable[[Linkage, Sequence[float], JointPositions], float], linkage: Linkage, parameters: Sequence[float] | None = None, n_results: int = 10, divisions: int = 5, **kwargs: Any) list[MutableAgent]

Return the list of dimensions optimizing eval_func.

Each dimension set has a score, which is added in an array of n_results results, contains the linkages with the best scores in a maximization problem by default.

Parameters:
  • eval_func – Evaluation function. Input: (linkage, num_constraints, initial_coordinates). Output: score (float).

  • linkage – Linkage to evaluate.

  • parameters – Parameters that will be modified. Geometric constraints. If not, it will be assigned tuple(linkage.get_num_constraints()). The default is None.

  • n_results – Number of the best candidates to return. The default is 10.

  • divisions – Number of subdivisions between bounds. The default is 5.

  • kwargs

    • Extra arguments for the optimization.

    • boundsA 2-uple (tuple of two elements), containing the minimal and maximal bounds.

      If None, we will use parameters as a center. (Default value = None).

    • order_relationA function of two arguments, should return the best score of two

      scores. Common examples are min, max, abs. (Default value = max()).

    • verboseThe number of combinations will be printed in console if True.

      (Default value = True).

    • sequential : If True, two consecutive linkages will have a small variation.

Returns:

3-uplet of score, dimensions and initial position for each Linkage to return. Its size is {n_results}.

Raises:

OptimizationError – If parameters are invalid or no valid solution is found.