{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
-- |
-- Module      : Data.Massiv.Array.Numeric
-- Copyright   : (c) Alexey Kuleshevich 2018-2019
-- License     : BSD3
-- Maintainer  : Alexey Kuleshevich <lehins@yandex.ru>
-- Stability   : experimental
-- Portability : non-portable
--
module Data.Massiv.Array.Numeric
  ( -- * Numeric
    Numeric
  , NumericFloat
    -- ** Pointwise addition
  , (.+)
  , (+.)
  , (.+.)
  , (!+!)
  -- ** Pointwise subtraction
  , (.-)
  , (-.)
  , (.-.)
  , (!-!)
  -- ** Pointwise multiplication
  , (.*)
  , (*.)
  , (.*.)
  , (!*!)
  , (.^)
  -- ** Dot product
  , (!.!)
  , dotM
  -- ** Matrix multiplication
  , (.><)
  , (!><)
  , multiplyMatrixByVector
  , (><.)
  , (><!)
  , multiplyVectorByMatrix
  , (.><.)
  , (!><!)
  , multiplyMatrices
  , multiplyMatricesTransposed
  -- Deprecated:
  , (#>)
  , (|*|)
  , multiplyTransposed
  -- * Norms
  , normL2
  -- ** Simple matrices
  , identityMatrix
  , lowerTriangular
  , upperTriangular
  , negateA
  , absA
  , signumA
  , fromIntegerA
  -- * Integral
  , quotA
  , remA
  , divA
  , modA
  , quotRemA
  , divModA
  -- * Fractional
  , (./)
  , (/.)
  , (./.)
  , (!/!)
  , (.^^)
  , recipA
  , fromRationalA
  -- * Floating
  , piA
  , expA
  , logA
  , sqrtA
  , (.**)
  , logBaseA
  , sinA
  , cosA
  , tanA
  , asinA
  , acosA
  , atanA
  , sinhA
  , coshA
  , tanhA
  , asinhA
  , acoshA
  , atanhA
  -- * RealFrac
  , truncateA
  , roundA
  , ceilingA
  , floorA
  -- * RealFloat
  , atan2A
  ) where

import Data.Massiv.Array.Mutable
import Data.Massiv.Array.Manifest
import Data.Massiv.Array.Delayed.Pull
import Data.Massiv.Array.Delayed.Push
import Data.Massiv.Array.Manifest.Internal
import Data.Massiv.Array.Ops.Fold as A
import Data.Massiv.Array.Ops.Map as A
import Data.Massiv.Array.Ops.Transform as A
import Data.Massiv.Array.Ops.Construct
import Data.Massiv.Core
import Data.Massiv.Core.Common
import Data.Massiv.Core.Operations
import Prelude as P
import System.IO.Unsafe
import Control.Scheduler
import Control.Monad (when)
import qualified Data.Foldable as F
import Data.Function

infixr 8  .^, .^^
infixl 7  !*!, .*., .*, *., !/!, ./., ./, /., `quotA`, `remA`, `divA`, `modA`
infixl 6  !+!, .+., .+, +., !-!, .-., .-, -.

liftArray2Matching
  :: (Source r1 ix a, Source r2 ix b)
  => (a -> b -> e) -> Array r1 ix a -> Array r2 ix b -> Array D ix e
liftArray2Matching :: (a -> b -> e) -> Array r1 ix a -> Array r2 ix b -> Array D ix e
liftArray2Matching a -> b -> e
f !Array r1 ix a
arr1 !Array r2 ix b
arr2
  | Sz ix
sz1 Sz ix -> Sz ix -> Bool
forall a. Eq a => a -> a -> Bool
== Sz ix
sz2 =
    Comp -> Sz ix -> (ix -> e) -> Array D ix e
forall r ix e.
Construct r ix e =>
Comp -> Sz ix -> (ix -> e) -> Array r ix e
makeArray
      (Array r1 ix a -> Comp
forall r ix e. Load r ix e => Array r ix e -> Comp
getComp Array r1 ix a
arr1 Comp -> Comp -> Comp
forall a. Semigroup a => a -> a -> a
<> Array r2 ix b -> Comp
forall r ix e. Load r ix e => Array r ix e -> Comp
getComp Array r2 ix b
arr2)
      Sz ix
sz1
      (\ !ix
ix -> a -> b -> e
f (Array r1 ix a -> ix -> a
forall r ix e. Source r ix e => Array r ix e -> ix -> e
unsafeIndex Array r1 ix a
arr1 ix
ix) (Array r2 ix b -> ix -> b
forall r ix e. Source r ix e => Array r ix e -> ix -> e
unsafeIndex Array r2 ix b
arr2 ix
ix))
  | Bool
otherwise = SizeException -> Array D ix e
forall a e. Exception e => e -> a
throw (SizeException -> Array D ix e) -> SizeException -> Array D ix e
forall a b. (a -> b) -> a -> b
$ Sz ix -> Sz ix -> SizeException
forall ix. Index ix => Sz ix -> Sz ix -> SizeException
SizeMismatchException (Array r1 ix a -> Sz ix
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Array r1 ix a
arr1) (Array r2 ix b -> Sz ix
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Array r2 ix b
arr2)
  where
    sz1 :: Sz ix
sz1 = Array r1 ix a -> Sz ix
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Array r1 ix a
arr1
    sz2 :: Sz ix
sz2 = Array r2 ix b -> Sz ix
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Array r2 ix b
arr2
{-# INLINE liftArray2Matching #-}

liftArray2M ::
     (Load r ix e, Numeric r e, MonadThrow m)
  => (e -> e -> e)
  -> Array r ix e
  -> Array r ix e
  -> m (Array r ix e)
liftArray2M :: (e -> e -> e) -> Array r ix e -> Array r ix e -> m (Array r ix e)
liftArray2M e -> e -> e
f Array r ix e
a1 Array r ix e
a2
  | Array r ix e -> Sz ix
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Array r ix e
a1 Sz ix -> Sz ix -> Bool
forall a. Eq a => a -> a -> Bool
== Array r ix e -> Sz ix
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Array r ix e
a2 = Array r ix e -> m (Array r ix e)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Array r ix e -> m (Array r ix e))
-> Array r ix e -> m (Array r ix e)
forall a b. (a -> b) -> a -> b
$ (e -> e -> e) -> Array r ix e -> Array r ix e -> Array r ix e
forall r e ix.
(Numeric r e, Index ix) =>
(e -> e -> e) -> Array r ix e -> Array r ix e -> Array r ix e
unsafeLiftArray2 e -> e -> e
f Array r ix e
a1 Array r ix e
a2
  | Bool
otherwise = SizeException -> m (Array r ix e)
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (SizeException -> m (Array r ix e))
-> SizeException -> m (Array r ix e)
forall a b. (a -> b) -> a -> b
$ Sz ix -> Sz ix -> SizeException
forall ix. Index ix => Sz ix -> Sz ix -> SizeException
SizeMismatchException (Array r ix e -> Sz ix
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Array r ix e
a1) (Array r ix e -> Sz ix
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Array r ix e
a2)
{-# INLINE liftArray2M #-}


liftNumericArray2M ::
     (Load r ix e, MonadThrow m)
  => (Array r ix e -> Array r ix e -> Array r ix e)
  -> Array r ix e
  -> Array r ix e
  -> m (Array r ix e)
liftNumericArray2M :: (Array r ix e -> Array r ix e -> Array r ix e)
-> Array r ix e -> Array r ix e -> m (Array r ix e)
liftNumericArray2M Array r ix e -> Array r ix e -> Array r ix e
f Array r ix e
a1 Array r ix e
a2
  | Array r ix e -> Sz ix
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Array r ix e
a1 Sz ix -> Sz ix -> Bool
forall a. Eq a => a -> a -> Bool
== Array r ix e -> Sz ix
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Array r ix e
a2 = Array r ix e -> m (Array r ix e)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Array r ix e -> m (Array r ix e))
-> Array r ix e -> m (Array r ix e)
forall a b. (a -> b) -> a -> b
$ Array r ix e -> Array r ix e -> Array r ix e
f Array r ix e
a1 Array r ix e
a2
  | Bool
otherwise = SizeException -> m (Array r ix e)
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (SizeException -> m (Array r ix e))
-> SizeException -> m (Array r ix e)
forall a b. (a -> b) -> a -> b
$ Sz ix -> Sz ix -> SizeException
forall ix. Index ix => Sz ix -> Sz ix -> SizeException
SizeMismatchException (Array r ix e -> Sz ix
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Array r ix e
a1) (Array r ix e -> Sz ix
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Array r ix e
a2)
{-# INLINE liftNumericArray2M #-}


-- | Add two arrays together pointwise. Same as `!+!` but produces monadic computation
-- that allows for handling failure.
--
-- /__Throws Exception__/: `SizeMismatchException` when array sizes do not match.
--
-- @since 0.4.0
(.+.) ::
     (Load r ix e, Numeric r e, MonadThrow m) => Array r ix e -> Array r ix e -> m (Array r ix e)
.+. :: Array r ix e -> Array r ix e -> m (Array r ix e)
(.+.) = (Array r ix e -> Array r ix e -> Array r ix e)
-> Array r ix e -> Array r ix e -> m (Array r ix e)
forall r ix e (m :: * -> *).
(Load r ix e, MonadThrow m) =>
(Array r ix e -> Array r ix e -> Array r ix e)
-> Array r ix e -> Array r ix e -> m (Array r ix e)
liftNumericArray2M Array r ix e -> Array r ix e -> Array r ix e
forall r e ix.
(Numeric r e, Index ix) =>
Array r ix e -> Array r ix e -> Array r ix e
additionPointwise
{-# INLINE (.+.) #-}

-- | Add two arrays together pointwise. Prefer to use monadic version of this function
-- `.+.` whenever possible, because it is better to avoid partial functions.
--
-- [Partial] Mismatched array sizes will result in an impure exception being thrown.
--
-- ====__Example__
--
-- >>> let a1 = Ix1 0 ... 10
-- >>> let a2 = Ix1 20 ... 30
-- >>> a1 !+! a2
-- Array D Seq (Sz1 11)
--   [ 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40 ]
--
-- @since 0.5.6
(!+!) :: (Load r ix e, Numeric r e) => Array r ix e -> Array r ix e -> Array r ix e
!+! :: Array r ix e -> Array r ix e -> Array r ix e
(!+!) Array r ix e
a1 Array r ix e
a2 = Either SomeException (Array r ix e) -> Array r ix e
forall a. Either SomeException a -> a
throwEither (Array r ix e
a1 Array r ix e -> Array r ix e -> Either SomeException (Array r ix e)
forall r ix e (m :: * -> *).
(Load r ix e, Numeric r e, MonadThrow m) =>
Array r ix e -> Array r ix e -> m (Array r ix e)
.+. Array r ix e
a2)
{-# INLINE (!+!) #-}

-- | Add a scalar to each element of the array. Array is on the left.
--
-- @since 0.1.0
(.+) :: (Index ix, Numeric r e) => Array r ix e -> e -> Array r ix e
.+ :: Array r ix e -> e -> Array r ix e
(.+) = Array r ix e -> e -> Array r ix e
forall r e ix.
(Numeric r e, Index ix) =>
Array r ix e -> e -> Array r ix e
plusScalar
{-# INLINE (.+) #-}

-- | Add a scalar to each element of the array. Array is on the right.
--
-- @since 0.4.0
(+.) :: (Index ix, Numeric r e) => e -> Array r ix e -> Array r ix e
+. :: e -> Array r ix e -> Array r ix e
(+.) = (Array r ix e -> e -> Array r ix e)
-> e -> Array r ix e -> Array r ix e
forall a b c. (a -> b -> c) -> b -> a -> c
flip Array r ix e -> e -> Array r ix e
forall r e ix.
(Numeric r e, Index ix) =>
Array r ix e -> e -> Array r ix e
plusScalar
{-# INLINE (+.) #-}

-- | Subtract two arrays pointwise. Same as `!-!` but produces monadic computation that
-- allows for handling failure.
--
-- /__Throws Exception__/: `SizeMismatchException` when array sizes do not match.
--
-- @since 0.4.0
(.-.) ::
     (Load r ix e, Numeric r e, MonadThrow m) => Array r ix e -> Array r ix e -> m (Array r ix e)
.-. :: Array r ix e -> Array r ix e -> m (Array r ix e)
(.-.) = (Array r ix e -> Array r ix e -> Array r ix e)
-> Array r ix e -> Array r ix e -> m (Array r ix e)
forall r ix e (m :: * -> *).
(Load r ix e, MonadThrow m) =>
(Array r ix e -> Array r ix e -> Array r ix e)
-> Array r ix e -> Array r ix e -> m (Array r ix e)
liftNumericArray2M Array r ix e -> Array r ix e -> Array r ix e
forall r e ix.
(Numeric r e, Index ix) =>
Array r ix e -> Array r ix e -> Array r ix e
subtractionPointwise
{-# INLINE (.-.) #-}


-- | Subtract one array from another pointwise. Prefer to use monadic version of this
-- function `.-.` whenever possible, because it is better to avoid partial functions.
--
-- [Partial] Mismatched array sizes will result in an impure exception being thrown.
--
-- ====__Example__
--
-- >>> let a1 = Ix1 0 ... 10
-- >>> let a2 = Ix1 20 ... 30
-- >>> a1 !-! a2
-- Array D Seq (Sz1 11)
--   [ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20 ]
--
-- @since 0.5.6
(!-!) :: (Load r ix e, Numeric r e) => Array r ix e -> Array r ix e -> Array r ix e
!-! :: Array r ix e -> Array r ix e -> Array r ix e
(!-!) Array r ix e
a1 Array r ix e
a2 = Either SomeException (Array r ix e) -> Array r ix e
forall a. Either SomeException a -> a
throwEither (Array r ix e
a1 Array r ix e -> Array r ix e -> Either SomeException (Array r ix e)
forall r ix e (m :: * -> *).
(Load r ix e, Numeric r e, MonadThrow m) =>
Array r ix e -> Array r ix e -> m (Array r ix e)
.-. Array r ix e
a2)
{-# INLINE (!-!) #-}

-- | Subtract a scalar from each element of the array. Array is on the left.
--
-- @since 0.4.0
(.-) :: (Index ix, Numeric r e) => Array r ix e -> e -> Array r ix e
.- :: Array r ix e -> e -> Array r ix e
(.-) = Array r ix e -> e -> Array r ix e
forall r e ix.
(Numeric r e, Index ix) =>
Array r ix e -> e -> Array r ix e
minusScalar
{-# INLINE (.-) #-}

-- | Subtract each element of the array from a scalar. Array is on the right.
--
-- @since 0.5.6
(-.) :: (Index ix, Numeric r e) => e -> Array r ix e -> Array r ix e
-. :: e -> Array r ix e -> Array r ix e
(-.) = e -> Array r ix e -> Array r ix e
forall r e ix.
(Numeric r e, Index ix) =>
e -> Array r ix e -> Array r ix e
scalarMinus
{-# INLINE (-.) #-}


-- | Multiply two arrays together pointwise. Same as `!*!` but produces monadic
-- computation that allows for handling failure.
--
-- /__Throws Exception__/: `SizeMismatchException` when array sizes do not match.
--
-- @since 0.4.0
(.*.) ::
     (Load r ix e, Numeric r e, MonadThrow m) => Array r ix e -> Array r ix e -> m (Array r ix e)
.*. :: Array r ix e -> Array r ix e -> m (Array r ix e)
(.*.) = (Array r ix e -> Array r ix e -> Array r ix e)
-> Array r ix e -> Array r ix e -> m (Array r ix e)
forall r ix e (m :: * -> *).
(Load r ix e, MonadThrow m) =>
(Array r ix e -> Array r ix e -> Array r ix e)
-> Array r ix e -> Array r ix e -> m (Array r ix e)
liftNumericArray2M Array r ix e -> Array r ix e -> Array r ix e
forall r e ix.
(Numeric r e, Index ix) =>
Array r ix e -> Array r ix e -> Array r ix e
multiplicationPointwise
{-# INLINE (.*.) #-}


-- | Multiplication of two arrays pointwise,
-- i.e. <https://en.wikipedia.org/wiki/Hadamard_product_(matrices) Hadamard product>.
-- Prefer to use monadic version of this function `.*.` whenever possible,
-- because it is better to avoid partial functions.
--
-- [Partial] Mismatched array sizes will result in an impure exception being thrown.
--
-- ====__Example__
--
-- >>> let a1 = Ix1 0 ... 10
-- >>> let a2 = Ix1 20 ... 30
-- >>> a1 !*! a2
-- Array D Seq (Sz1 11)
--   [ 0, 21, 44, 69, 96, 125, 156, 189, 224, 261, 300 ]
--
-- @since 0.5.6
(!*!) :: (Load r ix e, Numeric r e) => Array r ix e -> Array r ix e -> Array r ix e
!*! :: Array r ix e -> Array r ix e -> Array r ix e
(!*!) Array r ix e
a1 Array r ix e
a2 = Either SomeException (Array r ix e) -> Array r ix e
forall a. Either SomeException a -> a
throwEither (Array r ix e
a1 Array r ix e -> Array r ix e -> Either SomeException (Array r ix e)
forall r ix e (m :: * -> *).
(Load r ix e, Numeric r e, MonadThrow m) =>
Array r ix e -> Array r ix e -> m (Array r ix e)
.*. Array r ix e
a2)
{-# INLINE (!*!) #-}


-- | Multiply each element of the array by a scalar value. Scalar is on the right.
--
-- ====__Example__
--
-- >>> let arr = Ix1 20 ..: 25
-- >>> arr
-- Array D Seq (Sz1 5)
--   [ 20, 21, 22, 23, 24 ]
-- >>> arr .* 10
-- Array D Seq (Sz1 5)
--   [ 200, 210, 220, 230, 240 ]
--
-- @since 0.4.0
(.*) :: (Index ix, Numeric r e) => Array r ix e -> e -> Array r ix e
.* :: Array r ix e -> e -> Array r ix e
(.*) = Array r ix e -> e -> Array r ix e
forall r e ix.
(Numeric r e, Index ix) =>
Array r ix e -> e -> Array r ix e
multiplyScalar
{-# INLINE (.*) #-}


-- | Multiply each element of the array by a scalar value. Scalar is on the left.
--
-- ====__Example__
--
-- >>> let arr = Ix1 20 ..: 25
-- >>> arr
-- Array D Seq (Sz1 5)
--   [ 20, 21, 22, 23, 24 ]
-- >>> 10 *. arr
-- Array D Seq (Sz1 5)
--   [ 200, 210, 220, 230, 240 ]
--
-- @since 0.4.0
(*.) :: (Index ix, Numeric r e) => e -> Array r ix e -> Array r ix e
*. :: e -> Array r ix e -> Array r ix e
(*.) = (Array r ix e -> e -> Array r ix e)
-> e -> Array r ix e -> Array r ix e
forall a b c. (a -> b -> c) -> b -> a -> c
flip Array r ix e -> e -> Array r ix e
forall r e ix.
(Numeric r e, Index ix) =>
Array r ix e -> e -> Array r ix e
multiplyScalar
{-# INLINE (*.) #-}


-- | Raise each element of the array to a power.
--
-- ====__Example__
--
-- >>> let arr = Ix1 20 ..: 25
-- >>> arr
-- Array D Seq (Sz1 5)
--   [ 20, 21, 22, 23, 24 ]
-- >>> arr .^ 3
-- Array D Seq (Sz1 5)
--   [ 8000, 9261, 10648, 12167, 13824 ]
--
-- @since 0.4.0
(.^) :: (Index ix, Numeric r e) => Array r ix e -> Int -> Array r ix e
.^ :: Array r ix e -> Int -> Array r ix e
(.^) = Array r ix e -> Int -> Array r ix e
forall r e ix.
(Numeric r e, Index ix) =>
Array r ix e -> Int -> Array r ix e
powerPointwise
{-# INLINE (.^) #-}

-- | Matrix-vector product
--
-- Inner dimensions must agree, otherwise `SizeMismatchException`
--
-- @since 0.5.2
(#>) :: (MonadThrow m, Num e, Source (R r) Ix1 e, Manifest r' Ix1 e, OuterSlice r Ix2 e) =>
        Array r Ix2 e -- ^ Matrix
     -> Array r' Ix1 e -- ^ Vector
     -> m (Array D Ix1 e)
Array r Ix2 e
mm #> :: Array r Ix2 e -> Array r' Int e -> m (Array D Int e)
#> Array r' Int e
v
  | Int
mCols Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
n = SizeException -> m (Array D Int e)
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (SizeException -> m (Array D Int e))
-> SizeException -> m (Array D Int e)
forall a b. (a -> b) -> a -> b
$ Sz Ix2 -> Sz Ix2 -> SizeException
forall ix. Index ix => Sz ix -> Sz ix -> SizeException
SizeMismatchException (Array r Ix2 e -> Sz Ix2
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Array r Ix2 e
mm) (Int -> Int -> Sz Ix2
Sz2 Int
n Int
1)
  | Bool
otherwise = Array D Int e -> m (Array D Int e)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Array D Int e -> m (Array D Int e))
-> Array D Int e -> m (Array D Int e)
forall a b. (a -> b) -> a -> b
$ Comp -> Sz Int -> (Int -> e) -> Array D Int e
forall r ix e.
Construct r ix e =>
Comp -> Sz ix -> (ix -> e) -> Array r ix e
makeArray (Array r Ix2 e -> Comp
forall r ix e. Load r ix e => Array r ix e -> Comp
getComp Array r Ix2 e
mm Comp -> Comp -> Comp
forall a. Semigroup a => a -> a -> a
<> Array r' Int e -> Comp
forall r ix e. Load r ix e => Array r ix e -> Comp
getComp Array r' Int e
v) (Int -> Sz Int
Sz1 Int
mRows) ((Int -> e) -> Array D Int e) -> (Int -> e) -> Array D Int e
forall a b. (a -> b) -> a -> b
$ \Int
i ->
      (e -> e -> e) -> e -> Array D Int e -> e
forall r ix e a.
Source r ix e =>
(a -> e -> a) -> a -> Array r ix e -> a
A.foldlS e -> e -> e
forall a. Num a => a -> a -> a
(+) e
0 ((e -> e -> e)
-> Array (R r) Int e -> Array r' Int e -> Array D Int e
forall r1 ix e1 r2 e2 e.
(Source r1 ix e1, Source r2 ix e2) =>
(e1 -> e2 -> e) -> Array r1 ix e1 -> Array r2 ix e2 -> Array D ix e
A.zipWith e -> e -> e
forall a. Num a => a -> a -> a
(*) (Array r Ix2 e -> Int -> Elt r Ix2 e
forall r ix e.
OuterSlice r ix e =>
Array r ix e -> Int -> Elt r ix e
unsafeOuterSlice Array r Ix2 e
mm Int
i) Array r' Int e
v)
  where
    Sz2 Int
mRows Int
mCols = Array r Ix2 e -> Sz Ix2
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Array r Ix2 e
mm
    Sz1 Int
n = Array r' Int e -> Sz Int
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Array r' Int e
v
{-# INLINE (#>) #-}
{-# DEPRECATED (#>) "In favor of (`.><`)" #-}


-- | Dot product of two vectors.
--
-- [Partial] Throws an impure exception when lengths of vectors do not match
--
-- @since 0.5.6
(!.!) :: (Numeric r e, Source r Ix1 e) => Vector r e -> Vector r e -> e
!.! :: Vector r e -> Vector r e -> e
(!.!) Vector r e
v1 Vector r e
v2 = Either SomeException e -> e
forall a. Either SomeException a -> a
throwEither (Either SomeException e -> e) -> Either SomeException e -> e
forall a b. (a -> b) -> a -> b
$ Vector r e -> Vector r e -> Either SomeException e
forall r e (m :: * -> *).
(Numeric r e, Source r Int e, MonadThrow m) =>
Vector r e -> Vector r e -> m e
dotM Vector r e
v1 Vector r e
v2
{-# INLINE (!.!) #-}

-- | Dot product of two vectors.
--
-- /__Throws Exception__/: `SizeMismatchException` when lengths of vectors do not match
--
-- @since 0.5.6
dotM :: (Numeric r e, Source r Ix1 e, MonadThrow m) => Vector r e -> Vector r e -> m e
dotM :: Vector r e -> Vector r e -> m e
dotM Vector r e
v1 Vector r e
v2
  | Vector r e -> Sz Int
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Vector r e
v1 Sz Int -> Sz Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Vector r e -> Sz Int
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Vector r e
v2 = SizeException -> m e
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (SizeException -> m e) -> SizeException -> m e
forall a b. (a -> b) -> a -> b
$ Sz Int -> Sz Int -> SizeException
forall ix. Index ix => Sz ix -> Sz ix -> SizeException
SizeMismatchException (Vector r e -> Sz Int
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Vector r e
v1) (Vector r e -> Sz Int
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Vector r e
v2)
  | Comp
comp Comp -> Comp -> Bool
forall a. Eq a => a -> a -> Bool
== Comp
Seq = e -> m e
forall (f :: * -> *) a. Applicative f => a -> f a
pure (e -> m e) -> e -> m e
forall a b. (a -> b) -> a -> b
$! Vector r e -> Vector r e -> e
forall r e ix.
(Numeric r e, Index ix) =>
Array r ix e -> Array r ix e -> e
unsafeDotProduct Vector r e
v1 Vector r e
v2
  | Bool
otherwise = e -> m e
forall (f :: * -> *) a. Applicative f => a -> f a
pure (e -> m e) -> e -> m e
forall a b. (a -> b) -> a -> b
$! IO e -> e
forall a. IO a -> a
unsafePerformIO (IO e -> e) -> IO e -> e
forall a b. (a -> b) -> a -> b
$ Vector r e -> Vector r e -> IO e
forall (m :: * -> *) r b ix.
(MonadUnliftIO m, Numeric r b, Source r ix b) =>
Array r ix b -> Array r ix b -> m b
unsafeDotProductIO Vector r e
v1 Vector r e
v2
  where
    comp :: Comp
comp = Vector r e -> Comp
forall r ix e. Load r ix e => Array r ix e -> Comp
getComp Vector r e
v1 Comp -> Comp -> Comp
forall a. Semigroup a => a -> a -> a
<> Vector r e -> Comp
forall r ix e. Load r ix e => Array r ix e -> Comp
getComp Vector r e
v2
{-# INLINE dotM #-}


unsafeDotProductIO ::
     (MonadUnliftIO m, Numeric r b, Source r ix b)
  => Array r ix b
  -> Array r ix b
  -> m b
unsafeDotProductIO :: Array r ix b -> Array r ix b -> m b
unsafeDotProductIO Array r ix b
v1 Array r ix b
v2 = do
  [b]
results <-
    Comp -> (Scheduler m b -> m ()) -> m [b]
forall (m :: * -> *) a b.
MonadUnliftIO m =>
Comp -> (Scheduler m a -> m b) -> m [a]
withScheduler Comp
comp ((Scheduler m b -> m ()) -> m [b])
-> (Scheduler m b -> m ()) -> m [b]
forall a b. (a -> b) -> a -> b
$ \Scheduler m b
scheduler ->
      Int -> Int -> (Int -> Int -> m ()) -> m ()
forall a. Int -> Int -> (Int -> Int -> a) -> a
splitLinearly (Scheduler m b -> Int
forall (m :: * -> *) a. Scheduler m a -> Int
numWorkers Scheduler m b
scheduler) Int
totalLength ((Int -> Int -> m ()) -> m ()) -> (Int -> Int -> m ()) -> m ()
forall a b. (a -> b) -> a -> b
$ \Int
chunkLength Int
slackStart -> do
        let n :: Sz Int
n = Int -> Sz Int
forall ix. ix -> Sz ix
SafeSz Int
chunkLength
        Int -> (Int -> Bool) -> (Int -> Int) -> (Int -> m ()) -> m ()
forall (m :: * -> *) a.
Monad m =>
Int -> (Int -> Bool) -> (Int -> Int) -> (Int -> m a) -> m ()
loopM_ Int
0 (Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
slackStart) (Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
chunkLength) ((Int -> m ()) -> m ()) -> (Int -> m ()) -> m ()
forall a b. (a -> b) -> a -> b
$ \ !Int
start ->
          Scheduler m b -> m b -> m ()
forall (m :: * -> *) a. Scheduler m a -> m a -> m ()
scheduleWork Scheduler m b
scheduler (m b -> m ()) -> m b -> m ()
forall a b. (a -> b) -> a -> b
$
          b -> m b
forall (f :: * -> *) a. Applicative f => a -> f a
pure (b -> m b) -> b -> m b
forall a b. (a -> b) -> a -> b
$! Array r Int b -> Array r Int b -> b
forall r e ix.
(Numeric r e, Index ix) =>
Array r ix e -> Array r ix e -> e
unsafeDotProduct (Int -> Sz Int -> Array r ix b -> Array r Int b
forall r ix e.
Source r ix e =>
Int -> Sz Int -> Array r ix e -> Array r Int e
unsafeLinearSlice Int
start Sz Int
n Array r ix b
v1) (Int -> Sz Int -> Array r ix b -> Array r Int b
forall r ix e.
Source r ix e =>
Int -> Sz Int -> Array r ix e -> Array r Int e
unsafeLinearSlice Int
start Sz Int
n Array r ix b
v2)
        Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
slackStart Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
totalLength) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
          let k :: Sz Int
k = Int -> Sz Int
forall ix. ix -> Sz ix
SafeSz (Int
totalLength Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
slackStart)
          Scheduler m b -> m b -> m ()
forall (m :: * -> *) a. Scheduler m a -> m a -> m ()
scheduleWork Scheduler m b
scheduler (m b -> m ()) -> m b -> m ()
forall a b. (a -> b) -> a -> b
$
            b -> m b
forall (f :: * -> *) a. Applicative f => a -> f a
pure (b -> m b) -> b -> m b
forall a b. (a -> b) -> a -> b
$!
            Array r Int b -> Array r Int b -> b
forall r e ix.
(Numeric r e, Index ix) =>
Array r ix e -> Array r ix e -> e
unsafeDotProduct (Int -> Sz Int -> Array r ix b -> Array r Int b
forall r ix e.
Source r ix e =>
Int -> Sz Int -> Array r ix e -> Array r Int e
unsafeLinearSlice Int
slackStart Sz Int
k Array r ix b
v1) (Int -> Sz Int -> Array r ix b -> Array r Int b
forall r ix e.
Source r ix e =>
Int -> Sz Int -> Array r ix e -> Array r Int e
unsafeLinearSlice Int
slackStart Sz Int
k Array r ix b
v2)
  b -> m b
forall (f :: * -> *) a. Applicative f => a -> f a
pure (b -> m b) -> b -> m b
forall a b. (a -> b) -> a -> b
$! (b -> b -> b) -> b -> [b] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
F.foldl' b -> b -> b
forall a. Num a => a -> a -> a
(+) b
0 [b]
results
  where
    totalLength :: Int
totalLength = Sz ix -> Int
forall ix. Index ix => Sz ix -> Int
totalElem (Array r ix b -> Sz ix
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Array r ix b
v1)
    comp :: Comp
comp = Array r ix b -> Comp
forall r ix e. Load r ix e => Array r ix e -> Comp
getComp Array r ix b
v1 Comp -> Comp -> Comp
forall a. Semigroup a => a -> a -> a
<> Array r ix b -> Comp
forall r ix e. Load r ix e => Array r ix e -> Comp
getComp Array r ix b
v2
{-# INLINE unsafeDotProductIO #-}


-- | Compute L2 norm of an array.
--
-- @since 0.5.6
normL2 :: (Floating e, Numeric r e, Source r ix e) => Array r ix e -> e
normL2 :: Array r ix e -> e
normL2 Array r ix e
v
  | Array r ix e -> Comp
forall r ix e. Load r ix e => Array r ix e -> Comp
getComp Array r ix e
v Comp -> Comp -> Bool
forall a. Eq a => a -> a -> Bool
== Comp
Seq = e -> e
forall a. Floating a => a -> a
sqrt (e -> e) -> e -> e
forall a b. (a -> b) -> a -> b
$! Array r ix e -> Int -> e
forall r e ix. (Numeric r e, Index ix) => Array r ix e -> Int -> e
powerSumArray Array r ix e
v Int
2
  | Bool
otherwise = e -> e
forall a. Floating a => a -> a
sqrt (e -> e) -> e -> e
forall a b. (a -> b) -> a -> b
$! IO e -> e
forall a. IO a -> a
unsafePerformIO (IO e -> e) -> IO e -> e
forall a b. (a -> b) -> a -> b
$ Array r ix e -> Int -> IO e
forall (m :: * -> *) r b ix.
(MonadUnliftIO m, Numeric r b, Source r ix b) =>
Array r ix b -> Int -> m b
powerSumArrayIO Array r ix e
v Int
2
{-# INLINE normL2 #-}

powerSumArrayIO ::
     (MonadUnliftIO m, Numeric r b, Source r ix b)
  => Array r ix b
  -> Int
  -> m b
powerSumArrayIO :: Array r ix b -> Int -> m b
powerSumArrayIO Array r ix b
v Int
p = do
  [b]
results <-
    Comp -> (Scheduler m b -> m ()) -> m [b]
forall (m :: * -> *) a b.
MonadUnliftIO m =>
Comp -> (Scheduler m a -> m b) -> m [a]
withScheduler (Array r ix b -> Comp
forall r ix e. Load r ix e => Array r ix e -> Comp
getComp Array r ix b
v) ((Scheduler m b -> m ()) -> m [b])
-> (Scheduler m b -> m ()) -> m [b]
forall a b. (a -> b) -> a -> b
$ \Scheduler m b
scheduler ->
      Int -> Int -> (Int -> Int -> m ()) -> m ()
forall a. Int -> Int -> (Int -> Int -> a) -> a
splitLinearly (Scheduler m b -> Int
forall (m :: * -> *) a. Scheduler m a -> Int
numWorkers Scheduler m b
scheduler) Int
totalLength ((Int -> Int -> m ()) -> m ()) -> (Int -> Int -> m ()) -> m ()
forall a b. (a -> b) -> a -> b
$ \Int
chunkLength Int
slackStart -> do
        let n :: Sz Int
n = Int -> Sz Int
forall ix. ix -> Sz ix
SafeSz Int
chunkLength
        Int -> (Int -> Bool) -> (Int -> Int) -> (Int -> m ()) -> m ()
forall (m :: * -> *) a.
Monad m =>
Int -> (Int -> Bool) -> (Int -> Int) -> (Int -> m a) -> m ()
loopM_ Int
0 (Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
slackStart) (Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
chunkLength) ((Int -> m ()) -> m ()) -> (Int -> m ()) -> m ()
forall a b. (a -> b) -> a -> b
$ \ !Int
start ->
          Scheduler m b -> m b -> m ()
forall (m :: * -> *) a. Scheduler m a -> m a -> m ()
scheduleWork Scheduler m b
scheduler (m b -> m ()) -> m b -> m ()
forall a b. (a -> b) -> a -> b
$ b -> m b
forall (f :: * -> *) a. Applicative f => a -> f a
pure (b -> m b) -> b -> m b
forall a b. (a -> b) -> a -> b
$! Array r Int b -> Int -> b
forall r e ix. (Numeric r e, Index ix) => Array r ix e -> Int -> e
powerSumArray (Int -> Sz Int -> Array r ix b -> Array r Int b
forall r ix e.
Source r ix e =>
Int -> Sz Int -> Array r ix e -> Array r Int e
unsafeLinearSlice Int
start Sz Int
n Array r ix b
v) Int
p
        Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
slackStart Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
totalLength) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
          let k :: Sz Int
k = Int -> Sz Int
forall ix. ix -> Sz ix
SafeSz (Int
totalLength Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
slackStart)
          Scheduler m b -> m b -> m ()
forall (m :: * -> *) a. Scheduler m a -> m a -> m ()
scheduleWork Scheduler m b
scheduler (m b -> m ()) -> m b -> m ()
forall a b. (a -> b) -> a -> b
$ b -> m b
forall (f :: * -> *) a. Applicative f => a -> f a
pure (b -> m b) -> b -> m b
forall a b. (a -> b) -> a -> b
$! Array r Int b -> Int -> b
forall r e ix. (Numeric r e, Index ix) => Array r ix e -> Int -> e
powerSumArray (Int -> Sz Int -> Array r ix b -> Array r Int b
forall r ix e.
Source r ix e =>
Int -> Sz Int -> Array r ix e -> Array r Int e
unsafeLinearSlice Int
slackStart Sz Int
k Array r ix b
v) Int
p
  b -> m b
forall (f :: * -> *) a. Applicative f => a -> f a
pure (b -> m b) -> b -> m b
forall a b. (a -> b) -> a -> b
$! (b -> b -> b) -> b -> [b] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
F.foldl' b -> b -> b
forall a. Num a => a -> a -> a
(+) b
0 [b]
results
  where
    totalLength :: Int
totalLength = Sz ix -> Int
forall ix. Index ix => Sz ix -> Int
totalElem (Array r ix b -> Sz ix
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Array r ix b
v)
{-# INLINE powerSumArrayIO #-}


-- | Multiply a matrix by a column vector. Same as `!><` but produces monadic
-- computation that allows for handling failure.
--
-- /__Throws Exception__/: `SizeMismatchException` when inner dimensions of arrays do not match.
--
-- @since 0.5.6
(.><) ::
     (MonadThrow m, Numeric r e, Source r Ix1 e, Source r Ix2 e)
  => Matrix r e -- ^ Matrix
  -> Vector r e -- ^ Column vector (Used many times, so make sure it is computed)
  -> m (Vector D e)
.>< :: Matrix r e -> Vector r e -> m (Vector D e)
(.><) Matrix r e
mm Vector r e
v
  | Int
mCols Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
n = SizeException -> m (Vector D e)
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (SizeException -> m (Vector D e))
-> SizeException -> m (Vector D e)
forall a b. (a -> b) -> a -> b
$ Sz Ix2 -> Sz Ix2 -> SizeException
forall ix. Index ix => Sz ix -> Sz ix -> SizeException
SizeMismatchException (Matrix r e -> Sz Ix2
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Matrix r e
mm) (Int -> Int -> Sz Ix2
Sz2 Int
n Int
1)
  | Bool
otherwise = Vector D e -> m (Vector D e)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Vector D e -> m (Vector D e)) -> Vector D e -> m (Vector D e)
forall a b. (a -> b) -> a -> b
$ Comp -> Sz Int -> (Int -> e) -> Vector D e
forall r ix e.
Construct r ix e =>
Comp -> Sz ix -> (ix -> e) -> Array r ix e
makeArray (Matrix r e -> Comp
forall r ix e. Load r ix e => Array r ix e -> Comp
getComp Matrix r e
mm Comp -> Comp -> Comp
forall a. Semigroup a => a -> a -> a
<> Vector r e -> Comp
forall r ix e. Load r ix e => Array r ix e -> Comp
getComp Vector r e
v) (Int -> Sz Int
Sz1 Int
mRows) ((Int -> e) -> Vector D e) -> (Int -> e) -> Vector D e
forall a b. (a -> b) -> a -> b
$ \Int
i ->
      Vector r e -> Vector r e -> e
forall r e ix.
(Numeric r e, Index ix) =>
Array r ix e -> Array r ix e -> e
unsafeDotProduct (Int -> Sz Int -> Matrix r e -> Vector r e
forall r ix e.
Source r ix e =>
Int -> Sz Int -> Array r ix e -> Array r Int e
unsafeLinearSlice (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
n) Sz Int
sz Matrix r e
mm) Vector r e
v
  where
    Sz2 Int
mRows Int
mCols = Matrix r e -> Sz Ix2
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Matrix r e
mm
    sz :: Sz Int
sz@(Sz1 Int
n) = Vector r e -> Sz Int
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Vector r e
v
{-# INLINE (.><) #-}

-- | Multiply matrix by a column vector. Same as `.><` but returns computed version of a vector
--
-- /__Throws Exception__/: `SizeMismatchException` when inner dimensions of arrays do not match.
--
-- @since 0.5.7
multiplyMatrixByVector ::
     (MonadThrow m, Numeric r e, Mutable r Ix1 e, Mutable r Ix2 e)
  => Matrix r e -- ^ Matrix
  -> Vector r e -- ^ Column vector (Used many times, so make sure it is computed)
  -> m (Vector r e)
multiplyMatrixByVector :: Matrix r e -> Vector r e -> m (Vector r e)
multiplyMatrixByVector Matrix r e
mm Vector r e
v = Array D Int e -> Vector r e
forall r ix e r'.
(Mutable r ix e, Load r' ix e) =>
Array r' ix e -> Array r ix e
compute (Array D Int e -> Vector r e)
-> m (Array D Int e) -> m (Vector r e)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Matrix r e
mm Matrix r e -> Vector r e -> m (Array D Int e)
forall (m :: * -> *) r e.
(MonadThrow m, Numeric r e, Source r Int e, Source r Ix2 e) =>
Matrix r e -> Vector r e -> m (Vector D e)
.>< Vector r e
v
{-# INLINE multiplyMatrixByVector #-}


-- | Multiply a matrix by a column vector
--
-- [Partial] Throws impure exception when inner dimensions do not agree
--
-- @since 0.5.6
(!><) ::
     (Numeric r e, Source r Ix1 e, Source r Ix2 e)
  => Matrix r e -- ^ Matrix
  -> Vector r e -- ^ Column vector (Used many times, so make sure it is computed)
  -> Vector D e
!>< :: Matrix r e -> Vector r e -> Vector D e
(!><) Matrix r e
mm Vector r e
v = Either SomeException (Vector D e) -> Vector D e
forall a. Either SomeException a -> a
throwEither (Matrix r e
mm Matrix r e -> Vector r e -> Either SomeException (Vector D e)
forall (m :: * -> *) r e.
(MonadThrow m, Numeric r e, Source r Int e, Source r Ix2 e) =>
Matrix r e -> Vector r e -> m (Vector D e)
.>< Vector r e
v)
{-# INLINE (!><) #-}


-- | Multiply a row vector by a matrix. Same as `><!` but produces monadic computation
-- that allows for handling failure.
--
-- /__Throws Exception__/: `SizeMismatchException` when inner dimensions of arrays do not match.
--
-- @since 0.5.6
(><.) :: (MonadThrow m, Numeric r e, Mutable r Ix1 e, Mutable r Ix2 e) =>
         Vector r e -- ^ Row vector
      -> Matrix r e -- ^ Matrix
      -> m (Vector D e)
><. :: Vector r e -> Matrix r e -> m (Vector D e)
(><.) Vector r e
v Matrix r e
mm = Vector r e -> Vector D e
forall r ix e. Source r ix e => Array r ix e -> Array D ix e
delay (Vector r e -> Vector D e) -> m (Vector r e) -> m (Vector D e)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Vector r e -> Matrix r e -> m (Vector r e)
forall (m :: * -> *) r e.
(MonadThrow m, Numeric r e, Mutable r Int e, Mutable r Ix2 e) =>
Vector r e -> Matrix r e -> m (Vector r e)
multiplyVectorByMatrix Vector r e
v Matrix r e
mm
{-# INLINE (><.) #-}

-- | Multiply a row vector by a matrix. Same as `><.` but returns computed vector instead of
-- a delayed one.
--
-- /__Throws Exception__/: `SizeMismatchException` when inner dimensions of arrays do not match.
--
-- @since 0.5.7
multiplyVectorByMatrix ::
     (MonadThrow m, Numeric r e, Mutable r Ix1 e, Mutable r Ix2 e)
  => Vector r e -- ^ Row vector
  -> Matrix r e -- ^ Matrix
  -> m (Vector r e)
multiplyVectorByMatrix :: Vector r e -> Matrix r e -> m (Vector r e)
multiplyVectorByMatrix Vector r e
v Matrix r e
mm
  | Int
mRows Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
n = SizeException -> m (Vector r e)
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (SizeException -> m (Vector r e))
-> SizeException -> m (Vector r e)
forall a b. (a -> b) -> a -> b
$ Sz Ix2 -> Sz Ix2 -> SizeException
forall ix. Index ix => Sz ix -> Sz ix -> SizeException
SizeMismatchException (Int -> Int -> Sz Ix2
Sz2 Int
1 Int
n) (Matrix r e -> Sz Ix2
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Matrix r e
mm)
  | Bool
otherwise =
    Vector r e -> m (Vector r e)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Vector r e -> m (Vector r e)) -> Vector r e -> m (Vector r e)
forall a b. (a -> b) -> a -> b
$!
    IO (Vector r e) -> Vector r e
forall a. IO a -> a
unsafePerformIO (IO (Vector r e) -> Vector r e) -> IO (Vector r e) -> Vector r e
forall a b. (a -> b) -> a -> b
$ do
      MArray RealWorld r Int e
mv <- Sz Int -> IO (MArray (PrimState IO) r Int e)
forall r ix e (m :: * -> *).
(Mutable r ix e, PrimMonad m) =>
Sz ix -> m (MArray (PrimState m) r ix e)
new (Int -> Sz Int
forall ix. Index ix => ix -> Sz ix
Sz Int
mCols)
      Comp -> (Scheduler IO () -> IO ()) -> IO ()
withMassivScheduler_ Comp
comp ((Scheduler IO () -> IO ()) -> IO ())
-> (Scheduler IO () -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Scheduler IO ()
scheduler -> do
        let loopCols :: e -> Int -> Int -> Int -> IO ()
loopCols e
x Int
ivto =
              ((Int -> Int -> IO ()) -> Int -> Int -> IO ())
-> Int -> Int -> IO ()
forall a. (a -> a) -> a
fix (((Int -> Int -> IO ()) -> Int -> Int -> IO ())
 -> Int -> Int -> IO ())
-> ((Int -> Int -> IO ()) -> Int -> Int -> IO ())
-> Int
-> Int
-> IO ()
forall a b. (a -> b) -> a -> b
$ \Int -> Int -> IO ()
go Int
im Int
iv ->
                Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
iv Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
ivto) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
                  e
_ <- MArray (PrimState IO) r Int e -> (e -> IO e) -> Int -> IO e
forall r ix e (m :: * -> *).
(Mutable r ix e, PrimMonad m) =>
MArray (PrimState m) r ix e -> (e -> m e) -> Int -> m e
unsafeLinearModify MArray RealWorld r Int e
MArray (PrimState IO) r Int e
mv (\e
a -> e -> IO e
forall (f :: * -> *) a. Applicative f => a -> f a
pure (e -> IO e) -> e -> IO e
forall a b. (a -> b) -> a -> b
$ e
a e -> e -> e
forall a. Num a => a -> a -> a
+ Matrix r e -> Int -> e
forall r ix e. Source r ix e => Array r ix e -> Int -> e
unsafeLinearIndex Matrix r e
mm Int
im e -> e -> e
forall a. Num a => a -> a -> a
* e
x) Int
iv
                  Int -> Int -> IO ()
go (Int
im Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (Int
iv Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
            loopRows :: Int -> Int -> Int -> IO ()
loopRows Int
i0 Int
from Int
to =
              (((Int -> IO ()) -> Int -> IO ()) -> Int -> IO ())
-> Int -> ((Int -> IO ()) -> Int -> IO ()) -> IO ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((Int -> IO ()) -> Int -> IO ()) -> Int -> IO ()
forall a. (a -> a) -> a
fix Int
i0 (((Int -> IO ()) -> Int -> IO ()) -> IO ())
-> ((Int -> IO ()) -> Int -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Int -> IO ()
go Int
i ->
                Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
mRows) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
                  e -> Int -> Int -> Int -> IO ()
loopCols (Vector r e -> Int -> e
forall r ix e. Source r ix e => Array r ix e -> Int -> e
unsafeLinearIndex Vector r e
v Int
i) Int
to (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
mCols Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
from) Int
from
                  Int -> IO ()
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
        Scheduler IO () -> Int -> (Int -> Int -> IO ()) -> IO ()
forall (m :: * -> *).
Monad m =>
Scheduler m () -> Int -> (Int -> Int -> m ()) -> m ()
splitLinearlyM_ Scheduler IO ()
scheduler Int
mCols (Int -> Int -> Int -> IO ()
loopRows Int
0)
      Comp -> MArray (PrimState IO) r Int e -> IO (Vector r e)
forall r ix e (m :: * -> *).
(Mutable r ix e, PrimMonad m) =>
Comp -> MArray (PrimState m) r ix e -> m (Array r ix e)
unsafeFreeze Comp
comp MArray RealWorld r Int e
MArray (PrimState IO) r Int e
mv
  where
    comp :: Comp
comp = Matrix r e -> Comp
forall r ix e. Load r ix e => Array r ix e -> Comp
getComp Matrix r e
mm Comp -> Comp -> Comp
forall a. Semigroup a => a -> a -> a
<> Vector r e -> Comp
forall r ix e. Load r ix e => Array r ix e -> Comp
getComp Vector r e
v
    Sz2 Int
mRows Int
mCols = Matrix r e -> Sz Ix2
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Matrix r e
mm
    Sz1 Int
n = Vector r e -> Sz Int
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Vector r e
v
{-# INLINE multiplyVectorByMatrix #-}


-- | Multiply a row vector by a matrix.
--
-- [Partial] Throws impure exception when inner dimensions do not agree
--
-- @since 0.5.6
(><!) ::
     (Numeric r e, Mutable r Ix1 e, Mutable r Ix2 e)
  => Vector r e -- ^ Row vector (Used many times, so make sure it is computed)
  -> Matrix r e -- ^ Matrix
  -> Vector D e
><! :: Vector r e -> Matrix r e -> Vector D e
(><!) Vector r e
v Matrix r e
mm = Either SomeException (Vector D e) -> Vector D e
forall a. Either SomeException a -> a
throwEither (Vector r e
v Vector r e -> Matrix r e -> Either SomeException (Vector D e)
forall (m :: * -> *) r e.
(MonadThrow m, Numeric r e, Mutable r Int e, Mutable r Ix2 e) =>
Vector r e -> Matrix r e -> m (Vector D e)
><. Matrix r e
mm)
{-# INLINE (><!) #-}



-- | Multiply two matrices together.
--
-- [Partial] Inner dimension must agree
--
-- ====__Examples__
--
-- >>> a1 = makeArrayR P Seq (Sz2 5 6) $ \(i :. j) -> i + j
-- >>> a2 = makeArrayR D Seq (Sz2 6 5) $ \(i :. j) -> i - j
-- >>> a1 !><! a2
-- Array D Seq (Sz (5 :. 5))
--   [ [ 55, 40, 25, 10, -5 ]
--   , [ 70, 49, 28, 7, -14 ]
--   , [ 85, 58, 31, 4, -23 ]
--   , [ 100, 67, 34, 1, -32 ]
--   , [ 115, 76, 37, -2, -41 ]
--   ]
--
-- @since 0.5.6
(!><!) :: (Numeric r e, Mutable r Ix2 e, Source r' Ix2 e) => Matrix r e -> Matrix r' e -> Matrix D e
!><! :: Matrix r e -> Matrix r' e -> Matrix D e
(!><!) Matrix r e
a1 Matrix r' e
a2 = Either SomeException (Matrix D e) -> Matrix D e
forall a. Either SomeException a -> a
throwEither (Matrix r e
a1 Matrix r e -> Matrix r' e -> Either SomeException (Matrix D e)
forall r r' e (m :: * -> *).
(Numeric r e, Mutable r Ix2 e, Source r' Ix2 e, MonadThrow m) =>
Matrix r e -> Matrix r' e -> m (Matrix D e)
`multiplyMatrices` Matrix r' e
a2)
{-# INLINE (!><!) #-}

-- | Matrix multiplication. Same as `!><!` but produces monadic computation that allows
-- for handling failure.
--
-- /__Throws Exception__/: `SizeMismatchException` when inner dimensions of arrays do not match.
--
-- @since 0.5.6
(.><.) ::
     (Numeric r e, Mutable r Ix2 e, Source r' Ix2 e, MonadThrow m)
  => Matrix r e
  -> Matrix r' e
  -> m (Matrix D e)
.><. :: Matrix r e -> Matrix r' e -> m (Matrix D e)
(.><.) = Matrix r e -> Matrix r' e -> m (Matrix D e)
forall r r' e (m :: * -> *).
(Numeric r e, Mutable r Ix2 e, Source r' Ix2 e, MonadThrow m) =>
Matrix r e -> Matrix r' e -> m (Matrix D e)
multiplyMatrices
{-# INLINE (.><.) #-}


-- | Synonym for `.><.`
--
-- @since 0.5.6
multiplyMatrices ::
     forall r r' e m. (Numeric r e, Mutable r Ix2 e, Source r' Ix2 e, MonadThrow m)
  => Matrix r e
  -> Matrix r' e
  -> m (Matrix D e)
multiplyMatrices :: Matrix r e -> Matrix r' e -> m (Matrix D e)
multiplyMatrices Matrix r e
arr1 Matrix r' e
arr2 = Matrix r e -> Matrix r e -> m (Matrix D e)
forall r e (m :: * -> *).
(Numeric r e, Manifest r Ix2 e, MonadThrow m) =>
Matrix r e -> Matrix r e -> m (Matrix D e)
multiplyMatricesTransposed Matrix r e
arr1 Matrix r e
arr2'
  where
    arr2' :: Array r Ix2 e
    arr2' :: Matrix r e
arr2' = Matrix D e -> Matrix r e
forall r ix e r'.
(Mutable r ix e, Load r' ix e) =>
Array r' ix e -> Array r ix e
compute (Matrix D e -> Matrix r e) -> Matrix D e -> Matrix r e
forall a b. (a -> b) -> a -> b
$ Matrix r' e -> Matrix D e
forall r e. Source r Ix2 e => Array r Ix2 e -> Array D Ix2 e
transpose Matrix r' e
arr2
{-# INLINE [1] multiplyMatrices #-}

{-# RULES
"multiplyMatricesTransposed" [~1] forall arr1 arr2 . multiplyMatrices arr1 (transpose arr2) =
    multiplyMatricesTransposedFused arr1 (convert arr2)
 #-}

-- | Computes the matrix-matrix multiplication where second matrix is transposed (i.e. M
-- x N')
--
-- > m1 .><. transpose m2 == multiplyMatricesTransposed m1 m2
--
-- @since 0.5.6
multiplyMatricesTransposed ::
     (Numeric r e, Manifest r Ix2 e, MonadThrow m)
  => Matrix r e
  -> Matrix r  e
  -> m (Matrix D e)
multiplyMatricesTransposed :: Matrix r e -> Matrix r e -> m (Matrix D e)
multiplyMatricesTransposed Matrix r e
arr1 Matrix r e
arr2
  | Int
n1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
m2 = SizeException -> m (Matrix D e)
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (SizeException -> m (Matrix D e))
-> SizeException -> m (Matrix D e)
forall a b. (a -> b) -> a -> b
$ Sz Ix2 -> Sz Ix2 -> SizeException
forall ix. Index ix => Sz ix -> Sz ix -> SizeException
SizeMismatchException (Matrix r e -> Sz Ix2
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Matrix r e
arr1) (Int -> Int -> Sz Ix2
Sz2 Int
m2 Int
n2)
  | Bool
otherwise =
    Matrix D e -> m (Matrix D e)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Matrix D e -> m (Matrix D e)) -> Matrix D e -> m (Matrix D e)
forall a b. (a -> b) -> a -> b
$
    Comp -> Sz Ix2 -> (Ix2 -> e) -> Matrix D e
forall ix e. Comp -> Sz ix -> (ix -> e) -> Array D ix e
DArray (Matrix r e -> Comp
forall r ix e. Load r ix e => Array r ix e -> Comp
getComp Matrix r e
arr1 Comp -> Comp -> Comp
forall a. Semigroup a => a -> a -> a
<> Matrix r e -> Comp
forall r ix e. Load r ix e => Array r ix e -> Comp
getComp Matrix r e
arr2) (Ix2 -> Sz Ix2
forall ix. ix -> Sz ix
SafeSz (Int
m1 Int -> Int -> Ix2
:. Int
n2)) ((Ix2 -> e) -> Matrix D e) -> (Ix2 -> e) -> Matrix D e
forall a b. (a -> b) -> a -> b
$ \(Int
i :. Int
j) ->
      Array r Int e -> Array r Int e -> e
forall r e ix.
(Numeric r e, Index ix) =>
Array r ix e -> Array r ix e -> e
unsafeDotProduct (Int -> Sz Int -> Matrix r e -> Array r Int e
forall r ix e.
Source r ix e =>
Int -> Sz Int -> Array r ix e -> Array r Int e
unsafeLinearSlice (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
n1) Sz Int
n Matrix r e
arr1) (Int -> Sz Int -> Matrix r e -> Array r Int e
forall r ix e.
Source r ix e =>
Int -> Sz Int -> Array r ix e -> Array r Int e
unsafeLinearSlice (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
n1) Sz Int
n Matrix r e
arr2)
  where
    n :: Sz Int
n = Int -> Sz Int
forall ix. ix -> Sz ix
SafeSz Int
n1
    SafeSz (Int
m1 :. Int
n1) = Matrix r e -> Sz Ix2
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Matrix r e
arr1
    SafeSz (Int
n2 :. Int
m2) = Matrix r e -> Sz Ix2
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Matrix r e
arr2
{-# INLINE multiplyMatricesTransposed #-}

multiplyMatricesTransposedFused ::
     (Manifest r Ix2 e, Numeric r e, MonadThrow m) => Matrix r e -> Matrix r e -> m (Matrix D e)
multiplyMatricesTransposedFused :: Matrix r e -> Matrix r e -> m (Matrix D e)
multiplyMatricesTransposedFused Matrix r e
arr1 Matrix r e
arr2 = Matrix r e -> Matrix r e -> m (Matrix D e)
forall r e (m :: * -> *).
(Numeric r e, Manifest r Ix2 e, MonadThrow m) =>
Matrix r e -> Matrix r e -> m (Matrix D e)
multiplyMatricesTransposed Matrix r e
arr1 Matrix r e
arr2
{-# INLINE multiplyMatricesTransposedFused #-}



--- Below is outdated

-- | Matrix multiplication
--
-- /__Throws Exception__/: `SizeMismatchException` when inner dimensions of arrays do not match.
--
-- @since 0.4.0
(|*|) ::
     (Mutable r Ix2 e, Source r' Ix2 e, OuterSlice r Ix2 e, Source (R r) Ix1 e, Num e, MonadThrow m)
  => Array r Ix2 e
  -> Array r' Ix2 e
  -> m (Array r Ix2 e)
|*| :: Array r Ix2 e -> Array r' Ix2 e -> m (Array r Ix2 e)
(|*|) Array r Ix2 e
a1 Array r' Ix2 e
a2 = Array D Ix2 e -> Array r Ix2 e
forall r ix e r'.
(Mutable r ix e, Load r' ix e) =>
Array r' ix e -> Array r ix e
compute (Array D Ix2 e -> Array r Ix2 e)
-> m (Array D Ix2 e) -> m (Array r Ix2 e)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Array r Ix2 e -> Array r' Ix2 e -> m (Array D Ix2 e)
forall r r' e (m :: * -> *).
(Mutable r Ix2 e, Source r' Ix2 e, OuterSlice r Ix2 e,
 Source (R r) Int e, Num e, MonadThrow m) =>
Array r Ix2 e -> Array r' Ix2 e -> m (Array D Ix2 e)
multArrs Array r Ix2 e
a1 Array r' Ix2 e
a2
{-# INLINE [1] (|*|) #-}
{-# DEPRECATED (|*|) "In favor of `.><.`" #-}

{-# RULES
"multDoubleTranspose" [~1] forall arr1 arr2 . arr1 |*| transpose arr2 =
    multiplyTransposedFused arr1 (convert arr2)
 #-}


multiplyTransposedFused ::
     ( Mutable r Ix2 e
     , OuterSlice r Ix2 e
     , Source (R r) Ix1 e
     , Num e
     , MonadThrow m
     )
  => Array r Ix2 e
  -> Array r Ix2 e
  -> m (Array r Ix2 e)
multiplyTransposedFused :: Array r Ix2 e -> Array r Ix2 e -> m (Array r Ix2 e)
multiplyTransposedFused Array r Ix2 e
arr1 Array r Ix2 e
arr2 = Array D Ix2 e -> Array r Ix2 e
forall r ix e r'.
(Mutable r ix e, Load r' ix e) =>
Array r' ix e -> Array r ix e
compute (Array D Ix2 e -> Array r Ix2 e)
-> m (Array D Ix2 e) -> m (Array r Ix2 e)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Array r Ix2 e -> Array r Ix2 e -> m (Array D Ix2 e)
forall r e (m :: * -> *).
(Manifest r Ix2 e, OuterSlice r Ix2 e, Source (R r) Int e, Num e,
 MonadThrow m) =>
Array r Ix2 e -> Array r Ix2 e -> m (Array D Ix2 e)
multiplyTransposed Array r Ix2 e
arr1 Array r Ix2 e
arr2
{-# INLINE multiplyTransposedFused #-}


multArrs :: forall r r' e m.
            ( Mutable r Ix2 e
            , Source r' Ix2 e
            , OuterSlice r Ix2 e
            , Source (R r) Ix1 e
            , Num e
            , MonadThrow m
            )
         => Array r Ix2 e -> Array r' Ix2 e -> m (Array D Ix2 e)
multArrs :: Array r Ix2 e -> Array r' Ix2 e -> m (Array D Ix2 e)
multArrs Array r Ix2 e
arr1 Array r' Ix2 e
arr2 = Array r Ix2 e -> Array r Ix2 e -> m (Array D Ix2 e)
forall r e (m :: * -> *).
(Manifest r Ix2 e, OuterSlice r Ix2 e, Source (R r) Int e, Num e,
 MonadThrow m) =>
Array r Ix2 e -> Array r Ix2 e -> m (Array D Ix2 e)
multiplyTransposed Array r Ix2 e
arr1 Array r Ix2 e
arr2'
  where
    arr2' :: Array r Ix2 e
    arr2' :: Array r Ix2 e
arr2' = Array D Ix2 e -> Array r Ix2 e
forall r ix e r'.
(Mutable r ix e, Load r' ix e) =>
Array r' ix e -> Array r ix e
compute (Array D Ix2 e -> Array r Ix2 e) -> Array D Ix2 e -> Array r Ix2 e
forall a b. (a -> b) -> a -> b
$ Array r' Ix2 e -> Array D Ix2 e
forall r e. Source r Ix2 e => Array r Ix2 e -> Array D Ix2 e
transpose Array r' Ix2 e
arr2
{-# INLINE multArrs #-}

-- | Computes the matrix-matrix transposed product (i.e. A * A')
multiplyTransposed ::
     ( Manifest r Ix2 e
     , OuterSlice r Ix2 e
     , Source (R r) Ix1 e
     , Num e
     , MonadThrow m
     )
  => Array r Ix2 e
  -> Array r Ix2 e
  -> m (Array D Ix2 e)
multiplyTransposed :: Array r Ix2 e -> Array r Ix2 e -> m (Array D Ix2 e)
multiplyTransposed Array r Ix2 e
arr1 Array r Ix2 e
arr2
  | Int
n1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
m2 = SizeException -> m (Array D Ix2 e)
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (SizeException -> m (Array D Ix2 e))
-> SizeException -> m (Array D Ix2 e)
forall a b. (a -> b) -> a -> b
$ Sz Ix2 -> Sz Ix2 -> SizeException
forall ix. Index ix => Sz ix -> Sz ix -> SizeException
SizeMismatchException (Array r Ix2 e -> Sz Ix2
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Array r Ix2 e
arr1) (Array r Ix2 e -> Sz Ix2
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Array r Ix2 e
arr2)
  | Bool
otherwise =
    Array D Ix2 e -> m (Array D Ix2 e)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Array D Ix2 e -> m (Array D Ix2 e))
-> Array D Ix2 e -> m (Array D Ix2 e)
forall a b. (a -> b) -> a -> b
$
    Comp -> Sz Ix2 -> (Ix2 -> e) -> Array D Ix2 e
forall ix e. Comp -> Sz ix -> (ix -> e) -> Array D ix e
DArray (Array r Ix2 e -> Comp
forall r ix e. Load r ix e => Array r ix e -> Comp
getComp Array r Ix2 e
arr1 Comp -> Comp -> Comp
forall a. Semigroup a => a -> a -> a
<> Array r Ix2 e -> Comp
forall r ix e. Load r ix e => Array r ix e -> Comp
getComp Array r Ix2 e
arr2) (Ix2 -> Sz Ix2
forall ix. ix -> Sz ix
SafeSz (Int
m1 Int -> Int -> Ix2
:. Int
n2)) ((Ix2 -> e) -> Array D Ix2 e) -> (Ix2 -> e) -> Array D Ix2 e
forall a b. (a -> b) -> a -> b
$ \(Int
i :. Int
j) ->
      (e -> e -> e) -> e -> Array D Int e -> e
forall r ix e a.
Source r ix e =>
(a -> e -> a) -> a -> Array r ix e -> a
A.foldlS e -> e -> e
forall a. Num a => a -> a -> a
(+) e
0 ((e -> e -> e)
-> Array (R r) Int e -> Array (R r) Int e -> Array D Int e
forall r1 ix e1 r2 e2 e.
(Source r1 ix e1, Source r2 ix e2) =>
(e1 -> e2 -> e) -> Array r1 ix e1 -> Array r2 ix e2 -> Array D ix e
A.zipWith e -> e -> e
forall a. Num a => a -> a -> a
(*) (Array r Ix2 e -> Int -> Elt r Ix2 e
forall r ix e.
OuterSlice r ix e =>
Array r ix e -> Int -> Elt r ix e
unsafeOuterSlice Array r Ix2 e
arr1 Int
i) (Array r Ix2 e -> Int -> Elt r Ix2 e
forall r ix e.
OuterSlice r ix e =>
Array r ix e -> Int -> Elt r ix e
unsafeOuterSlice Array r Ix2 e
arr2 Int
j))
  where
    SafeSz (Int
m1 :. Int
n1) = Array r Ix2 e -> Sz Ix2
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Array r Ix2 e
arr1
    SafeSz (Int
n2 :. Int
m2) = Array r Ix2 e -> Sz Ix2
forall r ix e. Load r ix e => Array r ix e -> Sz ix
size Array r Ix2 e
arr2
{-# INLINE multiplyTransposed #-}

-- | Create an indentity matrix.
--
-- ==== __Example__
--
-- >>> import Data.Massiv.Array
-- >>> identityMatrix 5
-- Array DL Seq (Sz (5 :. 5))
--   [ [ 1, 0, 0, 0, 0 ]
--   , [ 0, 1, 0, 0, 0 ]
--   , [ 0, 0, 1, 0, 0 ]
--   , [ 0, 0, 0, 1, 0 ]
--   , [ 0, 0, 0, 0, 1 ]
--   ]
--
-- @since 0.3.6
identityMatrix :: Num e => Sz1 -> Matrix DL e
identityMatrix :: Sz Int -> Matrix DL e
identityMatrix (Sz Int
n) =
  Sz Ix2
-> e
-> (forall (m :: * -> *). Monad m => (Ix2 -> e -> m Bool) -> m ())
-> Matrix DL e
forall ix e.
Index ix =>
Sz ix
-> e
-> (forall (m :: * -> *). Monad m => (ix -> e -> m Bool) -> m ())
-> Array DL ix e
makeLoadArrayS (Int -> Int -> Sz Ix2
Sz2 Int
n Int
n) e
0 ((forall (m :: * -> *). Monad m => (Ix2 -> e -> m Bool) -> m ())
 -> Matrix DL e)
-> (forall (m :: * -> *). Monad m => (Ix2 -> e -> m Bool) -> m ())
-> Matrix DL e
forall a b. (a -> b) -> a -> b
$ \ Ix2 -> e -> m Bool
w -> Int -> (Int -> Bool) -> (Int -> Int) -> (Int -> m Bool) -> m ()
forall (m :: * -> *) a.
Monad m =>
Int -> (Int -> Bool) -> (Int -> Int) -> (Int -> m a) -> m ()
loopM_ Int
0 (Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
n) (Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) ((Int -> m Bool) -> m ()) -> (Int -> m Bool) -> m ()
forall a b. (a -> b) -> a -> b
$ \ Int
i -> Ix2 -> e -> m Bool
w (Int
i Int -> Int -> Ix2
:. Int
i) e
1
{-# INLINE identityMatrix #-}

-- | Create a lower triangular (L in LU decomposition) matrix of size @NxN@
--
-- ==== __Example__
--
-- >>> import Data.Massiv.Array
-- >>> lowerTriangular Seq 5 (\(i :. j) -> i + j)
-- Array DL Seq (Sz (5 :. 5))
--   [ [ 0, 0, 0, 0, 0 ]
--   , [ 1, 2, 0, 0, 0 ]
--   , [ 2, 3, 4, 0, 0 ]
--   , [ 3, 4, 5, 6, 0 ]
--   , [ 4, 5, 6, 7, 8 ]
--   ]
--
-- @since 0.5.2
lowerTriangular :: Num e => Comp -> Sz1 -> (Ix2 -> e) -> Matrix DL e
lowerTriangular :: Comp -> Sz Int -> (Ix2 -> e) -> Matrix DL e
lowerTriangular Comp
comp (Sz1 Int
n) Ix2 -> e
f =
  let sz :: Sz Ix2
sz = Int -> Int -> Sz Ix2
Sz2 Int
n Int
n
   in Comp
-> Sz Ix2
-> Maybe e
-> (forall (m :: * -> *).
    Monad m =>
    Scheduler m () -> (Int -> e -> m ()) -> m ())
-> Matrix DL e
forall ix e.
Index ix =>
Comp
-> Sz ix
-> Maybe e
-> (forall (m :: * -> *).
    Monad m =>
    Scheduler m () -> (Int -> e -> m ()) -> m ())
-> Array DL ix e
unsafeMakeLoadArrayAdjusted Comp
comp Sz Ix2
sz (e -> Maybe e
forall a. a -> Maybe a
Just e
0) ((forall (m :: * -> *).
  Monad m =>
  Scheduler m () -> (Int -> e -> m ()) -> m ())
 -> Matrix DL e)
-> (forall (m :: * -> *).
    Monad m =>
    Scheduler m () -> (Int -> e -> m ()) -> m ())
-> Matrix DL e
forall a b. (a -> b) -> a -> b
$ \Scheduler m ()
scheduler Int -> e -> m ()
wr ->
        Array D Int Int -> (Int -> m ()) -> m ()
forall r ix a (m :: * -> *) b.
(Source r ix a, Monad m) =>
Array r ix a -> (a -> m b) -> m ()
forM_ (Int
0 Int -> Int -> Array D Int Int
forall ix. Index ix => ix -> ix -> Array D ix ix
..: Int
n) ((Int -> m ()) -> m ()) -> (Int -> m ()) -> m ()
forall a b. (a -> b) -> a -> b
$ \Int
i ->
          Scheduler m () -> m () -> m ()
forall (m :: * -> *) a. Scheduler m a -> m a -> m ()
scheduleWork Scheduler m ()
scheduler (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$
          Array D Int Int -> (Int -> m ()) -> m ()
forall r ix a (m :: * -> *) b.
(Source r ix a, Monad m) =>
Array r ix a -> (a -> m b) -> m ()
forM_ (Int
0 Int -> Int -> Array D Int Int
forall ix. Index ix => ix -> ix -> Array D ix ix
... Int
i) ((Int -> m ()) -> m ()) -> (Int -> m ()) -> m ()
forall a b. (a -> b) -> a -> b
$ \Int
j ->
            let ix :: Ix2
ix = Int
i Int -> Int -> Ix2
:. Int
j
             in Int -> e -> m ()
wr (Sz Ix2 -> Ix2 -> Int
forall ix. Index ix => Sz ix -> ix -> Int
toLinearIndex Sz Ix2
sz Ix2
ix) (Ix2 -> e
f Ix2
ix)
{-# INLINE lowerTriangular #-}

-- | Create an upper triangular (U in LU decomposition) matrix of size @NxN@
--
-- ==== __Example__
--
-- >>> import Data.Massiv.Array
-- >>> upperTriangular Par 5 (\(i :. j) -> i + j)
-- Array DL Par (Sz (5 :. 5))
--   [ [ 0, 1, 2, 3, 4 ]
--   , [ 0, 2, 3, 4, 5 ]
--   , [ 0, 0, 4, 5, 6 ]
--   , [ 0, 0, 0, 6, 7 ]
--   , [ 0, 0, 0, 0, 8 ]
--   ]
--
-- @since 0.5.2
upperTriangular :: Num e => Comp -> Sz1 -> (Ix2 -> e) -> Matrix DL e
upperTriangular :: Comp -> Sz Int -> (Ix2 -> e) -> Matrix DL e
upperTriangular Comp
comp (Sz1 Int
n) Ix2 -> e
f =
  let sz :: Sz Ix2
sz = Int -> Int -> Sz Ix2
Sz2 Int
n Int
n
   in Comp
-> Sz Ix2
-> Maybe e
-> (forall (m :: * -> *).
    Monad m =>
    Scheduler m () -> (Int -> e -> m ()) -> m ())
-> Matrix DL e
forall ix e.
Index ix =>
Comp
-> Sz ix
-> Maybe e
-> (forall (m :: * -> *).
    Monad m =>
    Scheduler m () -> (Int -> e -> m ()) -> m ())
-> Array DL ix e
unsafeMakeLoadArrayAdjusted Comp
comp Sz Ix2
sz (e -> Maybe e
forall a. a -> Maybe a
Just e
0) ((forall (m :: * -> *).
  Monad m =>
  Scheduler m () -> (Int -> e -> m ()) -> m ())
 -> Matrix DL e)
-> (forall (m :: * -> *).
    Monad m =>
    Scheduler m () -> (Int -> e -> m ()) -> m ())
-> Matrix DL e
forall a b. (a -> b) -> a -> b
$ \Scheduler m ()
scheduler Int -> e -> m ()
wr ->
        Array D Int Int -> (Int -> m ()) -> m ()
forall r ix a (m :: * -> *) b.
(Source r ix a, Monad m) =>
Array r ix a -> (a -> m b) -> m ()
forM_ (Int
0 Int -> Int -> Array D Int Int
forall ix. Index ix => ix -> ix -> Array D ix ix
..: Int
n) ((Int -> m ()) -> m ()) -> (Int -> m ()) -> m ()
forall a b. (a -> b) -> a -> b
$ \Int
i ->
          Scheduler m () -> m () -> m ()
forall (m :: * -> *) a. Scheduler m a -> m a -> m ()
scheduleWork Scheduler m ()
scheduler (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$
          Array D Int Int -> (Int -> m ()) -> m ()
forall r ix a (m :: * -> *) b.
(Source r ix a, Monad m) =>
Array r ix a -> (a -> m b) -> m ()
forM_ (Int
i Int -> Int -> Array D Int Int
forall ix. Index ix => ix -> ix -> Array D ix ix
..: Int
n) ((Int -> m ()) -> m ()) -> (Int -> m ()) -> m ()
forall a b. (a -> b) -> a -> b
$ \Int
j ->
            let ix :: Ix2
ix = Int
i Int -> Int -> Ix2
:. Int
j
             in Int -> e -> m ()
wr (Sz Ix2 -> Ix2 -> Int
forall ix. Index ix => Sz ix -> ix -> Int
toLinearIndex Sz Ix2
sz Ix2
ix) (Ix2 -> e
f Ix2
ix)
{-# INLINE upperTriangular #-}

-- | Negate each element of the array
--
-- @since 0.4.0
negateA :: (Index ix, Numeric r e) => Array r ix e -> Array r ix e
negateA :: Array r ix e -> Array r ix e
negateA = (e -> e) -> Array r ix e -> Array r ix e
forall r e ix.
(Numeric r e, Index ix) =>
(e -> e) -> Array r ix e -> Array r ix e
unsafeLiftArray e -> e
forall a. Num a => a -> a
negate
{-# INLINE negateA #-}

-- | Apply `abs` to each element of the array
--
-- @since 0.4.0
absA :: (Index ix, Numeric r e) => Array r ix e -> Array r ix e
absA :: Array r ix e -> Array r ix e
absA = Array r ix e -> Array r ix e
forall r e ix.
(Numeric r e, Index ix) =>
Array r ix e -> Array r ix e
absPointwise
{-# INLINE absA #-}

-- | Apply `signum` to each element of the array
--
-- @since 0.4.0
signumA :: (Index ix, Numeric r e) => Array r ix e -> Array r ix e
signumA :: Array r ix e -> Array r ix e
signumA = (e -> e) -> Array r ix e -> Array r ix e
forall r e ix.
(Numeric r e, Index ix) =>
(e -> e) -> Array r ix e -> Array r ix e
unsafeLiftArray e -> e
forall a. Num a => a -> a
signum
{-# INLINE signumA #-}

-- | Create a singleton array from an `Integer`
fromIntegerA :: (Index ix, Num e) => Integer -> Array D ix e
fromIntegerA :: Integer -> Array D ix e
fromIntegerA = e -> Array D ix e
forall r ix e. Construct r ix e => e -> Array r ix e
singleton (e -> Array D ix e) -> (Integer -> e) -> Integer -> Array D ix e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> e
forall a. Num a => Integer -> a
fromInteger
{-# INLINE fromIntegerA #-}
{-# DEPRECATED fromIntegerA "This almost never a desired behavior. Use `Data.Massiv.Array.Ops.Construct.replicate` instead" #-}

-- | Divide each element of one array by another pointwise. Same as `!/!` but produces
-- monadic computation that allows for handling failure.
--
-- /__Throws Exception__/: `SizeMismatchException` when array sizes do not match.
--
-- @since 0.4.0
(./.) ::
     (Load r ix e, NumericFloat r e, MonadThrow m)
  => Array r ix e
  -> Array r ix e
  -> m (Array r ix e)
./. :: Array r ix e -> Array r ix e -> m (Array r ix e)
(./.) = (Array r ix e -> Array r ix e -> Array r ix e)
-> Array r ix e -> Array r ix e -> m (Array r ix e)
forall r ix e (m :: * -> *).
(Load r ix e, MonadThrow m) =>
(Array r ix e -> Array r ix e -> Array r ix e)
-> Array r ix e -> Array r ix e -> m (Array r ix e)
liftNumericArray2M Array r ix e -> Array r ix e -> Array r ix e
forall r e ix.
(NumericFloat r e, Index ix) =>
Array r ix e -> Array r ix e -> Array r ix e
divisionPointwise
{-# INLINE (./.) #-}


-- | Divide two arrays pointwise. Prefer to use monadic version of this function `./.`
-- whenever possible, because it is better to avoid partial functions.
--
-- [Partial] Mismatched array sizes will result in an impure exception being thrown.
--
-- ====__Example__
--
-- >>> let arr1 = fromIntegral <$> (Ix1 20 ..: 25) :: Array D Ix1 Float
-- >>> let arr2 = fromIntegral <$> (Ix1 100 ..: 105) :: Array D Ix1 Float
-- >>> arr1 !/! arr2
-- Array D Seq (Sz1 5)
--   [ 0.2, 0.20792079, 0.21568628, 0.22330096, 0.23076923 ]
--
-- @since 0.5.6
(!/!) :: (Load r ix e, NumericFloat r e) => Array r ix e -> Array r ix e -> Array r ix e
!/! :: Array r ix e -> Array r ix e -> Array r ix e
(!/!) Array r ix e
a1 Array r ix e
a2 = Either SomeException (Array r ix e) -> Array r ix e
forall a. Either SomeException a -> a
throwEither (Array r ix e
a1 Array r ix e -> Array r ix e -> Either SomeException (Array r ix e)
forall r ix e (m :: * -> *).
(Load r ix e, NumericFloat r e, MonadThrow m) =>
Array r ix e -> Array r ix e -> m (Array r ix e)
./. Array r ix e
a2)
{-# INLINE (!/!) #-}

-- | Divide a scalar value by each element of the array.
--
-- > e /. arr == e *. recipA arr
--
-- ====__Example__
--
-- >>> let arr = fromIntegral <$> (Ix1 20 ..: 25) :: Array D Ix1 Float
-- >>> arr
-- Array D Seq (Sz1 5)
--   [ 20.0, 21.0, 22.0, 23.0, 24.0 ]
-- >>> 100 /. arr
-- Array D Seq (Sz1 5)
--   [ 5.0, 4.7619047, 4.5454545, 4.347826, 4.1666665 ]
--
-- @since 0.5.6
(/.) ::(Index ix,  NumericFloat r e) => e -> Array r ix e -> Array r ix e
/. :: e -> Array r ix e -> Array r ix e
(/.) = e -> Array r ix e -> Array r ix e
forall r e ix.
(NumericFloat r e, Index ix) =>
e -> Array r ix e -> Array r ix e
scalarDivide
{-# INLINE (/.) #-}

-- | Divide each element of the array by a scalar value.
--
-- ====__Example__
--
-- >>> let arr = fromIntegral <$> (Ix1 20 ..: 25) :: Array D Ix1 Float
-- >>> arr
-- Array D Seq (Sz1 5)
--   [ 20.0, 21.0, 22.0, 23.0, 24.0 ]
-- >>> arr ./ 100
-- Array D Seq (Sz1 5)
--   [ 0.2, 0.21, 0.22, 0.23, 0.24 ]
--
-- @since 0.4.0
(./) ::(Index ix,  NumericFloat r e) => Array r ix e -> e -> Array r ix e
./ :: Array r ix e -> e -> Array r ix e
(./) = Array r ix e -> e -> Array r ix e
forall r e ix.
(NumericFloat r e, Index ix) =>
Array r ix e -> e -> Array r ix e
divideScalar
{-# INLINE (./) #-}

(.^^)
  :: (Index ix, Numeric r e, Fractional e, Integral b)
  => Array r ix e -> b -> Array r ix e
.^^ :: Array r ix e -> b -> Array r ix e
(.^^) Array r ix e
arr b
n = (e -> e) -> Array r ix e -> Array r ix e
forall r e ix.
(Numeric r e, Index ix) =>
(e -> e) -> Array r ix e -> Array r ix e
unsafeLiftArray (e -> b -> e
forall a b. (Fractional a, Integral b) => a -> b -> a
^^ b
n) Array r ix e
arr
{-# INLINE (.^^) #-}

-- | Apply reciprocal to each element of the array.
--
-- > recipA arr == 1 /. arr
--
-- @since 0.4.0
recipA :: (Index ix, NumericFloat r e) => Array r ix e -> Array r ix e
recipA :: Array r ix e -> Array r ix e
recipA = Array r ix e -> Array r ix e
forall r e ix.
(NumericFloat r e, Index ix) =>
Array r ix e -> Array r ix e
recipPointwise
{-# INLINE recipA #-}


fromRationalA
  :: (Index ix, Fractional e)
  => Rational -> Array D ix e
fromRationalA :: Rational -> Array D ix e
fromRationalA = e -> Array D ix e
forall r ix e. Construct r ix e => e -> Array r ix e
singleton (e -> Array D ix e) -> (Rational -> e) -> Rational -> Array D ix e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rational -> e
forall a. Fractional a => Rational -> a
fromRational
{-# INLINE fromRationalA #-}
{-# DEPRECATED fromRationalA "This almost never a desired behavior. Use `Data.Massiv.Array.Ops.Construct.replicate` instead" #-}

piA
  :: (Index ix, Floating e)
  => Array D ix e
piA :: Array D ix e
piA = e -> Array D ix e
forall r ix e. Construct r ix e => e -> Array r ix e
singleton e
forall a. Floating a => a
pi
{-# INLINE piA #-}
{-# DEPRECATED piA "This almost never a desired behavior. Use `Data.Massiv.Array.Ops.Construct.replicate` instead" #-}


-- | Apply exponent to each element of the array.
--
-- > expA arr == map exp arr
--
-- @since 0.4.0
expA :: (Index ix, NumericFloat r e) => Array r ix e -> Array r ix e
expA :: Array r ix e -> Array r ix e
expA = (e -> e) -> Array r ix e -> Array r ix e
forall r e ix.
(Numeric r e, Index ix) =>
(e -> e) -> Array r ix e -> Array r ix e
unsafeLiftArray e -> e
forall a. Floating a => a -> a
exp
{-# INLINE expA #-}

-- | Apply square root to each element of the array.
--
-- > sqrtA arr == map sqrt arr
--
-- @since 0.4.0
sqrtA :: (Index ix, NumericFloat r e) => Array r ix e -> Array r ix e
sqrtA :: Array r ix e -> Array r ix e
sqrtA = (e -> e) -> Array r ix e -> Array r ix e
forall r e ix.
(Numeric r e, Index ix) =>
(e -> e) -> Array r ix e -> Array r ix e
unsafeLiftArray e -> e
forall a. Floating a => a -> a
sqrt
{-# INLINE sqrtA #-}

-- | Apply logarithm to each element of the array.
--
-- > logA arr == map log arr
--
-- @since 0.4.0
logA :: (Index ix, NumericFloat r e) => Array r ix e -> Array r ix e
logA :: Array r ix e -> Array r ix e
logA = (e -> e) -> Array r ix e -> Array r ix e
forall r e ix.
(Numeric r e, Index ix) =>
(e -> e) -> Array r ix e -> Array r ix e
unsafeLiftArray e -> e
forall a. Floating a => a -> a
log
{-# INLINE logA #-}


-- | Apply logarithm to each element of the array where the base is in the same cell in
-- the second array.
--
-- > logBaseA arr1 arr2 == zipWith logBase arr1 arr2
--
-- [Partial] Throws an error when arrays do not have matching sizes
--
-- @since 0.4.0
logBaseA
  :: (Source r1 ix e, Source r2 ix e, Floating e)
  => Array r1 ix e -> Array r2 ix e -> Array D ix e
logBaseA :: Array r1 ix e -> Array r2 ix e -> Array D ix e
logBaseA = (e -> e -> e) -> Array r1 ix e -> Array r2 ix e -> Array D ix e
forall r1 ix e1 r2 e2 e.
(Source r1 ix e1, Source r2 ix e2) =>
(e1 -> e2 -> e) -> Array r1 ix e1 -> Array r2 ix e2 -> Array D ix e
liftArray2Matching e -> e -> e
forall a. Floating a => a -> a -> a
logBase
{-# INLINE logBaseA #-}
-- TODO: siwtch to
-- (breaking) logBaseA :: Array r ix e -> e -> Array D ix e
-- logBasesM :: Array r ix e -> Array r ix e -> m (Array D ix e)




-- | Apply power to each element of the array where the power value is in the same cell
-- in the second array.
--
-- > arr1 .** arr2 == zipWith (**) arr1 arr2
--
-- [Partial] Throws an error when arrays do not have matching sizes
--
-- @since 0.4.0
(.**)
  :: (Source r1 ix e, Source r2 ix e, Floating e)
  => Array r1 ix e -> Array r2 ix e -> Array D ix e
.** :: Array r1 ix e -> Array r2 ix e -> Array D ix e
(.**) = (e -> e -> e) -> Array r1 ix e -> Array r2 ix e -> Array D ix e
forall r1 ix e1 r2 e2 e.
(Source r1 ix e1, Source r2 ix e2) =>
(e1 -> e2 -> e) -> Array r1 ix e1 -> Array r2 ix e2 -> Array D ix e
liftArray2Matching e -> e -> e
forall a. Floating a => a -> a -> a
(**)
{-# INLINE (.**) #-}
-- TODO:
-- !**! :: Array r1 ix e -> Array r2 ix e -> Array D ix e
-- .**. :: Array r1 ix e -> Array r2 ix e -> m (Array D ix e)
-- (breaking) .** :: Array r1 ix e -> e -> Array D ix e



-- | Apply sine function to each element of the array.
--
-- > sinA arr == map sin arr
--
-- @since 0.4.0
sinA :: (Index ix, NumericFloat r e) => Array r ix e -> Array r ix e
sinA :: Array r ix e -> Array r ix e
sinA = (e -> e) -> Array r ix e -> Array r ix e
forall r e ix.
(Numeric r e, Index ix) =>
(e -> e) -> Array r ix e -> Array r ix e
unsafeLiftArray e -> e
forall a. Floating a => a -> a
sin
{-# INLINE sinA #-}

-- | Apply cosine function to each element of the array.
--
-- > cosA arr == map cos arr
--
-- @since 0.4.0
cosA :: (Index ix, NumericFloat r e) => Array r ix e -> Array r ix e
cosA :: Array r ix e -> Array r ix e
cosA = (e -> e) -> Array r ix e -> Array r ix e
forall r e ix.
(Numeric r e, Index ix) =>
(e -> e) -> Array r ix e -> Array r ix e
unsafeLiftArray e -> e
forall a. Floating a => a -> a
cos
{-# INLINE cosA #-}

-- | Apply tangent function to each element of the array.
--
-- > tanA arr == map tan arr
--
-- @since 0.4.0
tanA :: (Index ix, NumericFloat r e) => Array r ix e -> Array r ix e
tanA :: Array r ix e -> Array r ix e
tanA = (e -> e) -> Array r ix e -> Array r ix e
forall r e ix.
(Numeric r e, Index ix) =>
(e -> e) -> Array r ix e -> Array r ix e
unsafeLiftArray e -> e
forall a. Floating a => a -> a
tan
{-# INLINE tanA #-}

-- | Apply arcsine function to each element of the array.
--
-- > asinA arr == map asin arr
--
-- @since 0.4.0
asinA :: (Index ix, NumericFloat r e) => Array r ix e -> Array r ix e
asinA :: Array r ix e -> Array r ix e
asinA = (e -> e) -> Array r ix e -> Array r ix e
forall r e ix.
(Numeric r e, Index ix) =>
(e -> e) -> Array r ix e -> Array r ix e
unsafeLiftArray e -> e
forall a. Floating a => a -> a
asin
{-# INLINE asinA #-}

-- | Apply arctangent function to each element of the array.
--
-- > atanA arr == map atan arr
--
-- @since 0.4.0
atanA :: (Index ix, NumericFloat r e) => Array r ix e -> Array r ix e
atanA :: Array r ix e -> Array r ix e
atanA = (e -> e) -> Array r ix e -> Array r ix e
forall r e ix.
(Numeric r e, Index ix) =>
(e -> e) -> Array r ix e -> Array r ix e
unsafeLiftArray e -> e
forall a. Floating a => a -> a
atan
{-# INLINE atanA #-}

-- | Apply arccosine function to each element of the array.
--
-- > acosA arr == map acos arr
--
-- @since 0.4.0
acosA :: (Index ix, NumericFloat r e) => Array r ix e -> Array r ix e
acosA :: Array r ix e -> Array r ix e
acosA = (e -> e) -> Array r ix e -> Array r ix e
forall r e ix.
(Numeric r e, Index ix) =>
(e -> e) -> Array r ix e -> Array r ix e
unsafeLiftArray e -> e
forall a. Floating a => a -> a
acos
{-# INLINE acosA #-}

-- | Apply hyperbolic sine function to each element of the array.
--
-- > sinhA arr == map sinh arr
--
-- @since 0.4.0
sinhA :: (Index ix, NumericFloat r e) => Array r ix e -> Array r ix e
sinhA :: Array r ix e -> Array r ix e
sinhA = (e -> e) -> Array r ix e -> Array r ix e
forall r e ix.
(Numeric r e, Index ix) =>
(e -> e) -> Array r ix e -> Array r ix e
unsafeLiftArray e -> e
forall a. Floating a => a -> a
sinh
{-# INLINE sinhA #-}

-- | Apply hyperbolic tangent function to each element of the array.
--
-- > tanhA arr == map tanh arr
--
-- @since 0.4.0
tanhA :: (Index ix, NumericFloat r e) => Array r ix e -> Array r ix e
tanhA :: Array r ix e -> Array r ix e
tanhA = (e -> e) -> Array r ix e -> Array r ix e
forall r e ix.
(Numeric r e, Index ix) =>
(e -> e) -> Array r ix e -> Array r ix e
unsafeLiftArray e -> e
forall a. Floating a => a -> a
tanh
{-# INLINE tanhA #-}

-- | Apply hyperbolic cosine function to each element of the array.
--
-- > coshA arr == map cosh arr
--
-- @since 0.4.0
coshA :: (Index ix, NumericFloat r e) => Array r ix e -> Array r ix e
coshA :: Array r ix e -> Array r ix e
coshA = (e -> e) -> Array r ix e -> Array r ix e
forall r e ix.
(Numeric r e, Index ix) =>
(e -> e) -> Array r ix e -> Array r ix e
unsafeLiftArray e -> e
forall a. Floating a => a -> a
cosh
{-# INLINE coshA #-}

-- | Apply inverse hyperbolic sine function to each element of the array.
--
-- > asinhA arr == map asinh arr
--
-- @since 0.4.0
asinhA :: (Index ix, NumericFloat r e) => Array r ix e -> Array r ix e
asinhA :: Array r ix e -> Array r ix e
asinhA = (e -> e) -> Array r ix e -> Array r ix e
forall r e ix.
(Numeric r e, Index ix) =>
(e -> e) -> Array r ix e -> Array r ix e
unsafeLiftArray e -> e
forall a. Floating a => a -> a
asinh
{-# INLINE asinhA #-}

-- | Apply inverse hyperbolic cosine function to each element of the array.
--
-- > acoshA arr == map acosh arr
--
-- @since 0.4.0
acoshA :: (Index ix, NumericFloat r e) => Array r ix e -> Array r ix e
acoshA :: Array r ix e -> Array r ix e
acoshA = (e -> e) -> Array r ix e -> Array r ix e
forall r e ix.
(Numeric r e, Index ix) =>
(e -> e) -> Array r ix e -> Array r ix e
unsafeLiftArray e -> e
forall a. Floating a => a -> a
acosh
{-# INLINE acoshA #-}

-- | Apply inverse hyperbolic tangent function to each element of the array.
--
-- > atanhA arr == map atanh arr
--
-- @since 0.4.0
atanhA :: (Index ix, NumericFloat r e) => Array r ix e -> Array r ix e
atanhA :: Array r ix e -> Array r ix e
atanhA = (e -> e) -> Array r ix e -> Array r ix e
forall r e ix.
(Numeric r e, Index ix) =>
(e -> e) -> Array r ix e -> Array r ix e
unsafeLiftArray e -> e
forall a. Floating a => a -> a
atanh
{-# INLINE atanhA #-}


-- | Perform a pointwise quotient where first array contains numerators and the second
-- one denominators
--
-- > quotA arr1 arr2 == zipWith quot arr1 arr2
--
-- [Partial] Mismatched array sizes will result in an impure exception being thrown.
--
-- @since 0.1.0
quotA
  :: (Source r1 ix e, Source r2 ix e, Integral e)
  => Array r1 ix e -> Array r2 ix e -> Array D ix e
quotA :: Array r1 ix e -> Array r2 ix e -> Array D ix e
quotA = (e -> e -> e) -> Array r1 ix e -> Array r2 ix e -> Array D ix e
forall r1 ix e1 r2 e2 e.
(Source r1 ix e1, Source r2 ix e2) =>
(e1 -> e2 -> e) -> Array r1 ix e1 -> Array r2 ix e2 -> Array D ix e
liftArray2Matching e -> e -> e
forall a. Integral a => a -> a -> a
quot
{-# INLINE quotA #-}


-- | Perform a pointwise remainder computation
--
-- > remA arr1 arr2 == zipWith rem arr1 arr2
--
-- [Partial] Mismatched array sizes will result in an impure exception being thrown.
--
-- @since 0.1.0
remA
  :: (Source r1 ix e, Source r2 ix e, Integral e)
  => Array r1 ix e -> Array r2 ix e -> Array D ix e
remA :: Array r1 ix e -> Array r2 ix e -> Array D ix e
remA = (e -> e -> e) -> Array r1 ix e -> Array r2 ix e -> Array D ix e
forall r1 ix e1 r2 e2 e.
(Source r1 ix e1, Source r2 ix e2) =>
(e1 -> e2 -> e) -> Array r1 ix e1 -> Array r2 ix e2 -> Array D ix e
liftArray2Matching e -> e -> e
forall a. Integral a => a -> a -> a
rem
{-# INLINE remA #-}

-- | Perform a pointwise integer division where first array contains numerators and the
-- second one denominators
--
-- > divA arr1 arr2 == zipWith div arr1 arr2
--
-- [Partial] Mismatched array sizes will result in an impure exception being thrown.
--
-- @since 0.1.0
divA
  :: (Source r1 ix e, Source r2 ix e, Integral e)
  => Array r1 ix e -> Array r2 ix e -> Array D ix e
divA :: Array r1 ix e -> Array r2 ix e -> Array D ix e
divA = (e -> e -> e) -> Array r1 ix e -> Array r2 ix e -> Array D ix e
forall r1 ix e1 r2 e2 e.
(Source r1 ix e1, Source r2 ix e2) =>
(e1 -> e2 -> e) -> Array r1 ix e1 -> Array r2 ix e2 -> Array D ix e
liftArray2Matching e -> e -> e
forall a. Integral a => a -> a -> a
div
{-# INLINE divA #-}
-- TODO:
--  * Array r ix e -> Array r ix e -> m (Array r ix e)
--  * Array r ix e -> e -> Array r ix e
--  * e -> Array r ix e -> Array r ix e

-- | Perform a pointwise modulo computation
--
-- > modA arr1 arr2 == zipWith mod arr1 arr2
--
-- [Partial] Mismatched array sizes will result in an impure exception being thrown.
--
-- @since 0.1.0
modA
  :: (Source r1 ix e, Source r2 ix e, Integral e)
  => Array r1 ix e -> Array r2 ix e -> Array D ix e
modA :: Array r1 ix e -> Array r2 ix e -> Array D ix e
modA = (e -> e -> e) -> Array r1 ix e -> Array r2 ix e -> Array D ix e
forall r1 ix e1 r2 e2 e.
(Source r1 ix e1, Source r2 ix e2) =>
(e1 -> e2 -> e) -> Array r1 ix e1 -> Array r2 ix e2 -> Array D ix e
liftArray2Matching e -> e -> e
forall a. Integral a => a -> a -> a
mod
{-# INLINE modA #-}



-- | Perform a pointwise quotient with remainder where first array contains numerators
-- and the second one denominators
--
-- > quotRemA arr1 arr2 == zipWith quotRem arr1 arr2
--
-- [Partial] Mismatched array sizes will result in an impure exception being thrown.
--
-- @since 0.1.0
quotRemA
  :: (Source r1 ix e, Source r2 ix e, Integral e)
  => Array r1 ix e -> Array r2 ix e -> (Array D ix e, Array D ix e)
quotRemA :: Array r1 ix e -> Array r2 ix e -> (Array D ix e, Array D ix e)
quotRemA Array r1 ix e
arr1 = Array D ix (e, e) -> (Array D ix e, Array D ix e)
forall r ix e1 e2.
Source r ix (e1, e2) =>
Array r ix (e1, e2) -> (Array D ix e1, Array D ix e2)
A.unzip (Array D ix (e, e) -> (Array D ix e, Array D ix e))
-> (Array r2 ix e -> Array D ix (e, e))
-> Array r2 ix e
-> (Array D ix e, Array D ix e)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (e -> e -> (e, e))
-> Array r1 ix e -> Array r2 ix e -> Array D ix (e, e)
forall r1 ix e1 r2 e2 e.
(Source r1 ix e1, Source r2 ix e2) =>
(e1 -> e2 -> e) -> Array r1 ix e1 -> Array r2 ix e2 -> Array D ix e
liftArray2Matching (e -> e -> (e, e)
forall a. Integral a => a -> a -> (a, a)
quotRem) Array r1 ix e
arr1
{-# INLINE quotRemA #-}


-- | Perform a pointwise integer division with modulo where first array contains
-- numerators and the second one denominators
--
-- > divModA arr1 arr2 == zipWith divMod arr1 arr2
--
-- [Partial] Mismatched array sizes will result in an impure exception being thrown.
--
-- @since 0.1.0
divModA
  :: (Source r1 ix e, Source r2 ix e, Integral e)
  => Array r1 ix e -> Array r2 ix e -> (Array D ix e, Array D ix e)
divModA :: Array r1 ix e -> Array r2 ix e -> (Array D ix e, Array D ix e)
divModA Array r1 ix e
arr1 = Array D ix (e, e) -> (Array D ix e, Array D ix e)
forall r ix e1 e2.
Source r ix (e1, e2) =>
Array r ix (e1, e2) -> (Array D ix e1, Array D ix e2)
A.unzip (Array D ix (e, e) -> (Array D ix e, Array D ix e))
-> (Array r2 ix e -> Array D ix (e, e))
-> Array r2 ix e
-> (Array D ix e, Array D ix e)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (e -> e -> (e, e))
-> Array r1 ix e -> Array r2 ix e -> Array D ix (e, e)
forall r1 ix e1 r2 e2 e.
(Source r1 ix e1, Source r2 ix e2) =>
(e1 -> e2 -> e) -> Array r1 ix e1 -> Array r2 ix e2 -> Array D ix e
liftArray2Matching (e -> e -> (e, e)
forall a. Integral a => a -> a -> (a, a)
divMod) Array r1 ix e
arr1
{-# INLINE divModA #-}



-- | Truncate each element of the array.
--
-- > truncateA arr == map truncate arr
--
-- @since 0.1.0
truncateA
  :: (Source r ix a, RealFrac a, Integral e)
  => Array r ix a -> Array D ix e
truncateA :: Array r ix a -> Array D ix e
truncateA = (a -> e) -> Array r ix a -> Array D ix e
forall r ix e' e.
Source r ix e' =>
(e' -> e) -> Array r ix e' -> Array D ix e
A.map a -> e
forall a b. (RealFrac a, Integral b) => a -> b
truncate
{-# INLINE truncateA #-}


-- | Round each element of the array.
--
-- > truncateA arr == map truncate arr
--
-- @since 0.1.0
roundA :: (Source r ix a, RealFrac a, Integral e) => Array r ix a -> Array D ix e
roundA :: Array r ix a -> Array D ix e
roundA = (a -> e) -> Array r ix a -> Array D ix e
forall r ix e' e.
Source r ix e' =>
(e' -> e) -> Array r ix e' -> Array D ix e
A.map a -> e
forall a b. (RealFrac a, Integral b) => a -> b
round
{-# INLINE roundA #-}


-- | Ceiling of each element of the array.
--
-- > truncateA arr == map truncate arr
--
-- @since 0.1.0
ceilingA :: (Source r ix a, RealFrac a, Integral e) => Array r ix a -> Array D ix e
ceilingA :: Array r ix a -> Array D ix e
ceilingA = (a -> e) -> Array r ix a -> Array D ix e
forall r ix e' e.
Source r ix e' =>
(e' -> e) -> Array r ix e' -> Array D ix e
A.map a -> e
forall a b. (RealFrac a, Integral b) => a -> b
ceiling
{-# INLINE ceilingA #-}


-- | Floor each element of the array.
--
-- > truncateA arr == map truncate arr
--
-- @since 0.1.0
floorA :: (Source r ix a, RealFrac a, Integral e) => Array r ix a -> Array D ix e
floorA :: Array r ix a -> Array D ix e
floorA = (a -> e) -> Array r ix a -> Array D ix e
forall r ix e' e.
Source r ix e' =>
(e' -> e) -> Array r ix e' -> Array D ix e
A.map a -> e
forall a b. (RealFrac a, Integral b) => a -> b
floor
{-# INLINE floorA #-}

-- | Perform atan2 pointwise
--
-- > atan2A arr1 arr2 == zipWith atan2 arr1 arr2
--
-- /__Throws Exception__/: `SizeMismatchException` when array sizes do not match.
--
-- @since 0.1.0
atan2A ::
     (Load r ix e, Numeric r e, RealFloat e, MonadThrow m)
  => Array r ix e
  -> Array r ix e
  -> m (Array r ix e)
atan2A :: Array r ix e -> Array r ix e -> m (Array r ix e)
atan2A = (e -> e -> e) -> Array r ix e -> Array r ix e -> m (Array r ix e)
forall r ix e (m :: * -> *).
(Load r ix e, Numeric r e, MonadThrow m) =>
(e -> e -> e) -> Array r ix e -> Array r ix e -> m (Array r ix e)
liftArray2M e -> e -> e
forall a. RealFloat a => a -> a -> a
atan2
{-# INLINE atan2A #-}