pub struct Tensor { /* private fields */ }Expand description
An N-D array of f32 or f64 values that Rust owns, and that the host language (C, Python)
reads without a copy. The outputs of this crate are Tensor values. The inputs are
TensorView values.
§Data layout
A Tensor has a data pointer, a scalar type (dtype), a shape and a strides value for
each axis. The strides are in bytes. The value at the index (i0, i1, ...) is at the byte
offset i0 * strides[0] + i1 * strides[1] + ... from the data pointer.
The arrays use the column-major (Fortran) order of diffsol: the first axis changes fastest, and
the lane axis is the last axis. The arrays that this crate makes from diffsol values have these
layouts (s is the size of one value, and c is the column stride):
- A diffsol vector is
[n, nbatch], with the strides[s, c]. Each lane is one column. - A diffsol dense matrix is
[nrows, ncols, nbatch], with the strides[s, c, ncols * c]. Each lane is a column-major matrix. - A Rust
Vec<T>, for examplets, is[n], with the stride[s].
c is nrows * s for nalgebra. It can be larger for faer, which pads its columns. The padding
is not part of the array, and its memory is not initialized. A solution can also have spare
columns after the last time of each lane, which are not part of the array.
§Layout rules
Each Tensor and TensorView obeys these rules, which the constructors check:
- It has 1 to MAX_NDIM axes.
- The values of a column,
[:, j, k], are adjacent:strides[0]is the size of one value (or the first axis has 1 value or none). - The data pointer is aligned, and each stride is a multiple of the size of one value.
So each column is one slice, which Tensor::column and Tensor::columns give with no copy. The padding is only after a column, so a column never contains it. Tensor::index gives one value.
§Ownership
A Tensor always owns the value that holds its data (the owner), so the data stays valid
while the array exists.
Implementations§
Source§impl Tensor
impl Tensor
Sourcepub unsafe fn new<O: 'static>(
owner: O,
ptr: *const u8,
shape: &[usize],
strides: &[usize],
dtype: ScalarType,
) -> Self
pub unsafe fn new<O: 'static>( owner: O, ptr: *const u8, shape: &[usize], strides: &[usize], dtype: ScalarType, ) -> Self
Make an array that owns owner, with a shape and strides (in bytes) that obey the layout
rules. The Tensor docs give the data layout and the rules.
§Panics
If the layout does not obey the layout rules.
§Safety
ptr must point into data that owner holds on the heap, so that the data does not move
when owner moves into the array. For each index in shape, ptr plus the byte offset
from strides must point to a valid value of the type dtype. The data must not change
while the array exists.
Sourcepub fn view(&self) -> TensorView<'_>
pub fn view(&self) -> TensorView<'_>
A view of the array, with no copy.
Sourcepub fn strides(&self) -> &[usize]
pub fn strides(&self) -> &[usize]
The stride of each axis, in bytes. The Tensor docs give the data layout.
Sourcepub fn data_ptr(&self) -> *const u8
pub fn data_ptr(&self) -> *const u8
The pointer to the first value. It is valid while self exists, and the data must not
be changed through it.
Sourcepub fn dtype(&self) -> ScalarType
pub fn dtype(&self) -> ScalarType
The scalar type of the values.
Sourcepub fn index<T: Scalar>(
&self,
index: impl AsRef<[usize]>,
) -> Result<&T, DiffsolRtError>
pub fn index<T: Scalar>( &self, index: impl AsRef<[usize]>, ) -> Result<&T, DiffsolRtError>
A reference to the value at index, with one value for each axis, for example
tensor.index::<f64>([0, i, 0]). The scalar type must be T.
§Panics
If index does not have one value for each axis, or a value is out of range.
Sourcepub fn column<T: Scalar>(&self, index: &[usize]) -> Result<&[T], DiffsolRtError>
pub fn column<T: Scalar>(&self, index: &[usize]) -> Result<&[T], DiffsolRtError>
The column at index: the values [:, index[0], index[1], ...], as one slice of
shape[0] values, with no copy. index has one value for each axis after the first. The
scalar type must be T.
For a vector [n, nbatch], column(&[b]) is lane b. For a matrix
[nrows, ncols, nbatch], column(&[j, b]) is column j of lane b. For a 1D array,
column(&[]) is all the values.
§Panics
If index does not have one value for each axis after the first, or a value is out of
range.
Sourcepub fn columns<T: Scalar>(
&self,
) -> Result<impl Iterator<Item = &[T]> + '_, DiffsolRtError>
pub fn columns<T: Scalar>( &self, ) -> Result<impl Iterator<Item = &[T]> + '_, DiffsolRtError>
All the columns (see Tensor::column), in column-major order: the index on axis 1
changes fastest. Together, they give all the values in column-major order. The scalar
type must be T.
Trait Implementations§
Auto Trait Implementations§
impl !RefUnwindSafe for Tensor
impl !Send for Tensor
impl !Sync for Tensor
impl !UnwindSafe for Tensor
impl Forget for Tensor
impl Freeze for Tensor
impl Move for Tensor
impl Unpin for Tensor
impl UnsafeUnpin for Tensor
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<T, U> Imply<T> for U
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.