acme_tensor/impls/
create.rs

1/*
2    Appellation: create <impls>
3    Contrib: FL03 <jo3mccain@icloud.com>
4*/
5use crate::prelude::IntoShape;
6use crate::tensor::{from_vec_with_kind, TensorBase};
7use num::traits::real::Real;
8use num::traits::{FromPrimitive, NumAssign, One, Zero};
9
10impl<T> TensorBase<T>
11where
12    T: Clone,
13{
14    /// Create a new tensor, whose elements are set to their default value
15    /// from the current shape.
16    pub fn default_like(&self) -> Self
17    where
18        T: Default,
19    {
20        Self::fill(self.shape(), T::default())
21    }
22
23    /// Create an empty tensor from the given shape
24    pub fn empty(shape: impl IntoShape) -> Self
25    where
26        T: Default,
27    {
28        Self::fill(shape, T::default())
29    }
30    /// Create a tensor, from the given shape, filled with the given value
31    pub fn fill(shape: impl IntoShape, value: T) -> Self {
32        let shape = shape.into_shape();
33        let store = vec![value; shape.size()];
34        from_vec_with_kind(false, shape, store)
35    }
36    /// Create a tensor, filled with some value, from the current shape
37    pub fn fill_like(&self, value: T) -> Self {
38        Self::fill(self.shape(), value)
39    }
40    pub fn like_with(&self, data: Vec<T>) -> Self {
41        from_vec_with_kind(false, self.shape(), data)
42    }
43}
44
45impl<T> TensorBase<T>
46where
47    T: Copy + NumAssign + PartialOrd,
48{
49    /// Create a tensor within a range of values
50    pub fn arange(start: T, end: T, step: T) -> Self {
51        if T::is_zero(&step) {
52            panic!("step must be non-zero");
53        }
54        let mut store = Vec::new();
55        let mut value = start;
56        while value < end {
57            store.push(value);
58            value += step;
59        }
60        Self::from_vec(store)
61    }
62    /// Create an identity matrix of a certain size
63    pub fn eye(size: usize) -> Self {
64        let mut store = Vec::with_capacity(size * size);
65        for i in 0..size {
66            for j in 0..size {
67                store.push(if i == j { T::one() } else { T::zero() });
68            }
69        }
70        Self::from_shape_vec((size, size), store)
71    }
72    /// Create a tensor with a certain number of elements, evenly spaced
73    /// between the provided start and end values
74    pub fn linspace(start: T, end: T, steps: usize) -> Self
75    where
76        T: FromPrimitive,
77    {
78        let step = (end - start) / T::from_usize(steps).unwrap();
79        Self::arange(start, end, step)
80    }
81
82    pub fn logspace(start: T, end: T, steps: usize) -> Self
83    where
84        T: Real,
85    {
86        let start = start.log2();
87        let end = end.log2();
88        let step = (end - start) / T::from(steps).unwrap();
89        let mut store = Vec::with_capacity(steps);
90        let mut value: T = start;
91        for _ in 0..steps {
92            store.push(value.exp2());
93            value += step;
94        }
95        from_vec_with_kind(false, (store.len(),), store)
96    }
97
98    pub fn geomspace(start: T, end: T, steps: usize) -> Self
99    where
100        T: Real,
101    {
102        let start = start.log10();
103        let end = end.log10();
104        let step = (end - start) / T::from(steps).unwrap();
105        let mut store = Vec::with_capacity(steps);
106        let mut value: T = start;
107        for _ in 0..steps {
108            store.push(value.exp());
109            value += step;
110        }
111        from_vec_with_kind(false, (store.len(),), store)
112    }
113}
114
115impl<T> TensorBase<T>
116where
117    T: Clone + One,
118{
119    /// Create a tensor, filled with ones, from the given shape
120    pub fn ones(shape: impl IntoShape) -> Self {
121        Self::fill(shape, T::one())
122    }
123    /// Create a tensor, filled with ones, from the shape of another tensor
124    pub fn ones_from(tensor: &TensorBase<T>) -> Self {
125        Self::ones(tensor.shape())
126    }
127    /// Create a tensor, filled with ones, from the shape of the tensor
128    pub fn ones_like(&self) -> Self {
129        Self::ones(self.shape())
130    }
131}
132
133impl<T> TensorBase<T>
134where
135    T: Clone + Zero,
136{
137    /// Create a tensor, filled with zeros, from the given shape
138    pub fn zeros(shape: impl IntoShape) -> Self {
139        Self::fill(shape, T::zero())
140    }
141    /// Create a tensor, filled with zeros, from the shape of another tensor
142    pub fn zeros_from(tensor: &TensorBase<T>) -> Self {
143        Self::zeros(tensor.shape())
144    }
145    /// Create a tensor, filled with zeros, from the shape of the tensor
146    pub fn zeros_like(&self) -> Self {
147        Self::zeros(self.shape())
148    }
149}