MATLAB tic-toc results in Minutes format - matlab

I am using tic-toc function in my Matlab project as many places. The output time can be 331.5264 or 1234.754 seconds, etc. Can I output this is minutes format? For eg. 5 minutes and 30.6 seconds? Thanks!

All you have to do is capture the output from toc (instead of letting it display its default output), then create an output yourself using the functions fprintf, floor, and rem:
tStart = tic;
% Do some things...
tEnd = toc(tStart);
fprintf('%d minutes and %f seconds\n', floor(tEnd/60), rem(tEnd,60));

While tic and toc do not have any way to display values in minutes, you can process the data slightly before displaying it. Check out the following link to a seconds to hour/minute converter.
Usage would be as follows:
tic
% Do something
time_str = SECS2HMS(toc)
disp(time_str)
I will try this out when I get back on my Windows VM. Hope this helps.
EDIT
You could use the datestr and datenum function built into Matlab as well in the following way. Note that I have not tried this code either, but the link reminded me of the syntax on how to do it (without bringing up Matlab)
tic
%Do something
t=toc;
disp(datestr(datenum(0,0,0,0,0,t),'HH:MM:SS'))

The easiest way I've found is to use:
TIME = tic;
% do calculations which take TIME to complete
fprintf('This took %s', duration([0, 0, toc(TIME)]));
(toc() returns the time from the stopwatch in seconds, and duration() expects a three-column matrix expressing a time duration in [hours, minutes, seconds] format).
This has the nice property of keeping most of the timing calculations out of sight.
Hope this helps.

This one suited me:
disp(['Elapsed time is ' num2str(round(toc/60,1)) ' minutes.'])

Related

find positive calendarDurations in matlab

AIM:
I need to synchronize the animation of two plots in Matlab.
PROBLEM:
The data of the two plots has been acquired with a variable sample rate.
SOLUTION:
I converted the time-stamps of the two datasets in duration objects (relative to the beginning of the streaming).
Now I want to plot the two datasets in a for loop.
For each loop, I want to show the datasets samples whose durations are within the elapsed time.
QUESTION:
How do I determine if the duration of a specific sample already happened or not?
CODE EXAMPLE:
here I simulate and sort 10 random durations (d1), and 1 random elapsed time (et). I want to find which durations are past the elapsed time.
`
% simulate elapsed time
et = calendarDuration(round(rand(1,6)*10));
% simulate data for plot 1
data_for_plot1 = rand(10,1);
% simulate durations for the samples in plot1
d1 = calendarDuration(sortrows(round(rand(10,6)*10)));
% find index of durations which are before the elapsed time
is_past = (d1-et)>0;
% plot the data
plot(data_for_plot1(is_past))
`
ERROR MESSAGE
is_past = (d1-et)>0;
Undefined operator '>' for input arguments of type 'calendarDuration'.
ALTERNATIVE SOLUTIONS:
It's my first time with duration and date objects, and I am hating every bit of it. If you have alternative solutions I would love to hear them.
Mind that the timestamps of data1 come as strings ('yyyy-MM-dd HH:mm:ss.SSS') and the timestamps of data2 come as double (eg: 42.525, 42 s and 525 ms).
Thank you for your help
You can use split function for this purpose.
Use is_past = split((d1-et),'time')> 0; instead of is_past = (d1-et)>0;

Selecting certain time range in Matlab

I have a project to do and im facing some problems. Please help me. Im not so good at matlab yet.
Basically, I have a set of movement data (data.mat) which were recorded for 3 days non stop. And I need to:
1. select only certain certain moments (time range) of this whole set of data
2. divide these moments into small 2.56 seconds parts
3. make FFT of each small parts , to see the movement in frequency domain, and select only 5-25 Hz
4. find a few biggest frequency peaks
I wrote a code for making FFT and peaks for whole my data "Data.mat" and it is working.
This is my code:
load('Data.mat');
P=data1(,2); %
Fs=100
Ts=1/Fs
L=length(P)
t = (0:L-1)*Ts;
nfft = 256
figure(1) % raw signal plotting
plot(t,P);
y = fft(P,nfft)/L; % FFT
ymag = abs(y(1:length(y)/2+1));
ft = Fs/2*linspace(0,1,nfft/2+1);
figure(2) % FFT plotting
plot(ft,2*abs(y(1:nfft/2+1)))
indx=ft>= 5 & ft<= 25; % only 5-25Hz
ftsub=ft(indx);
ymagsub=ymag(indx);
% highest peaks
[pks,locs] = findpeaks(ymagsub,'MinPeakHeight',0.02)
plot(ftsub,ymagsub,ftsub(locs),pks,'rv','MarkerFaceColor','r')
Now Im trying to select only certain moments of the data but I have problems with it.
E.g. lets say, I want select only time range: 13-03-2013 9:20:00-9:45:00 AM
I have tried:
t_start =datenum('13-03-2013 9:20:00 AM', 'dd-mm-yyyy HH:MM:SS AM');
t_end = datenum('13-03-2013 9:45:00 AM', 'dd-mm-yyyy HH:MM:SS AM');
rows=find(P>= t_start & P<= t_end);
but I get answer:
rows=
Empty matrix: 0-by-1
Whats wrong? If this code is wrong, how to select certain time range then?
And how to select into 2.56 seconds ?
Please help me, Ive been trying to find the solution since weeks, im really depressed now.
For this line to work properly:
rows=find(P>= t_start & P<= t_end); P must be a series of times in MATLAB datenum format.
I'm guessing P is your actual data - so it doesn't work because find simply compares the numeric values in P against the numeric date values - your "P" values aren't date-tagged in MATLAB. The important things to remember is that the output of datenum is simply a number, so MATLAB will allow you to compare it against other numbers even if the result doesn't make real-world sense.
Your options are:
If your data contains a timestamp, load that, check that it is in the correct format (convert back with datestr for a sanity check). This may be the first column of your data. Perform the find on the time values and then use that to plot/extract the appropriate parts of P.
Construct a time vector - using what you know about the time of the first data point + the sampling rate, and do the same. Similar to your t but in datenums. This will also work if your data acquisition means you only have the times in time-since-start-of-file plus a start time.
Then it's just something like:
r=find(t>= t_start & t<= t_end);
plot(t(r),P(r);

Milliseconds timer matlab

I am an amateur Matlab User who is attempting to write a code to run a specific function call every 10ms for a time span of 1 second. I am having trouble trying to get something to run for the exact amount of time; I have tried to use Tic and Toc but that's in seconds (I need millisecond precision). Here is some very basic code I have been playing with to try and get readings using a function called getvelocity. Any help would be appreciated, thanks!
function [ velocity ] = Vel()
i=1;
timerID=tic;
while (toc(timerID) <=2);
[v(i)]=vpx_GetTotalVelocity;
disp (v(i));
i=i+1;
end
velocity=mean(v);
end
The code above runs for two seconds; however, I want to run in ms precision.
Assuming the function you have is fast enough (not a trivial assumption) you can achieve it like so:
tic
for t = 0.01:0.01:1 %If you want the first function call to start right away you can change this to 0:0.01:0.99
while toc < t
end
t %Put your function call here.
end
Note that 0.01 sec is 10 ms

Will there be difference in performance between anonymous functions and normal functions?

Will there be difference in performance between anonymous functionS and normal functions? For example, any change in overhead of function calling?
Thanks and regards!
Unfortunately, I could not find anything specific on the subject. However, anonymous functions should have additional overhead in comparison to normal functions.
You can try it out for yourself. First create the file nonanon.m
function x=nonanon(y)
x=y^2;
end
Then create a cell file with:
%% non anon
tic
for i=1:1000000
z=nonanon(i);
end
toc
%% anon
f=#(x) x^2;
tic
for i=1:1000000
z=f(i);
end
toc
enjoy, the output:
Elapsed time is 0.513759 seconds.
Elapsed time is 14.434895 seconds.
Which concludes that anonymous functions are slower.
I repeated user677656's little test code, but a small variant using y=x*x instead of squaring (in both the nonanon and the anon case):
Elapsed time is 0.517514 seconds.
Elapsed time is 0.223450 seconds.
If I instead use the y=x^2 variant, I get similar results as user677656:
Elapsed time is 0.402366 seconds.
Elapsed time is 7.440174 seconds.
This is with Matlab 2012b. I have no idea why on earth these give different results.
I also tested y=sin(x) which gives similar results as the x*x case, and y=sqrt(x), which resulted in a slight (2.8 vs 3.9 seconds) advantage for the nonanon case.

Timing program execution in MATLAB; weird results

I have a program which I copied from a textbook, and which times the difference in program execution runtime when calculating the same thing with uninitialized, initialized array and vectors.
However, although the program runs somewhat as expected, if running several times every once in a while it will give out a crazy result. See below for program and an example of crazy result.
clear all; clc;
% Purpose:
% This program calculates the time required to calculate the squares of
% all integers from 1 to 10000 in three different ways:
% 1. using a for loop with an uninitialized output array
% 2. Using a for loop with a pre-allocated output array
% 3. Using vectors
% PERFORM CALCULATION WITH AN UNINITIALIZED ARRAY
% (done only once because it is so slow)
maxcount = 1;
tic;
for jj = 1:maxcount
clear square
for ii = 1:10000
square(ii) = ii^2;
end
end
average1 = (toc)/maxcount;
% PERFORM CALCULATION WITH A PRE-ALLOCATED ARRAY
% (averaged over 10 loops)
maxcount = 10;
tic;
for jj = 1:maxcount
clear square
square = zeros(1,10000);
for ii = 1:10000
square(ii) = ii^2;
end
end
average2 = (toc)/maxcount;
% PERFORM CALCULATION WITH VECTORS
% (averaged over 100 executions)
maxcount = 100;
tic;
for jj = 1:maxcount
clear square
ii = 1:10000;
square = ii.^2;
end
average3 = (toc)/maxcount;
% Display results
fprintf('Loop / uninitialized array = %8.6f\n', average1)
fprintf('Loop / initialized array = %8.6f\n', average2)
fprintf('Vectorized = %8.6f\n', average3)
Result - normal:
Loop / uninitialized array = 0.195286
Loop / initialized array = 0.000339
Vectorized = 0.000079
Result - crazy:
Loop / uninitialized array = 0.203350
Loop / initialized array = 973258065.680879
Vectorized = 0.000102
Why is this happening ?
(sometimes the crazy number is on vectorized, sometimes on loop initialized)
Where did MATLAB "find" that number?
That is indeed crazy. Don't know what could cause it, and was unable to reproduce on my own Matlab R2010a copy over several runs, invoked by name or via F5.
Here's an idea for debugging it.
When using tic/toc inside a script or function, use the "tstart = tic" form that captures the output. This makes it safe to use nested tic/toc calls (e.g. inside called functions), and lets you hold on to multiple start and elapsed times and examine them programmatically.
t0 = tic;
% ... do some work ...
te = toc(t0); % "te" for "time elapsed"
You can use different "t0_label" suffixes for each of the tic and toc returns, or store them in a vector, so you preserve them until the end of your script.
t0_uninit = tic;
% ... do the uninitialized-array test ...
te_uninit = toc(t0_uninit);
t0_prealloc = tic;
% ... test the preallocated array ...
te_prealloc = toc(t0_prealloc);
Have the script break in to the debugger when it finds one of the large values.
if any([te_uninit te_prealloc te_vector] > 5)
keyboard
end
Then you can examine the workspace and the return values from tic, which might provide some clues.
EDIT: You could also try testing tic() on its own to see if there's something odd with your system clock, or whatever tic/toc is calling. tic()'s return value looks like a native timestamp of some sort. Try calling it many times in a row and comparing the subsequent values. If it ever goes backwards, that would be surprising.
function test_tic
t0 = tic;
for i = 1:1000000
t1 = tic;
if t1 <= t0
fprintf('tic went backwards: %s to %s\n', num2str(t0), num2str(t1));
end
t0 = t1;
end
On Matlab R2010b (prerelease), which has int64 math, you can reproduce a similar ridiculous toc result by jiggering the reference tic value to be "in the future". Looks like an int rollover effect, as suggested by gary comtois.
>> t0 = tic; toc(t0+999999)
Elapsed time is 6148914691.236258 seconds.
This suggests that if there were some jitter in the timer that toc were using, you might get rollover if it occurs while you're timing very short operations. (I assume toc() internally does something like tic() to get a value to compare the input to.) Increasing the number of iterations could make the effect go away because a small amount of clock jitter would be less significant as part of longer tic/toc periods. Would also explain why you don't see this in your non-preallocated test, which takes longer.
UPDATE: I was able to reproduce this behavior. I was working on some unrelated code and found that on one particular desktop with a CPU model we haven't used before, a Core 2 Q8400 2.66GHz quad core, tic was giving inaccurate results. Looks like a system-dependent bug in tic/toc.
On this particular machine, tic/toc will regularly report bizarrely high values like yours.
>> for i = 1:50000; t0 = tic; te = toc(t0); if te > 1; fprintf('elapsed: %.9f\n', te); end; end
elapsed: 6934787980.471930500
elapsed: 6934787980.471931500
elapsed: 6934787980.471899000
>> for i = 1:50000; t0 = tic; te = toc(t0); if te > 1; fprintf('elapsed: %.9f\n', te); end; end
>> for i = 1:50000; t0 = tic; te = toc(t0); if te > 1; fprintf('elapsed: %.9f\n', te); end; end
elapsed: 6934787980.471928600
elapsed: 6934787980.471913300
>>
It goes past that. On this machine, tic/toc will regularly under-report elapsed time for operations, especially for low CPU usage tasks.
>> t0 = tic; c0 = clock; pause(4); toc(t0); fprintf('Wall time is %.6f seconds.\n', etime(clock, c0));
Elapsed time is 0.183467 seconds.
Wall time is 4.000000 seconds.
So it looks like this is a bug in tic/toc that is related to particular CPU models (or something else specific to the system configuration). I've reported the bug to MathWorks.
This means that tic/toc is probably giving you inaccurate results even when it doesn't produce those insanely large numbers. As a workaround, on this machine, use etime() instead, and time only longer chunks of work to compensate for etime's lower resolution. You could wrap it in your own tick/tock functions that use the for i=1:50000 test to detect when tic is broken on the current machine, use tic/toc normally, and have them warn and fall back to using etime() on broken-tic systems.
UPDATE 2012-03-28: I've seen this in the wild for a while now, and it's highly likely due to an interaction with the CPU's high resolution performance timer and speed scaling, and (on Windows) QueryPerformanceCounter, as described here: http://support.microsoft.com/kb/895980/. It is not a bug in tic/toc, the issue is in the OS features that tic/toc is calling. Setting a boot parameter can work around it.
Here's my theory about what might be happening, based on these two pieces of data I found:
There is a function maxNumCompThreads which controls the maximum number of computational threads used by MATLAB to perform tasks. Quoting the documentation:
By default, MATLAB makes use of the
multithreading capabilities of the
computer on which it is running.
Which leads me to think that perhaps multiple copies of your script are running at the same time.
This newsgroup thread discusses a bug in an older version of MATLAB (R14) "in the way that MATLAB accelerates M-code with global structure variables", which it appears the TIC/TOC functions may use. The solution there was to disable the accelerator using the undocumented FEATURE function:
feature accel off
Putting these two things together, I'm wondering if the multiple versions of your script that are running in the workspace may be simultaneously resetting global variables used by the TIC/TOC functions and screwing one another up. Maybe this isn't a problem when converting your script to a function as Amro did since this would separate the workspaces that the two programs are running in (i.e. they wouldn't both be running in the main workspace).
This could also explain the exceedingly large numbers you get. As gary and Andrew have pointed out, these numbers appear to be due to an integer roll-over effect (i.e. an integer overflow) whereby the starting time (from TIC) is larger than the ending time (from TOC). This would result in a huge number that is still positive because TIC/TOC are internally using unsigned 64-bit integers as time measures. Consider the following possible scenario with two scripts running at the same time on different threads:
The first thread calls TIC, initializing a global variable to a starting time measure (i.e. the current time).
The first thread then calls TOC, and the immediate action the TOC function is likely to make is to get the current time measure.
The second thread calls TIC, resetting the global starting time measure to the current time, which is later than the time just measured by the TOC function for the first thread.
The TOC function for the first thread accesses the global starting time measure to get the difference between it and the measure it previously took. This difference would result in a negative number, except that the time measures are unsigned integers. This results in integer overflow, giving a huge positive number for the time difference.
So, how might you avoid this problem? Changing your scripts to functions like Amro did is probably the best choice, as that seems to circumvent the problem and keeps the workspace from becoming cluttered. An alternative work-around you could try is to set the maximum number of computational threads to one:
maxNumCompThreads(1);
This should keep multiple copies of your script from running at the same time in the main workspace.
There are at least two possible error sources. Can you try to differentiate between 'tic/toc' and 'fprintf' by just looking at the computed values without formatting them.
I don't understand the braces around 'toc' but they shouldn't do any harm.
Here is a hypothesis which is testable. Matlab's tic()/toc() have to be using some high-resolution timer. On Windows, because their return value looks like clock cycles, I think they're using the Win32 QueryPerformanceCounter() call, or maybe something else hitting the CPU's RDTSC time stamp counter. These apparently have glitches on some multiprocessor systems, mentioned in the linked articles. Perhaps your machine is one of those, getting different results if the Matlab process is moved from core to core by the process scheduler.
http://msdn.microsoft.com/en-us/library/ms644904(VS.85).aspx
http://www.virtualdub.org/blog/pivot/entry.php?id=106
This would be hardware and system configuration dependent, which would explain why other posters haven't been able to reproduce it.
Try using Windows Task Manager to set the affinity on your Matlab.exe process to a single CPU. (On the Processes tab, right-click MATLAB.exe, "Set affinity...", un-check all but CPU 0.) If the crazy timing goes away while affinity is set, looks like you found the cause.
Regardless, the workaround looks like to just increase maxcount so you're timing longer pieces of work, and the noise you're apparently getting in tic()/toc() is small compared to the measured value. (You don't want to have to muck around with CPU affinity; Matlab is supposed to be easy to run.) If there's a problem in there that's causing int overflow, the other small positive numbers are a bit suspect too. Besides, hi-res timing in a high level language like Matlab is a bit problematic. Timing workloads down to a couple hundred microseconds subjects them to noise from other transient conditions in your machine's state.