-
Notifications
You must be signed in to change notification settings - Fork 47
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft: Support generic dense vectors in more APIs #272
Conversation
This will probably require some iteration. @mulimoen I'd be very interested in your feedback :) |
This looks great! I tried implementing note: upstream crates may add a new impl of trait `std::ops::Deref` for type `ndarray::ArrayBase<_, ndarray::Dim<[usize; 1]>>` in future versions |
I was thinking about incorporating the |
Yes orphan rules will prevent us from having too broad implementations here, I think we need to implement on a case by case. Fortunately most implementations are trivial.
Right now the I haven't played with |
347b5f0
to
280f276
Compare
Lots of APIs were using slices as their input, particularly when using output buffers. However, this was not a good fit for linear algebra, since consumers of the APIs are more likely to be using eg an array from ndarray. Here we extend the `DenseVector` trait with a mutable version to be able to use it on output parameters. Since these are sealed traits we should be able to add unsafe indexing if necessary without a breaking change. It should also be possible to support eg nalgebra in the future without too much trouble. This should improve the situation discussed in #93, though it's probably not done yet. As suggested by @mulimoen, the `index` and `index_mut` implementations hint as `#[inline(always)]` as we want them to be zero-cost abstractions, and it can be critical to have them inlined to allow the compiler to remove bounds checks when possible.
780241b
to
c25bd31
Compare
With the latest changes, I think I'm leaning towards an interesting implementation, I've been able to write a single product impl allowing to apply a permutation to any dense vector (so a I'm starting to think the //I'd like to use DenseVector here, but I probably need to expose it for public use
pub fn solve<'a, V>(&self, rhs: &V) -> Vec<N>
where
N: 'a + Copy + Num,
V: Deref<Target = [N]>,
{
let mut x = &self.symbolic.perm * &rhs[..];
let l = self.l();
ldl_lsolve(&l, &mut x);
linalg::diag_solve(&self.diag, &mut x);
ldl_ltsolve(&l, &mut x);
let pinv = self.symbolic.perm.inv();
&pinv * &x
} There's another interesting opportunity with this refactor: if I manage to implement everything that's related to dense vectors using these traits, then I can make the |
c25bd31
to
210bd1d
Compare
210bd1d
to
81f500f
Compare
Now it's possible to call on ndarray data as well, with a single impl.
81f500f
to
d76db99
Compare
This way dependent crates will be able to express algorithms in terms of that trait. It will remain sealed initially, as we want to gain experience before committing on its API.
9df0043
to
a06efbf
Compare
ccfa375
to
ec744cf
Compare
This removes some code duplication, and benchmarks show this does not affect performance. Also pointed to a place where I'm not satisfied with the current API, but where I don't see how to improve with the current rust's trait system.
ec744cf
to
3e15203
Compare
So I think I've reached a good state, I've been able to use |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a massive boost in usability of this crate! Looks great, I say this is ready to be merged.
Thanks for the review @mulimoen ! |
Lots of APIs were using slices as their input, particularly when using
output buffers. However, this was not a good fit for linear algebra,
since consumers of the APIs are more likely to be using eg an array from
ndarray.
Here we extend the
DenseVector
trait with a mutable version to be ableto use it on output parameters. Since these are sealed traits we should
be able to add unsafe indexing if necessary without a breaking change.
It should also be possible to support eg nalgebra in the future without
too much trouble.
This should improve the situation discussed in #93, though it's
probably not done yet.