来自惰性 ByteString 的 Massiv 多维数组示例?

问题描述 投票:0回答:1

我正在处理科学领域的大型数据数组,编码成二进制 FITS 文件。为了简单起见,假设我将 2GB 的 32 位浮点保存到一个文件中,旨在作为 2d 数组读取,并且我将文件作为惰性字节字符串加载

inp <- BL.readFile "myfile.fits"

如何将此文件解析为延迟的 Massiv 数组(

Array DS Ix2 Float
Array D Ix2 Float
)?

我想避免打电话给

compute
直到我的手术结束

我似乎找不到从 ByteString 加载 Massiv 数组的简单示例(这似乎应该是一个常见的用例)。我可以通过使用

sreplicateM
评估整个 ByteString 来加载它,将其解析为
Data.Massiv.Vector
,然后使用
resizeM
将其放入
Ix2
。不过,
resizeM
需要我先打电话给
compute

任何人都可以给我举一个如何将 Lazy ByteString 加载到 Massiv 数组并延迟计算的示例吗?

请随意指出解析为

D
DS
是错误的选择。我真正的问题是如何将文件中的二进制数据解析为
Array
并允许用户调用
size
slice
:>
!
等而不评估整个事情

arrays haskell bytestring massiv
1个回答
0
投票

我认为你想在这里使用

DL
数组,因为 - 与
DS
不同 -
DL
支持多维数组,并且与
D
不同,它可以让你控制写入过程(即,你选择从文件加载矩阵时的索引)。

一个独立的示例如下:

import Control.Applicative
import qualified Data.Binary.Get as Bin
import qualified Data.ByteString.Lazy as BL
import Data.Massiv.Array

main :: IO ()
main = do

  -- for real code, use lazy I/O for the input:
  --   input <- BL.readFile "input.txt"

  -- for this example, consider a 2x2 matrix in a lazy bytestring
  let input :: BL.ByteString
      input = BL.pack $ [ 0,0,0x80,0x3f -- 1
                        , 0,0,0x00,0x40 -- 2
                        , 0,0,0x40,0x40 -- 3
                        , 0,0,0x80,0x40 -- 4
                        ]
      nrow = 2
      ncol = 2

  -- use "binary" package to parse the floats into a lazy list
  let floats = Bin.runGet (many Bin.getFloathost) input

  -- create a DL array
      array :: Array DL Ix2 Float
      array = makeLoadArrayS (Sz (nrow :. ncol)) 0.0 $ \writer ->
        sequence_ $ Prelude.zipWith writer indices floats
        where indices = [(row :. col) | row <- [0..nrow-1], col <- [0..ncol-1]]

  -- compute it
  let array' :: Array P Ix2 Float
      array' = compute array
  print array'
© www.soinside.com 2019 - 2024. All rights reserved.