11//! Memory layout of matrices
2+ //!
3+ //! Different from ndarray format which consists of shape and strides,
4+ //! matrix format in LAPACK consists of row or column size and leading dimension.
5+ //!
6+ //! ndarray format and stride
7+ //! --------------------------
8+ //!
9+ //! Let us consider 3-dimensional array for explaining ndarray structure.
10+ //! The address of `(x,y,z)`-element in ndarray satisfies following relation:
11+ //!
12+ //! ```text
13+ //! shape = [Nx, Ny, Nz]
14+ //! where Nx > 0, Ny > 0, Nz > 0
15+ //! stride = [Sx, Sy, Sz]
16+ //!
17+ //! &data[(x, y, z)] = &data[(0, 0, 0)] + Sx*x + Sy*y + Sz*z
18+ //! for x < Nx, y < Ny, z < Nz
19+ //! ```
20+ //!
21+ //! The array is called
22+ //!
23+ //! - C-continuous if `[Sx, Sy, Sz] = [Nz*Ny, Nz, 1]`
24+ //! - F(Fortran)-continuous if `[Sx, Sy, Sz] = [1, Nx, Nx*Ny]`
25+ //!
26+ //! Strides of ndarray `[Sx, Sy, Sz]` take arbitrary value,
27+ //! e.g. it can be non-ordered `Sy > Sx > Sz`, or can be negative `Sx < 0`.
28+ //! If the minimum of `[Sx, Sy, Sz]` equals to `1`,
29+ //! the value of elements fills `data` memory region and called "continuous".
30+ //! Non-continuous ndarray is useful to get sub-array without copying data.
31+ //!
32+ //! Matrix layout for LAPACK
33+ //! -------------------------
34+ //!
35+ //! LAPACK interface focuses on the linear algebra operations for F-continuous 2-dimensional array.
36+ //! Under this restriction, stride becomes far simpler; we only have to consider the case `[1, S]`
37+ //! This `S` for a matrix `A` is called "leading dimension of the array A" in LAPACK document, and denoted by `lda`.
38+ //!
239
3- pub type LDA = i32 ;
4- pub type LEN = i32 ;
5- pub type Col = i32 ;
6- pub type Row = i32 ;
7-
8- #[ derive( Debug , Clone , Copy , PartialEq ) ]
40+ #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
941pub enum MatrixLayout {
10- C ( ( Row , LDA ) ) ,
11- F ( ( Col , LDA ) ) ,
42+ C { row : i32 , lda : i32 } ,
43+ F { col : i32 , lda : i32 } ,
1244}
1345
1446impl MatrixLayout {
15- pub fn size ( & self ) -> ( Row , Col ) {
47+ pub fn size ( & self ) -> ( i32 , i32 ) {
1648 match * self {
17- MatrixLayout :: C ( ( row, lda) ) => ( row, lda) ,
18- MatrixLayout :: F ( ( col, lda) ) => ( lda, col) ,
49+ MatrixLayout :: C { row, lda } => ( row, lda) ,
50+ MatrixLayout :: F { col, lda } => ( lda, col) ,
1951 }
2052 }
2153
22- pub fn resized ( & self , row : Row , col : Col ) -> MatrixLayout {
54+ pub fn resized ( & self , row : i32 , col : i32 ) -> MatrixLayout {
2355 match * self {
24- MatrixLayout :: C ( _ ) => MatrixLayout :: C ( ( row, col) ) ,
25- MatrixLayout :: F ( _ ) => MatrixLayout :: F ( ( col, row) ) ,
56+ MatrixLayout :: C { .. } => MatrixLayout :: C { row, lda : col } ,
57+ MatrixLayout :: F { .. } => MatrixLayout :: F { col, lda : row } ,
2658 }
2759 }
2860
29- pub fn lda ( & self ) -> LDA {
61+ pub fn lda ( & self ) -> i32 {
3062 std:: cmp:: max (
3163 1 ,
3264 match * self {
33- MatrixLayout :: C ( ( _ , lda) ) | MatrixLayout :: F ( ( _ , lda) ) => lda,
65+ MatrixLayout :: C { lda, .. } | MatrixLayout :: F { lda, .. } => lda,
3466 } ,
3567 )
3668 }
3769
38- pub fn len ( & self ) -> LEN {
70+ pub fn len ( & self ) -> i32 {
3971 match * self {
40- MatrixLayout :: C ( ( row, _ ) ) => row,
41- MatrixLayout :: F ( ( col, _ ) ) => col,
72+ MatrixLayout :: C { row, .. } => row,
73+ MatrixLayout :: F { col, .. } => col,
4274 }
4375 }
4476
@@ -48,8 +80,8 @@ impl MatrixLayout {
4880
4981 pub fn lapacke_layout ( & self ) -> lapacke:: Layout {
5082 match * self {
51- MatrixLayout :: C ( _ ) => lapacke:: Layout :: RowMajor ,
52- MatrixLayout :: F ( _ ) => lapacke:: Layout :: ColumnMajor ,
83+ MatrixLayout :: C { .. } => lapacke:: Layout :: RowMajor ,
84+ MatrixLayout :: F { .. } => lapacke:: Layout :: ColumnMajor ,
5385 }
5486 }
5587
@@ -59,8 +91,8 @@ impl MatrixLayout {
5991
6092 pub fn toggle_order ( & self ) -> Self {
6193 match * self {
62- MatrixLayout :: C ( ( row, col ) ) => MatrixLayout :: F ( ( col , row) ) ,
63- MatrixLayout :: F ( ( col, row ) ) => MatrixLayout :: C ( ( row, col) ) ,
94+ MatrixLayout :: C { row, lda } => MatrixLayout :: F { lda : row, col : lda } ,
95+ MatrixLayout :: F { col, lda } => MatrixLayout :: C { row : lda , lda : col } ,
6496 }
6597 }
6698}
0 commit comments