Asked by Morpheuskibbe
on 17 Oct 2019 at 20:12

I have a pile of data from a sensor and the sensor is getting maxed out. However, I knwo the data SHOULD be a sine wave and the top/bottom is only getting clipped off due to the sensor's limits. Is there a way to write an Mcode that will restore or unclip the sine wave?

I attached the worst of the data. As you can see in the third column, before you even bother to graph it, it's slamming into the top and bottom of the scale repeatedly.

Answer by Bjorn Gustavsson
on 17 Oct 2019 at 21:03

Accepted Answer

You can do something like this:

sfcn = @(t,pars) pars(1)+pars(2)*sin(pars(3)*t+pars(end)); % sine-like function with offset and phase-shift

fitfcn = @(pars,y,t,sfcn) sum(( sfcn(t,pars) - y).^2); % Sum-of-square function

Clipped3 = clipped(:,3); % Your thirs column

t = 1:numel(Clipped3); % Some time-array for uniformly sampled data

% Identify your clipped data points:

iBad = find(Clipped3>290|Clipped3<2);

Clipped3(iBad) = []; % Cut those points out

t(iBad) = []; % from data and time-array

pars0 = [150,500,2*pi/(46.7),pi/2];

% this fitting is painfully sensitive to bad start-guess so the above line

% we set the average at 150, the oscillating amplitude to 500, and the angular

% frequency to fit with a period-time of 46-47 time-steps, and the phase-shift

% to pi/2 since your data starts at a peak not a zero

% Fit by minimizing sum of squared residuals:

parsOK = fminsearch(@(pars) fitfcn(pars,Clipped3,t',sfcn),pars0)

%parsOK =

% 166.1 240.25 0.13416 1.7285

plot(clipped(:,3),'b-') % initial curve

hold on

plot(t,Clipped3,'b.') % unclipped points

% Residuals:

plot(t,Clipped3'-sfcn(t,parsOK),'r.')

% Well-fitting sinusoidal curve

plot(t(1):t(end),sfcn(t(1):t(end),parsOK),'r')

HTH

Morpheuskibbe
on 17 Oct 2019 at 21:27

Made a very slight modification just to pass the array to it and get this error:

Unable to perform assignment because the size of the left side is 1-by-1 and the size of the right side is 1-by-653.

Error in fminsearch (line 200)

fv(:,1) = funfcn(x,varargin{:});

Error in unclip (line 16)

parsOK = fminsearch(@(pars) fitfcn(pars,Clipped3,t',sfcn),pars0);

Morpheuskibbe
on 17 Oct 2019 at 21:31

Nevermind, i realized how i borked it.

Seems to work. Thanks

Morpheuskibbe
on 17 Oct 2019 at 22:28

Sign in to comment.

Opportunities for recent engineering grads.

Apply Today
## 0 Comments

Sign in to comment.