{-# LANGUAGE ConstraintKinds  #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeOperators    #-}
-- |
-- Module      : Data.Array.Accelerate.Math.DFT.Centre
-- Copyright   : [2012..2020] The Accelerate Team
-- License     : BSD3
--
-- Maintainer  : Trevor L. McDonell <trevor.mcdonell@gmail.com>
-- Stability   : experimental
-- Portability : non-portable (GHC extensions)
--
-- These transforms allow the centering of the frequency domain of a DFT such
-- that the zero frequency is in the middle. The centering transform, when
-- performed on the input of a DFT, will cause zero frequency to be centred in
-- the middle. The shifting transform however takes the output of a DFT to give
-- the same result. Therefore the relationship between the two is:
--
-- > fft(center(X)) = shift(fft(X))
--
module Data.Array.Accelerate.Math.DFT.Centre (

  centre1D, centre2D, centre3D,
  shift1D,  shift2D,  shift3D,
  ishift1D,  ishift2D,  ishift3D,

) where

import Prelude                                  as P
import Data.Array.Accelerate                    as A
import Data.Array.Accelerate.Data.Complex


-- | Apply the centring transform to a vector
--
centre1D
    :: (A.RealFloat e, A.FromIntegral Int e)
    => Acc (Array DIM1 (Complex e))
    -> Acc (Array DIM1 (Complex e))
centre1D :: Acc (Array DIM1 (Complex e)) -> Acc (Array DIM1 (Complex e))
centre1D Acc (Array DIM1 (Complex e))
arr
  = Exp DIM1
-> (Exp DIM1 -> Exp (Complex e)) -> Acc (Array DIM1 (Complex e))
forall sh a.
(Shape sh, Elt a) =>
Exp sh -> (Exp sh -> Exp a) -> Acc (Array sh a)
A.generate (Acc (Array DIM1 (Complex e)) -> Exp DIM1
forall sh e. (Shape sh, Elt e) => Acc (Array sh e) -> Exp sh
shape Acc (Array DIM1 (Complex e))
arr)
               (\Exp DIM1
ix -> let Z
Z :. Exp Int
x = Exp (Plain (Z :. Exp Int)) -> Z :. Exp Int
forall (c :: * -> *) e. Unlift c e => c (Plain e) -> e
unlift Exp (Plain (Z :. Exp Int))
Exp DIM1
ix           :: Z :. Exp Int
                       in  Complex (Exp e) -> Exp (Plain (Complex (Exp e)))
forall (c :: * -> *) e. Lift c e => e -> c (Plain e)
lift (((-Exp e
1) Exp e -> Exp e -> Exp e
forall a. Floating a => a -> a -> a
** Exp Int -> Exp e
forall a b. (FromIntegral a b, Integral a) => Exp a -> Exp b
A.fromIntegral Exp Int
x) Exp e -> Exp e -> Complex (Exp e)
forall a. a -> a -> Complex a
:+ Exp e
0) Exp (Complex e) -> Exp (Complex e) -> Exp (Complex e)
forall a. Num a => a -> a -> a
* Acc (Array DIM1 (Complex e))
arrAcc (Array DIM1 (Complex e)) -> Exp DIM1 -> Exp (Complex e)
forall sh e.
(Shape sh, Elt e) =>
Acc (Array sh e) -> Exp sh -> Exp e
!Exp DIM1
ix)

-- | Apply the centring transform to a matrix
--
centre2D
    :: (A.RealFloat e, A.FromIntegral Int e)
    => Acc (Array DIM2 (Complex e))
    -> Acc (Array DIM2 (Complex e))
centre2D :: Acc (Array DIM2 (Complex e)) -> Acc (Array DIM2 (Complex e))
centre2D Acc (Array DIM2 (Complex e))
arr
  = Exp DIM2
-> (Exp DIM2 -> Exp (Complex e)) -> Acc (Array DIM2 (Complex e))
forall sh a.
(Shape sh, Elt a) =>
Exp sh -> (Exp sh -> Exp a) -> Acc (Array sh a)
A.generate (Acc (Array DIM2 (Complex e)) -> Exp DIM2
forall sh e. (Shape sh, Elt e) => Acc (Array sh e) -> Exp sh
shape Acc (Array DIM2 (Complex e))
arr)
               (\Exp DIM2
ix -> let Z
Z :. Exp Int
y :. Exp Int
x = Exp (Plain ((Z :. Exp Int) :. Exp Int))
-> (Z :. Exp Int) :. Exp Int
forall (c :: * -> *) e. Unlift c e => c (Plain e) -> e
unlift Exp (Plain ((Z :. Exp Int) :. Exp Int))
Exp DIM2
ix      :: Z :. Exp Int :. Exp Int
                       in  Complex (Exp e) -> Exp (Plain (Complex (Exp e)))
forall (c :: * -> *) e. Lift c e => e -> c (Plain e)
lift (((-Exp e
1) Exp e -> Exp e -> Exp e
forall a. Floating a => a -> a -> a
** Exp Int -> Exp e
forall a b. (FromIntegral a b, Integral a) => Exp a -> Exp b
A.fromIntegral (Exp Int
y Exp Int -> Exp Int -> Exp Int
forall a. Num a => a -> a -> a
+ Exp Int
x)) Exp e -> Exp e -> Complex (Exp e)
forall a. a -> a -> Complex a
:+ Exp e
0) Exp (Complex e) -> Exp (Complex e) -> Exp (Complex e)
forall a. Num a => a -> a -> a
* Acc (Array DIM2 (Complex e))
arrAcc (Array DIM2 (Complex e)) -> Exp DIM2 -> Exp (Complex e)
forall sh e.
(Shape sh, Elt e) =>
Acc (Array sh e) -> Exp sh -> Exp e
!Exp DIM2
ix)

-- | Apply the centring transform to a 3D array
--
centre3D
    :: (A.RealFloat e, A.FromIntegral Int e)
    => Acc (Array DIM3 (Complex e))
    -> Acc (Array DIM3 (Complex e))
centre3D :: Acc (Array DIM3 (Complex e)) -> Acc (Array DIM3 (Complex e))
centre3D Acc (Array DIM3 (Complex e))
arr
  = Exp DIM3
-> (Exp DIM3 -> Exp (Complex e)) -> Acc (Array DIM3 (Complex e))
forall sh a.
(Shape sh, Elt a) =>
Exp sh -> (Exp sh -> Exp a) -> Acc (Array sh a)
A.generate (Acc (Array DIM3 (Complex e)) -> Exp DIM3
forall sh e. (Shape sh, Elt e) => Acc (Array sh e) -> Exp sh
shape Acc (Array DIM3 (Complex e))
arr)
               (\Exp DIM3
ix -> let Z
Z :. Exp Int
z :. Exp Int
y :. Exp Int
x = Exp (Plain (((Z :. Exp Int) :. Exp Int) :. Exp Int))
-> ((Z :. Exp Int) :. Exp Int) :. Exp Int
forall (c :: * -> *) e. Unlift c e => c (Plain e) -> e
unlift Exp (Plain (((Z :. Exp Int) :. Exp Int) :. Exp Int))
Exp DIM3
ix :: Z :. Exp Int :. Exp Int :. Exp Int
                       in  Complex (Exp e) -> Exp (Plain (Complex (Exp e)))
forall (c :: * -> *) e. Lift c e => e -> c (Plain e)
lift (((-Exp e
1) Exp e -> Exp e -> Exp e
forall a. Floating a => a -> a -> a
** Exp Int -> Exp e
forall a b. (FromIntegral a b, Integral a) => Exp a -> Exp b
A.fromIntegral (Exp Int
z Exp Int -> Exp Int -> Exp Int
forall a. Num a => a -> a -> a
+ Exp Int
y Exp Int -> Exp Int -> Exp Int
forall a. Num a => a -> a -> a
+ Exp Int
x)) Exp e -> Exp e -> Complex (Exp e)
forall a. a -> a -> Complex a
:+ Exp e
0) Exp (Complex e) -> Exp (Complex e) -> Exp (Complex e)
forall a. Num a => a -> a -> a
* Acc (Array DIM3 (Complex e))
arrAcc (Array DIM3 (Complex e)) -> Exp DIM3 -> Exp (Complex e)
forall sh e.
(Shape sh, Elt e) =>
Acc (Array sh e) -> Exp sh -> Exp e
!Exp DIM3
ix)


-- | Apply the shifting transform to a vector
--
shift1D :: Elt e => Acc (Vector e) -> Acc (Vector e)
shift1D :: Acc (Vector e) -> Acc (Vector e)
shift1D Acc (Vector e)
arr = Exp DIM1
-> (Exp DIM1 -> Exp DIM1) -> Acc (Vector e) -> Acc (Vector e)
forall sh sh' a.
(Shape sh, Shape sh', Elt a) =>
Exp sh'
-> (Exp sh' -> Exp sh) -> Acc (Array sh a) -> Acc (Array sh' a)
backpermute Exp DIM1
sh Exp DIM1 -> Exp DIM1
p Acc (Vector e)
arr
      where
        sh :: Exp DIM1
sh      = Acc (Vector e) -> Exp DIM1
forall sh e. (Shape sh, Elt e) => Acc (Array sh e) -> Exp sh
shape Acc (Vector e)
arr
        n :: Exp Int
n       = Exp DIM1 -> Exp Int
forall sh a. (Elt sh, Elt a) => Exp (sh :. a) -> Exp a
indexHead Exp DIM1
sh
        --
        shift :: Exp Int
shift   = (Exp Int
n Exp Int -> Exp Int -> Exp Int
forall a. Integral a => a -> a -> a
`quot` Exp Int
2) Exp Int -> Exp Int -> Exp Int
forall a. Num a => a -> a -> a
+ Exp Bool -> Exp Int
boolToInt (Exp Int -> Exp Bool
forall a. Integral a => Exp a -> Exp Bool
A.odd Exp Int
n)
        roll :: Exp Int -> Exp Int
roll Exp Int
i  = (Exp Int
iExp Int -> Exp Int -> Exp Int
forall a. Num a => a -> a -> a
+Exp Int
shift) Exp Int -> Exp Int -> Exp Int
forall a. Integral a => a -> a -> a
`rem` Exp Int
n
        p :: Exp DIM1 -> Exp DIM1
p       = (Exp Int -> Exp Int) -> Exp DIM1 -> Exp DIM1
ilift1 Exp Int -> Exp Int
roll

-- | The inverse of the shift1D function, such that
-- > ishift1D (shift1D v) = ishift1D (shift1D v) = v
-- for all vectors
--
ishift1D :: Elt e => Acc (Vector e) -> Acc (Vector e)
ishift1D :: Acc (Vector e) -> Acc (Vector e)
ishift1D Acc (Vector e)
arr = Exp DIM1
-> (Exp DIM1 -> Exp DIM1) -> Acc (Vector e) -> Acc (Vector e)
forall sh sh' a.
(Shape sh, Shape sh', Elt a) =>
Exp sh'
-> (Exp sh' -> Exp sh) -> Acc (Array sh a) -> Acc (Array sh' a)
backpermute Exp DIM1
sh Exp DIM1 -> Exp DIM1
p Acc (Vector e)
arr
      where
        sh :: Exp DIM1
sh      = Acc (Vector e) -> Exp DIM1
forall sh e. (Shape sh, Elt e) => Acc (Array sh e) -> Exp sh
shape Acc (Vector e)
arr
        n :: Exp Int
n       = Exp DIM1 -> Exp Int
forall sh a. (Elt sh, Elt a) => Exp (sh :. a) -> Exp a
indexHead Exp DIM1
sh
        --
        shift :: Exp Int
shift   = (Exp Int
n Exp Int -> Exp Int -> Exp Int
forall a. Integral a => a -> a -> a
`quot` Exp Int
2)-- + boolToInt (A.odd n)
        roll :: Exp Int -> Exp Int
roll Exp Int
i  = (Exp Int
iExp Int -> Exp Int -> Exp Int
forall a. Num a => a -> a -> a
+Exp Int
shift) Exp Int -> Exp Int -> Exp Int
forall a. Integral a => a -> a -> a
`rem` Exp Int
n
        p :: Exp DIM1 -> Exp DIM1
p       = (Exp Int -> Exp Int) -> Exp DIM1 -> Exp DIM1
ilift1 Exp Int -> Exp Int
roll

-- | Apply the shifting transform to a 2D array
--
shift2D :: Elt e => Acc (Array DIM2 e) -> Acc (Array DIM2 e)
shift2D :: Acc (Array DIM2 e) -> Acc (Array DIM2 e)
shift2D Acc (Array DIM2 e)
arr
  = Exp DIM2
-> (Exp DIM2 -> Exp DIM2)
-> Acc (Array DIM2 e)
-> Acc (Array DIM2 e)
forall sh sh' a.
(Shape sh, Shape sh', Elt a) =>
Exp sh'
-> (Exp sh' -> Exp sh) -> Acc (Array sh a) -> Acc (Array sh' a)
backpermute Exp DIM2
sh Exp DIM2 -> Exp DIM2
forall (c :: * -> *).
Unlift c ((Z :. Exp Int) :. Exp Int) =>
c DIM2 -> Exp DIM2
p Acc (Array DIM2 e)
arr
  where
    sh :: Exp DIM2
sh      = Acc (Array DIM2 e) -> Exp DIM2
forall sh e. (Shape sh, Elt e) => Acc (Array sh e) -> Exp sh
shape Acc (Array DIM2 e)
arr
    Z
Z :. Exp Int
h :. Exp Int
w = Exp (Plain ((Z :. Exp Int) :. Exp Int))
-> (Z :. Exp Int) :. Exp Int
forall (c :: * -> *) e. Unlift c e => c (Plain e) -> e
unlift Exp (Plain ((Z :. Exp Int) :. Exp Int))
Exp DIM2
sh
    --
    shifth :: Exp Int
shifth = (Exp Int
h Exp Int -> Exp Int -> Exp Int
forall a. Integral a => a -> a -> a
`quot` Exp Int
2) Exp Int -> Exp Int -> Exp Int
forall a. Num a => a -> a -> a
+ Exp Bool -> Exp Int
boolToInt (Exp Int -> Exp Bool
forall a. Integral a => Exp a -> Exp Bool
A.odd Exp Int
h)
    shiftw :: Exp Int
shiftw = (Exp Int
w Exp Int -> Exp Int -> Exp Int
forall a. Integral a => a -> a -> a
`quot` Exp Int
2) Exp Int -> Exp Int -> Exp Int
forall a. Num a => a -> a -> a
+ Exp Bool -> Exp Int
boolToInt (Exp Int -> Exp Bool
forall a. Integral a => Exp a -> Exp Bool
A.odd Exp Int
w)

    p :: c DIM2 -> Exp DIM2
p c DIM2
ix
      = let Z
Z:.Exp Int
y:.Exp Int
x = c (Plain ((Z :. Exp Int) :. Exp Int)) -> (Z :. Exp Int) :. Exp Int
forall (c :: * -> *) e. Unlift c e => c (Plain e) -> e
unlift c (Plain ((Z :. Exp Int) :. Exp Int))
c DIM2
ix :: Z :. Exp Int :. Exp Int
        in Exp Int -> Exp Int -> Exp DIM2
forall i. Elt i => Exp i -> Exp i -> Exp ((Z :. i) :. i)
index2 ((Exp Int
y Exp Int -> Exp Int -> Exp Int
forall a. Num a => a -> a -> a
+ Exp Int
shifth) Exp Int -> Exp Int -> Exp Int
forall a. Integral a => a -> a -> a
`rem` Exp Int
h)
                  ((Exp Int
x Exp Int -> Exp Int -> Exp Int
forall a. Num a => a -> a -> a
+ Exp Int
shiftw) Exp Int -> Exp Int -> Exp Int
forall a. Integral a => a -> a -> a
`rem` Exp Int
w)

-- | The inverse of the shift2D function
--
ishift2D :: Elt e => Acc (Array DIM2 e) -> Acc (Array DIM2 e)
ishift2D :: Acc (Array DIM2 e) -> Acc (Array DIM2 e)
ishift2D Acc (Array DIM2 e)
arr
  = Exp DIM2
-> (Exp DIM2 -> Exp DIM2)
-> Acc (Array DIM2 e)
-> Acc (Array DIM2 e)
forall sh sh' a.
(Shape sh, Shape sh', Elt a) =>
Exp sh'
-> (Exp sh' -> Exp sh) -> Acc (Array sh a) -> Acc (Array sh' a)
backpermute Exp DIM2
sh Exp DIM2 -> Exp DIM2
forall (c :: * -> *).
Unlift c ((Z :. Exp Int) :. Exp Int) =>
c DIM2 -> Exp DIM2
p Acc (Array DIM2 e)
arr
  where
    sh :: Exp DIM2
sh      = Acc (Array DIM2 e) -> Exp DIM2
forall sh e. (Shape sh, Elt e) => Acc (Array sh e) -> Exp sh
shape Acc (Array DIM2 e)
arr
    Z
Z :. Exp Int
h :. Exp Int
w = Exp (Plain ((Z :. Exp Int) :. Exp Int))
-> (Z :. Exp Int) :. Exp Int
forall (c :: * -> *) e. Unlift c e => c (Plain e) -> e
unlift Exp (Plain ((Z :. Exp Int) :. Exp Int))
Exp DIM2
sh
    --
    shifth :: Exp Int
shifth = (Exp Int
h Exp Int -> Exp Int -> Exp Int
forall a. Integral a => a -> a -> a
`quot` Exp Int
2)
    shiftw :: Exp Int
shiftw = (Exp Int
w Exp Int -> Exp Int -> Exp Int
forall a. Integral a => a -> a -> a
`quot` Exp Int
2)

    p :: c DIM2 -> Exp DIM2
p c DIM2
ix
      = let Z
Z:.Exp Int
y:.Exp Int
x = c (Plain ((Z :. Exp Int) :. Exp Int)) -> (Z :. Exp Int) :. Exp Int
forall (c :: * -> *) e. Unlift c e => c (Plain e) -> e
unlift c (Plain ((Z :. Exp Int) :. Exp Int))
c DIM2
ix :: Z :. Exp Int :. Exp Int
        in Exp Int -> Exp Int -> Exp DIM2
forall i. Elt i => Exp i -> Exp i -> Exp ((Z :. i) :. i)
index2 ((Exp Int
y Exp Int -> Exp Int -> Exp Int
forall a. Num a => a -> a -> a
+ Exp Int
shifth) Exp Int -> Exp Int -> Exp Int
forall a. Integral a => a -> a -> a
`rem` Exp Int
h)
                  ((Exp Int
x Exp Int -> Exp Int -> Exp Int
forall a. Num a => a -> a -> a
+ Exp Int
shiftw) Exp Int -> Exp Int -> Exp Int
forall a. Integral a => a -> a -> a
`rem` Exp Int
w)

-- | Apply the shifting transform to a 3D array
--
shift3D :: Elt e => Acc (Array DIM3 e) -> Acc (Array DIM3 e)
shift3D :: Acc (Array DIM3 e) -> Acc (Array DIM3 e)
shift3D Acc (Array DIM3 e)
arr
  = Exp DIM3
-> (Exp DIM3 -> Exp DIM3)
-> Acc (Array DIM3 e)
-> Acc (Array DIM3 e)
forall sh sh' a.
(Shape sh, Shape sh', Elt a) =>
Exp sh'
-> (Exp sh' -> Exp sh) -> Acc (Array sh a) -> Acc (Array sh' a)
backpermute Exp DIM3
sh Exp DIM3 -> Exp DIM3
forall (c :: * -> *).
Unlift c (((Z :. Exp Int) :. Exp Int) :. Exp Int) =>
c DIM3 -> Exp DIM3
p Acc (Array DIM3 e)
arr
  where
    sh :: Exp DIM3
sh      = Acc (Array DIM3 e) -> Exp DIM3
forall sh e. (Shape sh, Elt e) => Acc (Array sh e) -> Exp sh
shape Acc (Array DIM3 e)
arr
    Z
Z :. Exp Int
d :. Exp Int
h :. Exp Int
w = Exp (Plain (((Z :. Exp Int) :. Exp Int) :. Exp Int))
-> ((Z :. Exp Int) :. Exp Int) :. Exp Int
forall (c :: * -> *) e. Unlift c e => c (Plain e) -> e
unlift Exp (Plain (((Z :. Exp Int) :. Exp Int) :. Exp Int))
Exp DIM3
sh
    --
    shiftd :: Exp Int
shiftd = (Exp Int
d Exp Int -> Exp Int -> Exp Int
forall a. Integral a => a -> a -> a
`quot` Exp Int
2) Exp Int -> Exp Int -> Exp Int
forall a. Num a => a -> a -> a
+ Exp Bool -> Exp Int
boolToInt (Exp Int -> Exp Bool
forall a. Integral a => Exp a -> Exp Bool
A.odd Exp Int
d)
    shifth :: Exp Int
shifth = (Exp Int
h Exp Int -> Exp Int -> Exp Int
forall a. Integral a => a -> a -> a
`quot` Exp Int
2) Exp Int -> Exp Int -> Exp Int
forall a. Num a => a -> a -> a
+ Exp Bool -> Exp Int
boolToInt (Exp Int -> Exp Bool
forall a. Integral a => Exp a -> Exp Bool
A.odd Exp Int
h)
    shiftw :: Exp Int
shiftw = (Exp Int
w Exp Int -> Exp Int -> Exp Int
forall a. Integral a => a -> a -> a
`quot` Exp Int
2) Exp Int -> Exp Int -> Exp Int
forall a. Num a => a -> a -> a
+ Exp Bool -> Exp Int
boolToInt (Exp Int -> Exp Bool
forall a. Integral a => Exp a -> Exp Bool
A.odd Exp Int
w)

    p :: c DIM3 -> Exp DIM3
p c DIM3
ix
      = let Z
Z:.Exp Int
z:.Exp Int
y:.Exp Int
x = c (Plain (((Z :. Exp Int) :. Exp Int) :. Exp Int))
-> ((Z :. Exp Int) :. Exp Int) :. Exp Int
forall (c :: * -> *) e. Unlift c e => c (Plain e) -> e
unlift c (Plain (((Z :. Exp Int) :. Exp Int) :. Exp Int))
c DIM3
ix :: Z :. Exp Int :. Exp Int :. Exp Int
        in Exp Int -> Exp Int -> Exp Int -> Exp DIM3
forall i.
Elt i =>
Exp i -> Exp i -> Exp i -> Exp (((Z :. i) :. i) :. i)
index3 ((Exp Int
z Exp Int -> Exp Int -> Exp Int
forall a. Num a => a -> a -> a
+ Exp Int
shiftd) Exp Int -> Exp Int -> Exp Int
forall a. Integral a => a -> a -> a
`rem` Exp Int
d)
                  ((Exp Int
y Exp Int -> Exp Int -> Exp Int
forall a. Num a => a -> a -> a
+ Exp Int
shifth) Exp Int -> Exp Int -> Exp Int
forall a. Integral a => a -> a -> a
`rem` Exp Int
h)
                  ((Exp Int
x Exp Int -> Exp Int -> Exp Int
forall a. Num a => a -> a -> a
+ Exp Int
shiftw) Exp Int -> Exp Int -> Exp Int
forall a. Integral a => a -> a -> a
`rem` Exp Int
w)

-- | The inverse of the shift3D function
--
ishift3D :: Elt e => Acc (Array DIM3 e) -> Acc (Array DIM3 e)
ishift3D :: Acc (Array DIM3 e) -> Acc (Array DIM3 e)
ishift3D Acc (Array DIM3 e)
arr
  = Exp DIM3
-> (Exp DIM3 -> Exp DIM3)
-> Acc (Array DIM3 e)
-> Acc (Array DIM3 e)
forall sh sh' a.
(Shape sh, Shape sh', Elt a) =>
Exp sh'
-> (Exp sh' -> Exp sh) -> Acc (Array sh a) -> Acc (Array sh' a)
backpermute Exp DIM3
sh Exp DIM3 -> Exp DIM3
forall (c :: * -> *).
Unlift c (((Z :. Exp Int) :. Exp Int) :. Exp Int) =>
c DIM3 -> Exp DIM3
p Acc (Array DIM3 e)
arr
  where
    sh :: Exp DIM3
sh      = Acc (Array DIM3 e) -> Exp DIM3
forall sh e. (Shape sh, Elt e) => Acc (Array sh e) -> Exp sh
shape Acc (Array DIM3 e)
arr
    Z
Z :. Exp Int
d :. Exp Int
h :. Exp Int
w = Exp (Plain (((Z :. Exp Int) :. Exp Int) :. Exp Int))
-> ((Z :. Exp Int) :. Exp Int) :. Exp Int
forall (c :: * -> *) e. Unlift c e => c (Plain e) -> e
unlift Exp (Plain (((Z :. Exp Int) :. Exp Int) :. Exp Int))
Exp DIM3
sh
    --
    shiftd :: Exp Int
shiftd = (Exp Int
d Exp Int -> Exp Int -> Exp Int
forall a. Integral a => a -> a -> a
`quot` Exp Int
2)
    shifth :: Exp Int
shifth = (Exp Int
h Exp Int -> Exp Int -> Exp Int
forall a. Integral a => a -> a -> a
`quot` Exp Int
2)
    shiftw :: Exp Int
shiftw = (Exp Int
w Exp Int -> Exp Int -> Exp Int
forall a. Integral a => a -> a -> a
`quot` Exp Int
2)

    p :: c DIM3 -> Exp DIM3
p c DIM3
ix
      = let Z
Z:.Exp Int
z:.Exp Int
y:.Exp Int
x = c (Plain (((Z :. Exp Int) :. Exp Int) :. Exp Int))
-> ((Z :. Exp Int) :. Exp Int) :. Exp Int
forall (c :: * -> *) e. Unlift c e => c (Plain e) -> e
unlift c (Plain (((Z :. Exp Int) :. Exp Int) :. Exp Int))
c DIM3
ix :: Z :. Exp Int :. Exp Int :. Exp Int
        in Exp Int -> Exp Int -> Exp Int -> Exp DIM3
forall i.
Elt i =>
Exp i -> Exp i -> Exp i -> Exp (((Z :. i) :. i) :. i)
index3 ((Exp Int
z Exp Int -> Exp Int -> Exp Int
forall a. Num a => a -> a -> a
+ Exp Int
shiftd) Exp Int -> Exp Int -> Exp Int
forall a. Integral a => a -> a -> a
`rem` Exp Int
d)
                  ((Exp Int
y Exp Int -> Exp Int -> Exp Int
forall a. Num a => a -> a -> a
+ Exp Int
shifth) Exp Int -> Exp Int -> Exp Int
forall a. Integral a => a -> a -> a
`rem` Exp Int
h)
                  ((Exp Int
x Exp Int -> Exp Int -> Exp Int
forall a. Num a => a -> a -> a
+ Exp Int
shiftw) Exp Int -> Exp Int -> Exp Int
forall a. Integral a => a -> a -> a
`rem` Exp Int
w)