Skip to main content

ariadnetor_tensor/dense/
scalar_ops.rs

1//! Scalar-dependent operations for `DenseTensorData<T>` (conjugate,
2//! norm, complex conversion).
3//!
4//! Element-wise transforms (`conj`, `real`, `imag`, `to_complex`)
5//! preserve the layout; norm-related operations route through the
6//! storage half.
7
8use crate::DenseTensorData;
9
10impl<T> DenseTensorData<T>
11where
12    T: ariadnetor_core::Scalar,
13{
14    /// Element-wise complex conjugate.
15    pub fn conj(&self) -> Self {
16        self.map(|x| x.conj())
17    }
18
19    /// Convert each element to its complex representation.
20    pub fn to_complex(&self) -> DenseTensorData<T::Complex> {
21        self.map(|x| x.into_complex())
22    }
23
24    /// Extract the real part of each element.
25    pub fn real(&self) -> DenseTensorData<T::Real> {
26        self.map(|x| x.re())
27    }
28
29    /// Extract the imaginary part of each element.
30    pub fn imag(&self) -> DenseTensorData<T::Real> {
31        self.map(|x| x.im())
32    }
33
34    /// Compute Frobenius norm: √(Σ |element|²).
35    pub fn norm_frobenius(&self) -> T::Real {
36        self.storage().norm_frobenius()
37    }
38
39    /// Compute Frobenius norm (alias for [`norm_frobenius`](Self::norm_frobenius)).
40    pub fn norm(&self) -> T::Real {
41        self.storage().norm()
42    }
43
44    /// Normalize to unit Frobenius norm (in-place).
45    ///
46    /// Returns the norm before normalization. Panics if the tensor
47    /// has zero norm.
48    pub fn normalize(&mut self) -> T::Real {
49        self.storage_mut().normalize()
50    }
51
52    /// Normalize and return a new tensor (out-of-place).
53    ///
54    /// Returns `(normalized_tensor, original_norm)`. Panics if the
55    /// tensor has zero norm.
56    pub fn normalized(&self) -> (Self, T::Real) {
57        let mut result = self.clone();
58        let norm = result.normalize();
59        (result, norm)
60    }
61}