Skip to content

Add quantity constructor overload for UnitSystem #547

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
angularsen opened this issue Nov 3, 2018 · 9 comments
Closed

Add quantity constructor overload for UnitSystem #547

angularsen opened this issue Nov 3, 2018 · 9 comments
Assignees

Comments

@angularsen
Copy link
Owner

Per discussion in #519, we want to construct quantities using a unit system such as SI or a custom unit system. The advantage is consistent base units and not having to specify the unit when constructing quantities.

So you can do

new Length(1); // 1 meter, SI unit system
new Length(1, UnitSystem.SI); // same
new Length(1, myUnitSystem); // whatever length unit you configured in your system

Implementation

  • Add constructor MyQuantity(double numericValue, UnitSystem unitSystem) {}
  • Add constructor MyQuantity(double numericValue) : MyQuantity(numericValue, UnitSystem.SI) {}

Quantities with dimensions matching base units is easy

public Length(double numericValue, UnitSystem unitSystem) 
    : this(numericValue, unitSystem.BaseUnits.Length) { }

Dimensionless quantities?

Information, Ratio, Angle, etc...

public Information(decimal numericValue, UnitSystem unitSystem) 
    : this(numericValue, unitSystem.BaseUnits./*???*/) { }

These are not coupled to any unit system, so we can keep the existing choice of base unit?

Logarithmic quantities?

Level (dB), PoweRatio, AmplitudeRatio

public PowerRatio(decimal numericValue, UnitSystem unitSystem) 
    : this(numericValue, unitSystem.BaseUnits./*???*/) { }

AmplitudeRatio dBV

Unit system: (used in any unit system)

PoweRatio dBW

Unit system: (not in a named unit system)

They seem uncoupled from unit systems, so we can keep the existing choices of base unit?

Non-trivial quantities?

Most quantities fall in this category. How do we construct them given a non-SI instance of UnitSystem?

ElectricChargeDensity C/m³

Unit system: Système International d'Unités (SI)

public ElectricChargeDensity(decimal numericValue, UnitSystem unitSystem) 
    : this(numericValue, unitSystem.BaseUnits./*???*/) { }
@angularsen angularsen added this to the 4.0 milestone Nov 3, 2018
@angularsen
Copy link
Owner Author

angularsen commented Nov 3, 2018

@tmilnthorp I started on this and quickly realized I didn't fully understand how we should implement it. Hoping you have some ideas :-)

I hoped to bring it into v4, but it can wait to v5 if it's not straight forward.

@tmilnthorp
Copy link
Collaborator

  • For base quantities it is indeed as easy as picking up the unit directly from the UnitSystem's BaseUnits
  • Dimensionless don't need to do anything. Always Dimensionless.
  • I am not 100% certain what to do for log quantities. They're really just a ratio of something (power, sound pressure, etc.). I believe a 3dB change in W is the same as a 3dB change in Btu/hr. Not sure if it's as easy as converting the ratio unit?
  • For derived quantities, we'll need to specify the base units for each. For example Area in SquareMile will need BaseUnit.Length = Length.Mile. If you pass a UnitSystem where BaseUnit.Length = Length.Mile, you match the unit.

@tmilnthorp
Copy link
Collaborator

I wonder how we'll resolve things like this:

      "SingularName": "SquareFoot",
      "PluralName": "SquareFeet",
      "BaseUnits": {
        "Length": "LengthUnit.Foot"
      },
      "FromUnitToBaseFunc": "x*0.092903",
      "FromBaseToUnitFunc": "x/0.092903",
      "Localization": [
        {
          "Culture": "en-US",
          "Abbreviations": [ "ft²" ]
        },
        {
          "Culture": "ru-RU",
          "Abbreviations": [ "фут²" ]
        }
      ]
    },
    {
      "SingularName": "UsSurveySquareFoot",
      "PluralName": "UsSurveySquareFeet",
      "BaseUnits": {
        "Length": "LengthUnit.Foot"
      },
      "FromUnitToBaseFunc": "x*0.09290341161",
      "FromBaseToUnitFunc": "x/0.09290341161",
      "Localization": [
        {
          "Culture": "en-US",
          "Abbreviations": [ "ft² (US)" ]
        }
      ]
    },

Both have a base unit of feet. Similar to ambiguous parsing we'll have ambiguous unit system values potentially.

@angularsen
Copy link
Owner Author

Well, in this particular scenario, UsSurveySquareFoot should have BaseUnits.Length = LengthUnit.UsSurveyFoot. I can't immediately think of a scenario where units have overlapping base units like you describe here, but I'm also not certain there aren't any.

I think maybe we'll just have to try mapping up all the units and see if we find any ambiguity?

@angularsen
Copy link
Owner Author

One thing we can run into is unmapped units. You've defined a UnitSystem with base length unit UsSurveyFoot. Then you try to create an Area with this unit system and maybe we didn't get around to adding UsSurveySquareFoot yet. That would throw an exception. Not sure how big of a problem this would be, but I kind of don't like running into runtime exceptions like this. At least something to be aware of when using these constructors.

Another thing is, we are adding significant complexity here and I sincerely hope it adds enough value that people will make use of it.

@angularsen angularsen removed this from the 4.0 milestone Dec 16, 2018
@tmilnthorp tmilnthorp mentioned this issue Jan 28, 2019
@angularsen
Copy link
Owner Author

I'm not sure how to move this discussion along. There seems to be some uncertainty how this should all work, I think I need to see a PR with some actual code and tests to consider it further. I'm closing this issue due to inactivity, please create a PR or reopen this issue to discuss further.

@tmilnthorp
Copy link
Collaborator

In my example PR you can see I added a constructor for it. Just need to finalize that and add base units for everything

@angularsen
Copy link
Owner Author

angularsen commented Feb 16, 2019

For reference, ☝️ is #601 .

@tmilnthorp
Copy link
Collaborator

Now I just need some help adding BaseUnits for all the units we have!

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

No branches or pull requests

2 participants