packages feed

matlab-0.2.0.0: Foreign/Matlab/Runtime/Generic.hs

{-|
  Generic runtime library interface.
  This uses a Matlab library built along with HSMatlab to provide runtime access to general Matlab functionality throuh "Foreign.Matlab.Runtime".
  Any builtin Matlab function can be called through this interface, but other M-file functions may not -- these need to be put into a library or used through "Foreign.Matlab.Engine" instead.
-}
module Foreign.Matlab.Runtime.Generic (
    MLGeneric,
    openMLGeneric,
    closeMLGeneric,
    mlGenericEval,
    mlGenericFun,
    mlGenericSetVar,
    mlGenericGetVar,
    mlGenericCapture
  ) where

import Foreign.C.String
--import System.FilePath
import Foreign.Matlab.Util
import Foreign.Matlab.Types
import Foreign.Matlab.Array
import Foreign.Matlab.Runtime
--import Paths_matlab

data MLGeneric = MLGeneric {
    mlgLibrary :: MLibrary,
    mlgFeval :: CString -> MFun
  }

-- |Create a generic interface to the Matlab runtime.  Only one is necessary in any given application.
openMLGeneric :: [String] -> IO MLGeneric
openMLGeneric opt = do
  -- libdir <- getLibDir
  ml <- openMLibrary ({- libdir </> -} "hsmatlab") opt
  feval <- mlGenericFeval ml
  return $ MLGeneric { mlgLibrary = ml, mlgFeval = feval }

-- |Close a MLGeneric interface no longer in use.
closeMLGeneric :: MLGeneric -> IO ()
closeMLGeneric MLGeneric{ mlgLibrary = ml } = closeMLibrary ml

-- |Call the named Matlab function using the specified interface.
mlGenericFun :: MLGeneric -> String -> MFun
mlGenericFun mlg f a n = do
  withCString f (\f -> mlgFeval mlg f (map anyMXArray a) n)

-- |Eval Matlab code.
mlGenericEval :: MLGeneric 
  -> String -- ^ The Matlab code string to evaluate
  -> Int -- ^ The number of arguments returned by the code
  -> IO [MAnyArray]
mlGenericEval mlg e n = do
  e <- createRowVector e
  r <- mlGenericFun mlg "eval" [anyMXArray e] n
  freeMXArray e
  return r

-- |Set the given variable to the value in the base scope
mlGenericSetVar :: MLGeneric -> String -> MXArray a -> IO ()
mlGenericSetVar mlg v x = do
  b <- createRowVector "base"
  v <- createRowVector v
  _ <- mlGenericFun mlg "assignin" [anyMXArray b,anyMXArray v,anyMXArray x] 0
  freeMXArray v
  freeMXArray b

-- |Get the value of the given variable in the base scope
mlGenericGetVar :: MLGeneric -> String -> IO MAnyArray
mlGenericGetVar mlg v = head =.< mlGenericEval mlg v 1

-- |Evaluate Matlab code and capture the generated output (see 'mlGenericEval')
mlGenericCapture :: MLGeneric -> String -> Int -> IO (String,[MAnyArray])
mlGenericCapture mlg e n = do
  e <- createRowVector e
  (cap:res) <- mlGenericFun mlg "evalc" [anyMXArray e] (succ n)
  freeMXArray e
  Just cap <- castMXArray cap
  cap <- mxArrayGetAll cap
  return $ (cap,res)