packages feed

brush-strokes-0.1.0.0: src/lib/Math/Root/Isolation/Utils.hs

{-# LANGUAGE ScopedTypeVariables #-}

-- | Utilities for root isolation
module Math.Root.Isolation.Utils
  ( fromComponents, matMulVec, boxMidpoint )
  where

-- base
import Prelude hiding ( unzip )
import Data.Foldable
  ( toList )
import Data.Functor
  ( unzip )

-- brush-strokes
import Math.Interval
import Math.Linear

--------------------------------------------------------------------------------

fromComponents
  :: forall n
  .  ( Representable 𝕀 ( 𝕀ℝ n ), n ~ RepDim ( 𝕀ℝ n ) )
  => ( Fin n -> [ ( 𝕀, Bool ) ] ) -> [ ( 𝕀ℝ n, Vec n Bool ) ]
fromComponents f = do
  ( xs, bs ) <- unzip <$> traverse f ( universe @n )
  return $ ( tabulate $ \ i -> xs ! i, bs )
    -- TODO: this could be more efficient.
{-# INLINEABLE fromComponents #-}

-- | The midpoint of a box.
boxMidpoint :: ( Representable 𝕀 ( 𝕀ℝ n ), Representable Double ( ℝ n ) ) => 𝕀ℝ n -> ℝ n
boxMidpoint box =
  tabulate $ \ i -> midpoint ( box `index` i )
{-# INLINEABLE boxMidpoint #-}

-- | Matrix multiplication \( A v \).
matMulVec
  :: forall n m
  .  ( Representable 𝕀 ( 𝕀ℝ n ), Representable 𝕀 ( 𝕀ℝ m )
     , Representable Double ( ℝ n ), Representable Double ( ℝ m )
     )
  => Vec m ( ℝ n ) -- ^ columns of the matrix \( A )
  -> 𝕀ℝ m          -- ^ vector \( v \)
  -> 𝕀ℝ n
matMulVec as v = tabulate $ \ r ->
  sum [ scaleInterval ( a `index` r ) ( index v c )
      | ( c, a ) <- toList ( (,) <$> universe @m <*> as )
      ]
{-# INLINEABLE matMulVec #-}