use crate::prelude::IntoShape;
use crate::tensor::{from_vec_with_kind, TensorBase};
use num::traits::real::Real;
use num::traits::{FromPrimitive, NumAssign, One, Zero};
impl<T> TensorBase<T>
where
T: Clone,
{
pub fn default_like(&self) -> Self
where
T: Default,
{
Self::fill(self.shape(), T::default())
}
pub fn empty(shape: impl IntoShape) -> Self
where
T: Default,
{
Self::fill(shape, T::default())
}
pub fn fill(shape: impl IntoShape, value: T) -> Self {
let shape = shape.into_shape();
let store = vec![value; shape.size()];
from_vec_with_kind(false, shape, store)
}
pub fn fill_like(&self, value: T) -> Self {
Self::fill(self.shape(), value)
}
}
impl<T> TensorBase<T>
where
T: Copy + NumAssign + PartialOrd,
{
pub fn arange(start: T, end: T, step: T) -> Self {
if T::is_zero(&step) {
panic!("step must be non-zero");
}
let mut store = Vec::new();
let mut value = start;
while value < end {
store.push(value);
value += step;
}
Self::from_vec(store)
}
pub fn eye(size: usize) -> Self {
let mut store = Vec::with_capacity(size * size);
for i in 0..size {
for j in 0..size {
store.push(if i == j { T::one() } else { T::zero() });
}
}
Self::from_shape_vec((size, size), store)
}
pub fn linspace(start: T, end: T, steps: usize) -> Self
where
T: FromPrimitive,
{
let step = (end - start) / T::from_usize(steps).unwrap();
Self::arange(start, end, step)
}
pub fn logspace(start: T, end: T, steps: usize) -> Self
where
T: Real,
{
let start = start.log2();
let end = end.log2();
let step = (end - start) / T::from(steps).unwrap();
let mut store = Vec::with_capacity(steps);
let mut value: T = start;
for _ in 0..steps {
store.push(value.exp2());
value += step;
}
from_vec_with_kind(false, (store.len(),), store)
}
pub fn geomspace(start: T, end: T, steps: usize) -> Self
where
T: Real,
{
let start = start.log10();
let end = end.log10();
let step = (end - start) / T::from(steps).unwrap();
let mut store = Vec::with_capacity(steps);
let mut value: T = start;
for _ in 0..steps {
store.push(value.exp());
value += step;
}
from_vec_with_kind(false, (store.len(),), store)
}
}
impl<T> TensorBase<T>
where
T: Clone + One,
{
pub fn ones(shape: impl IntoShape) -> Self {
Self::fill(shape, T::one())
}
pub fn ones_from(tensor: &TensorBase<T>) -> Self {
Self::ones(tensor.shape())
}
pub fn ones_like(&self) -> Self {
Self::ones(self.shape())
}
}
impl<T> TensorBase<T>
where
T: Clone + Zero,
{
pub fn zeros(shape: impl IntoShape) -> Self {
Self::fill(shape, T::zero())
}
pub fn zeros_from(tensor: &TensorBase<T>) -> Self {
Self::zeros(tensor.shape())
}
pub fn zeros_like(&self) -> Self {
Self::zeros(self.shape())
}
}