How do I create a wavelet transform from an existing signal? - matlab

I have a signal in time domain that has more than 4500 sample. From this signal I have extracted the following signature:
Using the code that can be seen under (in matlab)I have managed to create a wavelet transform out of this signature.
Current_DIR = cd; % Save the current directory name.
cd(tempdir); % Work in a temporary directory.
familyName = 'MyWAVE T1';
familyShortName = 'mywa';
familyWaveType = 1;
familyNums = '';
fileWaveName = 'mywa.mat';
myna =F; %F is the signal
save myna mywa
wavemngr('add',familyName,familyShortName,familyWaveType, ...
familyNums,fileWaveName)
Once I have created the wavelet, I tried to plot it which was successful and looked like follow:
For now all is good up to here.
When I try to use the wavemenu tool in matlab to view the wavelet it gives me the following error:
>> wavemenu
Error using vertcat
Dimensions of matrices being concatenated are not consistent.
Error in wdstem (line 38)
yy = [zeros(1,n);y;nan*ones(size(y))];
Error in wvdtool (line 390)
wdstem(axe_Lo_D,xVal_f,Lo_D,stemCOL,1);
Error while evaluating UIControl Callback
My question is, am I doing something wrong in the process? Is it even possible to take a signal and transform it into a wavelet in matlab?
Thank you in advance for your help. :)

Related

Error using ~= Matrix dimensions must agree

I'm using the following code of "Computed tomography-based volumetric tool for standardized measurement of the maxillary sinus" article to measure the volume of the maxillary sinus in DCOM images:
% Read images
clear all
close all
[filename, pathname] = uigetfile('*','Select CT exam (all slices)','MultiSelect','on');
num= length(filename);
bbbb=1;
step=input('Step of image reading: \')
for aaaa = 1:step:num
xinfo=dicominfo([pathname,char(filename(aaaa))]);
pxsp=cat(2,xinfo.PixelSpacing);
x=dicomread([pathname,char(filename(aaaa))])+cat(2,xinfo.RescaleIntercept);
k=x;
k = im2bw(k,0.49);
k = imfill(k,'holes');
cc = bwconncomp(k);
stats = regionprops(cc,'Area');
A = [stats.Area];
[~,biggest] = max(A);
k(labelmatrix(cc)~=biggest) = 0;
x(k~=1)=-2000;
masccranio(:,:,bbbb)=k;
cranio(:,:,bbbb)=x;
cranio_full(:,:,bbbb)=x;
bbbb=bbbb+1;
end
at the first, we don't have any idea about the reading step input at the beginning, please help on that if you can. Our second problem is when we run the code we get the following error:
Error using ~=
Matrix dimensions must agree.
Error in Quant (line 32)
k(labelmatrix(cc)~=biggest) = 0;
I'm using Matlab 2019b and as I know this code is for 2013. Any help is appreciated.
I expect you want biggest to represent the biggest value of all region areas in this line:
k(labelmatrix(cc)~=biggest) = 0;
In that case, your problem is likely that A is not a vector, and therefore biggest is not a scalar. This causes the operation to fail as the ~= operator only works on matrices of the same size or with scalars.

Using MLE function to estimate the parameters of a custom distribution

I am trying to use mle() function in MATLAB to estimate the parameters of a 6-parameter custom distribution.
The PDF of the custom distribution is
and the CDF is
where Γ(x,y) and Γ(x) are the upper incomplete gamma function and the gamma function, respectively. α, θ, β, a, b, and c are the parameters of the custom distribution. K is given by
Given a data vector 'data', I want to estimate the parameters α, θ, β, a, b, and c.
So, far I have come up with this code:
data = rand(20000,1); % Since I cannot upload the acutal data, we may use this
t = 0:0.0001:0.5;
fun = #(w,a,b,c) w^(a-1)*(1-w)^(b-1)*exp^(-c*w);
% to estimate the parameters
custpdf = #(data,myalpha,mybeta,mytheta,a,b,c)...
((integral(#(t)fun(t,a,b,c),0,1)^-1)*...
mybeta*...
igamma(myalpha,((mytheta/t)^mybeta)^(a-1))*...
(mytheta/t)^(myalpha*mybeta+1)*...
exp(-(mytheta/t)^mybeta-(c*(igamma(myalpha,(mytheta/t)^mybeta)/gamma(myalpha)))))...
/...
(mytheta*...
gamma(myalpha)^(a+b-1)*...
(gamma(myalpha)-igamma(myalpha,(mytheta/t)^mybeta))^(1-b));
custcdf = #(data,myalpha,mybeta,mytheta,a,b,c)...
(integral(#(t)fun(t,a,b,c),0,1)^-1)*...
integral(#(t)fun(t,a,b,c),0,igamma(myalpha,(mytheta/t)^mybeta)^mybeta/gamma(myalpha));
phat = mle(data,'pdf',custpdf,'cdf',custcdf,'start',0.0);
But I get the following error:
Error using mlecustom (line 166)
Error evaluating the user-supplied pdf function
'#(data,myalpha,mybeta,mytheta,a,b,c)((integral(#(t)fun(t,a,b,c),0,1)^-1)*mybeta*igamma(myalpha,((mytheta/t)^mybeta)^(a-1))*(mytheta/t)^(myalpha*mybeta+1)*exp(-(mytheta/t)^mybeta-(c*(igamma(myalpha,(mytheta/t)^mybeta)/gamma(myalpha)))))/(mytheta*gamma(myalpha)^(a+b-1)*(gamma(myalpha)-igamma(myalpha,(mytheta/t)^mybeta))^(1-b))'.
Error in mle (line 245)
phat = mlecustom(data,varargin{:});
Caused by:
Not enough input arguments.
I tried to look into the error lines but I can't figure out where the error actually is.
Which function lacks fewer inputs? Is it referring to fun? Why would mle lack fewer inputs when it is trying to estimate the parameters?
Could someone kindly help me debug the error?
Thanks in advance.
exp() is a function, not a variable, precise the argument
exp^(-c*w) ---> exp(-c*w)
The starting point concerns the 6 parameters, not only one
0.1*ones(1,6)
In custcdf mle requires the upper bound of the integral to be a
scalar, I did some trial and error and the range is [2~9]. for the
trial some values lead to negative cdf or less than 1 discard them.
Then use the right one to compute the upper bound see if it's the
same as the one you predefined.
I re-write all the functions, check them out
The code is as follow
Censored = ones(5,1);% All data could be trusted
data = rand(5,1); % Since I cannot upload the acutal data, we may use this
f = #(w,a,b,c) (w.^(a-1)).*((1-w).^(b-1)).*exp(-c.*w);
% to estimate the parameters
custpdf = #(t,alpha,theta,beta, a,b,c)...
(((integral(#(w)f(w,a,b,c), 0,1)).^-1).*...
beta.*...
((igamma(alpha, (theta./t).^beta)).^(a-1)).*...
((theta./t).^(alpha.*beta + 1 )).*...
exp(-(((theta./t).^beta)+...
c.*igamma(alpha, (theta./t).^beta)./gamma(alpha))))./...
(theta.*...
((gamma(alpha)).^(a+b-1)).*...
((gamma(alpha)-...
igamma(alpha, (theta./t).^beta)).^(1-b)));
custcdf = #(t,alpha,theta,beta, a,b,c)...
((integral(#(w)f(w,a,b,c), 0,1)).^-1).*...
(integral(#(w)f(w,a,b,c), 0,2));
phat = mle(data,'pdf',custpdf,'cdf',custcdf,'start', 0.1.*ones(1,6),'Censoring',Censored);
Result
phat = 0.1017 0.1223 0.1153 0.1493 -0.0377 0.0902

MATLAB plotting in a parfor-loop

I need to plot figures with subplots inside a parfor-loop, similar to this question (which deals more with the quality of the plots).
My code looks something like this:
parfor idx=1:numel(A)
N = A(idx);
fig = figure();
ax = subplot(3,1,1);
plot(ax, ...);
...
saveas(fig,"..."),'fig');
saveas(fig,"...",'png');
end
This gives a weird error:
Data must be numeric, datetime, duration or an array convertible to double.
I am sure that the problem does not lie in non-numeric data as the same code without parallelization works.
At this point I expected an error because threads will concurrently create and access figures and axes objects, and I do not think it is ensured that the handles always correspond to the right object (threads are "cross-plotting" so to say).
If I pre-initialize the objects and then acces them like this,
ax = cell(1,numel(A)); % or ax = zeros(1,numel(A));
ax(idx) = subplot(3,1,1);
I get even weirder errors somewhere in the fit-calls I use:
Error using curvefit.ensureLogical>iConvertSubscriptIndexToLogical (line 26)
Excluded indices must be nonnegative integers that reference the fit's input data points
Error in curvefit.ensureLogical (line 18)
exclude = iConvertSubscriptIndexToLogical(exclude, nPoints);
Error in cfit/plot (line 46)
outliers = curvefit.ensureLogical( outliers, numel( ydata ) );
I have the feeling it has to work with some sort of variable slicing described in the documentation, I just can't quite figure out how.
I was able to narrow the issues down to a fitroutine I was using.
TLDR: Do not use fitobjects (cfit or sfit) for plots in a parfor-loop!
Solutions:
Use wrappers like nlinfit() or lsqcurvefit() instead of fit(). They give you the fit parameters directly so you can call your fitfunction with them when plotting.
If you have to use fit() (for some reason it is the only one which was able to fit my data more or less consistently), extract the fit parameters and then call your fitfunction using cell expansion.
fitfunc = #(a,b,c,d,e,x) ( ... );
[fitobject,gof,fitinfo] = fit(x,y,fitfunc,fitoptions(..));
vFitparam = coeffvalues(fitobject);
vFitparam_cell = num2cell(vFitparam);
plot(ax,x,fitfunc(vFitparam_cell{:},x), ... );
As far as I know fit() requires the function handle to have subsequent parameters (not a vector), so by using a cell you can avoid bloated code like this:
plot(ax,x,fitfunc(vFitparam(1),vFitparam(2),vFitparam(3),vFitparam(4),vFitparam(5),x), ... );

How to use the filter generated using design function on Matlab?

I have created a peaking filter with 800 Hz center frequency using the commands as follows:
fs = 44100;
N = 6; F0 = 800/(fs/2); BW = 50/(fs/2);
peakspec = fdesign.peak('N,F0,BW',N,F0,BW);
peakfilt = design(peakspec,'SystemObject', true);
% Input signal
x = 2*cos(2*pi*(80).*(0.01:0.0001:10))+3*cos(2*pi*(100).*(0.01:0.0001:10));
% Getting the filtered output
y = filter(peakfilt, x);
This last line gives the error: Not enough input arguments.
I do not understand why I get this error.
I looked it up on the website and came to know that peakfilt is a BiquadFilter and it would be helpful if someone could explain how to use a BiquadFilter.
Thanks.
You're very close and there isn't much else you need to change to get it working.
% Getting the filtered output
y = filter(peakfilt, x);
In this last line you are trying to the use the filter function to apply your custom biquad filter, BUT the filter() function takes 3 inputs (minimum) as described in the documentation:
y = filter(b,a,x)
Where b & a are your two arrays of filter coefficients and x is your input signal that you want to filter.
In your case, you are trying to pass the peakfilt system object as an input to the filter() and it is then throwing back the error Not enough input arguments because its expecting 3 inputs minimum and 2 of them to be filter coefficients.
Following the biquad filter documentation filtering an input requires a slightly different approach:
filteredOutput = biquad(input);
And in your case changing the last line to the following should solve it:
y = peakfilt(x);
To then see the frequency response of your filter have a look at fvtool(filterObject); (documentation with the biquad filter docs), in your case:
fvtool(peakfilt);
I hope this helps!

Matlab TreeBagger: Table variable is not a valid predictor

I'm trying to use TreeBagger to build a classifier based on the UCI Diabetes 130-US database, http://archive.ics.uci.edu/ml/datasets/Diabetes+130-US+hospitals+for+years+1999-2008.
I have imported the data as a table (letting Matlab decide on the data types), and have done some cleaning on the data. I'm calling the classifier as from an example, using my own data:
num_trees = 50;
B = TreeBagger(num_trees, train, train.readmitted,...
'OOBPrediction','On',...
'Method','classification');
oobErrorBaggedEnsemble = oobError(B);
plot(oobErrorBaggedEnsemble)
xlabel 'Number of grown trees';
ylabel 'Out-of-bag classification error';
I get the following error:
Error using classreg.learning.internal.table2PredictMatrix>makeXMatrix (line 100) Table variable is not a valid predictor.
Error in classreg.learning.internal.table2PredictMatrix (line 57)
Xout = makeXMatrix(X,CategoricalPredictors,vrange,pnames);
Error in classreg.learning.classif.CompactClassificationTree/predict (line 639)
X = classreg.learning.internal.table2PredictMatrix(X,[],[],...
Error in CompactTreeBagger/treeEval (line 1083)
[labels,~,nodes] = predict(tree,x);
Error in CompactTreeBagger/predictAccum (line 1414)
thisR = treeEval(bagger,it,thisX,doclassregtree);
Error in CompactTreeBagger/error (line 470)
predictAccum(bagger,X,'useifort',useIforT,...
Error in TreeBagger/oobError (line 1479)
err = error(bagger.Compact,bagger.X,bagger.Y,...
train is a table, and table.readmitted is a cell retrieved from the table. Most of the rows are cells, as most of the data in this dataset is categorical.
I'm wondering is there are certain datatypes that the classifier can't handle.
Thanks for any help!
The use of tables for the Machine Learning toolbox was introduced in R2016a. For previous versions, the data could only be passed to the fit* functions or TreeBagger as arrays.
The behavior changed from R2015(a,b) to R2016a.