I used the Matlab command polyfit to interpolate a curve. I then wanted to calculate the y-max value of that curve. I have found the roots for the polynomial, so i now have an x-value I want to insert in the polynomial from polyfit to get the y-value for that x-value.
I have difficulties to get it working properly.
P is the polynomial, so as you know, P(1)^4, P(2)^3... and so on
P = [-1.99405270507682e+26 5.55362828633395e+24 -5.80027044841956e+22 2.69238494640005e+20 -4.68659390860982e+17]
The x-value I want to insert to get a y-value is
x = 7.765633479578490e-04
The y-value should be about 17.7.
Am I thinking right here? The x-value is correct, I have compared it to my plot.
Thanks in advance guys!
Something is wrong in your calculations. With the values you give in your question, P(x) is enormous due to the enormous polynomial coefficients you have:
P =
-1.9941e+026 5.5536e+024 -5.8003e+022 2.6924e+020 -4.6866e+017
>> x = 7.765633479578490e-04
x = 7.7656e-004
>> y = polyval(P,x)
y = -2.9203e+017
These are the roots of your polynomial, they have very small imaginary parts, but given the enormous coefficients of the polynomial, they cannot be neglected:
>> format long g
>> roots(P)
ans =
0.00696463336211033 + 9.88579484856405e-07i
0.00696463336211033 - 9.88579484856405e-07i
0.00696084682252702 + 1.06977927834625e-06i
0.00696084682252702 - 1.06977927834625e-06i
Related
I would like to plot the roots of the cubic equation x^{3}+Ax^{2}+1=0 in matlab. I know that there are 3 real roots for A<-1.88 and 1 if A>-1.88. I would like to plot the 3 real roots as a function of A and when it switches to 1 real root and 2 complex to plot the real root and the real part of the complex conjugate solutions all in the same plot (perhaps as 2-3 graphs).
I am a matlab beginner though. I tried
syms x A
r = solve(x^3 + A*x^2+1 == 0, x);
ezplot(vpa(r(1)),[-10,10])
ezplot(vpa(r(2)),[-10,10])
ezplot(vpa(r(3)),[-10,10])
but vpa doesnt know how to numerically evaluate r.
There's no need to do symbolic math for this,
A = (-3:0.01:0)'; % create a vector of values for A
r = arrayfun(#(A)real(roots([1 A 0 1])),A,'uni',false); % calculate the polynomial roots for all values of A
r = [r{:}]; % convert result to a numeric array
plot(A,r'); % plot the result
grid on;
title('Real parts of Polynomial');
xlabel('A');
I'm trying to find the line which best fits to the data. I use the following code below but now I want to have the data placed into an array sorted so it has the data which is closest to the line first how can I do this? Also is polyfit the correct function to use for this?
x=[1,2,2.5,4,5];
y=[1,-1,-.9,-2,1.5];
n=1;
p = polyfit(x,y,n)
f = polyval(p,x);
plot(x,y,'o',x,f,'-')
PS: I'm using Octave 4.0 which is similar to Matlab
You can first compute the error between the real value y and the predicted value f
err = abs(y-f);
Then sort the error vector
[val, idx] = sort(err);
And use the sorted indexes to have your y values sorted
y2 = y(idx);
Now y2 has the same values as y but the ones closer to the fitting value first.
Do the same for x to compute x2 so you have a correspondence between x2 and y2
x2 = x(idx);
Sembei Norimaki did a good job of explaining your primary question, so I will look at your secondary question = is polyfit the right function?
The best fit line is defined as the line that has a mean error of zero.
If it must be a "line" we could use polyfit, which will fit a polynomial. Of course, a "line" can be defined as first degree polynomial, but first degree polynomials have some properties that make it easy to deal with. The first order polynomial (or linear) equation you are looking for should come in this form:
y = mx + b
where y is your dependent variable and X is your independent variable. So the challenge is this: find the m and b such that the modeled y is as close to the actual y as possible. As it turns out, the error associated with a linear fit is convex, meaning it has one minimum value. In order to calculate this minimum value, it is simplest to combine the bias and the x vectors as follows:
Xcombined = [x.' ones(length(x),1)];
then utilized the normal equation, derived from the minimization of error
beta = inv(Xcombined.'*Xcombined)*(Xcombined.')*(y.')
great, now our line is defined as Y = Xcombined*beta. to draw a line, simply sample from some range of x and add the b term
Xplot = [[0:.1:5].' ones(length([0:.1:5].'),1)];
Yplot = Xplot*beta;
plot(Xplot, Yplot);
So why does polyfit work so poorly? well, I cant say for sure, but my hypothesis is that you need to transpose your x and y matrixies. I would guess that that would give you a much more reasonable line.
x = x.';
y = y.';
then try
p = polyfit(x,y,n)
I hope this helps. A wise man once told me (and as I learn every day), don't trust an algorithm you do not understand!
Here's some test code that may help someone else dealing with linear regression and least squares
%https://youtu.be/m8FDX1nALSE matlab code
%https://youtu.be/1C3olrs1CUw good video to work out by hand if you want to test
function [a0 a1] = rtlinreg(x,y)
x=x(:);
y=y(:);
n=length(x);
a1 = (n*sum(x.*y) - sum(x)*sum(y))/(n*sum(x.^2) - (sum(x))^2); %a1 this is the slope of linear model
a0 = mean(y) - a1*mean(x); %a0 is the y-intercept
end
x=[65,65,62,67,69,65,61,67]'
y=[105,125,110,120,140,135,95,130]'
[a0 a1] = rtlinreg(x,y); %a1 is the slope of linear model, a0 is the y-intercept
x_model =min(x):.001:max(x);
y_model = a0 + a1.*x_model; %y=-186.47 +4.70x
plot(x,y,'x',x_model,y_model)
Assume we want to determine the coefficients of a polynomial equation that is approximating the tangent function between 0 to 1, as follow:
-A is m×n vandermonde matrix. The entries are populated using m value between 0 to 11(given as input).
-The corresponding vector b is calculated using tangent function.
-x is calculated by typing x= A\b in MATLAB.
Now, using MATLAB, the computed x are subsittued in Ax. The result is plotted and it is pretty close to tangent function. But if I use polyval function of n−1 degree (in MATLAB) to calculate b, the resulting plot is significantly different from the original b. I cannot understand the reason for such a significant difference between the results of these two methods.
Here is the code:
clear all;
format long;
m = 60;
n = 11;
t = linspace(0,1,m);
A= fliplr(vander(t));
A=A(:,1:n);
b=tan(t');
x= A\b;
y=polyval(x, t);
plot(t,y,'r')
y2= A*x
hold on;
plot(t,y2,'g.');
hold on;
plot(t,tan(t),'--b');
Any insight would be appreciated. Thank you.
After A= fliplr(vander(t)) the A matrix is equal to
1 t(1) t(1)^2 ...
1 t(2) t(2)^2 ...
...
1 t(m) t(m)^2 ...
It is not correct because polyval accepts the coefficients in descending powers. You don't need to flip the columns of A:
A= vander(t);
A= A(:,end-n+1:end);
I have
x = linspace(-5,5,256)
y = 1./(1+x.^2)
plot(x,y,'...') %plot of (x,y)
I want to estimate this with a polynomial of order 10, such that the polynomial intersects the graph at 11 points.
So, I did this:
x2 = linspace(-5,5,11)
y2 = 1./(1+x2.^2)
p = polyfit(x2,y2,10) %finds coefficients of polynomial of degree 10 that fits x2,y2
y3 = polyval(p,x2)
plot(x,y,x2,y3,'...')
I thought the polyfit would give me the coefficients for a polynomial up to order 10, which intersects the points (x2,y2) (i.e 11 points)
then y3 is essentially just the y values of where the 10th order polynomial lands, so plotting them altogether would give me the 10th order polynomial, intersecting my original graph at 11 unique points?
What have I done wrong?
My result:
Your computations are correct, but you are not plotting the function the right way. The blue line in your generated plot is piecewise linear. That's because you are only evaluating your polynomial p at the interpolation points x2. The plot command then draws line segments between those points and you are presented with your unexpected plot.
To get the expected result you simply have to evaluate your polynomial more densely like so:
x3 = linspace(-5,-5,500);
y3 = polyval(p,x3);
plot(x3,y3);
Consider the points (1,3), (2,6.2) and (3,13.5). Use Matlab's builtin function polyfit to obtain the best parameters for fitting the model P = Poekt to this data
I need to draw an elliptic curve over the finite field F17(in other words, I want to draw some specific dots on the curve), but somehow I don't get it right.
The curve is defined by the equation:
y^2 = x^3 +x + 1 (mod 17)
I tried the way below, but it can't work.
for x = 0:16, plot(x, mod(sqrt(x^3+x+1), 16),'r')', end
Can someone help ?
[Update]
According to Nathan and Bill's suggestions, here is a slightly modified version.
x = 0:18
plot(mod(x,16), mod(sqrt(x.^3+x+1), 16),'ro')
However, I feel the figure is WRONG , e.g.,y is not an integer when x=4 .
You have to test all points that fulfill the equation y^2 = x^3 +x + 1 (mod 17). Since it is a finite field, you cannot simply take the square root on the right side.
This is how I would go about it:
a=0:16 %all points of your finite field
left_side = mod(a.^2,17) %left side of the equation
right_side = mod(a.^3+a+1,17) %right side of the equation
points = [];
%testing if left and right side are the same
%(you could probably do something nicer here)
for i = 1:length(right_side)
I = find(left_side == right_side(i));
for j=1:length(I)
points = [points;a(i),a(I(j))];
end
end
plot(points(:,1),points(:,2),'ro')
set(gca,'XTick',0:1:16)
set(gca,'YTick',0:1:16)
grid on;
Matlab works with vectors natively.
your syntax was close, but needs to be vectorized:
x = 0:16
plot(x, mod(sqrt(x.^3+x+1), 16),'r')
Note the . in x.^3. This tells Matlab to cube each element of x individually, as opposed to raising the vector x to the 3rd power, which doesn't mean anything.
You can use this code if you want to plot on Real numbers:
syms x y;
v=y^2-x^3-x-1;
ezplot(v, [-1,3,-5,5]);
But, for plot in modulo, at first you can write below code;
X=[]; for x=[0:16], z=[x; mod(x^3+x+1,17)]; X=[X, z]; end, X,
Then, you can plot X with a coordinate matrix.