Azzera filtri
Azzera filtri

How can I use Regress Function to fit a line to an irregular line?

1 visualizzazione (ultimi 30 giorni)
I've been advised to use the regress function to plot a fit for the mean spectral slice (PSD) I have created. Basically, I want to fit a line to an irregular line shape . However, I would like it to pivot at the mean , so basically, there are two slopes , one going upwards towards the mean, and then one going downwards away from the mean.
With that being said, I tried the following:
fitzone = 30:333; %indexes the vectors we want from the matrix
k = regress(fa(fitzone), 10*log10(meanpxx(fitzone)));
fitzone is there because I only want to use a portion of the vector .
Sufficed to say, I'm lost. The explanation and example with carsmall is not entirely clear to me! I'm not sure what I should be putting in for my regress(y, x). The primary data I want to fit the line to is meanpxx , but since it has gone through a multitaper power spectral density estimate I have to multiple it my 10*log10 in order to get the actual spectral shape. Below, I have pasted my entire code before the regress function and attached some sound files and an example plot (without the regression line). Any help is appreciated.
a = wavread('sheppard_1');
b = wavread('sheppard_2');
c = wavread('sheppard_3');
d = wavread('sheppard_4');
e = wavread('sheppard_5');
f = wavread('sheppard_6');
g = wavread('sheppard_7');
h = wavread('sheppard_8');
i = wavread('sheppard_9');
fs = 44100;
[pxxa,fa] = pmtm(a, 3, length(a), fs);
[pxxb,fb] = pmtm(b, 3, length(b), fs);
[pxxc,fc] = pmtm(c, 3, length(c), fs);
[pxxd,fd] = pmtm(d, 3, length(d), fs);
[pxxe,fe] = pmtm(e, 3, length(e), fs);
[pxxf,ff] = pmtm(f, 3, length(f), fs);
[pxxg,fg] = pmtm(g, 3, length(g), fs);
[pxxh,fh] = pmtm(h, 3, length(h), fs);
[pxxi,fi] = pmtm(i, 3, length(i), fs);
meanpxx = (pxxa + pxxb + pxxc + pxxd + pxxe + pxxf + pxxg + pxxh + pxxi)/9;
h = [0.5, 0.5, 0.5];
figure1 = figure;
axes1 = axes('Parent',figure1,'YGrid','on',...
'XTickLabel',{'0','5','10','15','20'},...
'XTick',[0 5000 1e+004 1.5e+004 2e+004],...
'XGrid','on');
hold(axes1, 'all');
plot(fa, 10*log10(pxxa), 'color', h);
plot(fb, 10*log10(pxxb), 'color', h);
plot(fc, 10*log10(pxxc), 'color', h);
plot(fd, 10*log10(pxxd), 'color', h);
plot(fe, 10*log10(pxxe), 'color', h);
plot(ff, 10*log10(pxxf), 'color', h);
plot(fg, 10*log10(pxxg), 'color', h);
plot(fh, 10*log10(pxxh), 'color', h);
plot(fi, 10*log10(pxxi), 'color', h);
plot(fa, 10*log10(meanpxx), 'k-', 'LineWidth', 3);
grid on
title('Thompson Multitaper Power Spectral Density Estimate')
xlabel('Frequency(kHz)')
ylabel('Power/Frequency(dB/Hz)')
axis([1000 11025 -150 -40])
[C, I] = max(meanpxx);
C1 = 10*log10(C);
fm = fa(I);
Thanks for any help!

Risposta accettata

Star Strider
Star Strider il 4 Ago 2014
This is a preliminary version of my code. I use created data but data that are similar to yours. Note that since I’m forcing both lines to meet at the mean, the slopes are not as they would be if we estimated the intercepts as well. I can probably make a function out of it that accepts your fa and 10*log10(meanpxx) as arguments, and returns the slopes and the calculated lines as output. I’ll wait until you have a chance to run this and see if it meets your requirements.
The logic is straightforward. I put the x and y coordinates of the mean at (0,0), divided the data into two segments to the ‘left’ and ‘right’ of the mean, then computed the resulting slopes, forcing the y-intercept to be zero in both regressions. I then re-centred the calculated regression lines to overplot your data:
x = linspace(0,25);
y = [3.*x(1:20)-80 -2.*x(21:end)-55] + randn(1,100);
Lx = length(x);
mnix = find(y == max(y)); % Index of mean here
xmn = x(mnix); % X-Value of mean
ymn = y(mnix); % Y-Value of mean
xmc = x-xmn; % Shift X to put ‘mean’ at x=0
ymc = y-ymn; % Shift Y to put ‘mean’ at y=0
ix_rng1 = 1:mnix; % First segment
Lx1 = length(ix_rng1);
M1 = [xmc(ix_rng1)']\[ymc(ix_rng1)'] % Slope of First Segment
ix_rng2 = mnix:Lx-mnix;
Lx2 = length(ix_rng2);
M2 = [xmc(ix_rng2)']\[ymc(ix_rng2)'] % Slope of First Segment
RL1 = [x(ix_rng1)']*M1 + ymn-M1*x(mnix);
RL2 = [x(mnix:Lx)']*M2 + ymn-M2*x(mnix);
figure(1)
plot(x, y)
hold on
plot(x(ix_rng1), RL1, 'r')
plot(x(mnix:Lx), RL2, 'r')
hold off
grid
I apologise for the delay, but I’m still tired after last night’s spambot battle.
  6 Commenti
Phil
Phil il 4 Ago 2014
Thanks! You've helped me out a ton. I can't thank you enough.
Star Strider
Star Strider il 5 Ago 2014
My pleasure!
As scientists, we’re all in this together!

Accedi per commentare.

Più risposte (1)

dpb
dpb il 4 Ago 2014
  1 Commento
Phil
Phil il 4 Ago 2014
This is nice and I would use it, but unfortunately, I don't think my license for MATLAB has all of these functions!

Accedi per commentare.

Prodotti

Community Treasure Hunt

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

Start Hunting!

Translated by