AlbertoRuiz/hmatrix — pull request #6 by reinerp (2012-01-07 01:28:39+00:00)
Title: Unsafe building/reading primitives

The attached code includes some changes to improve the typical code generated by hmatrix-syntax. As an example, I used the following file:

module Test where

import Data.Packed
import Data.Packed.ST
import Data.Packed.Development

build :: Double -> Double -> Vector Double
build a b = runSTVector $
do
v <- newUndefinedVector 2
unsafeWriteVector v 0 a
unsafeWriteVector v 1 b
return v

buildMat :: Double -> Double -> Matrix Double
buildMat a b = runSTMatrix $
do
m <- newUndefinedMatrix RowMajor 1 2
unsafeWriteMatrix m 0 0 a
unsafeWriteMatrix m 0 1 b
return m

unpackMat :: Matrix Double -> Double
unpackMat m
| rows m == 1 && cols m == 3
= atM' m 0 0 + atM' m 0 1 + atM' m 0 2
| otherwise = error "unpackMat"

and I examined the generated code with `ghc-core Test.hs`. The changes are as follows:

* support `atM'` for unsafe matrix reads.

* allow newUndefinedMatrix and newUndefinedVector to inline. (They are in the ST monad, so I don't see why this would be unsafe.)

* replace `divMod` with `quotRem`, because `quotRem` is faster in general, and because GHC will constant-fold `quotRem` but not the `divMod`. (This, combined with allowing newUndefinedMatrix to inline as above, means that all the dimension checks in `buildMat` above are optimised away)

* make `Matrix` a product type. I'm much less sure of the this change, since it is quite a significant one. In certain cases, including in the test case above, it avoids some branching. I'm not sure what negative effects this change has, though.

Regards,
Reiner