2011-06-12 4 views
3

repa에 (/)의 유사어가 있는지 궁금합니다.Repa에서 본질적으로 순차적 인 배열 변환

병렬 변환 할 수없는 배열 변환에 필요합니다. 예를 들어 함수가 전체 배열에 배열의 단일 항목을 변경하고 새로운 배열에 적용하는 등의 작업이 필요한 경우 (순차적으로 실행해야하는 경우)

답변

5

(//)는 Data.Array.Repa.fromFunction의 관점에서 구현 될 수있다 :

import Data.Array.Repa 

(//) :: Shape sh => Array sh a -> [(sh,a)] -> Array sh a 
(//) arr us = fromFunction (extent arr) (\sh -> case lookup sh us of 
               Just a -> a 
               Nothing -> index arr sh) 

fromFunction 자체는 전체 어레이를 사용할 수있다 Shape sh => s -> a 유형의 기능을 전달할 수있다.

위의 구현은 모든 업데이트를 한 번에 수행합니다.

4

(//)의 잠재적 인 문제 중 하나는 각 요소의 값을 찾기 위해 목록을 검색해야한다는 것입니다. 배열이나 목록이 크면 비용이 많이 듭니다.

또 다른 옵션은 Data.Vector에서 편리한 기능을 활용하는 것입니다

modify :: Vector v a => (forall s. Mutable v s a -> ST s()) -> v a -> v a 

이 그것이 안전한지 장소에 업데이트를 수행 할 가능성이있다. 그래서 내 노트북에

import Data.Vector.Unboxed as V 
import Data.Vector.Mutable.Unboxed as M 
import Data.Array.Repa as R 

(///) :: Shape sh => Array sh a -> [(sh,a)] -> Array sh a 
(///) arr us = R.fromVector sh . modify f $ R.toVector arr 
    where 
    sh = extent arr 
    f mv = forM_ us $ \(k,x) -> do 
    M.write mv (R.toIndex sh k) x 

같은, 나는이 시간을 100 개 항목을 갱신, 1 백만 요소 DIM1 배열이 테스트를하고 있어요 : (//) : 3.598973 (///) : 2.0859999999999997e-3

관련 문제