1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//! Matrix laboratory.

#[cfg(test)]
extern crate assert;

#[cfg(feature = "acceleration")]
extern crate blas;

#[cfg(feature = "complex")]
extern crate complex;

#[cfg(feature = "acceleration")]
extern crate lapack;

use std::convert::Into;
use std::{error, fmt};

use format::Conventional;

/// A matrix.
pub trait Matrix: Into<Conventional<<Self as Matrix>::Element>> + Size {
    /// The element type.
    type Element: Element;

    /// Count nonzero elements.
    fn nonzeros(&self) -> usize;

    /// Create a zero matrix.
    fn zero<S: Size>(S) -> Self;
}

/// A macro for composing matrices in the natural order.
///
/// The data of a generic matrix is conventionally stored in the column-major
/// order; see `format::Conventional`. Consequently, the vector
///
/// ```norun
/// vec![
///     1.0, 2.0, 3.0, 4.0,
///     5.0, 6.0, 7.0, 8.0,
/// ]
/// ```
///
/// corresponds to the following matrix with four rows and two columns:
///
/// ```math
/// ┌            ┐
/// │  1.0  5.0  │
/// │  2.0  6.0  │
/// │  3.0  7.0  │
/// │  4.0  8.0  │
/// └            ┘
/// ```
///
/// The macro allows one to write such a matrix in the natural order:
///
/// ```norun
/// matrix![
///     1.0, 5.0;
///     2.0, 6.0;
///     3.0, 7.0;
///     4.0, 8.0;
/// ]
/// ```
#[macro_export]
macro_rules! matrix {
    ($([$tail:expr,];)* -> [$($head:expr,)*]) => (
        vec![$($head,)* $($tail,)*]
    );
    ($([$middle:expr, $($tail:expr,)*];)* -> [$($head:expr,)*]) => (
        matrix!($([$($tail,)*];)* -> [$($head,)* $($middle,)*])
    );
    ($($($item:expr),*;)*) => (
        matrix!($([$($item,)*];)* -> [])
    );
    ($($($item:expr,)*;)*) => (
        matrix!($([$($item,)*];)* -> [])
    );
}

/// An error.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Error(String);

/// A result.
pub type Result<T> = std::result::Result<T, Error>;

macro_rules! raise(
    ($message:expr) => (
        return Err(::Error($message.to_string()));
    );
);

impl fmt::Display for Error {
    #[inline]
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(formatter)
    }
}

impl error::Error for Error {
    #[inline]
    fn description(&self) -> &str {
        &self.0
    }
}

mod element;
mod number;
mod position;
mod size;

pub use element::Element;
pub use number::Number;
pub use position::Position;
pub use size::Size;

pub mod format;
pub mod operation;
pub mod prelude;