'findpeaks' function on matlab outputs error. the error is 'too many output arguments'? - matlab

well first thanks in advance.
i am a machine learning person.
for a project, i have created a matlab function which returns several features of a signal in frequency domain.
the function returns signal's energy, sum of fourier coefficients, entropy, pwr_at_DC, power at peak frequency, and peak freq/dominant frequency.
the error states 'two many output arguments'!
code is this...
%signal = [120 111 117 109 94 104 125 161]; %for example consider this discrete signal.
%the function returns Singal's energy, sum of fourier coefficients, entropy,
%pwr_at_DC, power at peak frq, and peak freq.
function [signalFeatures] = SigFreqAnalysis(signal)
NFFT = length(signal); %leangth of the signal
signal = signal - mean(signal); %remove DC comp (avoid peak at 0Freq.
FT = fft(signal,NFFT); %fourier transform n point
sEnergy = sum(abs(FT).^2)/NFFT; %spectral energy
SumCoeff = sum(abs(FT)); %total of all NFFT coefficients!
%[P,F] = periodogram(signal,[],NFFT,'power');
[P,F] = pwelch(signal,ones(NFFT,1),0,NFFT,'power'); %[P,F] - PSD of the signal
%P1=real(P1);
%Steps for Entropy: calc PSD ---> normalize p ---> entropy = ??(P)log2(P);
Pn=P/norm(P); log2Pn = log2(Pn + 1e-12);
Entropy = -sum(Pn.*log2Pn)/log2(length(Pn));
PdBW = 10*log10(P); pwr_at_DC = PdBW(F==0); % power in dBW
%the most important dominant frquency! ! !
[pks_dBW,locs] = findpeaks(PdBW,'NPEAKS',1,'SORTSTR','descend'); %peak/dominant!
%findpeak returns empty vector if no freq found!
if isempty(pks_dBW)
pks_dBW=0; pkFrq = 0; %if pks_dbs is 0 findpeak returns empty matrix;
else
pkFrq = F(locs); %this is the dominant/peak frequency of X axes!!
end
signalFeatures = [sEnergy SumCoeff Entropy pwr_at_DC pks_dBW pkFrq];
%return this vector.
end
error ---> 'too many output arguments' in findpeak function!
can anyone help me resolve this error!
thanks,
Adesh Shah

Your code that calls the function should look like this:
signal = [120 111 117 109 94 104 125 161]
a = SigFreqAnalysis(signal)
but you are probably calling it this way
[a b] = SigFreqAnalysis(signal)
Hence, too many outputs

Related

How to interpret dependency on order for 1/3-octave band filters in Matlab?

I am trying to obtain a third-octave band representation of the frequency content of an acoustic signal, obtained by numerical simulation. The signal is the following:
The code I use (you can reproduce it by replacing P and t with other signals):
P = PNL(:,3) ; % Acoustic pressure signal
t = timeWindow ; % Time array
T = t(end) - t(1) ; % Signal duration
fs = length(t)/T ; % = 98123 [Hz]
T0 = 1 ; % Reference duration of 1 [s]
filterOrder = 6 ;
allANSIFrequencies = getANSICenterFrequencies(octaveFilter('FilterOrder', filterOrder, 'Bandwidth', '1/3 octave', 'SampleRate', fs));
cf = allANSIFrequencies(19 : 50) ; % Restricting the frequency range to [15 Hz - 20000 Hz]
for k = 1 : length(cf)
octFilt = octaveFilter(cf(k), 'Bandwidth', '1/3 octave','SampleRate', fs, 'FilterOrder', filterOrder, 'Oversample', false);
y = octFilt(P);
Prms = sqrt((1/T0) * trapz(t, y.^2)) ; % Root mean square pressure level
LE(k) = 20 * log10(Prms/20e-6) ; % [db] Sound Exposure Level
end
semilogx(cf, LE)
grid on
xlabel('Frequency (Hz)') ;
ylabel('L_{E} (dB)') ;
legend('Order 2', 'Order 4', 'Order 6', 'Order 12')
The frequency content I would expect based on experimental data is a mix of the results at different orders: up to 1000 [Hz] the levels from order 6 are correct, while from 1000 [Hz] onwards, it's the order 2 that describes best the frequency content.
I obtain very different results depending on the filter order I am using. To a certain degree that's normal. Higher orders should provide a sharper response of the filter, but I fail to interpret these results.
The resolution of the signal under investigation should be high enough (98123 [Hz]). Any idea of what the issue could be?
Thank you in advance, I'd appreciate any insight on this!

MATLAB "Index out of bounds" Error

I have a project to make FIR filter coefficients but when in process of Minimum-Order Lowpass Filter there is error which
I have no idea what that means and which part I need to repair:
function [ output_args ] = FIR_FilterCoeff()
N = 100; % FIR filter order
Fp = 20e3; % 20 kHz passband-edge frequency
Fp = 20e3; % 20 kHz passband-edge frequency
Fs = 96e3; % 96 kHz sampling frequency
Rp = 0.00057565; % Corresponds to 0.01 dB peak-to-peak ripple
Rst = 1e-4; % Corresponds to 80 dB stopband attenuation
NUM = firceqrip (N,Fp/(Fs/2),[Rp Rst],'passedge');
N2= 200; % change filter order to 200
NUM200 = firceqrip(N2,Fp/(Fs/2),[Rp Rst],'passedge');
Fst = 23e3; % transition width = Fst-Fp
NUM_MIN = firgr('minorder',[0,Fp/(Fs/2),Fst(Fs/2),1],[ 1 1 0 0 ],[Rp Rst]);
Your error lies in Fst(Fs/2) on your last line. Fst is a vector of length 1. It has 1 value 23e3. Round brackets, (), in MATLAB directly after a variable are used for indexing variables.
When you type Fst(Fs/2) you are attempting to access the 48000 element in Fst but it does not exist so MATLAB throws an error. I think you may have meant this to be
Fst/(Fs/2)
or (possibly)
Fst*(Fs/2)
The * sign is needed to perform multiplication in MATLAB. It is not good enough to simply use round brackets, (), as they have another purpose, Matrix Indexing.

Chi squared test

I have written code in MATLAB for a Chi-Square test. I wish to obtain P-values as 0.897 or 0.287 and so on, but my results are too small. Below is my code:
pd = fitdist(sample, 'weibull');
[h,p,st] = chi2gof(sample,'CDF',pd)
I've also tried using the AD test with similar result:
dist = makedist('Weibull', 'a',A, 'b',B);
[h,p,ad,cv] = adtest(sample, 'Distribution',dist)
Below is a histogram of the data with a fitted Weibull density function (Weibull parameters are A=4.0420 and B=2.0853)
When the p-value is less than a predetermined significance level (default is 5% or 0.05), it means that the null hypotheses is rejected (which in your case means that the sample did not come from a Weibull distribution).
The chi2gof function first output variable h denotes the test result, where h=1 means that the test rejects the null hypothesis at the specified significance level.
Example:
sample = rand(1000,1); % sample from Uniform distribution
pd = fitdist(sample, 'weibull');
[h,p,st] = chi2gof(sample, 'CDF',pd, 'Alpha',0.05)
The test clearly rejects H0, and concludes that the data did not came from a Weibull distribution:
h =
1 % 1: H1 (alternate hypo), 0: H0 (null hypo)
p =
2.8597e-27 % note that p << 0.05
st =
chi2stat: 141.1922
df: 7
edges: [0.0041 0.1035 0.2029 0.3023 0.4017 0.5011 0.6005 0.6999 0.7993 0.8987 0.9981]
O: [95 92 92 97 107 110 102 95 116 94]
E: [53.4103 105.6778 130.7911 136.7777 129.1428 113.1017 93.1844 72.8444 54.3360 110.7338]
Next let's try that again with a conforming sample:
>> sample = wblrnd(0.5, 2, [1000,1]); % sample from a Weibull distribution
>> pd = fitdist(sample, 'weibull')
pd =
WeibullDistribution
Weibull distribution
A = 0.496413 [0.481027, 0.512292]
B = 2.07314 [1.97524, 2.17589]
>> [h,p] = chi2gof(sample, 'CDF',pd, 'Alpha',0.05)
h =
0
p =
0.7340
the test now clearly passes with a high p-value.
EDIT:
Looking at the histogram you've shown, it does look like the data follows a Weibull distribution, although there might be cases of outliers (look at the right side of the histogram), which might explain why you are getting bad p-values. Consider preprocessing your data to handle extreme outliers..
Here is an example where I simulate outlier values:
% 5000 samples from a Weibull distribution
pd = makedist('Weibull', 'a',4.0420, 'b',2.0853);
sample = random(pd, [5000 1]);
%sample = wblrnd(4.0420, 2.0853, [5000 1]);
% add 20 outlier instances
sample(1:20) = [rand(10,1)+15; rand(10,1)+25];
% hypothesis tests using original distribution
[h,p,st] = chi2gof(sample, 'CDF',pd, 'Alpha',0.05)
[h,p,ad,cv] = adtest(sample, 'Distribution',pd)
% hypothesis tests using empirical distribution
[h,p,st] = chi2gof(sample, 'CDF',fitdist(sample,'Weibull'))
[h,p,ad,cv] = adtest(sample, 'Distribution', 'Weibull')
% show histogram
histfit(sample, 20, 'Weibull')
% chi-squared test
h =
1
p =
0.0382
st =
chi2stat: 8.4162
df: 3
edges: [0.1010 2.6835 5.2659 7.8483 25.9252]
O: [1741 2376 764 119]
E: [1.7332e+03 2.3857e+03 788.6020 92.5274]
% AD test
h =
1
p =
1.2000e-07
ad =
Inf
cv =
2.4924
The outliers are causing the distribution tests to fail (null hypothesis rejected). Still I couldn't reproduce getting a NaN p-value (you might wanna check this related question on Stats.SE about getting NaN p-values)..

Calculating Variance of Monte Carlo Estimate

I want to estimate the variance of R_LW, this is the ratio of the mean square error (MSE) of the estimator LW to the standard OLS estimator (R stands for ratio).
Each MSE is calculated over 5000 sims to give one R_LW. I want to know what the standard deviation of the estimate of Ratio R_LW is.
To estimate this I repeat the process 100 times to gain 100 estimates of R_LW and then calculate the variance of the 100 R_LWs produced. What I am seeing is that the R_LWs produced consecutively in the 100 simulations tend to be very similar in value resulting in a low overall variance 3.81E-06.
However when I rerun the whole process the it produces another 100 estimates of R_LW which although close to each other and producing a similar variance to the first set, the average value that they fluctuate around tends to have moved a lot further than the estimated variance of either run would suggest.
Given a variance of 3.8106 this equates to a standard deviation of 0.001953 so I would not expect to see a movement of more than 3 standard deviations over 100 sims, and indeed within one simulation run you don't see a movement larger than that across the 100 samples.
However when you look at the R_LW's between different runs it's mean value moves around a lot! See below
Run1 0.6133
Run2 0.5901
Run3 0.6169
Run4 0.5833
Run5 0.6161
Stdev 0.016
The between runs standard deviation is nearly 10 times higher? I'm guessing it had to do with how normrnd() is seeded?
clear;
tic
dim=1;
flag=0;
n=30;
p1=3;
p2=2;
alpha1=0.9;
alpha2=0.9;
error_vol=1^0.5;
MSE_OLS=0;
MSE_R=0;
MSE_OLS_tot=0;
MSE_LW_tot=0;
MSE_OLS_AVR=0;
MSE_R_AVR=0;
SUM_STD_MSE_OLS=0;
SUM_STD_MSE_R=0;
STD_OLS=0;
STD_R=0;
nsims=5000;
tot_p=p1+p2;
x=zeros(n,tot_p);
for i=1:n
z_i4=normrnd(0,1);
for j=1:p1
x(i,j)=x(i,j)+alpha1*z_i4;
x(i,j)= x(i,j)+(1-alpha1^2)^(0.5)*normrnd(0,1);
end
for j=1+p1:tot_p
x(i,j)=x(i,j)+alpha2*z_i4;
x(i,j)= x(i,j)+(1-alpha2^2)^(0.5)*normrnd(0,1);
end
end
mu= mean(x,dim);
sigma = std(x,flag,dim);
sigma0 = sigma;
sigma0(sigma0==0) = 1;
x_scaled = bsxfun(#minus,x, mu);
sigma0=sigma0*sqrt(n-1);
x_scaled = bsxfun(#rdivide, x_scaled, sigma0);
econFlag=0;
[U,sigma,coeff] = svd(x_scaled,econFlag);
b_act=coeff(:,1);
sigmax = std(x,flag,dim);
mu_x=mean(x,dim);
nrepl=100;
R_LW_tot=0;
R_LW_sq=0;
R_LW_var=0;
for vv=1:nrepl
for t=1:nsims
residuals=normrnd(0,error_vol,n,1);
y=x*b_act + residuals;
mu_y=mean(y,dim);
mu_y=mu_y*ones(n,1);
sigmay = std(y,flag,dim);
mu= mean(y,dim);
sigma = std(y,flag,dim);
sigma0 = sigma;
sigma0(sigma0==0) = 1;
y_scaled = bsxfun(#minus,y, mu);
sigma0=sigma0*sqrt(n-1);
y_scaled = bsxfun(#rdivide, y_scaled, sigma0);
b=x_scaled\y_scaled;
[b_LW k_LW]=LW(y_scaled, x_scaled);
for i=1:tot_p
b_LW(i)=b_LW(i)*sigmay/sigmax(i);
end
MSE_OLS=(b-b_act)'*(b-b_act);
MSE_LW=(b_LW-b_act)'*(b_LW-b_act);
MSE_OLS_tot=MSE_OLS_tot+MSE_OLS;
MSE_LW_tot=MSE_LW_tot+MSE_LW;
end
MSE_OLS_AVR=MSE_OLS_tot/nsims;
MSE_LW_AVR=MSE_LW_tot/nsims;
R_LW=MSE_LW_AVR/MSE_OLS_AVR;
R_LW_store(vv)=R_LW;
R_LW_tot=R_LW_tot+R_LW;
R_LW_sq=R_LW_sq+R_LW^2;
end
R_LW_var=(R_LW_sq)-(R_LW_tot^2/nrepl)/(nrepl-1);
toc
LW:
function [b k]=LW(y,x)
[n, p]=size(x);
dim=1;
flag=0;
b=x\y;
y_hat=x*b;
r=(y-y_hat);
s_squared=(r'*r)/(n-p-1);%s_squared=(r'*r)/(n-p-1);
econFlag=0;
[U,sigma,coeff] = svd(x,econFlag);%[U,sigma,coeff] = svd(z,econFlag);
EV=sigma.^2;
k=p*s_squared/(b'*x'*x*b);
pseudo = sqrt(k) * eye(p);
x_ridge = [x;pseudo];
y_ridge = [y;zeros(p,1)];
b = x_ridge\y_ridge;
end

Error Backpropagation - Neural network

I am trying to write a code for error back-propagation for neural network but my code is taking really long time to execute. I know that training of Neural network takes long time but it is taking long time for a single iteration as well.
Multi-class classification problem!
Total number of training set = 19978
Number of inputs = 513
Number of hidden units = 345
Number of classes = 10
Below is my entire code:
X=horzcat(ones(19978,1),inputMatrix); %Adding bias
M=floor(0.66*(513+10)); %Taking two-third of imput+output
Wji=rand(513,M);
aj=X*Wji;
zj=tanh(aj); %Hidden Layer output
Wkj=rand(M,10);
ak=zj*Wkj;
akTranspose = ak';
ykTranspose=softmax(akTranspose); %For multi-class classification
yk=ykTranspose'; %Final output
error=0;
%Initializing target variables
t = zeros(19978,10);
t(1:2000,1)=1;
t(2001:4000,2)=1;
t(4001:6000,3)=1;
t(6001:8000,4)=1;
t(8001:10000,5)=1;
t(10001:12000,6)=1;
t(12001:14000,7)=1;
t(14001:16000,8)=1;
t(16001:18000,9)=1;
t(18001:19778,10)=1;
errorArray=zeros(100000,1); %Stroing error values to keep track of error iteration
errorDiff=zeros(100000,1);
for nIterations=1:5
errorOld=error;
aj=X*Wji; %Forward propagating in each iteration
zj=tanh(aj);
ak=zj*Wkj;
akTranspose = ak';
ykTranspose=softmax(akTranspose);
yk=ykTranspose';
error=0;
%Calculating error
for n=1:19978 %for 19978 training samples
for k=1:10 %for 10 classes
error = error + t(n,k)*log(yk(n,k)); %using cross entropy function
end
end
error=-error;
Ediff = error-errorOld;
errorArray(nIterations,1)=error;
errorDiff(nIterations,1)=Ediff;
%Calculating dervative of error wrt weights wji
derEWji=zeros(513,345);
derEWkj=zeros(345,10);
for i=1:513
for j=1:M;
derErrorTemp=0;
for k=1:10
for n=1:19978
derErrorTemp=derErrorTemp+Wkj(j,k)*(yk(n,k)-t(n,k));
Calculating derivative of E wrt Wkj%
derEWkj(j,k) = derEWkj(j,k)+(yk(n,k)-t(n,k))*zj(n,j);
end
end
for n=1:19978
Calculating derivative of E wrt Wji
derEWji(i,j) = derEWji(i,j)+(1-(zj(n,j)*zj(n,j)))*derErrorTemp;
end
end
end
eta = 0.0001; %learning rate
Wji = Wji - eta.*derEWji; %updating weights
Wkj = Wkj - eta.*derEWkj;
end
for-loop is very time-consuming in Matlab even with the help of JIT. Try to modify your code by vectorize them rather than organizing them in a 3-loop or even 4-loop. For example,
for n=1:19978 %for 19978 training samples
for k=1:10 %for 10 classes
error = error + t(n,k)*log(yk(n,k)); %using cross entropy function
end
end
can be changed to:
error = sum(sum(t.*yk)); % t and yk are both n*k arrays that you construct
You may try to do similar jobs for the rest of your code. Use dot product or multiplication operations on arrays for different cases.