|
1 | 1 |
|
2 |
| -use ndarray::{Ix2, Array, RcArray, NdFloat, ArrayBase, DataMut}; |
| 2 | +use ndarray::{Data, Ix1, Ix2, Array, RcArray, NdFloat, ArrayBase, DataMut}; |
3 | 3 |
|
4 | 4 | use matrix::{Matrix, MFloat};
|
5 | 5 | use square::SquareMatrix;
|
6 | 6 | use error::LinalgError;
|
7 | 7 | use solve::ImplSolve;
|
8 | 8 |
|
9 |
| -pub trait TriangularMatrix: Matrix + SquareMatrix { |
| 9 | +pub trait TriangularMatrix<Rhs>: Matrix + SquareMatrix { |
| 10 | + type Output; |
10 | 11 | /// solve a triangular system with upper triangular matrix
|
11 |
| - fn solve_upper(&self, Self::Vector) -> Result<Self::Vector, LinalgError>; |
| 12 | + fn solve_upper(&self, &Rhs) -> Result<Self::Output, LinalgError>; |
12 | 13 | /// solve a triangular system with lower triangular matrix
|
13 |
| - fn solve_lower(&self, Self::Vector) -> Result<Self::Vector, LinalgError>; |
| 14 | + fn solve_lower(&self, &Rhs) -> Result<Self::Output, LinalgError>; |
14 | 15 | }
|
15 | 16 |
|
16 |
| -impl<A: MFloat> TriangularMatrix for Array<A, Ix2> { |
17 |
| - fn solve_upper(&self, b: Self::Vector) -> Result<Self::Vector, LinalgError> { |
| 17 | +impl<A, S> TriangularMatrix<ArrayBase<S, Ix1>> for Array<A, Ix2> |
| 18 | + where A: MFloat, |
| 19 | + S: Data<Elem = A> |
| 20 | +{ |
| 21 | + type Output = Array<A, Ix1>; |
| 22 | + |
| 23 | + fn solve_upper(&self, b: &ArrayBase<S, Ix1>) -> Result<Self::Output, LinalgError> { |
18 | 24 | self.check_square()?;
|
19 | 25 | let (n, _) = self.size();
|
20 | 26 | let layout = self.layout()?;
|
21 | 27 | let a = self.as_slice_memory_order().unwrap();
|
22 |
| - let x = ImplSolve::solve_triangle(layout, 'U' as u8, n, a, b.into_raw_vec(), 1)?; |
| 28 | + let x = ImplSolve::solve_triangle(layout, 'U' as u8, n, a, b.to_owned().into_raw_vec(), 1)?; |
23 | 29 | Ok(Array::from_vec(x))
|
24 | 30 | }
|
25 |
| - fn solve_lower(&self, b: Self::Vector) -> Result<Self::Vector, LinalgError> { |
| 31 | + fn solve_lower(&self, b: &ArrayBase<S, Ix1>) -> Result<Self::Output, LinalgError> { |
26 | 32 | self.check_square()?;
|
27 | 33 | let (n, _) = self.size();
|
28 | 34 | let layout = self.layout()?;
|
29 | 35 | let a = self.as_slice_memory_order().unwrap();
|
30 |
| - let x = ImplSolve::solve_triangle(layout, 'L' as u8, n, a, b.into_raw_vec(), 1)?; |
| 36 | + let x = ImplSolve::solve_triangle(layout, 'L' as u8, n, a, b.to_owned().into_raw_vec(), 1)?; |
31 | 37 | Ok(Array::from_vec(x))
|
32 | 38 | }
|
33 | 39 | }
|
34 | 40 |
|
35 |
| -impl<A: MFloat> TriangularMatrix for RcArray<A, Ix2> { |
36 |
| - fn solve_upper(&self, b: Self::Vector) -> Result<Self::Vector, LinalgError> { |
| 41 | +impl<A, S> TriangularMatrix<ArrayBase<S, Ix1>> for RcArray<A, Ix2> |
| 42 | + where A: MFloat, |
| 43 | + S: Data<Elem = A> |
| 44 | +{ |
| 45 | + type Output = RcArray<A, Ix1>; |
| 46 | + |
| 47 | + fn solve_upper(&self, b: &ArrayBase<S, Ix1>) -> Result<Self::Output, LinalgError> { |
37 | 48 | // XXX unnecessary clone
|
38 |
| - let x = self.to_owned().solve_upper(b.to_owned())?; |
| 49 | + let x = self.to_owned().solve_upper(&b)?; |
39 | 50 | Ok(x.into_shared())
|
40 | 51 | }
|
41 |
| - fn solve_lower(&self, b: Self::Vector) -> Result<Self::Vector, LinalgError> { |
| 52 | + fn solve_lower(&self, b: &ArrayBase<S, Ix1>) -> Result<Self::Output, LinalgError> { |
42 | 53 | // XXX unnecessary clone
|
43 |
| - let x = self.to_owned().solve_lower(b.to_owned())?; |
| 54 | + let x = self.to_owned().solve_lower(&b)?; |
44 | 55 | Ok(x.into_shared())
|
45 | 56 | }
|
46 | 57 | }
|
|
0 commit comments