I have some code which I need to run both in MATLAB and in Freemat, using different service functions in each case. To make the whole thing portable I need to find a way to determine which functions to call at the start of my code, depending on which environment I am in.
How does one do that?
I was thinking of using the version command but no too sure if this is really robust.
Use verstring in the context of a try \ catch, the output in matlab will be an error while in Freemat it'll be something like "freemat 4.0", for example:
try
txt=verstring;
output='Freemat';
catch err
output='Matlab';
end
I would try to identify each, and give an error if unsure, or ask the user to identify it manually in such case:
% try to identify if it is freeMat
isDefinatelyFreeMat = false;
try
versionIdentifier=verstring;
if (strcmpi(versionIdentifier(1:7), 'FreeMat'))
isDefinatelyFreeMat = true;
end
catch e
end
% try to identify if it is Matlab
isDefinatelyMatlab = false;
try
versionIdentifier=ver;
if (strcmpi(versionIdentifier.Name, 'Matlab'))
isDefinatelyMatlab = true;
end
catch e
end
% if identification was not successful
if ((isDefinatelyFreeMat && isDefinatelyMatlab) || (~isDefinatelyFreeMat && ~isDefinatelyMatlab))
error('Was unable to identify software.');
% TODO: Ask user to identify software manually
end
Related
I am calling an external exec. file (not written by me) using the system() command inside the MATLAB code. For some reasons the external file s/t gives the Segmentation fault error, and if I run the code again, it gets fixed.
Therefore, as we do in other languages, I am using try catch to catch the error, w/o stopping the whole process. Here is what I have written:
flag = false;
while(~flag)
try
system('….');
flag = true;
catch MExc
flag = false;
end
end
However, it does not catch the error. How to fix it?
I doubt that you can catch an exception thrown by an external application when called within Matlab (actually it's not a doubt, I'm certain, but the sentence is much more elegant). Anyway, from my knowledge, an application that shuts down without errors should return an ExitCode equal to 0.
Fortunately, the system function returns that value as its first output argument (official documentation), so try the following code instead:
status = -1;
while (status ~= 0)
[status,cmdout] = system('...');
end
% do something with cmdout
I am looking for an elegant way to use a conditional try catch statement.
I suppose it could look something like this:
tryif loose==1
% Do something, like loading the user preferences
catch %Or catchif?
% Hande it
end
So far I know that you can use try catch blocks to let your compiled code run, but force it to stop in a debug session with dbstop if caught error. Now I am basically looking for the opposite:
Normally I want the code to stop if unexpected situations occur (to guarantee the integrity of results) but want to be less strict about certain things sometimes when I am debugging.
How about this:
try
% Do something, like loading the user preferences
catch exception
if loose ~= 1
rethrow(exception)
end
% Handle it
end
I don't know about elegant ;-), but at least it avoids the duplication of "do something".
I know one way to do it, though I would hardly call this elegant:
if loose == 1
try
% Do something, like loading the user preferences
catch
% Hande it
end
else
% Do something, like loading the user preferences
end
The best I've been able to do is:
try
% Do something, like loading the user preferences
catch me
errorLogger(me);
%Handle the error
end
And then
function errorLogger(me)
LOOSE = true;
%LOOSE could also be a function-defined constant, if you want multiple uses.
% (See: http://blogs.mathworks.com/loren/2006/09/13/constants/)
if LOOSE
%Log the error using a logger tool. I use java.util.logging classes,
%but I think there may be better options available.
else
rethrow(me);
end
Then, if desired for production-style deployments, avoid the constant condition checking like this:
function errorLogger(me)
%Error logging disabled for deployment
For the "tryif" functionality, you could assert on the first line of the try block:
try
assert(loose==1)
% Do something
catch err
if strcmp(err.identifier,'MATLAB:assertion:failed'),
else
% Hande error from code following assert
end
end
Note that the "Do something" code will not be executed if loose==1.
For the "catchif" functionality, A.Donda's approach of checking loose~=1 on the first line of the catch block seems quite good.
I've been looking over, but I don't think it exists.
There is return to essentially force close your function, which is nice, but in my current script, I want if it does something incorrectly, to instead return to the start of the sub function that it exists in.
Are there any functions that exist already to do that, or will I have to make a system in order to let myself do that?
Instead of using return, error out of the function when something is "done incorrectly", then use try/catch in a while-loop:
while 1
try
myFunction();
break; % if myFunction() was successful, this will exit the while loop
catch
% do some sort of processing here, then go back to the while loop
end
end
The catch portion of the try/catch block will execute only if myFunction() had an error. return implies the function succeeded (whether or not it gave correct output is a different issue entirely).
Alternatively, you could put your function in a while-loop as suggested by #natan. Return some sort of error code, then check for that error code in the while condition.
Just use an while 1 loop to wrap around the whole function and continue when you want to restart the function.
Here is how I would do it if you are not looking for error handling, but just outcome handling
finishedSuccesfully = false
while ~finishedSuccesfully
output = myFunction();
finishedSuccesfully = evaluateoutput(output);
end
The MATLAB imread function provides the ability to read an image from a URL. This generally works OK, but occasionally I encounter an image that takes a very long time to respond.
For instance, at the time of posting the following URL appears to just be stuck in a 'connecting...' state for over 5 minutes before finally succeeding.
http://www.hollywoodheadache.com/wp-content/uploads/2007/12/tom-and-julia.jpg
Is there any way I can set a timeout within MATLAB?
Thanks
I don't know how to interrupt imread with a timer object. Besides, I suspect about its possibility. But I may recommend you to check whether you can access to the file first, and then, you get the file. I have written the following function to check the file and internet status:
function flag = does_url_exist(urlName)
url =java.net.URL(urlName);
try
link = openStream(url);
parse = java.io.InputStreamReader(link);
snip = java.io.BufferedReader(parse);
if ~isempty(snip)
flag = 1;
else
flag = 0;
end
catch exception
flag = 0;
end
end
Then it is as follows:
fname = 'http://www.hollywoodheadache.com/wp-content/uploads/2007/12/tom-and-julia.jpg';
if(does_url_exist(fname))
img = imread(fname);
end
Note that for internet connection checking, I took the initial code from this post. Also note that if you are sure that the file exists, it is not efficient to check it again since it increases the running time.
I am trying to create a matlab script (m-file) which shall be controlled by an external VBA script.
The matlab script shall do the same operation every time (even params change, but this is not the matter in this case) for a certain number of loops.
If I see it right, I can use matlab funktions in VBA like this: http://www.mathworks.de/help/techdoc/matlab_external/f135590.html#f133975
My main problem is how to implement the matlab part of this problem...at the moment my control part looks like this:
start.m:
run = 1;
reset = 0;
while run ~= 0 % Loop until external reset of 'run' to '0'
if reset ~= 0
doReset(); % Reset the parameters for the processing
reset = 0;
disp('I did a reset');
end
disp('I am processing');
doProcess();
pause(1)
end
disp('I am done');
The reset part works very fine while changing the value by the script, but when I manually try to change the value of 'run' or 'reset' to any other value in my workspace, nothing happens...my script doen't abort, neither does the reset-if do it's work...
this seems to me that the script doesn't recognize any changes in the workspace?!
later the variables 'run' and 'reset' shall be set or unset by the VBA script.
Is there any plausible reason why I can't abort the loop by hand?
Thanks for any advice!
greets, poeschlorn
Edit:
It seems that the script loads the variables once before starting and never again during runtime...is there a possibility to have explicit access to a workspace variable?
Edit 2:
I use Matlab 2010b with no additional Toolboxes at the moment
Edit 3:
I found out, that there are several 'workspaces' or RAMs in Matlab. If my function is running, the variables are stored in 'base' (?) workspace, which is not the matlab workspace on which you can click and change every value. So I have to get access to this ominous 'base' space and change the flag 'run' to zero.
I assume your problem is simply that your loop is blocking execution of the external interface. While the loop runs you cannot access the other interfaces.
I wanted to do a similar thing -- allow control of a matlab loop by an external program (either Ruby or another matlab instance). The most flexible solution by far was using UDP. There is a great toolbox called PNET for matlab, and I assume VB must have a socket library too. I simply open a UDP port on both sides, and use simple text commands to control and give feedback.
obj.conn = pnet('udpsocket', 9999);
command = '';
while run ~= 0
nBytes = pnet(obj.conn, 'readpacket');
if nBytes > 0
command = pnet(obj.conn, 'read', nBytes, 'string');
end
switch command
case '--reset--'
doReset(); % Reset the parameters for the processing
reset = 0;
disp('I did a reset');
case '--abort--'
run = 0;
disp('Going to abort');
case '--echo--'
pnet(obj.conn, 'write', '--echo--');
pnet(obj.conn, 'writepacket', remoteAddress, remotePort);
end
doProcess();
end
This way I can build my own extensible control interface without worrying about blocking from the loop, it can work cross-platform and cross-language, can work within a machine or across the network.
UPDATE:
To talk between two UDP clients, you need to set up two complimentary UDP ports, both are clients (this example is all in matlab, pretend obj here is a structure, in my case it is a class i wrap around the pnet functionality):
obj = struct();
obj.success = 0;
obj.client1Port = 9999;
obj.client2Port = 9998;
obj.client1Address = '127.0.0.1';
obj.client2Address = '127.0.0.1';
obj.conn1 = pnet('udpsocket', obj.client1Port);
obj.conn2 = pnet('udpsocket', obj.client2Port);
pnet(obj.conn1, 'write', '--echo--')
pnet(obj.conn1, 'writepacket', obj.client2Address, obj.client2Port);
nBytes = pnet(obj.conn2, 'readpacket');
if nBytes > 0
command = pnet(obj.conn2, 'read', nBytes, 'string');
if regexpi(command,'--echo--')
obj.success = obj.success+1;
fprintf('Client 2 recieved this message: %s\n',command);
pnet(obj.conn2, 'write', '--echo--')
pnet(obj.conn2, 'writepacket', obj.client1Address, obj.client1Port);
end
end
nBytes = pnet(obj.conn1, 'readpacket');
if nBytes > 0
command = pnet(obj.conn1, 'read', nBytes, 'string');
if regexpi(command,'--echo--')
obj.success = obj.success+1;
fprintf('Client 1 got this back: %s\n',command);
end
end
if obj.success == 2
fprintf('\nWe both sent and received messages!\n');
end
Is your script a script m-file or a function?
If it's a function, you'll be losing the scope of the workspace variables which is why it's not working. I'd turn your code into a function like this:
function processRun(run,reset)
while run ~= 0 % Loop until external reset of 'run' to '0'
if reset ~= 0
doReset; % Reset the parameters for the processing
reset = 0;
disp('I did a reset');
end
disp('I am processing');
[run,reset] = doProcess;
pause(1)
end
You can then set the values of run and reset evertime you call the function from VBA.
If you have a script, try removing the run and reset lines from the top, and set their values in the workspace before you run the script. I think you're overwriting your workspace values by running the script file.
Sorry, I don't have enough rep to make a comment so I'll quote it here:
#Adam Leadbetter: Thanks, this makes sense. The only thing I habe trouble with is how to pause (after this reset and then resume) the script when it has been started by run=1 as param... – poeschlorn Feb 25 at 7:17
If you want to break out of the loop once reset has been set to one, and then wait for the loop to continue again once run = 1 that is pretty much the same as just starting over again?
function processRun()
run = 1;
while run ~= 1
run = doProcess();
end
if doProcess() returns 0 then the function processRun() will end (like the behaviour you want to have when reset), the next time processRun is called it starts over, with "reset"/default values.
Or am I missing something?