evograd-diff 0.1.1__tar.gz → 0.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/.claude/settings.local.json +2 -1
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/PKG-INFO +16 -15
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/README.md +15 -14
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/pyproject.toml +1 -1
- evograd_diff-0.1.2/test.py +32 -0
- evograd_diff-0.1.2/test2.py +20 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/uv.lock +1 -1
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/.gitignore +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/.python-version +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/LICENSE +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/Test_new_evograd.ipynb +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/__init__.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/algorithms/__init__.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/algorithms/cmaes.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/algorithms/de.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/algorithms/ga.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/algorithms/pso.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/algorithms/shade.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/benchmarks/functions/__init__.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/benchmarks/functions/base.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/benchmarks/functions/cec2017/__init__.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/benchmarks/functions/cec2017/basic.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/benchmarks/functions/cec2017/composition.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/benchmarks/functions/cec2017/data.pkl +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/benchmarks/functions/cec2017/data.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/benchmarks/functions/cec2017/hybrid.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/benchmarks/functions/cec2017/simple.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/benchmarks/functions/classical.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/benchmarks/functions/smoothed_funnel.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/benchmarks/functions/transforms.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/benchmarks/run_benchmark_functions.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/core/__init__.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/core/algorithm.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/core/maximize.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/core/minimize.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/core/problem.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/core/result.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/core/termination.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/operators/__init__.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/operators/crossover.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/operators/mutation.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/operators/relaxations.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/operators/repair.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/operators/sampling.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/operators/selection.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/operators/survival.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/tests/__init__.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/tests/run_all.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/tests/test_cmaes.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/tests/test_core.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/tests/test_ga.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/tests/test_operators.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/tests/test_per_individual.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/tests/test_utils.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/utils/__init__.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/utils/callbacks.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/utils/device.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/utils/duplicates.py +0 -0
- {evograd_diff-0.1.1 → evograd_diff-0.1.2}/plot_benchmarks.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: evograd-diff
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: PyTorch-based framework for differentiable evolutionary computation and swarm intelligence
|
|
5
5
|
Project-URL: Homepage, https://github.com/andreatangherloni/EvoGrad
|
|
6
6
|
Project-URL: Repository, https://github.com/andreatangherloni/EvoGrad
|
|
@@ -122,10 +122,10 @@ ga = GA(pop_size=100, differentiable=False)
|
|
|
122
122
|
# Fully differentiable GA with custom operators
|
|
123
123
|
ga = GA(
|
|
124
124
|
pop_size=100,
|
|
125
|
-
selection=RouletteSelection(
|
|
126
|
-
crossover=SBXCrossover(
|
|
127
|
-
mutation=PolynomialMutation(
|
|
128
|
-
survival=MergeSurvival(
|
|
125
|
+
selection=RouletteSelection(adaptive=True, learn_temperature=True),
|
|
126
|
+
crossover=SBXCrossover(adaptive=True, learn_eta=True, learn_prob=True),
|
|
127
|
+
mutation=PolynomialMutation(adaptive=True, learn_eta=True, learn_prob=True),
|
|
128
|
+
survival=MergeSurvival(elitism=True, adaptive=True),
|
|
129
129
|
differentiable=True, # Makes population learnable
|
|
130
130
|
)
|
|
131
131
|
```
|
|
@@ -134,7 +134,7 @@ ga = GA(
|
|
|
134
134
|
|-----------|--------|
|
|
135
135
|
| `differentiable=False` | Classical GA with discrete operators |
|
|
136
136
|
| `differentiable=True` | Population is an `nn.Parameter` (learnable via backprop) |
|
|
137
|
-
| Operator `
|
|
137
|
+
| Operator `adaptive=True` | Operator uses Gumbel-Softmax/Binary-Concrete for gradient flow |
|
|
138
138
|
| Operator `learn_*=True` | Operator hyperparameters become learnable `nn.Parameter` |
|
|
139
139
|
|
|
140
140
|
### Differential Evolution (DE)
|
|
@@ -175,10 +175,10 @@ de = DE(pop_size=100, variant="DE/current-to-best/1/bin", adaptive=True, differe
|
|
|
175
175
|
PSO uses the same **algorithm-level flags** as DE:
|
|
176
176
|
|
|
177
177
|
```python
|
|
178
|
-
from evograd.algorithms import PSO, pso_constriction,
|
|
178
|
+
from evograd.algorithms import PSO, pso_constriction, pso_default
|
|
179
179
|
|
|
180
180
|
# Classical PSO
|
|
181
|
-
pso = PSO(pop_size=100,
|
|
181
|
+
pso = PSO(pop_size=100, w=0.7, c1=1.5, c2=1.5)
|
|
182
182
|
|
|
183
183
|
# Adaptive PSO (learnable inertia, c1, c2)
|
|
184
184
|
pso = PSO(pop_size=100, adaptive=True)
|
|
@@ -256,7 +256,7 @@ EvoGrad provides a comprehensive library of evolutionary operators:
|
|
|
256
256
|
| `BlendCrossover` | BLX-α crossover | ✓ |
|
|
257
257
|
| `ArithmeticCrossover` | Weighted average | ✓ |
|
|
258
258
|
| `UniformCrossover` | Gene-wise uniform swap | ✓ |
|
|
259
|
-
| `
|
|
259
|
+
| `NPointCrossover` | N-point crossover | ✓ |
|
|
260
260
|
|
|
261
261
|
### Mutation
|
|
262
262
|
| Operator | Description | Differentiable |
|
|
@@ -264,21 +264,22 @@ EvoGrad provides a comprehensive library of evolutionary operators:
|
|
|
264
264
|
| `PolynomialMutation` | Polynomial bounded mutation | ✓ |
|
|
265
265
|
| `GaussianMutation` | Additive Gaussian noise | ✓ |
|
|
266
266
|
| `UniformMutation` | Uniform random replacement | ✓ |
|
|
267
|
-
| `
|
|
267
|
+
| `NonUniformMutation` | Annealed mutation strength | ✓ |
|
|
268
268
|
|
|
269
269
|
### Survival
|
|
270
270
|
| Operator | Description |
|
|
271
271
|
|----------|-------------|
|
|
272
272
|
| `MergeSurvival` | (μ+λ) with optional elitism |
|
|
273
|
-
| `
|
|
274
|
-
| `
|
|
273
|
+
| `CommaSurvival` | (μ,λ) generational replacement |
|
|
274
|
+
| `ReplaceWorstSurvival` | Steady-state worst replacement |
|
|
275
|
+
| `AgeSurvival` | Age-based replacement |
|
|
275
276
|
| `FitnessSurvival` | Pure fitness-based truncation |
|
|
276
277
|
|
|
277
278
|
### Repair
|
|
278
279
|
| Operator | Description |
|
|
279
280
|
|----------|-------------|
|
|
280
281
|
| `BoundsRepair` | Clamp to bounds |
|
|
281
|
-
| `
|
|
282
|
+
| `ReflectRepair` | Bounce off boundaries |
|
|
282
283
|
| `WrapRepair` | Toroidal wrap-around |
|
|
283
284
|
| `RandomRepair` | Random resampling |
|
|
284
285
|
|
|
@@ -290,7 +291,7 @@ EvoGrad provides a comprehensive library of evolutionary operators:
|
|
|
290
291
|
import torch
|
|
291
292
|
import torch.nn as nn
|
|
292
293
|
from evograd.algorithms import CMAES
|
|
293
|
-
from evograd.core import Problem
|
|
294
|
+
from evograd.core import Problem, minimize
|
|
294
295
|
from evograd.core.termination import MaxEvaluations
|
|
295
296
|
|
|
296
297
|
|
|
@@ -344,7 +345,7 @@ print(f"Final loss: {result.best_fitness:.6f}")
|
|
|
344
345
|
### Callbacks for Logging
|
|
345
346
|
|
|
346
347
|
```python
|
|
347
|
-
from evograd.core import minimize
|
|
348
|
+
from evograd.core import minimize, MaxEvaluations
|
|
348
349
|
from evograd.utils import HistoryCallback, PrintCallback
|
|
349
350
|
|
|
350
351
|
callbacks = [
|
|
@@ -95,10 +95,10 @@ ga = GA(pop_size=100, differentiable=False)
|
|
|
95
95
|
# Fully differentiable GA with custom operators
|
|
96
96
|
ga = GA(
|
|
97
97
|
pop_size=100,
|
|
98
|
-
selection=RouletteSelection(
|
|
99
|
-
crossover=SBXCrossover(
|
|
100
|
-
mutation=PolynomialMutation(
|
|
101
|
-
survival=MergeSurvival(
|
|
98
|
+
selection=RouletteSelection(adaptive=True, learn_temperature=True),
|
|
99
|
+
crossover=SBXCrossover(adaptive=True, learn_eta=True, learn_prob=True),
|
|
100
|
+
mutation=PolynomialMutation(adaptive=True, learn_eta=True, learn_prob=True),
|
|
101
|
+
survival=MergeSurvival(elitism=True, adaptive=True),
|
|
102
102
|
differentiable=True, # Makes population learnable
|
|
103
103
|
)
|
|
104
104
|
```
|
|
@@ -107,7 +107,7 @@ ga = GA(
|
|
|
107
107
|
|-----------|--------|
|
|
108
108
|
| `differentiable=False` | Classical GA with discrete operators |
|
|
109
109
|
| `differentiable=True` | Population is an `nn.Parameter` (learnable via backprop) |
|
|
110
|
-
| Operator `
|
|
110
|
+
| Operator `adaptive=True` | Operator uses Gumbel-Softmax/Binary-Concrete for gradient flow |
|
|
111
111
|
| Operator `learn_*=True` | Operator hyperparameters become learnable `nn.Parameter` |
|
|
112
112
|
|
|
113
113
|
### Differential Evolution (DE)
|
|
@@ -148,10 +148,10 @@ de = DE(pop_size=100, variant="DE/current-to-best/1/bin", adaptive=True, differe
|
|
|
148
148
|
PSO uses the same **algorithm-level flags** as DE:
|
|
149
149
|
|
|
150
150
|
```python
|
|
151
|
-
from evograd.algorithms import PSO, pso_constriction,
|
|
151
|
+
from evograd.algorithms import PSO, pso_constriction, pso_default
|
|
152
152
|
|
|
153
153
|
# Classical PSO
|
|
154
|
-
pso = PSO(pop_size=100,
|
|
154
|
+
pso = PSO(pop_size=100, w=0.7, c1=1.5, c2=1.5)
|
|
155
155
|
|
|
156
156
|
# Adaptive PSO (learnable inertia, c1, c2)
|
|
157
157
|
pso = PSO(pop_size=100, adaptive=True)
|
|
@@ -229,7 +229,7 @@ EvoGrad provides a comprehensive library of evolutionary operators:
|
|
|
229
229
|
| `BlendCrossover` | BLX-α crossover | ✓ |
|
|
230
230
|
| `ArithmeticCrossover` | Weighted average | ✓ |
|
|
231
231
|
| `UniformCrossover` | Gene-wise uniform swap | ✓ |
|
|
232
|
-
| `
|
|
232
|
+
| `NPointCrossover` | N-point crossover | ✓ |
|
|
233
233
|
|
|
234
234
|
### Mutation
|
|
235
235
|
| Operator | Description | Differentiable |
|
|
@@ -237,21 +237,22 @@ EvoGrad provides a comprehensive library of evolutionary operators:
|
|
|
237
237
|
| `PolynomialMutation` | Polynomial bounded mutation | ✓ |
|
|
238
238
|
| `GaussianMutation` | Additive Gaussian noise | ✓ |
|
|
239
239
|
| `UniformMutation` | Uniform random replacement | ✓ |
|
|
240
|
-
| `
|
|
240
|
+
| `NonUniformMutation` | Annealed mutation strength | ✓ |
|
|
241
241
|
|
|
242
242
|
### Survival
|
|
243
243
|
| Operator | Description |
|
|
244
244
|
|----------|-------------|
|
|
245
245
|
| `MergeSurvival` | (μ+λ) with optional elitism |
|
|
246
|
-
| `
|
|
247
|
-
| `
|
|
246
|
+
| `CommaSurvival` | (μ,λ) generational replacement |
|
|
247
|
+
| `ReplaceWorstSurvival` | Steady-state worst replacement |
|
|
248
|
+
| `AgeSurvival` | Age-based replacement |
|
|
248
249
|
| `FitnessSurvival` | Pure fitness-based truncation |
|
|
249
250
|
|
|
250
251
|
### Repair
|
|
251
252
|
| Operator | Description |
|
|
252
253
|
|----------|-------------|
|
|
253
254
|
| `BoundsRepair` | Clamp to bounds |
|
|
254
|
-
| `
|
|
255
|
+
| `ReflectRepair` | Bounce off boundaries |
|
|
255
256
|
| `WrapRepair` | Toroidal wrap-around |
|
|
256
257
|
| `RandomRepair` | Random resampling |
|
|
257
258
|
|
|
@@ -263,7 +264,7 @@ EvoGrad provides a comprehensive library of evolutionary operators:
|
|
|
263
264
|
import torch
|
|
264
265
|
import torch.nn as nn
|
|
265
266
|
from evograd.algorithms import CMAES
|
|
266
|
-
from evograd.core import Problem
|
|
267
|
+
from evograd.core import Problem, minimize
|
|
267
268
|
from evograd.core.termination import MaxEvaluations
|
|
268
269
|
|
|
269
270
|
|
|
@@ -317,7 +318,7 @@ print(f"Final loss: {result.best_fitness:.6f}")
|
|
|
317
318
|
### Callbacks for Logging
|
|
318
319
|
|
|
319
320
|
```python
|
|
320
|
-
from evograd.core import minimize
|
|
321
|
+
from evograd.core import minimize, MaxEvaluations
|
|
321
322
|
from evograd.utils import HistoryCallback, PrintCallback
|
|
322
323
|
|
|
323
324
|
callbacks = [
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "evograd-diff"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.2"
|
|
8
8
|
description = "PyTorch-based framework for differentiable evolutionary computation and swarm intelligence"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "Apache-2.0" }
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import torch
|
|
2
|
+
from evograd.core import Problem, minimize, MaxEvaluations
|
|
3
|
+
from evograd.algorithms import GA, DE, PSO, CMAES
|
|
4
|
+
|
|
5
|
+
# Define an optimisation problem
|
|
6
|
+
problem = Problem(
|
|
7
|
+
objective=lambda x: (x**2).sum(dim=-1), # Sphere function
|
|
8
|
+
n_var=30,
|
|
9
|
+
xl=-100.0,
|
|
10
|
+
xu=100.0,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
# Run with Genetic Algorithm
|
|
14
|
+
ga = GA(pop_size=100, differentiable=True)
|
|
15
|
+
result = minimize(problem, ga, termination=MaxEvaluations(10000), seed=42)
|
|
16
|
+
print(f"GA Best: {result.best_fitness:.6f}")
|
|
17
|
+
|
|
18
|
+
# Run with Differential Evolution
|
|
19
|
+
de = DE(pop_size=100, variant="DE/rand/1/bin", adaptive=True)
|
|
20
|
+
result = minimize(problem, de, termination=MaxEvaluations(10000), seed=42)
|
|
21
|
+
print(f"DE Best: {result.best_fitness:.6f}")
|
|
22
|
+
|
|
23
|
+
# Run with Particle Swarm Optimisation
|
|
24
|
+
pso = PSO(pop_size=100, adaptive=True, differentiable=True)
|
|
25
|
+
result = minimize(problem, pso, termination=MaxEvaluations(10000), seed=42)
|
|
26
|
+
print(f"PSO Best: {result.best_fitness:.6f}")
|
|
27
|
+
|
|
28
|
+
# Run with CMA-ES
|
|
29
|
+
cmaes = CMAES(sigma=0.5, adaptive=True)
|
|
30
|
+
result = minimize(problem, cmaes, termination=MaxEvaluations(10000), seed=42)
|
|
31
|
+
print(f"CMA-ES Best: {result.best_fitness:.6f}")
|
|
32
|
+
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from evograd.algorithms import GA
|
|
2
|
+
from evograd.operators import (
|
|
3
|
+
RouletteSelection,
|
|
4
|
+
SBXCrossover,
|
|
5
|
+
PolynomialMutation,
|
|
6
|
+
MergeSurvival,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
# Classical GA (no gradients)
|
|
10
|
+
ga = GA(pop_size=100, differentiable=False)
|
|
11
|
+
|
|
12
|
+
# Fully differentiable GA with custom operators
|
|
13
|
+
ga = GA(
|
|
14
|
+
pop_size=100,
|
|
15
|
+
selection=RouletteSelection(differentiable=True, learn_temperature=True),
|
|
16
|
+
crossover=SBXCrossover(differentiable=True, learn_eta=True, learn_prob=True),
|
|
17
|
+
mutation=PolynomialMutation(differentiable=True, learn_eta=True, learn_prob=True),
|
|
18
|
+
survival=MergeSurvival(selection=RouletteSelection(differentiable=True)),
|
|
19
|
+
differentiable=True, # Makes population learnable
|
|
20
|
+
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{evograd_diff-0.1.1 → evograd_diff-0.1.2}/evograd/benchmarks/functions/cec2017/composition.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|