Question

I've got a numeric application that does a lot of work with negative logs of probabilities, which (since probabilities range from zero to one) take the values of positive doubles, or negative infinity (if the underlying probability was zero).

I'm using these with a newtype Score as follows:

newtype Score = Score Double
  deriving (Eq, Ord)
 -- ^ A "score" is the negated logarithm of a probability

negLogZero :: Score -- ^ Stands in for - log 0
negLogZero = Score 10e1024

negLogOne :: Score -- ^ - log 1
negLogOne = Score 0.0

unScore :: Score -> Double
unScore (Score x) = x

instance Show Score where
  show (Score x) = show x

Now, in an implementation of the Viterbi algorithm, I've been using Data.Vector a lot, and indeed I have some Data.Vectors of Scores. While trying to do some performance tuning, I decided to try using Data.Vector.Unboxed. However, I need to write an instance for Unbox, which cannot be derived, and I can't quite figure out what I need to do (particularly, what the contract for the Unbox typeclass is). Since Score is really a Double with some useful constructors and semantics, this should be possible, I'd think. As far as I can tell, I need to be able to tell Data.Vector.Unboxed how big each slot in a vector of Scores must be, and I guess how to read and write them (but heck, they're a lot like Doubles).

So, what do I do? Thanks!

Was it helpful?

Solution

The Unbox type class doesn't have any methods -- it's just shorthand for the Vector and MVector type classes. Derive those, and the Unbox class comes for free (either via deriving or by just writing instance U.Unbox Score on its own line somewhere).

{-# LANGUAGE GeneralizedNewtypeDeriving #-}
import Data.Vector.Generic.Base
import Data.Vector.Generic.Mutable
import qualified Data.Vector.Unboxed as U
newtype Score = Score Double deriving (Vector U.Vector, MVector U.MVector, U.Unbox)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top