Efficient and quick way to summation of large data points

3 ビュー (過去 30 日間)
Pradeep Chandran
Pradeep Chandran 2023 年 8 月 6 日
移動済み: Dyuman Joshi 2023 年 9 月 8 日
I have a large data points of about 1e7 (voltage with respect to time) of which I need to measure allan deviation. I averaged out and skipped the datapoints 2e5. I used about 90 discrete values of averaging time (tau) using the log space. The code is given below. Yet it take 14 minutes to run the program. Is there anything that I could do to reduce the running time?
Kindly suggest any improvement in the program. Thanks in advance.
% Data Pre-processing (DC Zero level in window of 33 data points)
% Data Pre-processing (Skip data points - first data point in each window of 33)
V = floor(length(voltage)/33);
c = zeros(1, V);
t = zeros(1, V);
d = zeros(1, V);
l=1;
for i=1:33:33*V
k=0;
for j=1:1+32
k=k+voltage(j);
end
k=k/33;
for j=i:i+32
c(j)=voltage(j)-k;
end
t(l)=time(i);
d(l)=c(i);
l=l+1;
end
t = transpose(t);
d = transpose(d);
% Voltage (V) to Omega (deg/hr)
% Omega = Voltage / Sensitivity, where Sensitivity is 9.27 mV/deg/s
omega = (d/9.27e-3)*3600;
N = length(omega);
% Setting Averaging time
t0 = t(2)-t(1);
n = unique(ceil(logspace(log10(1), log10((N-1)/2), 100).')); % n is the selected discrete values of cluster size
tau = n*t0;
% Computing Allan Deviation
% Allan Deviation Equation DOI 10.1109/TIM.2007.908635
adev = 0;
Y = [];
for i=1:numel(n)
a = 0;
ni = n(i);
for k=1:(N-(2*n(i))+1)
a = a + (((sum(omega(k+n(i):k+n(i)+n(i)-1)/(n(i)*t0)))-(sum(omega(k:k+n(i)-1)/(n(i)*t0))))^2);
end
adev = sqrt((1/(2*(N-(2*n(i))+1)))*a);
Y = [Y; adev];
end
  4 件のコメント
Bruno Luong
Bruno Luong 2023 年 8 月 6 日
移動済み: Dyuman Joshi 2023 年 9 月 8 日
" transpose might take a toll on time."
0.2 ms
A=rand(1,1e7); % I believe OP array size is 33 time smaller
tic; A=A.'; toc
Elapsed time is 0.000162 seconds.
Dyuman Joshi
Dyuman Joshi 2023 年 8 月 6 日
移動済み: Dyuman Joshi 2023 年 9 月 8 日
Well, I did say might. But yeah, it's not the case here.

サインインしてコメントする。

回答 (1 件)

Bruno Luong
Bruno Luong 2023 年 8 月 6 日
編集済み: Bruno Luong 2023 年 8 月 6 日
instead of doing over and over (in the loop on the bottom) such calculation
sum(omega(i1:i2));
you could do once the cumulative sum
I = cumsum([0; omega(:)]);
and then replace sum(omega(i1:i2)) by
I(i2+1)-I(i1) % == sum(omega(i1:i2));
Your loop becomes (EDIT)
Y = zeros(numel(n),1);
I = cumsum([0; omega(:)]);
for i=1:numel(n)
a = 0;
ni = n(i);
for k=1:(N-(2*n(i))+1)
a = a + ((I(k+2*ni)-I(k+ni))/(ni*t0) - (I(k+ni)-I(k))/(n(i)*t0))^2;
end
adev = sqrt((1/(2*(N-(2*ni)+1)))*a);
Y(i) = adev;
end
which in term can be further vectorized (EDIT)
Y = zeros(numel(n),1);
I = cumsum([0; omega(:)]);
for i=1:numel(n)
ni = n(i);
p = N-2*ni+1;
K = 1:p;
Y(i) = 1/(ni*t0*sqrt(2*p)) * norm(I(K+2*ni) - 2*I(K+ni) + I(K));
end
  7 件のコメント
Bruno Luong
Bruno Luong 2023 年 8 月 7 日
編集済み: Bruno Luong 2023 年 8 月 7 日
@Pradeep Chandran "But in your code I understand that k is a scalar (mean of the first window"
I simply duplicate what your code does.
k=0;
for j=1:1+32
k=k+voltage(j);
end
k=k/33;
Your code compute k as mean of the first window, look at j index of your loop.
If you want the mean of the current windows you should make
for j=i:i+32
...
end
I believe few people ask you about this oddness and potential bug, including me but I delete later the question since you did not answer.
Bruno Luong
Bruno Luong 2023 年 8 月 7 日
編集済み: Bruno Luong 2023 年 8 月 7 日
My other question (was deleted so I reapeat here) is that why you use the first value of c in the window to set d
d(l)=c(i);
Is it intentional, and the other value of voltages are used only to compute the mean value k?
If I had to chose one c per window do nuild d, I would rather select the middle point
d(l)=c(i+16);

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeSemiconductors and Converters についてさらに検索

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by