I have a set of data that I need to separate into unequal intervals in order to calculate the RMS value of these data (The data points are continuous over time)
10 views (last 30 days)
Show older comments
ABDALLA AL KHALEDI
on 1 May 2023
Commented: ABDALLA AL KHALEDI
on 5 May 2023
I have a set of torque data and I need to calculate the rms (root-mean-square) torque. The problem is that I have almost 16000 data points with negative and positive values over time, These data must be seperated into intervals first and the length (unequal intervals) of each interval must be found.
What possible code can I use to perform a similar operation but on the full range of data as in the example picture below?
The torque data and time values saved as an Excel file and are attached below.
I know that MATLAB is able to find the rms value for a set of independent data as I read here but my data is continuous over time.
Note: some torque values do not repeat over a period of time and show up once in between two intervals, these can be omitted as I am intrested in the overall average of the intervals.
Thank you in advance.
3 Comments
Accepted Answer
dpb
on 4 May 2023
Edited: dpb
on 4 May 2023
For the solution for all torque levels without collapsing any,
tq=readmatrix('Torque Data.xlsx');
d=[true; diff(tq(:,2)) ~= 0]; % TRUE if values change (down to machine eps)
TQ=tq(d,2); % torque values at change points
ix=find([d(:); true]); % location of changes in logical vector
N = diff(ix); % difference in locations --> number
% so calculate the torque rms by group weighted by time
dt=mean(diff(tq(:,1))); % remove roundoff in dt calculationto get one dt overall
T=dt*(size(tq,1)-1); % total T
tq_rms=sqrt(sum(TQ.^2.*(N-1)*dt)/T)
@Jan coded <an FEX submission as a mex function RunLength> that is quite a bit faster if series lengths were to get to be really, really long...and is the root source of the M-code outline above although the general technique has wide applicability in finding crossing, etc., etc, etc., ...
ADDENDUM: The above takes care of the one-sample elements automatically in that the time interval is zero for a count of one...you don't even have to remove them first.
10 Comments
dpb
on 5 May 2023
"...about that don't matter from a practical point of view"
For the sample dataset, all the above return essentially the same result. The time-weighted value could be somewhat more different depending on the particular transient behavior, however...
More Answers (3)
Joe Vinciguerra
on 2 May 2023
Here is one way to do it based on your example:
% import the data from your file using readmatrix(), but using your example:
t = [0.2 0.4 0.6 0.8 1.0]'
data = [3 3 2 2 2]'
% find the unique torque values in data set to create an index for use below
[C, ia, ic] = unique(data, "stable")
% find the max and min times at which the unique values occure
t_max = accumarray(ic, t, [] ,@max)
t_min = accumarray(ic, t, [], @min)
% date the delta
t_delta = t_max - t_min
% perform you calcultion on these arrays
P = sum(C.^2 .* t_delta)
1 Comment
Mathieu NOE
on 4 May 2023
hello
maybe this ? I know I reinvented the histogram ( :)) , in few lines...
% Torque post processing
data = readmatrix("Torque Data.xlsx");
t = data(:,1);
torque = data(:,2);
dt = mean(diff(t));
% create levels (edges, like for a histogram)
Tmin = floor(min(torque));
Tmax = ceil(max(torque));
levels = 10;
Trange = linspace(Tmin,Tmax,levels+1);
for ci = 1:levels
id = (torque>=Trange(ci) & torque<Trange(ci+1));
torq_extr = torque(id);
samples = numel(find(id));
duration(ci) = samples*dt;
% T² computation
torq2(ci) = mean(torq_extr.^2); % T1², T2², etc
end
% finaly :
Torque_rms = sqrt(sum(torq2.*duration)/sum(duration));
% direct rms computation
Torque_rms_alt = sqrt(mean(torque.^2));
0 Comments
Star Strider
on 5 May 2023
It is not obvious to me exactly what you want to calculate. This isolates the regions between the spikes (that I refer to as ‘segments’), determines the times at the beginning and end of each segment, and calculates the RMS value of the signal in each region. I am not certain what you want to do beyond that.
One approach —
T1 = readtable('Torque Data.xlsx', 'VariableNamingRule','preserve')
VN = T1.Properties.VariableNames;
[pks,locs] = findpeaks(T1{:,2}, 'MinPeakProminence',1.5); % Quality Check
idx = [1; find(diff(sign(T1{:,2}-0.5))); size(T1,1)]; % Crossing Indices
blen = 2*ceil(numel(idx)/2); % Calculate Column Length Of 'idxmtx'
idxmtx = zeros(blen,1)+idx(end); % Preallocate
idxmtx(1:numel(idx)) = idx; % Assign Values To Vector
idxmtx = reshape(idxmtx, 2, []) % Convert To (2xN) Matrix Of Segment Beginning & End Indices
% idxmtx(:,end) % Check (Optional)
for k = 1:size(idxmtx,2)
idxrng = idxmtx(1,k) : idxmtx(2,k); % Vector Index Range
[b1,b2] = bounds(T1{idxrng,2}); % Range Of Segment Values (Optional
rangmtx(:,k) = [b1; b2; b2-b1]; % Store As Matrix (Optional)
timev{k} = T1{idxrng,1}; % Segment Time Vector
times(:,k) = T1{idxmtx(:,k),1}; % Segment Time Limits
rmsv(k) = rms(T1{idxrng,2}); % Segment RMS Value
end
times % Segment Beginning & End Times
rangmtx % Segment Minimum, Maximum & Difference
rmsv % Segment RMS Values
figure
hp{1} = plot(T1{:,1}, T1{:,2}, 'DisplayName','Data');
hold on
% plot(T1{locs,1}, pks, 'r+', 'DisplayName','Peaks')
hp{2} = plot(times, [1;1]*rmsv,'-m', 'DisplayName','Segment RMS Values');
hold off
grid
xlabel(VN{1})
ylabel(VN{2})
legend([hp{1},hp{2}(1)], 'Location','best')
I believe this gest close to what you asked for, however I do not understand how the times weight the RMS values. Incorporating that would be straightforward.
.
0 Comments
See Also
Categories
Find more on Data Type Conversion in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!