chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 13:30:25 +08:00
commit f19b2512d7
562 changed files with 38082 additions and 0 deletions
+19
View File
@@ -0,0 +1,19 @@
from prml.nn.array.broadcast import broadcast_to
from prml.nn.array.flatten import flatten
from prml.nn.array.reshape import reshape, reshape_method
from prml.nn.array.split import split
from prml.nn.array.transpose import transpose, transpose_method
from prml.nn.tensor.tensor import Tensor
Tensor.flatten = flatten
Tensor.reshape = reshape_method
Tensor.transpose = transpose_method
__all__ = [
"broadcast_to",
"flatten",
"reshape",
"split",
"transpose"
]
+36
View File
@@ -0,0 +1,36 @@
import numpy as np
from prml.nn.tensor.constant import Constant
from prml.nn.tensor.tensor import Tensor
from prml.nn.function import Function
class BroadcastTo(Function):
"""
Broadcast a tensor to an new shape
"""
def forward(self, x, shape):
x = self._convert2tensor(x)
self.x = x
output = np.broadcast_to(x.value, shape)
if isinstance(self.x, Constant):
return Constant(output)
return Tensor(output, function=self)
def backward(self, delta):
dx = delta
if delta.ndim != self.x.ndim:
dx = dx.sum(axis=tuple(range(dx.ndim - self.x.ndim)))
if isinstance(dx, np.number):
dx = np.array(dx)
axis = tuple(i for i, len_ in enumerate(self.x.shape) if len_ == 1)
if axis:
dx = dx.sum(axis=axis, keepdims=True)
self.x.backward(dx)
def broadcast_to(x, shape):
"""
Broadcast a tensor to an new shape
"""
return BroadcastTo().forward(x, shape)
+28
View File
@@ -0,0 +1,28 @@
from prml.nn.tensor.constant import Constant
from prml.nn.tensor.tensor import Tensor
from prml.nn.function import Function
class Flatten(Function):
"""
flatten array
"""
def forward(self, x):
x = self._convert2tensor(x)
self._atleast_ndim(x, 2)
self.x = x
if isinstance(self.x, Constant):
return Constant(x.value.flatten())
return Tensor(x.value.flatten(), function=self)
def backward(self, delta):
dx = delta.reshape(*self.x.shape)
self.x.backward(dx)
def flatten(x):
"""
flatten N-dimensional array (N >= 2)
"""
return Flatten().forward(x)
+32
View File
@@ -0,0 +1,32 @@
from prml.nn.tensor.constant import Constant
from prml.nn.tensor.tensor import Tensor
from prml.nn.function import Function
class Reshape(Function):
"""
reshape array
"""
def forward(self, x, shape):
x = self._convert2tensor(x)
self._atleast_ndim(x, 1)
self.x = x
if isinstance(self.x, Constant):
return Constant(x.value.reshape(*shape))
return Tensor(x.value.reshape(*shape), function=self)
def backward(self, delta):
dx = delta.reshape(*self.x.shape)
self.x.backward(dx)
def reshape(x, shape):
"""
reshape N-dimensional array (N >= 1)
"""
return Reshape().forward(x, shape)
def reshape_method(x, *args):
return Reshape().forward(x, args)
+48
View File
@@ -0,0 +1,48 @@
import numpy as np
from prml.nn.tensor.constant import Constant
from prml.nn.tensor.tensor import Tensor
from prml.nn.function import Function
class Nth(Function):
def __init__(self, n):
self.n = n
def forward(self, x):
self.x = x
if isinstance(self.x, Constant):
return Constant(x.value)
return Tensor(x.value, function=self)
def backward(self, delta):
self.x.backward(delta, n=self.n)
class Split(Function):
def __init__(self, indices_or_sections, axis=-1):
self.indices_or_sections = indices_or_sections
self.axis = axis
def forward(self, x):
x = self._convert2tensor(x)
self._atleast_ndim(x, 1)
self.x = x
output = np.split(x.value, self.indices_or_sections, self.axis)
if isinstance(self.x, Constant):
return tuple([Constant(out) for out in output])
self.n_output = len(output)
self.delta = [None for _ in output]
return tuple([Tensor(out, function=self) for out in output])
def backward(self, delta, n):
self.delta[n] = delta
if all([d is not None for d in self.delta]):
dx = np.concatenate(self.delta, axis=self.axis)
self.x.backward(dx)
def split(x, indices_or_sections, axis=-1):
output = Split(indices_or_sections, axis).forward(x)
return tuple([Nth(i).forward(out) for i, out in enumerate(output)])
+36
View File
@@ -0,0 +1,36 @@
import numpy as np
from prml.nn.tensor.constant import Constant
from prml.nn.tensor.tensor import Tensor
from prml.nn.function import Function
class Transpose(Function):
def __init__(self, axes=None):
self.axes = axes
def forward(self, x):
x = self._convert2tensor(x)
if self.axes is not None:
self._equal_ndim(x, len(self.axes))
self.x = x
if isinstance(self.x, Constant):
return Constant(np.transpose(x.value, self.axes))
return Tensor(np.transpose(x.value, self.axes), function=self)
def backward(self, delta):
if self.axes is None:
dx = np.transpose(delta)
else:
dx = np.transpose(delta, np.argsort(self.axes))
self.x.backward(dx)
def transpose(x, axes=None):
return Transpose(axes).forward(x)
def transpose_method(x, *args):
if args == ():
args = None
return Transpose(args).forward(x)