packages feed

gasp 1.2.0.0 → 1.3.0.0

raw patch · 3 files changed

+326/−152 lines, 3 filesdep +QuickCheckPVP ok

version bump matches the API change (PVP)

Dependencies added: QuickCheck

API changes (from Hackage documentation)

- Algebra.Classes: (:%) :: !a -> !a -> Ratio a
- Algebra.Classes: (:+) :: InitialAdditive -> InitialAdditive -> InitialAdditive
- Algebra.Classes: Zero :: InitialAdditive
- Algebra.Classes: add :: (Foldable t, Additive a) => t a -> a
- Algebra.Classes: data InitialAdditive
- Algebra.Classes: data Ratio a
- Algebra.Classes: instance (GHC.Classes.Ord k, Algebra.Classes.Module v v) => Algebra.Classes.Module v (Data.Map.Internal.Map k v)
- Algebra.Classes: instance Algebra.Classes.Additive Algebra.Classes.InitialAdditive
- Algebra.Classes: instance GHC.Classes.Eq a => GHC.Classes.Eq (Algebra.Classes.Ratio a)
- Algebra.Classes: instance GHC.Show.Show Algebra.Classes.InitialAdditive
- Algebra.Classes: multiply :: (Multiplicative a, Foldable f) => f a -> a
- Algebra.Classes: type MyRational = Ratio Integer
- Algebra.Classes: type VectorSpace scalar a = (Field scalar, Module scalar a)
- Algebra.Linear: (>$<) :: (Applicative v, Applicative w) => (a -> s) -> Mat a v w -> Mat s v w
- Algebra.Linear: (>*<) :: (Applicative v, Applicative w) => Mat (a -> s) v w -> Mat a v w -> Mat s v w
- Algebra.Linear: dotProd :: InnerProdSpace v => v -> v -> Scalar v
- Algebra.Linear: instance (Algebra.Classes.Ring a, Algebra.Classes.Field a, GHC.Base.Applicative f, Data.Foldable.Foldable f) => Algebra.Linear.InnerProdSpace (Algebra.Linear.Euclid f a)
- Algebra.Linear: instance forall k1 (s :: k1) k2 (w :: k1 -> k2) (v :: k2 -> *). GHC.Show.Show (v (w s)) => GHC.Show.Show (Algebra.Linear.Mat s w v)
- Algebra.Linear: matMul' :: (Traversable u, Ring s, Applicative w, Applicative v, Applicative u) => Mat s v u -> Mat s u w -> Mat s v w
- Algebra.Linear: type family Scalar v;
- Algebra.Linear: }
+ Algebra.Classes: (=.=) :: TestEqual a => a -> a -> Property
+ Algebra.Classes: (^+) :: Multiplicative a => a -> Natural -> a
+ Algebra.Classes: class (Arbitrary a, Show a) => TestEqual a
+ Algebra.Classes: infix 0 =.=
+ Algebra.Classes: infixr 8 ^
+ Algebra.Classes: instance (GHC.Classes.Ord k, Algebra.Classes.Module a b) => Algebra.Classes.Module a (Data.Map.Internal.Map k b)
+ Algebra.Classes: instance (GHC.Classes.Ord x, GHC.Show.Show x, Test.QuickCheck.Arbitrary.Arbitrary x, Algebra.Classes.TestEqual a, Algebra.Classes.Additive a) => Algebra.Classes.TestEqual (Data.Map.Internal.Map x a)
+ Algebra.Classes: instance Algebra.Classes.AbelianAdditive a => Algebra.Classes.AbelianAdditive (Data.Complex.Complex a)
+ Algebra.Classes: instance Algebra.Classes.Additive a => Algebra.Classes.Additive (Data.Complex.Complex a)
+ Algebra.Classes: instance Algebra.Classes.Field a => Algebra.Classes.Division (Data.Complex.Complex a)
+ Algebra.Classes: instance Algebra.Classes.Field a => Algebra.Classes.Field (Data.Complex.Complex a)
+ Algebra.Classes: instance Algebra.Classes.Group a => Algebra.Classes.Group (Data.Complex.Complex a)
+ Algebra.Classes: instance Algebra.Classes.Multiplicative Test.QuickCheck.Property.Property
+ Algebra.Classes: instance Algebra.Classes.Ring a => Algebra.Classes.Module (Data.Complex.Complex a) (Data.Complex.Complex a)
+ Algebra.Classes: instance Algebra.Classes.Ring a => Algebra.Classes.Module a (Data.Complex.Complex a)
+ Algebra.Classes: instance Algebra.Classes.Ring a => Algebra.Classes.Multiplicative (Data.Complex.Complex a)
+ Algebra.Classes: instance Algebra.Classes.Ring a => Algebra.Classes.Ring (Data.Complex.Complex a)
+ Algebra.Classes: instance Algebra.Classes.TestEqual GHC.Types.Int
+ Algebra.Classes: law_decidable_zero :: forall a. (DecidableZero a, TestEqual a) => Property
+ Algebra.Classes: law_module_mul :: forall s a. (Module s a, TestEqual a) => s -> s -> a -> Property
+ Algebra.Classes: law_module_one :: forall s a. (Module s a, TestEqual a) => a -> Property
+ Algebra.Classes: law_module_sum :: forall s a. (Module s a, TestEqual a) => s -> a -> a -> Property
+ Algebra.Classes: law_module_sum_left :: forall s a. (Module s a, TestEqual a) => s -> s -> a -> Property
+ Algebra.Classes: law_module_zero :: forall s a. (Module s a, TestEqual a) => s -> Property
+ Algebra.Classes: law_mult :: (TestEqual a, Group a) => Integer -> a -> Property
+ Algebra.Classes: law_negate_minus :: (TestEqual a, Group a) => a -> a -> Property
+ Algebra.Classes: law_plus_assoc :: (Additive a, TestEqual a) => a -> a -> a -> Property
+ Algebra.Classes: law_plus_comm :: (TestEqual a, Additive a) => a -> a -> Property
+ Algebra.Classes: law_plus_zero :: (Additive a, TestEqual a) => a -> Property
+ Algebra.Classes: law_times :: (TestEqual a, Additive a) => Positive Integer -> a -> Property
+ Algebra.Classes: law_zero_plus :: forall a. (Additive a, TestEqual a) => a -> Property
+ Algebra.Classes: laws_abelian_additive :: forall a. (Group a, TestEqual a) => Property
+ Algebra.Classes: laws_abelian_group :: forall a. (Group a, TestEqual a) => Property
+ Algebra.Classes: laws_additive :: forall a. (Additive a, TestEqual a) => Property
+ Algebra.Classes: laws_group :: forall a. (Group a, TestEqual a) => Property
+ Algebra.Classes: laws_module :: forall s a. (Module s a, TestEqual a, Arbitrary s, Show s) => Property
+ Algebra.Classes: multDefault :: Group a => Natural -> a -> a
+ Algebra.Classes: nameLaw :: Testable prop => String -> prop -> Property
+ Algebra.Classes: product :: (Multiplicative a, Foldable f) => f a -> a
+ Algebra.Classes: sum :: (Foldable t, Additive a) => t a -> a
+ Algebra.Classes: timesDefault :: (Additive a2, Integral a1) => a1 -> a2 -> a2
+ Algebra.Linear: (*<) :: (Functor f, Multiplicative b) => b -> f b -> f b
+ Algebra.Linear: (<+>) :: (Applicative f, Additive b) => f b -> f b -> f b
+ Algebra.Linear: Flat :: w (v s) -> Flat w v s
+ Algebra.Linear: [fromFlat] :: Flat w v s -> w (v s)
+ Algebra.Linear: flatMat :: Mat s w v -> Flat w v s
+ Algebra.Linear: infixr 7 *<
+ Algebra.Linear: inner :: (InnerProdSpace v, Field s) => v s -> v s -> s
+ Algebra.Linear: instance (Data.Foldable.Foldable w, Data.Foldable.Foldable v) => Data.Foldable.Foldable (Algebra.Linear.Flat w v)
+ Algebra.Linear: instance (GHC.Base.Applicative w, GHC.Base.Applicative v) => GHC.Base.Applicative (Algebra.Linear.Flat w v)
+ Algebra.Linear: instance (GHC.Base.Functor w, GHC.Base.Functor v) => GHC.Base.Functor (Algebra.Linear.Flat w v)
+ Algebra.Linear: instance Algebra.Linear.VectorR f => Algebra.Linear.InnerProdSpace (Algebra.Linear.Euclid f)
+ Algebra.Linear: instance forall k1 (s :: k1) k2 (w :: k2 -> *) (v :: k1 -> k2). GHC.Show.Show (w (v s)) => GHC.Show.Show (Algebra.Linear.Mat s w v)
+ Algebra.Linear: instance forall k1 (w :: k1 -> *) k2 (v :: k2 -> k1) (s :: k2). GHC.Show.Show (w (v s)) => GHC.Show.Show (Algebra.Linear.Flat w v s)
+ Algebra.Linear: matFlat :: Flat w v s -> Mat s w v
+ Algebra.Linear: newtype Flat w v s
+ Algebra.Linear: type VectorR v = (Applicative v, Traversable v)
+ Algebra.Linear: type VectorSpace scalar a = (Field scalar, Module scalar a, Group a)
- Algebra.Classes: (^) :: Multiplicative a => a -> Natural -> a
+ Algebra.Classes: (^) :: Division a => a -> Integer -> a
- Algebra.Linear: (·) :: InnerProdSpace v => v -> v -> Scalar v
+ Algebra.Linear: (·) :: Field s => InnerProdSpace v => v s -> v s -> s
- Algebra.Linear: (⊗) :: (Applicative v, Applicative w, Multiplicative s) => Euclid w s -> Euclid v s -> Mat s w v
+ Algebra.Linear: (⊗) :: (Applicative v, Applicative w, Multiplicative s) => w s -> v s -> Mat s w v
- Algebra.Linear: Mat :: v (w s) -> Mat s w v
+ Algebra.Linear: Mat :: w (v s) -> Mat s w v
- Algebra.Linear: [fromMat] :: Mat s w v -> v (w s)
+ Algebra.Linear: [fromMat] :: Mat s w v -> w (v s)
- Algebra.Linear: class VectorSpace (Scalar v) v => InnerProdSpace v where {
+ Algebra.Linear: class VectorR v => InnerProdSpace v
- Algebra.Linear: diagonal :: Traversable v => Ring s => Applicative v => Euclid v s -> SqMat v s
+ Algebra.Linear: diagonal :: Traversable v => Ring s => Applicative v => v s -> SqMat v s
- Algebra.Linear: matVecMul :: (Foldable f1, Ring b, Applicative f1, Functor f2) => Mat b f1 f2 -> Euclid f1 b -> Euclid f2 b
+ Algebra.Linear: matVecMul :: forall s v w. (Ring s, Foldable v, Applicative v, Applicative w) => Mat s v w -> v s -> w s
- Algebra.Linear: norm :: InnerProdSpace v => Floating (Scalar v) => v -> Scalar v
+ Algebra.Linear: norm :: Field s => InnerProdSpace v => Floating s => v s -> s
- Algebra.Linear: normalize :: Floating (Scalar v) => InnerProdSpace v => v -> v
+ Algebra.Linear: normalize :: VectorSpace s (v s) => Floating s => InnerProdSpace v => v s -> v s
- Algebra.Linear: pattern Mat2x2 :: forall s. s -> s -> s -> s -> Mat s V2' V2'
+ Algebra.Linear: pattern Mat2x2 :: forall s. s -> s -> s -> s -> Mat s V2 V2
- Algebra.Linear: pattern Mat3x3 :: forall s. s -> s -> s -> s -> s -> s -> s -> s -> s -> Mat s V3' V3'
+ Algebra.Linear: pattern Mat3x3 :: forall s. s -> s -> s -> s -> s -> s -> s -> s -> s -> Mat s V3 V3
- Algebra.Linear: rotation2d :: Floating a => a -> Mat2x2 a
+ Algebra.Linear: rotation2d :: (Group a, Floating a) => a -> Mat2x2 a
- Algebra.Linear: sqNorm :: InnerProdSpace v => v -> Scalar v
+ Algebra.Linear: sqNorm :: Field s => InnerProdSpace v => v s -> s
- Algebra.Linear: transpose :: Applicative f => Traversable g => Mat a f g -> Mat a g f
+ Algebra.Linear: transpose :: Applicative g => Traversable f => Mat a f g -> Mat a g f
- Algebra.Linear: type Mat2x2 s = SqMat V2' s
+ Algebra.Linear: type Mat2x2 s = SqMat V2 s
- Algebra.Linear: type Mat3x3 s = SqMat V3' s
+ Algebra.Linear: type Mat3x3 s = SqMat V3 s

Files

Algebra/Classes.hs view
@@ -1,8 +1,15 @@+{-# LANGUAGE TupleSections #-}+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE GADTs #-} {-# LANGUAGE MultiParamTypeClasses, ConstraintKinds, FlexibleContexts, FlexibleInstances, DeriveGeneric #-} module Algebra.Classes where -import Prelude as Algebra.Classes (Int,Integer,Float,Double, Foldable (..), (==), Monoid(..), Ord(..)-                                  ,Real(..), Enum(..), snd, Rational, Functor(..), Eq(..), Bool(..), Semigroup(..))+import Prelude (Int,Integer,Float,Double, (==), Monoid(..), Ord(..), Foldable,+                foldMap, Char,+                 Real(..), Enum(..), snd, Rational, Functor(..), Eq(..), Bool(..), Semigroup(..), Show(..), uncurry)+ import qualified Prelude import qualified Data.Ratio import qualified Data.Map.Strict as M@@ -10,8 +17,13 @@ import Foreign.C import Data.Word import Data.Binary+import Data.Complex import GHC.Generics+import Test.QuickCheck+import Control.Applicative +-- import Data.Functor.Utils ((#.))+ infixl 6 - infixl 6 + @@ -20,6 +32,8 @@ infixl 7 / infixl 7 `mod` infixl 7 `div`+infixr 8 ^+infixr 8 ^+  type Natural = Integer @@ -48,25 +62,62 @@ instance Additive a => Multiplicative (Exponential a) where   Exponential a * Exponential b = Exponential (a + b)   one = Exponential zero-  Exponential a ^ n = Exponential (times n a)+  Exponential a ^+ n = Exponential (times n a)  instance Group a => Division (Exponential a) where   recip (Exponential a) = Exponential (negate a)   Exponential a / Exponential b = Exponential (a - b) +timesDefault :: (Additive a2, Prelude.Integral a1) => a1 -> a2 -> a2+timesDefault n0 = if n0 < 0 then Prelude.error "Algebra.Classes.times: negative number of times" else go n0+    where go 0 _ = zero+          go n x = if r == 0 then y + y else x + y + y+            where (m,r) = n `Prelude.divMod` 2+                  y = go m x+ -- | Additive monoid class Additive a where   (+) :: a -> a -> a   zero :: a   times :: Natural -> a -> a-  times 0 _ = zero-  times n x = if r == 0 then y + y else x + y + y-    where (m,r) = n `Prelude.divMod` 2-          y = times m x+  times = timesDefault -add :: (Foldable t, Additive a) => t a -> a-add xs = fromSum (foldMap Sum xs)+class (Arbitrary a, Show a) => TestEqual a where+  (=.=) :: a -> a -> Property +infix 0 =.=++instance Multiplicative Property where+  one = property True+  (*) = (.&&.)++nameLaw :: Testable prop => Prelude.String -> prop -> Property+nameLaw x p = label x (counterexample x p)++law_zero_plus :: forall a. (Additive a, TestEqual a) => a -> Property+law_zero_plus n = nameLaw "zero/plus" (zero + n =.= n)++law_plus_zero :: (Additive a, TestEqual a) => a -> Property+law_plus_zero n = nameLaw "plus/zero" (n + zero =.= n)++law_plus_assoc :: (Additive a, TestEqual a) => a -> a -> a -> Property+law_plus_assoc m n o = nameLaw "plus/assoc" (n + (m + o) =.= (n + m) + o)++law_times :: (TestEqual a, Additive a) => Positive Integer -> a -> Property+law_times (Positive m) n = nameLaw "times" (times m n =.= timesDefault m n)++laws_additive :: forall a. (Additive a, TestEqual a) => Property+laws_additive = product [property (law_zero_plus @a)+                        ,property (law_plus_zero @a)+                        ,property (law_plus_assoc @a)+                        ,property (law_times @a)]++instance TestEqual Int where (=.=) = (===)+++sum :: (Foldable t, Additive a) => t a -> a+sum xs = fromSum (foldMap Sum xs)+ instance Additive Integer where   (+) = (Prelude.+)   zero = 0@@ -115,6 +166,10 @@ class Additive r => DecidableZero r where   isZero :: r -> Bool +law_decidable_zero :: forall a. (DecidableZero a, TestEqual a) => Property+law_decidable_zero = property (isZero (zero @a))++ instance DecidableZero Integer where   isZero = (== 0) instance DecidableZero CInt where@@ -136,6 +191,13 @@  class Additive a => AbelianAdditive a   -- just a law.++law_plus_comm :: (TestEqual a, Additive a) => a -> a -> Property+law_plus_comm m n = nameLaw "plus/comm" (m + n =.= n + m)++laws_abelian_additive :: forall a. (Group a, TestEqual a) => Property+laws_abelian_additive = laws_additive @a .&&. product [property (law_plus_comm @a)]+ instance AbelianAdditive Integer instance AbelianAdditive CInt instance AbelianAdditive Int@@ -143,6 +205,9 @@ instance AbelianAdditive Float instance (Ord k,AbelianAdditive v) => AbelianAdditive (Map k v) +multDefault :: Group a => Natural -> a -> a+multDefault n x = if n < 0 then negate (times (negate n) x) else times n x+ class Additive a => Group a where   {-# MINIMAL (negate | (-)) #-}   (-) :: a -> a -> a@@ -150,8 +215,23 @@   negate :: a -> a   negate b = zero - b   mult :: Integer -> a -> a-  mult n x = if n < 0 then negate (times (negate n) x) else times n x+  mult = multDefault +law_negate_minus :: (TestEqual a, Group a) => a -> a -> Property+law_negate_minus m n = nameLaw "minus/negate" (m + negate n =.= m - n)++law_mult :: (TestEqual a, Group a) => Integer -> a -> Property+law_mult m n = nameLaw "mult" (mult m n =.= multDefault m n)+++laws_group :: forall a. (Group a, TestEqual a) => Property+laws_group = laws_additive @a .&&. product [property (law_negate_minus @a)+                                           ,property (law_mult @a)]++laws_abelian_group :: forall a. (Group a, TestEqual a) => Property+laws_abelian_group = laws_group @a .&&. product [property (law_plus_comm @a)]++ instance Group Integer where   (-) = (Prelude.-)   negate = Prelude.negate@@ -194,6 +274,36 @@ class (AbelianAdditive a, PreRing scalar) => Module scalar a where   (*^) :: scalar -> a -> a +law_module_zero :: forall s a. (Module s a, TestEqual a) => s -> Property+law_module_zero s = nameLaw "module/zero" (s *^ zero =.= zero @a)++law_module_one :: forall s a. (Module s a, TestEqual a) => a -> Property+law_module_one x = nameLaw "module/one" ((one @s) *^ x =.= x)++law_module_sum :: forall s a. (Module s a, TestEqual a) => s -> a -> a -> Property+law_module_sum s x y = nameLaw "module/distr/left" (s *^ (x + y) =.= s*^x + s *^ y)++law_module_sum_left :: forall s a. (Module s a, TestEqual a) => s -> s -> a -> Property+law_module_sum_left s t x = nameLaw "module/distr/right" ((s + t) *^ x =.= s*^x + t *^ x)++law_module_mul :: forall s a. (Module s a, TestEqual a) => s -> s -> a -> Property+law_module_mul s t x = nameLaw "module/mul/assoc" ((s * t) *^ x =.= s *^ t *^ x)++laws_module :: forall s a. (Module s a, TestEqual a, Arbitrary s, Show s) => Property+laws_module = laws_additive @a .&&. product [property (law_module_zero @s @a)+                                            ,property (law_module_one @s @a)+                                            ,property (law_module_sum @s @a)+                                            ,property (law_module_sum_left @s @a)+                                            ,property (law_module_mul @s @a)+                                            ]++-- Comparision of maps with absence of a key equivalent to zero value.+instance (Ord x, Show x, Arbitrary x,TestEqual a,Additive a) => TestEqual (Map x a) where+  x =.= y = product (uncurry (=.=) <$> M.unionWith collapse ((,zero) <$> x) ((zero,) <$> y))+    where collapse :: (a,b) -> (c,d) -> (a,d)+          collapse (a,_) (_,b) = (a,b)++ instance Module Integer Integer where   (*^) = (*) @@ -209,64 +319,67 @@ instance Module Float Float where   (*^) = (*) -instance (Ord k, Module v v) => Module v (Map k v) where-  s *^ m = fmap (s *) m+instance (Ord k, Module a b) => Module a (Map k b) where+  s *^ m = fmap (s *^) m  -- | Multiplicative monoid class Multiplicative a where   (*) :: a -> a -> a   one :: a-  (^) :: a -> Natural -> a+  (^+) :: a -> Natural -> a -  (^) _ 0 = one-  (^) x n = if r == 0 then y * y else x * y * y-    where (m,r) = n `Prelude.divMod` 2-          y = (^) y m+  x0 ^+ n0 = if n0 < 0 then Prelude.error "Algebra.Classes.^: negative exponent" else go x0 n0+    where go _ 0 = one+          go x n = if r == 0 then y * y else x * y * y+            where (m,r) = n `Prelude.divMod` 2+                  y = go x m -multiply :: (Multiplicative a, Foldable f) => f a -> a-multiply xs = fromProduct (foldMap Product xs) +product :: (Multiplicative a, Foldable f) => f a -> a+product xs = fromProduct (foldMap Product xs)+ instance Multiplicative Integer where   (*) = (Prelude.*)   one = 1-  (^) = (Prelude.^)+  (^+) = (Prelude.^)  instance Multiplicative CInt where   (*) = (Prelude.*)   one = 1-  (^) = (Prelude.^)+  (^+) = (Prelude.^)  instance Multiplicative Word32 where   (*) = (Prelude.*)   one = 1-  (^) = (Prelude.^)+  (^+) = (Prelude.^)  instance Multiplicative Word16 where   (*) = (Prelude.*)   one = 1-  (^) = (Prelude.^)+  (^+) = (Prelude.^)  instance Multiplicative Word8 where   (*) = (Prelude.*)   one = 1-  (^) = (Prelude.^)+  (^+) = (Prelude.^)  instance Multiplicative Int where   (*) = (Prelude.*)   one = 1-  (^) = (Prelude.^)+  (^+) = (Prelude.^)  instance Multiplicative Double where   (*) = (Prelude.*)   one = 1-  (^) = (Prelude.^)+  (^+) = (Prelude.^)  instance Multiplicative Float where   (*) = (Prelude.*)   one = 1-  (^) = (Prelude.^)+  (^+) = (Prelude.^)  + type SemiRing a = (Multiplicative a, AbelianAdditive a) type PreRing a = (SemiRing a, Group a) @@ -300,11 +413,19 @@   (/) :: a -> a -> a   x / y           =  x * recip y +  (^) :: a -> Integer -> a+  b ^ n | n < 0 = recip b ^+ negate n+        | True  = b ^+ n+ instance Division Double where   (/) = (Prelude./)+  recip = Prelude.recip+  (^) = (Prelude.^^)  instance Division Float where   (/) = (Prelude./)+  recip = Prelude.recip+  (^) = (Prelude.^^)  class (Ring a, Division a) => Field a where   fromRational :: Rational -> a@@ -317,7 +438,6 @@ instance Field Float where   fromRational = Prelude.fromRational -type VectorSpace scalar a = (Field scalar, Module scalar a)  class Ring a => EuclideanDomain a where     {-# MINIMAL (stdUnit | normalize) , (divMod | (div , mod)) #-}@@ -370,19 +490,7 @@     rem       =  Prelude.rem     toInteger = Prelude.toInteger -{--Note: the following is not quite what we intuitively want, because -class Field a => AlgebraicallyClosed  a where-  sqrt :: a -> (a,a)--AlgebraicallyClosed numbers have two square roots.---}--data Ratio a = !a :% !a  deriving (Eq)-type MyRational = Ratio Integer- gcd             :: (Integral a) => a -> a -> a {-# NOINLINE [1] gcd #-} gcd x y         =  gcd' (stdAssociate x) (stdAssociate y)@@ -391,50 +499,12 @@    gcd' a 0  =  a    gcd' a b  =  gcd' b (a `rem` b) -{---- | 'reduce' is a subsidiary function used only in this module.--- It normalises a ratio by dividing both numerator and denominator by--- their greatest common divisor.-reduce :: (Eq a, Integral a) => a -> a -> Ratio a-{-# SPECIALISE reduce :: Integer -> Integer -> MyRational #-}-reduce _ 0              =  error "reduce: division by zero"-reduce x y              =  (x `quot` d) :% (y `quot` d)-                           where d = gcd x y+{- -} -(%) :: Integral a => a -> a -> Ratio a-x % y                   =  reduce (x * stdUnit y) (stdAssociate y)  -instance Integral a => AbelianAdditive (Ratio a) where--instance Integral a => Additive (Ratio a) where-    (x:%y) + (x':%y')   =  reduce (x*y' + x'*y) (y*y')-    zero = 0-    times n (x :% y) = reduce (times n x) y--instance Integral a => Multiplicative (Ratio a) where-    (x:%y) * (x':%y')   =  reduce (x * x') (y * y')-    one = 1 :% 1--instance Integral a => Group (Ratio a) where-    (x:%y) - (x':%y')   =  reduce (x*y' - x'*y) (y*y')-    negate (x:%y)       =  (-x) :% y--instance Integral a => EuclideanDomain (Ratio a) where-    stdAssociate (x:%y)          =  stdAssociate x :% y-    stdUnit (x:%_)       =  stdUnit x :% 1--instance Integral a => Ring (Ratio a) where-    fromInteger x       =  fromInteger x :% 1--instance Integral a => Division (Ratio a) where-  recip (x:%y) = y:%x--instance Integral a => Field (Ratio a) where----}-+--------------------------+-- Ratio instances instance Prelude.Integral a => Additive (Data.Ratio.Ratio a) where   zero = Prelude.fromInteger 0   (+) = (Prelude.+)@@ -448,31 +518,94 @@ instance Prelude.Integral a => Multiplicative (Data.Ratio.Ratio a) where   one = Prelude.fromInteger 1   (*) = (Prelude.*)+  (^+) = (Prelude.^)  instance Prelude.Integral a => Division (Data.Ratio.Ratio a) where   recip = Prelude.recip   (/) = (Prelude./)-+  (^) = (Prelude.^^) instance Prelude.Integral a => Module (Data.Ratio.Ratio a) (Data.Ratio.Ratio a) where   (*^) = (*)- instance Prelude.Integral a => Ring (Data.Ratio.Ratio a) where   fromInteger = Prelude.fromInteger- instance Prelude.Integral a => Field (Data.Ratio.Ratio a) where   fromRational = Prelude.fromRational ++----------------------+-- Complex instances+instance Module Rational Double where+    r *^ d = fromRational r * d+instance Additive a => Additive (Complex a) where+    (x:+y) + (x':+y')   =  (x+x') :+ (y+y')+    zero = zero :+ zero+instance Ring a => Multiplicative (Complex a) where+    (x:+y) * (x':+y')   =  (x*x'-y*y') :+ (x*y'+y*x')+    one = one :+ zero+instance Group a => Group  (Complex a) where+    (x:+y) - (x':+y')   =  (x-x') :+ (y-y')+    negate (x:+y)       =  negate x :+ negate y+instance AbelianAdditive a => AbelianAdditive (Complex a)+instance Ring a => Module (Complex a) (Complex a) where+  (*^) = (*)+instance Ring a => Module a (Complex a) where+  s *^ (x :+ y) =  (s *^ x :+ s *^ y)+instance Ring a => Ring (Complex a) where+    fromInteger n  =  fromInteger n :+ zero++instance  Field a => Division (Complex a)  where+    {-# SPECIALISE instance Division (Complex Double) #-}+    (x:+y) / (x':+y')   =  (x*x'+y*y') / d :+ (y*x'-x*y') / d+      where d   = x'*x' + y'*y'++instance Field a => Field (Complex a) where+    fromRational a =  fromRational a :+ zero++{-data Expr a where+  Embed :: a -> Expr a+  Add :: Expr a -> Expr a -> Expr a+  Mul :: Expr a -> Expr a -> Expr a+  Zero :: Expr a+  One :: Expr a+  deriving (Prelude.Show)+++instance Additive (Expr a) where+  zero = Zero+  Zero + x = x+  x + Zero = x+  x + y = Add x y++instance Multiplicative (Expr a) where+  one = One+  One * x = x+  x * One = x+  x * y = Mul x y+-}++-- Syntax+ ifThenElse :: Bool -> t -> t -> t ifThenElse True a _ = a ifThenElse False _ a = a  -data InitialAdditive = InitialAdditive :+ InitialAdditive | Zero-  deriving (Prelude.Show) -instance Additive InitialAdditive where-  zero = Zero-  (+) = (:+)+-- >>> times 5 (Embed "x")+-- Add (Add (Embed "x") (Add (Embed "x") (Embed "x"))) (Add (Embed "x") (Embed "x")) -instance Module Rational Double where-  r *^ d = fromRational r * d++-- >>> (Embed "x")+-- Zero+++{-+Note: the following is not quite what we intuitively want, because++class Field a => AlgebraicallyClosed  a where+  sqrt :: a -> (a,a)++AlgebraicallyClosed numbers have two square roots.++-}+
Algebra/Linear.hs view
@@ -21,16 +21,36 @@ {-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE RebindableSyntax #-}  module Algebra.Linear where -import Algebra.Classes-import Prelude (cos,sin,Floating(..),Functor(..),Show(..),Eq(..),Int,fst,flip,($),Ord)+import Algebra.Classes hiding ((*<))+import Prelude (cos,sin,Floating(..),Functor(..),Show(..),Eq(..),Int,fst,($),Ord,Double) import Control.Applicative-import Data.Foldable+import Data.Foldable hiding (sum,product) import Data.Traversable import Control.Monad.State import Algebra.Category++infixr 7 *<++type VectorSpace scalar a = (Field scalar, Module scalar a, Group a)+-- Because of the existence of bases, vector spaces can always be made representable (Traversable, Applicative) functors.+-- So we'd be better off using the following definition:++-- | Representation of vector as traversable functor+type VectorR v = (Applicative v,Traversable v)+-- ... but this is missing the link with *^ for module.  We should be+-- able to add forall s. PreRing s => Module s (v s), but GHC does not+-- like it. (In fact, QuantifiedConstraints is very buggy in ghc 8.6)++class VectorR v => InnerProdSpace v where+  inner :: Field s => v s -> v s -> s++--------------------------------------------------------------+-- Construction of finite vectors+ data VZero a = VZero deriving (Functor,Foldable,Traversable,Show,Eq,Ord) instance Applicative VZero where   pure _ = VZero@@ -53,7 +73,10 @@ pattern V3' :: forall a. a -> a -> a -> V3' a pattern V3' x y z = VNext (V2' x y) z --- | Make a Euclidean vector out of a traversable functor+--------------------------------------------+-- Euclidean spaces with a (inner product)++-- | Make a Euclidean vector out of a traversable functor. (The p) newtype Euclid f a = Euclid {fromEuclid :: f a} deriving (Functor,Foldable,Traversable,Show,Eq,Ord,Applicative)  type V3 = Euclid V3'@@ -78,49 +101,38 @@ pureMat :: (Applicative v, Applicative w) => s -> Mat s v w pureMat x = Mat (pure (pure x)) -(>*<) :: (Applicative v, Applicative w) =>-               Mat (a -> s) v w -> Mat a v w -> Mat s v w-Mat f >*< Mat x = Mat (((<*>) <$> f) <*> x)--(>$<) :: (Applicative v, Applicative w) =>-               (a -> s) -> Mat a v w -> Mat s v w-f >$< x = pureMat f >*< x- instance (Applicative f,Applicative g,Additive a) => Additive (Mat a f g) where   zero = pureMat zero-  x + y =  (+) >$< x >*< y+  x + y = matFlat ((+) <$> flatMat x <*> flatMat y) instance (Applicative f,Applicative g,AbelianAdditive a) => AbelianAdditive (Mat a f g) where instance (Applicative f,Applicative g,Group a) => Group (Mat a f g) where-  negate x = negate >$< x-  x - y = (-) >$< x >*< y+  negate x = matFlat (negate <$> flatMat x)+  x - y = matFlat ((-) <$> flatMat x <*> flatMat y)  instance (Applicative f, Applicative g,Module s a) => Module s (Mat a f g) where   s *^ Mat t = Mat (((s*^) <$>) <$> t) -class VectorSpace (Scalar v) v => InnerProdSpace v where-  type Scalar v-  dotProd :: v -> v -> Scalar v +-- | Hadamard product (⊙) :: Applicative v => Multiplicative s => v s -> v s -> v s x ⊙ y = (*) <$> x <*> y -instance (Ring a, Field a, Applicative f, Foldable f) => InnerProdSpace (Euclid f a) where-  type Scalar (Euclid f a) = a-  dotProd x y = add (x ⊙ y)+instance (VectorR f) => InnerProdSpace (Euclid f) where+  inner x y = sum (x ⊙ y) -- fixme -(·) :: InnerProdSpace v => v -> v -> Scalar v-(·) = dotProd+(·) :: Field s => InnerProdSpace v => v s -> v s -> s+(·) = inner -sqNorm :: InnerProdSpace v => v -> Scalar v-sqNorm x = dotProd x x+sqNorm :: Field s => InnerProdSpace v => v s -> s+sqNorm x = inner x x -norm :: InnerProdSpace v => Floating (Scalar v) => v  -> Scalar v+norm :: Field s => InnerProdSpace v => Floating s => v s  -> s norm = sqrt . sqNorm -normalize :: Floating (Scalar v) => InnerProdSpace v => v -> v+normalize :: (VectorSpace s (v s)) => Floating s => InnerProdSpace v => v s -> v s normalize v = recip (norm v) *^ v --- | Cross product https://en.wikipedia.org/wiki/Cross_product+-- | Cross product in 3 dimensions https://en.wikipedia.org/wiki/Cross_product (×) :: Ring a => V3 a -> V3 a -> V3 a (V3 a1 a2 a3) × (V3 b1 b2 b3) = V3 (a2*b3 - a3*b2)  (negate (a1*b3 - a3*b1)) (a1*b2 - a2*b1) @@ -129,52 +141,77 @@   where increment = do x <- get; put (x+1); return x  type SqMat v s = Mat s v v-newtype Mat s w v = Mat {fromMat :: v (w s)} deriving Show +-- | Matrix type. (w s) is a column. (v s) is a row.+newtype Mat s w v = Mat {fromMat :: w (v s)} deriving Show++-- | View of the matrix as a composition of functors.+newtype Flat w v s = Flat {fromFlat :: w (v s)} deriving (Show,Functor,Foldable)+flatMat :: Mat s w v -> Flat w v s+flatMat (Mat x) = (Flat x)+matFlat :: Flat w v s -> Mat s w v+matFlat (Flat x) = (Mat x)++instance (Applicative w, Applicative v) => Applicative (Flat w v) where+  pure x = Flat (pure (pure x))+  Flat f <*> Flat a = Flat (((<*>) <$> f) <*> a)++ instance Ring s => Category (Mat s) where-  type Con v = (Applicative v, Traversable v)+  type Con v = VectorR v   (.) = matMul   id = identity -type Mat3x3 s = SqMat V3' s-type Mat2x2 s = SqMat V2' s+type Mat3x3 s = SqMat V3 s+type Mat2x2 s = SqMat V2 s -pattern Mat2x2 :: forall s. s -> s -> s -> s -> Mat s V2' V2'-pattern Mat2x2 a b c d = Mat (V2' (V2' a b) (V2' c d))+pattern Mat2x2 :: forall s. s -> s -> s -> s -> Mat s V2 V2+pattern Mat2x2 a b c d = Mat (V2 (V2 a c)+                                 (V2 b d)) -pattern Mat3x3 :: forall s. s -> s -> s -> s -> s -> s -> s -> s -> s -> Mat s V3' V3'-pattern Mat3x3 a b c d e f g h i = Mat (V3' (V3' a b c) (V3' d e f) (V3' g h i))+pattern Mat3x3 :: forall s. s -> s -> s -> s -> s -> s -> s -> s -> s -> Mat s V3 V3+pattern Mat3x3 a b c d e f g h i = Mat (V3 (V3 a d g)+                                           (V3 b e h)+                                           (V3 c f i)) -matVecMul :: (Foldable f1, Ring b, Applicative f1, Functor f2) => Mat b f1 f2 -> Euclid f1 b -> Euclid f2 b-matVecMul (Mat m) v = Euclid (euclideanDotProd v <$> (Euclid <$> m))-   where euclideanDotProd x y = add (Euclid x ⊙ Euclid y)+-- | Vector scaling. If Module a (f a), then (*^) must be the same as (*<).+(*<) :: (Functor f, Multiplicative b) => b -> f b -> f b+s *< v = (s*) <$> v -rotation2d :: Floating a => a -> Mat2x2 a-rotation2d θ = Mat $ V2' (V2' (cos θ) (-sin θ))-                         (V2' (sin θ)  (cos θ)) +(<+>) :: (Applicative f, Additive b) => f b -> f b -> f b+u <+> v = (+) <$> u <*> v+++matVecMul :: forall s v w. (Ring s, Foldable v,Applicative v,Applicative w) => Mat s v w -> v s -> w s+matVecMul (Mat m) x = foldr (<+>) (pure zero) ((*<) <$> x <*> m) -- If GHC gets fixed: use VectorR constraint instead of Applicative, and add instead of foldr.++rotation2d :: (Group a,Floating a) => a -> Mat2x2 a+rotation2d θ = transpose $ Mat $ V2 (V2 (cos θ) (-sin θ))+                                    (V2 (sin θ)  (cos θ))+ -- >>> rotation2d (pi/2) -- Mat {fromMat = V2' (V2' 6.123233995736766e-17 (-1.0)) (V2' 1.0 6.123233995736766e-17)}  crossProductMatrix :: Group a => V3 a -> Mat3x3 a-crossProductMatrix (V3 a1 a2 a3) = Mat (V3'  (V3' zero (negate a3) a2)-                                             (V3' a3 zero (negate a1))-                                             (V3' (negate a2) a1 zero))+crossProductMatrix (V3 a1 a2 a3) = Mat3x3 zero  (-a3) a2+                                          a3    zero  (-a1)+                                          (-a2) a1    zero  -- | Tensor product (⊗) :: (Applicative v, Applicative w, Multiplicative s)-    => Euclid w s -> Euclid v s -> Mat s w v-Euclid v1 ⊗ Euclid v2 = flip (tensorWith (*)) v1 v2+    => w s -> v s -> Mat s w v+v1 ⊗ v2 = tensorWith (*) v2 v1  tensorWith :: (Applicative v, Applicative w)            => (s -> t -> u) -> w s -> v t -> Mat u v w-tensorWith f v1 v2 = flip f >$< Mat (pure v2) >*< Mat (pure <$> v1)+tensorWith f v1 v2 = matFlat (f <$> Flat (pure v1) <*> Flat (pure <$> v2))  identity :: Traversable v => Ring s => Applicative v => SqMat v s identity = tensorWith (\x y -> if x == y then one else zero) index index -diagonal :: Traversable v => Ring s => Applicative v => Euclid v s -> SqMat v s-diagonal (Euclid v) = tensorWith (\x (y,a) -> if x == y then a else zero) index ((,) <$> index <*> v)+diagonal :: Traversable v => Ring s => Applicative v => v s -> SqMat v s+diagonal v = tensorWith (\x (y,a) -> if x == y then a else zero) index ((,) <$> index <*> v)  -- | 3d rotation around given axis rotation3d :: Ring a => Floating a => a -> V3 a -> Mat3x3 a@@ -182,27 +219,30 @@                  sin θ *^ crossProductMatrix u +                  (1 - cos θ) *^ (u ⊗ u) +-- | 3d rotation mapping the direction of 'from' to that of 'to' rotationFromTo :: (Floating a, Module a a,Field a)                => V3 a -> V3 a -> Mat3x3 a rotationFromTo from to = c *^ identity + s *^ crossProductMatrix v + (1-c) *^ (v ⊗ v)   where y = to         x = from-        v = x × y-        c = dotProd x y-        s = norm v+        v = x × y -- axis of rotation+        c = inner x y -- cos of angle+        s = norm v -- sin of angle -transpose :: Applicative f => Traversable g => Mat a f g -> Mat a g f-transpose = Mat . sequenceA . fromMat+-- >>> let u = (V3 (1::Double) 0 0); v = (V3 0 1 1); in (rotationFromTo u v) `matVecMul` u+-- Euclid {fromEuclid = VNext (VNext (VNext VZero 0.0) 1.4142135623730951) 1.4142135623730951} -matMul' :: (Traversable u, Ring s, Applicative w, Applicative v, Applicative u) => Mat s v u -> Mat s u w -> Mat s v w-matMul' (transpose -> Mat y) (Mat x)  = tensorWith (\a b -> add (a ⊙ b)) x y+transpose :: Applicative g => Traversable f => Mat a f g -> Mat a g f+transpose = Mat . sequenceA . fromMat  matMul :: (Traversable u, Ring s, Applicative w, Applicative v, Applicative u) => Mat s u w -> Mat s v u -> Mat s v w-matMul = flip matMul'+matMul a (Mat b) = Mat (matVecMul a <$> b)  --- >>> let t1 = rotation2d (1::Double) in matMul t1 (transpose t1)--- Mat {fromMat = V2' (V2' 1.0 0.0) (V2' 0.0 1.0)}+-- >>> let t1 = rotation2d (1::Double) in matMul (transpose t1) t1+-- Mat {fromMat = VNext (VNext VZero (VNext (VNext VZero 1.0) 0.0)) (VNext (VNext VZero 0.0) 1.0)}++  -- The group of Orthogonal matrices, using "Multiplicative" for respecting conventions a bit better newtype OrthoMat v s = OrthoMat (SqMat v s)
gasp.cabal view
@@ -1,5 +1,5 @@ name:           gasp-version:        1.2.0.0+version:        1.3.0.0 category:       Algebra synopsis:       A framework of algebraic classes description:@@ -22,6 +22,7 @@   build-depends: containers   build-depends: binary   build-depends: mtl+  build-depends: QuickCheck    exposed-modules:        Algebra.Classes