ndarray_linalg/
layout.rs

1//! Convert ndarray into LAPACK-compatible matrix format
2
3use super::error::*;
4use ndarray::*;
5
6pub use lax::layout::MatrixLayout;
7
8pub trait AllocatedArray {
9    type Elem;
10    fn layout(&self) -> Result<MatrixLayout>;
11    fn square_layout(&self) -> Result<MatrixLayout>;
12    /// Returns Ok iff the matrix is square (without computing the layout).
13    fn ensure_square(&self) -> Result<()>;
14    fn as_allocated(&self) -> Result<&[Self::Elem]>;
15}
16
17pub trait AllocatedArrayMut: AllocatedArray {
18    fn as_allocated_mut(&mut self) -> Result<&mut [Self::Elem]>;
19}
20
21impl<A> AllocatedArray for ArrayRef<A, Ix2> {
22    type Elem = A;
23
24    fn layout(&self) -> Result<MatrixLayout> {
25        let shape = self.shape();
26        let strides = self.strides();
27        if shape[0] == strides[1] as usize {
28            return Ok(MatrixLayout::F {
29                col: self.ncols() as i32,
30                lda: self.nrows() as i32,
31            });
32        }
33        if shape[1] == strides[0] as usize {
34            return Ok(MatrixLayout::C {
35                row: self.nrows() as i32,
36                lda: self.ncols() as i32,
37            });
38        }
39        Err(LinalgError::InvalidStride {
40            s0: strides[0],
41            s1: strides[1],
42        })
43    }
44
45    fn square_layout(&self) -> Result<MatrixLayout> {
46        let l = self.layout()?;
47        let (n, m) = l.size();
48        if n == m {
49            Ok(l)
50        } else {
51            Err(LinalgError::NotSquare { rows: n, cols: m })
52        }
53    }
54
55    fn ensure_square(&self) -> Result<()> {
56        if self.is_square() {
57            Ok(())
58        } else {
59            Err(LinalgError::NotSquare {
60                rows: self.nrows() as i32,
61                cols: self.ncols() as i32,
62            })
63        }
64    }
65
66    fn as_allocated(&self) -> Result<&[A]> {
67        self.as_slice_memory_order()
68            .ok_or(LinalgError::MemoryNotCont)
69    }
70}
71
72impl<A> AllocatedArrayMut for ArrayRef<A, Ix2> {
73    fn as_allocated_mut(&mut self) -> Result<&mut [A]> {
74        self.as_slice_memory_order_mut()
75            .ok_or(LinalgError::MemoryNotCont)
76    }
77}