Skip to content

Commit 6b02eef

Browse files
authored
Merge pull request #17 from rust-cv/maintainance
Maintainance
2 parents cd4a5c0 + 31b0ae5 commit 6b02eef

File tree

9 files changed

+260
-226
lines changed

9 files changed

+260
-226
lines changed

Cargo.toml

+8-5
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,16 @@ license = "MIT"
1212
readme = "README.md"
1313

1414
[features]
15-
default = ["nalgebra", "nalgebra_std", "ndarray", "image"]
16-
nalgebra_std = ["nalgebra/std"]
15+
default = ["alloc", "nalgebra", "ndarray", "image"]
16+
alloc = ["nalgebra?/alloc"]
17+
nalgebra = ["dep:nalgebra"]
18+
ndarray = ["dep:ndarray", "alloc"]
19+
image = ["dep:image", "alloc"]
1720

1821
[dependencies]
19-
ndarray = { version = "0.15.4", default-features = false, optional = true }
20-
nalgebra = { version = "0.30.1", default-features = false, optional = true }
21-
image = { version = "0.24.0", default-features = false, optional = true }
22+
ndarray = { version = "0.16", default-features = false, optional = true }
23+
nalgebra = { version = "0.33", default-features = false, optional = true }
24+
image = { version = "0.25", default-features = false, optional = true }
2225

2326
[package.metadata.docs.rs]
2427
all-features = true

README.md

+6-7
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,16 @@
1919

2020
Provides traits that allow conversion between n-dimensional types in different Rust crates
2121

22-
**NOTE**: By default, this crate includes no conversions. You must choose which crates you want to use using the features:
22+
**NOTE**: By default, this crate includes conversions for all supported crates. If you want to limit compilation, use `no-default-features = true` enable the corresponding feature for each dependency:
2323

24-
* `ndarray`
2524
* `nalgebra`
25+
* `ndarray`
2626
* `image`
2727

28-
When crates are included, any available conversions between the enabled crates are turned on.
28+
When two crate features are enabled, any available conversions between the two crates are turned on.
29+
30+
## Limitations
2931

3032
Right now this crate really only provides conversions to owned and borrowed ndarray types. Some limitations exist with `nalgebra`, as it only utilizes positive strides, while `ndarray` supports negative strides as well. The `image` crate has no concept of strides. Due to this, the `ndarray` crate is the most flexible, and is ideal for interoperability between these various crates.
3133

32-
## Supported Crates
33-
* `image`
34-
* `ndarray`
35-
* `nalgebra`
34+
`nalgebra` currently does not offer a solution to directly pass it an owned vector from `ndarray`, so `into` conversions do perform a copy. It is recommended to create the owned copy in `nalgebra` and then borrow a mutable array view of it using ndarray. You can then populate it accordingly without any copies of the data.

src/toimage.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
///
33
/// This uses an associated type to avoid ambiguity for the compiler.
44
/// By calling this, the compiler always knows the returned type.
5-
pub trait ToImageLuma {
5+
pub trait IntoImageLuma {
66
type Out;
77

88
fn into_image_luma(self) -> Self::Out;

src/tonalgebra.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
#[cfg(all(feature = "ndarray", feature = "nalgebra_std"))]
1+
#[cfg(feature = "ndarray")]
22
mod ndarray_impl;
33

44
/// Converts a 1 or 2 dimensional type to a nalgebra type.
55
///
66
/// This uses an associated type to avoid ambiguity for the compiler.
77
/// By calling this, the compiler always knows the returned type.
8-
pub trait ToNalgebra {
8+
pub trait IntoNalgebra {
99
type Out;
1010

1111
fn into_nalgebra(self) -> Self::Out;

src/tonalgebra/ndarray_impl.rs

+58-62
Original file line numberDiff line numberDiff line change
@@ -3,189 +3,185 @@
33
use super::*;
44

55
use core::convert::TryFrom;
6-
use nalgebra::Dynamic as Dy;
6+
use nalgebra::Dyn;
77

88
/// ```
9-
/// use nshare::ToNalgebra;
9+
/// use nshare::IntoNalgebra;
1010
///
11-
/// let arr = ndarray::arr1(&[0.1, 0.2, 0.3, 0.4]);
11+
/// let arr = ndarray::array![0.1, 0.2, 0.3, 0.4];
1212
/// let m = arr.view().into_nalgebra();
1313
/// assert!(m.iter().eq(&[0.1, 0.2, 0.3, 0.4]));
1414
/// assert_eq!(m.shape(), (4, 1));
1515
/// ```
16-
impl<'a, T> ToNalgebra for ndarray::ArrayView1<'a, T>
16+
impl<'a, T> IntoNalgebra for ndarray::ArrayView1<'a, T>
1717
where
1818
T: nalgebra::Scalar,
1919
{
20-
type Out = nalgebra::DVectorSlice<'a, T>;
20+
type Out = nalgebra::DVectorView<'a, T>;
2121
fn into_nalgebra(self) -> Self::Out {
22-
let len = Dy::new(self.len());
22+
let len = Dyn(self.len());
2323
let ptr = self.as_ptr();
2424
let stride: usize = TryFrom::try_from(self.strides()[0]).expect("Negative stride");
2525
let storage = unsafe {
26-
nalgebra::SliceStorage::from_raw_parts(
26+
nalgebra::ViewStorage::from_raw_parts(
2727
ptr,
2828
(len, nalgebra::Const::<1>),
29-
(nalgebra::Const::<1>, Dy::new(stride)),
29+
(nalgebra::Const::<1>, Dyn(stride)),
3030
)
3131
};
3232
nalgebra::Matrix::from_data(storage)
3333
}
3434
}
3535
/// ```
36-
/// use nshare::ToNalgebra;
36+
/// use nshare::IntoNalgebra;
3737
///
38-
/// let mut arr = ndarray::arr1(&[0.1, 0.2, 0.3, 0.4]);
38+
/// let mut arr = ndarray::array![0.1, 0.2, 0.3, 0.4];
3939
/// let m = arr.view_mut().into_nalgebra();
4040
/// assert!(m.iter().eq(&[0.1, 0.2, 0.3, 0.4]));
4141
/// assert_eq!(m.shape(), (4, 1));
4242
/// ```
43-
impl<'a, T> ToNalgebra for ndarray::ArrayViewMut1<'a, T>
43+
impl<'a, T> IntoNalgebra for ndarray::ArrayViewMut1<'a, T>
4444
where
4545
T: nalgebra::Scalar,
4646
{
47-
type Out = nalgebra::DVectorSliceMut<'a, T>;
47+
type Out = nalgebra::DVectorViewMut<'a, T>;
4848
fn into_nalgebra(mut self) -> Self::Out {
49-
let len = Dy::new(self.len());
49+
let len = Dyn(self.len());
5050
let stride: usize = TryFrom::try_from(self.strides()[0]).expect("Negative stride");
5151
let ptr = self.as_mut_ptr();
5252
let storage = unsafe {
53-
// Drop to not have simultaneously the ndarray and nalgebra valid.
54-
drop(self);
55-
nalgebra::SliceStorageMut::from_raw_parts(
53+
nalgebra::ViewStorageMut::from_raw_parts(
5654
ptr,
5755
(len, nalgebra::Const::<1>),
58-
(nalgebra::Const::<1>, Dy::new(stride)),
56+
(nalgebra::Const::<1>, Dyn(stride)),
5957
)
6058
};
6159
nalgebra::Matrix::from_data(storage)
6260
}
6361
}
6462

6563
/// ```
66-
/// use nshare::ToNalgebra;
64+
/// use nshare::IntoNalgebra;
6765
///
68-
/// let arr = ndarray::arr1(&[0.1, 0.2, 0.3, 0.4]);
66+
/// let arr = ndarray::array![0.1, 0.2, 0.3, 0.4];
6967
/// let m = arr.into_nalgebra();
7068
/// assert!(m.iter().eq(&[0.1, 0.2, 0.3, 0.4]));
7169
/// assert_eq!(m.shape(), (4, 1));
7270
/// ```
73-
impl<T> ToNalgebra for ndarray::Array1<T>
71+
impl<T> IntoNalgebra for ndarray::Array1<T>
7472
where
7573
T: nalgebra::Scalar,
7674
{
7775
type Out = nalgebra::DVector<T>;
7876
fn into_nalgebra(self) -> Self::Out {
79-
let len = Dy::new(self.len());
80-
Self::Out::from_vec_generic(len, nalgebra::Const::<1>, self.into_raw_vec())
77+
let len = Dyn(self.len());
78+
// There is no method to give nalgebra the vector directly where it isn't allocated. If you call
79+
// from_vec_generic, it simply calls from_iterator_generic which uses Iterator::collect(). Due to this,
80+
// the simplest solution is to just pass an iterator over the values. If you come across this because you
81+
// have a performance issue, I would recommend creating the owned data using naglebra and borrowing it with
82+
// ndarray to perform operations on it instead of the other way around.
83+
Self::Out::from_iterator_generic(len, nalgebra::Const::<1>, self.iter().cloned())
8184
}
8285
}
8386

8487
/// ```
85-
/// use nshare::ToNalgebra;
88+
/// use nshare::IntoNalgebra;
8689
///
87-
/// let arr = ndarray::arr2(&[
90+
/// let arr = ndarray::array![
8891
/// [0.1, 0.2, 0.3, 0.4],
8992
/// [0.5, 0.6, 0.7, 0.8],
9093
/// [1.1, 1.2, 1.3, 1.4],
9194
/// [1.5, 1.6, 1.7, 1.8],
92-
/// ]);
95+
/// ];
9396
/// let m = arr.view().into_nalgebra();
9497
/// assert!(m.row(1).iter().eq(&[0.5, 0.6, 0.7, 0.8]));
9598
/// assert_eq!(m.shape(), (4, 4));
9699
/// assert!(arr.t().into_nalgebra().column(1).iter().eq(&[0.5, 0.6, 0.7, 0.8]));
97100
/// ```
98-
impl<'a, T> ToNalgebra for ndarray::ArrayView2<'a, T>
101+
impl<'a, T> IntoNalgebra for ndarray::ArrayView2<'a, T>
99102
where
100103
T: nalgebra::Scalar,
101104
{
102-
type Out = nalgebra::DMatrixSlice<'a, T, Dy, Dy>;
105+
type Out = nalgebra::DMatrixView<'a, T, Dyn, Dyn>;
103106
fn into_nalgebra(self) -> Self::Out {
104-
let nrows = Dy::new(self.nrows());
105-
let ncols = Dy::new(self.ncols());
107+
let nrows = Dyn(self.nrows());
108+
let ncols = Dyn(self.ncols());
106109
let ptr = self.as_ptr();
107-
let stride_row: usize = TryFrom::try_from(self.strides()[0]).expect("Negative row stride");
108-
let stride_col: usize =
109-
TryFrom::try_from(self.strides()[1]).expect("Negative column stride");
110+
let stride_row: usize = TryFrom::try_from(self.strides()[0])
111+
.expect("can only convert positive row stride to nalgebra");
112+
let stride_col: usize = TryFrom::try_from(self.strides()[1])
113+
.expect("can only convert positive col stride to nalgebra");
110114
let storage = unsafe {
111-
nalgebra::SliceStorage::from_raw_parts(
115+
nalgebra::ViewStorage::from_raw_parts(
112116
ptr,
113117
(nrows, ncols),
114-
(Dy::new(stride_row), Dy::new(stride_col)),
118+
(Dyn(stride_row), Dyn(stride_col)),
115119
)
116120
};
117121
nalgebra::Matrix::from_data(storage)
118122
}
119123
}
120124

121125
/// ```
122-
/// use nshare::ToNalgebra;
126+
/// use nshare::IntoNalgebra;
123127
///
124-
/// let mut arr = ndarray::arr2(&[
128+
/// let mut arr = ndarray::array![
125129
/// [0.1, 0.2, 0.3, 0.4],
126130
/// [0.5, 0.6, 0.7, 0.8],
127131
/// [1.1, 1.2, 1.3, 1.4],
128132
/// [1.5, 1.6, 1.7, 1.8],
129-
/// ]);
133+
/// ];
130134
/// let m = arr.view_mut().into_nalgebra();
131135
/// assert!(m.row(1).iter().eq(&[0.5, 0.6, 0.7, 0.8]));
132136
/// assert_eq!(m.shape(), (4, 4));
133137
/// assert!(arr.view_mut().reversed_axes().into_nalgebra().column(1).iter().eq(&[0.5, 0.6, 0.7, 0.8]));
134138
/// ```
135-
impl<'a, T> ToNalgebra for ndarray::ArrayViewMut2<'a, T>
139+
impl<'a, T> IntoNalgebra for ndarray::ArrayViewMut2<'a, T>
136140
where
137141
T: nalgebra::Scalar,
138142
{
139-
type Out = nalgebra::DMatrixSliceMut<'a, T, Dy, Dy>;
143+
type Out = nalgebra::DMatrixViewMut<'a, T, Dyn, Dyn>;
140144
fn into_nalgebra(mut self) -> Self::Out {
141-
let nrows = Dy::new(self.nrows());
142-
let ncols = Dy::new(self.ncols());
143-
let stride_row: usize = TryFrom::try_from(self.strides()[0]).expect("Negative row stride");
144-
let stride_col: usize =
145-
TryFrom::try_from(self.strides()[1]).expect("Negative column stride");
145+
let nrows = Dyn(self.nrows());
146+
let ncols = Dyn(self.ncols());
147+
let stride_row: usize = TryFrom::try_from(self.strides()[0])
148+
.expect("can only convert positive row stride to nalgebra");
149+
let stride_col: usize = TryFrom::try_from(self.strides()[1])
150+
.expect("can only convert positive col stride to nalgebra");
146151
let ptr = self.as_mut_ptr();
147152
let storage = unsafe {
148-
// Drop to not have simultaneously the ndarray and nalgebra valid.
149-
drop(self);
150-
nalgebra::SliceStorageMut::from_raw_parts(
153+
nalgebra::ViewStorageMut::from_raw_parts(
151154
ptr,
152155
(nrows, ncols),
153-
(Dy::new(stride_row), Dy::new(stride_col)),
156+
(Dyn(stride_row), Dyn(stride_col)),
154157
)
155158
};
156159
nalgebra::Matrix::from_data(storage)
157160
}
158161
}
159162

160163
/// ```
161-
/// use nshare::ToNalgebra;
164+
/// use nshare::IntoNalgebra;
162165
///
163-
/// let mut arr = ndarray::arr2(&[
166+
/// let mut arr = ndarray::array![
164167
/// [0.1, 0.2, 0.3, 0.4],
165168
/// [0.5, 0.6, 0.7, 0.8],
166169
/// [1.1, 1.2, 1.3, 1.4],
167170
/// [1.5, 1.6, 1.7, 1.8],
168-
/// ]);
171+
/// ];
169172
/// let m = arr.clone().into_nalgebra();
170173
/// assert!(m.row(1).iter().eq(&[0.5, 0.6, 0.7, 0.8]));
171174
/// assert_eq!(m.shape(), (4, 4));
172175
/// assert!(arr.reversed_axes().into_nalgebra().column(1).iter().eq(&[0.5, 0.6, 0.7, 0.8]));
173176
/// ```
174-
impl<T> ToNalgebra for ndarray::Array2<T>
177+
impl<T> IntoNalgebra for ndarray::Array2<T>
175178
where
176179
T: nalgebra::Scalar,
177180
{
178181
type Out = nalgebra::DMatrix<T>;
179182
fn into_nalgebra(self) -> Self::Out {
180-
let std_layout = self.is_standard_layout();
181-
let nrows = Dy::new(self.nrows());
182-
let ncols = Dy::new(self.ncols());
183-
let mut res = Self::Out::from_vec_generic(nrows, ncols, self.into_raw_vec());
184-
if std_layout {
185-
// This can be expensive, but we have no choice since nalgebra VecStorage is always
186-
// column-based.
187-
res.transpose_mut();
188-
}
189-
res
183+
let nrows = Dyn(self.nrows());
184+
let ncols = Dyn(self.ncols());
185+
Self::Out::from_iterator_generic(nrows, ncols, self.t().iter().cloned())
190186
}
191187
}

0 commit comments

Comments
 (0)