Skip to content

Fitting routines exploration#36

Open
mmikhasenko wants to merge 13 commits into
mainfrom
docs/minuit2-componentarrays-optimization
Open

Fitting routines exploration#36
mmikhasenko wants to merge 13 commits into
mainfrom
docs/minuit2-componentarrays-optimization

Conversation

@mmikhasenko
Copy link
Copy Markdown
Collaborator

Summary

  • Update the Minuit2 + ComponentArrays tutorial to use the Optimization.jl OptimizationProblem / MigradOptimizer workflow.
  • Show how constructor-derived lower and upper bounds are passed through problem_settings = (lb = lower, ub = upper).
  • Keep a lower-level Minuit example for passing descriptor uncertainties as Minuit step sizes via error = collect(step).

Test plan

  • Checked edited files with Cursor lints.
  • Not run: full docs build.

Made with Cursor

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the documentation to demonstrate how Minuit2.jl integrates with Optimization.jl when using ComponentArrays. It introduces a new fit_minuit_nll helper function and refactors the tutorial to use the Optimization.jl solver interface. Review feedback recommends using the idiomatic loglikelihood function to improve performance, renaming variables to align with Optimization.jl conventions, and re-including parameter names in the low-level Minuit constructor for better debugging output.

Comment on lines +52 to +55
function nll(c, data, pars)
model = build_model(c, pars)
return -sum(logpdf.(Ref(model), data))
end
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Use loglikelihood from Distributions.jl instead of manually summing logpdf calls. This is more idiomatic and avoids the allocation of a temporary array during broadcasting, which can improve performance during optimization.

Suggested change
function nll(c, data, pars)
model = build_model(c, pars)
return -sum(logpdf.(Ref(model), data))
end
function nll(c, data, pars)
model = build_model(c, pars)
return -loglikelihood(model, data)
end

Comment on lines +57 to +69
function fit_minuit_nll(
constructor,
pars,
data;
minuit_settings = (strategy = 2, tolerance = 0.01, errordef = 0.5),
optimizer_settings = (maxiters = 100,),
problem_settings = (;),
)
objective(pars) = nll(constructor, data, pars)
opf = OptimizationFunction((p, x) -> objective(p))
opp = OptimizationProblem(opf, pars; problem_settings...)
return solve(opp, MigradOptimizer(; minuit_settings...); optimizer_settings...)
end
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The variable name pars is used for both the initial guess argument and the optimization variable in the closure, which can be confusing. Using u0 for the initial guess and u for the optimization variable is more consistent with Optimization.jl conventions. Additionally, the objective closure can be simplified by calling nll directly in the OptimizationFunction.

Suggested change
function fit_minuit_nll(
constructor,
pars,
data;
minuit_settings = (strategy = 2, tolerance = 0.01, errordef = 0.5),
optimizer_settings = (maxiters = 100,),
problem_settings = (;),
)
objective(pars) = nll(constructor, data, pars)
opf = OptimizationFunction((p, x) -> objective(p))
opp = OptimizationProblem(opf, pars; problem_settings...)
return solve(opp, MigradOptimizer(; minuit_settings...); optimizer_settings...)
end
function fit_minuit_nll(
constructor,
u0,
data;
minuit_settings = (strategy = 2, tolerance = 0.01, errordef = 0.5),
optimizer_settings = (maxiters = 100,),
problem_settings = (;),
)
opf = OptimizationFunction((u, p) -> nll(constructor, data, u))
opp = OptimizationProblem(opf, u0; problem_settings...)
return solve(opp, MigradOptimizer(; minuit_settings...); optimizer_settings...)
end

Comment on lines 110 to 119
minuit = Minuit(
objective,
pars -> nll(constructor, data, pars),
start;
names = string.(keys(start)),
limits = limits,
error = collect(errors),
limits = collect(zip(lower, upper)),
error = collect(step),
arraycall = true,
errordef = 0.5,
strategy = 2,
tolerance = 0.01,
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Including the names argument in the Minuit constructor allows the optimizer to display meaningful parameter names in its output (e.g., during migrad! or when printing the minuit object). This significantly improves the debugging experience and maintains the functionality present in the previous version of the tutorial.

Suggested change
minuit = Minuit(
objective,
pars -> nll(constructor, data, pars),
start;
names = string.(keys(start)),
limits = limits,
error = collect(errors),
limits = collect(zip(lower, upper)),
error = collect(step),
arraycall = true,
errordef = 0.5,
strategy = 2,
tolerance = 0.01,
)
minuit = Minuit(
pars -> nll(constructor, data, pars),
start;
names = string.(keys(start)),
limits = collect(zip(lower, upper)),
error = collect(step),
arraycall = true,
errordef = 0.5,
strategy = 2,
tolerance = 0.01,
)

@codecov
Copy link
Copy Markdown

codecov Bot commented May 20, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.83%. Comparing base (abe877e) to head (f7db594).
⚠️ Report is 6 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff             @@
##             main      #36       +/-   ##
===========================================
+ Coverage   50.36%   86.83%   +36.46%     
===========================================
  Files           9       11        +2     
  Lines         407      433       +26     
===========================================
+ Hits          205      376      +171     
+ Misses        202       57      -145     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@mmikhasenko mmikhasenko force-pushed the docs/minuit2-componentarrays-optimization branch from 61b34c8 to f7db594 Compare May 24, 2026 16:52
@mmikhasenko mmikhasenko changed the title docs: update Minuit2 ComponentArrays tutorial Fitting routines exploration May 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant