repmat function in Matlab does not work consistently? - matlab

Matlab functions meshgrid and streamline are not matching. How to fix?
%% direction field plot
[x,y]=meshgrid(-4:.5:4,-4:.5:4);
dx = 2*x +1*y;
dy = 1*x +2*y;
dxu = dx./sqrt(dx.^2+dy.^2);
dyu = dy./sqrt(dx.^2+dy.^2);
quiver(x,y,dxu,dyu)
hold on
%% Trajectory Plot
startx = repmat([-4:.5:4], 0,2);
starty = ones(size(startx));
streamline(x,y,dxu, dyu, startx, starty)
dxu = dx./sqrt(dx.^2+dy.^2);
dyu = dy./sqrt(dx.^2+dy.^2);
print('c:\data\DirectionField','-dmeta')
saveas(gcf, 'c:\data\streamline.emf')
hold off
Error messages are given below:
Error using repmat!
Replication factors must be a row vector of integers or integer scalars.
This has occurred when I added 7 trajectory plots to the code. When using only two trajectories the error did not occur? What is happening here?
MM

Your startx and starty matrices are currently empty. The last two arguments of repmat should be the number of times you want to repeat the matrix in the vertical and horizontal directions respectively. Since your replication factors are 0 and 2, the result is an empty matrix. Use positive integers for the replication factors.
I'm not completely sure what you're trying to do, but if you want the quiver and streamline plots to be consistent, I think you should not be using repmat at all. Instead, I think you should just do:
streamline(x, y, dxu, dyu, x, y);
Updated after OP's comment:
If you want to want to plot trajectories from a specific set of starting points, use the code below where startxy is an m x 2 matrix containing the coordinates of m starting points.
startxy = [0,2;
1,-3;
2,1]; %e.g. 3 starting points
streamline(x,y,dxu, dyu, startxy(:,1), startxy(:,2));

Related

Matlab- Given matrix X with xi samples, y binary column vector, and a vector w plot all these into 3d graph

I have started to learn Machine Learning, and programming in matlab.
I want to plot a matrix sized m*d where d=3 and m are the number of points.
with y binary vector I'd like to color each point with blue/red.
and plot a plane which is described with the vertical vector to it w.
The problem I trying to solve is to give some kind of visual representation of the data and the linear predictor.
All I know is how to single points with plot3, but no any number of points.
Thanks.
Plot the points using scatter3()
scatter3(X(y,1),X(y,2),X(y,3),'filled','fillcolor','red');
hold on;
scatter3(X(~y,1),X(~y,2),X(~y,3),'filled','fillcolor','blue');
or using plot3()
plot(X(y,1),X(y,2),X(y,3),' o','MarkerEdgeColor','red','MarkerFaceColor','red');
hold on;
plot(X(~y,1),X(~y,2),X(~y,3),' o','MarkerEdgeColor','blue','MarkerFaceColor','blue');
There are a few ways to plot a plane. As long as w(3) isn't very close to 0 then the following will work okay. I'm assuming your plane is defined by x'*w+b=0 where b is a scalar and w and x are column vectors.
x1min = min(X(:,1)); x2min = min(X(:,2));
x1max = max(X(:,1)); x2max = max(X(:,2));
[x1,x2] = meshgrid(linspace(x1min,x1max,20), linspace(x2min, x2max, 20));
x3 = -(w(1)*x1 + w(2)*x2 + b)/w(3);
surf(x1,x2,x3,'FaceColor',[0.6,0.6,0.6],'FaceAlpha',0.7,'EdgeColor',[0.4,0.4,0.4],'EdgeAlpha',0.4);
xlabel('x_1'); ylabel('x_2'); zlabel('x_3'); axis('vis3d');
Resulting plot

Plotting a linear decision boundary

I have a set of data points (40 x 2), and I've derived the formula for the decision boundary which ends up like this :
wk*X + w0 = 0
wk is a 1 x 2 vector and X is a 2 x 1 point from the data point set; essentially X = (xi,yi), where i = 1,2,...,40. I have the values for wk and w0.
I'm trying to plot the line wk*X + w0 = 0 but I have no idea how to plot the actual line. In the past, I've done this by finding the minimum and maximum of the data points and just connecting them together but that's definitely not the right approach.
wk*X is simply the dot product between two vectors, and so the equation becomes:
w1*x + w2*y + w0 = 0
... assuming a general point (x,y). If we rearrange this equation and solve for y, we get:
y = -(w1/w2)*x - (w0/w2)
As such, this defines an equation of the line where the slope is -(w1/w2) with an intercept -(w0/w2). All you have to do is define a bunch of linearly spaced points within a certain range, take each point and substitute this into the above equation and get an output. You'd plot all of these output points in the figure as well as the actual points themselves. You make the space or resolution between points small enough so that we are visualizing a line when we connect all of the points together.
To determine the range or limits of this line, figure out what the smallest and largest x value is in your data, define a set of linearly spaced points between these and plot your line using the equation of the line we just talked about.
Something like this could work assuming that you have a matrix of points stored in X as you have mentioned, and w1 and w2 are defined in the vector wk and w0 is defined separately:
x = linspace(min(X(:,1)), max(X(:,1)));
y = -(wk(1)/wk(2))*x - (w0/wk(2));
plot(X(:,1), X(:,2), 'b.', x, y);
linspace determines a linearly spaced array of points from a beginning to an end, and by default 100 points are generated. We then create the output values of the line given these points and we plot the individual points in blue as well as the line itself on top of these points.

Dividing matlab plot into grids

I have two different functions of time x(t) and y(t). I want to plot x(t) vs y(t) in Matlab . The plot needs to be divided into a 40x40 grid stretching from min and max values of signal in each direction. I then need to calculate the number of grid boxes occupied in the plot. Please suggest a convenient way to implement this in Matlab.
I've tried the following code (neglect the upper and lower limits of axis):
NrGrid = 20; % Number Of Grids
x = linspace(0, 100, NrGrid+1);
[X,Y] = meshgrid(x);
figure(1)
plot(X,Y,'k')
hold on
plot(Y,X,'k')
hold off
set(gca, 'Box','off', 'XTick',[], 'YTick',[])
axis square
In my understanding, the code only divides the plot into grids. how do I count the number of grids that are occupied?
Reference: I basically need to implement the algorithm in this paper:
http://www.fhv.at/media/pdf/forschung/prozess-und-produktengineering/working-papers/working-papers-2005/detecting-ventricular
Sounds like you want to create a 40x40 matrix and then use a Bresenham line drawing algorithm to connect each of the points (after appropriate scaling) in x(t)/y(t) correspondence in that matrix.
You can then use nnz to count the number of non-zero elements in the matrix.
I managed to get a much simpler solution than the one mentioned by Dave Durbin by quantizing the signal into 40 levels and then comparing it with its shifted region. The code is attached for reference:
function TD=TimeDelay(val,fs)
n=40;
jump=( max(val) + abs(min(val)))/40;
level=zeros(n,1);
level(1)=min(val) + jump;
for i=2:n
level(i)=level(i-1)+jump;
end
level(n)=level(n)+1;
ScaledECG=zeros(size(val));
ScaledECG(val <= level(1))=1;
for j=2:n
ScaledECG( val<=level(j) & val>level(j-1))=j;
end
tau=fs*.5;
N=zeros(n,n);
for k=tau+1:1:length(val)
N(ScaledECG(k-tau),ScaledECG(k))=N(ScaledECG(k-tau),ScaledECG(k)) + 1;
end
N(N>5)=0;
N(N<=5)=1;
TD=sum(sum(N));

Sequential connecting points in 2D in Matlab

I was wondering if you could advise me how I can connect several points together exactly one after each other.
Assume:
data =
x y
------------------
591.2990 532.5188
597.8405 558.6672
600.0210 542.3244
606.5624 566.2938
612.0136 546.6825
616.3746 570.6519
617.4648 580.4575
619.6453 600.0688
629.4575 557.5777
630.5477 584.8156
630.5477 618.5906
639.2696 604.4269
643.6306 638.2019
646.9013 620.7697
652.3525 601.1584
"data" is coordinate of points.
Now, I would like to connect(plot) first point(1st array) to second point, second point to third point and so on.
Please mind that plot(data(:,1),data(:,2)) will give me the same result. However, I am looking for a loop which connect (plot) each pair of point per each loop.
For example:
data1=data;
figure
scatter(X,Y,'.')
hold on
for i=1:size(data,1)
[Liaa,Locbb] = ismember(data(i,:),data1,'rows');
data1(Locbb,:)=[];
[n,d] = knnsearch(data1,data(i,:),'k',1);
x=[data(i,1) data1(n,1)];
y=[data(i,2) data1(n,2)];
plot(x,y);
end
hold off
Although, the proposed loop looks fine, I want a kind of plot which each point connect to maximum 2 other points (as I said like plot(x,y))
Any help would be greatly appreciated!
Thanks for all of your helps, finally a solution is found:
n=1;
pt1=[data(n,1), data(n,2)];
figure
scatter(data(:,1),data(:,2))
hold on
for i=1:size(data,1)
if isempty(pt1)~=1
[Liaa,Locbb] = ismember(pt1(:)',data,'rows');
if Locbb~=0
data(Locbb,:)=[];
[n,d] = knnsearch(data,pt1(:)','k',1);
x=[pt1(1,1) data(n,1)];
y=[pt1(1,2) data(n,2)];
pt1=[data(n,1), data(n,2)];
plot(x,y);
end
end
end
hold off
BTW it is possible to delete the last longest line as it is not related to the question, if someone need it please let me know.
You don't need to use a loop at all. You can use interp1. Specify your x and y data points as control points. After, you can specify a finer set of points from the first x value to the last x value. You can specify a linear spline as this is what you want to accomplish if the behaviour you want is the same as plot. Assuming that data is a 2D matrix as you have shown above, without further ado:
%// Get the minimum and maximum x-values
xMin = min(data(:,1));
xMax = max(data(:,1));
N = 3000; % // Specify total number of points
%// Create an array of N points that linearly span from xMin to xMax
%// Make N larger for finer resolution
xPoints = linspace(xMin, xMax, N);
%//Use the data matrix as control points, then xPoints are the values
%//along the x-axis that will help us draw our lines. yPoints will be
%//the output on the y-axis
yPoints = interp1(data(:,1), data(:,2), xPoints, 'linear');
%// Plot the control points as well as the interpolated points
plot(data(:,1), data(:,2), 'rx', 'MarkerSize', 12);
hold on;
plot(xPoints, yPoints, 'b.');
Warning: You have two x values that map to 630.5477 but produce different y values. If you use interp1, this will give you an error, which is why I had to slightly perturb one of the values by a small amount to get this to work. This should hopefully not be the case when you start using your own data. This is the plot I get:
You'll see that there is a huge gap between those two points I talked about. This is the only limitation to interp1 as it assumes that the x values are strictly monotonically increasing. As such, you can't have the same two points in your set of x values.

MATLAB vectors, angles, plots

I apologize for the ambiguous title, but I am not entirely sure how to phrase this one. So bear with me.
I have a matrix of data. Each column and row represents a certain vector (column 1 = row 1, column 2 = row 2, etc.), and every cell value is the cosine similarity between the corresponding vectors. So every value in the matrix is a cosine.
There are a couple of things I want to do with this. First, I want to create a figure that shows all of the vectors on it. I know the cosine of the angle between every vector, and I know the magnitude of each vector, but that is the only information I have - is there some algorithm I can implement that will run through all of the various pair-wise angles and display it graphically? That is, I don't know where all the vectors are in relation to each other, and there are too many data points to do this by hand (e.g. if I only had three vectors, and the angles between them all were 45, 12, and 72 degrees it would be trivial). So how do I go about doing this? I don't even have the slightest idea what sort of mathematical function I would need to do this. (I have 83 vectors, so that's thousands of cosine values). So basically this figure (it could be either 2D or multidimensional, and to be honest I would like to do both) would show all of the vectors and how they relate to each other in space (so I could compare both angles and relative magnitudes).
The other thing I would like to do is simpler but I am having a hard time figuring it out. I can convert the cosine values into Cartesian coordinates and display them in a scatter plot. Is there a way to connect each of the points of a scatter plot to (0,0) on the plot?
Finally, in trying to figure out how to do some of the above on my own I have run into some inconsistencies. I calculated the mean angles and Cartesian coordinates for each of the 83 vectors. The math for this is easy, and I have checked and double-checked it. However, when I try to plot it, different plotting methods give me radically different things. So, if I plot the Cartesian coordinates as a scatter plot I get this:
If I plot the mean angles in a compass plot I get this:
And if I use a quiver plot I get something like this (I transformed this a little by shifting the origin up and to the right just so you can see it better):
Am I doing something wrong, or am I misunderstanding the plotting functions I am using? Because these results all seem pretty inconsistent. The mean angles on the compass plot are all <30 degrees or so, but on the quiver plot some seem to exceed 90 degrees, and on the scatter plot they extend above 30 as well. What's going on here?
(Here is my code:)
cosine = load('LSA.txt');
[rows,columns]=size(cosine);
p = cosine.^2;
pp = bsxfun(#minus, 1, p);
sine = sqrt(pp);
tangent = sine./cosine;
Xx = zeros(rows,1);
Yy = zeros(rows,1);
for i = 1:columns
x = cosine(:,i);
y = sine(:,i);
Xx(i,1) = sum(x) * (1/columns);
Yy(i,1) = sum(y) * (1/columns);
end
scatter(Xx,Yy);
Rr = zeros(rows,1);
Uu = zeros(rows,1);
for j = 1:rows
Rr(j,1) = sqrt(Xx(j,1).^2 + Yy(j,1).^2);
Uu(j,1) = atan2(Xx(j,1),Yy(j,2));
end
%COMPASS PLOT
[theta,rho] = pol2cart(Uu,1);
compass(theta,rho);
%QUIVER PLOT
r = 7;
sx = ones(size(cosine))*2; sy = ones(size(cosine))*2;
pu = r * cosine;
pv = r * sine;
h = quiver(sx,sy,pu,pv);
set(gca, 'XLim', [1 10], 'YLim', [1 10]);
You can exactly solve this problem. The dot product calculates the cosine. This means your matrix is actually M=V'*V
This should be solvable through eigenvalues. And you said you also have the length.
Your only problem - as your original matrix the vectors will be 83 dimensional. Not easy to plot in 2 or 3 dimensions. I think you are over simplifying by just using the average angle. There are some techniques called dimensionality reduction - here's a toolbox. I would suggest a sammon projection on 1-cosine (as this would be the distance of points on the unit ball) to calculate the vectors for such a plot.
In the quiver plot, you are plotting all of the data in the cosine and sine matrices. In the other plots, you are only plotting the means. The first two plots appear to match up, so no problem there.
A few other things. I notice that in
Uu(j,1) = atan2(Xx(j,1),Yy(j,2));
Yy(j,2) is not actually defined, so it seems like this code should fail.
Furthermore, you could define Yy and Xx as:
Xx = mean(cosine,2);
Yy = mean(sine,2);
And also get rid of the other for loop:
Rr = sqrt(Xx.^2 + Yy.^2)
Uu = atan2(Xx,Yy)
I still have to think about your first question, but I hope this was helpful.