[[PageOutline]] The MATLAB API of MUSCLE is a subset of the C++ API, the C++ API is again a subset of the Java API. Because the core of MUSCLE is written in Java, the runtime would start a new MATLAB instance that will communicate with Java code, but this is hidden in the API. == MATLAB API == The MATLAB API allows sending and receiving basic data types and getting properties from the MUSCLE configuration file. Below are the available functions, which mirror their [["C++ API"|MUSCLE C API]] counterpart. {{{ % Initialize MUSCLE environment muscleInit() % Cleanup MUSCLE environment muscleFinalize() % returns kernel name muscleKernelName() % return configuration file property value muscleGetProperty('propName') % check if property exists muscleHasProperty('prop_name') % test against the formal submodel termination condition muscleWillStop() % sends data muscleSend('entrance', array) % receives data data = muscleReceive('exit', data_type) }}} Due to mismatch between C and MATLAB datatypes, only a subset of the datatypes supported in the C API is available in the MATLAB API, namely: * `MUSCLE_DOUBLE` - array of doubles * `MUSCLE_STRING` - character string * `MUSCLE_INT32` - array of integers * `MUSCLE_BOOLEAN` - array of logicals In the MUSCLE configuration file, kernels should use the `muscle.core.standalone.MatlabKernel` class or its subclass as their implementation, and `MatlabInstance` as the CxA counterpart: {{{ w = MatlabInstance.new('w', 'my/matlab/script.m') }}} In the constructor, the Matlab executable and its arguments, the Java class, and script arguments can optionally be specified, in any order: {{{ w = MatlabInstance.new('w', 'my/matlab/script.m', matlab: '/opt/bin/matlab', matlab_args: '-matlab_arg1 -matlab_arg2', java_class: 'company.MyMatlabJavaInstance' args: 'param1 param2') }}} == Example == In the `src/matlab/examples/simplematlab` is an example of a kernel using the MATLAB API to send an array of doubles. This array is then received by the !ConsoleWriter class, as specified in the configuration file `src/cxa/SimpleMatlabExample.cxa.rb`. * The `sender.m` MATLAB script is as follows: {{{ muscleInit() fprintf('Kernel Name = %s\n', muscleKernelName()) fprintf('has property "script"? = %d \n', muscleHasProperty('script')) fprintf('Property[script] = %s \n', muscleGetProperty('script')) fprintf('has property "not_existing"? = %d \n', muscleHasProperty('not_existing')) dataA = [ 0.0, 1.0, 2.0, 3.0, 4.0 ] muscleWillStop() while not( muscleWillStop() ) muscleSend('data', dataA) end muscleFinalize() }}} * A session using this script outputs the following (note that MATLAB is started to run the script): {{{ Running both MUSCLE2 Simulation Manager and the Simulation === Running MUSCLE2 Simulation Manager === [15:32:59 muscle] Started the connection handler, listening on 10.10.4.225:9000 === Running MUSCLE2 Simulation === [15:33:00 muscle] Using directory [15:33:00 muscle] r: connecting... [15:33:00 muscle] Registered ID r [15:33:00 muscle] w: connecting... [15:33:00 muscle] Registered ID w [15:33:00 muscle] The conduit exit 'data@r' will use filter(s) [multiply_0.5]. [15:33:00 muscle] w conduit entrances (out): [data] w conduit exits (in): [] [15:33:00 muscle] w: executing [15:33:00 muscle] r conduit entrances (out): [] r conduit exits (in): [data] [15:33:00 muscle] r: executing [15:33:00 muscle] warning: MATLAB command variable 'matlab_command' for w not given. Using matlab. [15:33:00 muscle] warning: MATLAB arguments variable 'matlab_args' for w not given. Not using arguments. (15:33:00 w) Spawning standalone kernel: [matlab, -nosplash, -nodisplay, -r, addpath('/mnt/lustre/scratch/groups/plggmuscle/2.0/share/muscle/examples/simplematlab','/mnt/lustre/scratch/groups/plggmuscle/2.0/share/muscle/matlab/modules/'); try, sender, catch Ex, Error = Ex, ErrorReport = getReport(Ex, 'extended'), ErrorStack = Ex.stack, exit(4), end; exit] < M A T L A B (R) > Copyright 1984-2013 The MathWorks, Inc. R2013b (8.2.0.701) 64-bit (glnxa64) August 13, 2013 To get started, type one of these: helpwin, helpdesk, or demo. For product information, visit www.mathworks.com. Kernel Name = w has property "script"? = 1 Property[script] = /mnt/lustre/scratch/groups/plggmuscle/2.0/share/muscle/examples/simplematlab/sender.m has property "not_existing"? = 0 dataA = 0 1 2 3 4 ans = 0 (15:33:12 r) got: 0.0 (15:33:12 r) got: 0.5 (15:33:12 r) got: 1.0 (15:33:12 r) got: 1.5 (15:33:12 r) got: 2.0 (15:33:12 r) (15:33:12 r) got: 0.0 (15:33:12 r) got: 0.5 (15:33:12 r) got: 1.0 (15:33:12 r) got: 1.5 (15:33:12 r) got: 2.0 (15:33:12 r) (15:33:12 r) got: 0.0 (15:33:12 r) got: 0.5 (15:33:12 r) got: 1.0 (15:33:12 r) got: 1.5 (15:33:12 r) got: 2.0 (15:33:12 r) (15:33:12 r) got: 0.0 (15:33:12 r) got: 0.5 (15:33:12 r) got: 1.0 (15:33:12 r) got: 1.5 (15:33:12 r) got: 2.0 (15:33:12 r) [15:33:12 muscle] r: finished [15:33:12 muscle] Deregistered r; will quit MUSCLE once 'w' has finished computation. (15:33:12 w) Program finished. (15:33:12 w) Command [matlab, -nosplash, -nodisplay, -r, addpath('/mnt/lustre/scratch/groups/plggmuscle/2.0/share/muscle/examples/simplematlab','/mnt/lustre/scratch/groups/plggmuscle/2.0/share/muscle/matlab/modules/'); try, sender, catch Ex, Error = Ex, ErrorReport = getReport(Ex, 'extended'), ErrorStack = Ex.stack, exit(4), end; exit] finished. [15:33:12 muscle] w: finished [15:33:12 muscle] All ID's have finished, quitting MUSCLE now. [15:33:12 muscle] All local submodels have finished; exiting. Executed in }}}