packages feed

zwirn-core-0.1.1.0: src/Zwirn/Core/Time.hs

{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}

module Zwirn.Core.Time where

{-
    Time.hs - automated differentiation for time
    Copyright (C) 2025, Martin Gius

    This library is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this library.  If not, see <http://www.gnu.org/licenses/>.
-}

data Time
  = Time {tTime :: Rational, tDiff :: Rational}
  deriving (Eq, Ord)

instance Show Time where
  show (Time x _) = show x

showAll :: Time -> String
showAll (Time x y) = "(" ++ show x ++ "," ++ show y ++ ")"

instance Num Time where
  Time x x' + Time y y' = Time (x + y) (x' + y')
  Time x x' * Time y y' = Time (x * y) (y' * x + x' * y)
  fromInteger x = Time (fromInteger x) 0
  negate (Time x x') = Time (negate x) (negate x')
  signum (Time x _) = Time (signum x) 0
  abs (Time x x') = Time (abs x) (x' * signum x)

instance Enum Time where
  toEnum i = Time (fromIntegral i) 0
  fromEnum (Time i _) = fromEnum i

instance Fractional Time where
  fromRational x = Time x 0
  recip (Time x x') = Time (recip x) (-(x' / x * x))

instance Real Time where
  toRational (Time x x') = x

instance RealFrac Time where
  properFraction (Time x x') = (i, Time p x')
    where
      (i, p) = properFraction x

instance Floating Rational where
  pi = toRational pi
  exp = toRational . exp . fromRational
  log = toRational . log . fromRational
  sin = toRational . sin . fromRational
  cos = toRational . cos . fromRational
  asin = toRational . asin . fromRational
  acos = toRational . acos . fromRational
  atan = toRational . atan . fromRational
  sinh = toRational . sinh . fromRational
  cosh = toRational . cosh . fromRational
  asinh = toRational . asinh . fromRational
  acosh = toRational . acosh . fromRational
  atanh = toRational . atanh . fromRational

instance Floating Time where
  pi = Time pi 0
  exp (Time x x') = Time (exp x) (x' * exp x)
  log (Time x x') = Time (log x) (x' / x)
  sqrt (Time x x') = Time (sqrt x) (x' / (2 * sqrt x))
  sin (Time x x') = Time (sin x) (x' * cos x)
  cos (Time x x') = Time (cos x) (x' * (-sin x))
  asin (Time x x') = Time (asin x) (x' / sqrt (1 - x * x))
  acos (Time x x') = Time (acos x) (x' / (-sqrt (1 - x * x)))
  atan (Time x x') = Time (atan x) (1 / ((x' * x') + 1))
  sinh (Time x x') = Time (sinh x) (cosh x')
  cosh (Time x x') = Time (cosh x) (sinh x')
  asinh (Time x x') = Time (asinh x) (1 / sqrt ((x' * x') + 1))
  acosh (Time x x') = Time (acosh x) (1 / sqrt (x' - 1) * sqrt (x' + 1))
  atanh (Time x x') = Time (atanh x) (1 / (1 - (x' * x')))