Running same script with different input variables using batch command - matlab

I would like to run a script called 'myscript' using the batch command:
j = batch('myscript')
My script has a function in the beginning so:
function myscript(input)
...
end
Is it somehow possible to run batch files with different input parameters for my function? I know that there are matlabpool, parfor etc commands, but it is unfortunately not working for me.

The syntax you have to use is indicated in the documentation of batch():
j = batch(fcn,N,{x1, ..., xn})
and in your case
j = batch(fcn, 1, {input})
Alternatively, you can check How do I call MATLAB from the DOS prompt?

Related

How to pass integers and strings from MATLAB to a PowerShell script?

I need to automate a test. The test itself is being written (by me) in MATLAB, has 5 stages, each stage ends with setting a value to an integer (uint16_t and uint8_t) and with a message. I have to pass these 5 integers and 5 strings to a PowerShell script because Jenkins can only run a PowerShell or Python script, but I'm not entirely sure how can I achieve that. I have never used PS or done any scripting, and there isn't much on the Internet on how to even run a MATLAB script with PowerShell. (Maybe I should check batch file scripts running MATLAB scripts.)
The only option I've found so far is writing into a (temporary) file with MATLAB, then reading from it (and deleting it), it could be a .txt file, or preferably a .csv file (although using csvwrite is not recommended by Mathworks), but this isn't very reliable. Can anyone suggest other methods to pass it more directly? The MATLAB file is not a function, but it can be made to be one that has these variables as outputs. Also, it's fine if the integers are cast to another integer type.
Like #TessellatingHeckler said the way is $results = matlab.exe yourscript.
Here is an example if you want more features when launch the tests like no display windows ,run in a batch mode or wait to the end of matlab execution.
runTestMatlab (){
result=$(matlab.exe -wait -nosplash -noFigureWindows -batch TestScript.m)
if [ $? -ne 0 ]; then
# Error with the Matlab run
echo $result
return 1
fi
echo "$result"
return 0
}
Then you can parse the result with awk or any other tool that you want.

run script command in Matlab

I am running a script in another directory.
Assume I have the following code:
arr = [10;20;30];
run(script); % script= path to the script file + scriptfile.mat ..
x = arr(2);
It gave me the following error:
Undefined function 'arr' for input arguments of type 'double'.
After debugging the code, I found that run(script) .. run the script and then clear all variables .. such as arr.
Is there any way to make run command doesn't clear all variables..
Edit: the following is the original code..
xValues =[2;4;6];
yValues =[10;15;20;30;40];
for var1 =1:size(xValues,1)
results =[];
for var2 =1: size(yValues,1)
run(strcat('C:\Users\as\Desktop\study',num2str(xValues(var1)),'folder\',num2str(yValues(var2)),'folder\file1.m'));
results(var2,1) = yValues(var2);
end
end
Thanks,
Here is an example, erase clear command in your script file:
testing.m
arr = [10;20;30];
run('ScriptFile.m')
x = arr(2);
ScriptFile.m
disp('Hello World');
Command Window
Hello World
After the implementation x holds number 20.
It is clear all inside your script doing the mess I believe.
As for how to avoid it:
Simply remove it. This is generally the easiest and best solution.
Write file to the disk, run script, load from disk. You need a hardcoded file name.
Create "data_holding_function" that has persistent cell array, you load your data there and then restore it after script. You can make the function perform both loading (when you have some input) and unloading (when you don't).

Parallel computing using Matlab

I am executing windows '.exe' file in 'cmd' prompt for various inputs through Matlab. The commands as follows.
for i = 1:n
filename = sprintf('input_%d.dat',i);
string = sprintf('!sfbox.exe %s', filename);
eval(string)
end
All input files are present and independent of each other. But if I attempt to parallelize the execution using 'parfor' as follows,
parfor i = 1:n
filename = sprintf('input_%d.dat',i);
string = sprintf('!sfbox.exe %s', filename);
eval(string)
end
I get an error, but the code runs serially without stopping
Explanation
MATLAB runs parfor loops on multiple MATLAB workers that have
multiple workspaces. The indicated function might not access the
correct workspace; therefore, its usage is invalid.
Is there a correct way to execute the eval using parfor?
(PS: I tried manually executing several .exe files in cmd prompt and it is feasible to run several .exe files at same time in command prompt. Problem is the way I attempt to do it in Matlab. Please suggest better methods.)
You are hitting issues with Matlab not knowing what eval is actually doing. While you know that it's doing the right thing, the eval command could be executing anything. There is a little documentation on transparency issues using eval statements in parfor and spmd statements.
Switching to use an feval statement should solve your problem, as Matlab will know that the only thing going into that statement is a string. More directly, you can use the system command to directly execute an arbitrary string in the cmd prompt from matlab.
parfor i = 1:n
filename = sprintf('input_%d.dat',i);
string = sprintf('sfbox.exe %s', filename);
system(string);
end

Get command line arguments in matlab

This is probably too easy, but I cannot google the answer for this: how can I get command line arguments in matlab script.
I run matlab as matlab -nodisplay -r "run('script.m')" and I want to return all arguments as a list. Something similar to python sys.argv. How can I do this?
I'm using Linux Mint and MATLAB 2015a.
I came up with a simple function that works on both Windows and Linux (Ubuntu):
function args = GetCommandLineArgs()
if isunix
fid = fopen(['/proc/' num2str(feature('getpid')) '/cmdline'], 'r');
args = textscan(fid, '%s', 'Delimiter', char(0));
fclose(fid);
else
kernel32WasAlreadyLoaded = libisloaded('kernel32');
if ~kernel32WasAlreadyLoaded
temporaryHeaderName = [gettempfolder '\GetCommandLineA.h'];
dlmwrite(temporaryHeaderName, 'char* __stdcall GetCommandLineA(void);', '');
loadlibrary('kernel32', temporaryHeaderName);
delete(temporaryHeaderName);
end
args = textscan(calllib('kernel32', 'GetCommandLineA'), '%q');
if ~kernel32WasAlreadyLoaded
unloadlibrary kernel32;
end
end
args = args{1};
On your sample call, it would return this:
>> GetCommandLineArgs
args =
'/[path-to-matlab-home-folder]/'
'-nodisplay'
'-r'
'run('script.m')'
It returns a cell array of strings, where the first string is the path to MATLAB home folder (on Linux) or the full path to MATLAB executable (on Windows) and the others are the program arguments (if any).
How it works:
On Linux: the function gets the current Matlab process ID using the feature function (be aware it's an undocumented feature). And reads the /proc/[PID]/cmdline file, which on Linux gives the command line arguments of any process. The values are separated by the null character \0, hence the textscan with delimiter = char(0).
On Windows: the function calls GetCommandLineA, which returns the command line arguments on a string. Then it uses textscan to split the arguments on individual strings. The GetCommandLineA function is called using MATLAB's calllib. It requires a header file. Since we only want to use one function, it creates the header file on the fly on the temporary folder and deletes it after it's no longer needed. Also the function takes care not to unload the library in case it was already loaded (for example, if the calling script already loads it for some other purpose).
I am not aware of a direction solution (like an inbuilt function).
However, you can use one of the following workarounds:
1. method
This only works in Linux:
Create a file pid_wrapper.m with the following contents:
function [] = pid_wrapper( parent_pid )
[~, matlab_pid] = system(['pgrep -P' num2str(parent_pid)]);
matlab_pid = strtrim(matlab_pid);
[~, matlab_args] = system(['ps -h -ocommand ' num2str(matlab_pid)]);
matlab_args = strsplit(strtrim(matlab_args));
disp(matlab_args);
% call your script with the extracted arguments in matlab_args
% ...
end
Invoke MATLAB like this:
matlab -nodisplay -r "pid_wrapper($$)"
This will pass the process id of MATLAB's parent process (i.e. the shell which launches MATLAB) to wrapper. This can then be used to find out the child MATLAB process and its command line arguments which you then can access in matlab_args.
2. method
This method is OS independent and does not really find out the command line arguments, but since your goal is to pass additional parameters to a script, it might work for you.
Create a file vararg_wrapper.m with the following contents:
function [] = wrapper( varargin )
% all parameters can be accessed in varargin
for i=1:nargin
disp(varargin{i});
end
% call your script with the supplied parameters
% ...
end
Invoke MATLAB like this:
matlab -nodisplay -r "vararg_wrapper('first_param', 'second_param')"
This will pass {'first_param', 'second_param'} to vararg_wrapper which you can then forward to your script.

Running a matlab program with arguments

I have a matlab file that takes in a file. I would like to run that program in the matlab shell, such as prog. I need to implement it so that it takes a number of arguments, such as "prog filename.txt 1 2 which would mean that i can use filename.txt and 1 2 as variables in my program.
Thank you!
In order to make a script accept arguments from the command line, you must first turn it into a function that will get the arguments you want, i.e if your script is named prog.m, put as the first line
function []=prog(arg1, arg2)
and add an end at the end (assuming that the file has only one function). It's very important that you call the function the same name as the file.
The next thing is that you need to make sure that the script file is located at the same place from where you call the script, or it's located at the Matlab working path, otherwise it'll not be able to recognize your script.
Finally, to execute the script you use
matlab -r "prog arg1 arg2"
which is equivalent to calling
prog(arg1,arg2)
from inside Matlab.
*- tested in Windows and Linux environments
Once your function is written in a separate file, as discussed by the other answer you can call it with a slightly more complicated setup to make it easier to catch errors etc.
There is useful advice in this thread about ensuring that Matlab doesn't launch the graphical interface and quits after finishing the script, and reports the error nicely if there is one.
For example:
matlab -nodisplay -nosplash -r "try, prog(1, 'file.txt'), catch me, fprintf('%s / %s\n',me.identifier,me.message), exit(1), end, exit(0)"
The script given to Matlab would read as follows if line spaces were added:
% Try running the script
try
prog(1, 'file.txt')
catch me
% On error, print error message and exit with failure
fprintf('%s / %s\n',me.identifier,me.message)
exit(1)
end
% Else, exit with success
exit(0)