goldfirere / units

The home of the units Haskell package
95 stars 19 forks source link

Scalar product: shall we normalize the dimension #31

Closed nushio3 closed 10 years ago

nushio3 commented 10 years ago

With respect to the following update: https://github.com/goldfirere/units/commit/20100a6ee490152942599ab12aad8288cc9dc2ce#diff-55b7a1b2fff6092d774c2e61be91ca57R236

Should scalar product normalize the dimension of quantities?

-- | Multiply a quantity by a scalar from the left
(*|) :: Num n => n -> Qu b l n -> Qu (Normalize b) l n
a *| (Qu b) = Qu (a * b)

The type signature used to be: (*|) :: Num n => n -> Qu b l n -> Qu b l n .

First of all, let me apologize my carelessness if the change was necessary to the updates recently made.

If I have choice, I'd prefer the older type signature that doesn't normalize the type.

I used the fact that the scalar product preserve the quantity type quite a lot in my research. For example, the following code makes some linear combination of function according to air composition:

airMix :: (ChemicalSpecies -> Qu d l Double) -> Qu d l Double
airMix func = 0.78 *| func N2 |+| 0.21 *| func O2 |+| 0.01 *| func Ar

Well, I was able to update the physics code by adding type constraint such as d ~ Normalize d . Then I need the new constraint everywhere I use airMix . In some sense, it can be good convention to encourage keep dimensions normalized.

In addition, the change introduced type errors where I use specific units such as radiance and spectral flux density. I assume the source of error is one of the power index of the dimensions cancelling out and going to zero. I'm trying to create a minimum working example. (Minimum not-working example, to be more precise.)

Anyway, my intuition is that scalar product doesn't change the direction of vector; 2 *| x is equivalent to x |+| x and qSum [x, x]. If the latter two does not normalize the dimension, my thinking is that the former don't, too.

goldfirere commented 10 years ago

I rewrote a bunch of the arithmetic operators in terms of others, in trying to reduce the number of places I used the dangerous Qu constructor. In doing so, I had to subtly change a few type signatures. Then, more refactoring led me to re-introduce the use of the Qu constructors, but I didn't change the types back.

I agree that dropping the Normalize is an improvement here, and will make the change. There are other types that should likely change, too.

Could you provide a standalone test-case that will make sure that this mistake doesn't happen again?

nushio3 commented 10 years ago

Thank you, Richard, and please don't call it a mistake! I appreciate the fast pace you make developments. I am just satisfied with providing usecases and checks. I'm happy if they would assist the development.

May I ask questions for the test design? I see many tests are called from Tests/Main.hs . Are there any test conventions I should follow? Are they automated?

goldfirere commented 10 years ago

See the newly-created file https://github.com/goldfirere/units/blob/master/Tests/README.md for more info about testing.

nushio3 commented 10 years ago

Thank you!

nushio3 commented 10 years ago

Hi,

I wrote the test, and also changed the type signatures to make the test pass c.f. 309236af6dcc6aae4da1bb4b2c7bab91534b6614 . Sorry for taking your job :)

Please apply any other type changes in your mind and then close this issue.

goldfirere commented 10 years ago

Looks good to me. Thanks!