mini-1.6.4.0: src/Mini/Linear/Space.hs
-- | Vector spaces of up to four dimensions
module Mini.Linear.Space (
-- * Elements
V0 (V0),
V1 (V1),
V2 (V2),
V3 (V3),
V4 (V4),
-- * Spaces
R1 (
x
),
R2 (
y,
xy,
yx
),
R3 (
z,
xz,
yz,
zx,
zy,
xyz,
xzy,
yxz,
yzx,
zxy,
zyx
),
R4 (
w,
xw,
yw,
zw,
wx,
wy,
wz,
xyw,
xzw,
xwy,
xwz,
yxw,
yzw,
ywx,
ywz,
zxw,
zyw,
zwx,
zwy,
wxy,
wxz,
wyx,
wyz,
wzx,
wzy,
xyzw,
xywz,
xzyw,
xzwy,
xwyz,
xwzy,
yxzw,
yxwz,
yzxw,
yzwx,
ywxz,
ywzx,
zxyw,
zxwy,
zyxw,
zywx,
zwxy,
zwyx,
wxyz,
wxzy,
wyxz,
wyzx,
wzxy,
wzyx
),
) where
import Control.Applicative (
liftA2,
)
import Control.Monad (
ap,
liftM,
)
import Mini.Hash.Class (
Hashable (
toBytes
),
)
import Mini.Linear.Approx (
Approx,
(~=),
)
import Mini.Optics.Lens (
Lens,
view,
)
import Mini.Random.Class (
Random,
random,
)
import Prelude (
Applicative,
Bool (
False,
True
),
Eq,
Foldable,
Functor,
Monad,
Monoid,
Ord,
Semigroup,
Show,
Traversable,
and,
concatMap,
fmap,
foldr,
id,
length,
mempty,
null,
pure,
traverse,
($),
(.),
(<$>),
(<*>),
(<>),
(>>=),
)
-- Spaces
-- | Vector space with at least one dimension
class R1 v where
-- | Basis vector lens of the first dimension
x :: Lens (v a) (v a) a a
-- | Vector space with at least two dimensions
class (R1 v) => R2 v where
-- | Basis vector lens of the second dimension
y :: Lens (v a) (v a) a a
y f = xy (\(V2 a0 a1) -> V2 a0 <$> f a1)
xy :: Lens (v a) (v a) (V2 a) (V2 a)
yx :: Lens (v a) (v a) (V2 a) (V2 a)
yx f = xy (\v -> f $ V2 (view y v) (view x v))
-- | Vector space with at least three dimensions
class (R2 v) => R3 v where
-- | Basis vector lens of the third dimension
z :: Lens (v a) (v a) a a
z f = xyz (\(V3 a0 a1 a2) -> V3 a0 a1 <$> f a2)
xz :: Lens (v a) (v a) (V2 a) (V2 a)
xz f =
xyz
( \v ->
(\v' -> V3 (view x v') (view y v) (view y v'))
<$> f (V2 (view x v) (view z v))
)
yz :: Lens (v a) (v a) (V2 a) (V2 a)
yz f =
xyz
( \v ->
(\v' -> V3 (view x v) (view x v') (view y v'))
<$> f (V2 (view y v) (view z v))
)
zx :: Lens (v a) (v a) (V2 a) (V2 a)
zx f =
xyz
( \v ->
(\v' -> V3 (view y v') (view y v) (view x v'))
<$> f (V2 (view z v) (view x v))
)
zy :: Lens (v a) (v a) (V2 a) (V2 a)
zy f =
xyz
( \v ->
(\v' -> V3 (view x v) (view y v') (view x v'))
<$> f (V2 (view z v) (view y v))
)
xyz :: Lens (v a) (v a) (V3 a) (V3 a)
xzy :: Lens (v a) (v a) (V3 a) (V3 a)
xzy f = xyz (\v -> f $ V3 (view x v) (view z v) (view y v))
yxz :: Lens (v a) (v a) (V3 a) (V3 a)
yxz f = xyz (\v -> f $ V3 (view y v) (view x v) (view z v))
yzx :: Lens (v a) (v a) (V3 a) (V3 a)
yzx f = xyz (\v -> f $ V3 (view y v) (view z v) (view x v))
zxy :: Lens (v a) (v a) (V3 a) (V3 a)
zxy f = xyz (\v -> f $ V3 (view z v) (view x v) (view y v))
zyx :: Lens (v a) (v a) (V3 a) (V3 a)
zyx f = xyz (\v -> f $ V3 (view z v) (view y v) (view x v))
-- | Vector space with at least four dimensions
class (R3 v) => R4 v where
-- | Basis vector lens of the fourth dimension
w :: Lens (v a) (v a) a a
w f = xyzw (\(V4 a0 a1 a2 a3) -> V4 a0 a1 a2 <$> f a3)
xw :: Lens (v a) (v a) (V2 a) (V2 a)
xw f =
xyzw
( \v ->
(\v' -> V4 (view x v') (view y v) (view z v) (view y v'))
<$> f (V2 (view x v) (view w v))
)
yw :: Lens (v a) (v a) (V2 a) (V2 a)
yw f =
xyzw
( \v ->
(\v' -> V4 (view x v) (view x v') (view z v) (view y v'))
<$> f (V2 (view y v) (view w v))
)
zw :: Lens (v a) (v a) (V2 a) (V2 a)
zw f =
xyzw
( \v ->
(\v' -> V4 (view x v) (view y v) (view x v') (view y v'))
<$> f (V2 (view z v) (view w v))
)
wx :: Lens (v a) (v a) (V2 a) (V2 a)
wx f =
xyzw
( \v ->
(\v' -> V4 (view y v') (view y v) (view z v) (view x v'))
<$> f (V2 (view w v) (view x v))
)
wy :: Lens (v a) (v a) (V2 a) (V2 a)
wy f =
xyzw
( \v ->
(\v' -> V4 (view x v) (view y v') (view z v) (view x v'))
<$> f (V2 (view w v) (view y v))
)
wz :: Lens (v a) (v a) (V2 a) (V2 a)
wz f =
xyzw
( \v ->
(\v' -> V4 (view x v) (view y v) (view y v') (view x v'))
<$> f (V2 (view w v) (view z v))
)
xyw :: Lens (v a) (v a) (V3 a) (V3 a)
xyw f =
xyzw
( \v ->
(\v' -> V4 (view x v') (view y v') (view z v) (view z v'))
<$> f (V3 (view x v) (view y v) (view w v))
)
xzw :: Lens (v a) (v a) (V3 a) (V3 a)
xzw f =
xyzw
( \v ->
(\v' -> V4 (view x v') (view y v) (view y v') (view z v'))
<$> f (V3 (view x v) (view z v) (view w v))
)
xwy :: Lens (v a) (v a) (V3 a) (V3 a)
xwy f =
xyzw
( \v ->
(\v' -> V4 (view x v') (view y v') (view z v) (view y v'))
<$> f (V3 (view x v) (view w v) (view y v))
)
xwz :: Lens (v a) (v a) (V3 a) (V3 a)
xwz f =
xyzw
( \v ->
(\v' -> V4 (view x v') (view y v) (view z v') (view y v'))
<$> f (V3 (view x v) (view w v) (view z v))
)
yxw :: Lens (v a) (v a) (V3 a) (V3 a)
yxw f =
xyzw
( \v ->
(\v' -> V4 (view x v') (view x v') (view z v) (view z v'))
<$> f (V3 (view y v) (view x v) (view w v))
)
yzw :: Lens (v a) (v a) (V3 a) (V3 a)
yzw f =
xyzw
( \v ->
(\v' -> V4 (view x v) (view x v') (view y v') (view z v'))
<$> f (V3 (view y v) (view z v) (view w v))
)
ywx :: Lens (v a) (v a) (V3 a) (V3 a)
ywx f =
xyzw
( \v ->
(\v' -> V4 (view z v') (view x v') (view z v) (view y v'))
<$> f (V3 (view y v) (view w v) (view x v))
)
ywz :: Lens (v a) (v a) (V3 a) (V3 a)
ywz f =
xyzw
( \v ->
(\v' -> V4 (view x v) (view x v') (view z v') (view y v'))
<$> f (V3 (view y v) (view w v) (view z v))
)
zxw :: Lens (v a) (v a) (V3 a) (V3 a)
zxw f =
xyzw
( \v ->
(\v' -> V4 (view y v') (view y v) (view x v') (view z v'))
<$> f (V3 (view z v) (view x v) (view w v))
)
zyw :: Lens (v a) (v a) (V3 a) (V3 a)
zyw f =
xyzw
( \v ->
(\v' -> V4 (view x v) (view y v') (view x v') (view z v'))
<$> f (V3 (view z v) (view y v) (view w v))
)
zwx :: Lens (v a) (v a) (V3 a) (V3 a)
zwx f =
xyzw
( \v ->
(\v' -> V4 (view z v') (view y v) (view x v') (view y v'))
<$> f (V3 (view z v) (view w v) (view x v))
)
zwy :: Lens (v a) (v a) (V3 a) (V3 a)
zwy f =
xyzw
( \v ->
(\v' -> V4 (view x v) (view z v') (view x v') (view y v'))
<$> f (V3 (view z v) (view w v) (view y v))
)
wxy :: Lens (v a) (v a) (V3 a) (V3 a)
wxy f =
xyzw
( \v ->
(\v' -> V4 (view y v') (view z v') (view z v) (view x v'))
<$> f (V3 (view w v) (view x v) (view y v))
)
wxz :: Lens (v a) (v a) (V3 a) (V3 a)
wxz f =
xyzw
( \v ->
(\v' -> V4 (view y v') (view y v) (view z v') (view x v'))
<$> f (V3 (view w v) (view x v) (view z v))
)
wyx :: Lens (v a) (v a) (V3 a) (V3 a)
wyx f =
xyzw
( \v ->
(\v' -> V4 (view z v') (view y v') (view z v) (view x v'))
<$> f (V3 (view w v) (view y v) (view x v))
)
wyz :: Lens (v a) (v a) (V3 a) (V3 a)
wyz f =
xyzw
( \v ->
(\v' -> V4 (view x v) (view y v') (view z v') (view x v'))
<$> f (V3 (view w v) (view y v) (view z v))
)
wzx :: Lens (v a) (v a) (V3 a) (V3 a)
wzx f =
xyzw
( \v ->
(\v' -> V4 (view z v') (view y v) (view y v') (view x v'))
<$> f (V3 (view w v) (view z v) (view x v))
)
wzy :: Lens (v a) (v a) (V3 a) (V3 a)
wzy f =
xyzw
( \v ->
(\v' -> V4 (view x v) (view z v') (view y v') (view x v'))
<$> f (V3 (view w v) (view z v) (view y v))
)
xyzw :: Lens (v a) (v a) (V4 a) (V4 a)
xywz :: Lens (v a) (v a) (V4 a) (V4 a)
xywz f = xyzw (\v -> f $ V4 (view x v) (view y v) (view w v) (view z v))
xzyw :: Lens (v a) (v a) (V4 a) (V4 a)
xzyw f = xyzw (\v -> f $ V4 (view x v) (view z v) (view y v) (view w v))
xzwy :: Lens (v a) (v a) (V4 a) (V4 a)
xzwy f = xyzw (\v -> f $ V4 (view x v) (view z v) (view w v) (view y v))
xwyz :: Lens (v a) (v a) (V4 a) (V4 a)
xwyz f = xyzw (\v -> f $ V4 (view x v) (view w v) (view y v) (view z v))
xwzy :: Lens (v a) (v a) (V4 a) (V4 a)
xwzy f = xyzw (\v -> f $ V4 (view x v) (view w v) (view z v) (view y v))
yxzw :: Lens (v a) (v a) (V4 a) (V4 a)
yxzw f = xyzw (\v -> f $ V4 (view y v) (view x v) (view z v) (view w v))
yxwz :: Lens (v a) (v a) (V4 a) (V4 a)
yxwz f = xyzw (\v -> f $ V4 (view y v) (view x v) (view w v) (view z v))
yzxw :: Lens (v a) (v a) (V4 a) (V4 a)
yzxw f = xyzw (\v -> f $ V4 (view y v) (view z v) (view x v) (view w v))
yzwx :: Lens (v a) (v a) (V4 a) (V4 a)
yzwx f = xyzw (\v -> f $ V4 (view y v) (view z v) (view w v) (view x v))
ywxz :: Lens (v a) (v a) (V4 a) (V4 a)
ywxz f = xyzw (\v -> f $ V4 (view y v) (view w v) (view x v) (view z v))
ywzx :: Lens (v a) (v a) (V4 a) (V4 a)
ywzx f = xyzw (\v -> f $ V4 (view y v) (view w v) (view z v) (view x v))
zxyw :: Lens (v a) (v a) (V4 a) (V4 a)
zxyw f = xyzw (\v -> f $ V4 (view z v) (view x v) (view y v) (view w v))
zxwy :: Lens (v a) (v a) (V4 a) (V4 a)
zxwy f = xyzw (\v -> f $ V4 (view z v) (view x v) (view w v) (view y v))
zyxw :: Lens (v a) (v a) (V4 a) (V4 a)
zyxw f = xyzw (\v -> f $ V4 (view z v) (view y v) (view x v) (view w v))
zywx :: Lens (v a) (v a) (V4 a) (V4 a)
zywx f = xyzw (\v -> f $ V4 (view z v) (view y v) (view w v) (view x v))
zwxy :: Lens (v a) (v a) (V4 a) (V4 a)
zwxy f = xyzw (\v -> f $ V4 (view z v) (view w v) (view x v) (view y v))
zwyx :: Lens (v a) (v a) (V4 a) (V4 a)
zwyx f = xyzw (\v -> f $ V4 (view z v) (view w v) (view y v) (view x v))
wxyz :: Lens (v a) (v a) (V4 a) (V4 a)
wxyz f = xyzw (\v -> f $ V4 (view w v) (view x v) (view y v) (view z v))
wxzy :: Lens (v a) (v a) (V4 a) (V4 a)
wxzy f = xyzw (\v -> f $ V4 (view w v) (view x v) (view z v) (view y v))
wyxz :: Lens (v a) (v a) (V4 a) (V4 a)
wyxz f = xyzw (\v -> f $ V4 (view w v) (view y v) (view x v) (view z v))
wyzx :: Lens (v a) (v a) (V4 a) (V4 a)
wyzx f = xyzw (\v -> f $ V4 (view w v) (view y v) (view z v) (view x v))
wzxy :: Lens (v a) (v a) (V4 a) (V4 a)
wzxy f = xyzw (\v -> f $ V4 (view w v) (view z v) (view x v) (view y v))
wzyx :: Lens (v a) (v a) (V4 a) (V4 a)
wzyx f = xyzw (\v -> f $ V4 (view w v) (view z v) (view y v) (view x v))
-- Elements
-- | Zero-dimensional vector
data V0 a = V0
deriving (Show, Eq, Ord)
instance Functor V0 where
fmap = liftM
instance Applicative V0 where
pure _ = V0
(<*>) = ap
instance Monad V0 where
_ >>= _ = V0
instance Foldable V0 where
foldr _ b _ = b
null _ = True
length _ = 0
instance Traversable V0 where
traverse _ _ = pure V0
instance Semigroup (V0 a) where
_ <> _ = V0
instance Monoid (V0 a) where
mempty = V0
instance Approx (V0 a) where
_ ~= _ = True
instance Hashable (V0 a) where
toBytes _ = []
instance Random (V0 a) where
random g = (V0, g)
-- | One-dimensional vector
newtype V1 a = V1 a
deriving (Show, Eq, Ord)
instance R1 V1 where
x f (V1 a0) = V1 <$> f a0
instance Functor V1 where
fmap = liftM
instance Applicative V1 where
pure = V1
(<*>) = ap
instance Monad V1 where
m >>= k = k $ view x m
instance Foldable V1 where
foldr f b v = f (view x v) b
null _ = False
length _ = 1
instance Traversable V1 where
traverse f v = V1 <$> f (view x v)
instance (Semigroup a) => Semigroup (V1 a) where
(<>) = liftA2 (<>)
instance (Monoid a) => Monoid (V1 a) where
mempty = pure mempty
instance (Approx a) => Approx (V1 a) where
u ~= v = view x u ~= view x v
instance (Hashable a) => Hashable (V1 a) where
toBytes = concatMap toBytes
instance (Random a) => Random (V1 a) where
random g = let (a, g') = random g in (V1 a, g')
-- | Two-dimensional vector
data V2 a = V2 a a
deriving (Show, Eq, Ord)
instance R1 V2 where
x f (V2 a0 a1) = (`V2` a1) <$> f a0
instance R2 V2 where
xy = id
instance Functor V2 where
fmap = liftM
instance Applicative V2 where
pure a = V2 a a
(<*>) = ap
instance Monad V2 where
m >>= k = V2 (view x . k $ view x m) (view y . k $ view y m)
instance Foldable V2 where
foldr f b v = f (view x v) $ f (view y v) b
null _ = False
length _ = 2
instance Traversable V2 where
traverse f v = V2 <$> f (view x v) <*> f (view y v)
instance (Semigroup a) => Semigroup (V2 a) where
(<>) = liftA2 (<>)
instance (Monoid a) => Monoid (V2 a) where
mempty = pure mempty
instance (Approx a) => Approx (V2 a) where
u ~= v = and $ liftA2 (~=) u v
instance (Hashable a) => Hashable (V2 a) where
toBytes = concatMap toBytes
instance (Random a) => Random (V2 a) where
random g =
let (a0, g') = random g
(a1, g'') = random g'
in (V2 a0 a1, g'')
-- | Three-dimensional vector
data V3 a = V3 a a a
deriving (Show, Eq, Ord)
instance R1 V3 where
x f (V3 a0 a1 a2) = (\a0' -> V3 a0' a1 a2) <$> f a0
instance R2 V3 where
xy f (V3 a0 a1 a2) =
(\(V2 a0' a1') -> V3 a0' a1' a2)
<$> f (V2 a0 a1)
instance R3 V3 where
xyz = id
instance Functor V3 where
fmap = liftM
instance Applicative V3 where
pure a = V3 a a a
(<*>) = ap
instance Monad V3 where
m >>= k =
V3
(view x . k $ view x m)
(view y . k $ view y m)
(view z . k $ view z m)
instance Foldable V3 where
foldr f b v = f (view x v) . f (view y v) $ f (view z v) b
null _ = False
length _ = 3
instance Traversable V3 where
traverse f v = V3 <$> f (view x v) <*> f (view y v) <*> f (view z v)
instance (Semigroup a) => Semigroup (V3 a) where
(<>) = liftA2 (<>)
instance (Monoid a) => Monoid (V3 a) where
mempty = pure mempty
instance (Approx a) => Approx (V3 a) where
u ~= v = and $ liftA2 (~=) u v
instance (Hashable a) => Hashable (V3 a) where
toBytes = concatMap toBytes
instance (Random a) => Random (V3 a) where
random g =
let (a0, g') = random g
(a1, g'') = random g'
(a2, g''') = random g''
in (V3 a0 a1 a2, g''')
-- | Four-dimensional vector
data V4 a = V4 a a a a
deriving (Show, Eq, Ord)
instance R1 V4 where
x f (V4 a0 a1 a2 a3) = (\a0' -> V4 a0' a1 a2 a3) <$> f a0
instance R2 V4 where
xy f (V4 a0 a1 a2 a3) = (\(V2 a0' a1') -> V4 a0' a1' a2 a3) <$> f (V2 a0 a1)
instance R3 V4 where
xyz f (V4 a0 a1 a2 a3) =
(\(V3 a0' a1' a2') -> V4 a0' a1' a2' a3)
<$> f (V3 a0 a1 a2)
instance R4 V4 where
xyzw = id
instance Functor V4 where
fmap = liftM
instance Applicative V4 where
pure a = V4 a a a a
(<*>) = ap
instance Monad V4 where
m >>= k =
V4
(view x . k $ view x m)
(view y . k $ view y m)
(view z . k $ view z m)
(view w . k $ view w m)
instance Foldable V4 where
foldr f b v = f (view x v) . f (view y v) . f (view z v) $ f (view w v) b
null _ = False
length _ = 4
instance Traversable V4 where
traverse f v =
V4
<$> f (view x v)
<*> f (view y v)
<*> f (view z v)
<*> f (view w v)
instance (Semigroup a) => Semigroup (V4 a) where
(<>) = liftA2 (<>)
instance (Monoid a) => Monoid (V4 a) where
mempty = pure mempty
instance (Approx a) => Approx (V4 a) where
u ~= v = and $ liftA2 (~=) u v
instance (Hashable a) => Hashable (V4 a) where
toBytes = concatMap toBytes
instance (Random a) => Random (V4 a) where
random g =
let (a0, g') = random g
(a1, g'') = random g'
(a2, g''') = random g''
(a3, g'''') = random g'''
in (V4 a0 a1 a2 a3, g'''')