Using Mathematica within E-Prime

When programming complex experiments (for example, involving the generation of stimuli online)

low-level programming language.E-Prime is such a experiment programming software.Within E-Prime, it is possible to add customized code using the Visual-Basic programming language.Whereas verifying that a performance criterion is reached is fairly easy to program in Visual-Basic (point i above), generating random stimuli can be more difficult if a random number generator different from a uniform distribution is needed.As of altering stimuli, it can be near impossible to do with Visual-Basic as there is no linear algebra, no Fourier or wavelet transforms, no convolution sub-routines in this language (this is why it is called a "low-level" programming language).Such sub-routines (either procedures or functions) can be defined in E-Prime, but doing so takes times (the code for any such sub-routine can be many pages long, with debugging and testing a tedious process).
When one of those situations arise, there are two possible courses of action: (A) Give up the use of an experiment programming software and program everything with a low-level programming language such as C.Although advanced sub-routines are not part of the C language, they can be found in various references (e. g.Press, Flannery, Teukolsky and Vetterling, 1986).(B) Use a high-level programming environment as long as it is capable of presenting stimuli and reading responses with a very high timing accuracy.To our knowledge, only Matlab is capable of this if a special library is downloaded, the Psychophysics toolbox (Brainard, 1997).
We believe that both solutions are too radical as they totally evacuate the experiment programming software.These software are robust, very easy to program and easy to connect to other devices such as response boxes, fMRI and EEG acquisition systems, etc.In what follow, we propose a third alternative: a mixed environment in which all the stimulus presentation and response collections are assumed by an experiment programming software and in which all the advanced computational capabilities are assumed by a high-level programming software.
The duo discussed in this article is E-Prime and Mathematica (E-Prime, 2004, Chen, Cui, & Zhang, 2005, Wolfram, 1996).Here, E-Prime is used as the primary program: It will start Mathematica, send requests and read responses, and finally, shut down Mathematica when the experiment is finished.In the first section, we show how E-Prime can start and end a Mathematica session.In the subsequent section, we will briefly explain the protocol used to exchange information between the two programs.However, all these technical details are not essential: Section 3 provides the necessary sub-routines to add to E-Prime.You can simple type them into E-Prime and use them to control Mathematica without advanced understanding of how they operate.Section 4 gives a complete example where additive noise is added to images in proportion to the accuracy of the identification responses.

1-Starting and ending a session with the Mathematical kernel
Mathematica is in fact composed of two programs: The Mathematica front-end (the file mathematica.exe)which is the user interface, and the Mathematica kernel (the file mathkernel.exe)which is responsible for actually performing the computations.When the user type "Enter" in the front-end, the expression in the current cell is packed and send to the kernel.The kernel processes it and returns packages ("packet" in the Mathematica idiom) containing the response(s) of the kernel.The sending and receiving of packets are managed by the MathLink protocol.Figure 1 summarizes this.
The MathLink protocol is implemented in a library composed of functions and subprograms.The latest version (Implementation 3) is available for both 32-byte and 64 byte processors (in doubt, the 32-byte version works on all machines).It is installed by Mathematica in the C:\Windows\System32 folder under the name ML32I3.dll(or ML64I3 for the 64-byte version).Here, the extension ".dll" stands for "dynamically-linked library".Such files contain functions and subroutines that can be used by any programs written in any language.They are already compiled and ready to use.
To start a kernel and be able to communicate with it, you need to use two functions provided in the MathLink library, MLInitialize and MLOpenString.The second will return a link which will identify the kernel with which E-Prime is interacting (many kernels can be opened simultaneously).The link is necessary for all interaction and to close the kernel.To start the kernel, a connecting string is required which specifies that a new kernel must be launched (the alternative would be to spy on an existing kernel) and what is the path and file name of the kernel on your computer.The instructions in E-Basic (Visual Basic for E-Prime) are: Dim MLEnv as long, MLLink as long, MLErrNo as long MLEnv = MLInitialize(0) MLLink = MLOpenString(MLEnv, "-linkmode launch -linkname \"C:\\\\Program files\\\\Wolfram Research\\\\Mathematica \\\\6.0\\\\MathKernel.exe-mathlink\" ", MLErrNo) The second command is all on a single line.Because both E-Prime and the MathLink library interpret the backslash as an escape character, it has to be doubled twice (hence quadrupled).Finally, the path must be enclosed in " so they must be preceded by the escape character (the backslash).
To close the kernel, the instructions are:

2-The protocol to communicate with the Mathematical kernel
Before it can be sent to the kernel, an expression must be Once received, the kernel returns the response, accordingly wrapped in a ReturnTextPacket, followed by a string containing the response, e.g."4" (here, Return means "Returned from the kernel").The kernel also returns identifications of the current output label (e.g."Out[1]=") wrapped in OutputNamePacket as well as the next input label (e.g."In[2]:=") wrapped in InputNamePacket.In addition, if an error occurred, an ErrorMessagePacket and a TextPacket will be issued giving the error name and the error description (e.g.Part::partd : Part specification <<1>> is longer than depth of object).Figure 2 left gives an example where the wrappers are shown.
If more flexibility is required, instructions can be sent under the form of an expression.Expressions detail explicitly the functions, the symbols, the integers, the reals and the strings being sent.For example, the expression 2+2 is in fact given by Plus[2,2] (use FullForm in Mathematica to know how to represent an expression explicitly).To do so, the expression is wrapped in an EnterExpressionPacket and the response is wrapped in a ReturnExpressionPacket. Figure 2 right gives and example.
Once the packets have been set, they must be sent using the appropriate function from the MathLink library, one function call per element in the packet.
Functions are sent using the function MLPutFunction followed by the name of the function (or wrapper, they are seen as function as well) and the number of arguments to the function.Data are sent using MLPutInteger, MLPutReal or MLPutString depending on the type of data.Finally, symbol names (variables and constants) are sent using MLPutSymbol.To signal the end of a packet, use MLEndPacket.Listing 1, top, indicates how to send a string containing 2+2 using the EnterTextPacket while Listing 2, bottom does the same using an expression.Those functions returns a non-zero value if an error occurred (but if the link opened properly and the packet is syntaxically correct, there should not be an error).
Table 1 gives the list of functions that are required to manage a link to a kernel.If the wrapper EnterTextExpression is used, the functions to put and get reals, integers and symbols are no longer useful since everything is sent and received as strings.
The kernel places the response packets in a waiting list where they can be fetched.The packets have a packet type and a packet content.For example, in response to Plus[2,2], the response packet will be of type Integer and its content will be the number 4. Response packets are wrapped in a ReturnTextPacket.This packet has a type of its own (see Table 2) but has no content of its own.It only signals that a string packets follows.
To know the packet type, use the function MLNextPacket.Packet types are identified by a unique number, listed in Table 2.As wrapper packets have no content, simply fetch the subsequent packet with MLGetNext or skip the remaining of the packet with MLNewPacket.

3-Integrating all this into E-Prime
All the previous considerations can be reduced to four operations: Opening and closing the kernel, sending Mathematica instructions and receiving responses.To achieve this within E-Prime, we programmed two subprocedures and two functions: Sub MLStart starts the kernel in mathlink mode; you must verify that the path to the file MathKernel.exe is correct on your system.

Table 1 .
Functions part of the MathLink library

Table 2 :
types of packet and the number identifying them (received by MLNextPacket or MLGetNext).
Declare Function MLPutSymbol Lib "ML32I3.dll"(ByVal link As Long, ByVal symb As String) As Long Declare Function MLPutString Lib "ML32I3.dll"(ByVal link As Long, ByVal comm As String) As Long Declare Function MLPutInteger Lib "ML32I3.dll"(ByVal link As Long, ByVal n As Integer) As Long Declare Function MLPutDouble Lib "ML32I3.dll"(ByVal link As Long, ByVal x As Double) As Long Declare Function MLGetString Lib "ML32I3.dll"(ByVal link As Long, ByRef funct As String) As Long Declare Function MLGetFunction Lib "ML32I3.dll"(ByVal link As Long, ByRef funct As String, ByRef n As Long) As Long Declare Function MLGetInteger Lib "ML32I3.dll"(ByVal link As Long, ByRef n As Integer) As Long Declare Function MLGetDouble Lib "ML32I3.dll"(ByVal link As Long, ByRef x As Double) As Long Declare Function MLGetSymbol Lib "ML32I3.dll"(ByVal link As Long, ByRef symb As String) As Long