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

Split general functions in the Float trait into one or more general math traits #26

Closed
porky11 opened this issue Jan 17, 2018 · 1 comment

Comments

@porky11
Copy link

porky11 commented Jan 17, 2018

The Float trait does not only cover float specific functions, but also some general math functions, which are applicable for many number types.
For example fixed point number types could define functions like sqrt, log and sin, but not the float specific functions like infinity, neg_zero, ǹan.
So I propose to outsorce some functions of the float trait into another trait.

This trait should also be applicable to more complicated kinds of numbers, where such functions make sence, like complex numbers, quaternions, matrices or similar.

I also could implement it myself, but I think, it's good to talk about this before.

I'll define the trait, As I'd implement it:

pub trait Math: Add<Output=Self>+Sub<Output=Self>+Mul+Neg<Output=Self>+Sized

The name of the trait may be different, I just called it Math.
Addition, Subtraction and Negation should result in the same output type.
Multiplication may also result in different output types.
For example, if you implement real numbers and imaginary numbers as seperate types, multiplication of two imaginary numbers will result in real numbers.
Or multiplication of matrices of different sizes will result in another matrix of a size depending on the matrix size.
Division is not required for this trait. For many mathematical types, where multiplication is not symmetric (for example for matrices) division seems not that useful. Instead you would normally multiply by the inverse.
The type doesn't even need to implement One or Zero, because some types may be useful, which don't have a identity element for multiplication (for example the imaginary numbers).
Implementing at least Zero may be useful.

A list of functions will follow, I would include into the trait.
The functions are just the functions from the float trait, that seem useful for most mathematical types, which can represent more then whole numbers.
Maybe the output value has to be more general for some of these functions, because of the low restrictions on multiplication. (for example exp on imaginary numbers would need complex numbers as output type).

    fn recip(self) -> Self;

    fn powi(self, n: i32) -> Self;

    fn powf(self, n: Self) -> Self;

    fn sqrt(self) -> Self;

    fn exp(self) -> Self;

    fn exp2(self) -> Self;

    fn ln(self) -> Self;

    fn log(self, base: Self) -> Self;

    fn log2(self) -> Self;

    fn log10(self) -> Self;

    fn cbrt(self) -> Self;

    fn sin(self) -> Self;

    fn cos(self) -> Self;

    fn tan(self) -> Self;

    fn asin(self) -> Self;

    fn acos(self) -> Self;

    fn atan(self) -> Self;

    fn sin_cos(self) -> (Self, Self);

    fn exp_m1(self) -> Self;

    fn ln_1p(self) -> Self;

    fn sinh(self) -> Self;

    fn cosh(self) -> Self;

    fn tanh(self) -> Self;

    fn asinh(self) -> Self;

    fn acosh(self) -> Self;

    fn atanh(self) -> Self;

Default implementations may also be useful, because for most function there is some definition, that can be used for every type, often as an infinite sum.

Another soulution may also be to add some more specific traits, which only implement some functions:

trait Trigonometric {
    fn sin(self) -> Self;
    fn cos(self) -> Self;
    fn tan(self) -> Self;
    fn asin(self) -> Self;
    fn acos(self) -> Self;
    fn atan(self) -> Self;
}

trait Power {
    fn powi(self, n: i32) -> Self;
    fn powf(self, self) -> Self;
    fn exp(self) -> Self;
    fn exp2(self) -> Self;
    fn ln(self) -> Self;
    fn log2(self) -> Self;
    fn log10(self) -> Self;
    fn sqrt(self) -> Self;
    fn cbrt(self) -> Self;
}

But I doubt, this more detailled split really is useful, since you can normally define trigonometric functions in terms of exp and the other way round, and also implement the default impelmentations that way.

So I'm interested, how you would implement such traits, so I don't require to use floats in order to use a generic sqrt and exponential functions.
Are there arleady plans in this crate?

@cuviper
Copy link
Member

cuviper commented Jan 17, 2018

I think this is basically the same concern as #19, which is getting a Real trait in #23. I'm going to close this as a duplicate, but you can re-open if I'm wrong. Please feel free to add your thoughts to the other issue and pull request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants