How do I suppress the DOS window from Matlab? - matlab

I have 'inherited' Matlab code (A) that uses another compiled Matlab code (B). I do not have the source of B. B requires user intervention ('Hit return to continue'), and I need to use A in a loop. I need to do something so I would not need to hit Return each and every time until the loop is done.
The command I use in the loop is:
str='!start "Code_B" /low "c:\Code_B\bin\Code.exe" r';
eval(str)
Are there any other switches that I can use to suppress the call to 'Hit return' ?
Thanks
Katto

One way you could do this is to create a batch file that:
Starts the compiled Matlab program
Waits for the program to run (fixed delay?)
Uses a utility to send the program an Enter key
There are many (free) utilities that let you send keystrokes to a program.
Instead of calling Program B, you would call this batch file.

You can create a text file, let's say autoreturn.txt, with many empty lines (just end of line characters), over the number of loops you expect. Then add redirection of input from this at the end of your string:
str='!start "Code_B" /low "c:\Code_B\bin\Code.exe" r < autoreturn.txt';

Related

Keep terminal session between system() calls in MATLAB

MATLAB opens a new session every time system is called.
I want to be able to keep the session open and perform several calls to it.
Ideally, this would work:
system('export DUMMY=2');
[~, out] = system('echo $DUMMY');
disp(out)
But it doesn't as each system call is separate. How can I get around this and keep one session running?
The code above can be fixed by using setenv, replacing the first line with setenv('DUMMY', '2');, but I am looking for a more general solution.
Would something along these lines be suitable for you?
C:\Users\...>SET "foo=bar" & ECHO %foo%
bar
Windows batch files and command prompt allow to execute multiple commands on a single line concatenating them with &. Example with Matlab:
[~, out] = system('SET "foo=bar" & ECHO %foo%');
disp(out); % bar
Alternatively, you could create a .bat file to be called through the system function, whose behavior depends on the arguments you pass to it (read this post for more information).

Running an interactive Matlab .m file with a batch call

I have a Matlab .m file that I usually run interactively. I would like to run some jobs overnight, WITHOUT re-writing the .m file to remove the interactive queries for input. I used to be able to do this with Fortran or C or VB executables by running a batch file from the OS's command line. Is this possible with Matlab? (Also, I don't have the Matlab compiler. But I can have Matlab open the whole time.)
Skeleton of Program:
Input variable1 from keyboard;
Input variable2 from keyboard;
Long calculation;
Save results to file;
Stop
But, if I make a "batch" .m file to run Program, like this:
Program
0.2
0.47
Program
1.2
2.4
then Program just sits there forever waiting for my input from the keyboard. Is there a way to run Program so that it gets its interactive inputs from the calling .m file?
What environment/operating system are you working on? You refer to a batch file which leads one to think you are working in Windows. If you are working in Linux, you can use the echo command and pipe the results into your program. For example:
#my_bash_script.sh
echo "0.2
0.47
" | Program
Perhaps you can do something similar if you are working with Windows batch files. Check out this as one resource:
https://ss64.com/nt/syntax-redirection.html
This is a workaround, not an answer, but it is too long for a comment. After researching this for a while, I don't think Matlab can do what the question requests. (Not without compiling the Matlab code into an executable.) I got around it by writing a function (call it Meta) that reads the entire "batch" file of responses and returns them as a string array. I gave Program two extra input parameters: a flag for interactive/batch running (FlagBatch), and a string for the batch filename (BatchName). If FlagBatch is 1, Program uses Meta to read BatchName and generate ResponseArray, which is used to provide responses to any requests from Program. Kludgey, but it works, with minimal reprogramming of Program. (Of course, I had to have access to Program's code, but if I'd only had an executable from someone else, then I wouldn't have had this problem in the first place!)
Another workaround. Define myinput (see below), and use that everywhere to replace input. As in my other workaround, you give Program two extra input parameters: a flag for interactive/batch running (FlagBatch), and a string for the batch filename (BatchName). Also have
if FlagBatch==1, fid=open(BatchName); end
near top of Program. This approach is nice when you have dozens of input statements scattered all over Program (and various subroutines/functions).
function A=myinput(fileID,prompt,formatSpec,sizeA)
% A=myinput(fileID,prompt,formatSpec);
% Function myinput will read from either stdin (keyboard) or from a file,
% allowing programs' inputs to be entered interactively or from a file.
% Use it instead of Matlab's built-in functions input and fscanf.
% fileID = file ID (fid) of the opened file, or 0 for keyboard input.
% prompt = the prompt string (not used for file input)
% formatSpec = string containing Matlab format spec;
% not used for keyboard input
% sizeA = size of A; basically specifies how many times to use formatSpec;
% not used for keyboard input
%
% Example Uses in Program (where fid would have been set earlier):
% NumOrcs=myinput(fid,'Enter # of orcs','%i',1);
% MapFile=myinput(fid,'Enter filename for LotR map','s',1);
% [Sgimli,Slegolas]=myinput(fid,'Strengths of Gimli and Legolas?','%g',2);
%
if fileID==0
if formatSpec=='%s'
A=input(prompt,'s');
else
A=input(prompt);
end
else
A = fscanf(fileID,formatSpec, sizeA);
end
return

How to generate new numbers if i run the program everytime from the begining?

I am working on CATScript in optimization of a part.
When I run the script everytime it shoud provide numbers in ascending order.
For example if I run the program for the first time it should provide the output as " 1 "
and if I run the program again it shoud provide the output as " 2 " and so on.
I am stuck with this and I could not figure out th logic that we have to use here.
Looking forward for your help.
Thank you!!
An option (matlab based) could be to save a counter variable to a .mat-file at the end of the script, which is then loaded again at the beginning of the script.
That would allow you to keep track of how many times the script have been run.
In CATIA if it is being run multiple times on the same part/product, you could add a hidden, integer parameter to the specification tree and increment it each time the macro is run.
Another, more generic way would be to create a text file on the user's local and update the number in the text file.

fopen error - works for a while but then gives an error

I have a script that is running a series of for loops, and within these for loops a file is created that is then run using an external program using the script command. In summary it looks like this:
for i=1:n1
for j=1:n2
for k=1:n3
fid=fopen('file.txt','w');
fprintf(fid,'Some commands to pass to external program depending on i j k');
fclose(fid);
system('program file.txt');
end
end
end
The script has in total about 500k cases (n1xn2xn3), and runs fine for a small scenario (about 100 runs), but for the entire script it runs for a while and then returns an error for no apparent reason, giving this error:
fopen invalid file identifier object
There is no obvious reason for this, and Im wondering if anyone could point out what is wrong?
Just a guess: an instance of your external program is reading file.txt and at the same time the next iteration of your nested loop wants to open file.txt for writing. The more instances of your external program are running at the same time, the slower your machine, the more likely becomes this scenario. (called a 'race condition')
Possible solution for this: use a separate text file per case with a unique file name
You should also consider using other ways to call your external function because file handling for 500k cases should be very slow.
Hope that helps,
Eli

Running a Perl script within a Stata .do file

Is it possible to execute a Perl script within a Stata .do file?
I have a Stata .do file in which I make some manipulations to the data set and arrange it in a certain way. Then I have a Perl script in which I take one of the variables at this point, apply a Perl package to it, and make a transformation to one of the variables. In particular, I use Perl's NYSIIS function, resulting in a very short script. After this output is provided in Perl, I'd like to continue with some additional work in Stata.
Two alternatives that come to mind but that are less desirable are:
Write Stata code to do nysiis but I prefer to use Perl's built-in function.
outsheet and save the output from the Stata .do file as a .txt for Perl. Then do the Perl script separately to get another .txt. Then read in that .txt to Stata to a new .do file and resume.
Your approach number 2 is what I use to call other programs to operate on Stata data. As Nick says, Stata won't necessarily wait for your output, unless you ask it to. You first outsheet the text file, then call the Perl script from Stata using ! to run something on the command line. Finally, have Stata periodically check for the result file, using a while loop and the sleep command so Stata isn't constantly checking.
outsheet using "perl_input.txt"
!perl my_perl_script.pl
while (1) {
capture insheet using "perl_output.txt", clear
if _rc == 0 continue, break
sleep 10000
}
!rm perl_output.txt
Here, your formatted data is saved from Stata as perl_input.txt. Next, your Perl script is run from the command line, and using a while loop, Stata checks for the output every 10 seconds (sleep takes arguments in milliseconds). When it finds the output file, it breaks out of the while loop. The last line is a good idea so that when you re-use the code you don't run the risk of using the Perl output from the last run.
I think the main issue is that although you can use the shell to call up something else, Stata is not going to wait for the results.
Start with help shell to see what is possible, but your #2 does sound easiest.