从Mathematica调用Haskell DLL

时间:2017-01-06 16:12:05

标签: r haskell dll wolfram-mathematica

寻找一种从Mathematica调用Haskell DLL的方法,对于GNU R,我偶然发现了这个:

http://neilmitchell.blogspot.com.br/2011/10/calling-haskell-from-r.html

这是(对我而言)一个很好的例子,我设法让它在Mathematica上工作而不需要通过这个法术进行修改:

Needs["NETLink`"]
hsStart = DefineDLLFunction["HsStart", "c:\\temp\\SumRoots.dll", "void", {}];
hsEnd = DefineDLLFunction["HsEnd", "c:\\temp\\SumRoots.dll", "void", {}];
sroot = DefineDLLFunction["sumRootsR", "c:\\temp\\SumRoots.dll", "double", {"int*", "double[]", "double*"}];
hsStart[];
resulta = 0;
lista = {9, 3.5, 5.58, 64.1, 12.54};
sroot[Length[lista], lista, resulta];
resulta
18.7805
hsEnd[];

然后我尝试修改示例以返回双精度矢量,而不是单个值:
Haskell中的代码:

-- SumRoots.hs

{-# LANGUAGE ForeignFunctionInterface #-}
module SumRoots where

import Foreign

foreign export ccall acumSumR :: Ptr Int -> Ptr Double -> Ptr Double -> IO ()

acumSum :: [Double] -> [Double]
acumSum xs = scanl (\x y -> x+y) 0 xs

acumSumR :: Ptr Int -> Ptr Double -> Ptr Double -> IO ()
acumSumR n xs result = do
                       n <- peek n
                       xs <- peekArray n xs
                       pokeArray result $ acumSum xs

C中的代码:(与上述博客文章完全相同)

编译:

ghc -c SumRoots.hs
ghc -c StartEnd.c
ghc -shared -o SumRoots.dll SumRoots.o StartEnd.o

Mathematica中的代码:

Needs["NETLink`"]
hsStart = DefineDLLFunction["HsStart", "c:\\temp\\SumRoots.dll", "void", {}];
hsEnd = DefineDLLFunction["HsEnd", "c:\\temp\\SumRoots.dll", "void", {}];
acums = DefineDLLFunction["acumSumR", "c:\\temp\\SumRoots.dll", "double[]", {"int*", "double[]", "double[]"}];
hsStart[];
lista = {9, 3.5, 5.58, 64.1, 12.54};
NETBlock@Module[{n, resultb}, n = Length[lista]+1; 
  resultb = NETNew["System.Double[]", n]; acums[n, lista, resultb]; 
  NETObjectToExpression[resultb]]

{0., 0., 0., 0., 0., 0.}

结果应为{0.0,9.0,12.5,18.08,82.18,94.72}。我不确定这个问题是否属于Mathematica或Haskell领域,但是这里的帖子是基于GNU R调用工作的事实:

dyn.load("C:/temp/SumRoots.dll") 
.C("HsStart")
acumSum <- function(input)
{
return(.C("acumSumR", n=as.integer(length(input)), xs=as.double(input), result=as.double(rep(0,length(input)+1)))$result)
}
input <- c(9,3.5,5.58,64.1,12.54)
acumSum(input)

那么,有人可以提示如何从Mathematica调用这个修改过的Haskell DLL函数吗?
环境:
SO:Windows 10 64位
Mathematica 8.0 64位
Haskell平台8.0.1 64位
GNU R 3.3.2 64位

干杯,

兰德

0 个答案:

没有答案