or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-optimization.mdconfiguration.mdconstraints-boundaries.mdcore-optimization.mdfitness-functions.mdindex.mdlogging-analysis.mdsamplers-adaptation.md

fitness-functions.mddocs/

0

# Fitness Functions and Testing

1

2

Comprehensive collection of test functions, benchmark problems, and fitness transformations for algorithm testing, validation, and performance evaluation.

3

4

## Test Function Collection (ff module)

5

6

The `ff` module provides a rich collection of test functions commonly used in optimization research and algorithm benchmarking. All functions are accessible via `cma.ff.<function_name>`.

7

8

### Complete Function List

9

10

```python { .api }

11

# Complete list of available test functions in cma.ff module

12

import cma

13

14

# Basic quadratic functions

15

cma.ff.sphere # Sphere function: sum(x**2)

16

cma.ff.elli # Ellipsoid function with conditioning

17

cma.ff.cigar # Cigar function: x[0]**2 + 1e6*sum(x[1:]**2)

18

cma.ff.tablet # Tablet function: 1e6*x[0]**2 + sum(x[1:]**2)

19

cma.ff.twoaxes # Two-axes function with group separability

20

cma.ff.ellirot # Rotated ellipsoid function

21

22

# Multi-modal functions

23

cma.ff.rosen # Rosenbrock function

24

cma.ff.diffpowell # Different powers function

25

cma.ff.rastrigin # Rastrigin function with many local minima

26

cma.ff.schwefel # Schwefel function

27

cma.ff.griewank # Griewank function

28

cma.ff.ackley # Ackley function

29

30

# Noise and randomness

31

cma.ff.noise # Add Gaussian noise to any function

32

cma.ff.noisysphere # Noisy sphere function

33

cma.ff.spherenoise # Sphere with added noise

34

35

# Step functions and plateaus

36

cma.ff.step # Step function

37

cma.ff.parab # Parabolic ridge function

38

39

# Composition functions

40

cma.ff.composed # Composition of multiple functions

41

42

# Special test cases

43

cma.ff.optprob # Optimization problem wrapper

44

cma.ff.warped # Warped/transformed function space

45

```

46

47

### Basic Test Functions

48

49

```python { .api }

50

# Access test functions through cma.ff

51

import cma

52

53

# Basic quadratic functions

54

def sphere(x):

55

"""

56

Sphere function - simplest quadratic test function.

57

58

Global minimum: f(0, ..., 0) = 0

59

Properties: Unimodal, separable, quadratic

60

"""

61

return sum(x**2)

62

63

def elli(x, cond=1e6):

64

"""

65

Ellipsoid function - ill-conditioned quadratic.

66

67

Parameters:

68

-----------

69

x : array-like

70

Input vector.

71

cond : float, optional

72

Condition number (default 1e6).

73

74

Global minimum: f(0, ..., 0) = 0

75

Properties: Unimodal, separable, ill-conditioned

76

"""

77

N = len(x)

78

return sum(cond**(np.arange(N) / (N - 1 + 1e-9)) * np.asarray(x)**2)

79

80

# Usage examples

81

>>> import cma

82

>>>

83

>>> # Sphere function

84

>>> f_val = cma.ff.sphere([1, 2, 3]) # Returns 14.0

85

>>>

86

>>> # Ellipsoid with different condition numbers

87

>>> f_val = cma.ff.elli([1, 1, 1]) # Default condition 1e6

88

>>> f_val = cma.ff.elli([1, 1, 1], cond=100) # Condition number 100

89

>>>

90

>>> # Use in optimization

91

>>> x, es = cma.fmin2(cma.ff.sphere, [1, 2, 3], 0.5)

92

>>> x, es = cma.fmin2(cma.ff.elli, [1, 2, 3], 0.5)

93

```

94

95

### Non-Separable Test Functions

96

97

```python { .api }

98

# Non-separable functions available through cma.ff

99

import cma

100

101

# Cigar function - one dominant direction

102

>>> def cigar_example():

103

... """Cigar function: x[0]^2 + cond * sum(x[1:]^2)"""

104

... x, es = cma.fmin2(cma.ff.cigar, [1, 2, 3, 4], 0.5)

105

... print(f"Cigar result: {x}")

106

... return x, es

107

108

# Tablet function - one weak direction

109

>>> def tablet_example():

110

... """Tablet function: cond * x[0]^2 + sum(x[1:]^2)"""

111

... x, es = cma.fmin2(cma.ff.tablet, [1, 2, 3, 4], 0.5)

112

... print(f"Tablet result: {x}")

113

... return x, es

114

115

# Two-axes function - group separability

116

>>> def twoaxes_example():

117

... """Two-axes function with different conditioning"""

118

... x, es = cma.fmin2(cma.ff.twoaxes, 6 * [0.5], 0.3)

119

... print(f"Two-axes result: {x}")

120

... return x, es

121

122

# Rotated ellipsoid - no separability

123

>>> def ellirot_example():

124

... """Rotated ellipsoid - tests rotation invariance"""

125

... x, es = cma.fmin2(cma.ff.ellirot, [1, 2, 3], 0.5)

126

... print(f"Rotated ellipsoid result: {x}")

127

... return x, es

128

```

129

130

### Multi-Modal Test Functions

131

132

```python { .api }

133

# Multi-modal and difficult functions

134

import cma

135

import numpy as np

136

137

# Rosenbrock function - classic benchmark

138

>>> def rosenbrock_example():

139

... """Rosenbrock function - narrow curved valley"""

140

... # The Rosenbrock function is available as cma.ff.rosen

141

... x, es = cma.fmin2(cma.ff.rosen, 4 * [0], 0.5)

142

... print(f"Rosenbrock result: {x}") # Should be close to [1, 1, 1, 1]

143

... return x, es

144

145

# Rastrigin function - many local minima

146

>>> def rastrigin_example():

147

... """Rastrigin function - highly multi-modal"""

148

... # Note: Rastrigin may be in BBOB collection

149

... def rastrigin(x):

150

... A = 10

151

... n = len(x)

152

... return A * n + sum(xi**2 - A * np.cos(2 * np.pi * xi) for xi in x)

153

...

154

... x, es = cma.fmin2(rastrigin, 5 * [2.0], 1.0,

155

... options={'maxfevals': 10000})

156

... print(f"Rastrigin result: {x}")

157

... return x, es

158

159

# Ackley function - many local minima with global structure

160

>>> def ackley_example():

161

... """Ackley function - exponential multi-modal"""

162

... def ackley(x):

163

... x = np.asarray(x)

164

... n = len(x)

165

... return (-20 * np.exp(-0.2 * np.sqrt(sum(x**2) / n)) -

166

... np.exp(sum(np.cos(2 * np.pi * xi) for xi in x) / n) +

167

... 20 + np.e)

168

...

169

... x, es = cma.fmin2(ackley, 3 * [1.0], 0.5)

170

... print(f"Ackley result: {x}")

171

... return x, es

172

```

173

174

### Constrained and Special Test Functions

175

176

```python { .api }

177

# Special test functions with constraints or unusual properties

178

import cma

179

import numpy as np

180

181

# Functions with constraints built-in

182

>>> def constrained_sphere_example():

183

... """Sphere function with constraint x[0] > 1"""

184

... x, es = cma.fmin2(cma.ff.spherewithoneconstraint, [2, 1, 1], 0.3)

185

... print(f"Constrained sphere result: {x}")

186

... return x, es

187

188

# Asymmetric functions

189

>>> def sectorsphere_example():

190

... """Asymmetric sphere - different scaling for negative values"""

191

... x, es = cma.fmin2(cma.ff.sectorsphere, [1, -1, 0], 0.5)

192

... print(f"Sector sphere result: {x}")

193

... return x, es

194

195

# Functions with corners/boundaries

196

>>> def cornersphere_example():

197

... """Sphere function constrained to corner x >= 1"""

198

... x, es = cma.fmin2(cma.ff.cornersphere, [1.5, 1.5, 1.5], 0.2)

199

... print(f"Corner sphere result: {x}")

200

... return x, es

201

202

# Noisy functions

203

>>> def noisy_sphere_example():

204

... """Sphere function with multiplicative noise"""

205

... x, es = cma.fmin2(cma.ff.noisysphere, [1, 1, 1], 0.5,

206

... noise_handler=cma.NoiseHandler(3))

207

... print(f"Noisy sphere result: {x}")

208

... return x, es

209

210

# Functions with different dimensions of influence

211

>>> def subspace_sphere_example():

212

... """Sphere function in random subspace"""

213

... x, es = cma.fmin2(cma.ff.subspace_sphere, 10 * [0.5], 0.3)

214

... print(f"Subspace sphere result: {x}")

215

... return x, es

216

```

217

218

### Complete Test Function Reference

219

220

```python { .api }

221

# Complete list of available test functions in cma.ff

222

import cma

223

224

# Get all available functions

225

ff_functions = {

226

# Basic unimodal functions

227

'sphere': cma.ff.sphere, # sum(x^2)

228

'elli': cma.ff.elli, # Ellipsoid with condition number

229

'cigar': cma.ff.cigar, # One large eigenvalue

230

'tablet': cma.ff.tablet, # One small eigenvalue

231

'twoaxes': cma.ff.twoaxes, # Two groups of eigenvalues

232

'ellirot': cma.ff.ellirot, # Rotated ellipsoid

233

'hyperelli': cma.ff.hyperelli, # Hyperellipsoid

234

235

# Multi-modal functions

236

'rosen': cma.ff.rosen, # Rosenbrock function

237

238

# Functions with constraints/boundaries

239

'spherewithoneconstraint': cma.ff.spherewithoneconstraint,

240

'cornersphere': cma.ff.cornersphere,

241

'cornerelli': cma.ff.cornerelli,

242

'sectorsphere': cma.ff.sectorsphere,

243

244

# Noisy functions

245

'noisysphere': cma.ff.noisysphere,

246

247

# Special/research functions

248

'subspace_sphere': cma.ff.subspace_sphere,

249

'partsphere': cma.ff.partsphere,

250

'linear': cma.ff.linear,

251

'rand': cma.ff.rand,

252

253

# Gradient functions (for testing)

254

'grad_sphere': cma.ff.grad_sphere,

255

'grad_cigar': cma.ff.grad_cigar,

256

'grad_tablet': cma.ff.grad_tablet,

257

}

258

259

# Usage pattern for testing multiple functions

260

def test_multiple_functions():

261

"""Test CMA-ES on multiple benchmark functions."""

262

263

results = {}

264

265

for name, func in ff_functions.items():

266

if name.startswith('grad_'): # Skip gradient functions

267

continue

268

269

try:

270

print(f"Testing {name}...")

271

x, es = cma.fmin2(func, 3 * [0.5], 0.3,

272

options={'maxfevals': 1000, 'verbose': -9})

273

274

results[name] = {

275

'success': es.result.fbest < 1e-6,

276

'evaluations': es.result.evaluations,

277

'final_value': es.result.fbest,

278

'solution': es.result.xbest

279

}

280

281

except Exception as e:

282

results[name] = {'error': str(e)}

283

284

return results

285

286

# Run comprehensive test

287

results = test_multiple_functions()

288

for func_name, result in results.items():

289

if 'error' not in result:

290

print(f"{func_name}: {'✓' if result['success'] else '✗'} "

291

f"({result['evaluations']} evals, f = {result['final_value']:.2e})")

292

```

293

294

## BBOB Benchmark Functions

295

296

The Black-Box Optimization Benchmarking (BBOB) test suite provides standardized benchmark problems.

297

298

### BBOB Function Access

299

300

```python { .api }

301

import cma

302

303

# Access BBOB functions

304

bbob = cma.ff.BBOB # or cma.bbobbenchmarks

305

306

# BBOB provides 24 test functions in various problem dimensions

307

# Functions are grouped by properties:

308

309

# Group 1: Separable functions (f1-f5)

310

separable_functions = {

311

1: "Sphere",

312

2: "Ellipsoid separable",

313

3: "Rastrigin separable",

314

4: "Skew Rastrigin-Bueche separable",

315

5: "Linear slope"

316

}

317

318

# Group 2: Functions with low or moderate conditioning (f6-f9)

319

moderate_functions = {

320

6: "Attractive sector",

321

7: "Step-ellipsoid",

322

8: "Rosenbrock original",

323

9: "Rosenbrock rotated"

324

}

325

326

# Group 3: Functions with high conditioning and unimodal (f10-f14)

327

unimodal_functions = {

328

10: "Ellipsoid",

329

11: "Discus",

330

12: "Bent cigar",

331

13: "Sharp ridge",

332

14: "Different powers"

333

}

334

335

# Group 4: Multi-modal functions with adequate global structure (f15-f19)

336

multimodal_adequate = {

337

15: "Rastrigin",

338

16: "Weierstrass",

339

17: "Schaffers F7, condition 10",

340

18: "Schaffers F7, condition 1000",

341

19: "Griewank-Rosenbrock F8F2"

342

}

343

344

# Group 5: Multi-modal functions with weak global structure (f20-f24)

345

multimodal_weak = {

346

20: "Schwefel",

347

21: "Gallagher 101 peaks",

348

22: "Gallagher 21 peaks",

349

23: "Katsuuras",

350

24: "Lunacek bi-Rastrigin"

351

}

352

353

# Example usage

354

def bbob_function_example():

355

"""Example using BBOB benchmark functions."""

356

357

try:

358

# Test multiple BBOB functions

359

for func_id in [1, 8, 15, 20]: # Representative from each group

360

361

# Create function instance

362

f = bbob.F(func_id, instance=1, dimension=5)

363

364

print(f"Testing F{func_id} ({separable_functions.get(func_id, 'Other')})")

365

366

# Optimize with CMA-ES

367

x, es = cma.fmin2(f, 5 * [0], 0.5,

368

options={'maxfevals': 2000, 'verbose': -9})

369

370

print(f" Result: f = {es.result.fbest:.2e} in {es.result.evaluations} evals")

371

372

except ImportError:

373

print("BBOB benchmarks not available. Install with: pip install cma[bbob]")

374

375

return

376

377

bbob_function_example()

378

```

379

380

### BBOB Usage Patterns

381

382

```python { .api }

383

import cma

384

385

def bbob_systematic_testing():

386

"""Systematic testing on BBOB benchmark suite."""

387

388

try:

389

bbob = cma.bbobbenchmarks

390

391

# Test configuration

392

dimensions = [2, 5, 10]

393

function_ids = range(1, 25) # All BBOB functions

394

instances = [1, 2, 3] # Multiple instances per function

395

396

results = {}

397

398

for dim in dimensions:

399

results[dim] = {}

400

401

for fid in function_ids:

402

results[dim][fid] = {}

403

404

for inst in instances:

405

# Create BBOB function

406

f = bbob.F(fid, instance=inst, dimension=dim)

407

408

# Optimize with CMA-ES

409

x, es = cma.fmin2(

410

f, dim * [0], 0.5,

411

options={

412

'maxfevals': 100 * dim**2, # Budget scales with dimension

413

'ftarget': 1e-8,

414

'verbose': -9

415

}

416

)

417

418

# Record result

419

results[dim][fid][inst] = {

420

'fbest': es.result.fbest,

421

'evaluations': es.result.evaluations,

422

'success': es.result.fbest < 1e-8

423

}

424

425

print(f"F{fid:2d} D{dim:2d} I{inst}: "

426

f"{'✓' if results[dim][fid][inst]['success'] else '✗'} "

427

f"({results[dim][fid][inst]['evaluations']} evals)")

428

429

return results

430

431

except ImportError:

432

print("BBOB not available. Use: pip install cma[bbob]")

433

return None

434

435

# Run systematic test (comment out for large-scale testing)

436

# results = bbob_systematic_testing()

437

```

438

439

## Fitness Transformations

440

441

Tools for modifying and composing objective functions to create more challenging or realistic optimization problems.

442

443

### ScaleCoordinates - Coordinate Scaling

444

445

```python { .api }

446

class ScaleCoordinates:

447

"""

448

Scale and shift coordinate systems for fitness functions.

449

450

Allows transformation of variables to create ill-conditioned problems

451

or to adapt functions to specific domains.

452

"""

453

454

def __init__(self, function, multipliers=None, zero=None,

455

upper=None, lower=None):

456

"""

457

Create coordinate-scaled function wrapper.

458

459

Parameters:

460

-----------

461

function : callable

462

Original fitness function to transform.

463

464

multipliers : array-like, optional

465

Scaling factors per coordinate. If shorter than input dimension,

466

last value is recycled.

467

468

zero : array-like, optional

469

Offset in original coordinate system (preimage space).

470

471

upper, lower : array-like, optional

472

Domain bounds. Creates scaling: f(lower + (upper-lower) * x).

473

474

Examples:

475

---------

476

>>> import cma

477

>>> from cma.fitness_transformations import ScaleCoordinates

478

>>>

479

>>> # Scale coordinates with different factors

480

>>> scaled_sphere = ScaleCoordinates(

481

... cma.ff.sphere,

482

... multipliers=[1, 10, 100] # Different scales per coordinate

483

... )

484

>>>

485

>>> # Result: f([x0, x1, x2]) = x0^2 + (10*x1)^2 + (100*x2)^2

486

>>> result = scaled_sphere([1, 1, 1]) # = 1 + 100 + 10000 = 10101

487

>>>

488

>>> # Domain transformation [0,1]^n -> [lower, upper]^n

489

>>> domain_sphere = ScaleCoordinates(

490

... cma.ff.sphere,

491

... lower=[-5, -10],

492

... upper=[5, 10]

493

... )

494

>>>

495

>>> # Now x in [0,1] maps to [-5,5] x [-10,10] domain

496

>>> x, es = cma.fmin2(domain_sphere, [0.5, 0.5], 0.2)

497

>>>

498

>>> # Ill-conditioned problem creation

499

>>> ill_conditioned = ScaleCoordinates(

500

... cma.ff.sphere,

501

... multipliers=[1, 1e3, 1e6] # Condition number 1e12

502

... )

503

>>>

504

>>> x, es = cma.fmin2(ill_conditioned, [1, 1, 1], 0.1)

505

"""

506

pass

507

508

# Usage examples

509

def scaling_examples():

510

"""Examples of coordinate scaling transformations."""

511

512

from cma.fitness_transformations import ScaleCoordinates

513

import cma

514

515

# Example 1: Create ill-conditioned sphere

516

def ill_conditioned_example():

517

"""Create highly ill-conditioned optimization problem."""

518

519

# Original sphere function

520

def sphere(x):

521

return sum(x**2)

522

523

# Scale with exponentially increasing factors

524

scales = [10**(i/2) for i in range(5)] # [1, ~3.16, 10, ~31.6, 100]

525

526

scaled_sphere = ScaleCoordinates(sphere, multipliers=scales)

527

528

print(f"Scales: {scales}")

529

530

# Optimize scaled version

531

x, es = cma.fmin2(scaled_sphere, 5 * [1], 0.3,

532

options={'maxfevals': 3000})

533

534

print(f"Scaled sphere result: {x}")

535

print(f"Condition number effect visible in solution scaling")

536

537

return x, es

538

539

# Example 2: Domain mapping

540

def domain_mapping_example():

541

"""Map optimization to specific domain."""

542

543

# Want to optimize in domain x1 ∈ [-10, 10], x2 ∈ [0, 100]

544

domain_sphere = ScaleCoordinates(

545

cma.ff.sphere,

546

lower=[-10, 0],

547

upper=[10, 100]

548

)

549

550

# Optimize in [0,1]^2 space

551

x_unit, es = cma.fmin2(domain_sphere, [0.5, 0.5], 0.2)

552

553

# Transform back to original domain

554

x_original = [-10 + 20*x_unit[0], 0 + 100*x_unit[1]]

555

556

print(f"Unit domain result: {x_unit}")

557

print(f"Original domain result: {x_original}")

558

559

return x_unit, x_original

560

561

# Example 3: Different scales per coordinate group

562

def grouped_scaling_example():

563

"""Scale different groups of coordinates differently."""

564

565

# 6D problem: scale first 2 coordinates x1, last 4 coordinates x1000

566

scales = [1, 1, 1000, 1000, 1000, 1000]

567

568

grouped_sphere = ScaleCoordinates(cma.ff.sphere, multipliers=scales)

569

570

x, es = cma.fmin2(grouped_sphere, 6 * [0.1], 0.3)

571

572

print(f"Grouped scaling result: {x}")

573

print(f"Notice different scales in solution components")

574

575

return x, es

576

577

ill_conditioned_example()

578

domain_mapping_example()

579

grouped_scaling_example()

580

581

scaling_examples()

582

```

583

584

### GlueArguments - Function Argument Binding

585

586

```python { .api }

587

class GlueArguments:

588

"""

589

DEPRECATED: Use functools.partial instead.

590

591

Bind additional arguments to fitness functions.

592

"""

593

594

def __init__(self, fitness_function, *args, **kwargs):

595

"""

596

Create function with bound arguments.

597

598

Parameters:

599

-----------

600

fitness_function : callable

601

Function to wrap.

602

*args : tuple

603

Positional arguments to append.

604

**kwargs : dict

605

Keyword arguments to bind.

606

607

Examples:

608

---------

609

>>> import cma

610

>>> from cma.fitness_transformations import GlueArguments

611

>>>

612

>>> # Create ellipsoid with specific condition number

613

>>> elli_1e4 = GlueArguments(cma.ff.elli, cond=1e4)

614

>>> result = elli_1e4([1, 1, 1]) # Uses cond=1e4

615

>>>

616

>>> # Better: use functools.partial (recommended)

617

>>> import functools

618

>>> elli_1e4_better = functools.partial(cma.ff.elli, cond=1e4)

619

>>> result = elli_1e4_better([1, 1, 1])

620

"""

621

pass

622

623

# Modern alternative using functools.partial

624

def function_binding_examples():

625

"""Examples of binding arguments to fitness functions."""

626

627

import functools

628

import cma

629

630

# Example 1: Create specialized test functions

631

def specialized_functions():

632

"""Create specialized versions of test functions."""

633

634

# Ellipsoids with different condition numbers

635

elli_easy = functools.partial(cma.ff.elli, cond=100)

636

elli_hard = functools.partial(cma.ff.elli, cond=1e8)

637

638

# Test both versions

639

x1, es1 = cma.fmin2(elli_easy, [1, 1, 1], 0.5,

640

options={'maxfevals': 1000, 'verbose': -9})

641

642

x2, es2 = cma.fmin2(elli_hard, [1, 1, 1], 0.5,

643

options={'maxfevals': 1000, 'verbose': -9})

644

645

print(f"Easy ellipsoid (cond=100): {es1.result.evaluations} evals")

646

print(f"Hard ellipsoid (cond=1e8): {es2.result.evaluations} evals")

647

648

return (x1, es1), (x2, es2)

649

650

# Example 2: Parametric function families

651

def parametric_functions():

652

"""Create parametric function families."""

653

654

# Generalized sphere function: sum((x - center)^p)

655

def generalized_sphere(x, center=None, p=2):

656

x = np.asarray(x)

657

if center is not None:

658

x = x - np.asarray(center)

659

return sum(np.abs(x)**p)

660

661

# Create family of functions

662

functions = {

663

'sphere_origin_L2': functools.partial(generalized_sphere, center=[0, 0], p=2),

664

'sphere_shifted_L2': functools.partial(generalized_sphere, center=[1, 1], p=2),

665

'sphere_origin_L1': functools.partial(generalized_sphere, center=[0, 0], p=1),

666

'sphere_origin_L4': functools.partial(generalized_sphere, center=[0, 0], p=4),

667

}

668

669

# Test all variants

670

results = {}

671

for name, func in functions.items():

672

x, es = cma.fmin2(func, [2, 2], 0.5,

673

options={'maxfevals': 1500, 'verbose': -9})

674

results[name] = (x, es.result.fbest, es.result.evaluations)

675

print(f"{name}: x={x}, f={es.result.fbest:.2e}, evals={es.result.evaluations}")

676

677

return results

678

679

# Example 3: Noisy function variants

680

def noisy_function_variants():

681

"""Create functions with different noise characteristics."""

682

683

def noisy_sphere(x, noise_std=0.1, noise_type='additive'):

684

base_value = sum(x**2)

685

686

if noise_type == 'additive':

687

return base_value + noise_std * np.random.randn()

688

elif noise_type == 'multiplicative':

689

return base_value * (1 + noise_std * np.random.randn())

690

else:

691

return base_value

692

693

# Create noise variants

694

noise_variants = {

695

'clean': functools.partial(noisy_sphere, noise_std=0),

696

'low_noise': functools.partial(noisy_sphere, noise_std=0.01),

697

'high_noise': functools.partial(noisy_sphere, noise_std=0.1),

698

'multiplicative': functools.partial(noisy_sphere, noise_std=0.05,

699

noise_type='multiplicative')

700

}

701

702

# Test with noise handling

703

for name, func in noise_variants.items():

704

noise_handler = cma.NoiseHandler(3, maxevals=[1, 2, 10]) if 'noise' in name else None

705

706

x, es = cma.fmin2(func, [1, 1, 1], 0.3,

707

noise_handler=noise_handler,

708

options={'maxfevals': 2000, 'verbose': -9})

709

710

print(f"{name}: final f = {es.result.fbest:.2e}")

711

712

specialized_functions()

713

parametric_functions()

714

noisy_function_variants()

715

716

function_binding_examples()

717

```

718

719

### Function Composition and Advanced Transformations

720

721

```python { .api }

722

# Advanced function transformations and compositions

723

import cma

724

import numpy as np

725

from cma.fitness_transformations import ScaleCoordinates

726

import functools

727

728

def advanced_transformations():

729

"""Advanced fitness function transformations and compositions."""

730

731

# Example 1: Rotation + Scaling composition

732

def rotation_scaling_composition():

733

"""Combine rotation and scaling transformations."""

734

735

from cma.transformations import Rotation

736

737

# Create rotated and scaled function

738

def rotated_scaled_sphere(x, rotation_matrix=None, scales=None):

739

x = np.asarray(x)

740

741

# Apply rotation

742

if rotation_matrix is not None:

743

x = rotation_matrix @ x

744

745

# Apply scaling

746

if scales is not None:

747

x = x * np.asarray(scales)

748

749

return sum(x**2)

750

751

# Create rotation matrix

752

np.random.seed(42) # For reproducibility

753

rotation = Rotation()

754

R = rotation(len=3) # 3D rotation matrix

755

756

# Create composed function

757

composed_func = functools.partial(

758

rotated_scaled_sphere,

759

rotation_matrix=R,

760

scales=[1, 10, 100]

761

)

762

763

# Optimize

764

x, es = cma.fmin2(composed_func, [1, 1, 1], 0.5)

765

766

print(f"Rotation+scaling result: {x}")

767

return x, es

768

769

# Example 2: Multi-objective to single-objective

770

def multiobjective_scalarization():

771

"""Convert multi-objective to single-objective via scalarization."""

772

773

def multiobjective_function(x):

774

"""Example multi-objective function returning [f1, f2]."""

775

f1 = sum(x**2) # Minimize distance from origin

776

f2 = sum((x - 1)**2) # Minimize distance from [1,1,...]

777

return [f1, f2]

778

779

# Weighted sum scalarization

780

def weighted_sum_scalarization(x, weights=[0.5, 0.5]):

781

objectives = multiobjective_function(x)

782

return sum(w * f for w, f in zip(weights, objectives))

783

784

# Different weight combinations

785

weight_sets = [

786

[1.0, 0.0], # Focus on f1

787

[0.0, 1.0], # Focus on f2

788

[0.5, 0.5], # Equal weights

789

[0.8, 0.2], # Prefer f1

790

]

791

792

results = {}

793

for i, weights in enumerate(weight_sets):

794

scalarized = functools.partial(weighted_sum_scalarization, weights=weights)

795

796

x, es = cma.fmin2(scalarized, [0.5, 0.5, 0.5], 0.3,

797

options={'maxfevals': 1000, 'verbose': -9})

798

799

# Evaluate both objectives at solution

800

objectives = multiobjective_function(x)

801

results[f"weights_{weights}"] = {

802

'solution': x,

803

'f1': objectives[0],

804

'f2': objectives[1],

805

'weighted_sum': scalarized(x)

806

}

807

808

print(f"Weights {weights}: x={x}, f1={objectives[0]:.3f}, f2={objectives[1]:.3f}")

809

810

return results

811

812

# Example 3: Time-varying fitness landscape

813

def time_varying_function():

814

"""Create time-varying fitness function."""

815

816

evaluation_counter = [0] # Mutable counter

817

818

def dynamic_sphere(x, period=100, amplitude=1.0):

819

"""Sphere function with moving optimum."""

820

evaluation_counter[0] += 1

821

822

# Moving optimum based on evaluation count

823

t = evaluation_counter[0] / period

824

optimum = amplitude * np.array([np.sin(t), np.cos(t), 0])

825

826

return sum((x - optimum)**2)

827

828

# Optimize dynamic function

829

x, es = cma.fmin2(dynamic_sphere, [0, 0, 0], 0.5,

830

options={'maxfevals': 2000, 'verb_disp': 100})

831

832

print(f"Dynamic function result: {x}")

833

print(f"Total evaluations: {evaluation_counter[0]}")

834

835

return x, es

836

837

# Example 4: Constraint violation penalty

838

def penalty_method_transformation():

839

"""Transform constrained to unconstrained via penalty method."""

840

841

def constrained_objective(x):

842

"""Original objective: minimize x^2."""

843

return sum(x**2)

844

845

def constraints(x):

846

"""Constraints: g(x) <= 0."""

847

return [

848

x[0] + x[1] - 1, # x[0] + x[1] <= 1

849

x[0]**2 + x[1]**2 - 4 # x[0]^2 + x[1]^2 <= 4

850

]

851

852

def penalty_function(x, penalty_factor=1000):

853

"""Unconstrained function with penalty for violations."""

854

obj_val = constrained_objective(x)

855

856

# Add penalty for constraint violations

857

g_vals = constraints(x)

858

penalty = sum(max(0, g)**2 for g in g_vals)

859

860

return obj_val + penalty_factor * penalty

861

862

# Optimize with different penalty factors

863

penalty_factors = [10, 100, 1000, 10000]

864

865

for pf in penalty_factors:

866

penalized = functools.partial(penalty_function, penalty_factor=pf)

867

868

x, es = cma.fmin2(penalized, [0.5, 0.5], 0.3,

869

options={'maxfevals': 2000, 'verbose': -9})

870

871

# Check constraint satisfaction

872

g_vals = constraints(x)

873

feasible = all(g <= 1e-6 for g in g_vals)

874

875

print(f"Penalty {pf}: x={x}, feasible={feasible}, "

876

f"obj={constrained_objective(x):.4f}")

877

878

rotation_scaling_composition()

879

multiobjective_scalarization()

880

time_varying_function()

881

penalty_method_transformation()

882

883

advanced_transformations()

884

```

885

886

## Testing and Validation Utilities

887

888

Tools for systematic testing and algorithm validation.

889

890

```python { .api }

891

import cma

892

import numpy as np

893

import time

894

895

def algorithm_testing_suite():

896

"""Comprehensive testing suite for CMA-ES validation."""

897

898

class OptimizationTester:

899

"""Systematic testing framework for optimization algorithms."""

900

901

def __init__(self):

902

self.results = {}

903

904

def test_function_suite(self, algorithm_func, test_functions,

905

dimensions=[2, 5, 10], repetitions=5):

906

"""Test algorithm on suite of functions."""

907

908

for func_name, func in test_functions.items():

909

self.results[func_name] = {}

910

911

for dim in dimensions:

912

self.results[func_name][dim] = {

913

'successes': 0,

914

'evaluations': [],

915

'final_values': [],

916

'times': []

917

}

918

919

for rep in range(repetitions):

920

start_time = time.time()

921

922

try:

923

# Run optimization

924

x, es = algorithm_func(func, dim * [0.5], 0.3)

925

926

elapsed = time.time() - start_time

927

928

# Record results

929

success = es.result.fbest < 1e-6

930

if success:

931

self.results[func_name][dim]['successes'] += 1

932

933

self.results[func_name][dim]['evaluations'].append(

934

es.result.evaluations)

935

self.results[func_name][dim]['final_values'].append(

936

es.result.fbest)

937

self.results[func_name][dim]['times'].append(elapsed)

938

939

except Exception as e:

940

print(f"Error on {func_name} D{dim} rep{rep}: {e}")

941

942

def print_summary(self):

943

"""Print summary of test results."""

944

945

print("\nOptimization Test Summary")

946

print("=" * 50)

947

948

for func_name in self.results:

949

print(f"\nFunction: {func_name}")

950

951

for dim in sorted(self.results[func_name].keys()):

952

result = self.results[func_name][dim]

953

954

success_rate = result['successes'] / len(result['evaluations'])

955

avg_evals = np.mean(result['evaluations']) if result['evaluations'] else 0

956

avg_time = np.mean(result['times']) if result['times'] else 0

957

958

print(f" D{dim:2d}: {success_rate:4.1%} success, "

959

f"{avg_evals:6.0f} evals, {avg_time:5.2f}s")

960

961

# Define test function suite

962

test_functions = {

963

'sphere': cma.ff.sphere,

964

'elli': cma.ff.elli,

965

'cigar': cma.ff.cigar,

966

'tablet': cma.ff.tablet,

967

'rosen': cma.ff.rosen,

968

'ellirot': cma.ff.ellirot

969

}

970

971

# Test CMA-ES with different configurations

972

def test_cmaes_basic(func, x0, sigma0):

973

"""Basic CMA-ES test."""

974

return cma.fmin2(func, x0, sigma0,

975

options={'maxfevals': 1000 * len(x0)**2, 'verbose': -9})

976

977

def test_cmaes_large_pop(func, x0, sigma0):

978

"""CMA-ES with large population."""

979

return cma.fmin2(func, x0, sigma0,

980

options={'maxfevals': 1000 * len(x0)**2,

981

'popsize_factor': 2, 'verbose': -9})

982

983

# Run tests

984

tester = OptimizationTester()

985

986

print("Testing basic CMA-ES...")

987

tester.test_function_suite(test_cmaes_basic, test_functions,

988

dimensions=[2, 5], repetitions=3)

989

990

tester.print_summary()

991

992

return tester

993

994

def performance_profiling():

995

"""Profile performance characteristics of different functions."""

996

997

import time

998

999

functions_to_profile = {

1000

'sphere': cma.ff.sphere,

1001

'elli': functools.partial(cma.ff.elli, cond=1e6),

1002

'rosen': cma.ff.rosen,

1003

'noisy_sphere': functools.partial(cma.ff.noisysphere, noise=0.01)

1004

}

1005

1006

dimensions = [2, 5, 10, 20]

1007

1008

print("Performance Profiling Results")

1009

print("=" * 40)

1010

1011

for func_name, func in functions_to_profile.items():

1012

print(f"\nFunction: {func_name}")

1013

1014

for dim in dimensions:

1015

# Time single evaluation

1016

x = np.random.randn(dim)

1017

1018

start_time = time.time()

1019

for _ in range(1000): # 1000 evaluations

1020

_ = func(x)

1021

elapsed = time.time() - start_time

1022

1023

evals_per_sec = 1000 / elapsed

1024

1025

print(f" D{dim:2d}: {evals_per_sec:8.0f} evals/sec")

1026

1027

# Run testing suite (comment out for large-scale testing)

1028

# tester = algorithm_testing_suite()

1029

performance_profiling()

1030

```

1031

1032

This comprehensive fitness functions documentation covers:

1033

1034

1. **Basic Test Functions** - Fundamental functions like sphere, ellipsoid, and cigar

1035

2. **Multi-Modal Functions** - Rosenbrock, Rastrigin, Ackley for challenging optimization

1036

3. **BBOB Benchmark Suite** - Standardized benchmark functions for algorithm comparison

1037

4. **Fitness Transformations** - ScaleCoordinates, GlueArguments for function modification

1038

5. **Advanced Transformations** - Complex compositions and multi-objective handling

1039

6. **Testing Utilities** - Systematic testing and validation frameworks

1040

1041

The documentation provides complete API references with practical usage examples for algorithm testing, benchmarking, and validation.