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
121
122
123
124
125
126
127
128
129
/// With a focus on being concise: This macro will create a matrix using syntax similar to matlab
/// A semicolon ';' represends a new matrix row
/// # example 1:
/// ```
/// # use numb_rs::{mat, Dense};
/// # fn main() {
/// let a = mat![
///     0, 1, 2;
///     3, 4, 5
/// ];
/// # }
/// ```
/// will provide a 3x2 matrix as specified
///
/// # example 2:
/// It's also possible to initialise a matrix with a given value
/// This uses a different syntax to standard rust code due to a semicolon being used to denote a
/// row change. for instance:
/// ```
/// let x = [0.;5];
/// ```
/// is translated to:
/// ```
/// # use numb_rs::{mat, Dense};
/// # fn main() {
/// let x = mat![0. => 5, 1];
/// # }
/// ```
/// where 5, 1 represent m and n, i.e. the row and column lengths respectively
///
#[macro_export]
macro_rules! mat {
    // empty
    () => {
        Dense::new()
    };
    // standard
    ($($($item:expr),+);+) => {{
        let mut v = Vec::new();
        // underscored to surpress warnings
        let mut _n;
        let mut m = 0;
        $(
            _n = 0;
            $({
                v.push($item);
                _n += 1;
            })*
            m += 1;
        )*
        Dense{
            data: v,
            n: _n,
            m,
        }
    }};
    // fills an array with a value
    ($val:expr => $m: expr, $n: expr) => {{
        let mut v = Vec::new();
        for _ in 0..($m * $n) {
            v.push($val)
        }
        Dense {
            data: v,
            m: $m,
            n: $n,
        }
    }}
}

/// Creates a symmetrical matrix
/// Note that the symmetrical matrix is of type MatrixS,
/// The aim of this macro and associated struct is for saving space
/// # example:
/// ```
/// # use numb_rs::symmetric::Symmetric;
/// # use numb_rs::dense::Dense;
/// # use numb_rs::{mat, symmat};
///
/// # fn main() {
/// let a = symmat![
/// 0;
/// 1, 2;
/// 3, 4, 5
///
/// ];
///
/// assert_eq!(a[[1, 2]], a[[2, 1]]);
///
/// // equivalent to:
/// let b = mat![
/// 0, 1, 3;
/// 1, 2, 4;
/// 3, 4, 5
/// ];
///
/// assert_eq!(a, b);
/// # }
/// ```
#[macro_export]
macro_rules! symmat {
    ($($($item:expr),+);+) => {{
        let mut v = Vec::new();
        let mut n = 0;
        $(
        $({
            v.push($item);
        })*
            n += 1;
        )*

        Symmetric{
        data: v,
        n: n,
        }
    }};
    // fills an array with a value
    // REVIEW: What if n is not an integer?
    ($val:expr => $n: expr) => {{
        let mut v = Vec::new();
        for _ in 0..($n * ( $n + 1 ) / 2) {
            v.push($val)
        }
        Symmetric{
            data: v,
            n: $n,
        }
    }}
}