Skip to content

Honor the step given in get_riemann_rectangles' x_range - #2532

Open
NgoQuocViet2001 wants to merge 1 commit into
3b1b:masterfrom
NgoQuocViet2001:fix-riemann-x-range-step
Open

NgoQuocViet2001 wants to merge 1 commit into
3b1b:masterfrom
NgoQuocViet2001:fix-riemann-x-range-step

Conversation

@NgoQuocViet2001

Copy link
Copy Markdown
Contributor

Motivation

get_riemann_rectangles accepts a three-element x_range so the caller can choose the sampling step — that is what the if len(x_range) < 3 branch normalises away. On that path two things go wrong in one line:

if dx is None:
    dx = self.x_range[2]
if len(x_range) < 3:
    x_range = [*x_range, dx]

rects = []
x_range[1] = x_range[1] + dx
xs = np.arange(*x_range)

np.arange steps by x_range[2], so reaching the requested right endpoint takes exactly one of those steps. The nudge uses dx, which on the three-element path was never set from x_range — it is self.x_range[2], the axis default.

The same line writes into the sequence the caller passed in. The two-element path builds a new list, so only the three-element path mutates the caller's object.

Measured on master with Axes() (default x_range (-8, 8, 1.0)):

axes = Axes()
graph = axes.get_graph(lambda x: x)
rects = axes.get_riemann_rectangles(graph, x_range=[0, 2, 0.5])
rectangles              : 5          (expected 4)
spans                   : (0.0,0.5) (0.5,1.0) (1.0,1.5) (1.5,2.0) (2.0,2.5)
spans past the right end: (2.0, 2.5)
caller's list afterward : [0, 3.0, 0.5]      <- was [0, 2, 0.5]

The last rectangle sits entirely outside the requested range, so the drawn area is wrong, and a second call with the same list drifts further because the bound has already been raised.

Proposed changes

  • Copy x_range before writing to it.
  • Nudge by x_range[2], the step actually being sampled.

Two-element x_range is byte-identical: dx is appended as x_range[2] there, so the two nudges are the same number.

Test

Two cases added to the existing tests/test_coordinate_systems.py — one asserting four rectangles ending at 2.0, one asserting the caller's list is unchanged.

python -m pytest tests/test_coordinate_systems.py tests/test_space_ops.py

Result: 8 passed. On master both new tests fail — five rectangles, and [0, 3.0, 0.5] where [0, 2, 0.5] is expected.

np.arange steps by x_range[2], so nudging the upper bound to include the
requested right endpoint takes one of those steps. The code nudged by dx
instead, which on the three-element path is the axis default rather than the
step the caller asked for -- x_range=[0, 2, 0.5] on a default Axes drew five
rectangles, the last spanning 2.0 to 2.5, entirely outside the range.

The same line also wrote to the caller's own sequence, so [0, 2, 0.5] came
back as [0, 3.0, 0.5] and a second call drifted further. Copy it first.

Two-element x_range is unaffected: dx is appended as x_range[2] there, so the
two nudges are the same value.

This branch has not been deployed

No deployments
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