Skip to content
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

Add Inv and Pow traits. #37

Merged
merged 7 commits into from
Feb 27, 2018
Merged

Add Inv and Pow traits. #37

merged 7 commits into from
Feb 27, 2018

Conversation

clarfonthey
Copy link
Contributor

@clarfonthey clarfonthey commented Feb 18, 2018

This is not a breaking change, and closes #34 and #38.

This doesn't add any impls for the other num crates, just floats with std enabled. The trait has to be added before those other crates can be updated.

Copy link
Member

@cuviper cuviper left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR - it's a good start. Besides the comments below, can you also add some testing? A simple example in the documentation should suffice. Maybe also note that some types may panic on "invalid" input, like a divide-by-zero, non-square matrix, etc.

src/ops/mod.rs Outdated
@@ -1,3 +1,4 @@
pub mod saturating;
pub mod checked;
pub mod wrapping;
pub mod new;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be pub mod inv;?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

src/ops/inv.rs Outdated

#[inline]
fn inv(self) -> $out {
($fn)(self)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't this function call will actually work for the reference versions, and it's weird having a lifetime parameter on the value versions. There are only 4 implementations here, so maybe it's not worth trying to make a unified macro.

To avoid cfg(feature = "std"), we could just implement these as 1.0 / self. That's all the standard library is doing anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll do that later today

@clarfonthey
Copy link
Contributor Author

I figured I'd implement #38 in this as well considering how I was going to offer both, and I don't want to deal with merge conflicts. Let me know if everything looks alright!

src/ops/pow.rs Outdated
pow_impl!(isize, u32, pow);

#[cfg(feature = "std")]
mod float_impls {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'll have to use super::Pow; to get it into this module.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

…that is correct. I'll just factor out the cfg.

@cuviper
Copy link
Member

cuviper commented Feb 19, 2018

Let's put Pow into the existing pow module, instead of under ops.

src/ops/inv.rs Outdated
/// let x = 7.0;
/// let y = -0.0;
/// assert_eq!(x.inv() * x, One::one());
/// assert_eq!(y.inv() * y, One::one());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is -inf * -0.0, which is actually NAN. Maybe just assert the -inf instead?

src/pow.rs Outdated
///
/// ```
/// use num_traits::Pow;
/// assert_eq!(10.pow(2), 100);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CI failed here because it inferred this like 10i32.pow(2i32), which is not implemented.

@clarfonthey clarfonthey changed the title Add Inv trait. Add Inv and Pow traits. Feb 23, 2018
@clarfonthey
Copy link
Contributor Author

Should be ready to merge now.

@cuviper
Copy link
Member

cuviper commented Feb 23, 2018

Sorry if I misspoke, but I did not mean that we should have so many variations of Pow implementations. Do you have your own reasons for all them? I'm especially worried about the ones with lossy as casts. Just the basic natively-supported pow implementations looked good to me.

@clarfonthey
Copy link
Contributor Author

@cuviper I accidentally added the u64 casts in error, but the rest are lossless casts (such as u8 as u32).

My main reasoning was to do something similar to how Shl is done in the standard library: https://doc.rust-lang.org/std/ops/trait.Shl.html

@cuviper
Copy link
Member

cuviper commented Feb 23, 2018

Ah, I got confused by the macros, and thought you had some signed->unsigned casts in there too.

Can we do it without the closures though? I think if you leverage From/Into, then the final implementation can be just $method(self, rhs.into()), where $method is either the type's inherent pow or num's pow for usize. No as casting at all.

Should floats do u32 and usize with num's pow too? And perhaps also u8 and u16 this way under no_std (without powi)?

I count 372 Pow implementations so far in the generated docs! The downside is that all this does significantly increase the compilation time, compared to the current master branch.

@clarfonthey
Copy link
Contributor Author

I think that doing without the closures is very fair and I'll refactor this in a bit to achieve that. Also I just noticed rust-lang/rust#48321 and I think that simply deferring to wrapping_pow once it's stable would be better for Wrapping, and that those impls can just be removed for now to avoid compile time hikes.

I'll see what I can do about benchmarking compile times and how that can be improved.

@cuviper
Copy link
Member

cuviper commented Feb 24, 2018

To put real numbers on it, cargo build --release goes from 0.72 seconds to 1.3 seconds on my i7-7700k. That's still bearable, but quite a significant increase for just one feature.

@clarfonthey
Copy link
Contributor Author

I don't think a double in compile time is acceptable; I'll see what I can do.

@clarfonthey clarfonthey reopened this Feb 24, 2018
@clarfonthey
Copy link
Contributor Author

@cuviper with the latest change, my compile time went from 2.29s to 1.84s, which is only a 20% increase. Could you provide benchmarks on your end?

Longer-term it may be best to make the standalone pow function private and change the usize exponent to a u64 for compatibility. This is breaking, obviously, and I didn't do that.

@cuviper
Copy link
Member

cuviper commented Feb 27, 2018

For me it's now 0.86s vs master's 0.72s -- that seems fine. There are still a lot of implementations -- 292 -- so I'd guess the closures were the main culprit for the slowdown.

Let's merge!

bors r+

bors bot added a commit that referenced this pull request Feb 27, 2018
37: Add Inv and Pow traits. r=cuviper a=clarcharr

This is not a breaking change, and closes #34 and #38.

This doesn't add any impls for the other `num` crates, just floats with `std` enabled. The trait has to be added before those other crates can be updated.
@bors
Copy link
Contributor

bors bot commented Feb 27, 2018

Build succeeded

@bors bors bot merged commit 79b557f into rust-num:master Feb 27, 2018
@clarfonthey
Copy link
Contributor Author

Awesome! Could you push a new version of num-traits with these changes added?

@cuviper
Copy link
Member

cuviper commented Feb 27, 2018

Yeah, but I still want to revisit FloatCore and perhaps add some more to it before it's published. I'll try to do this today.

@clarfonthey
Copy link
Contributor Author

That's fair; no rush. :)

@clarfonthey clarfonthey deleted the inv branch March 5, 2018 21:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feature request: Recip trait
2 participants