{-# LANGUAGE RecordWildCards     #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE DataKinds           #-}
{-# LANGUAGE FlexibleInstances   #-}
{-# LANGUAGE TypeApplications    #-}
{-# LANGUAGE ViewPatterns        #-}
{-# LANGUAGE KindSignatures      #-}
{-# LANGUAGE TypeFamilies        #-}
{-# LANGUAGE FlexibleContexts    #-}
--------------------------------------------------------------------------------
-- |
-- Module      : ArrayFire.Data
-- Copyright   : David Johnson (c) 2019-2020
-- License     : BSD 3
-- Maintainer  : David Johnson <djohnson.m@gmail.com>
-- Stability   : Experimental
-- Portability : GHC
--
-- Functions for populating 'Array' with Data.
--
-- @
-- >>> constant @Double [2,2] 2.0
--  ArrayFire Array
-- [2 2 1 1]
--    2.0000     2.0000
--    2.0000     2.0000
-- @
--
--------------------------------------------------------------------------------
module ArrayFire.Data where

import Control.Exception
import Control.Monad
import Data.Complex
import Data.Int
import Data.Proxy
import Data.Word
import Foreign.C.Types
import Foreign.ForeignPtr
import Foreign.Marshal          hiding (void)
import Foreign.Storable
import System.IO.Unsafe
import Unsafe.Coerce

import ArrayFire.Exception
import ArrayFire.FFI
import ArrayFire.Internal.Data
import ArrayFire.Internal.Defines
import ArrayFire.Internal.Types
import ArrayFire.Arith

-- | Creates an 'Array' from a scalar value from given dimensions
--
-- >>> constant @Double [2,2] 2.0
--  ArrayFire Array
-- [2 2 1 1]
--    2.0000     2.0000
--    2.0000     2.0000
constant
  :: forall a . AFType a
  => [Int]
  -- ^ Dimensions
  -> a
  -- ^ Scalar value
  -> Array a
constant :: forall a. AFType a => [Int] -> a -> Array a
constant [Int]
dims a
val =
  case AFDtype
dtyp of
    AFDtype
x | AFDtype
x AFDtype -> AFDtype -> Bool
forall a. Eq a => a -> a -> Bool
== AFDtype
c64 ->
        Array (Complex Double) -> Array a
forall a b. (AFType a, AFType b) => Array a -> Array b
cast (Array (Complex Double) -> Array a)
-> Array (Complex Double) -> Array a
forall a b. (a -> b) -> a -> b
$ [Int] -> Complex Double -> Array (Complex Double)
forall arr.
(Real arr, AFType (Complex arr)) =>
[Int] -> Complex arr -> Array (Complex arr)
constantComplex [Int]
dims (a -> Complex Double
forall a b. a -> b
unsafeCoerce a
val :: Complex Double)
      | AFDtype
x AFDtype -> AFDtype -> Bool
forall a. Eq a => a -> a -> Bool
== AFDtype
c32 ->
        Array (Complex Float) -> Array a
forall a b. (AFType a, AFType b) => Array a -> Array b
cast (Array (Complex Float) -> Array a)
-> Array (Complex Float) -> Array a
forall a b. (a -> b) -> a -> b
$ [Int] -> Complex Float -> Array (Complex Float)
forall arr.
(Real arr, AFType (Complex arr)) =>
[Int] -> Complex arr -> Array (Complex arr)
constantComplex [Int]
dims (a -> Complex Float
forall a b. a -> b
unsafeCoerce a
val :: Complex Float)
      | AFDtype
x AFDtype -> AFDtype -> Bool
forall a. Eq a => a -> a -> Bool
== AFDtype
s64 ->
        Array Int -> Array a
forall a b. (AFType a, AFType b) => Array a -> Array b
cast (Array Int -> Array a) -> Array Int -> Array a
forall a b. (a -> b) -> a -> b
$ [Int] -> Int -> Array Int
constantLong [Int]
dims (a -> Int
forall a b. a -> b
unsafeCoerce a
val :: Int)
      | AFDtype
x AFDtype -> AFDtype -> Bool
forall a. Eq a => a -> a -> Bool
== AFDtype
u64 ->
        Array Word64 -> Array a
forall a b. (AFType a, AFType b) => Array a -> Array b
cast (Array Word64 -> Array a) -> Array Word64 -> Array a
forall a b. (a -> b) -> a -> b
$ [Int] -> Word64 -> Array Word64
constantULong [Int]
dims (a -> Word64
forall a b. a -> b
unsafeCoerce a
val :: Word64)
      | AFDtype
x AFDtype -> AFDtype -> Bool
forall a. Eq a => a -> a -> Bool
== AFDtype
s32 ->
        Array Double -> Array a
forall a b. (AFType a, AFType b) => Array a -> Array b
cast (Array Double -> Array a) -> Array Double -> Array a
forall a b. (a -> b) -> a -> b
$ [Int] -> Double -> Array Double
constant' [Int]
dims (Int32 -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (a -> Int32
forall a b. a -> b
unsafeCoerce a
val :: Int32) :: Double)
      | AFDtype
x AFDtype -> AFDtype -> Bool
forall a. Eq a => a -> a -> Bool
== AFDtype
s16 ->
        Array Double -> Array a
forall a b. (AFType a, AFType b) => Array a -> Array b
cast (Array Double -> Array a) -> Array Double -> Array a
forall a b. (a -> b) -> a -> b
$ [Int] -> Double -> Array Double
constant' [Int]
dims (Int16 -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (a -> Int16
forall a b. a -> b
unsafeCoerce a
val :: Int16) :: Double)
      | AFDtype
x AFDtype -> AFDtype -> Bool
forall a. Eq a => a -> a -> Bool
== AFDtype
u32 ->
        Array Double -> Array a
forall a b. (AFType a, AFType b) => Array a -> Array b
cast (Array Double -> Array a) -> Array Double -> Array a
forall a b. (a -> b) -> a -> b
$ [Int] -> Double -> Array Double
constant' [Int]
dims (Word32 -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (a -> Word32
forall a b. a -> b
unsafeCoerce a
val :: Word32) :: Double)
      | AFDtype
x AFDtype -> AFDtype -> Bool
forall a. Eq a => a -> a -> Bool
== AFDtype
u8 ->
        Array Double -> Array a
forall a b. (AFType a, AFType b) => Array a -> Array b
cast (Array Double -> Array a) -> Array Double -> Array a
forall a b. (a -> b) -> a -> b
$ [Int] -> Double -> Array Double
constant' [Int]
dims (Word8 -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (a -> Word8
forall a b. a -> b
unsafeCoerce a
val :: Word8) :: Double)
      | AFDtype
x AFDtype -> AFDtype -> Bool
forall a. Eq a => a -> a -> Bool
== AFDtype
u16 ->
        Array Double -> Array a
forall a b. (AFType a, AFType b) => Array a -> Array b
cast (Array Double -> Array a) -> Array Double -> Array a
forall a b. (a -> b) -> a -> b
$ [Int] -> Double -> Array Double
constant' [Int]
dims (Word16 -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (a -> Word16
forall a b. a -> b
unsafeCoerce a
val :: Word16) :: Double)
      | AFDtype
x AFDtype -> AFDtype -> Bool
forall a. Eq a => a -> a -> Bool
== AFDtype
f64 ->
        Array Double -> Array a
forall a b. (AFType a, AFType b) => Array a -> Array b
cast (Array Double -> Array a) -> Array Double -> Array a
forall a b. (a -> b) -> a -> b
$ [Int] -> Double -> Array Double
constant' [Int]
dims (a -> Double
forall a b. a -> b
unsafeCoerce a
val :: Double)
      | AFDtype
x AFDtype -> AFDtype -> Bool
forall a. Eq a => a -> a -> Bool
== AFDtype
b8  ->
        Array Double -> Array a
forall a b. (AFType a, AFType b) => Array a -> Array b
cast (Array Double -> Array a) -> Array Double -> Array a
forall a b. (a -> b) -> a -> b
$ [Int] -> Double -> Array Double
constant' [Int]
dims (CBool -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (a -> CBool
forall a b. a -> b
unsafeCoerce a
val :: CBool) :: Double)
      | AFDtype
x AFDtype -> AFDtype -> Bool
forall a. Eq a => a -> a -> Bool
== AFDtype
f32 ->
        Array Double -> Array a
forall a b. (AFType a, AFType b) => Array a -> Array b
cast (Array Double -> Array a) -> Array Double -> Array a
forall a b. (a -> b) -> a -> b
$ [Int] -> Double -> Array Double
constant' [Int]
dims (Float -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac (a -> Float
forall a b. a -> b
unsafeCoerce a
val :: Float))
      | Bool
otherwise -> [Char] -> Array a
forall a. HasCallStack => [Char] -> a
error [Char]
"constant: Invalid array fire type"
  where
    dtyp :: AFDtype
dtyp = Proxy a -> AFDtype
forall a. AFType a => Proxy a -> AFDtype
afType (forall {t}. Proxy t
forall {k} (t :: k). Proxy t
Proxy @a)

    constant'
      :: [Int]
      -- ^ Dimensions
      -> Double
      -- ^ Scalar value
      -> Array Double
    constant' :: [Int] -> Double -> Array Double
constant' [Int]
dims' Double
val' =
      IO (Array Double) -> Array Double
forall a. IO a -> a
unsafePerformIO (IO (Array Double) -> Array Double)
-> (IO (Array Double) -> IO (Array Double))
-> IO (Array Double)
-> Array Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO (Array Double) -> IO (Array Double)
forall a. IO a -> IO a
mask_ (IO (Array Double) -> Array Double)
-> IO (Array Double) -> Array Double
forall a b. (a -> b) -> a -> b
$ do
        AFArray
ptr <- (Ptr AFArray -> IO AFArray) -> IO AFArray
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr AFArray -> IO AFArray) -> IO AFArray)
-> (Ptr AFArray -> IO AFArray) -> IO AFArray
forall a b. (a -> b) -> a -> b
$ \Ptr AFArray
ptrPtr -> do
          Ptr AFArray -> IO ()
zeroOutArray Ptr AFArray
ptrPtr
          [DimT] -> (Ptr DimT -> IO AFArray) -> IO AFArray
forall a b. Storable a => [a] -> (Ptr a -> IO b) -> IO b
withArray (Int -> DimT
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> DimT) -> [Int] -> [DimT]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Int]
dims') ((Ptr DimT -> IO AFArray) -> IO AFArray)
-> (Ptr DimT -> IO AFArray) -> IO AFArray
forall a b. (a -> b) -> a -> b
$ \Ptr DimT
dimArray -> do
            AFErr -> IO ()
throwAFError (AFErr -> IO ()) -> IO AFErr -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr AFArray -> Double -> CUInt -> Ptr DimT -> AFDtype -> IO AFErr
af_constant Ptr AFArray
ptrPtr Double
val' CUInt
n Ptr DimT
dimArray AFDtype
typ
            Ptr AFArray -> IO AFArray
forall a. Storable a => Ptr a -> IO a
peek Ptr AFArray
ptrPtr
        ForeignPtr () -> Array Double
forall a. ForeignPtr () -> Array a
Array (ForeignPtr () -> Array Double)
-> IO (ForeignPtr ()) -> IO (Array Double)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
          FinalizerPtr () -> AFArray -> IO (ForeignPtr ())
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr
            FinalizerPtr ()
af_release_array_finalizer
              AFArray
ptr
          where
            n :: CUInt
n = Int -> CUInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral ([Int] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
dims')
            typ :: AFDtype
typ = Proxy Double -> AFDtype
forall a. AFType a => Proxy a -> AFDtype
afType (forall {t}. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Double)

    -- | Creates an 'Array (Complex Double)' from a scalar val'ue
    --
    -- @
    -- >>> constantComplex [2,2] (2.0 :+ 2.0)
    -- @
    --
    constantComplex
      :: forall arr . (Real arr, AFType (Complex arr))
      => [Int]
      -- ^ Dimensions
      -> Complex arr
      -- ^ Scalar val'ue
      -> Array (Complex arr)
    constantComplex :: forall arr.
(Real arr, AFType (Complex arr)) =>
[Int] -> Complex arr -> Array (Complex arr)
constantComplex [Int]
dims' ((arr -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac -> Double
x) :+ (arr -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac -> Double
y)) = IO (Array (Complex arr)) -> Array (Complex arr)
forall a. IO a -> a
unsafePerformIO (IO (Array (Complex arr)) -> Array (Complex arr))
-> (IO (Array (Complex arr)) -> IO (Array (Complex arr)))
-> IO (Array (Complex arr))
-> Array (Complex arr)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO (Array (Complex arr)) -> IO (Array (Complex arr))
forall a. IO a -> IO a
mask_ (IO (Array (Complex arr)) -> Array (Complex arr))
-> IO (Array (Complex arr)) -> Array (Complex arr)
forall a b. (a -> b) -> a -> b
$ do
      AFArray
ptr <- (Ptr AFArray -> IO AFArray) -> IO AFArray
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr AFArray -> IO AFArray) -> IO AFArray)
-> (Ptr AFArray -> IO AFArray) -> IO AFArray
forall a b. (a -> b) -> a -> b
$ \Ptr AFArray
ptrPtr -> do
        Ptr AFArray -> IO ()
zeroOutArray Ptr AFArray
ptrPtr
        [DimT] -> (Ptr DimT -> IO AFArray) -> IO AFArray
forall a b. Storable a => [a] -> (Ptr a -> IO b) -> IO b
withArray (Int -> DimT
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> DimT) -> [Int] -> [DimT]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Int]
dims') ((Ptr DimT -> IO AFArray) -> IO AFArray)
-> (Ptr DimT -> IO AFArray) -> IO AFArray
forall a b. (a -> b) -> a -> b
$ \Ptr DimT
dimArray -> do
          AFErr -> IO ()
throwAFError (AFErr -> IO ()) -> IO AFErr -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr AFArray
-> Double -> Double -> CUInt -> Ptr DimT -> AFDtype -> IO AFErr
af_constant_complex Ptr AFArray
ptrPtr Double
x Double
y CUInt
n Ptr DimT
dimArray AFDtype
typ
          Ptr AFArray -> IO AFArray
forall a. Storable a => Ptr a -> IO a
peek Ptr AFArray
ptrPtr
      ForeignPtr () -> Array (Complex arr)
forall a. ForeignPtr () -> Array a
Array (ForeignPtr () -> Array (Complex arr))
-> IO (ForeignPtr ()) -> IO (Array (Complex arr))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
        FinalizerPtr () -> AFArray -> IO (ForeignPtr ())
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr
          FinalizerPtr ()
af_release_array_finalizer
            AFArray
ptr
          where
            n :: CUInt
n = Int -> CUInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral ([Int] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
dims')
            typ :: AFDtype
typ = Proxy (Complex arr) -> AFDtype
forall a. AFType a => Proxy a -> AFDtype
afType (forall {t}. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(Complex arr))

    -- | Creates an 'Array Int64' from a scalar val'ue
    --
    -- @
    -- >>> constantLong [2,2] 2.0
    -- @
    --
    constantLong
      :: [Int]
      -- ^ Dimensions
      -> Int
      -- ^ Scalar val'ue
      -> Array Int
    constantLong :: [Int] -> Int -> Array Int
constantLong [Int]
dims' Int
val' = IO (Array Int) -> Array Int
forall a. IO a -> a
unsafePerformIO (IO (Array Int) -> Array Int)
-> (IO (Array Int) -> IO (Array Int))
-> IO (Array Int)
-> Array Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO (Array Int) -> IO (Array Int)
forall a. IO a -> IO a
mask_ (IO (Array Int) -> Array Int) -> IO (Array Int) -> Array Int
forall a b. (a -> b) -> a -> b
$ do
      AFArray
ptr <- (Ptr AFArray -> IO AFArray) -> IO AFArray
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr AFArray -> IO AFArray) -> IO AFArray)
-> (Ptr AFArray -> IO AFArray) -> IO AFArray
forall a b. (a -> b) -> a -> b
$ \Ptr AFArray
ptrPtr -> do
        Ptr AFArray -> IO ()
zeroOutArray Ptr AFArray
ptrPtr
        [DimT] -> (Ptr DimT -> IO AFArray) -> IO AFArray
forall a b. Storable a => [a] -> (Ptr a -> IO b) -> IO b
withArray (Int -> DimT
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> DimT) -> [Int] -> [DimT]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Int]
dims') ((Ptr DimT -> IO AFArray) -> IO AFArray)
-> (Ptr DimT -> IO AFArray) -> IO AFArray
forall a b. (a -> b) -> a -> b
$ \Ptr DimT
dimArray -> do
          AFErr -> IO ()
throwAFError (AFErr -> IO ()) -> IO AFErr -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr AFArray -> IntL -> CUInt -> Ptr DimT -> IO AFErr
af_constant_long Ptr AFArray
ptrPtr (Int -> IntL
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
val') CUInt
n Ptr DimT
dimArray
          Ptr AFArray -> IO AFArray
forall a. Storable a => Ptr a -> IO a
peek Ptr AFArray
ptrPtr
      ForeignPtr () -> Array Int
forall a. ForeignPtr () -> Array a
Array (ForeignPtr () -> Array Int)
-> IO (ForeignPtr ()) -> IO (Array Int)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
        FinalizerPtr () -> AFArray -> IO (ForeignPtr ())
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr
          FinalizerPtr ()
af_release_array_finalizer
            AFArray
ptr
          where
            n :: CUInt
n = Int -> CUInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral ([Int] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
dims')

    -- | Creates an 'Array Word64' from a scalar val'ue
    --
    -- @
    -- >>> constantULong [2,2] 2.0
    -- @
    --
    constantULong
      :: [Int]
      -> Word64
      -> Array Word64
    constantULong :: [Int] -> Word64 -> Array Word64
constantULong [Int]
dims' Word64
val' = IO (Array Word64) -> Array Word64
forall a. IO a -> a
unsafePerformIO (IO (Array Word64) -> Array Word64)
-> (IO (Array Word64) -> IO (Array Word64))
-> IO (Array Word64)
-> Array Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO (Array Word64) -> IO (Array Word64)
forall a. IO a -> IO a
mask_ (IO (Array Word64) -> Array Word64)
-> IO (Array Word64) -> Array Word64
forall a b. (a -> b) -> a -> b
$ do
      AFArray
ptr <- (Ptr AFArray -> IO AFArray) -> IO AFArray
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr AFArray -> IO AFArray) -> IO AFArray)
-> (Ptr AFArray -> IO AFArray) -> IO AFArray
forall a b. (a -> b) -> a -> b
$ \Ptr AFArray
ptrPtr -> do
        Ptr AFArray -> IO ()
zeroOutArray Ptr AFArray
ptrPtr
        [DimT] -> (Ptr DimT -> IO AFArray) -> IO AFArray
forall a b. Storable a => [a] -> (Ptr a -> IO b) -> IO b
withArray (Int -> DimT
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> DimT) -> [Int] -> [DimT]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Int]
dims') ((Ptr DimT -> IO AFArray) -> IO AFArray)
-> (Ptr DimT -> IO AFArray) -> IO AFArray
forall a b. (a -> b) -> a -> b
$ \Ptr DimT
dimArray -> do
          AFErr -> IO ()
throwAFError (AFErr -> IO ()) -> IO AFErr -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr AFArray -> UIntL -> CUInt -> Ptr DimT -> IO AFErr
af_constant_ulong Ptr AFArray
ptrPtr (Word64 -> UIntL
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
val') CUInt
n Ptr DimT
dimArray
          Ptr AFArray -> IO AFArray
forall a. Storable a => Ptr a -> IO a
peek Ptr AFArray
ptrPtr
      ForeignPtr () -> Array Word64
forall a. ForeignPtr () -> Array a
Array (ForeignPtr () -> Array Word64)
-> IO (ForeignPtr ()) -> IO (Array Word64)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
        FinalizerPtr () -> AFArray -> IO (ForeignPtr ())
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr
          FinalizerPtr ()
af_release_array_finalizer
            AFArray
ptr
          where
            n :: CUInt
n = Int -> CUInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral ([Int] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
dims')

-- | Creates a range of values in an Array
--
-- >>> range @Double [10] (-1)
-- ArrayFire Array
-- [10 1 1 1]
--     0.0000
--     1.0000
--     2.0000
--     3.0000
--     4.0000
--     5.0000
--     6.0000
--     7.0000
--     8.0000
--     9.0000
range
  :: forall a
   . AFType a
  => [Int]
  -> Int
  -> Array a
range :: forall a. AFType a => [Int] -> Int -> Array a
range [Int]
dims (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral -> CInt
k) = IO (Array a) -> Array a
forall a. IO a -> a
unsafePerformIO (IO (Array a) -> Array a) -> IO (Array a) -> Array a
forall a b. (a -> b) -> a -> b
$ do
  AFArray
ptr <- (Ptr AFArray -> IO AFArray) -> IO AFArray
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr AFArray -> IO AFArray) -> IO AFArray)
-> (Ptr AFArray -> IO AFArray) -> IO AFArray
forall a b. (a -> b) -> a -> b
$ \Ptr AFArray
ptrPtr -> IO AFArray -> IO AFArray
forall a. IO a -> IO a
mask_ (IO AFArray -> IO AFArray) -> IO AFArray -> IO AFArray
forall a b. (a -> b) -> a -> b
$ do
    [DimT] -> (Ptr DimT -> IO AFArray) -> IO AFArray
forall a b. Storable a => [a] -> (Ptr a -> IO b) -> IO b
withArray (Int -> DimT
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> DimT) -> [Int] -> [DimT]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Int]
dims) ((Ptr DimT -> IO AFArray) -> IO AFArray)
-> (Ptr DimT -> IO AFArray) -> IO AFArray
forall a b. (a -> b) -> a -> b
$ \Ptr DimT
dimArray -> do
      AFErr -> IO ()
throwAFError (AFErr -> IO ()) -> IO AFErr -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr AFArray -> CUInt -> Ptr DimT -> CInt -> AFDtype -> IO AFErr
af_range Ptr AFArray
ptrPtr CUInt
n Ptr DimT
dimArray CInt
k AFDtype
typ
      Ptr AFArray -> IO AFArray
forall a. Storable a => Ptr a -> IO a
peek Ptr AFArray
ptrPtr
  ForeignPtr () -> Array a
forall a. ForeignPtr () -> Array a
Array (ForeignPtr () -> Array a) -> IO (ForeignPtr ()) -> IO (Array a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
    FinalizerPtr () -> AFArray -> IO (ForeignPtr ())
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr
      FinalizerPtr ()
af_release_array_finalizer
        AFArray
ptr
      where
        n :: CUInt
n = Int -> CUInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral ([Int] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
dims)
        typ :: AFDtype
typ = Proxy a -> AFDtype
forall a. AFType a => Proxy a -> AFDtype
afType (forall {t}. Proxy t
forall {k} (t :: k). Proxy t
Proxy @a)

-- | Create an sequence [0, dims.elements() - 1] and modify to specified dimensions dims and then tile it according to tile_dims.
--
-- <http://arrayfire.org/docs/group__data__func__iota.htm>
--
-- >>> iota @Double [5,3] []
-- ArrayFire Array
-- [5 3 1 1]
--     0.0000     5.0000    10.0000
--     1.0000     6.0000    11.0000
--     2.0000     7.0000    12.0000
--     3.0000     8.0000    13.0000
--     4.0000     9.0000    14.0000
--
-- >>> iota @Double [5,3] [1,2]
-- ArrayFire Array
-- [5 6 1 1]
--     0.0000     5.0000    10.0000     0.0000     5.0000    10.0000
--     1.0000     6.0000    11.0000     1.0000     6.0000    11.0000
--     2.0000     7.0000    12.0000     2.0000     7.0000    12.0000
--     3.0000     8.0000    13.0000     3.0000     8.0000    13.0000
--     4.0000     9.0000    14.0000     4.0000     9.0000    14.0000
iota
  :: forall a . AFType a
  => [Int]
  -- ^ is the array containing sizes of the dimension
  -> [Int]
  -- ^ is array containing the number of repetitions of the unit dimensions
  -> Array a
  -- ^ is the generated array
iota :: forall a. AFType a => [Int] -> [Int] -> Array a
iota [Int]
dims [Int]
tdims = IO (Array a) -> Array a
forall a. IO a -> a
unsafePerformIO (IO (Array a) -> Array a) -> IO (Array a) -> Array a
forall a b. (a -> b) -> a -> b
$ do
  let dims' :: [Int]
dims' = Int -> [Int] -> [Int]
forall a. Int -> [a] -> [a]
take Int
4 ([Int]
dims [Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++ Int -> [Int]
forall a. a -> [a]
repeat Int
1)
      tdims' :: [Int]
tdims' =  Int -> [Int] -> [Int]
forall a. Int -> [a] -> [a]
take Int
4 ([Int]
tdims [Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++ Int -> [Int]
forall a. a -> [a]
repeat Int
1)
  AFArray
ptr <- (Ptr AFArray -> IO AFArray) -> IO AFArray
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr AFArray -> IO AFArray) -> IO AFArray)
-> (Ptr AFArray -> IO AFArray) -> IO AFArray
forall a b. (a -> b) -> a -> b
$ \Ptr AFArray
ptrPtr -> IO AFArray -> IO AFArray
forall a. IO a -> IO a
mask_ (IO AFArray -> IO AFArray) -> IO AFArray -> IO AFArray
forall a b. (a -> b) -> a -> b
$ do
    Ptr AFArray -> IO ()
zeroOutArray Ptr AFArray
ptrPtr
    [DimT] -> (Ptr DimT -> IO AFArray) -> IO AFArray
forall a b. Storable a => [a] -> (Ptr a -> IO b) -> IO b
withArray (Int -> DimT
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> DimT) -> [Int] -> [DimT]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Int]
dims') ((Ptr DimT -> IO AFArray) -> IO AFArray)
-> (Ptr DimT -> IO AFArray) -> IO AFArray
forall a b. (a -> b) -> a -> b
$ \Ptr DimT
dimArray ->
      [DimT] -> (Ptr DimT -> IO AFArray) -> IO AFArray
forall a b. Storable a => [a] -> (Ptr a -> IO b) -> IO b
withArray (Int -> DimT
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> DimT) -> [Int] -> [DimT]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Int]
tdims') ((Ptr DimT -> IO AFArray) -> IO AFArray)
-> (Ptr DimT -> IO AFArray) -> IO AFArray
forall a b. (a -> b) -> a -> b
$ \Ptr DimT
tdimArray -> do
        AFErr -> IO ()
throwAFError (AFErr -> IO ()) -> IO AFErr -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr AFArray
-> CUInt -> Ptr DimT -> CUInt -> Ptr DimT -> AFDtype -> IO AFErr
af_iota Ptr AFArray
ptrPtr CUInt
4 Ptr DimT
dimArray CUInt
4 Ptr DimT
tdimArray AFDtype
typ
        Ptr AFArray -> IO AFArray
forall a. Storable a => Ptr a -> IO a
peek Ptr AFArray
ptrPtr
  ForeignPtr () -> Array a
forall a. ForeignPtr () -> Array a
Array (ForeignPtr () -> Array a) -> IO (ForeignPtr ()) -> IO (Array a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
    FinalizerPtr () -> AFArray -> IO (ForeignPtr ())
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr
      FinalizerPtr ()
af_release_array_finalizer
        AFArray
ptr
      where
        typ :: AFDtype
typ = Proxy a -> AFDtype
forall a. AFType a => Proxy a -> AFDtype
afType (forall {t}. Proxy t
forall {k} (t :: k). Proxy t
Proxy @a)

-- | Creates the identity `Array` from given dimensions
--
-- >>> identity [2,2]
-- ArrayFire Array
-- [2 2 1 1]
--    1.0000     0.0000
--    0.0000     1.0000
identity
  :: forall a . AFType a
  => [Int]
  -- ^ Dimensions
  -> Array a
identity :: forall a. AFType a => [Int] -> Array a
identity [Int]
dims = IO (Array a) -> Array a
forall a. IO a -> a
unsafePerformIO (IO (Array a) -> Array a)
-> (IO (Array a) -> IO (Array a)) -> IO (Array a) -> Array a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO (Array a) -> IO (Array a)
forall a. IO a -> IO a
mask_ (IO (Array a) -> Array a) -> IO (Array a) -> Array a
forall a b. (a -> b) -> a -> b
$ do
  let dims' :: [Int]
dims' = Int -> [Int] -> [Int]
forall a. Int -> [a] -> [a]
take Int
4 ([Int]
dims [Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++ Int -> [Int]
forall a. a -> [a]
repeat Int
1)
  AFArray
ptr <- (Ptr AFArray -> IO AFArray) -> IO AFArray
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr AFArray -> IO AFArray) -> IO AFArray)
-> (Ptr AFArray -> IO AFArray) -> IO AFArray
forall a b. (a -> b) -> a -> b
$ \Ptr AFArray
ptrPtr -> IO AFArray -> IO AFArray
forall a. IO a -> IO a
mask_ (IO AFArray -> IO AFArray) -> IO AFArray -> IO AFArray
forall a b. (a -> b) -> a -> b
$ do
    Ptr AFArray -> IO ()
zeroOutArray Ptr AFArray
ptrPtr
    [DimT] -> (Ptr DimT -> IO AFArray) -> IO AFArray
forall a b. Storable a => [a] -> (Ptr a -> IO b) -> IO b
withArray (Int -> DimT
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> DimT) -> [Int] -> [DimT]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Int]
dims') ((Ptr DimT -> IO AFArray) -> IO AFArray)
-> (Ptr DimT -> IO AFArray) -> IO AFArray
forall a b. (a -> b) -> a -> b
$ \Ptr DimT
dimArray -> do
      AFErr -> IO ()
throwAFError (AFErr -> IO ()) -> IO AFErr -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr AFArray -> CUInt -> Ptr DimT -> AFDtype -> IO AFErr
af_identity Ptr AFArray
ptrPtr CUInt
n Ptr DimT
dimArray AFDtype
typ
      Ptr AFArray -> IO AFArray
forall a. Storable a => Ptr a -> IO a
peek Ptr AFArray
ptrPtr
  ForeignPtr () -> Array a
forall a. ForeignPtr () -> Array a
Array (ForeignPtr () -> Array a) -> IO (ForeignPtr ()) -> IO (Array a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
    FinalizerPtr () -> AFArray -> IO (ForeignPtr ())
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr
      FinalizerPtr ()
af_release_array_finalizer
        AFArray
ptr
      where
        n :: CUInt
n = Int -> CUInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral ([Int] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
dims)
        typ :: AFDtype
typ = Proxy a -> AFDtype
forall a. AFType a => Proxy a -> AFDtype
afType (forall {t}. Proxy t
forall {k} (t :: k). Proxy t
Proxy @a)

-- | Create a diagonal matrix from input array when extract is set to false
--
-- >>> diagCreate (vector @Double 2 [1..]) 0
-- ArrayFire Array
-- [2 2 1 1]
--    1.0000     0.0000
--    0.0000     2.0000
diagCreate
  :: AFType (a :: *)
  => Array a
  -- ^	is the input array which is the diagonal
  -> Int
  -- ^ is the diagonal index
  -> Array a
diagCreate :: forall a. AFType a => Array a -> Int -> Array a
diagCreate Array a
x (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral -> CInt
n) =
  Array a
x Array a -> (Ptr AFArray -> AFArray -> IO AFErr) -> Array a
forall a.
Array a -> (Ptr AFArray -> AFArray -> IO AFErr) -> Array a
`op1` (\Ptr AFArray
p AFArray
a -> Ptr AFArray -> AFArray -> CInt -> IO AFErr
af_diag_create Ptr AFArray
p AFArray
a CInt
n)

-- | Create a diagonal matrix from input array when extract is set to false
--
-- >>> diagExtract (matrix @Double (2,2) [[1,2],[3,4]]) 0
-- ArrayFire Array
-- [2 1 1 1]
--     1.0000
--     4.0000
diagExtract
  :: AFType (a :: *)
  => Array a
  -> Int
  -> Array a
diagExtract :: forall a. AFType a => Array a -> Int -> Array a
diagExtract Array a
x (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral -> CInt
n) =
  Array a
x Array a -> (Ptr AFArray -> AFArray -> IO AFErr) -> Array a
forall a.
Array a -> (Ptr AFArray -> AFArray -> IO AFErr) -> Array a
`op1` (\Ptr AFArray
p AFArray
a -> Ptr AFArray -> AFArray -> CInt -> IO AFErr
af_diag_extract Ptr AFArray
p AFArray
a CInt
n)

-- | Join two Arrays together along a specified dimension
--
-- >>> join 0 (matrix @Double (2,2) [[1,2],[3,4]]) (matrix @Double (2,2) [[5,6],[7,8]])
-- ArrayFire Array
-- [4 2 1 1]
--     1.0000     3.0000
--     2.0000     4.0000
--     5.0000     7.0000
--     6.0000     8.0000
--
join
  :: Int
  -> Array (a :: *)
  -> Array a
  -> Array a
join :: forall a. Int -> Array a -> Array a -> Array a
join (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral -> CInt
n) Array a
arr1 Array a
arr2 = Array a
-> Array a
-> (Ptr AFArray -> AFArray -> AFArray -> IO AFErr)
-> Array a
forall b a.
Array b
-> Array a
-> (Ptr AFArray -> AFArray -> AFArray -> IO AFErr)
-> Array a
op2 Array a
arr1 Array a
arr2 (\Ptr AFArray
p AFArray
a AFArray
b -> Ptr AFArray -> CInt -> AFArray -> AFArray -> IO AFErr
af_join Ptr AFArray
p CInt
n AFArray
a AFArray
b)

-- | Join many Arrays together along a specified dimension
--
-- *FIX ME*
--
-- >>> joinMany 0 [1,2,3]
-- ArrayFire Array
-- [3 1 1 1]
--    1.0000     2.0000     3.0000
--
joinMany
  :: Int
  -> [Array a]
  -> Array a
joinMany :: forall a. Int -> [Array a] -> Array a
joinMany (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral -> CInt
n) [Array a]
arrays = IO (Array a) -> Array a
forall a. IO a -> a
unsafePerformIO (IO (Array a) -> Array a)
-> (IO (Array a) -> IO (Array a)) -> IO (Array a) -> Array a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO (Array a) -> IO (Array a)
forall a. IO a -> IO a
mask_ (IO (Array a) -> Array a) -> IO (Array a) -> Array a
forall a b. (a -> b) -> a -> b
$ do
  [ForeignPtr ()]
fptrs <- [Array a] -> (Array a -> IO (ForeignPtr ())) -> IO [ForeignPtr ()]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [Array a]
arrays ((Array a -> IO (ForeignPtr ())) -> IO [ForeignPtr ()])
-> (Array a -> IO (ForeignPtr ())) -> IO [ForeignPtr ()]
forall a b. (a -> b) -> a -> b
$ \(Array ForeignPtr ()
fptr) -> ForeignPtr () -> IO (ForeignPtr ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure ForeignPtr ()
fptr
  AFArray
newPtr <-
    (Ptr AFArray -> IO AFArray) -> IO AFArray
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr AFArray -> IO AFArray) -> IO AFArray)
-> (Ptr AFArray -> IO AFArray) -> IO AFArray
forall a b. (a -> b) -> a -> b
$ \Ptr AFArray
fPtrsPtr -> do
      [ForeignPtr ()] -> (ForeignPtr () -> IO ()) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [ForeignPtr ()]
fptrs ((ForeignPtr () -> IO ()) -> IO ())
-> (ForeignPtr () -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ForeignPtr ()
fptr ->
        ForeignPtr () -> (AFArray -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr ()
fptr (Ptr AFArray -> AFArray -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr AFArray
fPtrsPtr)
      (Ptr AFArray -> IO AFArray) -> IO AFArray
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr AFArray -> IO AFArray) -> IO AFArray)
-> (Ptr AFArray -> IO AFArray) -> IO AFArray
forall a b. (a -> b) -> a -> b
$ \Ptr AFArray
aPtr -> do
        Ptr AFArray -> IO ()
zeroOutArray Ptr AFArray
aPtr
        AFErr -> IO ()
throwAFError (AFErr -> IO ()) -> IO AFErr -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr AFArray -> CInt -> CUInt -> Ptr AFArray -> IO AFErr
af_join_many Ptr AFArray
aPtr CInt
n CUInt
nArrays Ptr AFArray
fPtrsPtr
        Ptr AFArray -> IO AFArray
forall a. Storable a => Ptr a -> IO a
peek Ptr AFArray
aPtr
  ForeignPtr () -> Array a
forall a. ForeignPtr () -> Array a
Array (ForeignPtr () -> Array a) -> IO (ForeignPtr ()) -> IO (Array a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
    FinalizerPtr () -> AFArray -> IO (ForeignPtr ())
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr ()
af_release_array_finalizer AFArray
newPtr
  where
    nArrays :: CUInt
nArrays = Int -> CUInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral ([Array a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Array a]
arrays)

-- | Tiles an Array according to specified dimensions
--
-- >>> tile @Double (scalar 22.0) [5,5]
-- ArrayFire Array
-- [5 5 1 1]
-- 22.0000    22.0000    22.0000    22.0000    22.0000
-- 22.0000    22.0000    22.0000    22.0000    22.0000
-- 22.0000    22.0000    22.0000    22.0000    22.0000
-- 22.0000    22.0000    22.0000    22.0000    22.0000
-- 22.0000    22.0000    22.0000    22.0000    22.0000
--
tile
  :: Array (a :: *)
  -> [Int]
  -> Array a
tile :: forall a. Array a -> [Int] -> Array a
tile Array a
a (Int -> [Int] -> [Int]
forall a. Int -> [a] -> [a]
take Int
4 ([Int] -> [Int]) -> ([Int] -> [Int]) -> [Int] -> [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++Int -> [Int]
forall a. a -> [a]
repeat Int
1) -> [Int
x,Int
y,Int
z,Int
w]) =
  Array a
a Array a -> (Ptr AFArray -> AFArray -> IO AFErr) -> Array a
forall a.
Array a -> (Ptr AFArray -> AFArray -> IO AFErr) -> Array a
`op1` (\Ptr AFArray
p AFArray
k -> Ptr AFArray
-> AFArray -> CUInt -> CUInt -> CUInt -> CUInt -> IO AFErr
af_tile Ptr AFArray
p AFArray
k (Int -> CUInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
x) (Int -> CUInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
y) (Int -> CUInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
z) (Int -> CUInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
w))
tile Array a
_ [Int]
_ = [Char] -> Array a
forall a. HasCallStack => [Char] -> a
error [Char]
"impossible"

-- | Reorders an Array according to newly specified dimensions
--
-- *FIX ME*
--
-- >>> reorder @Double (scalar 22.0) [5,5]
-- ArrayFire Array
-- [5 5 1 1]
-- 22.0000    22.0000    22.0000    22.0000    22.0000
-- 22.0000    22.0000    22.0000    22.0000    22.0000
-- 22.0000    22.0000    22.0000    22.0000    22.0000
-- 22.0000    22.0000    22.0000    22.0000    22.0000
-- 22.0000    22.0000    22.0000    22.0000    22.0000
--
reorder
  :: Array (a :: *)
  -> [Int]
  -> Array a
reorder :: forall a. Array a -> [Int] -> Array a
reorder Array a
a (Int -> [Int] -> [Int]
forall a. Int -> [a] -> [a]
take Int
4 ([Int] -> [Int]) -> ([Int] -> [Int]) -> [Int] -> [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++ Int -> [Int]
forall a. a -> [a]
repeat Int
0) -> [Int
x,Int
y,Int
z,Int
w]) =
  Array a
a Array a -> (Ptr AFArray -> AFArray -> IO AFErr) -> Array a
forall a.
Array a -> (Ptr AFArray -> AFArray -> IO AFErr) -> Array a
`op1` (\Ptr AFArray
p AFArray
k -> Ptr AFArray
-> AFArray -> CUInt -> CUInt -> CUInt -> CUInt -> IO AFErr
af_reorder Ptr AFArray
p AFArray
k (Int -> CUInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
x) (Int -> CUInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
y) (Int -> CUInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
z) (Int -> CUInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
w))
reorder Array a
_ [Int]
_ = [Char] -> Array a
forall a. HasCallStack => [Char] -> a
error [Char]
"impossible"

-- | Shift elements in an Array along a specified dimension (elements will wrap).
--
-- >>> shift (vector @Double 4 [1..]) 2 0 0 0
-- ArrayFire Array
-- [4 1 1 1]
--     3.0000
--     4.0000
--     1.0000
--     2.0000
--
shift
  :: Array (a :: *)
  -> Int
  -> Int
  -> Int
  -> Int
  -> Array a
shift :: forall a. Array a -> Int -> Int -> Int -> Int -> Array a
shift Array a
a (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral -> CInt
x) (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral -> CInt
y) (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral -> CInt
z) (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral -> CInt
w) =
  Array a
a Array a -> (Ptr AFArray -> AFArray -> IO AFErr) -> Array a
forall a.
Array a -> (Ptr AFArray -> AFArray -> IO AFErr) -> Array a
`op1` (\Ptr AFArray
p AFArray
k -> Ptr AFArray -> AFArray -> CInt -> CInt -> CInt -> CInt -> IO AFErr
af_shift Ptr AFArray
p AFArray
k CInt
x CInt
y CInt
z CInt
w)

-- | Modify dimensions of array
--
-- >>> moddims (vector @Double 3 [1..]) [1,3]
-- ArrayFire Array
-- [1 3 1 1]
--     1.0000     2.0000     3.0000
--
moddims
  :: forall a
   . Array (a :: *)
  -> [Int]
  -> Array a
moddims :: forall a. Array a -> [Int] -> Array a
moddims (Array ForeignPtr ()
fptr) [Int]
dims =
  IO (Array a) -> Array a
forall a. IO a -> a
unsafePerformIO (IO (Array a) -> Array a)
-> ((AFArray -> IO (Array a)) -> IO (Array a))
-> (AFArray -> IO (Array a))
-> Array a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO (Array a) -> IO (Array a)
forall a. IO a -> IO a
mask_ (IO (Array a) -> IO (Array a))
-> ((AFArray -> IO (Array a)) -> IO (Array a))
-> (AFArray -> IO (Array a))
-> IO (Array a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ForeignPtr () -> (AFArray -> IO (Array a)) -> IO (Array a)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr ()
fptr ((AFArray -> IO (Array a)) -> Array a)
-> (AFArray -> IO (Array a)) -> Array a
forall a b. (a -> b) -> a -> b
$ \AFArray
ptr -> do
    AFArray
newPtr <- (Ptr AFArray -> IO AFArray) -> IO AFArray
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr AFArray -> IO AFArray) -> IO AFArray)
-> (Ptr AFArray -> IO AFArray) -> IO AFArray
forall a b. (a -> b) -> a -> b
$ \Ptr AFArray
aPtr -> do
      Ptr AFArray -> IO ()
zeroOutArray Ptr AFArray
aPtr
      [DimT] -> (Ptr DimT -> IO AFArray) -> IO AFArray
forall a b. Storable a => [a] -> (Ptr a -> IO b) -> IO b
withArray (Int -> DimT
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> DimT) -> [Int] -> [DimT]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Int]
dims) ((Ptr DimT -> IO AFArray) -> IO AFArray)
-> (Ptr DimT -> IO AFArray) -> IO AFArray
forall a b. (a -> b) -> a -> b
$ \Ptr DimT
dimsPtr -> do
        AFErr -> IO ()
throwAFError (AFErr -> IO ()) -> IO AFErr -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr AFArray -> AFArray -> CUInt -> Ptr DimT -> IO AFErr
af_moddims Ptr AFArray
aPtr AFArray
ptr CUInt
n Ptr DimT
dimsPtr
        Ptr AFArray -> IO AFArray
forall a. Storable a => Ptr a -> IO a
peek Ptr AFArray
aPtr
    ForeignPtr () -> Array a
forall a. ForeignPtr () -> Array a
Array (ForeignPtr () -> Array a) -> IO (ForeignPtr ()) -> IO (Array a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FinalizerPtr () -> AFArray -> IO (ForeignPtr ())
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr ()
af_release_array_finalizer AFArray
newPtr
  where
    n :: CUInt
n = Int -> CUInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral ([Int] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
dims)

-- | Flatten an Array into a single dimension
--
-- >>> flat (matrix @Double (2,2) [[1..],[1..]])
-- ArrayFire Array
-- [4 1 1 1]
--     1.0000
--     2.0000
--     1.0000
--     2.0000
--
-- >>> flat $ cube @Int (2,2,2) [[[1,1],[1,1]],[[1,1],[1,1]]]
-- ArrayFire Array
-- [8 1 1 1]
--          1
--          1
--          1
--          1
--          1
--          1
--          1
--          1
--
flat
  :: Array a
  -> Array a
flat :: forall a. Array a -> Array a
flat = (Array a -> (Ptr AFArray -> AFArray -> IO AFErr) -> Array a
forall a.
Array a -> (Ptr AFArray -> AFArray -> IO AFErr) -> Array a
`op1` Ptr AFArray -> AFArray -> IO AFErr
af_flat)

-- | Flip the values of an Array along a specified dimension
--
-- >>> matrix @Double (2,2) [[2,2],[3,3]]
-- ArrayFire Array
-- [2 2 1 1]
--     2.0000     3.0000
--     2.0000     3.0000
--
-- >>> A.flip (matrix @Double (2,2) [[2,2],[3,3]]) 1
-- ArrayFire Array
-- [2 2 1 1]
--     3.0000     2.0000
--     3.0000     2.0000
--
flip
  :: Array a
  -> Int
  -> Array a
flip :: forall a. Array a -> Int -> Array a
flip Array a
a (Int -> CUInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral -> CUInt
dim) =
  Array a
a Array a -> (Ptr AFArray -> AFArray -> IO AFErr) -> Array a
forall a.
Array a -> (Ptr AFArray -> AFArray -> IO AFErr) -> Array a
`op1` (\Ptr AFArray
p AFArray
k -> Ptr AFArray -> AFArray -> CUInt -> IO AFErr
af_flip Ptr AFArray
p AFArray
k CUInt
dim)

-- | Create a lower triangular matrix from input array.
--
-- >>> lower (constant [2,2] 10 :: Array Double) True
-- ArrayFire Array
-- [2 2 1 1]
--     1.0000     0.0000
--    10.0000     1.0000
--
lower
  :: Array a
  -- ^ is the input matrix
  -> Bool
  -- ^ boolean parameter specifying if the diagonal elements should be 1
  -> Array a
lower :: forall a. Array a -> Bool -> Array a
lower Array a
a (Int -> CBool
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> CBool) -> (Bool -> Int) -> Bool -> CBool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Int
forall a. Enum a => a -> Int
fromEnum -> CBool
b) =
  Array a
a Array a -> (Ptr AFArray -> AFArray -> IO AFErr) -> Array a
forall a.
Array a -> (Ptr AFArray -> AFArray -> IO AFErr) -> Array a
`op1` (\Ptr AFArray
p AFArray
k -> Ptr AFArray -> AFArray -> CBool -> IO AFErr
af_lower Ptr AFArray
p AFArray
k CBool
b)

-- | Create an upper triangular matrix from input array.
--
-- >>> upper (constant [2,2] 10 :: Array Double) True
-- ArrayFire Array
-- [2 2 1 1]
--    1.0000     10.0000
--    0.0000     1.0000
--
upper
  :: Array a
  -> Bool
  -> Array a
upper :: forall a. Array a -> Bool -> Array a
upper Array a
a (Int -> CBool
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> CBool) -> (Bool -> Int) -> Bool -> CBool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Int
forall a. Enum a => a -> Int
fromEnum -> CBool
b) =
  Array a
a Array a -> (Ptr AFArray -> AFArray -> IO AFErr) -> Array a
forall a.
Array a -> (Ptr AFArray -> AFArray -> IO AFErr) -> Array a
`op1` (\Ptr AFArray
p AFArray
k -> Ptr AFArray -> AFArray -> CBool -> IO AFErr
af_upper Ptr AFArray
p AFArray
k CBool
b)

-- | Selects elements from two arrays based on the values of a binary conditional array.
--
-- >>> cond = vector @CBool 5 [1,0,1,0,1]
-- >>> arr1 = vector @Double 5 (repeat 1)
-- >>> arr2 = vector @Double 5 (repeat 2)
-- >>> select cond arr1 arr2
-- ArrayFire Array
-- [5 1 1 1]
--     1.0000
--     2.0000
--     1.0000
--     2.0000
--     1.0000
--
select
  :: Array CBool
  -- ^ is the conditional array
  -> Array a
  -- ^ is the array containing elements from the true part of the condition
  -> Array a
  -- ^	is the array containing elements from the false part of the condition
  -> Array a
  -- ^ is the output containing elements of a when cond is true else elements from b
select :: forall a. Array CBool -> Array a -> Array a -> Array a
select Array CBool
a Array a
b Array a
c = Array CBool
-> Array a
-> Array a
-> (Ptr AFArray -> AFArray -> AFArray -> AFArray -> IO AFErr)
-> Array a
forall b a.
Array b
-> Array a
-> Array a
-> (Ptr AFArray -> AFArray -> AFArray -> AFArray -> IO AFErr)
-> Array a
op3 Array CBool
a Array a
b Array a
c Ptr AFArray -> AFArray -> AFArray -> AFArray -> IO AFErr
af_select

-- | Selects elements from two arrays based on the values of a binary conditional array.
--
-- <http://arrayfire.org/docs/group__data__func__select.htm#gab6886120d0bac4717276910e468bbe88>
--
-- >>> cond = vector @CBool 5 [1,0,1,0,1]
-- >>> arr1 = vector @Double 5 (repeat 1)
-- >>> x = 99
-- >>> selectScalarR cond arr1 x
-- ArrayFire Array
-- [5 1 1 1]
--     1.0000
--    99.0000
--     1.0000
--    99.0000
--     1.0000
--
selectScalarR
  :: Array CBool
  -- ^ is the conditional array
  -> Array a
  -- ^ is the array containing elements from the true part of the condition
  -> Double
  -- ^	is a scalar assigned to out when cond is false
  -> Array a
  -- ^ the output containing elements of a when cond is true else elements from b
selectScalarR :: forall a. Array CBool -> Array a -> Double -> Array a
selectScalarR Array CBool
a Array a
b Double
c = Array CBool
-> Array a
-> (Ptr AFArray -> AFArray -> AFArray -> IO AFErr)
-> Array a
forall b a.
Array b
-> Array a
-> (Ptr AFArray -> AFArray -> AFArray -> IO AFErr)
-> Array a
op2 Array CBool
a Array a
b (\Ptr AFArray
p AFArray
w AFArray
x -> Ptr AFArray -> AFArray -> AFArray -> Double -> IO AFErr
af_select_scalar_r Ptr AFArray
p AFArray
w AFArray
x Double
c)

-- | Selects elements from two arrays based on the values of a binary conditional array.
--
-- [ArrayFire Docs](http://arrayfire.org/docs/group__data__func__select.htm#ga0ccdc05779f88cab5095bce987c2da9d)
--
-- >>> cond = vector @CBool 5 [1,0,1,0,1]
-- >>> arr1 = vector @Double 5 (repeat 1)
-- >>> x = 99
-- >>> selectScalarL cond x arr1
-- ArrayFire Array
-- [5 1 1 1]
--    99.0000
--     1.0000
--    99.0000
--     1.0000
--    99.0000
--
selectScalarL
  :: Array CBool
  -- ^ the conditional array
  -> Double
  -- ^ a scalar assigned to out when cond is true
  -> Array a
  -- ^ the array containing elements from the false part of the condition
  -> Array a
  -- ^ is the output containing elements of a when cond is true else elements from b
selectScalarL :: forall a. Array CBool -> Double -> Array a -> Array a
selectScalarL Array CBool
a Double
n Array a
b = Array CBool
-> Array a
-> (Ptr AFArray -> AFArray -> AFArray -> IO AFErr)
-> Array a
forall b a.
Array b
-> Array a
-> (Ptr AFArray -> AFArray -> AFArray -> IO AFErr)
-> Array a
op2 Array CBool
a Array a
b (\Ptr AFArray
p AFArray
w AFArray
x -> Ptr AFArray -> AFArray -> Double -> AFArray -> IO AFErr
af_select_scalar_l Ptr AFArray
p AFArray
w Double
n AFArray
x)

-- af_err af_replace(af_array a, const af_array cond, const af_array b);
-- af_err af_replace_scalar(af_array a, const af_array cond, const double b);