1use ndarray::*;
4use rand::prelude::*;
5
6use super::convert::*;
7use super::error::*;
8use super::qr::*;
9use super::types::*;
10
11pub fn conjugate<A, S>(a: &ArrayRef<A, Ix2>) -> ArrayBase<S, Ix2>
13where
14 A: Scalar,
15 S: DataOwned<Elem = A> + DataMut,
16{
17 let mut a: ArrayBase<S, Ix2> = replicate(&a.t());
18 for val in a.iter_mut() {
19 *val = val.conj();
20 }
21 a
22}
23
24pub fn random<A, S, Sh, D>(sh: Sh) -> ArrayBase<S, D>
29where
30 A: Scalar,
31 S: DataOwned<Elem = A>,
32 D: Dimension,
33 Sh: ShapeBuilder<Dim = D>,
34{
35 let mut rng = thread_rng();
36 random_using(sh, &mut rng)
37}
38
39pub fn random_using<A, S, Sh, D, R>(sh: Sh, rng: &mut R) -> ArrayBase<S, D>
43where
44 A: Scalar,
45 S: DataOwned<Elem = A>,
46 D: Dimension,
47 Sh: ShapeBuilder<Dim = D>,
48 R: Rng,
49{
50 ArrayBase::from_shape_fn(sh, |_| A::rand(rng))
51}
52
53pub fn random_unitary<A>(n: usize) -> Array2<A>
60where
61 A: Scalar + Lapack,
62{
63 let mut rng = thread_rng();
64 random_unitary_using(n, &mut rng)
65}
66
67pub fn random_unitary_using<A, R>(n: usize, rng: &mut R) -> Array2<A>
73where
74 A: Scalar + Lapack,
75 R: Rng,
76{
77 let a: Array2<A> = random_using((n, n), rng);
78 let (q, _r) = a.qr_into().unwrap();
79 q
80}
81
82pub fn random_regular<A>(n: usize) -> Array2<A>
89where
90 A: Scalar + Lapack,
91{
92 let mut rng = rand::thread_rng();
93 random_regular_using(n, &mut rng)
94}
95
96pub fn random_regular_using<A, R>(n: usize, rng: &mut R) -> Array2<A>
102where
103 A: Scalar + Lapack,
104 R: Rng,
105{
106 let a: Array2<A> = random_using((n, n), rng);
107 let (q, mut r) = a.qr_into().unwrap();
108 for i in 0..n {
109 r[(i, i)] = A::one() + A::from_real(r[(i, i)].abs());
110 }
111 q.dot(&r)
112}
113
114pub fn random_hermite<A, S>(n: usize) -> ArrayBase<S, Ix2>
119where
120 A: Scalar,
121 S: DataOwned<Elem = A> + DataMut,
122{
123 let mut rng = rand::thread_rng();
124 random_hermite_using(n, &mut rng)
125}
126
127pub fn random_hermite_using<A, S, R>(n: usize, rng: &mut R) -> ArrayBase<S, Ix2>
131where
132 A: Scalar,
133 S: DataOwned<Elem = A> + DataMut,
134 R: Rng,
135{
136 let mut a: ArrayBase<S, Ix2> = random_using((n, n), rng);
137 for i in 0..n {
138 a[(i, i)] = a[(i, i)] + a[(i, i)].conj();
139 for j in (i + 1)..n {
140 a[(i, j)] = a[(j, i)].conj();
141 }
142 }
143 a
144}
145
146pub fn random_hpd<A, S>(n: usize) -> ArrayBase<S, Ix2>
153where
154 A: Scalar,
155 S: DataOwned<Elem = A> + DataMut,
156{
157 let mut rng = rand::thread_rng();
158 random_hpd_using(n, &mut rng)
159}
160
161pub fn random_hpd_using<A, S, R>(n: usize, rng: &mut R) -> ArrayBase<S, Ix2>
167where
168 A: Scalar,
169 S: DataOwned<Elem = A> + DataMut,
170 R: Rng,
171{
172 let a: Array2<A> = random_using((n, n), rng);
173 let ah: Array2<A> = conjugate(&a);
174 ArrayBase::eye(n) + &ah.dot(&a)
175}
176
177pub fn from_diag<A>(d: &[A]) -> Array2<A>
179where
180 A: Scalar,
181{
182 let n = d.len();
183 let mut e = Array::zeros((n, n));
184 for i in 0..n {
185 e[(i, i)] = d[i];
186 }
187 e
188}
189
190pub fn hstack<A, S>(xs: &[ArrayBase<S, Ix1>]) -> Result<Array<A, Ix2>>
192where
193 A: Scalar,
194 S: Data<Elem = A>,
195{
196 let views: Vec<_> = xs.iter().map(|x| x.view()).collect();
197 stack(Axis(1), &views).map_err(Into::into)
198}
199
200pub fn vstack<A, S>(xs: &[ArrayBase<S, Ix1>]) -> Result<Array<A, Ix2>>
202where
203 A: Scalar,
204 S: Data<Elem = A>,
205{
206 let views: Vec<_> = xs.iter().map(|x| x.view()).collect();
207 stack(Axis(0), &views).map_err(Into::into)
208}