Git Product home page Git Product logo

Comments (3)

iliekturtles avatar iliekturtles commented on May 24, 2024

What I was thinking was to have dimensioned provide a high quality comprehensive implementation of the SI system with commonly used units and appropriate conversion factors as a primary goal. A secondary goal would be to allow users to define other systems of units unrelated to SI or use a different set of base units within the SI system. See the (very rough) example below for details about what I am envisioning.

In regards to this issue specifically the problem of conversion is almost entirely removed from the library user as everything is provided by the library. Within the library itself a single conversion factor is necessary (Temperature is an exception). High quality factors can be defined once based and taken from NIST 811. Library users don't need to implement their own system unless the units they're going to be receiving/outputting have a conversion factor too far from the base SI units. Even then the library user would only need to provide a new base unit type to replace Standard used in the example below.

Providing implementations for both f32 and f64 is where I am with my current experimentation. Nested macros may be a solution as 3.048E-1 as $conversion:expr will work in both contexts.

// Define Quantity<D, B, V> where D is the dimensions, B is the base units, and V is the value type.
pub struct Quantity<D, B, V> {
    value: V,
    dimensions: PhantomData<D>,
    base_units: PhantomData<B>,
}

// Define SI<> system with the seven dimensions of quantities.
...

// Define  Standard as the SI base units (m, kg, s, A, K, mol, cd) for the base
// quantities (length, mass, ...). This would be something similar to your From
// trait implementation
...

// Type alias desired base and derived quantities. Note that these aren't specific
// units such as meter or foot.
pub type Length<V> = Quantity<SI<P1, Z0, Z0, Z0, Z0, Z0, Z0>, Standard, V>;
pub type Mass<V> = Quantity<SI<Z0, P1, Z0, Z0, Z0, Z0, Z0>, Standard, V>;
...
pub type Force<V> = Quantity<SI<P1, Z0, N2, Z0, Z0, Z0, Z0>, Standard, V>;

// Define conversion factors, unit descriptions, and abbreviations for quantities
// defined above.
pub trait Conversion<V, U> {
    pub fn to_base(value: V, unit: U) -> V; // Converts value in unit to the base unit.
    pub fn _from_base(value: V, unit: U) -> V; // Converts value in the base unit to unit.
}

define_conversions!(Length
    meter: 1.0, "meter", "m";
    kilometer: Prefix.kilo, "kilometer", "km";
    foot: 3.048E-1, "foot", "f";
    inch: 2.54E-2, "inch", "in";
    ...);

define_conversions!(Mass ...);
...
define_conversions!(Force ...);

// Usage.
use dimensioned::si::f32::{Length, Time, Velocity};

// Raw values, from the user or untyped libraries, need to be lifted into appropriate
// dimensioned types:
let length1 = 100.0 * yard; // Length::new(100.0, yard);
let length2 = 100.0 * meter; // Length::new(100.0, meter);
let time = 100.0 * second; // Time::new(100.0, second);

// Once setup all formulas can be done using appropriate quantities and no effort
// needs to be put into unit conversions or dimensional analysis. The compiler catches
// impossible formulas.
let length3 = length1 + length2;
let velocity1 = length1 / time;
let velocity2 = length2 / time;
//let invalid = length1 + time; // mismatched types [E0308]

// Accessing a specific unit (ex. kilometer, foot, ...) is possible but shouldn't be done until
// a quantity is being persisted or displayed to the user.
let feet: f32 = length3.get(foot); // Discouraged.
println!(/*<format specifier saying value should be displayed in kilometers per
    hour and include the unit's abbreviation>*/, velocity1); // outputs 3.291 km/h

from dimensioned.

iliekturtles avatar iliekturtles commented on May 24, 2024

I put together a very rough proof of concept of the ideas above in https://github.com/iliekturtles/uom/blob/dev-4/examples/si.rs. I also have an even rougher concept with a base units type parameter at https://github.com/iliekturtles/uom/blob/dev-5/examples/new_base.rs.

from dimensioned.

paholg avatar paholg commented on May 24, 2024

I am now pleased with how conversions work (see my latest comment in #9 for details), so I'll close this issue.

If you'd like to discuss them more, feel free to and I'll be happy to reopen this issue.

from dimensioned.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.