How to code a moving average in a matlab function block using persistent variables

39 visualizaciones (últimos 30 días)
Hi all,
I'm trying to code a moving average in a MATLAB function block (I don't have access to the DSP toolbox). The block needs to take 1 input signal and then release a single output. However, the block is within a subsystem that is part of a closed loop system that will receive both new inputs, as well as 'recycled' inputs.
I've tried to declare a persistent variable that stores the inputs and then calculates a moving average to output a single signal every time a new 'slug' of material passes through the subsystem - BUT I'm not getting anywhere fast (I'm new to MATLAB/Simulink) and would greatly appreciate someone's help!
I've tried something along the lines of:
function Aprime = fcn(A)
persistent A_array
if isempty(A_array)
A_array = zeros([],1); % this trying to create an empty array to append/concatenate each new value of A \
% that passes through the block
end
A_array = [A_array, A];
Aprime = movmean(A_array, 3) % the '3' is arbitrary at this point.
end
This block of code clearly does not function, and I'm getting errors with persistent variable assignment orders, left side array does not equal right side, etc., etc. depending on what combination of things I try.
While I've tried to use the 'movmean' built-in function here just to get me started, it doesn't really capture what I need either, as I need just one mean as an output signal each time a slug of material flows through the block.
I think maybe something along the lines of declaring an persistent index ('idx') variable and 'sliding' the window by a tunable size (user-defined) would be best, but I'm really not sure how to go about this.
Anybody's help would be UBER appreciated!
Thanks in advance.
Cheers
  6 comentarios
Ryan Wilson
Ryan Wilson el 26 de Mayo de 2022
I was finally able to come up with something that works using a combination of both of your comments.
Thanks
Rik
Rik el 26 de Mayo de 2022
Feel free to explain what you did in an answer. That way, future readers will be able to use your solution.

Iniciar sesión para comentar.

Respuesta aceptada

Ryan Wilson
Ryan Wilson el 27 de Mayo de 2022
Using a combination of advice from Rik and Walter Roberson, here's what I ultimately ended up doing to code a simple moving average (sliding window) for the purposes of my model (which functions in a closed loop circuit):
function A_out = fcn(A, flowParams) % movAvgWindow comes from\
% myParams structure in base workspace.
% First the variables are declared.
persistent array n
% During the first call of the function, variables are initialized.
if isempty(n)
array = zeros(1, myParams.movAvgWindow);
n = 1;
end
% The following loop maintains the values needed by moving window.
% Notice that if n < window then nothing needs to be done.
% This for loop also sums up the values of the array.
sum = 0;
for i = 1:(n-1)
if n >= myParams.movAvgWindow
array(i) = array(i+1);
end
sum = sum + array(i+1);
end
% The last position is updated based on the most recent input.
% A running total is also captured for averaging purposes.
array(n) = A;
sum = sum + A;
% This is the value to be returned.
if n >= myParams.movAvgWindow
A_out = sum / myParams.movAvgWindow;
else
A_out = sum / n;
end
% Finally, variable 'n' is updated.
if n >= myParams.movAvgWindow
n = myParams.movAvgWindow - 1;
end
n = n + 1;
end
I'd like to note that I tested it out against the 'Moving Average' block from the DSP toolbox and it appears to function pretty well identically. A possible difference is in the handling of the current index: my code always sets the window backward from the current index; I believe the movmean function in matlab does the same for even numbered windows, but straddles the present index for odd numbered windows.
Let me know if anyone else has any thoughts on how to improve.
Cheers

Más respuestas (0)

Productos


Versión

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by