Skip to content

v2.17.0

Choose a tag to compare

@roytsmart roytsmart released this 26 Oct 15:12
e7ad18a

This release lets a function array be evaluated at scattered points, such as the positions of rays on a mirror, and not only on a new grid. It also fixes the stratified random spaces, which drew samples outside their range and on the diagonal of their strata.

Evaluating a function array at scattered points

FunctionArray.__call__(), regrid() and weights() can now evaluate a function at points listed along axes of their own, with the multilinear interpolation of regridding 3.6 on rectilinear or curvilinear grids of any number of dimensions (#275). Before, they could only resample a function onto a new grid along the same axes as its own.

# A height map sampled on a grid along "x" and "y", for each "channel"
f = na.FunctionArray(inputs=grid, outputs=height)

# The positions of rays on the mirror, along "ray"
points = na.Cartesian2dVectorArray(x_ray, y_ray)

f(points, axis=("x", "y"))      # the heights along "ray" and "channel"
  • Axes: axis names the axes of the function's own inputs to resample, and defaults to all of them. The function's other axes are broadcast against the new inputs by name, so the points can vary along them too, for a separate set of points for each channel. Every other axis of the new inputs takes the place of the resampled axes: the axes of a new grid, or the axes along which the points are listed. There can be any number of them, or none for a single point.
  • A separate grid for each element: if the inputs of the function vary along an axis like channel, with a grid for each channel, axis must leave that axis out, as in axis=("x", "y"), since the default would resample along it too.
  • A single point: if the inputs of the function are scalars, a single point can also be a plain number or quantity.
  • Components which aren't resampled: a component of the inputs which doesn't vary along axis, such as the wavelength of a map for each wavelength, isn't resampled. In the new inputs it can be None, or else it must equal the function's own everywhere, counting NaN as equal to NaN. It may be broadcast along other axes, such as the axes of the points, the way the rays of optika carry their wavelength. Either way, the result keeps the function's own component. The check is exact, so a copy which differs by rounding raises an error; pass None instead.
  • Errors: a ValueError explains what's wrong when axis names an axis which the inputs of the function don't vary along, when the number of components of the inputs which vary along axis isn't the number of axes in it, or when a component which isn't resampled is neither None nor equal to the function's own.
  • Bounds: bounds is added to na.regridding.regrid(), na.regridding.weights() and the three methods, and passed on to regridding. Points outside the grid are extrapolated by default, are NaN with bounds="nan", and raise an error with bounds="raise".

Scattered points need the multilinear method, which is the default. The conservative method still resamples onto a new grid of cells.

named-arrays now depends on regridding~=3.6.

Fix: leaving axis out always raised an error, since its default passed a generator to na.shape_broadcasted(), which found no axes in it. It now resamples along every axis of the inputs of the function.

Behavior change: a component of the new inputs which isn't resampled used to be passed on to the result as given, so the result could claim other wavelengths than the ones its outputs were computed at. Now it must be None or equal to the function's own.

Stratified random spaces

Two bugs in the stratified random spaces, found while using them to sample the field and pupil of optika raytraces, are fixed (#274):

  • Range: the centers=True default of AbstractStratifiedRandomSpace never took effect, since each concrete class took centers=False from its linear space. The strata sat on the edges of the cells, including start and stop, so samples were drawn up to half a step outside the range. Each concrete class now declares centers=True, and centers=False still gives the old strata.
  • Independent components: with a scalar start, stop and num, a vector space drew one random offset and added it to every component, putting each sample on the diagonal of its stratum. Each component is now drawn from its own stream.

Behavior change: with a given seed, a stratified random space now draws different samples, unless it is a scalar space given centers=False, so results computed from them, like the spot diagrams of a raytrace, change too.

Full Changelog: v2.16.0...v2.17.0