Add a new single-objective optimization algorithm to the sci-comp library. Use when the user asks to implement a new optimizer (e.g. gradient descent, BFGS, simulated annealing, differential evolution).
Scanned 9/12/2026
Install to Claude Code
npx -y skills add datagrok-ai/public --skill add-optimizer --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Add Optimizer?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/datagrok-ai-add-optimizer)More formats (shields.io, HTML) on the badges page.
---
name: add-optimizer
description: Add a new single-objective optimization algorithm to the sci-comp library. Use when the user asks to implement a new optimizer (e.g. gradient descent, BFGS, simulated annealing, differential evolution).
user-invocable: true
---
# Add a new single-objective optimizer
The user wants to add a new optimizer: **$ARGUMENTS**
Follow these steps exactly. Do not skip any step.
## Step 1: Understand the algorithm
Before writing code, research the algorithm:
- What are its tunable hyperparameters?
- Is it population-based or single-point?
- Does it require gradients?
- What is the iteration logic?
## Step 2: Read the reference implementation
Read these files to understand codebase patterns:
- `src/optimization/single-objective/optimizers/nelder-mead.ts` — reference optimizer
- `src/optimization/single-objective/__tests__/nelder-mead.test.ts` — reference tests (the new optimizer MUST include all the same test cases)
- `src/optimization/single-objective/__tests__/helpers.ts` — test functions and helpers
- `src/optimization/single-objective/examples/unconstrained.ts` — reference example
## Step 3: Create the optimizer file
Create `src/optimization/single-objective/optimizers/<name>.ts` following the pattern from `nelder-mead.ts`.
### Rules (beyond what's visible in the reference)
- `runInternal` receives the already-penalized objective — do NOT handle constraints
- `runInternal` receives settings with defaults already applied via `withDefaults`
- Set `converged = true` only if a convergence criterion was met, not just maxIterations
- **Pre-allocate all buffers before the loop** — zero allocations inside the iteration body
- Helper methods must write into caller-provided buffers (out-parameter pattern), not allocate new arrays
- `costHistory`: pre-allocate `Float64Array(maxIter)` with a separate `costLen` counter; return `costHistory.subarray(0, costLen)`
## Step 4: Export from index.ts
Edit `src/optimization/single-objective/index.ts`:
1. Add export for the class and settings type (in the "Built-in optimizers" section):
```typescript
export {<Name>} from './optimizers/<name>';
export type {<Name>Settings} from './optimizers/<name>';
```
2. Add auto-registration (in the "Auto-register" section at the bottom):
```typescript
import {<Name>} from './optimizers/<name>';
registerOptimizer('<kebab-name>', () => new <Name>());
```
## Step 5: Write tests
Create `src/optimization/single-objective/__tests__/<name>.test.ts`.
The new test file MUST replicate ALL test cases from `nelder-mead.test.ts` — every `describe` block, each with both `sync` and `async` variants.
You may adjust:
- `x0` starting points (if the algorithm needs a closer start)
- `maxIterations`, `tolerance`, and algorithm-specific settings
- Precision in `toBeCloseTo` / `expectPointClose` (if the algorithm is less precise)
You must NOT:
- Remove any test group
- Change expected values or expected points
## Step 6: Create example file
Create `src/optimization/single-objective/examples/<name>.ts` following the structure of `unconstrained.ts`. Must show `minimize`, `maximize`, and at least one constrained example with `boxConstraints` + `applyPenalty`.
## Step 7: Verify
Run in order:
1. `npm run lint-fix`
2. `npm run build` — must compile without errors
3. `npm test` — run all tests
**CRITICAL:** If any tests fail, do NOT silently fix or skip them. Instead:
1. Collect the full list of failing test names and reasons
2. Present the list to the user
3. **Wait for the user's response** — do NOT proceed until the user explicitly approves a course of action
This rule applies to every test run, including re-runs after fixes.
## Step 8: Add to benchmarks
The benchmark suite is split into two runners that share objective functions via
`benchmarks/test-functions.ts`. Register the new optimizer in **both** runners:
- `src/optimization/single-objective/benchmarks/unconstrained-benchmarks.ts` — single x₀ per problem
- `src/optimization/single-objective/benchmarks/multistart-benchmarks.ts` — three x₀ per problem
In each file:
1. Import the new optimizer class
2. Add an entry to the `optimizers` array:
```typescript
{
name: '<Name>',
optimizer: new <Name>(),
settings: {maxIterations: 10_000, /* algorithm-specific defaults */},
},
```
3. Run both benchmarks:
- `npx tsx src/optimization/single-objective/benchmarks/unconstrained-benchmarks.ts`
- `npx tsx src/optimization/single-objective/benchmarks/multistart-benchmarks.ts`
4. Regenerate **both** markdown reports (`unconstrained-benchmarks.md` and `multistart-benchmarks.md`) with the new optimizer's rows/columns.
5. Update the problem count / optimizer count in the banner if changed.
Do NOT add new objective functions inline — export them from `test-functions.ts` so both runners pick them up.
## Step 9: Update CLAUDE.md
In `CLAUDE.md`, update the architecture tree — add the new optimizer file under `optimizers/`.
## Step 10: Add to README.md
In `README.md`, add the new optimizer to the list under "Single-objective" section, with a Wikipedia or reference link.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!