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

Fractional units #27

Open
wants to merge 11 commits into
base: master
Choose a base branch
from

Conversation

joshuashaffer
Copy link

This is an idea to allow fractional dimension units that are powers of 1/2 or 1/4. We use the same amount of storage and just shift all the unit definitions to the left two bits and use those two bits as the binary fractions .5 and .25.

For example we can represent fracture toughness this way...

unit_databases=# select '1.0 psi * in^.5'::unit;
              unit
--------------------------------
 1098.84349410875 kg/m^0.50*s^2
(1 row)

unit_databases=# select '1.0 ksi * in^.5'::unit;
              unit
--------------------------------
 1098843.49410875 kg/m^0.50*s^2
(1 row)

unit_databases=# select '1.0 ksi * in^.52'::unit;
ERROR:  unit exponent is not allowed "^.52". Fractional part must be be one of: .0, .25, .5, .75.
LINE 1: select '1.0 ksi * in^.52'::unit;

@joshuashaffer
Copy link
Author

Add predicate function to test if a unit is compatible with a string representation of the unit.

This allows you to add constrains to unit columns.

unit_databases=# create table a (temp unit check(unit_compatible(temp,'degC')));
CREATE TABLE
unit_databases=# insert into a values ('12 degF'::unit);
INSERT 0 1
unit_databases=# insert into a values ('12 degC'::unit);
INSERT 0 1
unit_databases=# insert into a values ('12 degK'::unit);
INSERT 0 1
unit_databases=# insert into a values ('12 m'::unit);
ERROR:  new row for relation "a" violates check constraint "a_temp_check"
DETAIL:  Failing row contains (12 m).

@df7cb
Copy link
Owner

df7cb commented Dec 1, 2019

Hi,
when I implemented the module, I was looking at fractional units, and iirc the outcome was that the practical relevance was low.
But maybe I was wrong - which units do use them? The Wikipedia article https://en.wikipedia.org/wiki/Fracture_toughness doesn't even talk about the unit which appears as heading in the materials table.

@joshuashaffer
Copy link
Author

Plane-strain fracture toughness (K_ic) has the SI units MPa m^.5. Its definition and measurement are given in ASTM E399.

@joshuashaffer
Copy link
Author

joshuashaffer commented Dec 2, 2019

Added a predicate function that, given a text parameter, will tell you if that is parseable unit.

unit_databases=# select unit_valid('MPa m^0.5');
 unit_valid
------------
 t
(1 row)

unit_databases=# select unit_valid('abcdefghijklmnop');
 unit_valid
------------
 f
(1 row)

unit_databases=# select unit_valid('MPa m^1.2');
 unit_valid
------------
 f
(1 row)

Also added a function that prints out the value of UnitShifted as a double array...

unit_databases=# select unit_send_array('1 MPa m^0.5'::unit);
        unit_send_array
-------------------------------
 {1000000,-0.5,1,-2,0,0,0,0,0}
(1 row)

@df7cb
Copy link
Owner

df7cb commented Dec 5, 2019

TBH I need some time to think about this. Parts of me says "wtf physics doesn't like these", parts says "yeah people do use them". Then there's also the issue with breaking the on-disk format for people who have actually stored data in "unit" columns. I was actually pondering to halve the bit width of exponents to have room for more basic units (like € or $), this change would best be done with this one in parallel.

@joshuashaffer
Copy link
Author

joshuashaffer commented Dec 6, 2019

A few more ideas that could be useful: add base unit for pixel and cycle. I changed the unit definitions for angle and solid angles to be defined in terms of the new cycle base unit.

With these, it's possible to do things like this ...

unit_database=# select '72 pixel/in'::unit^2 @@ 'pixel^2/mm^2';
     ?column?
------------------
 8.03521607043214
(1 row)

unit_database=# select '1 sr'::unit @@ 'degree^2';
      ?column?
--------------------
 3282.8063500117437
(1 row)

unit_database=# select ('1 Hz'::unit * '.2  seconds'::unit) @@ 'radian';
      ?column?
--------------------
 1.2566370614359172
(1 row)

unit_database=# select '24 bits/pixel'::unit @@ 'MB/(1e6 pixel)';
 ?column?
----------
        3
(1 row)

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

Successfully merging this pull request may close these issues.

2 participants