def sliding_window_view(x, window_shape, axis=None):
if isinstance(window_shape, int):
window_shape = (window_shape,)
else:
window_shape = tuple(window_shape)
if axis is None:
axes = tuple(range(x.ndim - len(window_shape), x.ndim))
elif isinstance(axis, int):
axes = (axis,)
else:
axes = tuple(axis)
if len(window_shape) != len(axes):
raise ValueError("window_shape and axis must match in length")
out_shape = list(x.shape)
for win, ax in zip(window_shape, axes):
if win > x.shape[ax]:
raise ValueError("window larger than axis length")
out_shape[ax] = x.shape[ax] - win + 1
out_shape = out_shape + list(window_shape)
import numpy as np
out = np.zeros(tuple(out_shape), dtype=x.dtype)
leading_iters = [range(out_shape[ax]) for ax in axes]
def _walk(prefix, depth):
if depth == len(leading_iters):
window_idx = tuple(prefix)
slc = [slice(None)] * x.ndim
for k, ax in enumerate(axes):
start = prefix[k]
slc[ax] = slice(start, start + window_shape[k])
block = x[tuple(slc)]
full_lead = list(x.shape)
out_lead = list(slc)
for k, ax in enumerate(axes):
out_lead[ax] = prefix[k]
full_idx = tuple(out_lead) + (slice(None),) * len(window_shape)
out[full_idx] = block
return
for v in leading_iters[depth]:
_walk(prefix + (v,), depth + 1)
_walk((), 0)
return out
def as_strided(x, shape=None, strides=None, subok=False, writeable=True):
import numpy as np
if strides is not None:
raise NotImplementedError(
"as_strided with explicit strides is not supported (no true views)"
)
if shape is None:
return x.copy()
target = tuple(shape)
if int(np.prod(target)) == int(np.prod(x.shape)):
return x.reshape(target)
return np.broadcast_to(x, target).copy()
def broadcast_shapes(*shapes):
import numpy as np
if not shapes:
return ()
result = []
nd = max(len(s) for s in shapes)
padded = [(1,) * (nd - len(s)) + tuple(s) for s in shapes]
for axis_dims in zip(*padded):
m = 1
for d in axis_dims:
if d == 1:
continue
if m == 1:
m = d
elif m != d:
raise ValueError(f"shapes are not broadcastable: {shapes}")
result.append(m)
return tuple(result)