How to find the x-intercept of a plot in Matlab - matlab

I know there must be a really simple answer to this question, but I just can't seem to find it. (Guess I'm probably Googling the wrong terms.)
I am plotting some data in Matlab using the plot(x, data) function.
I want to find the x-intercept(s) of the line, i.e. the point(s) where y = 0.
In some cases, it may be that the data vector doesn't actually contain values equal to zero, so it's not just a matter of finding the indexes of the elements in data which are equal to zero, and then finding the corresponding elements in the x vector.
Like I said, it's a really simple problem and I'd think there's already some in-built function in Matlab...
Thank you for your help.

If you want to find X-intercept as interpolate between 2 closest points around X axes you can use INTERP1 function:
x0 = interp1(y,x,0);
It will work if x and y are monotonically increasing/decreasing.

x=-1.999:0.001:1.999;
y=(x-1).*(x+1);
plot(x,y)
hold on
plot(x,zeros(length(x),1),'--r')
find(abs(y)<1e-3)
So the last part will guarantee that even there is not exact y-intercept, you will still get a close value. The result of this code are the indices that satisfy the condition.

You can make a linear fit (1st order polynomial) to your data, then, from the slope and Y intercept of the fitted line, you'll be able to find X intercept. Here is an example:
x1 = 1:10;
y1 = x1 + randn(1,10);
P = polyfit(x1,y1,1);
xint = -P(2)/P(1);
if you want to know what is the slope and y_int, here it is:
Slope = P(1); % if needed
yint = P(2); % if need

Related

Limits of the Waterfall function ... or not?

I have a problem to figure out how in a waterfall figure the x axis can correspond to the x values, and not their point number. This question seems rather simple but in my particular case (due to the size of vectors) it's not easy to get the correct figure. So i really need your help ... after several hours of unsatisfied results.
Assuming that two vectors x and y of the same length are recorded at a time t. This procedure is performed k times. I finally want to plot with waterfall y versus x for the different times.
I give you a script that corresponds to the experiment where xx is just added to get here two continuous functions x and y for the different times. The result is almost perfect but I would like the x-y values on the corresponding x, y axis instead of the point number.
xx=0:0.1:8;
for t=1:2:11
x(t,:)=sin(t*xx.^2);
y(t,:)=cos(t*xx.*4);
end
waterfall(x,y)
The problem comes probably from the different size of x, y with t. Thanks in advance for your advice.
Two comments:
waterfall takes either Z or X,Y,Z as coordinates. So it takes your x matrix as Z, and the other argument is mapped to the C input, which dictates color. You can see that the plot is the same if you do waterfall(x), except with different colors.
Your x is not monotonically increasing, so if you plot x(t,:) vs y(t,:) for any t, you'll get a web-like graph, not anything nice to look at.
So I'll plot xx vs y, and I'm modifying your y a bit so it looks nicer. I hope you can take this idea and modify it to do what you need.
The code below doesn't use waterfall at all, it simply calls plot3 once for each t. It might be possible to call plot3 with your full x and y matrices, but this is just as easy.
In the plot3 call, the x-coordinates are given by xx, the y-coordinates by t (simply repeated to match the expected size), and the z-coordinates by y:
xx = 0:0.1:8;
for t = 1:2:11
y = cos(t*xx/4);
plot3(xx,repmat(t,size(xx)),y)
hold on
end
xlabel('x')
ylabel('t')
zlabel('y=cos(tx/4)')

How to order one dimensional matrices base on values

I want to determine a point in space by geometry and I have math computations that gives me several theta values. After evaluating the theta values, I could get N 1 x 3 dimension matrix where N is the number of theta evaluated. Since I have my targeted point, I only need to decide which of the matrices is closest to the target with adequate focus on the three coordinates (x,y,z).
Take a view of the analysis in the figure below:
Fig 1: Determining Closest Point with all points having minimal error
It can easily be seen that the third matrix is closest using sum(abs(Matrix[x,y,z])). However, if the method is applied on another figure given below, obviously, the result is wrong.
Fig 2: One Point has closest values with 2-axes of the reference point
Looking at point B, it is closer to the reference point on y-,z- axes but just that it strayed greatly on x-axis.
So how can I evaluate the matrices and select the closest one to point of reference and adequate emphasis will be on error differences in all coordinates (x,y,z)?
If your results is in terms of (x,y,z), why don't evaluate the euclidean distance of each matrix you have obtained from the reference point?
Sort of matlab code:
Ref_point = [48.98, 20.56, -1.44];
Curr_point = [x,y,z];
Xd = (x-Ref_point(1))^2 ;
Yd = (y-Ref_point(2))^2 ;
Zd = (z-Ref_point(3))^2 ;
distance = sqrt(Xd + Yd + Zd);
%find the minimum distance

MATLAB: mean(X(Y == y, :));

Looking over some MATLAB code related to multivariate Gaussian distributions and I come across this line:
params.means(k, :) = mean(X(Y == y, :));
Looking at the MATLAB documentation http://www.mathworks.com/help/matlab/ref/mean.html, my assumption is that it calculates the mean over the matrix X in the first dimension (the column). What I don't see is the parentheses that comes after. Is this a conditional probability (where Y = y)? Can someone point me to some documentation where this is explained?
Unpacked, this single line might look like:
row_indices = find(Y==y);
new_X = X(row_indices,:);
params.means(k,:) = mean(new_X);
So, as you can see, the Y==y is simply being used to find a subset of X over which the mean is taken.
Given that you said that this was for computing multivariate Gaussian distributions, I bet that X and Y are paired sets of data. I bet that the code is looping (using the variable k) over different values y. So, it finds all of the Y equal to y and then calculates the mean of the X values that correspond to those Y values.

Assume that x, y, and z are Matlab arrays, plot the function e^(-x)sin(x) across the interval [0. 4pi]

x=linspace(0, 2*pi, 100);
y=sin(x);
z=exp(-x);
Given that x, y, and z are already initialized, how do I write a function that plots exp(-x)sin(x) across the interval [0, 4pi] without additional calls to sin or exp? Just need some help getting started.
Thanks to #Rayryeng for getting me started. I believe the following command more closely satisfies the question's specifications.
plot(x+x, z.*z.*y)
Well, you've already created arrays for sin and exp stored in y and z respectively. These arrays were created on the same domain as x. You just need to multiply both arrays together element-wise and plot the graph. It's as simple as doing:
plot(x, z.*y);
Here, .* stands for element-wise multiplication. If you were to do z*y, MATLAB interprets this as matrix multiplication where z and y are interpreted to be matrices. This is obviously not what you want.
However, your array of x only contains points from 0 to 2*pi. If you want to plot this from 0 to 4*pi, you have to modify your call to linspace:
x=linspace(0, 4*pi, 100); %// Change
y=sin(x);
z=exp(-x);
plot(x, z.*y);
Now, x will contain 100 points between 0 to 4*pi. For more information on basic MATLAB operations, check out this link: http://www.mathworks.com/help/matlab/matlab_prog/array-vs-matrix-operations.html. What you have asked falls into the basic realms of array and matrix operations.
Edit
In the spirit of your question, we can't modify linspace. You did something clever where we can simply scale our values of x by 2 or adding with x so that we have points going from 0 to 2*pi to 0 to 4*pi. Also, if we scale our points by 2, this means that our input argument into the function must also be scaled by 2. So, the final function we need to plot is:
y = exp(-2x)*sin(2x)
Noting your hint, exp(-2x) = exp(-x-x) = exp(-x)exp(-x). Further, note that sin(2x) performs a compression by a factor of 2 (tip of the hat goes to knedlsepp for noticing my blunder). Due to the periodic nature of sin(x), we know that elements will repeat after 2*pi, and so if you want to go to 4*pi, simply subsample y by a factor of 2 and then append these same elements to a new vector. Therefore, our expression for the function simplifies to:
y = exp(-x)exp(-x)sin(2x)
This leads to the answer alluded to knedlsepp:
plot(x+x, z.*z.*[y(1:2:end) y(1:2:end)]);
As such, you should consider changing your edits to match this answer instead. It isn't quite right with respect to the sin(x) part in your code.

Outline your hand with splines (Matlab)

I'm trying to write a script so that one can put his hand on the screen, click a few points with ginput, and have matlab generate an outline of the persons hand using splines. However, I'm quite unsure how you can have splines connect points that result from your clicks, as they of course are described by some sort of parametrization. How can you use the spline command built into matlab when the points aren't supposed to be connected 'from left to right'?
The code I have so far is not much, it just makes a box and lets you click some points
FigHandle = figure('Position', [15,15, 1500, 1500]);
rectangle('Position',[0,0,40,40])
daspect([1,1,1])
[x,y] = ginput;
So I suppose my question is really what to do with x and y so that you can spline them in such a way that they are connected 'chronologically'. (And, in the end, connecting the last one to the first one)
look into function cscvn
curve = cscvn(points)
returns a parametric variational, or natural, cubic spline curve (in ppform) passing through the given sequence points(:j), j = 1:end.
An excellent example here:
http://www.mathworks.com/help/curvefit/examples/constructing-spline-curves-in-2d-and-3d.html
I've found an alternative for using the cscvn function.
Using a semi-arclength parametrisation, I can create the spline from the arrays x and y as follows:
diffx = diff(x);
diffy = diff(y);
t = zeros(1,length(x)-1);
for n = 1:length(x)-1
t(n+1) = t(n) + sqrt(diffx(n).^2+diffy(n).^2);
end
tj = linspace(t(1),t(end),300);
xj = interp1(t,x,tj,'spline');
yj = interp1(t,y,tj,'spline');
plot(x,y,'b.',xj,yj,'r-')
This creates pretty decent outlines.
What this does is use the fact that a curve in the plane can be approximated by connecting a finite number of points on the curve using line segments to create a polygonal path. Using this we can parametrize the points (x,y) in terms of t. As we only have a few points to create t from, we create more by adding linearly spaced points in between. Using the function interp1, we then find the intermediate values of x and y that correspond to these linearly spaced t, ti.
Here is an example of how to do it using linear interpolation: Interpolating trajectory from unsorted array of 2D points where order matters. This should get you to the same result as plot(x,y).
The idea in that post is to loop through each consecutive pair of points and interpolate between just those points. You might be able to adapt this to work with splines, you need to give it 4 points each time though which could cause problems since they could double back.
To connect the start and end though just do this before interpolating:
x(end+1) = x(1);
y(end+1) = y(1);