Skip to content

Instantly share code, notes, and snippets.

@nkaretnikov
Created May 12, 2015 19:29
Show Gist options
  • Save nkaretnikov/0680bc87f7fdba4a9dd4 to your computer and use it in GitHub Desktop.
Save nkaretnikov/0680bc87f7fdba4a9dd4 to your computer and use it in GitHub Desktop.
Milray
import Control.Applicative
import Data.Int
import Data.List
newtype Milray = Milray Int64 deriving Show
projectShareValue :: [Int64] -> Milray
projectShareValue shares =
Milray $ floor $ fromIntegral (10::Int64) * lg (g * 2) * (patrons - 1)
where
lg = logBase 2
patrons = toEnum $ length shares :: Double
-- (Π_{i=1,n} a_i)^{1/n} = exp [1/n Σ_{i=1,n} ln a_i]
-- https://en.wikipedia.org/wiki/Geometric_mean
--
-- This (straightforward) way of calculating the geometric mean:
-- g = (fromIntegral $ foldl1' (*) shares) ** (1 / patrons)
-- may produce a very large number when multiplying. E.g.,
-- projectShareValue $ replicate 101 4
-- overflows Int64 and returns 0 here.
-- So use the following method instead:
g = exp $ 1/patrons * (sum $ (log . fromIntegral) <$> shares)
main = print $ projectShareValue $ replicate 101 4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment