matlab-0.3.0.0: Foreign/Matlab/Engine/Wrappers.hs
{-|
Wrappers to common (and some uncommon) MATLAB functions using the MATLAB Engine.
Note that you cannot use "Foreign.Matlab.Engine" and "Foreign.Matlab.Runtime" in the same program.
This seems to be a Matlab limitation.
-}
module Foreign.Matlab.Engine.Wrappers (
addpath
, clearVar
, getArrayFromByteStream
, getByteStreamFromArray
, MEither(..), isMLeft, isMRight
, VarArgIn, mxVarArgs
) where
import qualified Data.Map.Strict as DM
import Foreign.Matlab
import Foreign.Matlab.Engine
import Path
type VarArgIn = DM.Map String MAnyArray
-- | We require an absolute path in this case
addpath :: Engine -> Path Abs Dir -> IO ()
addpath eng p = engineEvalProc eng "addpath" [EvalStr $ toFilePath p]
-- | TODO: add a test for this, likely not working as expected.
-- | Clears a variable from the engine's workspace
clearVar :: Engine -> String -> IO ()
clearVar eng var = engineEvalProc eng "clear" [EvalStr var]
-- | Wraps an undocumented function to serialize a MATLAB object.
getByteStreamFromArray :: Engine -> MAnyArray -> IO (Either String [MUint8])
getByteStreamFromArray eng mObj = do
[byteStream] <- engineEvalFun eng "getByteStreamFromArray" [EvalArray mObj] 1
mxArrMay <- castMXArray byteStream
case mxArrMay of
Just mxArr -> Right <$> mxArrayGetAll mxArr
Nothing -> pure $ Left
"getByteStreamFromArray: Couldn't convert MATLAB bytestream to [MUint8]"
-- | Wraps an undocumented function to deserialize a MATLAB object.
getArrayFromByteStream :: Engine -> [MUint8] -> IO MAnyArray
getArrayFromByteStream eng bytes = do
matBsArr <- createMXArray [length bytes]
mxArraySetAll matBsArr bytes
[mObj] <- engineEvalFun eng "getArrayFromByteStream" [EvalArray matBsArr] 1
pure mObj
newtype MEither = MEither {unMXEither :: MStructArray}
isMLeft :: MEither -> IO Bool
isMLeft me = do
sFields <- mStructFields $ unMXEither me
pure $ "left" `elem` sFields
isMRight :: MEither -> IO Bool
isMRight me = do
sFields <- mStructFields $ unMXEither me
pure $ "right" `elem` sFields
-- | Utility function to create an eval-able list of arguments for a vararg map.
mxVarArgs :: VarArgIn -> [EngineEvalArg MAny]
mxVarArgs varargin = DM.toList varargin >>= kvToArg
where
kvToArg :: (String, MAnyArray) -> [EngineEvalArg MAny]
kvToArg kv = [EvalStr $ fst kv, EvalArray $ snd kv]