Skip to content

Commit b02ee5b

Browse files
committed
Merge branch 'outer'
2 parents d6b2bef + cea4ea9 commit b02ee5b

File tree

5 files changed

+60
-2
lines changed

5 files changed

+60
-2
lines changed

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ keywords = ["ndarray", "lapack", "matrix"]
1010
license = "MIT"
1111

1212
[dependencies]
13-
lapack = "0.11.1"
13+
lapack = "0.11"
14+
blas = "0.15"
1415
num-traits = "0.1.36"
1516

1617
[dependencies.ndarray]

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
//! - [symmetric square root](hermite/trait.HermiteMatrix.html#tymethod.ssqrt)
3333
//! - [Cholesky factorization](hermite/trait.HermiteMatrix.html#tymethod.cholesky)
3434
35+
extern crate blas;
3536
extern crate lapack;
3637
extern crate num_traits;
3738
#[macro_use(s)]
@@ -45,6 +46,7 @@ pub mod square;
4546
pub mod hermite;
4647
pub mod triangular;
4748

49+
pub mod outer;
4850
pub mod qr;
4951
pub mod svd;
5052
pub mod eigh;

src/outer.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
2+
use blas::c::{Layout, dger, sger};
3+
4+
pub trait ImplOuter: Sized {
5+
fn outer(m: usize, n: usize, a: &[Self], b: &[Self], ab: &mut [Self]);
6+
}
7+
8+
macro_rules! impl_cholesky {
9+
($scalar:ty, $ger:path) => {
10+
impl ImplOuter for $scalar {
11+
fn outer(m: usize, n: usize, a: &[Self], b: &[Self], mut ab: &mut [Self]) {
12+
$ger(Layout::ColumnMajor, m as i32, n as i32, 1.0, a, 1, b, 1, ab, m as i32);
13+
}
14+
}
15+
}} // end macro_rules
16+
17+
impl_cholesky!(f64, dger);
18+
impl_cholesky!(f32, sger);

src/vector.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
//! Define trait for vectors
22
33
use std::iter::Sum;
4-
use ndarray::{LinalgScalar, ArrayBase, Data, Dimension};
4+
use ndarray::{Array, NdFloat, Ix1, Ix2, LinalgScalar, ArrayBase, Data, Dimension};
55
use num_traits::float::Float;
6+
use super::outer::ImplOuter;
67

78
/// Methods for vectors
89
pub trait Vector {
@@ -55,3 +56,19 @@ impl<A: Float> Squared for A {
5556
self.abs()
5657
}
5758
}
59+
60+
pub fn outer<A, S1, S2>(a: &ArrayBase<S1, Ix1>, b: &ArrayBase<S2, Ix1>) -> Array<A, Ix2>
61+
where A: NdFloat + ImplOuter,
62+
S1: Data<Elem = A>,
63+
S2: Data<Elem = A>
64+
{
65+
let m = a.len();
66+
let n = b.len();
67+
let mut ab = Array::zeros((n, m));
68+
ImplOuter::outer(m,
69+
n,
70+
a.as_slice_memory_order().unwrap(),
71+
b.as_slice_memory_order().unwrap(),
72+
ab.as_slice_memory_order_mut().unwrap());
73+
ab.reversed_axes()
74+
}

tests/outer.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
include!("header.rs");
2+
use ndarray_linalg::vector::outer;
3+
4+
#[test]
5+
fn outer_() {
6+
let dist = RealNormal::<f64>::new(0.0, 1.0);
7+
let m = 2;
8+
let n = 3;
9+
let a = Array::random(m, dist);
10+
let b = Array::random(n, dist);
11+
println!("a = \n{:?}", &a);
12+
println!("b = \n{:?}", &b);
13+
let ab = outer(&a, &b);
14+
println!("ab = \n{:?}", &ab);
15+
for i in 0..m {
16+
for j in 0..n {
17+
ab[(i, j)].assert_close(a[i] * b[j], 1e-7);
18+
}
19+
}
20+
}

0 commit comments

Comments
 (0)