-
Notifications
You must be signed in to change notification settings - Fork 48
Implementation field #416
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
BenjaminPINEAU
wants to merge
21
commits into
JuliaSmoothOptimizers:main
Choose a base branch
from
BenjaminPINEAU:implementation_features
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Implementation field #416
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
362c0d0
add some problems defined in PureJuMP but not in ADNPProblems and vic…
BenjaminPINEAU 40a0916
modif on glider and pinene
BenjaminPINEAU 94c5468
:implementation features
BenjaminPINEAU ce0c3e4
format file
BenjaminPINEAU adb5c2b
format file
BenjaminPINEAU bd5f184
format file
BenjaminPINEAU bd2e74e
initial Project.toml
BenjaminPINEAU 1790f8e
add unit test for :implementation consistency
BenjaminPINEAU 09c1bcc
Documentation for adding new problems in contributing.md (#410)
arnavk23 8c151ba
Add CLAUDE.md (#417)
tmigot a06408f
Add warnings when dimension is modified (#406)
arnavk23 14d09eb
Move doc from comments to meta (#407)
tmigot a95ade6
:robot: Format .jl files (#418)
github-actions[bot] 5340562
add some problems defined in PureJuMP but not in ADNPProblems and vic…
BenjaminPINEAU 0bfd3ad
:implementation features
BenjaminPINEAU f0e4abb
format file
BenjaminPINEAU 1ff553b
add unit test for :implementation consistency
BenjaminPINEAU 49720a8
rebase & format file
BenjaminPINEAU 772e129
rebase
BenjaminPINEAU de664de
format post rebase
BenjaminPINEAU 734df41
project.toml
BenjaminPINEAU File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,162 @@ | ||
| --- | ||
| name: find-bib | ||
| description: Find or construct a BibTeX reference for an OptimizationProblems.jl meta file. Given a DOI, problem name, or free-form reference text, searches for the DOI online, fetches BibTeX from doi2bib.org, and formats the result as a Julia raw string ready to paste into src/Meta/<name>.jl. | ||
| argument-hint: <problem-name | DOI | "free-form reference text"> | ||
| allowed-tools: [Read, Glob, Grep, WebSearch, WebFetch] | ||
| --- | ||
|
|
||
| # find-bib | ||
|
|
||
| Find or construct a BibTeX reference and format it as a Julia raw string for `src/Meta/<name>.jl`. | ||
|
|
||
| ## Arguments | ||
|
|
||
| The user invoked this skill with: $ARGUMENTS | ||
|
|
||
| This can be: | ||
| - A **problem name** from `src/Meta/` (e.g. `zangwil3`, `hs1`) — skill will read the file and extract context | ||
| - A **DOI** (e.g. `10.1145/355934.355936` or `https://doi.org/10.1145/355934.355356`) | ||
| - **Free-form reference text** (title, authors, journal, year — quoted or unquoted) | ||
| - **Empty** — if no argument is given, ask the user to specify a problem name or reference | ||
|
|
||
| --- | ||
|
|
||
| ## Instructions | ||
|
|
||
| Follow these steps in order. | ||
|
|
||
| ### Step 1 — Gather source material | ||
|
|
||
| If `$ARGUMENTS` looks like a problem name (no spaces, no slashes, exists as `src/Meta/<name>.jl`): | ||
| - Read `src/Meta/$ARGUMENTS.jl` | ||
| - Extract `:url`, `:notes`, `:origin_notes`, and the existing `:reference` field (may be empty) | ||
| - Use this text as the source for Steps 2–4 | ||
|
|
||
| Otherwise, treat `$ARGUMENTS` directly as a DOI or free-form reference text. | ||
|
|
||
| ### Step 2 — Extract or find a DOI | ||
|
|
||
| 1. Regex-scan all gathered text for a DOI pattern: `10\.\d{4,}/\S+` | ||
| - DOIs appear in `:url`, `:notes`, `:origin_notes`, or in the argument itself | ||
| 2. If no DOI is found, run a **WebSearch** to locate one: | ||
| - Try: `"<title or key terms>" "<first author>" DOI` | ||
| - Try: `site:doi.org "<title or key terms>"` | ||
| - Try CrossRef: `site:search.crossref.org "<title or key terms>"` | ||
| 3. Extract the DOI string from any search result that contains one. | ||
|
|
||
| ### Step 3 — Fetch BibTeX | ||
|
|
||
| If a DOI was found (say `10.1145/355934.355936`), try these endpoints in order: | ||
|
|
||
| 1. **CrossRef** (primary): `https://api.crossref.org/works/10.1145/355934.355936/transform/application/x-bibtex` | ||
| 2. **doi2bib.org** (fallback): `https://www.doi2bib.org/bib/10.1145/355934.355936` | ||
|
|
||
| The response is plain-text BibTeX — clean up whitespace if needed, then apply these normalizations: | ||
|
|
||
| - **Citation key**: CrossRef often returns auto-generated keys like `More_1981` or `more1981testingunconstrained`. Always rename the key to the `Author1Author2YYYY` format described in Step 4 (e.g. `MoreGarbowHillstrom1981`). | ||
| - **`pages` field**: normalize to BibTeX double-hyphen. Replace Unicode en-dash `–` or a single hyphen `-` between page numbers with `--` (e.g. `175--184`). | ||
|
|
||
| If both endpoints fail or return an error, fall through to Step 4. | ||
|
|
||
| ### Step 4 — Construct BibTeX manually (fallback) | ||
|
|
||
| If no DOI was found or doi2bib.org failed, construct the best possible BibTeX from all available information. | ||
|
|
||
| Choose the entry type: | ||
|
|
||
| | Type | Use when | | ||
| |---|---| | ||
| | `@article` | journal or conference paper | | ||
| | `@book` | book or edited volume | | ||
| | `@techreport` | institutional or technical report | | ||
| | `@misc` | dataset, software, website, or unclear | | ||
|
|
||
| **Citation key format:** `Author1Author2YYYY` using last names only (e.g. `MoreGarbowHillstrom1981`, `HockSchittkowski1981`). For a single author: `AuthorYYYY`. For institutional authors use a compact CamelCase form (e.g. `NISTStRD`). | ||
|
|
||
| **`pages` field:** always use double-hyphen: `175--184`. Convert Unicode en-dash `–`, em-dash `—`, or single hyphen `-` between page numbers to `--`. | ||
|
|
||
| **LaTeX encoding for special characters:** `Mor{\'e}`, `{\'E}`, etc. | ||
|
|
||
| **Flag uncertain fields** with a trailing `% UNVERIFIED` comment on that line. | ||
|
|
||
| ### Step 5 — Present the result | ||
|
|
||
| Show three things: | ||
|
|
||
| **1. Status line** — one sentence: whether the DOI was found, and from where. | ||
|
|
||
| **2. The BibTeX entry** in a code block: | ||
| ```bibtex | ||
| @article{AuthorYear, | ||
| author = {Last, First and Last2, First2}, | ||
| title = {Title of the Article}, | ||
| journal = {Journal Name}, | ||
| year = {YYYY}, | ||
| volume = {V}, | ||
| number = {N}, | ||
| pages = {P1--P2}, | ||
| doi = {10.xxxx/xxxxx} | ||
| } | ||
| ``` | ||
|
|
||
| **3. The Julia snippet** ready to paste into `src/Meta/<name>.jl`: | ||
| ```julia | ||
| :reference => raw""" | ||
| @article{AuthorYear, | ||
| author = {Last, First and Last2, First2}, | ||
| title = {Title of the Article}, | ||
| journal = {Journal Name}, | ||
| year = {YYYY}, | ||
| volume = {V}, | ||
| number = {N}, | ||
| pages = {P1--P2}, | ||
| doi = {10.xxxx/xxxxx} | ||
| } | ||
| """, | ||
| ``` | ||
|
|
||
| ### Step 6 — Suggest next steps | ||
|
|
||
| - List any fields marked `% UNVERIFIED` that the user should check manually. | ||
| - If a DOI was found and the file's `:url` field does not already contain it, suggest adding `https://doi.org/<DOI>` to `:url`. The `:url` field supports multiple URLs as a **comma-separated string**. If a URL is already present, append the new one: `"https://existing.url, https://doi.org/<DOI>"`. | ||
| - If the problem name was given, name the exact file to edit: `src/Meta/<name>.jl`. | ||
|
|
||
| --- | ||
|
|
||
| ## BibTeX type templates (reference) | ||
|
|
||
| ```bibtex | ||
| @article{AuthorYear, | ||
| author = {Last, First}, | ||
| title = {Title}, | ||
| journal = {Journal}, | ||
| year = {YYYY}, | ||
| volume = {V}, | ||
| number = {N}, | ||
| pages = {P1--P2}, | ||
| doi = {10.xxxx/xxxxx} | ||
| } | ||
|
|
||
| @book{AuthorYear, | ||
| author = {Last, First}, | ||
| title = {Book Title}, | ||
| publisher = {Publisher}, | ||
| address = {City}, | ||
| year = {YYYY} | ||
| } | ||
|
|
||
| @techreport{AuthorYear, | ||
| author = {Last, First}, | ||
| title = {Report Title}, | ||
| institution = {Institution}, | ||
| number = {Report Number}, | ||
| year = {YYYY} | ||
| } | ||
|
|
||
| @misc{AuthorYear, | ||
| author = {Last, First}, | ||
| title = {Title}, | ||
| year = {YYYY}, | ||
| howpublished = {\url{https://...}} | ||
| } | ||
| ``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,3 +2,7 @@ | |
| *.jl.*.cov | ||
| *.jl.mem | ||
| Manifest.toml | ||
| .DS_Store | ||
| *.bib | ||
| */settings.local.json | ||
| .DS_Store | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,201 @@ | ||
| # CLAUDE.md — OptimizationProblems.jl | ||
|
|
||
| ## Overview | ||
|
|
||
| **OptimizationProblems.jl** (v0.9.3) is a Julia package providing ~680+ nonlinear programming (NLP) test problems for benchmarking and developing optimization solvers. It is part of the [JuliaSmoothOptimizers](https://github.com/JuliaSmoothOptimizers) ecosystem and integrates with NLPModels, ADNLPModels, and JuMP. | ||
|
|
||
| **Central registry:** `OptimizationProblems.meta` is a `DataFrame` built at load time from `src/Meta/`. It gives instant access to metadata (nvar, ncon, objtype, origin, bounds, feasibility, …) for all problems **without instantiating any model** — extremely useful for filtering and analysis. | ||
|
|
||
| ```julia | ||
| using OptimizationProblems | ||
| # Filter unconstrained problems with ≤ 50 variables | ||
| df = OptimizationProblems.meta | ||
| df[(df.ncon .== 0) .& (df.nvar .≤ 50), :] | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## Repository Structure | ||
|
|
||
| ``` | ||
| src/ | ||
| OptimizationProblems.jl # Main module — builds meta DataFrame | ||
| ADNLPProblems/ | ||
| ADNLPProblems.jl # Module loader (lazy, requires ADNLPModels) | ||
| <name>.jl # One file per problem | ||
| PureJuMP/ | ||
| PureJuMP.jl # Module loader (always loaded) | ||
| <name>.jl # One file per problem | ||
| Meta/ | ||
| <name>.jl # One metadata file per problem | ||
| test/ # Julia unit test suite | ||
| docs/ # Documenter.jl docs (make.jl, src/) | ||
| src/contributing.md # Authoritative contributor guidelines | ||
| benchmark/ # BenchmarkTools suite (own Project.toml) | ||
| data/ # .jld2 data files for mesh-heavy problems | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## Three-File Pattern | ||
|
|
||
| New problems should provide exactly three files sharing the same base name. (Some existing problems are JuMP-only and lack an `ADNLPProblems` file; a few files also define multiple problems — see `triangle.jl` — but these are legacy exceptions.) | ||
|
|
||
| ### `src/ADNLPProblems/<name>.jl` | ||
|
|
||
| AD-based model. Lazy-loaded (only available when `ADNLPModels` is imported). | ||
|
|
||
| ```julia | ||
| export <name> | ||
|
|
||
| function <name>(; n::Int = default_nvar, type::Type{T} = Float64, kwargs...) where {T} | ||
| # x0 must be Vector{T}, objective must return type T | ||
| f(x) = ... | ||
| x0 = ones(T, n) | ||
| return ADNLPModels.ADNLPModel(f, x0, name = "<name>"; kwargs...) | ||
| end | ||
| ``` | ||
|
|
||
| ### `src/PureJuMP/<name>.jl` | ||
|
|
||
| JuMP algebraic model. Always loaded. Short docstring above the function. | ||
|
|
||
| ```julia | ||
| export <name> | ||
|
|
||
| "Short description of the problem." | ||
| function <name>(args...; n::Int = default_nvar, kwargs...) | ||
| nlp = Model() | ||
| # define variables, constraints, objective | ||
| return nlp | ||
| end | ||
| ``` | ||
|
|
||
| ### `src/Meta/<name>.jl` | ||
|
|
||
| Metadata dictionary. Does **not** export the problem function. | ||
|
|
||
| ```julia | ||
| <name>_meta = Dict( | ||
| :nvar => 10, | ||
| :variable_nvar => false, | ||
| :ncon => 0, | ||
| :variable_ncon => false, | ||
| :minimize => true, | ||
| :name => "<name>", | ||
| :has_equalities_only => false, | ||
| :has_inequalities_only => false, | ||
| :has_bounds => false, | ||
| :has_fixed_variables => false, | ||
| :objtype => :other, # see valid values below | ||
| :contype => :unconstrained, # see valid values below | ||
| :best_known_lower_bound => -Inf, | ||
| :best_known_upper_bound => Inf, | ||
| :is_feasible => true, | ||
| :defined_everywhere => true, | ||
| :origin => :academic, # see valid values below | ||
| # Additional fields (branch move-docstring-to-metadata): | ||
| :url => "https://...", # must match ^https?:// | ||
| :notes => raw"""""", # problem description | ||
| :origin_notes => raw"""""", # provenance | ||
| :reference => raw"""@type{key, ...}""", # BibTeX, balanced braces | ||
| :lib => "CUTEst:NAME", # library codes, comma-separated | ||
| ) | ||
| ``` | ||
|
|
||
| **Valid values:** | ||
| - `:objtype`: `:none`, `:constant`, `:linear`, `:quadratic`, `:sum_of_squares`, `:other`, `:least_squares` | ||
| - `:contype`: `:unconstrained`, `:linear`, `:quadratic`, `:general` | ||
| - `:origin`: `:academic`, `:modelling`, `:real`, `:unknown` | ||
|
|
||
| --- | ||
|
|
||
| ## Scalable Problems | ||
|
|
||
| Problems that accept a variable size use `n::Int = default_nvar` (default = 100). | ||
|
|
||
| - Adjust invalid `n` to the closest valid value silently with `@warn`, never throw an error. The exact adjustment depends on the problem's constraints on `n` (minimum size, divisibility, parity, etc.). | ||
| - Export getter functions for the Meta file: `get_<name>_nvar`, `get_<name>_ncon`, `get_<name>_nlin`, `get_<name>_nnln`, `get_<name>_nequ`, `get_<name>_nineq` | ||
| - Reference: `src/ADNLPProblems/arglina.jl`, `src/PureJuMP/arglina.jl`, `src/Meta/arglina.jl` | ||
|
|
||
| --- | ||
|
|
||
| ## Nonlinear Least-Squares (NLS) Problems | ||
|
|
||
| - Set `:objtype => :least_squares` in the meta file | ||
| - Support `use_nls=true/false` keyword: returns `ADNLSModel` or `ADNLPModel` | ||
| - Export `get_<name>_nls_nequ` | ||
| - `residual!(nls, x, Fx)` must be allocation-free | ||
| - Reference: `src/ADNLPProblems/lanczos1.jl`, `src/ADNLPProblems/brownal.jl` | ||
|
|
||
| --- | ||
|
|
||
| ## Code Formatting | ||
|
|
||
| Uses [JuliaFormatter.jl](https://github.com/domluna/JuliaFormatter.jl). Config is in `.JuliaFormatter.toml`: | ||
|
|
||
| | Setting | Value | | ||
| |---------|-------| | ||
| | `margin` | 100 | | ||
| | `indent` | 2 | | ||
| | `normalize_line_endings` | `"unix"` | | ||
|
|
||
| Format the codebase locally: | ||
|
|
||
| ```julia | ||
| using JuliaFormatter | ||
| format(".") | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## Testing | ||
|
|
||
| The test suite uses Julia's `Test` stdlib with `Distributed` for parallel execution. | ||
|
|
||
| ``` | ||
| julia --project test/runtests.jl | ||
| ``` | ||
|
|
||
| Key test files: | ||
|
|
||
| | File | Purpose | | ||
| |------|---------| | ||
| | `test/test-defined-problems.jl` | Verifies all meta entries have working implementations | | ||
| | `test/test-scalable.jl` | Validates scalable problem sizing and getter formulas | | ||
| | `test/test-in-place-residual.jl` | Allocation checks for NLS residuals | | ||
| | `test/utils.jl` | Helpers: `generate_meta()`, `test_multi_precision()` | | ||
|
|
||
| **Always test:** | ||
| - Multiple sizes for scalable problems: `n = 5`, `n = default_nvar`, large `n` | ||
| - Both `Float32` and `Float64` | ||
| - Allocation-free in-place APIs (`cons_nln!`, `residual!`) | ||
|
|
||
| --- | ||
|
|
||
| ## Good Reference Problems | ||
|
|
||
| | Category | Examples | | ||
| |----------|---------| | ||
| | Unconstrained, scalable | `arwhead`, `arglina` | | ||
| | Constrained | `hs100`, `catmix` | | ||
| | Least squares (NLS) | `lanczos1`, `brownal` | | ||
| | With data files | `catmix`, `rocket` | | ||
|
|
||
| --- | ||
|
|
||
| ## Benchmarks | ||
|
|
||
| The `benchmark/` directory has its own Julia environment. Run locally: | ||
|
|
||
| ``` | ||
| julia benchmark/run_local.jl | ||
| ``` | ||
|
|
||
| Benchmarks cover constructor time and objective evaluation for both `ADNLPProblems` and `PureJuMP`, using `BenchmarkTools.jl`. | ||
|
|
||
| --- | ||
|
|
||
| ## Full Contributor Guidelines | ||
|
|
||
| See [`docs/src/contributing.md`](docs/src/contributing.md) for the complete checklist when adding or modifying problems, including the full reviewer checklist for meta fields, implementation consistency, type stability, and allocation requirements. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not in this PR