mlkem-0.2.2.0: src/Matrix.hs
-- |
-- Module : Matrix
-- License : BSD-3-Clause
-- Copyright : (c) 2025 Olivier Chéron
--
-- A matrix here is simply a vector of vectors. The module also implements
-- two utility functions 'mulw' and 'muly' that multiply a matrix and a vector.
--
{-# LANGUAGE CPP #-}
module Matrix
( create, mulw, muly
#ifdef ML_KEM_TESTING
, transpose
#endif
) where
import Base
import Math
import Vector (Vector)
import qualified Vector
create :: (KnownNat m, KnownNat n) => (Offset ty -> Offset (Vector n ty) -> ty) -> Vector m (Vector n ty)
create f = Vector.create $ \j -> Vector.create (`f` j)
{-# INLINE create #-}
index :: Vector m (Vector n ty) -> Offset ty -> Offset (Vector n ty) -> ty
index a i j = Vector.index (Vector.index a j) i
mulw :: BiMulAdd b a => Vector m (Vector n b) -> Vector m a -> Vector n a -> Vector n a
mulw a u b = Vector.seq u (Vector.mapIx f b)
where
f (Offset i) bv =
let g (Offset j) vu = (index a (Offset i) (Offset j), vu)
in Vector.biMulFoldIndexWith g bv u
{-# INLINE mulw #-}
muly :: BiMulAdd b a => Vector m (Vector n b) -> Vector n a -> Vector m a
muly a u = Vector.seq u (fmap (`Vector.dot` u) a)
{-# INLINE muly #-}
#ifdef ML_KEM_TESTING
transpose :: (KnownNat m, KnownNat n) => Vector m (Vector n ty) -> Vector n (Vector m ty)
transpose a = create $ \(Offset j) (Offset i) -> index a (Offset i) (Offset j)
#endif