Skip to content

Fix linspace retstep dtype handling - #2304

Open
Sanjays2402 wants to merge 1 commit into
pymc-devs:mainfrom
Sanjays2402:fix/1297-linspace-retstep
Open

Fix linspace retstep dtype handling#2304
Sanjays2402 wants to merge 1 commit into
pymc-devs:mainfrom
Sanjays2402:fix/1297-linspace-retstep

Conversation

@Sanjays2402

Copy link
Copy Markdown

Description

linspace(..., retstep=True) now casts only the generated samples instead of calling astype on the returned tuple. The step keeps NumPy-compatible floating-point precision.

Related Issue

Checklist

  • Checked that the pre-commit linting/style checks pass
  • Included tests that prove the fix is effective or that the new feature works
  • Added necessary documentation (docstrings and/or example notebooks)
  • If you are a pro: each commit corresponds to a relevant logical change

Type of change

  • New feature / enhancement
  • Bug fix
  • Documentation
  • Maintenance
  • Other (please specify):

Cast only the generated samples when retstep is enabled, preserving the step value returned by the core implementation. Add regression coverage across inferred, integer, and floatX dtypes.
dtype = pytensor.config.floatX
start, stop = broadcast_arrays(start, stop)

ls = _linspace_core(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

the other places that make use of this helper don't share the same problem?

@Sanjays2402

Copy link
Copy Markdown
Author

Good question — I checked, and no, the other callers are unaffected.

_linspace_core has three callers, and the two besides linspace pass retstep=False explicitly and hardcode it (not exposed as a kwarg on their own signatures):

  • geomspace (extra_ops.py:1783) — retstep=False, then result = base**result and .astype(dtype)
  • logspace (extra_ops.py:1858) — retstep=False, then return (base**ls).astype(dtype)

Since _linspace_core only returns the (samples, step) tuple when retstep=True, both of them always get a bare tensor back, so the .astype(dtype) on the return value can never hit a tuple. linspace was the only one that forwarded a user-controllable retstep through and then unconditionally called .astype on the result.

Confirmed on the branch:

geomspace dtype=int64 -> type=TensorVariable out_dtype=int64
geomspace dtype=float64 -> type=TensorVariable out_dtype=float64
logspace dtype=int64 -> type=TensorVariable out_dtype=int64
logspace dtype=float64 -> type=TensorVariable out_dtype=float64
linspace retstep int64: samples.dtype= int64  step.dtype= float64

One thing worth flagging from that last line: I left step un-cast, matching numpy — np.linspace(0, 1, num=3, retstep=True, dtype='int64') also returns an int64 samples array with a float64 step, since the step is the true spacing rather than a sample value. That's what the added test asserts against.

$ python -m pytest tests/tensor/test_extra_ops.py -k "linspace or space_ops or geomspace or logspace" -q
66 passed, 257 deselected, 14 warnings in 17.03s

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.

linspace and retstep=True fails

2 participants