LamarckianGeneration#

class empulse.optimizers.LamarckianGeneration(grad_objective, local_steps=5, lr=0.05, optimizer='adam', beta1=0.9, beta2=0.999, eps=1e-08, grad_clip=5.0, **kwargs)[source]#

Real-coded GA generation with Lamarckian local gradient search.

Before evaluating each individual’s fitness the genome is improved in-place by local_steps gradient steps (Lamarckian learning: the refined weights replace the original ones). This lets the GA operate on a much smoother fitness landscape while the population still maintains global diversity across the rugged high-alpha MaxProfit surface.

The convex hull required by the gradient objective is computed once per individual at the start of the local search and then cached across all local_steps gradient evaluations via the gradient_steps generator. This cuts hull-reconstruction overhead by a factor of local_steps.

Parameters:
local_stepsint, default=5

Number of gradient steps applied to each individual per generation.

lrfloat, default=0.05

Learning rate (step size) for the local search.

optimizer{“adam”, “sgd”}, default=”adam”

Local-search update rule.

  • "adam" – adaptive moment estimation (recommended for noisy gradients; uses beta1, beta2, and eps).

  • "sgd" – plain gradient descent (theta -= lr * grad).

beta1float, default=0.9

Adam: exponential decay rate for the first moment estimate. Ignored when optimizer="sgd".

beta2float, default=0.999

Adam: exponential decay rate for the second moment estimate. Ignored when optimizer="sgd".

epsfloat, default=1e-8

Adam: small term added to the denominator for numerical stability. Ignored when optimizer="sgd".

grad_clipfloat, default=5.0

Gradient clipping threshold applied element-wise before the update.

grad_objectiveLogitObjective

Objective providing the gradient steps for the local search (logit_gradient_steps).

**kwargs

Forwarded to Generation.

optimize(objective, bounds)#

Optimize the objective function.

Parameters:
objectiveCallable

Objective function to optimize. Should be of signature objective(weights) -> float.

boundslist[tuple[float, float]]

List of tuples of lower and upper bounds for each weight.

Yields:
selfGeneration

Current instance of the optimizer.

Notes

This is an infinite generator. The caller is responsible for stopping iteration (e.g. via break or itertools.islice). Calling optimize on the same instance a second time resets all accumulated state (fx_best, result, elite_pool, etc.).