Getting the correct output units from the PLOMB (Lomb-scargle periodogram) function - matlab

I am trying to analyze timeseries of wheel turns that were sampled at 1 minute intervals for 10 days. t is a 1 x 14000 array that goes from .1666 hours to 240 hours. analysis.timeseries.(grp).(chs) is a 1 x 14000 array for each of my groups of interest and their specific channels that specifize activity at each minute sampled. I'm interested in collecting the maximum power and the frequency it occurs at. My problem is I'm not sure what units f is coming out in. I would like to have it return in cycles per hour and span to a maximum period of 30 hours. I tried to use the Galileo example in the documentation as a guide, but it didn't seem to work.
Below is my code:
groups = {'GFF' 'GMF' 'SFF' 'SMF'};
chgroups = {chnamesGF chnamesGM chnamesSF chnamesSM};
t1 = (t * 3600); %matlab treats this as seconds so convert it to an hour form
onehour = seconds(hours(1));
for i = 1:4
grp = groups{1,i};
chn = chgroups{1,i};
for channel = 1:length(chn)
chs = chn{channel,1};
[pxx,f]= plomb(analysis.timeseries.(grp).(chs),t, 30/onehour,'normalized');
analysis.pxx.(grp).(chs) = pxx;
analysis.f.(grp).(chs) = f;
analysis.lsp.power.(grp).(chs) = max(pxx);
[row,col,v] = find(analysis.pxx.(grp).(chs) == analysis.lsp.power.(grp).(chs));
analysis.lsp.tau.(grp).(chs) = analysis.f.(grp).(chs)(row);
end
end

Not really an answer but it is hard to put a image in a comment.
Judging by this (plomb manual matlab),
I think that pxx is without dimension as for f is is the frequency so 1/(dimension of t) dimension. If your t is in hours I would say h^-1.
So I'd rather say try
[pxx,f]= plomb(analysis.timeseries.(grp).(chs),t*30.0/onehour,'normalized');

Related

How to increase time by 1s and replace old DT_i with the new one

I'm trying to calculate the DT value from a model I set up on Sim4Life. Firstly, i'd like to say that I am a complete beginner and I am trying to understand how programming works in general.
Now, I have a function with some constants and two variables, the one being time Dt (starting from 1 sec to 900 secs) and the other being the initial DT_i value. I want to calculate the increase of temperature for every second and create a loop that replaces the DT_i value with the DT_1_i value and also calculates the increased temperature DT_i_1. The function looks like this: DT_1_i=DT_i+Dt.
I know it is a very simple problem but I couldn't work my way through other similar questions. Any help would be appreciated.
Temperature variation:
You need initial temperature variation , I used 0
T(i+1) stands for Next temperature variation
T(i) stands for present temperature variation
i stands for time step, dt
Read through comment in my code
Time
Use for loop to set the time for i = 1 : 900 %Temperature increase end
i =1:900 just means
first run use time = 1s,
second run time = 1+1 = 2
so on till 900
The code is as follow
% Initial Temperature variation is set to zero, unless you have some data
d = 1.3;
c = 3.7;
S_i = 3*10^3;
t_reg = 900;
%Time
t = 1:900;
% Length oftime to help me know the size of the variable needed to
% initialize
l = length(t);
% Initialize variable that used to store DT it helps speed up
% comutation
% Initial Temperature variation is set to zero, unless you have some data
DT = zeros(1, l);
for i = 1:900
% the value of i represent dt, first run i = 1, dt = 1, second run
% i = 2 and dt = 2 so on
if i == 900
%do nothing already reached the last index 900, i+1 = 901 will be
%out of range
else
DT(i+1) = DT(i) + (i./t_reg).*(d.*sqrt(c*S_i)-DT(i+1));
end
end

dsearchn() Command is slowing down my algorithm, Any better Solution? MATLAB

I am using the following code to calculate altitude.
Data = [Distance1',Gradient];
Result = Data(dsearchn(Data(:,1), Distance2), 2);
Altitude = -cumtrapz(Distance2, Result)/1000;
Distance 1 and Distance 2 has different size with same values so I am comparing them to get corresponding value of Gradient to use with Distance 2.
Just to execute these 3 lines the Matlab takes 12 to 15 seconds. Which slow down my whole algorithm.
Is there any better way I can perform above action without slowing down my algorithm?
If I understand correctly, you are looking for the first occurance of number Distance2 in the column Data(:,1). You can perform about 3 times faster using find. Try:
k = find(Data(:,1) == Distance2,1);
Result = Data(k,2);
Here is a timing test, where pow is the length of your data (10^pow for 10000 rows), and fac is the increased speed factor for using find
pow = 5;
data = round(rand(10^pow,1)*10);
funcFind = #() find(data == 5,1);
timeFind = timeit(funcFind);
funcD = #() dsearchn(data,5);
timeD = timeit(funcD);
fac = timeD/timeFind
I manage to find alternative method by using interp1 function.
Here is an Example Code.
Distance2= [1:10:1000]';
Distance1= [1:1:1000]';
Gradient= rand(1000,1);
Data= [Distance1,Gradient];
interp1(Distance1,Data(:,2),Distance2,'nearest');
This function add just 1 second to my original simulation time which is way better then previous 12 to 15 seconds.

There is a bug in my code and I don't know where!!! [MATLAB]

I am trying to reproduce the results from an article. But so far I am not being successful. Here is the code I wrote
EDIT: Based on the initial comments of Zizy Archer, the code has been revised.
clear;
Nmax = 30; % number of rounds
M = 10000; % number of simulations
beta0 = 5*10^-6; % relative clock offset in micro seconds
alpha0 = 1.01; % relative clock skew
for simN = 1:M
for N = 1:Nmax
mean_dly = randi([20 50],N,1).*10^-6; % micro seconds
stdd_dly = randi([1 5],N,1).*10^-6; % micro seconds
XpropDly = normrnd(mean_dly,stdd_dly,N,1); % micro seconds
YpropDly = normrnd(mean_dly,stdd_dly,N,1); % micro seconds
prcssTme = randi([100 500],N,1).*10^-6; % micro seconds
T_1 = (1:N)'*10^-3; % milli seconds
T_2 = T_1 + XpropDly; % milli seconds
T_3 = T_2 + prcssTme; % milli seconds
T_4 = T_3 + YpropDly; % milli seconds
% actual time
T_2act = (T_1 + XpropDly).*alpha0 + beta0;
T_3act = (T_4 - YpropDly).*alpha0 + beta0;
% equation 13
A = sum(T_2act(1:N) + T_3act(1:N));
B = sum(T_1(1:N) + T_4(1:N));
C = sum((T_2act(1:N) + T_3act(1:N)).^2);
D = sum((T_2act(1:N) + T_3act(1:N)).*(T_1(1:N) + T_4(1:N)));
% equation 16
alpha0est(simN,N) = (A.^2-C.*Nmax)./(A.*B-D.*Nmax);
beta0est(simN,N) = (B.*C-A.*D)./(2.*(A.*B-D.*Nmax));
end
timestamps = [T_1 T_2 T_3 T_4];
clear T_*;
end
% equation 29 and 30
MSE_alpha = sum((alpha0est - alpha0).^2)/M;
MSE_beta = sum((beta0est - beta0).^2)/M;
figure %2(a)
semilogy(1:Nmax,MSE_beta.*10^12)
xlabel('N');ylabel('MSE of the estimated offset \beta_{0}')
figure %2(b)
semilogy(1:Nmax,MSE_alpha)
xlabel('N');ylabel('MSE of the estimated skew \alpha_{0}')
But this is what I get:
EDIT2: Snippets were removed.
Can anyone tell me what is wrong with my code?
Thanking you all in advance.
Next time at least try some rudimentary debugging yourself to figure out what could be wrong.
To debug, perhaps print out some variables or plot stuff. Put some conditionals to check if the values are somewhat expected or make no sense. It isn't that hard if you know something is wrong in such a small piece of code (however, if there was no paper you were trying to hit, this bug might have been lurking for a while).
Well, to the step-by-step solution in this case:
What you immediately notice is that if you plot alpha0est or beta0est, your estimate for alpha is systematically too high, at 1.015 instead of 1.01 for the single round case, similar for beta.
Now, what could it be? It obviously isn't noise in signal processing or delays, this one is shown as all this hairy stuff around the mean, you can set all delays to 0 to verify this. So, it has to be something else.
Looking further, you can notice that this systematic error is decreasing when you increase number of rounds performed, and is gone for full 30 rounds.
So, it has to be something with the number of rounds you are doing. Now try setting N = 10 instead of 30, whoa now 10 round case is fine. And there you have your bug. Equation 13 from the paper - there you have N elements summed. Equation 16 similarly multiplies with N. This N obviously has to be the same number. But as it turns out, in your code it isn't. Equation 13 in your code sums ROUNDS cases. Could be 1, could be 30. Equation 16 multiplies with N (=30, always).
All this could be easily avoided if you used saner variable names (all-caps, really?). If you used N for number of rounds performed, and maxN as the limit how many rounds you can try doing at maximum, you would easily get it right.

average wind direction using histc matlab

Hello this question might be easy but i am struggling to get average wind directions for 1 year. I need hourly averages to compare with concentration measurements. My wind measurements are every minute in degree. So my idea was to use the histc function in matlab to get the most common winddirection within the hour. this works for 1 h but how do i create a loop which gives me hourly values for a year.
here is the code
wdd=winddirections in degree(vectorsize e.g for a year 525600)
binranges = [0:10:360];
[bincounts,ind] = histc(wdd(1:60),binranges);
[num idx] = max(bincounts(:));
wd_out=binranges(idx);
kind regards matthias
How about this one -
binranges = [0:10:360]
[bincounts,ind] = histc(reshape(wdd,60,[]),binranges)
[nums idxs] = max(bincounts)
wd_out=binranges(idxs)
What I would do is:
wdd_phour=reshape(wdd,60,525600/60); % get a matrix of size 60(min) X hours per year
mean_phour=mean(wdd_phour,1); % compute the average of each 60 mins for every our in a year

clock Time on x-axis in matlab

I need some help related to plots in MATLAB.
I want to plot my data with respect to clock time on x-axis. I have an occupancy information data for every 15 minutes interval. I want to plot it against time. How can i do it? The problem is with the x-axis, how can i handle time and uniform intervals e.g data is of the form
data=[1 0 0 0 0 1 1 1 1 0 0 0 .............]
value of time is from 9 AM to 9 PM and the interval is 15 minutes
How can i set the intervals on the x-axis?
Thank you
The following code solves the problem. you enter Integer values for starting hour and minute, the ending time and the time steps between the measurements. Further enter/change the steps_x value. This shows how many time values are skipped on the x-axis. 7=skip6 values. Below the for-loop is my y-data. I just used random-function.
The resulting x-axis is a cell-array. This could be a problem for some applications. Further I used some 'unneccessary' variables. These i used for verifing my code. I didn't change it, because i thought that it would be easier to understand that way.
The biggest problem of my so
clc; clear all; close all;
%%//Variable declaration
start_hour = 9; %in hours
start_min = 5; %//in minutes
steps_min = 10; %//in minutes
end_hour = 21.0; %//in hours
end_min= 0; %//in minutes
steps_x = 7; %//how many times are displayed on the axis, doesn't change data
%%// code for computing internal values, steps and transforming to am/pm
%//changes the entries above to hour display(9.75=9h45min)
start_time= (start_hour+start_min/60);
%//changes the entries above to hour display(9.75=9h45min)
end_time=(end_hour+end_min/60);
%//changes steps to hour
steps_hour= steps_min/60;
%//array of hours
mytest_timeline = start_time:steps_hour:end_time;
%//array of minutes(copied and modified from #natan)
mytest_minutes = mod((0:steps_min:(steps_min*(length(mytest_timeline)-1)))+start_min,60);
%//cell array for am/pm display
mytest_timeline_ampm = num2cell(mytest_timeline);
%//if hour is smaller 12 write am otherwise pm
for k=1:length(mytest_timeline);
if mytest_timeline(k) < 12
mytest_ampm = {'am'};
%//converting the down rounded hour to str
helper_hour=num2str(mod(floor(mytest_timeline(k)),12));
%//converting the minute to str and giving it 2 digits eg. 05 for 5min
helper_minute = num2str(mytest_minutes(k),'%02d');
%//joining strings
mytest_timeline_ampm(k)= strcat(helper_hour,{'.'}, helper_minute, mytest_ampm);
%//same as for am just for pm
else
mytest_ampm = {'pm'};
helper_hour=num2str(mod(floor(mytest_timeline(k)),12));
helper_minute = num2str(mytest_minutes(k),'%02d');
mytest_timeline_ampm(k)= strcat(helper_hour,{'.'}, helper_minute, mytest_ampm);
end
end
%%// generated y data so that i could test the code
mytest_y = rand(size(mytest_timeline));
%%// changing display
%//x-coordinates(for displaying x,y)
mytest_x= 1:length(mytest_timeline);
%//x-axis label
mytest_x_axis = 1:steps_x:length(mytest_timeline);
%//plots the data mytest_y in uniform distances (mytest_x)
plot(mytest_x, mytest_y, 'b')
%//changes the x-label accordingly to mytest_x_axis to the am/pm timeline
set(gca, 'XTick',mytest_x_axis, 'XTickLabel',mytest_timeline_ampm(mytest_x_axis))