Running MATLAB script in a bash loop - bash

I need to run a MATLAB script inside a bash loop. I'm aware of the syntax which goes as follows:
for i in "${img[#]}"
do
echo $i
matlab -nosplash -nodesktop -nojvm -r "myfunction('$i','cropped_$i');quit;"
done
It works as it should, however, I find it extremely annoying that it has to quit and open MATLAB every iteration, greatly increasing computation time. Is there any way to run it more natively without having to close/open every iteration?

Writing the loop in Matlab is clearly the superior answer, although I don't know Matlab well enough to present that as an answer. Another option is to construct the Matlab code dynamically.
for i in "${img[#]}"; do
code+="myfunction('$i', 'cropped_$i');"
done
code+="quit;"
matlab -nosplash -nodesktop -nojvm -r "$code"

Related

MATLAB scripts and fortran scripts are used in a for loop of a bash script. Can I avoid call MATLAB multiple times?

I have a bash shell script that runs multiple MATLAB and fortran codes within a for loop.
In the loop, the bash script calls MATLAB over and over again. This make the script inefficient.
I use MATLAB 2017b and Mac OS X Catalina(10.15.7).
Any suggestions?
#!/bin/bash
for i in {1..10}
do
cp initial_input_$i initial_input
matlab -nodesktop -nosplash -r "matlab1; exit;"
cp matlat1.output fortran1.input
gfortran fortran1.f
./a.out
cp fortran1.output matlab2.input
matlab -nodesktop -nosplash -r "matlab2; exit;"
cp matlab2.output fortran2.input
gfortran fortran2.f
./a.out
cp fortran2.output matlab3.input
matlab -nodesktop -nosplash -r "matlab3; exit;"
cp matlab3.output fortran3.input
gfortran fortran3.f
./a.out
cp fortran3.output final_output_$i
done
There's no built-in plain Matlab way to do this on Mac or Linux; it doesn't run in a "client/server" mode where there's a persistent Matlab process that takes multiple commands. (If you were on Windows, you could use Matlab's "COM Automation Server" mode to do this.)
The official MathWorks way to do this would probably be to use their Matlab Production Server product, which is a server that runs a pool of Matlab workers that you can dispatch calls to via a JSON API. But that's pretty heavyweight and enterprisey for your environment, doesn't run on Mac at all, and will cost you like $20,000.
If you really wanted to do this with Matlab in a client-server way, you could write a Matlab program that causes Matlab to operate as a server: Have it run a loop that waits for input by checking a directory for new files or listening on a socket, and then when new input arrives, use eval() to run it, and then returns to the loop to wait for more input. When you're all done with it, send it an exit command.
But that's kind of a lot of work, and debugging multi-process communication stuff like that is hard. So what I'd actually do in your case is just push the bash script stuff down in to Matlab M-code like Cris Luengo suggested, so that your Matlab script is in control of the whole process. The functionality of this bash script could be easily written in Matlab using the system() function and/or ! construct.

How to use variables from a Bash shell script in Matlab m-file

I've inherited an m-file that calls the function:
function conditions(varargin)
This requires me to type a series of names when running the m-file. E.g.,:
conditions('c01','c02','c03')
I also have a text file (conditions.txt) that contains all conditions names, one conditions per line. e.g.,:
'c01'
'c02'
'c03'
etc...
Is there a way to automate conditions.m through the Bash shell by running through each line of the text file, one line at a time?
Since you're happy to take other suggestions as well, I'm going to suggest you do this through a simple MATLAB script. MATLAB takes a while to start up, so it is quite inefficient to start MATLAB anew for each "condition".
I'm going to assume that your text file example is a simplification, maybe you have multiple parameters per line, and need to pass each of them as an argument to the conditions function. For example the file conditions.txt could contain:
'c01',5,false
'c02',100,true,0,'foo'
...
and you'd want to generate the calls
conditions('c01',5,false)
conditions('c02',100,true,0,'foo')
...
The following code accomplishes this:
f = fopen('conditions.txt','rt');
while true
data = fgetl(f);
if isequal(data,-1), break, end
eval('conditions(',data,')')
end
fclose(f);
exit
You could save that as an M-file script (e.g. runconditions.m), and execute it from bash as follows:
matlab -nosplash -nodesktop -r runconditions
eval is evil, in general, but in this case it's the same as what you'd be doing from the Bash script in Christian's answer. The only difference with that answer is that you avoid starting up MATLAB repeatedly.
At least on windows you can call matlab functions from batch like this: matlab -wait -r 'conditions(%var%)'
So your bash looping should be solvable with a code snipped like this:
while read p; do
matlab -wait -r 'conditions($p)'
done <yourfile.txt
Or any other looping style of your choice:
Looping through the content of a file in Bash

run Matlab commands one by one on windows using .bat file

I am trying to run a function on different files; I would like to use Bash-Like script to do that. When I looked on the web; I found that I can use .bat file.
My .bat file contains this
matlab -bodesktop -nosplash -r myFunction('input_1.txt')
matlab -bodesktop -nosplash -r myFunction('input_2.txt')
matlab -bodesktop -nosplash -r myFunction('input_3.txt')
matlab -bodesktop -nosplash -r myFunction('input_4.txt')
matlab -bodesktop -nosplash -r myFunction('input_5.txt')
When I double click the file, it seems that these commands are running on parallel, which, makes the PC to crash.
I looked on Matlab Forum for alternative solutions, but couldn't work with me
Another option I found:
start -wait matlab -bodesktop -nosplash -r "myFunction('input_1.txt');exit"
..
Anyone used this before ?
There are two matlab binaries, one matlabroot/bin the other in matlabroot/bin/win64/. The first one is only a launcher application which typically terminates as soon as the main application is started successfully. To keep it open until the main application terminates you have to use the -wait option with your matlab.exe (not to be confused with the start -wait option, bot can be used together).
In your case try:
matlab -wait -nodesktop -nosplash -r myFunction('input_1.txt')
(I assume you intended to use "nodesktop").
All start parameters for windows are explained here in the documentation. (You have to click "option1...optionN" to expand the relevant section.)
First check that you have the option spelled correctly. Click here for the options.
Try this:
matlab -wait -nodesktop -nosplash -r "myFunction('input_1.txt')"
Edit:
By default, when you call the matlab command from a script, the command starts MATLAB and then immediately executes the next statements in the script. The -wait option pauses the script until MATLAB terminates.
Use the -wait option in a startup script to process the results from MATLAB. Calling MATLAB with this option blocks the script from continuing until the results are generated.

Running Matlab .m file with arguments in a bash script

I have a Matlab .m file that takes three input arguments:
calculate('input.txt','Alex','output.txt')
I would like to run this .m file in a shell script as follows:
matlab -nodisplay -nodesktop -r "run
calculate('input.txt','Alex','output.txt)"
Unfortunately, this did not work. I get the following error:
Error using run (line 70)
calculate('input.txt','Alex','output.txt') not
found.
Any pointer as to how I can give the input arguments/variables?
Thanks.
Note: The following did not work either - complaining too many arguments.
matlab -nodisplay -nodesktop -r "run calculate input.txt Alex output.txt"
I think you just need to remove run. run is for scripts, not for functions (and anyway it's not necessary unless you need to specify the script's path). So, try
matlab -nodisplay -nodesktop -r "calculate('input.txt','Alex','output.txt')"
If your function calculate is not in Matlab's path, change to its folder first. For example
matlab -nodisplay -nodesktop -r "cd 'c:\users\Alex\SomeFolder'; calculate('input.txt','Alex','output.txt')"

Calling Matlab/Psychtoolbox from the Shell or from a Makefile does not give the same behavior ! Why?

I thought a Makefile was just executing the stated shell commands, but things seem not that simple :
sample.m is a minimal matlab program that displays a word on screen.
When launched from a Makefile, it does not behave the same as when launched from the shell...
From the shell
alex:~$ matlab -nosplash -nodisplay -r "sample"
-> Displays the word correctly
From a Makefile
all :
matlab -nosplash -nodisplay -r "sample"
alex:~$ make
-> Displays the word with a blue bounding box
How can it be different ?
I'm using Matlab 2010a on a Ubuntu 10.04 machine.
No arguments are passed to the sample.m script.
Did you make sure you quit Matlab after running the script?
The Matlab console will linger in memory, invisible when run from make, and some resources will remain locked.
try this in your Makefile:
matlab -nosplash -nodisplay -r "sample; exit"
I tested sample.m and it works here.

Resources