mirror of
https://github.com/drewcassidy/vector-victor.git
synced 2024-09-01 14:58:35 +00:00
More API and fleshing things out
This commit is contained in:
parent
e928ed6926
commit
969a1ece67
@ -7,3 +7,4 @@ edition = "2021"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
generic_parameterize = "0.1.0"
|
generic_parameterize = "0.1.0"
|
||||||
|
num-traits = "0.2.15"
|
||||||
|
@ -3,5 +3,6 @@ extern crate core;
|
|||||||
pub mod index;
|
pub mod index;
|
||||||
mod macros;
|
mod macros;
|
||||||
mod matrix;
|
mod matrix;
|
||||||
|
mod matrix_traits;
|
||||||
|
|
||||||
pub use matrix::{Matrix, Scalar, Vector};
|
pub use matrix::{Matrix, Scalar, Vector};
|
||||||
|
@ -102,7 +102,7 @@ macro_rules! _impl_op_m_internal {
|
|||||||
($ops_trait:ident, $ops_fn:ident, $lhs:ty, $out:ty) => {
|
($ops_trait:ident, $ops_fn:ident, $lhs:ty, $out:ty) => {
|
||||||
impl<L, const M: usize, const N: usize> ::std::ops::$ops_trait for $lhs
|
impl<L, const M: usize, const N: usize> ::std::ops::$ops_trait for $lhs
|
||||||
where
|
where
|
||||||
L: ::std::ops::$ops_trait<Output = L> + Scalar,
|
L: ::std::ops::$ops_trait<Output = L> + Copy,
|
||||||
{
|
{
|
||||||
type Output = $out;
|
type Output = $out;
|
||||||
|
|
||||||
@ -125,8 +125,8 @@ macro_rules! _impl_op_mm_internal {
|
|||||||
($ops_trait:ident, $ops_fn:ident, $lhs:ty, $rhs:ty, $out:ty) => {
|
($ops_trait:ident, $ops_fn:ident, $lhs:ty, $rhs:ty, $out:ty) => {
|
||||||
impl<L, R, const M: usize, const N: usize> ::std::ops::$ops_trait<$rhs> for $lhs
|
impl<L, R, const M: usize, const N: usize> ::std::ops::$ops_trait<$rhs> for $lhs
|
||||||
where
|
where
|
||||||
L: ::std::ops::$ops_trait<R, Output = L> + Scalar,
|
L: ::std::ops::$ops_trait<R, Output = L> + Copy,
|
||||||
R: Scalar,
|
R: Copy,
|
||||||
{
|
{
|
||||||
type Output = $out;
|
type Output = $out;
|
||||||
|
|
||||||
@ -149,8 +149,8 @@ macro_rules! _impl_opassign_mm_internal {
|
|||||||
($ops_trait:ident, $ops_fn:ident, $lhs:ty, $rhs:ty, $out:ty) => {
|
($ops_trait:ident, $ops_fn:ident, $lhs:ty, $rhs:ty, $out:ty) => {
|
||||||
impl<L, R, const M: usize, const N: usize> ::std::ops::$ops_trait<$rhs> for $lhs
|
impl<L, R, const M: usize, const N: usize> ::std::ops::$ops_trait<$rhs> for $lhs
|
||||||
where
|
where
|
||||||
L: ::std::ops::$ops_trait<R> + Scalar,
|
L: ::std::ops::$ops_trait<R> + Copy,
|
||||||
R: Scalar,
|
R: Copy,
|
||||||
{
|
{
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn $ops_fn(&mut self, other: $rhs) {
|
fn $ops_fn(&mut self, other: $rhs) {
|
||||||
@ -169,8 +169,8 @@ macro_rules! _impl_op_ms_internal {
|
|||||||
($ops_trait:ident, $ops_fn:ident, $lhs:ty, $rhs:ty, $out:ty) => {
|
($ops_trait:ident, $ops_fn:ident, $lhs:ty, $rhs:ty, $out:ty) => {
|
||||||
impl<L, R, const M: usize, const N: usize> ::std::ops::$ops_trait<$rhs> for $lhs
|
impl<L, R, const M: usize, const N: usize> ::std::ops::$ops_trait<$rhs> for $lhs
|
||||||
where
|
where
|
||||||
L: ::std::ops::$ops_trait<R, Output = L> + Scalar,
|
L: ::std::ops::$ops_trait<R, Output = L> + Copy,
|
||||||
R: Scalar,
|
R: Copy + Num,
|
||||||
{
|
{
|
||||||
type Output = $out;
|
type Output = $out;
|
||||||
|
|
||||||
@ -193,8 +193,8 @@ macro_rules! _impl_opassign_ms_internal {
|
|||||||
($ops_trait:ident, $ops_fn:ident, $lhs:ty, $rhs:ty, $out:ty) => {
|
($ops_trait:ident, $ops_fn:ident, $lhs:ty, $rhs:ty, $out:ty) => {
|
||||||
impl<L, R, const M: usize, const N: usize> ::std::ops::$ops_trait<$rhs> for $lhs
|
impl<L, R, const M: usize, const N: usize> ::std::ops::$ops_trait<$rhs> for $lhs
|
||||||
where
|
where
|
||||||
L: ::std::ops::$ops_trait<R> + Scalar,
|
L: ::std::ops::$ops_trait<R> + Copy,
|
||||||
R: Scalar,
|
R: Copy + Num,
|
||||||
{
|
{
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn $ops_fn(&mut self, r: $rhs) {
|
fn $ops_fn(&mut self, r: $rhs) {
|
||||||
|
174
src/matrix.rs
174
src/matrix.rs
@ -1,8 +1,11 @@
|
|||||||
use crate::impl_matrix_op;
|
use crate::impl_matrix_op;
|
||||||
use crate::index::Index2D;
|
use crate::index::Index2D;
|
||||||
|
use crate::matrix_traits::Mult;
|
||||||
|
use num_traits::{Num, One, Zero};
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::iter::{zip, Flatten, Product, Sum};
|
use std::iter::{zip, Flatten, Product, Sum};
|
||||||
use std::ops::{AddAssign, Deref, DerefMut, Index, IndexMut, MulAssign};
|
use std::ops::{Add, AddAssign, Deref, DerefMut, Index, IndexMut, Mul, MulAssign, Neg, Sub};
|
||||||
|
use std::process::Output;
|
||||||
|
|
||||||
/// A Scalar that a [Matrix] can be made up of.
|
/// A Scalar that a [Matrix] can be made up of.
|
||||||
///
|
///
|
||||||
@ -25,15 +28,29 @@ where
|
|||||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||||
pub struct Matrix<T, const M: usize, const N: usize>
|
pub struct Matrix<T, const M: usize, const N: usize>
|
||||||
where
|
where
|
||||||
T: Scalar,
|
T: Copy,
|
||||||
{
|
{
|
||||||
data: [[T; N]; M],
|
data: [[T; N]; M], // Column-Major order
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An alias for a [Matrix] with a single column
|
/// An alias for a [Matrix] with a single column
|
||||||
pub type Vector<T, const N: usize> = Matrix<T, N, 1>;
|
pub type Vector<T, const N: usize> = Matrix<T, N, 1>;
|
||||||
|
|
||||||
impl<T: Scalar, const M: usize, const N: usize> Matrix<T, M, N> {
|
pub trait Dot<R> {
|
||||||
|
type Output;
|
||||||
|
#[must_use]
|
||||||
|
fn dot(&self, rhs: &R) -> Output;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Cross<R> {
|
||||||
|
#[must_use]
|
||||||
|
fn cross_r(&self, rhs: &R) -> Self;
|
||||||
|
#[must_use]
|
||||||
|
fn cross_l(&self, rhs: &R) -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simple access functions that only require T be copyable
|
||||||
|
impl<T: Copy, const M: usize, const N: usize> Matrix<T, M, N> {
|
||||||
/// Generate a new matrix from a 2D Array
|
/// Generate a new matrix from a 2D Array
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
@ -95,8 +112,8 @@ impl<T: Scalar, const M: usize, const N: usize> Matrix<T, M, N> {
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn from_rows<I>(iter: I) -> Self
|
pub fn from_rows<I>(iter: I) -> Self
|
||||||
where
|
where
|
||||||
Self: Default,
|
|
||||||
I: IntoIterator<Item = Vector<T, N>>,
|
I: IntoIterator<Item = Vector<T, N>>,
|
||||||
|
Self: Default,
|
||||||
{
|
{
|
||||||
let mut result = Self::default();
|
let mut result = Self::default();
|
||||||
for (m, row) in iter.into_iter().enumerate().take(M) {
|
for (m, row) in iter.into_iter().enumerate().take(M) {
|
||||||
@ -124,8 +141,8 @@ impl<T: Scalar, const M: usize, const N: usize> Matrix<T, M, N> {
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn from_cols<I>(iter: I) -> Self
|
pub fn from_cols<I>(iter: I) -> Self
|
||||||
where
|
where
|
||||||
Self: Default,
|
|
||||||
I: IntoIterator<Item = Vector<T, M>>,
|
I: IntoIterator<Item = Vector<T, M>>,
|
||||||
|
Self: Default,
|
||||||
{
|
{
|
||||||
let mut result = Self::default();
|
let mut result = Self::default();
|
||||||
for (n, col) in iter.into_iter().enumerate().take(N) {
|
for (n, col) in iter.into_iter().enumerate().take(N) {
|
||||||
@ -143,17 +160,17 @@ impl<T: Scalar, const M: usize, const N: usize> Matrix<T, M, N> {
|
|||||||
/// assert!(vec![1,2,3,4].iter().eq(my_matrix.elements()))
|
/// assert!(vec![1,2,3,4].iter().eq(my_matrix.elements()))
|
||||||
/// ```
|
/// ```
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn elements<'a>(&'a self) -> impl Iterator<Item = &T> + 'a {
|
pub fn elements<'a>(&'a self) -> impl Iterator<Item = &'a T> + 'a {
|
||||||
self.data.iter().flatten()
|
self.data.iter().flatten()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a mutable iterator over the elements of the matrix in row-major order.
|
/// Returns a mutable iterator over the elements of the matrix in row-major order.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn elements_mut<'a>(&'a mut self) -> impl Iterator<Item = &mut T> + 'a {
|
pub fn elements_mut<'a>(&'a mut self) -> impl Iterator<Item = &'a mut T> + 'a {
|
||||||
self.data.iter_mut().flatten()
|
self.data.iter_mut().flatten()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a reference to the element at that position in the matrix or `None` if out of bounds.
|
/// Returns a reference to the element at that position in the matrix, or `None` if out of bounds.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
@ -163,6 +180,11 @@ impl<T: Scalar, const M: usize, const N: usize> Matrix<T, M, N> {
|
|||||||
///
|
///
|
||||||
/// // element at index 2 is the same as the element at (row 1, column 0).
|
/// // element at index 2 is the same as the element at (row 1, column 0).
|
||||||
/// assert_eq!(my_matrix.get(2), my_matrix.get((1,0)));
|
/// assert_eq!(my_matrix.get(2), my_matrix.get((1,0)));
|
||||||
|
///
|
||||||
|
/// // my_matrix.get() is equivalent to my_matrix[],
|
||||||
|
/// // but returns an Option instead of panicking
|
||||||
|
/// assert_eq!(my_matrix.get(2), Some(&my_matrix[2]));
|
||||||
|
///
|
||||||
/// // index 4 is out of range, so get(4) returns None.
|
/// // index 4 is out of range, so get(4) returns None.
|
||||||
/// assert_eq!(my_matrix.get(4), None);
|
/// assert_eq!(my_matrix.get(4), None);
|
||||||
/// ```
|
/// ```
|
||||||
@ -173,6 +195,7 @@ impl<T: Scalar, const M: usize, const N: usize> Matrix<T, M, N> {
|
|||||||
Some(&self.data[m][n])
|
Some(&self.data[m][n])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a mutable reference to the element at that position in the matrix, or `None` if out of bounds.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn get_mut(&mut self, index: impl Index2D) -> Option<&mut T> {
|
pub fn get_mut(&mut self, index: impl Index2D) -> Option<&mut T> {
|
||||||
@ -180,14 +203,28 @@ impl<T: Scalar, const M: usize, const N: usize> Matrix<T, M, N> {
|
|||||||
Some(&mut self.data[m][n])
|
Some(&mut self.data[m][n])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a row of the matrix. panics if index is out of bounds
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use vector_victor::{Matrix, Vector};
|
||||||
|
/// let my_matrix = Matrix::new([[1,2],[3,4]]);
|
||||||
|
///
|
||||||
|
/// // row at index 1
|
||||||
|
/// assert_eq!(my_matrix.row(1), Vector::vec([3,4]));
|
||||||
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn row(&self, m: usize) -> Option<Vector<T, N>> {
|
pub fn row(&self, m: usize) -> Vector<T, N> {
|
||||||
if m < M {
|
assert!(
|
||||||
Some(Vector::<T, N>::vec(self.data[m]))
|
m < M,
|
||||||
} else {
|
"Row index {} out of bounds for {}x{} matrix",
|
||||||
None
|
m,
|
||||||
}
|
M,
|
||||||
|
N
|
||||||
|
);
|
||||||
|
Vector::<T, N>::vec(self.data[m])
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -231,17 +268,41 @@ impl<T: Scalar, const M: usize, const N: usize> Matrix<T, M, N> {
|
|||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn rows<'a>(&'a self) -> impl Iterator<Item = Vector<T, N>> + 'a {
|
pub fn rows<'a>(&'a self) -> impl Iterator<Item = Vector<T, N>> + 'a {
|
||||||
(0..M).map(|m| self.row(m).expect("invalid row reached while iterating"))
|
(0..M).map(|m| self.row(m))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn cols<'a>(&'a self) -> impl Iterator<Item = Vector<T, M>> + 'a {
|
pub fn cols<'a>(&'a self) -> impl Iterator<Item = Vector<T, M>> + 'a {
|
||||||
(0..N).map(|n| self.col(n).expect("invalid column reached while iterating"))
|
(0..N).map(|n| self.col(n).expect("invalid column reached while iterating"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn transpose(&self) -> Matrix<T, N, M>
|
||||||
|
where
|
||||||
|
Matrix<T, N, M>: Default,
|
||||||
|
{
|
||||||
|
Matrix::<T, N, M>::from_rows(self.cols())
|
||||||
|
}
|
||||||
|
|
||||||
|
// pub fn mmul<const P: usize, R, O>(&self, rhs: &Matrix<R, P, N>) -> Matrix<T, P, M>
|
||||||
|
// where
|
||||||
|
// R: Num,
|
||||||
|
// T: Scalar + Mul<R, Output = T>,
|
||||||
|
// Vector<T, N>: Dot<Vector<R, M>, Output = T>,
|
||||||
|
// {
|
||||||
|
// let mut result: Matrix<T, P, M> = Zero::zero();
|
||||||
|
//
|
||||||
|
// for (m, a) in self.rows().enumerate() {
|
||||||
|
// for (n, b) in rhs.cols().enumerate() {
|
||||||
|
// // result[(m, n)] = a.dot(b)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1D vector implementations
|
// 1D vector implementations
|
||||||
impl<T: Scalar, const M: usize> Matrix<T, M, 1> {
|
impl<T: Copy, const M: usize> Vector<T, M> {
|
||||||
/// Create a vector from a 1D array.
|
/// Create a vector from a 1D array.
|
||||||
/// Note that vectors are always column vectors unless explicitly instantiated as row vectors
|
/// Note that vectors are always column vectors unless explicitly instantiated as row vectors
|
||||||
///
|
///
|
||||||
@ -249,7 +310,7 @@ impl<T: Scalar, const M: usize> Matrix<T, M, 1> {
|
|||||||
///
|
///
|
||||||
/// * `data`: A 1D array of elements to copy into the new vector
|
/// * `data`: A 1D array of elements to copy into the new vector
|
||||||
///
|
///
|
||||||
/// returns: Matrix<T, { M }, 1>
|
/// returns: Vector<T, M>
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
@ -260,17 +321,49 @@ impl<T: Scalar, const M: usize> Matrix<T, M, 1> {
|
|||||||
/// assert_eq!(my_vector, Matrix::new([[1],[2],[3],[4]]));
|
/// assert_eq!(my_vector, Matrix::new([[1],[2],[3],[4]]));
|
||||||
/// ```
|
/// ```
|
||||||
pub fn vec(data: [T; M]) -> Self {
|
pub fn vec(data: [T; M]) -> Self {
|
||||||
return Matrix::<T, M, 1> {
|
return Vector::<T, M> {
|
||||||
data: data.map(|e| [e; 1]),
|
data: data.map(|e| [e]),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: Num + Copy, R: Num + Copy, const M: usize> Dot<Vector<R, M>> for Vector<T, M>
|
||||||
|
where
|
||||||
|
for<'a> Output: Sum<&'a T>,
|
||||||
|
for<'b> &'b Self: Mul<&'b Vector<R, M>, Output = Self>,
|
||||||
|
{
|
||||||
|
type Output = T;
|
||||||
|
fn dot(&self, rhs: &Matrix<R, M, 1>) -> Output {
|
||||||
|
(self * rhs).elements().sum::<Output>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Scalar> Vector<T, 3> {
|
||||||
|
pub fn cross_r<R: Scalar>(&self, rhs: Vector<R, 3>) -> Self
|
||||||
|
where
|
||||||
|
T: Mul<R, Output = T> + Sub<T, Output = T>,
|
||||||
|
{
|
||||||
|
Self::vec([
|
||||||
|
(self[1] * rhs[2]) - (self[2] * rhs[1]),
|
||||||
|
(self[2] * rhs[0]) - (self[0] * rhs[2]),
|
||||||
|
(self[0] * rhs[1]) - (self[1] * rhs[0]),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cross_l<R: Scalar>(&self, rhs: Vector<R, 3>) -> Self
|
||||||
|
where
|
||||||
|
T: Mul<R, Output = T> + Sub<T, Output = T>,
|
||||||
|
Self: Neg<Output = Self>,
|
||||||
|
{
|
||||||
|
-self.cross_r(rhs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Index
|
// Index
|
||||||
impl<I, T, const M: usize, const N: usize> Index<I> for Matrix<T, M, N>
|
impl<I, T, const M: usize, const N: usize> Index<I> for Matrix<T, M, N>
|
||||||
where
|
where
|
||||||
I: Index2D,
|
I: Index2D,
|
||||||
T: Scalar,
|
T: Copy,
|
||||||
{
|
{
|
||||||
type Output = T;
|
type Output = T;
|
||||||
|
|
||||||
@ -295,13 +388,28 @@ where
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default
|
// Default
|
||||||
impl<T: Scalar, const M: usize, const N: usize> Default for Matrix<T, M, N> {
|
impl<T: Copy + Default, const M: usize, const N: usize> Default for Matrix<T, M, N> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Matrix {
|
Matrix::new([[T::default(); N]; M])
|
||||||
data: [[T::default(); N]; M],
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Zero
|
||||||
|
impl<T: Copy + Zero, const M: usize, const N: usize> Zero for Matrix<T, M, N> {
|
||||||
|
fn zero() -> Self {
|
||||||
|
Matrix::new([[T::zero(); N]; M])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_zero(&self) -> bool {
|
||||||
|
self.elements().all(|e| e.is_zero())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// One
|
||||||
|
impl<T: Copy + One, const M: usize, const N: usize> One for Matrix<T, M, N> {
|
||||||
|
fn one() -> Self {
|
||||||
|
Matrix::new([[T::one(); N]; M])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,9 +471,12 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Scalar + AddAssign, const M: usize, const N: usize> Sum for Matrix<T, M, N> {
|
impl<T: Scalar + AddAssign, const M: usize, const N: usize> Sum for Matrix<T, M, N>
|
||||||
|
where
|
||||||
|
Self: Zero + AddAssign,
|
||||||
|
{
|
||||||
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
|
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
|
||||||
let mut sum = Self::default();
|
let mut sum = Self::zero();
|
||||||
|
|
||||||
for m in iter {
|
for m in iter {
|
||||||
sum += m;
|
sum += m;
|
||||||
@ -375,9 +486,12 @@ impl<T: Scalar + AddAssign, const M: usize, const N: usize> Sum for Matrix<T, M,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Scalar + MulAssign, const M: usize, const N: usize> Product for Matrix<T, M, N> {
|
impl<T: Scalar + MulAssign, const M: usize, const N: usize> Product for Matrix<T, M, N>
|
||||||
|
where
|
||||||
|
Self: One + MulAssign,
|
||||||
|
{
|
||||||
fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
|
fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
|
||||||
let mut prod = Self::default();
|
let mut prod = Self::one();
|
||||||
|
|
||||||
for m in iter {
|
for m in iter {
|
||||||
prod *= m;
|
prod *= m;
|
||||||
|
22
src/matrix_traits.rs
Normal file
22
src/matrix_traits.rs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
use num_traits::Pow;
|
||||||
|
|
||||||
|
pub trait Dot<RHS> {
|
||||||
|
type Output;
|
||||||
|
fn dot(&self, other: &RHS) -> <Self as Dot<RHS>>::Output;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Cross<RHS> {
|
||||||
|
type Output;
|
||||||
|
fn cross(&self, other: &RHS) -> <Self as Cross<RHS>>::Output;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Mult<RHS> {
|
||||||
|
type Output;
|
||||||
|
fn mult(&self, other: &RHS) -> <Self as Mult<RHS>>::Output;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Magnitude<T: Pow<f32>> {
|
||||||
|
fn sqrmag(&self) -> T;
|
||||||
|
fn mag(&self) -> <T as Pow<f32>>::Output;
|
||||||
|
fn norm(&self) -> Self;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user