Calculate cubic spline integral in matlab with 3 values - matlab

I am trying to calculate an integral using spline interpolation with matlab (version R2014a on windows 8).
I have the 3 values of the function (for x=0,0.5,1).
so I have 2 vectors - x and y that contain the values of the function, and I'm executing
cube_spline = spline(x,y);
coefficients = qube_spline.coefs
And I'm expecting to get 2 polynomials, each of degree 3, i.e I'm expecting coefficients to be a matrix of size 2*4, but somewhy I'm getting a matrix that is 1*4, which means only 1 polynomial for 2 panels.
On the other hand, if for example I'm using 4 dots, (i.e 3 panels) then I'm getting that coefficients's size is 3*4 as expected, which means 3 polynomials for 3 panels.
My question is Why does matlab return only 1 polynomial for 2 panels spline, and 3 polynomial for 3 panels spline (or any number that is greater then 2)?

There are multiple possible boundary conditions for splines, e.g.:
second derivatives equals zero on the boundary
given first derivatives on the boundary
periodic conditions, i.e. same first and second derivatives on the boundary
not-a-knot: take the outermost three points to specify the boundary conditions.
It seems spline is using the not-a-knot condition by default. So for three points only a single cubic polynomial is necessary to interpolate your data (a quadratic one would be enough too if it weren't for the not-a-knot condition), so there's no reason for spline to return one spline for each of the two intervals. This is however not a bad thing.
By the way: If all you want is to interpolate the values and don't need the polynomial coefficients, you could go with interp1 instead. You can specify in a simpler way which kind of discontinuities you want. You have the options to go with:
'pchip': C^1 continuity.
Shape-preserving piecewise cubic interpolation. The interpolated value at a query point is based on a shape-preserving piecewise cubic interpolation of the values at neighboring grid points.
integral(#(xs) interp1(x, y, xs, 'pchip'), xmin, xmax)
'spline': C^2 continuity. (Seems to be using the same not-a-knot end conditions as spline.)
Spline interpolation using not-a-knot end conditions. The interpolated value at a query point is based on a cubic interpolation of the values at neighboring grid points in each respective dimension.
integral(#(xs) interp1(x, y, xs, 'spline'), xmin, xmax)

Related

Why ROC's plotting function perfcurve of MATLAB is yielding 3 ROC curves in case of cross validation?

I plotted 5 fold cross-validation data as a cell array to perfcurve function with positive class=1. Then it generated 3 curves as you can see in the diagram. I was expecting only one curve.
[X,Y,T,AUC,OPTROCPT,SUBY,SUBYNAMES] = perfcurve(Actual_label,Score,1);
plot(X,Y)
Here, Actual_label and Score are a cell array of size 5 X 1. Each cell array is of size 70 X 1. And 1 denotes positive class=1.
P.S: I am using One-class SVM and 'fitSVMPosterior' function is not appropriate for one-class learning (same has been mentioned in the documentation of MATLAB). Therefore posterior probability can't be used here.
When you compute the confidence bounds, X and Y are an m-by-3 array, where m is the number of fixed X values or thresholds (T values). The first column of Y contains the mean value. The second and third columns contain the lower bound and the upper bound, respectively, of the pointwise confidence bounds. AUC is also a row vector with three elements, following the same convention.
Above explanation is taken from MATLAB documentation.
That is expected because you are plotting the ROC curve for each of the 5 folds.
Now if you want to have only one ROC for your classifier, you can either use the 5 trained classifiers to predict the labels of an independent test set or you can average the posterior probabilities of the 5 folds and have one ROC.

Why is this polynomial equation badly conditioned?

I have 1x1024 matrix. So I'd like to estimate a polynomial equation.
X= (0:1023)'
Y= acquired data. A 1024 element vector
Then I try this in MATLAB:
polyfit(x,y,5)
But MATLAB makes an abnormal result with warning.
Warning: Polynomial is badly conditioned. Add points with distinct X values, reduce the degree of the ...
I don't understand what am I doing wrong?
Update
I got a bunch of numbers like this.
Y=
-0.0000000150
...
0.00001
...
0
...
0.17
X= 0~255
polyfit(X,Y,4)
I got a polynomial but it does not match to original curve.
Is there any options to match between original curve and polyfit's curve?
The problem can be attributed to the type of coefficient matrix that polyfit builds from the x vector: a Vandermonde matrix.
When
the elements of the x vector vary too much in magnitude, and
the degree of the fitting polynomial is too high,
you get an ill-conditioned matrix, and the associated linear system cannot be solved reliably.
Try to centre and scale your x vector first, before applying polyfit, as advised at the bottom of the polyfit help page:
Since the columns in the Vandermonde matrix are powers of the vector x, the condition number of V is often large for high-order fits, resulting in a singular coefficient matrix. In those cases centering and scaling can improve the numerical properties of the system to produce a more reliable fit.
(my emphasis)
The warning is because the data that you are supplying to polyfit with your desired degree of polynomial isn't suitable. Specifically, there is an insufficient amount of variability in your data so that you can successfully achieve a good fit. Therefore, MATLAB gives you that warning because the data can't be fit properly with your desired degree polynomial.
The solution to this is to either get more points so that you can get the desired fit of the polynomial degree you want or to decrease the degree of polynomial you want.
Try values that are less than 5... 4, 3 or perhaps 2:
coeff = polyfit(x, y, 4);
%// or
%coeff = polyfit(x, y, 3);
%coeff = polyfit(x, y, 2);
Try each degree until you don't get the warning anymore. However, without the actual data, I can only speculate what's wrong, and this is my best guess.

Dividing Polynomial Fitted Curves in MATLAB

I have two 5th order polynomial fits, one of which I have taken the derivative of. I want to divide to the two polynomials and plot the results. From what I can the only way to do this is to use the "deconv" function, but how do I plot the results? Or is there an easier way to do this?
cdpdz=coeffvalues(fitresult{2});
%where pn are the coefficients of the first derivative of the fitted polynomial
pp=[p1,p2,p3,p4,p5,p6];
[divpp.r]=deconv(pp/cdpdz);
Since you want to plot the results, I am assuming that you actually want to calculate the values of the polynomials at many points, and then divide those values. That is different than the polynomial division that is performed by deconv.
I would suggest that you must make a range of values x over which to evaluate the polynomials. Then use polyval to get the values over that range, and divide the two arrays (being careful of zeros in the denominator!)
ppval = polyval(pp,x);
cdpdzval = polyval(cdpdz,x);
plot(x,ppval./cdpdzval);

Find approximation of sine using least squares

I am doing a project where i find an approximation of the Sine function, using the Least Squares method. Also i can use 12 values of my own choice.Since i couldn't figure out how to solve it i thought of using Taylor's series for Sine and then solving it as a polynomial of order 5. Here is my code :
%% Find the sine of the 12 known values
x=[0,pi/8,pi/4,7*pi/2,3*pi/4,pi,4*pi/11,3*pi/2,2*pi,5*pi/4,3*pi/8,12*pi/20];
y=zeros(12,1);
for i=1:12
y=sin(x);
end
n=12;
j=5;
%% Find the sums to populate the matrix A and matrix B
s1=sum(x);s2=sum(x.^2);
s3=sum(x.^3);s4=sum(x.^4);
s5=sum(x.^5);s6=sum(x.^6);
s7=sum(x.^7);s8=sum(x.^8);
s9=sum(x.^9);s10=sum(x.^10);
sy=sum(y);
sxy=sum(x.*y);
sxy2=sum( (x.^2).*y);
sxy3=sum( (x.^3).*y);
sxy4=sum( (x.^4).*y);
sxy5=sum( (x.^5).*y);
A=[n,s1,s2,s3,s4,s5;s1,s2,s3,s4,s5,s6;s2,s3,s4,s5,s6,s7;
s3,s4,s5,s6,s7,s8;s4,s5,s6,s7,s8,s9;s5,s6,s7,s8,s9,s10];
B=[sy;sxy;sxy2;sxy3;sxy4;sxy5];
Then at matlab i get this result
>> a=A^-1*B
a =
-0.0248
1.2203
-0.2351
-0.1408
0.0364
-0.0021
However when i try to replace the values of a in the taylor series and solve f.e t=pi/2 i get wrong results
>> t=pi/2;
fun=t-t^3*a(4)+a(6)*t^5
fun =
2.0967
I am doing something wrong when i replace the values of a matrix in the Taylor series or is my initial thought flawed ?
Note: i can't use any built-in function
If you need a least-squares approximation, simply decide on a fixed interval that you want to approximate on and generate some x abscissae on that interval (possibly equally spaced abscissae using linspace - or non-uniformly spaced as you have in your example). Then evaluate your sine function at each point such that you have
y = sin(x)
Then simply use the polyfit function (documented here) to obtain least squares parameters
b = polyfit(x,y,n)
where n is the degree of the polynomial you want to approximate. You can then use polyval (documented here) to obtain the values of your approximation at other values of x.
EDIT: As you can't use polyfit you can generate the Vandermonde matrix for the least-squares approximation directly (the below assumes x is a row vector).
A = ones(length(x),1);
x = x';
for i=1:n
A = [A x.^i];
end
then simply obtain the least squares parameters using
b = A\y;
You can clearly optimise the clumsy Vandermonde generation loop above I have just written to illustrate the concept. For better numerical stability you would also be better to use a nice orthogonal polynomial system like Chebyshev polynomials of the first kind. If you are not even allowed to use the matrix divide \ function then you will need to code up your own implementation of a QR factorisation and solve the system that way (or some other numerically stable method).

Polynomial Constrained Least Squares curve fitting with matlab

I want to fit and draw a curve that is constrained with the following boundary condition:
diff (yfit)<=0
where yfit is the polynomial fitted function to degree n.
The condition ensures that the slope of the polynomial to any degree of is non-positive for all x .
How can I apply the condition using the "polyfit" function or any other polynomial fitting function?
From my limited point of mathematical view, a polynomial function of degree 2 for example has by definition a reagion with positive and negative slope.
One thing you can try is using absolute values:
Build your own fitting (ie least square is easy = polyfit) and dont use polynomial
Functions, but absolute functions thereof.
Least sqare: take 0 = d/da ( sum( func-point)^2 ) and this for each order.. Wikipedia and others provide in depth descriptions.