Mercurial > hg > plml
view README @ 8:173e1c48e335
Cleaned up mess of makefiles. Force user to copy Makefile.templ to Makefile.
author | samer |
---|---|
date | Thu, 19 Jan 2012 15:23:35 +0000 |
parents | 0dd31a8c66bd |
children | e395e387bd3c |
line wrap: on
line source
*** Prolog Matlab interface *** *** Authors: *** Samer Abdallah *** Centre for Digital Music, *** Queen Mary, University of London *** *** Christophe Rhodes *** Centre for Computational Creativity *** Goldsmiths College, University of London *** *** Dec 2004--January 2012 ------------------------------------------------------------------------- NB: output type tagging system has changed but this documentation has not yet. See pldoc documentation of plml.pl. ------------------------------------------------------------------------- OVERVIEW PLML is a foreign interface that enables Matlab to be used as a computational engine from within SWI Prolog. The basic idea is that instead of using the standard is/2 operator to evaluate a certain class of terms, we can use the ===/2 operator to get Matlab to evaluate a (much richer) class of terms, eg ?- float(A)===trace(eye(3)). A = 3.0 We can also get Matlab to perform actions with side effects, like making sounds and graphics; obviously these do not fit into the declartive semantics of Prolog and have to be dealt with under the procedural semantics. If you want to execute a Matlab command in an imperative way and see the textual output, use the ??/1 operator, eg ?- ??disp(`hello). >> hello The interface works by using the Matlab Engine API, which starts up a Matlab process on the end of a pipe. The Matlab process can be on another machine, and multiple Matlab engines can be started on the same or different machines. Matlab expressions are sent down the pipe and executed. Matlab's textual output comes back through the pipe. In addition, Matlab variables can be transferred directly between the Matlab engine's memory space and SWI's memory space. *** Expression language Expressions to evaluate are given in a sublanguage of terms which is similar to but not exactly the same as Matlab. In particular, Prolog syntax cannot accommodate the single quoted Matlab strings, the Matlab syntax of matrices, (eg [1 2; 3 4]), and the Matlab syntax for slicing arrays (eg A(:,3:4)) if A is a Prolog variable. Strings are handled using the q/1 or `/1 functors, ie `hello and q(hello) both evaluate to 'hello'. Arrays can be given either as flat lists, which are interpreted as horizontal concatenation as in Matlab: ?- ??[1,2,3]. >> ans = 1 2 3 ?- ??[eye(2),magic(2)]. >> ans = 1 0 1 3 0 1 4 2 or as nested listed for multidimensional arrays using the arr/1 functor, where the innermost nesting corresponds to the FIRST Matlab dimensions ?- ??arr([1,2,3]). >> ans = 1 2 3 ?- ??arr([[1,2],[3,4]]). >> ans = 1 3 2 4 Cell arrays can be specified in a similar way using braces or the cell/1 functor. To help with accessing array elements, see the Matlab functions general/paren, general/row, and general/col in the matlab directory. *** Return values The results of computations can handled in several ways: 1. Keep the result in a Matlab workspace variable in the engine's memory space. The names of these variables are allocated automatically and stored in a Prolog atom. The atoms have a garbage collection callback which means that the Matlab workspace variable is deleted if the Prolog atom goes out of scope. ?- A===2+2, ??disp(A). >> 4 % matlab textual output A = ws(<ml:t_2311>) % Prolog blob pointing to Matlab variable t_2311 2. Convert the result to a prolog atom or term. The type of the resulting prolog term depends on the *right hand side* of the ===/2 operator: ?- int(A)===2+2. A = 4 ?- float(A)===2+2. A = 4.0 There are other types for strings and atoms: ?- atom(A) === q(hello). % q/1 means quote as Matlab string A = hello. ?- string(A) === `hello. % `/1 is shorthand for q/1 A = "hello". You can also get the result as a Matlab binary array on the Prolog side: ?- mx(A)===eye(4). % identity matrix A = <#0239c3a0> % Prolog blob handle (with garbage collection) I haven't completely settled on the best way of handling arrays as self-contained Prolog terms, but you can do this: ?- array(A)===magic(3). A = [[8.0, 3.0, 4.0], [1.0, 5.0, 9.0], [6.0, 7.0, 2.0]]::[[3, 3]] As you can see, multidimensional arrays are returned as nested lists, and the size of the array is given after the :: as [[3,3]]. 3. Store the result to a MAT file and return a Prolog term which points to the file. The names are generated automatically. This allows for persistence of values which are referred to by stable names that can be stored, eg in a database: ?- mat(A)===fft(buffer(wavread('somefile.wav'),256,128)). A = mat:d0608/m48598|x % dynamically generated unique locator This relies on the mechanism provided by the functions in matlab/db. A certain directory is designed the root of a 'matbase' (MAT file database). The Matlab function dbroot returns or sets this directory: ?- ??dbroot. >> ans = /Users/samer/matbase ?- ??dbroot(q('/usr/share/lib/matbase')). % switch to shared matbase >> ans = /usr/share/lib/matbase In this case, the locator mat:d0608/m48598|x refers to a Matlab variable called 'x' (it's always 'x') in the file /usr/share/lib/matbase/d0608/m48598.mat. A new directory is created each month, and the filenames are chosen dynamically to avoid clashes with existing files. *** Debugging/tracing To help with debugging, you can issue the command: ?- utils:set_state(debug,on). which will cause each Matlab expression to be printed in its Matlab form before execution. I'm afraid the best documentation is the code itself, but I do intend to produce a manual once some of the more embarrassing aspects of system are resolved! ------------------------------------------------------------------------- BUILDING/INSTALLATION See INSTALL ------------------------------------------------------------------------- CHANGES 12/04 - Using Prolog blobs with garbage collection to handle Matlab workspace temporary variables. Works but code is still a little messy. Would like to unify variable handling- the important functions are alloc, free, get, put. Also, garbage collection seems to be rather difficult to provoke. 2005-08-08 Handle Matlab errors in mlEXEC by setting lasterr() before and checking it after engEvalString. If we do get a Matlab error, then throw a Prolog exception, because nothing else is safe in general. CSR. 2005-08-09 Be a little more paranoid in handling workspace variables, both in terms of checking matlab engine error codes and for bounds checking of our own functions such as uniquevar. 2005-09-26 Added matbase_mat/1 to enumerate all mat objects actually in the file system pointed to by the matlab function dbroot. 2005-11-11 Now sending very long Matlab commands via a char array Progress in Prolog-side mxArray support: done: MXINFO - get size and type of array MXSUB2IND - convert multi-dim subscript to linear index MXGETFLOAT - get one element of numeric array (must be real) MXGETLOGICAL - get element of logical or 0|1 array MXGETCELL - get sub mxArray from cell array MXGETREALS - get reals part of all elements as flat Prolog list MXCREATENUMERIC - create double array MXCREATECELL - create cell array MXCREATESTRING - create char array from string or atom MXPUTFLOAT - write one element of double array MXPUTFLOATS - write list of elements to double array MXPUTCELL - put an mxArray into a cell array MXCOPYNOGC - deep copy of array, return NON-MANAGED mx ref MXNEWREFGC - return memory managed ref to array, ie will be GCed to do: Imaginary parts? Reading list of fields from a structure Getting cell array contents as a list tidy up: error checking and function names possibly reduce the amount of bounds checking to improve speed? -> need to do proper profiling! 2006-11-28 Errors generated on the matlab side (ie errors in user functions rather than the mechanisms of this library) throw exceptions of the form mlerror(Engine,Message) instead of just atomic messages. Some changes to plml.pl - see header in that file for details. 2008-11-25 Moved declaration of \ operator to ops.pl Changed interface and implementation of ml_open to use list of options. Changed build procedure to use build script and two makefiles. 2010-02-25 Replaced use of mxFree with mxDestroyArray to release resources obtained using engGetVariable - this was causing a malloc error in Matlab 7.9. Also replaced -nojvm with -noawt option when starting Matlab, as -nojvm is no longer supported. Apparently they're going to withdraw support for X11 graphics at some point. I hate them. I'm not 'upgrading' any more. 2010-03-19 Removed dependency on flists 2010-05-30 Merged hostname module into utils. 2012-01 Big overhaul of Prolog part to simplify and speed up. Removed unused Matlab functions from matlab/general. Version 1! ------------------------------------------------------------------------- ACKNOWLEDGMENTS This work was partially supported by UK EPSRC grants GR/S84750/01 and GR/S82213/01.