1 | function averagedData = averageOverTime(data, time, startP, endP)
|
---|
2 | %averageOverTime - compute the time averaged value of data in the range [startP, endP]
|
---|
3 | %
|
---|
4 | % data: time dependent data,
|
---|
5 | % time: has same number of columns as data, sorted in ascending order
|
---|
6 | % startP: start time point for averaging, can be at any time point, or
|
---|
7 | % even not coincide with the given points in 'time'
|
---|
8 | % endP: end time point for averaging. if this is the same as the startP,
|
---|
9 | % or not given, then the output will be the linear interpolation of the
|
---|
10 | % data at startP.
|
---|
11 | %
|
---|
12 | % if out of the given time range, use constant extrapolation,
|
---|
13 | % if within the range, do linear interpolation.
|
---|
14 | %
|
---|
15 | % Author: Cheng Gong
|
---|
16 | % Last modified: 2020-09-09
|
---|
17 | if nargin < 4
|
---|
18 | endP = startP;
|
---|
19 | end
|
---|
20 |
|
---|
21 | Nt = length(time);
|
---|
22 | if Nt ~= size(data,2)
|
---|
23 | error('The data and time does not match!');
|
---|
24 | end
|
---|
25 |
|
---|
26 | if startP > endP
|
---|
27 | error('The given start point has to be smaller than the end point!');
|
---|
28 | elseif startP == endP
|
---|
29 | % extrapolation if earlier than the first time point
|
---|
30 | if startP <= time(1)
|
---|
31 | i1 = 1;
|
---|
32 | i2 = 2;
|
---|
33 | % extrapolation if later than the last time point
|
---|
34 | elseif startP >= time(Nt)
|
---|
35 | i1 = Nt-1;
|
---|
36 | i2 = Nt;
|
---|
37 | else
|
---|
38 | pos = (time > startP);
|
---|
39 | i2 = find(pos, 1, 'first');
|
---|
40 | i1 = i2 - 1;
|
---|
41 | end
|
---|
42 | % linear interpolation
|
---|
43 | averagedData = data(:, i1) + (data(:, i1)-data(:, i2)).*(startP-time(i1))./(time(i1)-time(i2));
|
---|
44 | else
|
---|
45 | % find the first and last ID in the time series within the given range
|
---|
46 | pos = ((time>=startP) & (time<=endP));
|
---|
47 | firstId = find(pos, 1, 'first');
|
---|
48 | lastId = find(pos, 1, 'last');
|
---|
49 | if isempty(firstId) | isempty(lastId)
|
---|
50 | averagedData = nan(size(data,1), 1);
|
---|
51 | % error('Time points out of range');
|
---|
52 | else
|
---|
53 | % computed the integral with trapzoidal rule
|
---|
54 | integData = zeros(size(data,1), 1);
|
---|
55 | for i = firstId:lastId-1
|
---|
56 | integData = integData + (data(:,i+1) + data(:,i)) .* (time(i+1) - time(i)).*0.5;
|
---|
57 | end
|
---|
58 |
|
---|
59 | % special treatment for the first and last time step, which are not
|
---|
60 | % complete steps.
|
---|
61 | if firstId == 1
|
---|
62 | % extrapolation
|
---|
63 | integData = integData + data(:,1) .* (time(1)-startP);
|
---|
64 | else
|
---|
65 | % interpolation
|
---|
66 | integData = integData + 0.5.*(time(firstId)-startP)./ ...
|
---|
67 | (time(firstId)-time(firstId-1)) .* ...
|
---|
68 | ((time(firstId)-startP) .* data(:,firstId-1) + ...
|
---|
69 | (time(firstId)+startP-2*time(firstId-1)).*data(:,firstId));
|
---|
70 | end
|
---|
71 |
|
---|
72 | if lastId == Nt
|
---|
73 | % extrapolation
|
---|
74 | integData = integData + data(:,Nt) .* (endP-time(Nt));
|
---|
75 | else
|
---|
76 | % interpolation
|
---|
77 | integData = integData + 0.5.*(time(lastId)-endP)./ ...
|
---|
78 | (time(lastId+1)-time(lastId)) .* ...
|
---|
79 | ((time(lastId)-endP) .* data(:,lastId+1) + ...
|
---|
80 | (time(lastId)+endP-2*time(lastId+1)).*data(:,lastId));
|
---|
81 | end
|
---|
82 |
|
---|
83 | averagedData = integData ./ (endP-startP);
|
---|
84 | end
|
---|
85 | end
|
---|
86 |
|
---|