{-# LANGUAGE TypeOperators, ExplicitForAll, FlexibleContexts #-}moduleData.Array.Repa.Operators.IndexSpace(reshape,append,(++),transpose,extract,backpermute,unsafeBackpermute,backpermuteDft,unsafeBackpermuteDft,extend,unsafeExtend,slice,unsafeSlice)whereimportData.Array.Repa.IndeximportData.Array.Repa.SliceimportData.Array.Repa.BaseimportData.Array.Repa.Repr.DelayedimportData.Array.Repa.Operators.TraversalimportData.Array.Repa.ShapeasSimportPreludehiding((++))importqualifiedPreludeasPstage="Data.Array.Repa.Operators.IndexSpace"-- Index space transformations -------------------------------------------------- | Impose a new shape on the elements of an array.-- The new extent must be the same size as the original, else `error`.reshape::(Shapesh1,Shapesh2,Sourcer1e)=>sh2->Arrayr1sh1e->ArrayDsh2ereshapesh2arr|not$S.sizesh2==S.size(extentarr)=error$stageP.++".reshape: reshaped array will not match size of the original"reshapesh2arr=fromFunctionsh2$unsafeIndexarr.fromIndex(extentarr).toIndexsh2{-# INLINE [2] reshape #-}-- | Append two arrays.append,(++)::(Shapesh,Sourcer1e,Sourcer2e)=>Arrayr1(sh:.Int)e->Arrayr2(sh:.Int)e->ArrayD(sh:.Int)eappendarr1arr2=unsafeTraverse2arr1arr2fnExtentfnElemwhere(_:.n)=extentarr1fnExtent(sh:.i)(_:.j)=sh:.(i+j)fnElemf1f2(sh:.i)|i<n=f1(sh:.i)|otherwise=f2(sh:.(i-n)){-# INLINE [2] append #-}(++)arr1arr2=appendarr1arr2{-# INLINE (++) #-}-- | Transpose the lowest two dimensions of an array.-- Transposing an array twice yields the original.transpose::(Shapesh,Sourcere)=>Arrayr(sh:.Int:.Int)e->ArrayD(sh:.Int:.Int)etransposearr=unsafeTraversearr(\(sh:.m:.n)->(sh:.n:.m))(\f->\(sh:.i:.j)->f(sh:.j:.i)){-# INLINE [2] transpose #-}-- | Extract a sub-range of elements from an array.extract::(Shapesh,Sourcere)=>sh-- ^ Starting index.->sh-- ^ Size of result.->Arrayrshe->ArrayDsheextractstartszarr=fromFunctionsz(\ix->arr`unsafeIndex`(addDimstartix)){-# INLINE [2] extract #-}-- | Backwards permutation of an array's elements.-- The result array has the same extent as the original.backpermute,unsafeBackpermute::forallrsh1sh2e.(Shapesh1,Shapesh2,Sourcere)=>sh2-- ^ Extent of result array.->(sh2->sh1)-- ^ Function mapping each index in the result array-- to an index of the source array.->Arrayrsh1e-- ^ Source array.->ArrayDsh2ebackpermutenewExtentpermarr=traversearr(constnewExtent)(.perm){-# INLINE [2] backpermute #-}unsafeBackpermutenewExtentpermarr=unsafeTraversearr(constnewExtent)(.perm){-# INLINE [2] unsafeBackpermute #-}-- | Default backwards permutation of an array's elements.-- If the function returns `Nothing` then the value at that index is taken-- from the default array (@arrDft@)backpermuteDft,unsafeBackpermuteDft::forallr1r2sh1sh2e.(Shapesh1,Shapesh2,Sourcer1e,Sourcer2e)=>Arrayr2sh2e-- ^ Default values (@arrDft@)->(sh2->Maybesh1)-- ^ Function mapping each index in the result array-- to an index in the source array.->Arrayr1sh1e-- ^ Source array.->ArrayDsh2ebackpermuteDftarrDftfnIndexarrSrc=fromFunction(extentarrDft)fnElemwherefnElemix=casefnIndexixofJustix'->arrSrc`index`ix'Nothing->arrDft`index`ix{-# INLINE [2] backpermuteDft #-}unsafeBackpermuteDftarrDftfnIndexarrSrc=fromFunction(extentarrDft)fnElemwherefnElemix=casefnIndexixofJustix'->arrSrc`unsafeIndex`ix'Nothing->arrDft`unsafeIndex`ix{-# INLINE [2] unsafeBackpermuteDft #-}-- | Extend an array, according to a given slice specification.---- For example, to replicate the rows of an array use the following:---- @extend arr (Any :. (5::Int) :. All)@--extend,unsafeExtend::(Slicesl,Shape(SliceShapesl),Shape(FullShapesl),Sourcere)=>sl->Arrayr(SliceShapesl)e->ArrayD(FullShapesl)eextendslarr=backpermute(fullOfSlicesl(extentarr))(sliceOfFullsl)arr{-# INLINE [2] extend #-}unsafeExtendslarr=unsafeBackpermute(fullOfSlicesl(extentarr))(sliceOfFullsl)arr{-# INLINE [2] unsafeExtend #-}-- | Take a slice from an array, according to a given specification.---- For example, to take a row from a matrix use the following:---- @slice arr (Any :. (5::Int) :. All)@---- To take a column use:---- @slice arr (Any :. (5::Int))@--slice,unsafeSlice::(Slicesl,Shape(FullShapesl),Shape(SliceShapesl),Sourcere)=>Arrayr(FullShapesl)e->sl->ArrayD(SliceShapesl)eslicearrsl=backpermute(sliceOfFullsl(extentarr))(fullOfSlicesl)arr{-# INLINE [2] slice #-}unsafeSlicearrsl=unsafeBackpermute(sliceOfFullsl(extentarr))(fullOfSlicesl)arr{-# INLINE [2] unsafeSlice #-}