iliekturtles / uom

Units of measurement -- type-safe zero-cost dimensional analysis
Apache License 2.0
1.03k stars 98 forks source link

Generic functions that use uom sqrt() #339

Open jacg opened 2 years ago

jacg commented 2 years ago

How would one write a generic function that uses Quantity::sqrt()?

Here is a toy example:

fn pythagoras<D, U>(a: Quantity<D, U, f32>, b: Quantity<D, U, f32>) -> Quantity<D, U, f32> 
where
       ??? ,
{
    (a*a + b*b).sqrt()
}
iliekturtles commented 2 years ago

The function is already available as hypot for f32/f64: https://github.com/iliekturtles/uom/blob/a8b34eac9d1e4bc47f56ededa60656efe80a10a0/src/system.rs#L616-L629

If you're looking to see how to make a function that is generic on the inputs then I expect we're headed to the land of trait bounds madness. For some reason when I drop your function into code that uses uom I get error[E0369]: cannot multiply Quantity<D, U, f32> by Quantity<D, U, f32>. Mul is implemented and you can start adding bounds (Quantity<D, U, f32>: Mul<Quantity<D, U, f32>>,. This is where the madness comes because it just keeps asking you to go deeper.

If you can provide more details about what you're looking to do perhaps there is a more constrained solution that is more feasible.

hypot implementation and bounds for reference: https://github.com/iliekturtles/uom/blob/a8b34eac9d1e4bc47f56ededa60656efe80a10a0/src/system.rs#L935-L943

jacg commented 2 years ago

If you're looking to see how to make a function that is generic on the inputs

Yes, that was my goal: I don't want to have to implement the same functions over and over again for each different Quantity.

then I expect we're headed to the land of trait bounds madness.

Yes, been there, done that, got the T-shirt. A number of times. An absurd explosion of trait bounds, with no end in sight. (Well, on one of my attempts I got the function to compile ... until I tried to call it, then all hell broke loose again.) Hence my question. I assumed I was being dense, or that I missed some key insight.

If you can provide more details about what you're looking to do perhaps there is a more constrained solution that is more feasible.

To start with, I'd like to have a function that can calculate the standard deviation of a collection of homogeneous Quantitys. After that, we'll probably need a variation on the theme in which the data are weighted.

I was wondering whether this might be done with some hack by extracting the base unit value, doing the arithmetic, and wrapping the result back in the original type, in order to avoid having to provide all the bounds that guarantee that you're allowed to do the operations you want ... which seems to be what hypot is doing in its implementation.