1use 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 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}