Curve Fitting error for two arrays - matlab

I have two arrays:
x=[ 2180000; 6070000; 12700000; 16600000; 25000000; 29400000; 32200000; 36100000; 41600000; 43900000; 47200000; 55000000 ]
y= [ 1.0e-07*0.0953; 1.0e-07*0.1060; 1.0e-07*0.1220; 1.0e-07*0.1290; 1.0e-07*0.1480; 1.0e-07*0.1580; 1.0e-07*0.1880; 1.0e-07*0.2510; 1.0e-07*0.3210; 1.0e-07*0.3510; 1.0e-07*0.4470; 1.0e-07*0.6090]
I used this custom equation:
y=a*exp(-b/(4.14e-21))*exp(((3.2e-9)*(x))/((2)*(1.38e-23)*(300)))
The problem that I have is:
NaN computed by model function, fitting cannot continue. Try using or tightening upper and lower bounds on coefficients.

Related

Confidence Bound of linear regression using polyfit and polyconf

I am doing a simple linear regression and I am trying to plot the 95% confidence boundary using the matlab functions polyfit and polyconf, but I'm wondering why I am getting more than two lines for the boundary? Thank you for your help.
x1= [ 165.371 227.7475 204.4437 93.874 259.2976 113.3138 74.67 121.1493 60.7095 46.7491 355.6146 876.4135 1.2875 169.7753 341.4739 29.8034 260.1231 664.0960 ];
y= [ 165.371 228.6 203.416 93.874 262.066 104.902 74.67 121.63 59.463 46.749061 186.82666 931.3108984074 11.287521 176.76547 338.75586 29.803396 169.38878 692.66666 ];
surface_area_model = fitlm(y,x1,'linear')
[p,s]=polyfit(y,x1,1);
[yfit,dy]=polyconf(p,y,s,'predopt','curve');
figure(3)
a= 100;
h1= scatter(y,x1,a,'ob','LineWidth',1.2);
line(y,yfit,'color','b','LineWidth',2);
line(y,yfit-dy,'color','r','linestyle',':');
line(y,yfit+dy,'color','r','linestyle',':');
Figure:
Your data is not sorted in ascending order. In fact not only the boundary, but the data and fitted data line are of multiple segments as well.
Applying the following code which sorts the data right after assignments
[y,k] = sort(y);
x1 = x1(k);
will result in this graph

Cholesky factorization type error Matlab

I'm trying nothing complicated but can't understand why it triggers this error (using Matlab's R2016a version).
I want to compute Matlab's Cholesky factorization chol() on my_matrix which is a [2x2x3 double]
my_matrix(:,:,1) = [ 4.2534 0.4791; 0.4791 0.3522];
my_matrix(:,:,2) = [ 0.9729 0.8723; 0.8723 2.6317];
my_matrix(:,:,3) = [ 0.9886 -1.2244; -1.2244 3.0187];
chol(my_matrix)
However this throws the following error :
Undefined function 'chol' for input arguments of type 'double' and
attributes 'full 3d real'.
As pointed out by #Eli Sadoff, the cholesky factorization takes in a 2D matrix. So this error meant I was using a 3D matrix instead of a 2D one. So I applied chol() to each of the last dimension instead.

Matlab SVM linear binary classification failure

I'm trying to implement a simple SVM linear binary classification in Matlab but I got strange results.
I have two classes g={-1;1} defined by two predictors varX and varY. In fact, varY is enough to classify the dataset in two distinct classes (about varY=0.38) but I will keep varX as random variable since I will need it to other works.
Using the code bellow (adapted from MAtlab examples) I got a wrong classifier. Linear classifier should be closer to an horizontal line about varY=0.38, as we can perceive by ploting 2D points.
It is not displayed the line that should separate two classes
What am I doing wrong?
g(1:14,1)=1;
g(15:26,1)=-1;
m3(:,1)=rand(26,1); %varX
m3(:,2)=[0.4008; 0.3984; 0.4054; 0.4048; 0.4052; 0.4071; 0.4088; 0.4113; 0.4189;
0.4220; 0.4265; 0.4353; 0.4361; 0.4288; 0.3458; 0.3415; 0.3528;
0.3481; 0.3564; 0.3374; 0.3610; 0.3241; 0.3593; 0.3434; 0.3361; 0.3201]; %varY
SVMmodel_testm = fitcsvm(m3,g,'KernelFunction','Linear');
d = 0.005; % Step size of the grid
[x1Grid,x2Grid] = meshgrid(min(m3(:,1)):d:max(m3(:,1)),...
min(m3(:,2)):d:max(m3(:,2)));
xGrid = [x1Grid(:),x2Grid(:)]; % The grid
[~,scores2] = predict(SVMmodel_testm,xGrid); % The scores
figure();
h(1:2)=gscatter(m3(:,1), m3(:,2), g,'br','ox');
hold on
% Support vectors
h(3) = plot(m3(SVMmodel_testm.IsSupportVector,1),m3(SVMmodel_testm.IsSupportVector,2),'ko','MarkerSize',10);
% Decision boundary
contour(x1Grid,x2Grid,reshape(scores2(:,1),size(x1Grid)),[0 0],'k');
xlabel('varX'); ylabel('varY');
set(gca,'Color',[0.5 0.5 0.5]);
hold off
A common problem with SVM or any classification method for that matter is unnormalized data. You have one dimension that spans for 0 to 1 and the other from about 0.3 to 0.4. This causes inbalance between the features. Common practice is to somehow normalize the features, for examply by std. try this code:
g(1:14,1)=1;
g(15:26,1)=-1;
m3(:,1)=rand(26,1); %varX
m3(:,2)=[0.4008; 0.3984; 0.4054; 0.4048; 0.4052; 0.4071; 0.4088; 0.4113; 0.4189;
0.4220; 0.4265; 0.4353; 0.4361; 0.4288; 0.3458; 0.3415; 0.3528;
0.3481; 0.3564; 0.3374; 0.3610; 0.3241; 0.3593; 0.3434; 0.3361; 0.3201]; %varY
m3(:,2) = m3(:,2)./std(m3(:,2));
SVMmodel_testm = fitcsvm(m3,g,'KernelFunction','Linear');
Notice the line before the last.

Difference between results of MATLAB and SPSS Factor Analysis(FA)

This is my code in IBM SPSS:
FACTOR
/VARIABLES VAR00001 VAR00002 VAR00003 VAR00004 VAR00005 VAR00006
/MISSING LISTWISE
/ANALYSIS VAR00001 VAR00002 VAR00003 VAR00004 VAR00005 VAR00006
/PRINT UNIVARIATE INITIAL CORRELATION SIG DET KMO INV REPR AIC EXTRACTION ROTATION
/PLOT EIGEN ROTATION
/CRITERIA MINEIGEN(1) ITERATE(25)
/EXTRACTION PC
/CRITERIA ITERATE(25)
/ROTATION VARIMAX
/METHOD=CORRELATION.
and this is code of MATLAB R2015b to do the same:
[lambda,psi,T,stats,F]=factoran(DATA,2,'rotate','varimax');
SPSS output for roteted component matrix:
Rotated Component Matrix
Component
1 2
VAR00001 .973 -.062
VAR00002 .911 -.134
VAR00003 .833 -.035
VAR00004 .972 -.102
VAR00005 -.236 .823
VAR00006 .062 .878
Extraction Method: Principal Component Analysis.
Rotation Method: Varimax with Kaiser Normalization.
a Rotation converged in 3 iterations.
MATLAB lambda output:
0.993085200854508 -0.0537771548307969
0.875990644597448 -0.147112975689921
0.748570753047806 -0.0343768914779775
0.987459815125692 -0.0988807726538385
-0.203059229288894 0.976610007465447
0.00719025397609984 0.475514010080256
Why these outputs are different? I want same results in MATLAB. As you know SPSS ignores eigenvalues smaller than 1. I want same structure in MATLAB. How can I do this?
PS.
MATLAB T output:
0.622170579007477 -0.782881709211232
0.782881709211232 0.622170579007477
MATLAB psi output:
0.0108898014620571
0.210998162961140
0.438460057014266
0.0151457063113246
0.00500000000002244
0.773834726466399
Other SPSS outputs:
Component Matrix
Component
1 2
VAR00001 .964 .144
VAR00002 .919 .061
VAR00003 .821 .141
VAR00004 .971 .105
VAR00005 -.404 .755
VAR00006 -.124 .871
Extraction Method: Principal Component Analysis.
a 2 components extracted.
Component Transformation Matrix
Component 1 2
1 .977 -.211
2 .211 .977
Extraction Method: Principal Component Analysis.
Rotation Method: Varimax with Kaiser Normalization.
Matlab extracts factors using the maximum likelihood method. I don't think you can change this. SPSS extracts methods using principle components as its default, and this is the method that you have chosen for your SPSS analysis. That's yet another difference...

fmincon does not match nonlinear constrains

I trying to minimize function handle with respect to vector of parameters beta0. My function uses built-in mvncdf function which uses positive definite covariance matrix. This matrix is counted from part of vector of parameters. Also there is constraint for absolute value of some parameters to be less than one.
I set constraints to fmincon in two ways: upper and lower bounds to required values and use following nonlinear constraint:
function [c,ceq] = pos_def(beta0)
rho_12 = beta0(end-2,1);
rho_13 = beta0(end-1,1);
rho_23 = beta0(end,1);
sigma111=[1 rho_12 rho_13; rho_12 1 rho_23; rho_13 rho_23 1];
sigma110=[1 rho_12 -rho_13; rho_12 1 -rho_23; -rho_13 -rho_23 1];
sigma101=[1 -rho_12 rho_13; -rho_12 1 -rho_23; rho_13 -rho_23 1];
sigma100=[1 -rho_12 -rho_13; -rho_12 1 rho_23; -rho_13 rho_23 1];
eig111 = eig(sigma111);
eig110 = eig(sigma110);
eig101 = eig(sigma101);
eig100 = eig(sigma100);
c = vertcat(-eig111,-eig110,-eig101,-eig100);
As all matrices are square and symmentric by constraction, as proxy to positive difiniteness I use signs of eigenvalues.
The optimization problem looks like:
opts = optimset ('Display','iter','TolX',1e-15,'TolFun',1e-15,...
'Algorithm','interior-point','MaxIter',100000,'MaxFunEvals',1000000);
xc3_3=fmincon(model, beta,[],[],[],[],lb,ub,#pos_def, opts)
But during estimation fmincon aborts with error
Error using mvncdf (line 193) SIGMA must be a square, symmetric, positive definite matrix.
Under debuging mode I can see that after two iterations of evaluation Matlab tries to estimate beta0 which does not sutisfy my nonlinear constraints,
beta0 =
-46.9208
33.2916
-2.1797
-46.4251
3.8337
-0.3066
6.1213
-20.9480
-1.7760
-0.1807
1.3950
4.5348
-0.9838
0.2600
-6.9887
-24.6157
-0.0112
-0.9923
-0.9284
0.7664
0.3062
And constraint c < 0 does not satisfied:
c =
0.3646
-1.2998
-2.0648
0.3646
-1.2998
-2.0648
0.3646
-1.2998
-2.0648
0.3646
-1.2998
-2.0648
I do not understand why this optimization tool trying to find solution in the prohibited area and how to avoid this problem. Or how to set constrains on positive definiteness in the linear way.
The optimizer is just evaluating points to see if they are feasible directions to move in or not. Within your model you should tell it that a particular direction is not a good one. The pseudo-code would look something like
GetEigvalues
if (positive definite) then
Do what you really want to happen
else
Return a large number
end
or alternatively
try
Do what you really want to happen
catch
Return a large number
end