{-# LANGUAGE CPP #-} {-# LANGUAGE Safe #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DefaultSignatures #-} {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE RebindableSyntax #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE RankNTypes #-} module Data.Semimodule.Finite ( -- * Vector types V1(..) , unV1 , V2(..) , V3(..) , cross , triple , V4(..) -- * Matrix types , type M11 , type M12 , type M13 , type M14 , type M21 , type M31 , type M41 , type M22 , type M23 , type M24 , type M32 , type M33 , type M34 , type M42 , type M43 , type M44 , m11 , m12 , m13 , m14 , m21 , m31 , m41 , m22 , m23 , m24 , m32 , m33 , m34 , m42 , m43 , m44 -- * Matrix determinants & inverses , inv1 , inv2 , bdet2 , det2 , bdet3 , det3 , inv3 , bdet4 , det4 , inv4 ) where import safe Control.Applicative import safe Data.Bool import safe Data.Distributive import safe Data.Functor.Classes import safe Data.Functor.Compose import safe Data.Functor.Rep hiding (Co) import safe Data.Semifield import safe Data.Semigroup.Foldable as Foldable1 import safe Data.Semimodule import safe Data.Semimodule.Basis import safe Data.Semimodule.Combinator import safe Data.Semiring import safe Prelude hiding (Num(..), Fractional(..), negate, sum, product) import safe Prelude (fromInteger) ------------------------------------------------------------------------------- -- Vectors ------------------------------------------------------------------------------- unV1 :: V1 a -> a unV1 (V1 a) = a newtype V1 a = V1 a deriving (Eq,Ord,Show) data V2 a = V2 !a !a deriving (Eq,Ord,Show) data V3 a = V3 !a !a !a deriving (Eq,Ord,Show) data V4 a = V4 !a !a !a !a deriving (Eq,Ord,Show) -- | Cross product. -- -- @ -- a `'cross'` a = 'zero' -- a `'cross'` b = 'negate' ( b `'cross'` a ) , -- a `'cross'` ( b '+' c ) = ( a `'cross'` b ) '+' ( a `'cross'` c ) , -- ( r a ) `'cross'` b = a `'cross'` ( r b ) = r ( a `'cross'` b ) . -- a `'cross'` ( b `'cross'` c ) '+' b `'cross'` ( c `'cross'` a ) '+' c `'cross'` ( a `'cross'` b ) = 'zero' . -- @ -- -- See < https://en.wikipedia.org/wiki/Jacobi_identity Jacobi identity >. -- cross :: Ring a => V3 a -> V3 a -> V3 a cross (V3 a b c) (V3 d e f) = V3 (b*f-c*e) (c*d-a*f) (a*e-b*d) {-# INLINABLE cross #-} -- | Scalar triple product. -- -- @ -- 'triple' x y z = 'triple' z x y = 'triple' y z x -- 'triple' x y z = 'negate' '$' 'triple' x z y = 'negate' '$' 'triple' y x z -- 'triple' x x y = 'triple' x y y = 'triple' x y x = 'zero' -- ('triple' x y z) '*.' x = (x `'cross'` y) `'cross'` (x `'cross'` z) -- @ -- -- >>> triple (V3 0 0 1) (V3 1 0 0) (V3 0 1 0) :: Double -- 1.0 -- triple :: Ring a => V3 a -> V3 a -> V3 a -> a triple x y z = inner x (cross y z) {-# INLINE triple #-} ------------------------------------------------------------------------------- -- Matrices ------------------------------------------------------------------------------- -- All matrices use row-major representation. -- | A 1x1 matrix. type M11 = Compose V1 V1 -- | A 1x2 matrix. type M12 = Compose V1 V2 -- | A 1x3 matrix. type M13 = Compose V1 V3 -- | A 1x4 matrix. type M14 = Compose V1 V4 -- | A 2x1 matrix. type M21 = Compose V2 V1 -- | A 3x1 matrix. type M31 = Compose V3 V1 -- | A 4x1 matrix. type M41 = Compose V4 V1 -- | A 2x2 matrix. type M22 = Compose V2 V2 -- | A 2x3 matrix. type M23 = Compose V2 V3 -- | A 2x4 matrix. type M24 = Compose V2 V4 -- | A 3x2 matrix. type M32 = Compose V3 V2 -- | A 3x3 matrix. type M33 = Compose V3 V3 -- | A 3x4 matrix. type M34 = Compose V3 V4 -- | A 4x2 matrix. type M42 = Compose V4 V2 -- | A 4x3 matrix. type M43 = Compose V4 V3 -- | A 4x4 matrix. type M44 = Compose V4 V4 ------------------------------------------------------------------------------- -- Matrix constructors ------------------------------------------------------------------------------- -- | Construct a 1x1 matrix. -- -- >>> m11 1 :: M11 Int -- Compose (V1 (V1 1)) -- m11 :: a -> M11 a m11 a = Compose $ V1 (V1 a) {-# INLINE m11 #-} -- | Construct a 1x2 matrix. -- -- >>> m12 1 2 :: M12 Int -- Compose (V1 (V2 1 2)) -- m12 :: a -> a -> M12 a m12 a b = Compose $ V1 (V2 a b) {-# INLINE m12 #-} -- | Construct a 1x3 matrix. -- -- >>> m13 1 2 3 :: M13 Int -- Compose (V1 (V3 1 2 3)) -- m13 :: a -> a -> a -> M13 a m13 a b c = Compose $ V1 (V3 a b c) {-# INLINE m13 #-} -- | Construct a 1x4 matrix. -- -- >>> m14 1 2 3 4 :: M14 Int -- Compose (V1 (V4 1 2 3 4)) -- m14 :: a -> a -> a -> a -> M14 a m14 a b c d = Compose $ V1 (V4 a b c d) {-# INLINE m14 #-} -- | Construct a 2x1 matrix. -- -- >>> m21 1 2 :: M21 Int -- Compose (V2 (V1 1) (V1 2)) -- m21 :: a -> a -> M21 a m21 a b = Compose $ V2 (V1 a) (V1 b) {-# INLINE m21 #-} -- | Construct a 3x1 matrix. -- -- >>> m31 1 2 3 :: M31 Int -- Compose (V3 (V1 1) (V1 2) (V1 3)) -- m31 :: a -> a -> a -> M31 a m31 a b c = Compose $ V3 (V1 a) (V1 b) (V1 c) {-# INLINE m31 #-} -- | Construct a 4x1 matrix. -- -- >>> m41 1 2 3 4 :: M41 Int -- Compose (V4 (V1 1) (V1 2) (V1 3) (V1 4)) -- m41 :: a -> a -> a -> a -> M41 a m41 a b c d = Compose $ V4 (V1 a) (V1 b) (V1 c) (V1 d) {-# INLINE m41 #-} -- | Construct a 2x2 matrix. -- -- Arguments are in row-major order. -- -- >>> m22 1 2 3 4 :: M22 Int -- Compose (V2 (V2 1 2) (V2 3 4)) -- m22 :: a -> a -> a -> a -> M22 a m22 a b c d = Compose $ V2 (V2 a b) (V2 c d) {-# INLINE m22 #-} -- | Construct a 2x3 matrix. -- -- Arguments are in row-major order. -- m23 :: a -> a -> a -> a -> a -> a -> M23 a m23 a b c d e f = Compose $ V2 (V3 a b c) (V3 d e f) {-# INLINE m23 #-} -- | Construct a 2x4 matrix. -- -- Arguments are in row-major order. -- m24 :: a -> a -> a -> a -> a -> a -> a -> a -> M24 a m24 a b c d e f g h = Compose $ V2 (V4 a b c d) (V4 e f g h) {-# INLINE m24 #-} -- | Construct a 3x2 matrix. -- -- Arguments are in row-major order. -- m32 :: a -> a -> a -> a -> a -> a -> M32 a m32 a b c d e f = Compose $ V3 (V2 a b) (V2 c d) (V2 e f) {-# INLINE m32 #-} -- | Construct a 3x3 matrix. -- -- Arguments are in row-major order. -- m33 :: a -> a -> a -> a -> a -> a -> a -> a -> a -> M33 a m33 a b c d e f g h i = Compose $ V3 (V3 a b c) (V3 d e f) (V3 g h i) {-# INLINE m33 #-} -- | Construct a 3x4 matrix. -- -- Arguments are in row-major order. -- m34 :: a -> a -> a -> a -> a -> a -> a -> a -> a -> a -> a -> a -> M34 a m34 a b c d e f g h i j k l = Compose $ V3 (V4 a b c d) (V4 e f g h) (V4 i j k l) {-# INLINE m34 #-} -- | Construct a 4x2 matrix. -- -- Arguments are in row-major order. -- m42 :: a -> a -> a -> a -> a -> a -> a -> a -> M42 a m42 a b c d e f g h = Compose $ V4 (V2 a b) (V2 c d) (V2 e f) (V2 g h) {-# INLINE m42 #-} -- | Construct a 4x3 matrix. -- -- Arguments are in row-major order. -- m43 :: a -> a -> a -> a -> a -> a -> a -> a -> a -> a -> a -> a -> M43 a m43 a b c d e f g h i j k l = Compose $ V4 (V3 a b c) (V3 d e f) (V3 g h i) (V3 j k l) {-# INLINE m43 #-} -- | Construct a 4x4 matrix. -- -- Arguments are in row-major order. -- m44 :: a -> a -> a -> a -> a -> a -> a -> a -> a -> a -> a -> a -> a -> a -> a -> a -> M44 a m44 a b c d e f g h i j k l m n o p = Compose $ V4 (V4 a b c d) (V4 e f g h) (V4 i j k l) (V4 m n o p) {-# INLINE m44 #-} ------------------------------------------------------------------------------- -- Matrix determinants and inverses ------------------------------------------------------------------------------- -- | 1x1 matrix inverse over a field. -- -- >>> inv1 $ m11 4.0 :: M11 Double -- Compose (V1 (V1 0.25)) -- inv1 :: Field a => M11 a -> M11 a inv1 = transpose . fmap recip -- | 2x2 matrix bdeterminant over a commutative semiring. -- -- >>> bdet2 $ m22 1 2 3 4 -- (4,6) -- bdet2 :: Semiring a => Basis2 E2 E2 f g => (f**g) a -> (a, a) bdet2 m = (elt2 E21 E21 m * elt2 E22 E22 m, elt2 E21 E22 m * elt2 E22 E21 m) {-# INLINE bdet2 #-} -- | 2x2 matrix determinant over a commutative ring. -- -- @ -- 'det2' = 'uncurry' ('-') . 'bdet2' -- @ -- -- >>> det2 $ m22 1 2 3 4 :: Double -- -2.0 -- det2 :: Ring a => Basis2 E2 E2 f g => (f**g) a -> a det2 = uncurry (-) . bdet2 {-# INLINE det2 #-} -- | 2x2 matrix inverse over a field. -- -- >>> inv2 $ m22 1 2 3 4 :: M22 Double -- Compose (V2 (V2 (-2.0) 1.0) (V2 1.5 (-0.5))) -- inv2 :: Field a => M22 a -> M22 a inv2 m = lscaleDef (recip $ det2 m) $ m22 d (-b) (-c) a where a = elt2 E21 E21 m b = elt2 E21 E22 m c = elt2 E22 E21 m d = elt2 E22 E22 m {-# INLINE inv2 #-} -- | 3x3 matrix bdeterminant over a commutative semiring. -- -- >>> bdet3 (V3 (V3 1 2 3) (V3 4 5 6) (V3 7 8 9)) -- (225, 225) -- bdet3 :: Semiring a => Basis2 E3 E3 f g => (f**g) a -> (a, a) bdet3 m = (evens, odds) where evens = a*e*i + g*b*f + d*h*c odds = a*h*f + d*b*i + g*e*c a = elt2 E31 E31 m b = elt2 E31 E32 m c = elt2 E31 E33 m d = elt2 E32 E31 m e = elt2 E32 E32 m f = elt2 E32 E33 m g = elt2 E33 E31 m h = elt2 E33 E32 m i = elt2 E33 E33 m {-# INLINE bdet3 #-} -- | 3x3 double-precision matrix determinant. -- -- @ -- 'det3' = 'uncurry' ('-') . 'bdet3' -- @ -- -- Implementation uses a cofactor expansion to avoid loss of precision. -- -- >>> det3 $ m33 1 2 3 4 5 6 7 8 9 -- 0 -- det3 :: Ring a => Basis2 E3 E3 f g => (f**g) a -> a det3 m = a * (e*i-f*h) - d * (b*i-c*h) + g * (b*f-c*e) where a = elt2 E31 E31 m b = elt2 E31 E32 m c = elt2 E31 E33 m d = elt2 E32 E31 m e = elt2 E32 E32 m f = elt2 E32 E33 m g = elt2 E33 E31 m h = elt2 E33 E32 m i = elt2 E33 E33 m {-# INLINE det3 #-} -- | 3x3 matrix inverse. -- -- >>> inv3 $ m33 1 2 4 4 2 2 1 1 1 :: M33 Double -- Compose (V3 (V3 0.0 0.5 (-1.0)) (V3 (-0.5) (-0.75) 3.5) (V3 0.5 0.25 (-1.5))) -- inv3 :: Field a => M33 a -> M33 a inv3 m = lscaleDef (recip $ det3 m) $ m33 a' b' c' d' e' f' g' h' i' where a = elt2 E31 E31 m b = elt2 E31 E32 m c = elt2 E31 E33 m d = elt2 E32 E31 m e = elt2 E32 E32 m f = elt2 E32 E33 m g = elt2 E33 E31 m h = elt2 E33 E32 m i = elt2 E33 E33 m a' = cofactor (e,f,h,i) b' = cofactor (c,b,i,h) c' = cofactor (b,c,e,f) d' = cofactor (f,d,i,g) e' = cofactor (a,c,g,i) f' = cofactor (c,a,f,d) g' = cofactor (d,e,g,h) h' = cofactor (b,a,h,g) i' = cofactor (a,b,d,e) cofactor (q,r,s,t) = det2 (m22 q r s t) {-# INLINE inv3 #-} -- | 4x4 matrix bdeterminant over a commutative semiring. -- -- >>> bdet4 $ m44 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 -- (27728,27728) -- bdet4 :: Semiring a => Basis2 E4 E4 f g => (f**g) a -> (a, a) bdet4 x = (evens, odds) where evens = a * (f*k*p + g*l*n + h*j*o) + b * (g*i*p + e*l*o + h*k*m) + c * (e*j*p + f*l*m + h*i*n) + d * (f*i*o + e*k*n + g*j*m) odds = a * (g*j*p + f*l*o + h*k*n) + b * (e*k*p + g*l*m + h*i*o) + c * (f*i*p + e*l*n + h*j*m) + d * (e*j*o + f*k*m + g*i*n) a = elt2 E41 E41 x b = elt2 E41 E42 x c = elt2 E41 E43 x d = elt2 E41 E44 x e = elt2 E42 E41 x f = elt2 E42 E42 x g = elt2 E42 E43 x h = elt2 E42 E44 x i = elt2 E43 E41 x j = elt2 E43 E42 x k = elt2 E43 E43 x l = elt2 E43 E44 x m = elt2 E44 E41 x n = elt2 E44 E42 x o = elt2 E44 E43 x p = elt2 E44 E44 x {-# INLINE bdet4 #-} -- | 4x4 matrix determinant over a commutative ring. -- -- @ -- 'det4' = 'uncurry' ('-') . 'bdet4' -- @ -- -- This implementation uses a cofactor expansion to avoid loss of precision. -- -- >>> det4 $ m44 1 0 3 2 2 0 2 1 0 0 0 1 0 3 4 0 :: Rational -- (-12) % 1 -- det4 :: Ring a => Basis2 E4 E4 f g => (f**g) a -> a det4 x = s0 * c5 - s1 * c4 + s2 * c3 + s3 * c2 - s4 * c1 + s5 * c0 where s0 = i00 * e11 - e10 * i01 s1 = i00 * e12 - e10 * i02 s2 = i00 * e13 - e10 * i03 s3 = i01 * e12 - e11 * i02 s4 = i01 * e13 - e11 * i03 s5 = i02 * e13 - e12 * i03 c5 = e22 * e33 - e32 * e23 c4 = e21 * e33 - e31 * e23 c3 = e21 * e32 - e31 * e22 c2 = e20 * e33 - e30 * e23 c1 = e20 * e32 - e30 * e22 c0 = e20 * e31 - e30 * e21 i00 = elt2 E41 E41 x i01 = elt2 E41 E42 x i02 = elt2 E41 E43 x i03 = elt2 E41 E44 x e10 = elt2 E42 E41 x e11 = elt2 E42 E42 x e12 = elt2 E42 E43 x e13 = elt2 E42 E44 x e20 = elt2 E43 E41 x e21 = elt2 E43 E42 x e22 = elt2 E43 E43 x e23 = elt2 E43 E44 x e30 = elt2 E44 E41 x e31 = elt2 E44 E42 x e32 = elt2 E44 E43 x e33 = elt2 E44 E44 x {-# INLINE det4 #-} -- | 4x4 matrix inverse. -- -- >>> row E41 . inv4 $ m44 1 0 3 2 2 0 2 1 0 0 0 1 0 3 4 0 :: V4 Rational -- V4 (6 % (-12)) ((-9) % (-12)) ((-3) % (-12)) (0 % (-12)) -- inv4 :: Field a => M44 a -> M44 a inv4 x = lscaleDef (recip det) $ x' where i00 = elt2 E41 E41 x i01 = elt2 E41 E42 x i02 = elt2 E41 E43 x i03 = elt2 E41 E44 x e10 = elt2 E42 E41 x e11 = elt2 E42 E42 x e12 = elt2 E42 E43 x e13 = elt2 E42 E44 x e20 = elt2 E43 E41 x e21 = elt2 E43 E42 x e22 = elt2 E43 E43 x e23 = elt2 E43 E44 x e30 = elt2 E44 E41 x e31 = elt2 E44 E42 x e32 = elt2 E44 E43 x e33 = elt2 E44 E44 x s0 = i00 * e11 - e10 * i01 s1 = i00 * e12 - e10 * i02 s2 = i00 * e13 - e10 * i03 s3 = i01 * e12 - e11 * i02 s4 = i01 * e13 - e11 * i03 s5 = i02 * e13 - e12 * i03 c5 = e22 * e33 - e32 * e23 c4 = e21 * e33 - e31 * e23 c3 = e21 * e32 - e31 * e22 c2 = e20 * e33 - e30 * e23 c1 = e20 * e32 - e30 * e22 c0 = e20 * e31 - e30 * e21 det = s0 * c5 - s1 * c4 + s2 * c3 + s3 * c2 - s4 * c1 + s5 * c0 x' = m44 (e11 * c5 - e12 * c4 + e13 * c3) (-i01 * c5 + i02 * c4 - i03 * c3) (e31 * s5 - e32 * s4 + e33 * s3) (-e21 * s5 + e22 * s4 - e23 * s3) (-e10 * c5 + e12 * c2 - e13 * c1) (i00 * c5 - i02 * c2 + i03 * c1) (-e30 * s5 + e32 * s2 - e33 * s1) (e20 * s5 - e22 * s2 + e23 * s1) (e10 * c4 - e11 * c2 + e13 * c0) (-i00 * c4 + i01 * c2 - i03 * c0) (e30 * s4 - e31 * s2 + e33 * s0) (-e20 * s4 + e21 * s2 - e23 * s0) (-e10 * c3 + e11 * c1 - e12 * c0) (i00 * c3 - i01 * c1 + i02 * c0) (-e30 * s3 + e31 * s1 - e32 * s0) (e20 * s3 - e21 * s1 + e22 * s0) {-# INLINE inv4 #-} ------------------------------------------------------------------------------- -- V1 instances ------------------------------------------------------------------------------- instance Show1 V1 where liftShowsPrec f _ d (V1 a) = showParen (d >= 10) $ showString "V1 " . f d a {- instance Field a => Composition a V1 where conj = id norm f = unV1 $ liftA2 (*) f f -} instance Functor V1 where fmap f (V1 a) = V1 (f a) {-# INLINE fmap #-} a <$ _ = V1 a {-# INLINE (<$) #-} instance Applicative V1 where pure = pureRep liftA2 = liftR2 instance Foldable V1 where foldMap f (V1 a) = f a {-# INLINE foldMap #-} null _ = False length _ = one instance Foldable1 V1 where foldMap1 f (V1 a) = f a {-# INLINE foldMap1 #-} instance Distributive V1 where distribute f = V1 $ fmap (\(V1 x) -> x) f {-# INLINE distribute #-} instance Representable V1 where type Rep V1 = E1 tabulate f = V1 (f E11) {-# INLINE tabulate #-} index (V1 x) E11 = x {-# INLINE index #-} ------------------------------------------------------------------------------- -- V2 instances ------------------------------------------------------------------------------- instance Show1 V2 where liftShowsPrec f _ d (V2 a b) = showsBinaryWith f f "V2" d a b instance Functor V2 where fmap f (V2 a b) = V2 (f a) (f b) {-# INLINE fmap #-} a <$ _ = V2 a a {-# INLINE (<$) #-} instance Applicative V2 where pure = pureRep liftA2 = liftR2 instance Foldable V2 where foldMap f (V2 a b) = f a <> f b {-# INLINE foldMap #-} null _ = False length _ = two instance Foldable1 V2 where foldMap1 f (V2 a b) = f a <> f b {-# INLINE foldMap1 #-} instance Distributive V2 where distribute f = V2 (fmap (\(V2 x _) -> x) f) (fmap (\(V2 _ y) -> y) f) {-# INLINE distribute #-} instance Representable V2 where type Rep V2 = E2 tabulate f = V2 (f E21) (f E22) {-# INLINE tabulate #-} index (V2 x _) E21 = x index (V2 _ y) E22 = y {-# INLINE index #-} ------------------------------------------------------------------------------- -- V3 instances ------------------------------------------------------------------------------- -- TODO add Prd1 and push instance downstream instance Eq1 V3 where liftEq k (V3 a b c) (V3 d e f) = k a d && k b e && k c f instance Show1 V3 where liftShowsPrec f _ d (V3 a b c) = showParen (d > 10) $ showString "V3 " . f 11 a . showChar ' ' . f 11 b . showChar ' ' . f 11 c instance Functor V3 where fmap f (V3 a b c) = V3 (f a) (f b) (f c) {-# INLINE fmap #-} a <$ _ = V3 a a a {-# INLINE (<$) #-} instance Applicative V3 where pure = pureRep liftA2 = liftR2 instance Foldable V3 where foldMap f (V3 a b c) = f a <> f b <> f c {-# INLINE foldMap #-} null _ = False --length _ = 3 instance Foldable1 V3 where foldMap1 f (V3 a b c) = f a <> f b <> f c {-# INLINE foldMap1 #-} instance Distributive V3 where distribute f = V3 (fmap (\(V3 x _ _) -> x) f) (fmap (\(V3 _ y _) -> y) f) (fmap (\(V3 _ _ z) -> z) f) {-# INLINE distribute #-} instance Representable V3 where type Rep V3 = E3 tabulate f = V3 (f E31) (f E32) (f E33) {-# INLINE tabulate #-} index (V3 x _ _) E31 = x index (V3 _ y _) E32 = y index (V3 _ _ z) E33 = z {-# INLINE index #-} ------------------------------------------------------------------------------- -- V4 instances ------------------------------------------------------------------------------- instance Show1 V4 where liftShowsPrec f _ z (V4 a b c d) = showParen (z > 10) $ showString "V4 " . f 11 a . showChar ' ' . f 11 b . showChar ' ' . f 11 c . showChar ' ' . f 11 d instance Functor V4 where fmap f (V4 a b c d) = V4 (f a) (f b) (f c) (f d) {-# INLINE fmap #-} a <$ _ = V4 a a a a {-# INLINE (<$) #-} instance Applicative V4 where pure = pureRep liftA2 = liftR2 instance Foldable V4 where foldMap f (V4 a b c d) = f a <> f b <> f c <> f d {-# INLINE foldMap #-} null _ = False length _ = two + two instance Foldable1 V4 where foldMap1 f (V4 a b c d) = f a <> f b <> f c <> f d {-# INLINE foldMap1 #-} instance Distributive V4 where distribute f = V4 (fmap (\(V4 x _ _ _) -> x) f) (fmap (\(V4 _ y _ _) -> y) f) (fmap (\(V4 _ _ z _) -> z) f) (fmap (\(V4 _ _ _ w) -> w) f) {-# INLINE distribute #-} instance Representable V4 where type Rep V4 = E4 tabulate f = V4 (f E41) (f E42) (f E43) (f E44) {-# INLINE tabulate #-} index (V4 x _ _ _) E41 = x index (V4 _ y _ _) E42 = y index (V4 _ _ z _) E43 = z index (V4 _ _ _ w) E44 = w {-# INLINE index #-} ------------------------------------------------------------------------------- -- Autogenerated instances ------------------------------------------------------------------------------- #define deriveAdditiveSemigroup(ty) \ instance (Additive-Semigroup) a => Semigroup (Additive (ty a)) where { \ (<>) = liftA2 $ mzipWithRep (+) \ ; {-# INLINE (<>) #-} \ } #define deriveAdditiveMonoid(ty) \ instance (Additive-Monoid) a => Monoid (Additive (ty a)) where { \ mempty = pure $ pureRep zero \ ; {-# INLINE mempty #-} \ } #define deriveMultiplicativeSemigroup(ty) \ instance (Multiplicative-Semigroup) a => Semigroup (Multiplicative (ty a)) where { \ (<>) = liftA2 $ mzipWithRep (*) \ ; {-# INLINE (<>) #-} \ } #define deriveMultiplicativeMonoid(ty) \ instance (Multiplicative-Monoid) a => Monoid (Multiplicative (ty a)) where { \ mempty = pure $ pureRep one \ ; {-# INLINE mempty #-} \ } #define deriveMultiplicativeMatrixSemigroup(ty) \ instance Semiring a => Semigroup (Multiplicative (ty a)) where { \ (<>) = liftA2 $ (.#.) \ ; {-# INLINE (<>) #-} \ } #define deriveMultiplicativeMatrixMonoid(ty) \ instance Semiring a => Monoid (Multiplicative (ty a)) where { \ mempty = pure identity \ ; {-# INLINE mempty #-} \ } #define deriveAdditiveMagma(ty) \ instance (Additive-Group) a => Magma (Additive (ty a)) where { \ (<<) = liftA2 $ mzipWithRep (-) \ ; {-# INLINE (<<) #-} \ } #define deriveAdditiveQuasigroup(ty) \ instance (Additive-Group) a => Quasigroup (Additive (ty a)) \ #define deriveAdditiveLoop(ty) \ instance (Additive-Group) a => Loop (Additive (ty a)) \ #define deriveAdditiveGroup(ty) \ instance (Additive-Group) a => Group (Additive (ty a)) \ #define derivePresemiring(ty) \ instance Semiring a => Presemiring (ty a) \ #define deriveSemiring(ty) \ instance Semiring a => Semiring (ty a) \ #define deriveRing(ty) \ instance Ring a => Ring (ty a) \ #define deriveFreeLeftSemimodule(ty) \ instance Semiring a => LeftSemimodule a (ty a) where { \ lscale = lscaleDef \ ; {-# INLINE lscale #-} \ } #define deriveFreeRightSemimodule(ty) \ instance Semiring a => RightSemimodule a (ty a) where { \ rscale = rscaleDef \ ; {-# INLINE rscale #-} \ } #define deriveFreeBisemimodule(ty) \ instance Semiring a => Bisemimodule a a (ty a) \ #define deriveBisemimodule(tyl, tyr, ty) \ instance Semiring a => Bisemimodule (tyl a) (tyr a) (ty a) \ #define deriveLeftSemimodule(tyl,ty) \ instance Semiring a => LeftSemimodule (tyl a) (ty a) where { \ lscale = (.#.) \ ; {-# INLINE lscale #-} \ } #define deriveRightSemimodule(tyr,ty) \ instance Semiring a => RightSemimodule (tyr a) (ty a) where { \ rscale = flip (.#.) \ ; {-# INLINE rscale #-} \ } #define deriveBisemimodule(tyl, tyr, ty) \ instance Semiring a => Bisemimodule (tyl a) (tyr a) (ty a) \ -- V1 deriveAdditiveSemigroup(V1) deriveAdditiveMonoid(V1) deriveAdditiveMagma(V1) deriveAdditiveQuasigroup(V1) deriveAdditiveLoop(V1) deriveAdditiveGroup(V1) deriveFreeLeftSemimodule(V1) deriveFreeRightSemimodule(V1) deriveFreeBisemimodule(V1) -- V2 deriveAdditiveSemigroup(V2) deriveAdditiveMonoid(V2) deriveAdditiveMagma(V2) deriveAdditiveQuasigroup(V2) deriveAdditiveLoop(V2) deriveAdditiveGroup(V2) deriveFreeLeftSemimodule(V2) deriveFreeRightSemimodule(V2) deriveFreeBisemimodule(V2) -- V3 deriveAdditiveSemigroup(V3) deriveAdditiveMonoid(V3) deriveAdditiveMagma(V3) deriveAdditiveQuasigroup(V3) deriveAdditiveLoop(V3) deriveAdditiveGroup(V3) deriveFreeLeftSemimodule(V3) deriveFreeRightSemimodule(V3) deriveFreeBisemimodule(V3) -- V4 deriveAdditiveSemigroup(V4) deriveAdditiveMonoid(V4) deriveAdditiveMagma(V4) deriveAdditiveQuasigroup(V4) deriveAdditiveLoop(V4) deriveAdditiveGroup(V4) deriveFreeLeftSemimodule(V4) deriveFreeRightSemimodule(V4) deriveFreeBisemimodule(V4) -- M11 deriveLeftSemimodule(M11, M11) deriveRightSemimodule(M11, M11) deriveMultiplicativeMatrixSemigroup(M11) deriveMultiplicativeMatrixMonoid(M11) derivePresemiring(M11) deriveSemiring(M11) deriveRing(M11) -- M21 deriveLeftSemimodule(M22, M21) deriveRightSemimodule(M11, M21) deriveBisemimodule(M22, M11, M21) -- M31 deriveLeftSemimodule(M33, M31) deriveRightSemimodule(M11, M31) deriveBisemimodule(M33, M11, M31) -- M41 deriveLeftSemimodule(M44, M41) deriveRightSemimodule(M11, M41) deriveBisemimodule(M44, M11, M41) -- M12 deriveLeftSemimodule(M11, M12) deriveRightSemimodule(M22, M12) deriveBisemimodule(M11, M22, M12) -- M22 deriveLeftSemimodule(M22, M22) deriveRightSemimodule(M22, M22) deriveMultiplicativeMatrixSemigroup(M22) deriveMultiplicativeMatrixMonoid(M22) derivePresemiring(M22) deriveSemiring(M22) deriveRing(M22) -- M32 deriveLeftSemimodule(M33, M32) deriveRightSemimodule(M22, M32) deriveBisemimodule(M33, M22, M32) -- M42 deriveLeftSemimodule(M44, M42) deriveRightSemimodule(M22, M42) deriveBisemimodule(M44, M22, M42) -- M13 deriveLeftSemimodule(M11, M13) deriveRightSemimodule(M33, M13) deriveBisemimodule(M11, M33, M13) -- M23 deriveLeftSemimodule(M22, M23) deriveRightSemimodule(M33, M23) deriveBisemimodule(M22, M33, M23) -- M33 deriveLeftSemimodule(M33, M33) deriveRightSemimodule(M33, M33) deriveMultiplicativeMatrixSemigroup(M33) deriveMultiplicativeMatrixMonoid(M33) derivePresemiring(M33) deriveSemiring(M33) deriveRing(M33) -- M43 deriveLeftSemimodule(M44, M43) deriveRightSemimodule(M33, M43) deriveBisemimodule(M44, M33, M43) -- M14 deriveLeftSemimodule(M11, M14) deriveRightSemimodule(M44, M14) deriveBisemimodule(M11, M44, M14) -- M24 deriveLeftSemimodule(M22, M24) deriveRightSemimodule(M44, M24) deriveBisemimodule(M22, M44, M24) -- M34 deriveLeftSemimodule(M33, M34) deriveRightSemimodule(M44, M34) deriveBisemimodule(M33, M44, M34) -- M44 deriveLeftSemimodule(M44, M44) deriveRightSemimodule(M44, M44) deriveMultiplicativeMatrixSemigroup(M44) deriveMultiplicativeMatrixMonoid(M44) derivePresemiring(M44) deriveSemiring(M44) deriveRing(M44)