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 | if nargin < 4
|
---|
16 | endP = startP;
|
---|
17 | end
|
---|
18 |
|
---|
19 | Nt = length(time);
|
---|
20 | if Nt ~= size(data,2)
|
---|
21 | error('The data and time does not match!');
|
---|
22 | end
|
---|
23 |
|
---|
24 | if startP > endP
|
---|
25 | error('The given start point has to be smaller than the end point!');
|
---|
26 | elseif startP == endP
|
---|
27 | % extrapolation if earlier than the first time point
|
---|
28 | if startP <= time(1)
|
---|
29 | i1 = 1;
|
---|
30 | i2 = 2;
|
---|
31 | % extrapolation if later than the last time point
|
---|
32 | elseif startP >= time(Nt)
|
---|
33 | i1 = Nt-1;
|
---|
34 | i2 = Nt;
|
---|
35 | else
|
---|
36 | pos = (time > startP);
|
---|
37 | i2 = find(pos, 1, 'first');
|
---|
38 | i1 = i2 - 1;
|
---|
39 | end
|
---|
40 | % linear interpolation
|
---|
41 | averagedData = data(:, i1) + (data(:, i1)-data(:, i2)).*(startP-time(i1))./(time(i1)-time(i2));
|
---|
42 | else
|
---|
43 | % find the first and last ID in the time series within the given range
|
---|
44 | pos = ((time>=startP) & (time<=endP));
|
---|
45 | firstId = find(pos, 1, 'first');
|
---|
46 | lastId = find(pos, 1, 'last');
|
---|
47 | if isempty(firstId) | isempty(lastId)
|
---|
48 | averagedData = nan(size(data,1), 1);
|
---|
49 | % error('Time points out of range');
|
---|
50 | else
|
---|
51 | % computed the integral with trapzoidal rule
|
---|
52 | integData = zeros(size(data,1), 1);
|
---|
53 | for i = firstId:lastId-1
|
---|
54 | integData = integData + (data(:,i+1) + data(:,i)) .* (time(i+1) - time(i)).*0.5;
|
---|
55 | end
|
---|
56 |
|
---|
57 | % special treatment for the first and last time step, which are not
|
---|
58 | % complete steps.
|
---|
59 | if firstId == 1
|
---|
60 | % extrapolation
|
---|
61 | integData = integData + data(:,1) .* (time(1)-startP);
|
---|
62 | else
|
---|
63 | % interpolation
|
---|
64 | integData = integData + 0.5.*(time(firstId)-startP)./ ...
|
---|
65 | (time(firstId)-time(firstId-1)) .* ...
|
---|
66 | ((time(firstId)-startP) .* data(:,firstId-1) + ...
|
---|
67 | (time(firstId)+startP-2*time(firstId-1)).*data(:,firstId));
|
---|
68 | end
|
---|
69 |
|
---|
70 | if lastId == Nt
|
---|
71 | % extrapolation
|
---|
72 | integData = integData + data(:,Nt) .* (endP-time(Nt));
|
---|
73 | else
|
---|
74 | % interpolation
|
---|
75 | integData = integData + 0.5.*(time(lastId)-endP)./ ...
|
---|
76 | (time(lastId+1)-time(lastId)) .* ...
|
---|
77 | ((time(lastId)-endP) .* data(:,lastId+1) + ...
|
---|
78 | (time(lastId)+endP-2*time(lastId+1)).*data(:,lastId));
|
---|
79 | end
|
---|
80 |
|
---|
81 | averagedData = integData ./ (endP-startP);
|
---|
82 | end
|
---|
83 | end
|
---|
84 |
|
---|