Skewness calculator using one pass algorithm. Code speed up needed.
Ältere Kommentare anzeigen
Hello,
I am using a one pass algorithm to calculate skewness. My code is as follows:
n = 10000000;
timeseries = randi(1000, 1, n);
tic
sk = skewness_onepass(timeseries);
toc
function skewness = skewness_onepass(x)
N = length(x);
M1 = 0;
M2 = 0;
M3 = 0;
% Algorithm taken from here:
% https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Higher-order_statistics
for n = 1: N
delta = x(n) - M1;
M1 = M1 + delta / n;
M3 = M3 + delta * delta * delta * (n - 1) * (n - 2) / (n * n) - 3 * delta * M2 / n;
M2 = M2 + delta * delta * (n - 1) / n;
end
std_dev = sqrt(M2 / N);
% Calculate skewness
skewness = (M3 / N) / (std_dev * std_dev * std_dev);
end
My Concern:
Is there anything I can do to speed up this code? My application is really time critical and I want to evaluate skewness as fast as possible.
Reading online seems to suggest that extending MATLAB using C++ (I know bit of C but not C++) could help, but I have no clue about this. If this is indeed something that can help, please provide code/snippet on how to execute this.
I also have other functions like this and I am hoping that lessons learnt on this can be used on those as well.
Thanks!
1 Kommentar
atharva aalok
am 19 Aug. 2023
Bearbeitet: atharva aalok
am 19 Aug. 2023
Akzeptierte Antwort
Weitere Antworten (1)
Bruno Luong
am 19 Aug. 2023
Bearbeitet: Bruno Luong
am 19 Aug. 2023
Simple factorize common quantities used in updating M1, M2, M3
function skewness = skewness_onepass_BLU2(x)
N = length(x);
M1 = 0;
M2 = 0;
M3 = 0;
for n = 1: N
delta = x(n) - M1;
a = delta / n;
M1 = M1 + a;
c = delta * a * (n - 1);
M3 = M3 + a * (c * (n - 2) - 3 * M2);
M2 = M2 + c;
end
skewness = M3 / (M2 * sqrt(M2/N));
end
EDIT: some more simplification
3 Kommentare
atharva aalok
am 19 Aug. 2023
Bruno Luong
am 19 Aug. 2023
Bearbeitet: Bruno Luong
am 19 Aug. 2023
On my laptop my edited code is slightly faster, not much though. Up to you to stay with your code. On the flops point of view mine is mess demanding.
n = 10000000;
timeseries = randi(1000, 1, n);
t_org = timeit(@()skewness_onepass(timeseries),1) % 0.0429 second
t_Bruno = timeit(@()skewness_onepass_BLU2(timeseries),1) % 0.0392 second
function skewness = skewness_onepass(x)
N = length(x);
M1 = 0;
M2 = 0;
M3 = 0;
% Algorithm taken from here:
% https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Higher-order_statistics
for n = 1: N
delta = x(n) - M1;
M1 = M1 + delta / n;
M3 = M3 + delta * delta * delta * (n - 1) * (n - 2) / (n * n) - 3 * delta * M2 / n;
M2 = M2 + delta * delta * (n - 1) / n;
end
std_dev = sqrt(M2 / N);
% Calculate skewness
skewness = (M3 / N) / (std_dev * std_dev * std_dev);
end
function skewness = skewness_onepass_BLU2(x)
N = length(x);
M1 = 0;
M2 = 0;
M3 = 0;
for n = 1: N
delta = x(n) - M1;
a = delta / n;
M1 = M1 + a;
c = delta * a * (n - 1);
M3 = M3 + a * (c * (n - 2) - 3 * M2);
M2 = M2 + c;
end
skewness = M3 / (M2 * sqrt(M2/N));
end
Bruno Luong
am 19 Aug. 2023
Bearbeitet: Bruno Luong
am 19 Aug. 2023
Here is the comparison of operations for each loop iteration.
original code
- +-: 8
- *: 9
- /: 4
- =: 4
- indexing: 1
My code
- +-: 7
- *: 5
- /: 1
- =: 6
- indexing: 1
So my code reduces
- 1 (+-) operation;
- 4 (*) operation;
- 3 (/) operation;
but increases
- 2 affectations
Kategorien
Mehr zu Write C Functions Callable from MATLAB (MEX Files) finden Sie in Hilfe-Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!