Skip to content

Commit 6bfb38b

Browse files
authored
Merge pull request #146 from rust-ndarray/ci_windows
Add Windows setting for Azure Pipeline
2 parents 03fe1ca + d8d779c commit 6bfb38b

File tree

5 files changed

+102
-8
lines changed

5 files changed

+102
-8
lines changed

Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ features = ["blas"]
3232
default-features = false
3333

3434
[dependencies.blas-src]
35-
version = "0.2"
35+
version = "0.3"
3636
default-features = false
3737
optional = true
3838

3939
[dependencies.lapack-src]
40-
version = "0.2"
40+
version = "0.3"
4141
default-features = false
4242
optional = true

azure-pipelines.yml

+13
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,16 @@ jobs:
5858
cargo test -v --features=intel-mkl --no-default-features
5959
cargo test -v --features=intel-mkl,serde-1 --no-default-features
6060
displayName: run test
61+
62+
- job: WindowsIntelMKL
63+
pool:
64+
vmImage: 'windows-2019'
65+
steps:
66+
- script: |
67+
curl -sSf -o rustup-init.exe https://win.rustup.rs
68+
rustup-init.exe -y 2>&1
69+
set PATH=%PATH%;%USERPROFILE%\.cargo\bin
70+
echo '##vso[task.setvariable variable=PATH;]%PATH%;%USERPROFILE%\.cargo\bin'
71+
displayName: install rustup on Windows
72+
- script: cargo test -v --features=intel-mkl --no-default-features 2>&1
73+
displayName: run test

src/eigh.rs

+6
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ where
6363
type EigVal = Array1<A::Real>;
6464

6565
fn eigh_inplace(&mut self, uplo: UPLO) -> Result<(Self::EigVal, &mut Self)> {
66+
let layout = self.square_layout()?;
67+
// XXX Force layout to be Fortran (see #146)
68+
match layout {
69+
MatrixLayout::C(_) => self.swap_axes(0, 1),
70+
MatrixLayout::F(_) => {}
71+
}
6672
let s = unsafe { A::eigh(true, self.square_layout()?, uplo, self.as_allocated_mut()?)? };
6773
Ok((ArrayBase::from_vec(s), self))
6874
}

src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@
3636
//! - [Random matrix generators](generate/index.html)
3737
//! - [Scalar trait](types/trait.Scalar.html)
3838
39+
extern crate blas_src;
40+
extern crate lapack_src;
41+
3942
pub mod assert;
4043
pub mod cholesky;
4144
pub mod convert;

tests/eigh.rs

+78-6
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,15 @@ use ndarray::*;
22
use ndarray_linalg::*;
33

44
#[test]
5-
fn eigen_vector_manual() {
5+
fn fixed() {
66
let a = arr2(&[[3.0, 1.0, 1.0], [1.0, 3.0, 1.0], [1.0, 1.0, 3.0]]);
77
let (e, vecs): (Array1<_>, Array2<_>) = (&a).eigh(UPLO::Upper).unwrap();
88
assert_close_l2!(&e, &arr1(&[2.0, 2.0, 5.0]), 1.0e-7);
9+
10+
// Check eigenvectors are orthogonalized
11+
let s = vecs.t().dot(&vecs);
12+
assert_close_l2!(&s, &Array::eye(3), 1.0e-7);
13+
914
for (i, v) in vecs.axis_iter(Axis(1)).enumerate() {
1015
let av = a.dot(&v);
1116
let ev = v.mapv(|x| e[i] * x);
@@ -14,12 +19,53 @@ fn eigen_vector_manual() {
1419
}
1520

1621
#[test]
17-
fn diagonalize() {
18-
let a = arr2(&[[3.0, 1.0, 1.0], [1.0, 3.0, 1.0], [1.0, 1.0, 3.0]]);
22+
fn fixed_t() {
23+
let a = arr2(&[[3.0, 1.0, 1.0], [1.0, 3.0, 1.0], [1.0, 1.0, 3.0]]).reversed_axes();
1924
let (e, vecs): (Array1<_>, Array2<_>) = (&a).eigh(UPLO::Upper).unwrap();
20-
let s = vecs.t().dot(&a).dot(&vecs);
21-
for i in 0..3 {
22-
assert_rclose!(e[i], s[(i, i)], 1e-7);
25+
assert_close_l2!(&e, &arr1(&[2.0, 2.0, 5.0]), 1.0e-7);
26+
27+
// Check eigenvectors are orthogonalized
28+
let s = vecs.t().dot(&vecs);
29+
assert_close_l2!(&s, &Array::eye(3), 1.0e-7);
30+
31+
for (i, v) in vecs.axis_iter(Axis(1)).enumerate() {
32+
let av = a.dot(&v);
33+
let ev = v.mapv(|x| e[i] * x);
34+
assert_close_l2!(&av, &ev, 1.0e-7);
35+
}
36+
}
37+
38+
#[test]
39+
fn fixed_lower() {
40+
let a = arr2(&[[3.0, 1.0, 1.0], [1.0, 3.0, 1.0], [1.0, 1.0, 3.0]]);
41+
let (e, vecs): (Array1<_>, Array2<_>) = (&a).eigh(UPLO::Lower).unwrap();
42+
assert_close_l2!(&e, &arr1(&[2.0, 2.0, 5.0]), 1.0e-7);
43+
44+
// Check eigenvectors are orthogonalized
45+
let s = vecs.t().dot(&vecs);
46+
assert_close_l2!(&s, &Array::eye(3), 1.0e-7);
47+
48+
for (i, v) in vecs.axis_iter(Axis(1)).enumerate() {
49+
let av = a.dot(&v);
50+
let ev = v.mapv(|x| e[i] * x);
51+
assert_close_l2!(&av, &ev, 1.0e-7);
52+
}
53+
}
54+
55+
#[test]
56+
fn fixed_t_lower() {
57+
let a = arr2(&[[3.0, 1.0, 1.0], [1.0, 3.0, 1.0], [1.0, 1.0, 3.0]]).reversed_axes();
58+
let (e, vecs): (Array1<_>, Array2<_>) = (&a).eigh(UPLO::Lower).unwrap();
59+
assert_close_l2!(&e, &arr1(&[2.0, 2.0, 5.0]), 1.0e-7);
60+
61+
// Check eigenvectors are orthogonalized
62+
let s = vecs.t().dot(&vecs);
63+
assert_close_l2!(&s, &Array::eye(3), 1.0e-7);
64+
65+
for (i, v) in vecs.axis_iter(Axis(1)).enumerate() {
66+
let av = a.dot(&v);
67+
let ev = v.mapv(|x| e[i] * x);
68+
assert_close_l2!(&av, &ev, 1.0e-7);
2369
}
2470
}
2571

@@ -48,3 +94,29 @@ fn ssqrt_t() {
4894
println!("ss = {:?}", &ss);
4995
assert_close_l2!(&ss, &ans, 1e-7);
5096
}
97+
98+
#[test]
99+
fn ssqrt_lower() {
100+
let a: Array2<f64> = random_hpd(3);
101+
let ans = a.clone();
102+
let s = a.ssqrt(UPLO::Lower).unwrap();
103+
println!("a = {:?}", &ans);
104+
println!("s = {:?}", &s);
105+
assert_close_l2!(&s.t(), &s, 1e-7);
106+
let ss = s.dot(&s);
107+
println!("ss = {:?}", &ss);
108+
assert_close_l2!(&ss, &ans, 1e-7);
109+
}
110+
111+
#[test]
112+
fn ssqrt_t_lower() {
113+
let a: Array2<f64> = random_hpd(3).reversed_axes();
114+
let ans = a.clone();
115+
let s = a.ssqrt(UPLO::Lower).unwrap();
116+
println!("a = {:?}", &ans);
117+
println!("s = {:?}", &s);
118+
assert_close_l2!(&s.t(), &s, 1e-7);
119+
let ss = s.dot(&s);
120+
println!("ss = {:?}", &ss);
121+
assert_close_l2!(&ss, &ans, 1e-7);
122+
}

0 commit comments

Comments
 (0)