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, S, D>(a: &ArrayRef<A, D>) -> ArrayBase<S, D>
50where
51 A: Copy,
52 S: DataOwned<Elem = A> + DataMut,
53 D: Dimension,
54{
55 unsafe {
56 let ret = ArrayBase::<S, D>::build_uninit(a.dim(), |view| {
57 a.assign_to(view);
58 });
59 ret.assume_init()
60 }
61}
62
63fn clone_with_layout<A, S>(l: MatrixLayout, a: &ArrayRef<A, Ix2>) -> ArrayBase<S, Ix2>
64where
65 A: Copy,
66 S: DataOwned<Elem = A> + DataMut,
67{
68 let shape_builder = match l {
69 MatrixLayout::C { row, lda } => (row as usize, lda as usize).set_f(false),
70 MatrixLayout::F { col, lda } => (lda as usize, col as usize).set_f(true),
71 };
72 unsafe {
73 let ret = ArrayBase::<S, _>::build_uninit(shape_builder, |view| {
74 a.assign_to(view);
75 });
76 ret.assume_init()
77 }
78}
79
80pub fn transpose_data<A, S>(a: &mut ArrayBase<S, Ix2>) -> Result<&mut ArrayBase<S, Ix2>>
81where
82 A: Copy,
83 S: DataOwned<Elem = A> + DataMut,
84{
85 let l = a.layout()?.toggle_order();
86 let new = clone_with_layout(l, a);
87 *a = new;
88 Ok(a)
89}
90
91pub fn generalize<A, S, D>(a: Array<A, D>) -> ArrayBase<S, D>
92where
93 S: DataOwned<Elem = A>,
94 D: Dimension,
95{
96 let strides: Vec<isize> = a.strides().to_vec();
99 let new = if a.is_standard_layout() {
100 ArrayBase::from_shape_vec(a.dim(), a.into_raw_vec_and_offset().0).unwrap()
101 } else {
102 ArrayBase::from_shape_vec(a.dim().f(), a.into_raw_vec_and_offset().0).unwrap()
103 };
104 assert_eq!(
105 new.strides(),
106 strides.as_slice(),
107 "Custom stride is not supported"
108 );
109 new
110}
111
112pub(crate) fn triangular_fill_hermitian<A>(a: &mut ArrayRef<A, Ix2>, uplo: UPLO)
121where
122 A: Scalar + Lapack,
123{
124 assert!(a.is_square());
125 match uplo {
126 UPLO::Upper => {
127 for row in 0..a.nrows() {
128 for col in 0..row {
129 a[(row, col)] = a[(col, row)].conj();
130 }
131 }
132 }
133 UPLO::Lower => {
134 for col in 0..a.ncols() {
135 for row in 0..col {
136 a[(row, col)] = a[(col, row)].conj();
137 }
138 }
139 }
140 }
141}