3737//! This `S` for a matrix `A` is called "leading dimension of the array A" in LAPACK document, and denoted by `lda`.
3838//!
3939
40- use cauchy :: Scalar ;
40+ use super :: * ;
4141
4242#[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
4343pub enum MatrixLayout {
@@ -153,7 +153,7 @@ impl MatrixLayout {
153153/// ------
154154/// - If size of `a` and `layout` size mismatch
155155///
156- pub fn square_transpose < T : Scalar > ( layout : MatrixLayout , a : & mut [ T ] ) {
156+ pub fn square_transpose < T : Copy > ( layout : MatrixLayout , a : & mut [ T ] ) {
157157 let ( m, n) = layout. size ( ) ;
158158 let n = n as usize ;
159159 let m = m as usize ;
@@ -162,23 +162,78 @@ pub fn square_transpose<T: Scalar>(layout: MatrixLayout, a: &mut [T]) {
162162 for j in ( i + 1 ) ..n {
163163 let a_ij = a[ i * n + j] ;
164164 let a_ji = a[ j * m + i] ;
165- a[ i * n + j] = a_ji. conj ( ) ;
166- a[ j * m + i] = a_ij. conj ( ) ;
165+ a[ i * n + j] = a_ji;
166+ a[ j * m + i] = a_ij;
167167 }
168168 }
169169}
170170
171171/// Out-place transpose for general matrix
172172///
173- /// Inplace transpose of non-square matrices is hard.
174- /// See also: https://en.wikipedia.org/wiki/In-place_matrix_transposition
173+ /// Examples
174+ /// ---------
175+ ///
176+ /// ```rust
177+ /// # use lax::layout::*;
178+ /// let layout = MatrixLayout::C { row: 2, lda: 3 };
179+ /// let a = vec![1., 2., 3., 4., 5., 6.];
180+ /// let (l, b) = transpose(layout, &a);
181+ /// assert_eq!(l, MatrixLayout::F { col: 3, lda: 2 });
182+ /// assert_eq!(b, &[1., 4., 2., 5., 3., 6.]);
183+ /// ```
184+ ///
185+ /// ```rust
186+ /// # use lax::layout::*;
187+ /// let layout = MatrixLayout::F { col: 2, lda: 3 };
188+ /// let a = vec![1., 2., 3., 4., 5., 6.];
189+ /// let (l, b) = transpose(layout, &a);
190+ /// assert_eq!(l, MatrixLayout::C { row: 3, lda: 2 });
191+ /// assert_eq!(b, &[1., 4., 2., 5., 3., 6.]);
192+ /// ```
193+ ///
194+ /// Panics
195+ /// ------
196+ /// - If input array size and `layout` size mismatch
197+ ///
198+ pub fn transpose < T > ( layout : MatrixLayout , input : & [ T ] ) -> ( MatrixLayout , Vec < T > ) {
199+ let ( m, n) = layout. size ( ) ;
200+ let transposed = layout. resized ( n, m) . t ( ) ;
201+ let m = m as usize ;
202+ let n = n as usize ;
203+ assert_eq ! ( input. len( ) , m * n) ;
204+
205+ let out: Vec < MaybeUninit < T > > = unsafe { vec_uninit2 ( m * n) } ;
206+
207+ match layout {
208+ MatrixLayout :: C { .. } => {
209+ for i in 0 ..m {
210+ for j in 0 ..n {
211+ out[ j * m + i] . write ( input[ i * n + j] ) ;
212+ }
213+ }
214+ }
215+ MatrixLayout :: F { .. } => {
216+ for i in 0 ..m {
217+ for j in 0 ..n {
218+ out[ i * n + j] . write ( input[ j * m + i] ) ;
219+ }
220+ }
221+ }
222+ }
223+ ( transposed, unsafe { out. assume_init ( ) } )
224+ }
225+
226+ /// Out-place transpose for general matrix
227+ ///
228+ /// Examples
229+ /// ---------
175230///
176231/// ```rust
177232/// # use lax::layout::*;
178233/// let layout = MatrixLayout::C { row: 2, lda: 3 };
179234/// let a = vec![1., 2., 3., 4., 5., 6.];
180235/// let mut b = vec![0.0; a.len()];
181- /// let l = transpose (layout, &a, &mut b);
236+ /// let l = transpose_over (layout, &a, &mut b);
182237/// assert_eq!(l, MatrixLayout::F { col: 3, lda: 2 });
183238/// assert_eq!(b, &[1., 4., 2., 5., 3., 6.]);
184239/// ```
@@ -188,16 +243,16 @@ pub fn square_transpose<T: Scalar>(layout: MatrixLayout, a: &mut [T]) {
188243/// let layout = MatrixLayout::F { col: 2, lda: 3 };
189244/// let a = vec![1., 2., 3., 4., 5., 6.];
190245/// let mut b = vec![0.0; a.len()];
191- /// let l = transpose (layout, &a, &mut b);
246+ /// let l = transpose_over (layout, &a, &mut b);
192247/// assert_eq!(l, MatrixLayout::C { row: 3, lda: 2 });
193248/// assert_eq!(b, &[1., 4., 2., 5., 3., 6.]);
194249/// ```
195250///
196251/// Panics
197252/// ------
198- /// - If size of `a` and `layout` size mismatch
253+ /// - If input array sizes and `layout` size mismatch
199254///
200- pub fn transpose < T : Scalar > ( layout : MatrixLayout , from : & [ T ] , to : & mut [ T ] ) -> MatrixLayout {
255+ pub fn transpose_over < T > ( layout : MatrixLayout , from : & [ T ] , to : & mut [ T ] ) -> MatrixLayout {
201256 let ( m, n) = layout. size ( ) ;
202257 let transposed = layout. resized ( n, m) . t ( ) ;
203258 let m = m as usize ;
0 commit comments