tropical-0.0.0.0: src/Data/Semiring/Tropical.hs
{-|
Module : Data.Semiring.Tropical
Description : The definition of tropicality
Copyright : 2014, Peter Harpending.
License : BSD3
Maintainer : Peter Harpending <pharpend2@gmail.com>
Stability : experimental
Portability : Linux
This file just contains the minimal definition of "tropical," meaning
any tropical object has to be an ordered semiring.
-}
module Data.Semiring.Tropical where
import Data.Semiring
-- |Tropical numbers are like real numbers, except zero is the same
-- thing as Infinity, and you can't subtract.
data Real t => Tropical t = Tropical { realValue :: t } -- ^Any tropical number
| Infinity -- ^Infinity
deriving (Eq, Ord, Show)
type Operator a = a -> a -> a
instance Real a => Semiring (Tropical a) where
-- |Tropical addition is the same as taking the minimum
a .+. b = min a b
-- |Tropical multiplication is the same as the sum
a .*. b
| Infinity==a || Infinity==b = Infinity
| otherwise = Tropical $ (realValue a) + (realValue b)
-- |Infinity acts like zero.
zero = Infinity
-- |Zero acts like one.
one = Tropical 0
-- |Tropical division. Remember, if Infinity is tropical zero, then
-- you can't divide by it!
(./.) :: Real a => Operator (Tropical a)
_ ./. Infinity = undefined
Infinity ./. _ = Infinity
a ./. b = Tropical $ (realValue a) - (realValue b)
-- -- |Tropical exponentiation - same as classical multiplication. A
-- -- mildly interesting correlary is that tropical exponentiation is
-- -- commutative. That is, y .^. x = x .^. y, for x and y tropical.
(.^.) :: Real a => Operator (Tropical a)
a .^. b
| Infinity==a || Infinity==b = Infinity
| otherwise = Tropical $ (realValue a) * (realValue b)