Skip to content

Second-order power weighting in plotSpectra/plotCDF (#383)#397

Open
gustavdelius wants to merge 1 commit into
second-order-plot-382from
second-order-plot-383
Open

Second-order power weighting in plotSpectra/plotCDF (#383)#397
gustavdelius wants to merge 1 commit into
second-order-plot-382from
second-order-plot-383

Conversation

@gustavdelius

Copy link
Copy Markdown
Member

Closes #383. Refines the plotting placement of #382 for the power argument of
the plotSpectra…/plotCDF… families.

Stacked on #396 (#382). This PR's base is the second-order-plot-382
branch, so the diff shows only the #383 changes. Merge #396 first, then this
retargets cleanly onto master.

The problem

plotSpectra() forms the plotted value with the weight and the location both at
the node: N_j · w_j^power at w = w_j. For a cell average N_j the
transformed density N(w) w^power is represented at the geometric bin centre
w*_j = w_j sqrt(β) by N_j (w*_j)^power, so the node is doubly off:

Fix

  • plot_spectra() (density): under second_order_w[["bin_average"]],
    evaluate both the w^power weight and the plotted location at the bin
    centre w* = w sqrt(β) (species, resource, total, background), reusing
    bin_midpoints() from Second-order plotting: locate bin-averaged values at geometric bin centres + Array representation tag #382. The default auto wlim follows the plotted grid
    so the centre shift does not clip the end bins.
  • animate.MizerSim() gets the same treatment;
    plotlySpectra()/plotlyCDF() inherit it (thin do.call wrappers);
    plotSpectraRelative() is the special case where the w^power factor
    cancels in 2(N2−N1)/(N1+N2), so only its x-location shifts — which it
    inherits automatically.
  • plotCDF() is the opposite case: a CDF value is cumulative up to a size,
    a boundary quantity, so plot_cdf() maps the density back to the bin
    edges (w = w*/sqrt(β)) — keeping the cumulative on the nodes — while the
    increments stay centre-weighted, so each value·Δw_k = N_k (w*_k)^power Δw_k
    is the second-order bin integral of N w^power.

Explicitly out of scope

getFlux() also has a power argument but is a flux at the boundary → a
point value at the face, correctly weighted at the node; it is left untouched.

Tests

test-plots.R: for power = 0/1/2 the spectrum x shifts by sqrt(β) and the
value scales by β^(power/2) (weight evaluated at the centre); the default path
keeps x on the nodes; plotCDF x stays on the node/edge grid (never the
centres) and is monotonic; plotSpectraRelative shifts x to centres but its
value is power-independent (cancellation). Default vdiffr snapshots unchanged.
Full suite: 2842 pass.

Docs

NEWS entry; the numerical-details vignette's plotting note extended to cover the
w^power-at-centre weighting and the CDF's edge placement.

🤖 Generated with Claude Code

Refines the plotting placement of #382 for the `power` argument. For a cell
average N_j the transformed density N(w) w^power is represented at the
geometric bin centre w* = w sqrt(beta) by N_j (w*)^power, so using the node
for both the w^power weight and the x-location is doubly off -- the location
error is the half-bin shift, and the w^power error is O(power*Δx), largest for
the common power = 2 Sheldon plot.

plot_spectra() now evaluates both the w^power weight and the plotted location
at the bin centre (species, resource, total, background) under
second_order_w[["bin_average"]]; the default auto wlim follows the plotted
grid so the shift does not clip the end bins. animate.MizerSim() gets the same
treatment. plotlySpectra/plotlyCDF/plotSpectraRelative inherit it (the latter's
w^power factor cancels in the relative ratio, so only its x-location shifts).

plotCDF is the opposite case: a CDF value is cumulative up to a size, a
boundary quantity, so plot_cdf() maps the density back to the bin edges
(w = w*/sqrt(beta)) -- keeping the cumulative on the nodes -- while the
increments stay centre-weighted, so each value*dw_k is the second-order bin
integral of N w^power. getFlux() (a face/point quantity) is deliberately left
untouched.

Default (first-order) plots, return_data and vdiffr snapshots are unchanged.
Tests cover power = 0/1/2 placement and weighting, the CDF staying on edges,
and the relative-plot cancellation. Full suite: 2842 pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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