hasktorch-indef-0.0.1.0: src/Torch/Indef/Dynamic/Tensor/Math/Pointwise.hs
-------------------------------------------------------------------------------
-- |
-- Module : Torch.Indef.Dynamic.Tensor.Math.Pointwise
-- Copyright : (c) Sam Stites 2017
-- License : BSD3
-- Maintainer: sam@stites.io
-- Stability : experimental
-- Portability: non-portable
--
-- Element-wise functions.
-------------------------------------------------------------------------------
{-# OPTIONS_GHC -fno-cse #-}
module Torch.Indef.Dynamic.Tensor.Math.Pointwise
( cross
, sign_ , sign
, clamp_ , clamp
, cadd_ , cadd , (^+^)
, csub_ , csub , (^-^)
, cmul_ , cmul , (^*^) , square
, cdiv_ , cdiv , (^/^)
, cpow_ , cpow
, clshift_ , clshift
, crshift_ , crshift
, cfmod_ , cfmod
, cremainder_ , cremainder
, cmax_ , cmax
, cmin_ , cmin
, cmaxValue_ , cmaxValue
, cminValue_ , cminValue
, cbitand_ , cbitand
, cbitor_ , cbitor
, cbitxor_ , cbitxor
, addcmul_ , addcmul
, addcdiv_ , addcdiv
) where
import System.IO.Unsafe
import Debug.Trace
import Torch.Indef.Types
import Torch.Indef.Dynamic.Tensor
import qualified Torch.Sig.Tensor.Math.Pointwise as Sig
-- | Replaces all elements in-place with the sign of the elements of the tensor.
sign_ :: Dynamic -> IO ()
sign_ a = _sign a a
-- | Returns a new Tensor with the sign (+/- 1) of the elements of a tensor
sign :: Dynamic -> Dynamic
sign t = unsafeDupablePerformIO $ do
let r = empty
_sign r t
pure r
{-# NOINLINE sign #-}
-- | returns the cross product of vectors in the specified dimension
--
-- a and b must have the same size, and both @a:size(n)@ and @b:size(n)@ must be 3.
cross
:: Dynamic -- ^ tensor a
-> Dynamic -- ^ tensor b (same size as tensor a in dimension below)
-> Word -- ^ dimension to operate over
-> Dynamic -- ^ new return tensor
cross a b di = unsafeDupablePerformIO $ do
let r = empty
_cross r a b di
pure r
{-# NOINLINE cross #-}
-- | Clamp all elements, inplace, in the tensor into the range @[min_value, max_value]@. ie:
--
-- @
-- { min_value, if x_i < min_value
-- y_i = { x_i, if min_value ≤ x_i ≤ max_value
-- { max_value, if x_i > max_value
-- @
clamp_ :: Dynamic -> HsReal -> HsReal -> IO ()
clamp_ t a b = _clamp t t a b
-- | pure version of 'clamp_' returning a new tensor as output.
clamp :: Dynamic -> HsReal -> HsReal -> Dynamic
clamp t a b = unsafeDupablePerformIO $ do
let r = new' (getSomeDims t)
_clamp r t a b
pure r
{-# NOINLINE clamp #-}
-- | Multiply elements of tensor2 by the scalar value and add it to tensor1.
-- The number of elements must match, but sizes do not matter.
--
-- Stores the result in tensor1.
cadd_
:: Dynamic -- ^ tensor1
-> HsReal -- ^ scale term to multiply againts tensor2
-> Dynamic -- ^ tensor2
-> IO ()
cadd_ t v b = _cadd t t v b
-- | Multiply elements of tensor2 by the scalar value and add it to tensor1.
-- The number of elements must match, but sizes do not matter.
cadd
:: Dynamic -- ^ tensor1
-> HsReal -- ^ scale term to multiply againts tensor2
-> Dynamic -- ^ tensor2
-> Dynamic
cadd t v b = unsafeDupablePerformIO $ do
let r = new' (getSomeDims t)
_cadd r t v b
pure r
{-# NOINLINE cadd #-}
-- | inline alias to 'cadd'
(^+^) :: Dynamic -> Dynamic -> Dynamic
(^+^) a b = cadd a 1 b
-- | Multiply elements of tensor2 by the scalar value and subtract it from tensor1.
-- The number of elements must match, but sizes do not matter.
--
-- Stores the result in tensor1.
csub_
:: Dynamic -- ^ tensor1
-> HsReal -- ^ scale term to multiply againts tensor2
-> Dynamic -- ^ tensor2
-> IO ()
csub_ t v b = _csub t t v b
-- | Multiply elements of tensor2 by the scalar value and subtract it from tensor1.
-- The number of elements must match, but sizes do not matter.
csub
:: Dynamic -- ^ tensor1
-> HsReal -- ^ scale term to multiply againts tensor2
-> Dynamic -- ^ tensor2
-> Dynamic
csub t v b = unsafeDupablePerformIO $ do
let r = new' (getSomeDims t)
_csub r t v b
pure r
{-# NOINLINE csub #-}
-- | inline alias to 'csub'
(^-^) :: Dynamic -> Dynamic -> Dynamic
(^-^) a b = csub a 1 b
-- | Performs the element-wise multiplication of tensor1 by tensor2. The number of elements must match,
-- but sizes do not matter.
--
-- Stores the result in tensor1.
cmul_
:: Dynamic -- ^ tensor1
-> Dynamic -- ^ tensor2
-> IO ()
cmul_ t1 t2 = _cmul t1 t1 t2
-- | Performs the element-wise multiplication of tensor1 by tensor2. The number of elements must match,
-- but sizes do not matter.
cmul
:: Dynamic -- ^ tensor1
-> Dynamic -- ^ tensor2
-> Dynamic
cmul t1 t2 = unsafeDupablePerformIO $ do
let r = new' (getSomeDims t1)
_cmul r t1 t2
pure r
{-# NOINLINE cmul #-}
-- | square a tensor.
--
-- FIXME: this is a call to 'cmul' but it might be better to use 'pow'
square :: Dynamic -> Dynamic
square t = cmul t t
-- | inline alias to 'cmul'
(^*^) :: Dynamic -> Dynamic -> Dynamic
(^*^) = cmul
-- | Performs the element-wise division of tensor1 by tensor2. The number of elements must match,
-- but sizes do not matter.
--
-- Stores the result in tensor1.
cdiv_
:: Dynamic -- ^ tensor1
-> Dynamic -- ^ tensor2
-> IO ()
cdiv_ t1 t2 = _cdiv t1 t1 t2
-- | Performs the element-wise division of tensor1 by tensor2. The number of elements must match,
-- but sizes do not matter.
cdiv
:: Dynamic -- ^ tensor1
-> Dynamic -- ^ tensor2
-> Dynamic
cdiv t1 t2 = unsafeDupablePerformIO $ do
let r = new' (getSomeDims t1)
_cdiv r t1 t2
pure r
{-# NOINLINE cdiv #-}
-- | inline alias to 'cdiv'
(^/^) :: Dynamic -> Dynamic -> Dynamic
(^/^) = cdiv
-- | Element-wise power operation, taking the elements of tensor1 to the powers given by elements
-- of tensor2. The number of elements must match, but sizes do not matter.
--
-- Stores the result in tensor1.
cpow_
:: Dynamic -- ^ tensor1
-> Dynamic -- ^ tensor2
-> IO ()
cpow_ t = _cpow t t
-- | Element-wise power operation, taking the elements of tensor1 to the powers given by elements
-- of tensor2. The number of elements must match, but sizes do not matter.
cpow
:: Dynamic -- ^ tensor1
-> Dynamic -- ^ tensor2
-> Dynamic
cpow = _mkNewFunction _cpow
-- | Element-wise, inplace, bitwise left shift. Mutates the first argument.
clshift_ :: Dynamic -> Dynamic -> IO ()
clshift_ t = _clshift t t
-- | Element-wise bitwise left shift.
clshift :: Dynamic -> Dynamic -> Dynamic
clshift = _mkNewFunction _clshift
-- | Element-wise, inplace, bitwise right shift. Mutates the first argument.
crshift_ :: Dynamic -> Dynamic -> IO ()
crshift_ t = _crshift t t
-- | Element-wise bitwise right shift.
crshift :: Dynamic -> Dynamic -> Dynamic
crshift = _mkNewFunction _crshift
-- | Computes the element-wise remainder of the division (rounded towards zero)
-- of tensor1 by tensor2. The number of elements must match, but sizes do not matter.
--
-- Stores the result in tensor1.
cfmod_
:: Dynamic -- ^ tensor1
-> Dynamic -- ^ tensor2
-> IO ()
cfmod_ t = _cfmod t t
-- | Computes the element-wise remainder of the division (rounded towards zero)
-- of tensor1 by tensor2. The number of elements must match, but sizes do not matter.
cfmod
:: Dynamic -- ^ tensor1
-> Dynamic -- ^ tensor2
-> Dynamic
cfmod = _mkNewFunction _cfmod
-- | Computes element-wise remainder of the division (rounded to nearest) of
-- tensor1 by tensor2. The number of elements must match, but sizes do not matter.
--
-- Stores the result in tensor1.
cremainder_
:: Dynamic -- ^ tensor1
-> Dynamic -- ^ tensor2
-> IO ()
cremainder_ t = _cremainder t t
-- | Computes element-wise remainder of the division (rounded to nearest) of
-- tensor1 by tensor2. The number of elements must match, but sizes do not matter.
cremainder
:: Dynamic -- ^ tensor1
-> Dynamic -- ^ tensor2
-> Dynamic
cremainder = _mkNewFunction _cremainder
-- | Element-wise, inplace, max function -- storing the higher value. Mutates the first argument.
cmax_ :: Dynamic -> Dynamic -> IO ()
cmax_ t = _cmax t t
-- | Element-wise max function -- keeping the higher value.
cmax :: Dynamic -> Dynamic -> Dynamic
cmax = _mkNewFunction _cmax
-- | Element-wise, inplace, min function -- storing the lower value. Mutates the first argument.
cmin_ :: Dynamic -> Dynamic -> IO ()
cmin_ t = _cmin t t
-- | Element-wise min function -- keeping the lower value.
cmin :: Dynamic -> Dynamic -> Dynamic
cmin = _mkNewFunction _cmin
-- | Store the maximum of the tensor and a scalar in the input tensor on an element-by-element basis.
cmaxValue_ :: Dynamic -> HsReal -> IO ()
cmaxValue_ t v = _cmaxValue t t v
-- | Store the maximum of the tensor and a scalar in a new tensor on an element-by-element basis.
cmaxValue :: Dynamic -> HsReal -> Dynamic
cmaxValue t v = unsafeDupablePerformIO $ do
let r = empty
_cmaxValue r t v
pure r
{-# NOINLINE cmaxValue #-}
-- | Store the minimum of the tensor and a scalar in the input tensor on an element-by-element basis.
cminValue_ :: Dynamic -> HsReal -> IO ()
cminValue_ t v = _cminValue t t v
-- | Store the minimum of the tensor and a scalar in a new tensor on an element-by-element basis.
cminValue :: Dynamic -> HsReal -> Dynamic
cminValue t v = unsafeDupablePerformIO $ do
let r = empty
_cminValue r t v
pure r
{-# NOINLINE cminValue #-}
-- | Element-wise, inplace, bitwise @and@. Mutates the first argument.
cbitand_ :: Dynamic -> Dynamic -> IO ()
cbitand_ t = _cbitand t t
-- | Element-wise, bitwise @and@
cbitand :: Dynamic -> Dynamic -> Dynamic
cbitand = _mkNewFunction _cbitand
-- | Element-wise, inplace, bitwise @or@. Mutates the first argument.
cbitor_ :: Dynamic -> Dynamic -> IO ()
cbitor_ t = _cbitor t t
-- | Element-wise, bitwise @or@
cbitor :: Dynamic -> Dynamic -> Dynamic
cbitor = _mkNewFunction _cbitor
-- | Element-wise, inplace, bitwise @xor@. Mutates the first argument.
cbitxor_ :: Dynamic -> Dynamic -> IO ()
cbitxor_ t = _cbitxor t t
-- | Element-wise, bitwise @xor@
cbitxor :: Dynamic -> Dynamic -> Dynamic
cbitxor = _mkNewFunction _cbitxor
-- | Performs the element-wise multiplication of tensor1 by tensor2, multiplies
-- the result by the scalar value and adds it to tensor0, which it mutates inplace.
--
-- The number of elements must match, but sizes do not matter.
addcmul_
:: Dynamic -- ^ tensor0
-> HsReal -- ^ scale term
-> Dynamic -- ^ tensor1
-> Dynamic -- ^ tensor2
-> IO ()
addcmul_ a v b c = _addcmul a a v b c
-- | Performs the element-wise multiplication of tensor1 by tensor2, multiplies
-- the result by the scalar value and adds it to tensor0.
--
-- The number of elements must match, but sizes do not matter.
addcmul
:: Dynamic -- ^ tensor0
-> HsReal -- ^ scale term
-> Dynamic -- ^ tensor1
-> Dynamic -- ^ tensor2
-> Dynamic
addcmul a v b c = unsafeDupablePerformIO $ do
let r = empty
_addcmul r a v b c
pure r
{-# NOINLINE addcmul #-}
-- | Performs the element-wise multiplication of tensor1 by tensor2, multiplies
-- the result by the scalar value and adds it to tensor0, which it mutates inplace.
--
-- The number of elements must match, but sizes do not matter.
addcdiv_
:: Dynamic -- ^ tensor0
-> HsReal -- ^ scale term
-> Dynamic -- ^ tensor1
-> Dynamic -- ^ tensor2
-> IO ()
addcdiv_ a = _addcdiv a a
-- | Performs the element-wise division of tensor1 by tensor2, multiplies
-- the result by the scalar value and adds it to tensor0.
--
-- The number of elements must match, but sizes do not matter.
addcdiv
:: Dynamic -- ^ tensor0
-> HsReal -- ^ scale term
-> Dynamic -- ^ tensor1
-> Dynamic -- ^ tensor2
-> Dynamic
addcdiv a v b c = unsafeDupablePerformIO $ do
let r = empty
_addcdiv r a v b c
pure r
{-# NOINLINE addcdiv #-}
-- ========================================================================= --
-- raw C-level calls
_sign :: Dynamic -> Dynamic -> IO ()
_sign r t = withLift $ Sig.c_sign
<$> managedState
<*> managedTensor r
<*> managedTensor t
_cross :: Dynamic -> Dynamic -> Dynamic -> Word -> IO ()
_cross t0 t1 t2 i0 = withLift $ Sig.c_cross
<$> managedState
<*> managedTensor t0
<*> managedTensor t1
<*> managedTensor t2
<*> pure (fromIntegral i0)
_clamp :: Dynamic -> Dynamic -> HsReal -> HsReal -> IO ()
_clamp r t v0 v1 = withLift $ Sig.c_clamp
<$> managedState
<*> managedTensor r
<*> managedTensor t
<*> pure (hs2cReal v0)
<*> pure (hs2cReal v1)
_cmax :: Dynamic -> Dynamic -> Dynamic -> IO ()
_cmax r t0 t1 = withLift $ Sig.c_cmax
<$> managedState
<*> managedTensor r
<*> managedTensor t0
<*> managedTensor t1
_cmin :: Dynamic -> Dynamic -> Dynamic -> IO ()
_cmin r t0 t1 = withLift $ Sig.c_cmin
<$> managedState
<*> managedTensor r
<*> managedTensor t0
<*> managedTensor t1
_cmaxValue :: Dynamic -> Dynamic -> HsReal -> IO ()
_cmaxValue r t v = withLift $ Sig.c_cmaxValue
<$> managedState
<*> managedTensor r
<*> managedTensor t
<*> pure (hs2cReal v)
_cminValue :: Dynamic -> Dynamic -> HsReal -> IO ()
_cminValue r t v = withLift $ Sig.c_cminValue
<$> managedState
<*> managedTensor r
<*> managedTensor t
<*> pure (hs2cReal v)
_addcmul :: Dynamic -> Dynamic -> HsReal -> Dynamic -> Dynamic -> IO ()
_addcmul t0 t1 v t2 t3 = withLift $ Sig.c_addcmul
<$> managedState
<*> managedTensor t0
<*> managedTensor t1
<*> pure (hs2cReal v)
<*> managedTensor t2
<*> managedTensor t3
_addcdiv :: Dynamic -> Dynamic -> HsReal -> Dynamic -> Dynamic -> IO ()
_addcdiv t0 t1 v t2 t3 = withLift $ Sig.c_addcdiv
<$> managedState
<*> managedTensor t0
<*> managedTensor t1
<*> pure (hs2cReal v)
<*> managedTensor t2
<*> managedTensor t3
_cadd :: Dynamic -> Dynamic -> HsReal -> Dynamic -> IO ()
_cadd t0 t1 v t2 = withLift $ Sig.c_cadd
<$> managedState
<*> managedTensor t0
<*> managedTensor t1
<*> pure (hs2cReal v)
<*> managedTensor t2
_csub :: Dynamic -> Dynamic -> HsReal -> Dynamic -> IO ()
_csub t0 t1 v t2 = withLift $ Sig.c_csub
<$> managedState
<*> managedTensor t0
<*> managedTensor t1
<*> pure (hs2cReal v)
<*> managedTensor t2
_cmul :: Dynamic -> Dynamic -> Dynamic -> IO ()
_cmul r t0 t1 = withLift $ Sig.c_cmul
<$> managedState
<*> managedTensor r
<*> managedTensor t0
<*> managedTensor t1
_cpow :: Dynamic -> Dynamic -> Dynamic -> IO ()
_cpow r t0 t1 = withLift $ Sig.c_cpow
<$> managedState
<*> managedTensor r
<*> managedTensor t0
<*> managedTensor t1
_cdiv :: Dynamic -> Dynamic -> Dynamic -> IO ()
_cdiv r t0 t1 = withLift $ Sig.c_cdiv
<$> managedState
<*> managedTensor r
<*> managedTensor t0
<*> managedTensor t1
_clshift :: Dynamic -> Dynamic -> Dynamic -> IO ()
_clshift r t0 t1 = withLift $ Sig.c_clshift
<$> managedState
<*> managedTensor r
<*> managedTensor t0
<*> managedTensor t1
_crshift :: Dynamic -> Dynamic -> Dynamic -> IO ()
_crshift r t0 t1 = withLift $ Sig.c_crshift
<$> managedState
<*> managedTensor r
<*> managedTensor t0
<*> managedTensor t1
_cfmod :: Dynamic -> Dynamic -> Dynamic -> IO ()
_cfmod r t0 t1 = withLift $ Sig.c_cfmod
<$> managedState
<*> managedTensor r
<*> managedTensor t0
<*> managedTensor t1
_cremainder :: Dynamic -> Dynamic -> Dynamic -> IO ()
_cremainder r t0 t1 = withLift $ Sig.c_cremainder
<$> managedState
<*> managedTensor r
<*> managedTensor t0
<*> managedTensor t1
_cbitand :: Dynamic -> Dynamic -> Dynamic -> IO ()
_cbitand r t0 t1 = withLift $ Sig.c_cbitand
<$> managedState
<*> managedTensor r
<*> managedTensor t0
<*> managedTensor t1
_cbitor :: Dynamic -> Dynamic -> Dynamic -> IO ()
_cbitor r t0 t1 = withLift $ Sig.c_cbitor
<$> managedState
<*> managedTensor r
<*> managedTensor t0
<*> managedTensor t1
_cbitxor :: Dynamic -> Dynamic -> Dynamic -> IO ()
_cbitxor r t0 t1 = withLift $ Sig.c_cbitxor
<$> managedState
<*> managedTensor r
<*> managedTensor t0
<*> managedTensor t1
-- ========================================================================= --
-- helper functions
_mkNewFunction :: (Dynamic -> Dynamic -> Dynamic -> IO ()) -> Dynamic -> Dynamic -> Dynamic
_mkNewFunction op t1 t2 = unsafeDupablePerformIO $ do
let r = empty
op r t1 t2
pure r