Skip to content

Commit bf56398

Browse files
committed
Rename transpose to transpose_over, create new transpose to write uninitilized buffer
1 parent ee00a0d commit bf56398

File tree

1 file changed

+65
-10
lines changed

1 file changed

+65
-10
lines changed

lax/src/layout.rs

Lines changed: 65 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
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)]
4343
pub 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

Comments
 (0)