Matlab GUI windowButtonMotionFcn Slow When No Action Taken - matlab

I have a MATLAB (r2016a) GUI with a windowButtonMotionFcn callback. Inside the callback is an if-elseif-else block that changes the cursor depending on which axes in the GUI the mouse is over. It runs very quickly when it encounters the cases when it needs to change something, but according to profiler, takes a significant amount of time on the "return" command.
Can anyone offer insight into a way to correct this? It seems to me if it's not executing any more code, it should be running more quickly when it is exiting the function (i.e. not getting hung up on a "return") than when it has more code to execute.
A basic outline of the code is as follows:
function mouseMove(handles)
xy = %Get cursor position
if %xy over axes1
set(gcf,'Pointer','crosshair')
elseif %xy over axes2
set(gcf,'Pointer','arrow')
else
return %Here is where MATLAB is spending a lot of time
end
%A lot of additional code for when the cursor is over axes1 or axes2.
end

This may be related to the fact that the end of a function often appears in the profiler as taking a lot of time. In general, the profiler is good for identifying inefficiencies in your code (functions that are called too many times, etc.) but really isn't well-suited to actually benchmarking code since JIT acceleration isn't enabled. For benchmarking, it's best to use timeit or some other function.
That being said, when I implement your same callback, I don't see any performance hit for the return statement
As #Ander pointed out, you should pay attention to the Calls column as it's possible that the number of times that return is called is simply more than the rest of the callback. The default coloration of a given line is based on the total time and not the time per call.

Related

Ending fminsearch on a whim

Id like to be able to cancel fminsearch (eg using ctrl+c) and retaining the best solution so far. Is there a way to do this? I dont know exactly what sort of tolerance I want to set, I'd much rather "play by ear" and ctrl+c when I'm satisfied with the solution. Matlab keeps going onnn and on and on for what seems to be no gain.
fminsearch can be terminated early by both output functions and plot functions. To get an interactive demand from the user, use of graphical interfaces that don't wait until code is finished executing to update is basically essential, so using a plot function would be the most straightforward way of achieving this. The default plot function figure has "Stop" and "Pause" buttons built in, as seen in the documentation's example for calling:
fminsearch(funfcn,x,optimset('PlotFcns',#optimplotfval))
If the Stop button is clicked, fminsearch returns the result of its latest iteration and by default displays the information:
Optimization terminated prematurely by user.

Creating delay with a while loop in Matlab

As a student I am currently working on a Matlab Simulink project. I am quite new to using Matlab/Simulink (few weeks).
I want to implement and run a Matlab “.m” file with which I can open Simulink and start the simulation. The aim is to do a 24h Test with a load cell cut into 1h “pieces” and to save the data to different sheets of an excel file each hour. So my simulation runs for 1h, stops and starts again, and so on. Through Matlab and a “for” loop I do the measures 24 times.
Between measuring steps I have to wait for simulink to finish its measures and saving the file in order for the Simulink window to be able to get closed by close_system('Thesis_SerDatTransm_Simulink').
So I tried to implement the delay with a while loop and by checking if the measures I get fit into an array of the size bigger than 449 (I measure 449 values):
for k=0:1:24
% Load Simulink
load_system('Thesis_SerDatTransm_Simulink.slx')
% Open Simulink
open_system('Thesis_SerDatTransm_Simulink.slx')
% Start Simulation
set_param('Thesis_SerDatTransm_Simulink', 'SimulationCommand', 'Start');
% Save Data
my_cell = sprintf('A%d',k);
xlswrite('file.xlsx',y,my_cell)
% Wait for Simulation
while 1
test=size(y)>=449;
if (test)
close_system('Thesis_SerDatTransm_Simulink')
break
end
end
end
The Problem now is, that program gets stuck at the while loop. Simulink is started, but no simulation or data gathering is done.
So I wondered if anyone could check if something is wrong with my While loop, since the rest of the programm works all fine without the loop (but receiving an error message, that during the simulation, Simulink window can't be closed).
I know there is a way to create a delay with waitforin matlab and create another function which I could call, but I couldn't figure out how to do this yet.
thanks
Regards
hohmchri
The right way to do this is to use the sim function to run your model (not the sequence of load_system, open_system and set_param that you have).
sim will block the execution of m-code until the model completes executing. Data can either be returned into the workspace (when used with no output arguments) or returned as an output from the call to sim. (And then you can write it to Excel as you've done.)
The only reason not to use sim, and perhaps use the commands you have, is if the model takes a long time to initialize, and you don't want to to open and close it every time through the loop. However, even in this case your code isn't correct. The load_system would be outside the loop; the open_system is not required; in your while loop you would poll the model's SimulationStatus property to see if it is still running (not the size of the y variable); and the close_system would be after the loop (as indicated by #m_power in one of the comments).
As written you should use the matlab pause command. This stops your execution for X seconds.
You should also look to optimize your code as m_power states

MATLAB command line output not following

There is something very simple that can be very upsetting occasionally.
I sometimes want to keep track of the outputs of an algorithm at each iteration, so within a for loop, I use disp command of MATLAB to output some information. However, although there is quite a bit of time between the calling of dispcommands, the MATLAB command window falls behind and I need to use the mouse to keep up with it manually. Do you know if there is any way to have it not fall behind?
Thanks,
It really shouldn't fall behind, but I could see this happening if the computations are intensive and the MATLAB JVM, which drives the GUI, does get the resources to update the command window.
The following command may be of help:
drawnow update % or just drawnow
According to the documenatation page, this "causes only user-interface objects to refresh, if needed". If that fails, try just drawnow with no arguments to see if it helps to flush the entire system event queue, including graphics updates.
If that doesn't work you could insert a pause(0.01) or something similar as a last resort.
It shouldn't fall behind if you don't use the mouse at all. However, I often use the waitbar for this purpose.
FEX also has several text & GUI progress bars.

figures pop up during code is running in matlab

I'm running a large code so I would like to ensure everything is correct when it starts to run. One thing I do is to plot some data to see if they make sense. I had several such plots (figure (1), figure (2) ...) and all of them are buried in different 'if' sentences. But I found only some of them pop up during the code is running, the others just don't show up until the code finished running. I have checked all the if statements are true.
Since my code is a little large I can't put it here. Can someone tell me the possible reasons that affect when figures pop up (during the code is running or after it's finished)? Thanks a lot!
You can use the drawnow function to update your figures while code is still running. If you want your figure window to "pop up" at any given time, you may also need to explicitly call figure(figNum).
Note that while it can be fun to watch your figures update in real time, you may incur a severe performance penalty by doing so. If you have long-running loops, you might consider only showing every N-th update, where N is 10, 100, 1000, or some other appropriate value:
for iter = 1:1e6
plot(x,y);
if ~mod(f0,1000); drawnow; end
end
If you are just interested in plotting right at the beginning as a sanity check, you might run the first iteration of your code outside of a for loop, and run drawnow to make sure it plots. Then enter into the for loop starting at the second iteration. The advantage over testing iter==1 is that you don't have to waste cycles on a conditional at every iteration.

How can I parallelize input and display in MATLAB?

I'm using Psychtoolbox in MATLAB to run a behavioral psychology paradigm. As part of the paradigm, users have to view a visual stimulus and respond to it using some input mechanism. For a keyboard, this works as follows:
show stimulus
poll keyboard for response
if no response detected, loop back to 1
if response detected, break and move on with script
This works fine for a keyboard, as step 2 takes between 1-2 ms. The problem comes when I use an alternate input mechanism; in that case, step 2 takes ~20 ms. (I need this alternate input to run the study, and that should be considered immutable fact.) As the stimulus changes with a very short timespan, this added delay breaks the task.
My current thought is to try to use the parallel processing, such that one thread shows the stimulus, and another thread polls the keyboard. I'm currently using the Parallel Computing Toolbox to do this. The problem I'm having is that I don't know how to direct keyboard input to a "parallelized" thread. Does anyone know (1) whether it's possible to direct keyboard input to a thread / have a thread send a visual signal to a monitor, and if yes, (2) how to do it?
Also, if anyone has any better ideas as to how to approach this problem, I'm all ears.
According to this MATLAB newsgroup thread, it appears that threads can't modify graphics objects. Only the desktop MATLAB client can do that. This means that you can't handle updating of graphics from a thread, and I can confirm this as I tried it and wasn't able to modify figures or even the root object from a thread.
However, I think you may be able to do the main graphics updating in MATLAB while a thread handles polling for your input. Here's a sample function for continuously updating a display until a thread waiting for input from KbCheck is finished running:
function varargout = plot_until_input
obj = createJob(); %# Create a job
task = createTask(obj,#get_input,4,{deviceNumber}); %# Create a task
submit(obj); %# Submit the job
waitForState(task,'running'); %# Wait for the task to start running
%# Initialize your stimulus display here
while ~strcmp(get(task,'State'),'finished') %# Loop while the task is running
%# Update your stimulus display here
end
varargout = get(task,'OutputArguments'); %# Get the outputs from the task
destroy(obj); %# Remove the job from memory
%#---Nested functions below---
function [keyIsDown,secs,keyCode,deltaSecs] = get_input(deviceNumber)
keyIsDown = false;
while ~keyIsDown %# Keep looping until a key is pressed
[keyIsDown,secs,keyCode,deltaSecs] = KbCheck(deviceNumber);
end
end
end
I was able to successfully run the above function with some simple plotting routines and replacing the code in get_input with a simple pause statement and a return value. I'm unsure whether KbCheck will work in a thread, but hopefully you will be able to adapt this for your needs.
Here's the documentation for the Parallel Computing Toolbox functions used in the above code: createJob, createTask, submit, waitForState, destroy.
I don't know of a way how you could do this with parallel processing.
However, a feature you might be able to use is the timer object. You would set up the timer object to poll the input mechanism, and, if anything is detected, change the value of a global variable. Then, you start your stimulus routine. In the while-loop in which you're updating the display, you keep checking the global variable for a change from the timer object.
You have to tackle the 20ms latency in your input device. If it's too slow then get another input device. You can get good sub-millisecond timing with proper response boxes.
All this talk about threading is misguided and not applicable to the PTB framework.