Matlab - Intersection points x-axis with line made with polyval - matlab

I used polyfit to find the best fit through my X and Y data.
p = polyfit(x,y,4)
After that I used polyval to make a line with the polyfit with other X data
a = [-5 : 0.1 : 15]
line = polyval(p,a)
When I plot this line and when I look at the data, I see that it has intersections with the x-axis. But there is not an exact y=0
My question is, how do I find the (there are 2) intersection points with the x-axis, or atleast the x where y is the closest to 0?
Thanks in advance!

First, don't use line as a variable name, it is a MATLAB function you are shadowing and won't be able to access.
p = polyfit(x,y,4);
a = [-5 : 0.1 : 15];
b = polyval(p,a);
To get the intersection with the x axis, you are essentially looking for the roots of the polynomial, i.e. when y=0 and there is a function just for that:
r = roots(p);

Related

Helix in Matlab

I am working to create a helix in Matlab.
Going by the below code:
t = 0:pi/50:20*pi;
(Can you please explain me this syntax or we have to follow this everytime when creating a helix?)
st = sin(t);
ct = cos(t);
plot3(st,ct,t)
As maximum efficiency in a helix angle is between 40 and 45 degrees, if I want to enter the angle as 42, how is it possible in the code?
It would be very helpful if anyone can share their opinion on this
TIA
What happens in the code is merely an execution of the parametric mathematical description of a helix, which you can read up on wikipedia as
x(t) = cos(t)
y(t) = sin(t)
z(t) = t
The first line of your code generates a vector for values of t from 0 to 20pi in steps of pi/50 (i.e., 1000 steps). Since every 2pi means one full rotation (cos and sin are 2pi-periodic), it coincides to 10 turns of the helix (if you want to change this, let t run up to 2*pi*NumberOfRotations). The other two lines generate corresponding vectors for x and y. plot3 plots a line in 3-D where x and y are passed and as argument for z we pass t since z=t.
To change the slope of the helix, use the more general description given by
x(t) = a*cos(t)
y(t) = a*sin(t)
z(t) = b*t
where a is the radius and b/a is the slope. To get 42° use b = a*atand(42). To make sure the aspect ratio is correct in display, use axis equal; after the plot and maybe axis vis3d; if you want to turn it around.

How to find the intersection of two ellipses in MATLAB

I have two equations:
ellipseOne = '((x-1)^2)/6^2 + y^2/3^2 = 1';
and
ellipseTwo = '((x+2)^2)/2^2 + ((y-5)^2)/4^2 = 1';
and I plotted them:
ezplot(ellipseOne, [-10, 10, -10, 10])
hold on
ezplot(ellipseTwo, [-10, 10, -10, 10])
title('Ellipses')
hold off
Now I'm trying to find the intersection of the two ellipses. I tried:
intersection = solve(ellipseOne, ellipseTwo)
intersection.x
intersection.y
to find the points where they intersect, but MATLAB is giving me a matrix and an equation as an answer which I don't understand. Could anyone point me in the right direction to get the coordinates of intersection?
The solution is in symbolic form. The last step you need to take is to transform it into numeric. Simply convert the result using double. However, because this is a pair of quadratic equations, there are 4 possible solutions due to the sign ambiguity (i.e. +/-) and can possibly give imaginary roots. Therefore, isolate out the real solutions and what is left should be your answer.
Therefore:
% Your code
ellipseOne = '((x-1)^2)/6^2 + y^2/3^2 = 1';
ellipseTwo = '((x+2)^2)/2^2 + ((y-5)^2)/4^2 = 1';
intersection = solve(ellipseOne, ellipseTwo);
% Find the points of intersection
X = double(intersection.x);
Y = double(intersection.y);
mask = ~any(imag(X), 2) | ~any(imag(Y), 2);
X = X(mask); Y = Y(mask);
The first three lines of code are what you did. The next four lines extract out the roots in numeric form, then I create a logical mask that isolates out only the points that are real. This looks at the imaginary portion of both the X and Y coordinate of all of the roots and if there is such a component for any of the roots, we want to eliminate those. We finally remove the roots that are imaginary and we should be left with two real roots.
We thus get for our intersection points:
>> disp([X Y])
-3.3574 2.0623
-0.2886 2.9300
The first column is the X coordinate and the second column is the Y coordinate. This also seems to agree with the plot. I'll take your ellipse plotting code and also insert the intersection points as blue dots using the above solution:
ezplot(ellipseOne, [-10, 10, -10, 10])
hold on
ezplot(ellipseTwo, [-10, 10, -10, 10])
% New - place intersection points
plot(X, Y, 'b.');
title('Ellipses');
hold off;

Draw a line with non-Cartesian coordinates in MATLAB

MATLAB's surf command allows you to pass it optional X and Y data that specify non-cartesian x-y components. (they essentially change the basis vectors). I desire to pass similar arguments to a function that will draw a line.
How do I plot a line using a non-cartesian coordinate system?
My apologies if my terminology is a little off. This still might technically be a cartesian space but it wouldn't be square in the sense that one unit in the x-direction is orthogonal to one unit in the y-direction. If you can correct my terminology, I would really appreciate it!
EDIT:
Below better demonstrates what I mean:
The commands:
datA=1:10;
datB=1:10;
X=cosd(8*datA)'*datB;
Y=datA'*log10(datB*3);
Z=ones(size(datA'))*cosd(datB);
XX=X./(1+Z);
YY=Y./(1+Z);
surf(XX,YY,eye(10)); view([0 0 1])
produces the following graph:
Here, the X and Y dimensions are not orthogonal nor equi-spaced. One unit in x could correspond to 5 cm in the x direction but the next one unit in x could correspond to 2 cm in the x direction + 1 cm in the y direction. I desire to replicate this functionality but drawing a line instead of a surf For instance, I'm looking for a function where:
straightLine=[(1:10)' (1:10)'];
my_line(XX,YY,straightLine(:,1),straightLine(:,2))
would produce a line that traced the red squares on the surf graph.
I'm still not certain of what your input data are about, and what you want to plot. However, from how you want to plot it, I can help.
When you call
surf(XX,YY,eye(10)); view([0 0 1]);
and want to get only the "red parts", i.e. the maxima of the function, you are essentially selecting a subset of the XX, YY matrices using the diagonal matrix as indicator. So you could select those points manually, and use plot to plot them as a line:
Xplot = diag(XX);
Yplot = diag(YY);
plot(Xplot,Yplot,'r.-');
The call to diag(XX) will take the diagonal elements of the matrix XX, which is exactly where you'll get the red patches when you use surf with the z data according to eye().
Result:
Also, if you're just trying to do what your example states, then there's no need to use matrices just to take out the diagonal eventually. Here's the same result, using elementwise operations on your input vectors:
datA = 1:10;
datB = 1:10;
X2 = cosd(8*datA).*datB;
Y2 = datA.*log10(datB*3);
Z2 = cosd(datB);
XX2 = X2./(1+Z2);
YY2 = Y2./(1+Z2);
plot(Xplot,Yplot,'rs-',XX2,YY2,'bo--','linewidth',2,'markersize',10);
legend('original','vector')
Result:
Matlab has many built-in function to assist you.
In 2D the easiest way to do this is polar that allows you to make a graph using theta and rho vectors:
theta = linspace(0,2*pi,100);
r = sin(2*theta);
figure(1)
polar(theta, r), grid on
So, you would get this.
There also is pol2cart function that would convert your data into x and y format:
[x,y] = pol2cart(theta,r);
figure(2)
plot(x, y), grid on
This would look slightly different
Then, if we extend this to 3D, you are only left with plot3. So, If you have data like:
theta = linspace(0,10*pi,500);
r = ones(size(theta));
z = linspace(-10,10,500);
you need to use pol2cart with 3 arguments to produce this:
[x,y,z] = pol2cart(theta,r,z);
figure(3)
plot3(x,y,z),grid on
Finally, if you have spherical data, you have sph2cart:
theta = linspace(0,2*pi,100);
phi = linspace(-pi/2,pi/2,100);
rho = sin(2*theta - phi);
[x,y,z] = sph2cart(theta, phi, rho);
figure(4)
plot3(x,y,z),grid on
view([-150 70])
That would look this way

Polyfit and polyval to perform interpolation

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

Intersection point of two independet lines in MATLAB

I am writing a code to find the intersection point value of two independent lines , but I am confused that how to obtain the value of the intersection point , till now I have coded :
y = [2.63 8.12 13.01 21.87 35.19 58.49];
x = [200 400 500 600 800 1000];
plot(x,y)
hold on
plot([200, 1000], [10, 10]) % this [10, 10] is a straight line
hold off
I want to find the meeting point of plot(x,y) and Straight line , Can anyone give me hint for this Thanks :)
The x-coordinate at which the monotonically increasing piecewise linear curve plot(x,y) crosses v is given by:
interp1q(y,x,v);
Ok, this is the formula JakubT was assuming for:
yIntersect = 10;
dy = diff(y);
dx = diff(x);
i=find(diff(y > yIntersect));
xIntersect = x(i)+dx(i)*(yIntersect-y(i))/dy(i);
-->
xIntersect = 438.45
Of course this is not production code.
Not a very elegant solution, but you could, for each pair of consecutive elements of x and y (e.g., [8.12 13.01] and [400 500] being the second such pair), take the equation of the line passing through these two points, compute intersection with your crossing line (I assume that you have/can get the analytical formula for that one?) - and for each such pair of points, you check if the intersection actually happens between these two boundary points - if so, you have both the equation of the line passing through these two points as well as the equation of the crossing line, which yields the point of intersection.