ndarray_linalg/
convert.rs1use lax::UPLO;
4use ndarray::*;
5
6use super::error::*;
7use super::layout::*;
8use super::types::*;
9
10pub fn into_col<S>(a: ArrayBase<S, Ix1>) -> ArrayBase<S, Ix2>
11where
12 S: Data,
13{
14 let n = a.len();
15 a.into_shape_with_order((n, 1)).unwrap()
16}
17
18pub fn into_row<S>(a: ArrayBase<S, Ix1>) -> ArrayBase<S, Ix2>
19where
20 S: Data,
21{
22 let n = a.len();
23 a.into_shape_with_order((1, n)).unwrap()
24}
25
26pub fn flatten<S>(a: ArrayBase<S, Ix2>) -> ArrayBase<S, Ix1>
27where
28 S: Data,
29{
30 let n = a.len();
31 a.into_shape_with_order(n).unwrap()
32}
33
34pub fn into_matrix<A, S>(l: MatrixLayout, a: Vec<A>) -> Result<ArrayBase<S, Ix2>>
35where
36 S: DataOwned<Elem = A>,
37{
38 match l {
39 MatrixLayout::C { row, lda } => {
40 Ok(ArrayBase::from_shape_vec((row as usize, lda as usize), a)?)
41 }
42 MatrixLayout::F { col, lda } => Ok(ArrayBase::from_shape_vec(
43 (lda as usize, col as usize).f(),
44 a,
45 )?),
46 }
47}
48
49pub fn replicate<A, Sv, So, D>(a: &ArrayBase<Sv, D>) -> ArrayBase<So, D>
50where
51 A: Copy,
52 Sv: Data<Elem = A>,
53 So: DataOwned<Elem = A> + DataMut,
54 D: Dimension,
55{
56 unsafe {
57 let ret = ArrayBase::<So, D>::build_uninit(a.dim(), |view| {
58 a.assign_to(view);
59 });
60 ret.assume_init()
61 }
62}
63
64fn clone_with_layout<A, Si, So>(l: MatrixLayout, a: &ArrayBase<Si, Ix2>) -> ArrayBase<So, Ix2>
65where
66 A: Copy,
67 Si: Data<Elem = A>,
68 So: DataOwned<Elem = A> + DataMut,
69{
70 let shape_builder = match l {
71 MatrixLayout::C { row, lda } => (row as usize, lda as usize).set_f(false),
72 MatrixLayout::F { col, lda } => (lda as usize, col as usize).set_f(true),
73 };
74 unsafe {
75 let ret = ArrayBase::<So, _>::build_uninit(shape_builder, |view| {
76 a.assign_to(view);
77 });
78 ret.assume_init()
79 }
80}
81
82pub fn transpose_data<A, S>(a: &mut ArrayBase<S, Ix2>) -> Result<&mut ArrayBase<S, Ix2>>
83where
84 A: Copy,
85 S: DataOwned<Elem = A> + DataMut,
86{
87 let l = a.layout()?.toggle_order();
88 let new = clone_with_layout(l, a);
89 *a = new;
90 Ok(a)
91}
92
93pub fn generalize<A, S, D>(a: Array<A, D>) -> ArrayBase<S, D>
94where
95 S: DataOwned<Elem = A>,
96 D: Dimension,
97{
98 let strides: Vec<isize> = a.strides().to_vec();
101 let new = if a.is_standard_layout() {
102 ArrayBase::from_shape_vec(a.dim(), a.into_raw_vec_and_offset().0).unwrap()
103 } else {
104 ArrayBase::from_shape_vec(a.dim().f(), a.into_raw_vec_and_offset().0).unwrap()
105 };
106 assert_eq!(
107 new.strides(),
108 strides.as_slice(),
109 "Custom stride is not supported"
110 );
111 new
112}
113
114pub(crate) fn triangular_fill_hermitian<A, S>(a: &mut ArrayBase<S, Ix2>, uplo: UPLO)
123where
124 A: Scalar + Lapack,
125 S: DataMut<Elem = A>,
126{
127 assert!(a.is_square());
128 match uplo {
129 UPLO::Upper => {
130 for row in 0..a.nrows() {
131 for col in 0..row {
132 a[(row, col)] = a[(col, row)].conj();
133 }
134 }
135 }
136 UPLO::Lower => {
137 for col in 0..a.ncols() {
138 for row in 0..col {
139 a[(row, col)] = a[(col, row)].conj();
140 }
141 }
142 }
143 }
144}