nalgebra/nalgebra-sparse/src/ops/mod.rs

82 lines
2.6 KiB
Rust
Raw Normal View History

2021-01-22 21:32:13 +08:00
//! Sparse matrix arithmetic operations.
//!
//! TODO: Explain that users should prefer to use std ops unless they need to get more performance
//!
//! The available operations are organized by backend. Currently, only the [`serial`] backend
//! is available. In the future, backends that expose parallel operations may become available.
//!
//! Many routines are able to implicitly transpose matrices involved in the operation.
//! For example, the routine [`spadd_csr_prealloc`](serial::spadd_csr_prealloc) performs the
//! operation `C <- beta * C + alpha * op(A)`. Here `op(A)` indicates that the matrix `A` can
//! either be used as-is or transposed. The notation `op(A)` is represented in code by the
//! [`Op`] enum.
2020-12-02 23:56:22 +08:00
2020-12-10 20:30:37 +08:00
mod impl_std_ops;
2020-12-02 23:56:22 +08:00
pub mod serial;
2021-01-22 21:32:13 +08:00
/// Determines whether a matrix should be transposed in a given operation.
///
/// See the [module-level documentation](crate::ops) for the purpose of this enum.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Op<T> {
2021-01-22 21:32:13 +08:00
/// Indicates that the matrix should be used as-is.
NoOp(T),
2021-01-22 21:32:13 +08:00
/// Indicates that the matrix should be transposed.
Transpose(T),
}
impl<T> Op<T> {
2021-01-22 21:32:13 +08:00
/// Returns a reference to the inner value that the operation applies to.
pub fn inner_ref(&self) -> &T {
2021-01-06 20:10:43 +08:00
self.as_ref().into_inner()
}
2021-01-22 21:32:13 +08:00
/// Returns an `Op` applied to a reference of the inner value.
pub fn as_ref(&self) -> Op<&T> {
match self {
Op::NoOp(obj) => Op::NoOp(&obj),
Op::Transpose(obj) => Op::Transpose(&obj)
}
}
2020-12-02 23:56:22 +08:00
2021-01-22 21:32:13 +08:00
/// Converts the underlying data type.
pub fn convert<U>(self) -> Op<U>
where T: Into<U>
{
2020-12-21 22:13:31 +08:00
self.map_same_op(T::into)
}
2021-01-22 21:32:13 +08:00
/// Transforms the inner value with the provided function, but preserves the operation.
pub fn map_same_op<U, F: FnOnce(T) -> U>(self, f: F) -> Op<U> {
match self {
Op::NoOp(obj) => Op::NoOp(f(obj)),
Op::Transpose(obj) => Op::Transpose(f(obj))
}
2020-12-02 23:56:22 +08:00
}
2020-12-21 22:13:31 +08:00
2021-01-22 21:32:13 +08:00
/// Consumes the `Op` and returns the inner value.
2021-01-06 20:10:43 +08:00
pub fn into_inner(self) -> T {
2020-12-21 22:13:31 +08:00
match self {
Op::NoOp(obj) | Op::Transpose(obj) => obj,
}
}
/// Applies the transpose operation.
///
/// This operation follows the usual semantics of transposition. In particular, double
/// transposition is equivalent to no transposition.
pub fn transposed(self) -> Self {
match self {
Op::NoOp(obj) => Op::Transpose(obj),
Op::Transpose(obj) => Op::NoOp(obj)
}
}
2020-12-10 20:30:37 +08:00
}
impl<T> From<T> for Op<T> {
fn from(obj: T) -> Self {
Self::NoOp(obj)
}
}
2020-12-10 20:30:37 +08:00