Skip to content

Remove most free-standing numeric functions and implement Interpolate trait #6986

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

Closed
wants to merge 9 commits into from

Conversation

brendanzab
Copy link
Member

As part of #4819, this commit removes most of the free-standing wrapper functions from the numeric modules. It also removes the re-exports of the delegated intrinsic and cmath functions in std::{float, f32, f64}.

What does this mean from a user perspective? Most of the functions you normally use are now covered by methods in the numeric trait hierarchy. For example, f32::sin(2.0) would now be written as 2.0f32.sin(), or int::min(1, 2) as 1i.min(&2) (unfortunately the explicit type suffix is needed because Rust can't infer the type).

@jensnockert has also added an Interpolate trait to std::num implemented for float, f64 and f32. This adds the following associated functions:

pub trait Interpolate {
    pub fn linear(x: Self, y: Self, t: Self) -> Self;
    pub fn cosine(x: Self, y: Self, t: Self) -> Self;
    pub fn smooth(x: Self, y: Self, t: Self) -> Self;
    pub fn barycentric(x: Self, y: Self, z: Self, t0: Self, t1: Self) -> Self;
    pub fn hermite(x: Self, xp: Self, y: Self, yp: Self, t: Self) -> Self;
    pub fn cubic(x: Self, y: Self, z: Self, u: Self, t: Self) -> Self;
    pub fn catmull_rom(x: Self, y: Self, z: Self, u: Self, t: Self) -> Self;
}

In addition, I have also added the error functions to std::num::Real:

pub trait Real {
    //...

    pub fn erf(&self) -> Self;
    pub fn erfc(&self) -> Self;

    // ...
}

brendanzab and others added 9 commits June 9, 2013 07:25
For the moment this includes only a lerp method. This trait should be expanded to be more comprehensive in the future.
Implements

 - Linear
 - Cosine
 - Smooth (Based on Smooth Step)
 - Barycentric
 - Hermite
 - Cubic
 - Catmull-Rom

They are implemented using Horner's rule, which should be the fastest
assuming that we cannot get any parallelism. At some later date we can
see if we could optimize them for super-scalar processors.

TODO: Add documentation, tests and make the implementation generic.
It just tests edge cases, but the actual results should vary with the
availability of fast FMA so I am not testing them right now.
…ng delegated f64/f32 functions

These should now be covered by methods in the numeric traits
The original tests were not accurate in double-precision, but I must
have forgotten to run the tests in double-precision so I never noticed
that.

The new tests are designed to be accurate in all sensible IEEE 754
precisions, including half-precision.
@brson
Copy link
Contributor

brson commented Jun 10, 2013

I r+'d this but I'm not at all confident that all these obscure interpolation functions are appropriate for std, nor that they make sense as a trait. In the future please try to put different features in different pull requests.

@brendanzab
Copy link
Member Author

@brson Sure thing, this one got a little out of hand. We'll discuss/debate further in #4819.

@Casorati
Copy link

why remove free-standing numeric functions? They are the most intuitive definition of numerical operation. A numerical function does not act on a number (it does not change it), but it maps it to an element form the same or different set. An expression like 2.0f32.sin() is ugly, hard to read and would probably prevent a lot of people (including me) to ever use rust for numerical applications.
You might follow the goal to make rust more consistent but the notation used for numerical functions is very mature and even consistent among different computer languages so in my option it should remain an exception if needed.
Also, as a welcome side effect those free-standing function prevent a misleading use of function names like exp, sin and so on. We can consider them to be reserved for their classical meaning.

@auroranockert
Copy link
Contributor

I agree with you @Casorati partially.

Syntax-wise I think we should allow for the sin(x) option in addition to x.sin(). What will be the 'default' way to call mathematical functions can then be decided by the community.

But I also think it is very important to remove the current free-standing numeric functions. Currently there are at least three different sin(x) which doesn't make sense to me.

The sane way to implement the numeric functions is to

  1. First remove the free-standing functions.
  2. Then add new generic functions that implement sin(x) &c. for all types that implement x.sin().

Ps. @bjz, could you split up this PR into two? The two groups of changes are completely orthogonal.

@graydon
Copy link
Contributor

graydon commented Jun 10, 2013

The method vs free-standing call thing is part of uniform method calls, which we intend to fix generally. Not sure about schedule.

@Casorati
Copy link

Then I think the changes should include the fix instead of forcing a temporary syntax change in existing code.

@JensNockert How can a generic version of a function like sin be defined in rust?

@auroranockert
Copy link
Contributor

@bjz Could you close this PR?

@Casorati I did some changes and split out that part of the PR, so please, could you check it over and maybe leave a comment? (#7090)

@brendanzab
Copy link
Member Author

@JensNockert sure thing! I think this has been a good discussion anyway. :)

@brendanzab brendanzab closed this Jun 12, 2013
@brendanzab brendanzab deleted the interpolate branch November 9, 2013 21:13
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.

6 participants