Recent

Author Topic: Type checking of units of measurement  (Read 6471 times)

qk

  • New Member
  • *
  • Posts: 13
Re: Type checking of units of measurement
« Reply #45 on: February 04, 2023, 03:51:29 pm »
Thanks circular!

Today I've compiled a real application using the huge dim.pas unit, that with more than five hundred operators.
At the moment the main problem is that the compilation in slowly.

Now I'm restarting with your dim.pas but there are some others unit to add, I will let you know.

circular

  • Hero Member
  • *****
  • Posts: 3962
    • Personal webpage
Re: Type checking of units of measurement
« Reply #46 on: February 04, 2023, 05:07:51 pm »
:)

Ok, I will gladly merge the other units you add.
Conscience is the debugger of the mind

qk

  • New Member
  • *
  • Posts: 13
Re: Type checking of units of measurement
« Reply #47 on: February 04, 2023, 06:42:31 pm »
Hi Circular,

TSquaredMillimeters, TCubicMillimeter ... and others added, but now I have a doubt about the approatch to the problem.

I think that working with the units (TMeter, TMillimeter, TInches ...) requires more operators or code that working with physical quantities (such as TLength, TArea ...).

I've tried to calculate speed using TMillimeter at numerator instead of TKilometer, but before it's needed to create a new class (such as TMillimeterPerHour, TCentimeterPerHour);

If for each combinations of unit (or multiplies) it's needed to write a new class and some operators, I think that there is too much code to write to have a usable unit Dim.pas.

Am I making a mistake? Thanks
« Last Edit: February 04, 2023, 08:02:31 pm by qk »

circular

  • Hero Member
  • *****
  • Posts: 3962
    • Personal webpage
Re: Type checking of units of measurement
« Reply #48 on: February 04, 2023, 08:39:30 pm »
I've applied your changes (add cm2, cm3, mm2, mm3). What you did is correct, there is no mistake.

I have some doubts as well about the maintainability.

Some things can be simplified. For example, the squared/cubed unit type could not be defined.

We could as well not define TMillimeterIdentifier and instead have a simple syntax to build it. For example "3*centi(m)" would be like "3*cm". This doesn't work yet though with the current version of the compiler. Maybe in trunk. We could do "m.centi" but I find it confusing.

Something that could work could be for exponents. For example it is possible to define that "km._2" or "km.sqr" would be the same as km2.

We can gain some space by putting the identifier definition directly on the var line.

Regarding the operators, we could consider unlikely that someone is going to write cm3/cm2 in the code, as it can obviously be replace by cm. I thought it would be nice that the unit would understood by the compiler, but that's not so important. So we can probably remove the additional operator / on units. It will anyway even become problematic if we add exponent 4 for example.

The operator on quantities also could be omitted. I wanted avoid any premultiplication by the unit factor, but one could argue that it doesn't matter much when dividing a volume by a surface. So one can go around this operator by converting to the base unit, for example "(3*km3).ToBase / (2*km2)" instead of "(3*km3) / (2*km2)"

So for example to define centimeters along with its exponents, that could be:
Code: Pascal  [Select][+][-]
  1. type
  2.   TCentimeter = specialize TCentiUnit<TMeter>;
  3.   TCentimeters = specialize TFactoredDimensionedQuantity<TMeter, TCentimeter>;
  4.   TSquareCentimeters = specialize TFactoredSquaredDimensionedQuantity<TMeter, TCentimeter>;
  5.   TCubicCentimeters = specialize TFactoredCubedDimensionedQuantity<TMeter, TCentimeter>;
  6.  
  7. var
  8.   cm: specialize TFactoredUnitIdentifier<TMeter, TCentimeter>;

That could be used like:
Code: Pascal  [Select][+][-]
  1. var
  2.   surface: TSquareCentimeters;
  3. begin
  4.   surface := 5*cm._2;

What do you think?
« Last Edit: February 04, 2023, 08:46:14 pm by circular »
Conscience is the debugger of the mind

qk

  • New Member
  • *
  • Posts: 13
Re: Type checking of units of measurement
« Reply #49 on: February 04, 2023, 11:46:47 pm »
About then proposal "3*centi(m)", "km._2" or "km.sqrt" I find it confusing too.

I'm reading your old posts to better understand the reason for moving from uunit.pas to dim.pas.
I have found two main reasons:

1) There is always a multiplication by a factor, even when it is not necessary (5*m, 10*s ...)

If this is true only when assign a value the first time then I think that it isn't a important problem.
How many people use m and how many people use others (mm cm, dm, foot, inches...) ? 

2) It's needed to define km_h ...

Yes, this is a little cons. km_h isn't intuitive to use.
There are other reasons ?

For my application, an usable dim.pas unit must have capability to manage and combine:

mm, mm2, mm3, mm4
Nm, N/m, N/mm2 (MPa)
kg/dm3
Hz


plus some extra units for calculation (1/mm, 1/mm2, 1/mm3, mm2/s2).
This is minimum requirement, but I want to extend it to english measurement system.

Consider that I have modified some formulas because, for example, in some calculations
the mm4 are exceeded... or there were new units not supported.
The situations can be very different, it' depend on branch, engineering, physics.

I hope that this description can help you to understand which is the better way.
At the moment the game is 1-0 for uunit.pas.  :o

Regards

circular

  • Hero Member
  • *****
  • Posts: 3962
    • Personal webpage
Re: Type checking of units of measurement
« Reply #50 on: February 05, 2023, 12:31:31 am »
Maybe "km.Squared" and we could have as well this function to square a quantity, for example (2*km).Squared = 4*km.Squared.

It is not that bad, and one can define their own unit in they program if they use them a lot.

I suppose you are ok with the other simplifications proposed. I've applied them. I guess it may be more doable now.

1) It is a bit more than that. Either we multiply once at the beginning but it means it is always automatically converted to the base unit, so we need to reconvert it back to the unit we want to display. This premultiplication has some effect on accuracy as well.

2) Indeed

About the other reasons, a big one was the number of operators to define. In the latest version, the number of operators defined for each new unit is considerably smaller. In the old versions I was getting a lot of operators, and in the new versions there are few even though I've added more units.

So for me it is not 1 - 0. I wouldn't say it is 0 - 1 either.
Conscience is the debugger of the mind

qk

  • New Member
  • *
  • Posts: 13
Re: Type checking of units of measurement
« Reply #51 on: February 05, 2023, 09:31:06 am »
Ok! I have tried to add mm4. Please check the code, I'm not a PRO.

circular

  • Hero Member
  • *****
  • Posts: 3962
    • Personal webpage
Re: Type checking of units of measurement
« Reply #52 on: February 05, 2023, 11:03:21 am »
Thanks. I've merged your changes.

About operator overloading, inside a class, it can be defined only if TSelf appears in the parameters * and /. The compiler does not complain but it will be ignored otherwise. That's why if we want m3/m2 then it needs to be defined outside of the meter records.

I am wondering about the name for the fourth power. The name "quarticed" does not seem to be used.

https://www.reddit.com/r/askscience/comments/3rchs6/if_2_is_squared_and_3_is_cubed_what_is_4_called/

Some people suggest "cubic -> cubed" so "quartic -> quarted". Others suggest "tesseracted" as a tesseract is a 4-dimensional cube. But those are not used either.

We can avoid this problem by calling things: square, cubic, quartic, quintic etc. Also the names can be made more consistent, sometimes I've put the cubed sometimes before sometimes after. So I will fix that.
Conscience is the debugger of the mind

qk

  • New Member
  • *
  • Posts: 13
Re: Type checking of units of measurement
« Reply #53 on: February 05, 2023, 11:27:54 am »
Quote
About operator overloading, inside a class, it can be defined only if TSelf appears in the parameters * and /. The compiler does not complain but it will be ignored otherwise. That's why if we want m3/m2 then it needs to be defined outside of the meter records.

Thank for explanation.

Quote
We can avoid this problem by calling things: square, cubic, quartic, quintic etc. Also the names can be made more consistent, sometimes I've put the cubed sometimes before sometimes after. So I will fix that.

I agree and I will wait your changer before start with N/mm.

Edit: with Github, is there a way to propose a change without applying it? I prefer that you apply the changes after checking. So we would avoid exchanging files on the forum.
« Last Edit: February 05, 2023, 11:59:41 am by qk »

circular

  • Hero Member
  • *****
  • Posts: 3962
    • Personal webpage
Re: Type checking of units of measurement
« Reply #54 on: February 05, 2023, 12:25:16 pm »
You're welcome.

I've applied the name changes. Also simplified how powers are defined. For example:
Code: Pascal  [Select][+][-]
  1. type
  2.   generic TSquareUnit<BaseU: TUnit> = {$DEFINE POWER_UNIT_INTF}{$i dim.pas}
  3.   generic TFactoredSquareUnit<BaseU: TFactoredUnit> = {$DEFINE FACTORED_POWER_UNIT_INTF}{$i dim.pas}
  4. ...
  5. { TSquareUnit }
  6.  
  7. class function TSquareUnit.Exponent: integer;
  8. begin
  9.   result := 2;
  10. end;
  11.  
  12. { TFactoredSquareUnit }
  13.  
  14. class function TFactoredSquareUnit.Exponent: integer;
  15. begin
  16.   result := 2;
  17. end;

Indeed, you can propose changes via GitHub. For that you need a GitHub account, and then in my repository, do a fork. The fork button is at the top of the page.

Then checkout your forked repository as any other Git repository, and commit changes there. Then go in my GitHub repository page and do a pull request.
Conscience is the debugger of the mind

qk

  • New Member
  • *
  • Posts: 13
Re: Type checking of units of measurement
« Reply #55 on: February 05, 2023, 12:30:07 pm »
ok thanks, I will try with fork.

I have an other question.
For creating N/m class I think to use TRatioUnit<TNewton, TMeter>, It's right ?

And for creating N/mm ? Millimeters are factored but I can't find TRightFactoredUnitRatio or something like that.

Can you better explain me when to use a class instead of another ?

circular

  • Hero Member
  • *****
  • Posts: 3962
    • Personal webpage
Re: Type checking of units of measurement
« Reply #56 on: February 05, 2023, 01:36:04 pm »
Ok.  :)
 
Indeed that can be a ratio of N and m. In fact here there is a choice we can make. It could be also a ratio of kg and s2 because N/m = kg/s2. So it depends on what is the most common use of this unit.

If you define as N/m, it could make sense to make an operator / that applies to kg and s2 that would also create a quantity in N/m. I don't know if that makes sense from a physical point of view. Then maybe an operator * so that if we multiply a quantity in N/m by a quantity in s2 that would give a quantity in kg.

Or that the operator operator / would give a quantiy in kg/s2 and define this unit as well. Then this could be linked by adding some equivalence like for the litre:
Code: Pascal  [Select][+][-]
  1. // dimension equivalence
  2. operator:=(const AVolume: TLitres): TCubicMeters;
  3. operator:=(const AVolume: TLitres): TCubicDecimeters;
Conscience is the debugger of the mind

qk

  • New Member
  • *
  • Posts: 13
Re: Type checking of units of measurement
« Reply #57 on: February 05, 2023, 02:21:46 pm »
kg/s2 is an acceleration, how fast I will get fat  :D
It can be a case to implement.  :)

I think is more common to multiply N/m (stifness) for m for having N (force).

Now, TNewton isn't a TUnit and we can't define N/m as TUnitRatio. How to fix it ?

Regards

circular

  • Hero Member
  • *****
  • Posts: 3962
    • Personal webpage
Re: Type checking of units of measurement
« Reply #58 on: February 05, 2023, 02:39:31 pm »
kg/s2 is an acceleration, how fast I will get fat  :D
:D

Quote
I think is more common to multiply N/m (stifness) for m for having N (force).

Now, TNewton isn't a TUnit and we can't define N/m as TUnitRatio. How to fix it ?
TNewton is a TFactoredUnit because it is uses kg instead of g. So I suppose you can combine it with TMeter with TFactoredNumeratorUnit.

Ah but then we need to define the base unit for TNewton, I suppose. That would be TMillinewton maybe? EDIT: No in fact that would be TKilogramMeterPerSecondSquared.

If that's too complicated we might want to define two kilograms unit. One being the factored unit from the gram, and one begin the SI base unit.
« Last Edit: February 05, 2023, 02:45:17 pm by circular »
Conscience is the debugger of the mind

qk

  • New Member
  • *
  • Posts: 13
Re: Type checking of units of measurement
« Reply #59 on: February 05, 2023, 03:43:44 pm »
Quote
TNewton is a TFactoredUnit because it is uses kg instead of g. So I suppose you can combine it with TMeter with TFactoredNumeratorUnit.
... but TFactoredNumeratorUnitIdentifier and TFactoredNumeratorUnitQuantity need TUnit not TFactoredUnit.

Quote
If that's too complicated we might want to define two kilograms unit. One being the factored unit from the gram, and one begin the SI base unit.

and then can a user combine units derived from these the two kg units ?
 :'(
« Last Edit: February 05, 2023, 03:45:52 pm by qk »

 

TinyPortal © 2005-2018