Count occurrences and stretch array in matlab - matlab

Let
input = [0 0 0 5 5 7 8 8];
I now want to transform this vector into the form
output = [3 3 3 3 5 5 6 8];
Which basically is a stairs plot.
Explanation
The input vector is used to plot data points along the x-axis. The y-axis is thereby provided by 1:length(input). So the resulting plot shows the cumulative number of datapoints along the y-axis and the time of occurrence along the x-axis.
I now want to fit a model against my dataset. Therefor I need a vector that provides the correct value for a certain time (x-value).
The desired output vector basically is the result of a stairs plot. I am looking for an efficient way to generate the desired vector in matlab. The result of
[x, y] = stairs(input, 1:length(input));
did not bring me any closer.

It can be done with bsfxun as follows:
x = [0 0 0 5 5 7 8 8];
y = sum(bsxfun(#le, x(:), min(x):max(x)), 1);
This counts, for each element in 1:numel(x), how many elements of x are less than or equal to that.

Related

How to plot all the matrix elements in matlab whitout knowing the size?

Lets say there is the next matrix
A = [ 1 2 2 ;
1 2 3 ;
2 3 4 ;
3 4 5 ;
4 4 6 ;
1 11 12]
I try to use quiver3 to plot the row in the next way:
quiver3(0,0,0,A(1:1),A(1:2),A(1:3),0);
quiver3(0,0,0,A(2:1),A(2:2),A(2:3),0);
quiver3(0,0,0,A(3:1),A(3:2),A(3:3),0);
and so on until the last row, but how can apply quiver3 for each row of the matrix instead of making one line per row?
Besides, isn't the same size of matrix always, so making one one command per row would yield some rows without plotting sometimes and perhaps not enough rows to plot other .
(Example: the matrix provided has 6 rows so I make 6 quiver3 expressions, but later if the matrix has only 3 rows, it gives me an error and if later it has 8 rows, there would be 2 vectors/row that aren't plotted).
Im guessing that it has to do with the range and meshgrid operator but I can not see how.
If your matrix A has N rows, where each row stores the [u v w] components to pass to quiver3, then you can plot all N arrows in one call to quiver3, provided you ensure all of your input arguments are the same size. If you are plotting all of them starting from the origin, then you have to create an N-by-1 vector of zeroes to use for your x, y, and z inputs:
A = [1 2 2;
1 2 3;
2 3 4;
3 4 5;
4 4 6;
1 11 12];
z = zeros(size(A, 1), 1);
quiver3(z, z, z, A(:, 1), A(:, 2), A(:, 3), 0);
Note the indexing syntax I used to split A up into columns to pass to quiver3. And here's the resulting plot for the given sample data:

Angles between n vectors - Matlab

Consider a set of points (just an example)
x = [0 1 2 5 4 8 5 6];
y = [5 8 4 2 5 6 4 5];
and another reference point:
xc=1;
yc=1;
In which I use to represent these points as vectors:
vec=[x-xc y-yc];
I wish to obtain a matrix with all the angles between all vectors which is obtained by the calculation (for single vectors)
angle = acosd(dot(v,u)/norm(u)*norm(v));
How can I obtain this calculation in a few lines without going vector by vector in a loop? In my calculation the number of points is very very large.
I think you mean vec = [x-xc; y-yc];. To calucate the dotproduct between all rows, you can use
vec.'*vec
The norm (Euclidean) of each vector can be determined as
no = sqrt(sum(vec.*vec,1))
The product of the different norms can be calculated the same as for vec:
no.'*no
The angles can thus be found as
no = sqrt(sum(vec.*vec,1));
angles = acosd(vec.'*vec./(no.'*no));

drow cumulative distribution function in matlab

I have two vectors of the same size. The first one can have any different numbers with any order, the second one is decreasing (but can have the same elements) and consists of only positive integers. For example:
a = [7 8 13 6];
b = [5 2 2 1];
I would like to plot them in the following way: on the x axis I have points from a vector and on the y axis I have the sum of elements from vector b before this points divided by the sum(b). Therefore I will have points:
(7; 0.5) - 0.5 = 5/(5+2+2+1)
(8; 0.7) - 0.7 = (5+2)/(5+2+2+1)
(13; 0.9) ...
(6; 1) ...
I assume that this explanation might not help, so I included the image
Because this looks to me as a cumulative distribution function, I tried to find luck with cdfplot but with no success.
I have another option is to draw the image by plotting each line segment separately, but I hope that there is a better way of doing this.
I find the values on the x axis a little confusing. Leaving that aside for the moment, I think this does what you want:
b = [5 2 2 1];
stairs(cumsum(b)/sum(b));
set(gca,'Ylim',[0 1])
And if you really need those values on the x axis, simply rename the ticks of that axis:
a = [7 8 13 6];
set(gca,'xtick',1:length(b),'xticklabel',a)
Also grid on will add grid to the plot

Generalize this matlab code for non-square matrices

I am working on some fourier transform code in matlab, and have come across the following:
xx = meshgrid(1:N);
% Center on DC
xx = xx - dcN;
% normalize dynamic range from -1 to 1
xx = xx./max(abs(xx(:)));
% form y coordinate from negative transpose of x coordinate (maintains symmetry about DC)
yy = -xx';
% compute the related radius of the x/y coordinates centered on DC
rr = sqrt(xx.^2 + yy.^2);
How can I generalize this for non-square matrices? This code is assuming my matrix is square, so dcN is the center of the square matrix (in other words, with 11x11, dcN = 6).
The math doesnt work out for that yy variable when the transpose is taken for a non-square matrix.
I have tried to figure out if I can make a meshgrid going from "top to bottom" instead of left to right - but I havent been able to figure taht out either.
Thanks
I have tried to figure out if I can
make a meshgrid going from "top to
bottom" instead of left to right - but
I havent been able to figure taht out
either.
>> N=5
N =
5
>> rot90(meshgrid(N:-1:1))
ans =
1 1 1 1 1
2 2 2 2 2
3 3 3 3 3
4 4 4 4 4
5 5 5 5 5
From your question I guess that you want to find rr, i.e. the distance of any element in the matrix from the center.
If you want this for a M-by-N array, you'd do the following
%# note that using meshgrid instead of ndgrid will swap xx and yy
[xx,yy] = ndgrid(-(M-1)/2:(M-1)/2,-(N-1)/2:(N-1)/2);
%# normalize to the max of xx,yy
nrm = max((M-1)/2,(N-1)/2);
xx = xx./nrm;
yy = yy./nrm;
rr = sqrt(xx.^2+yy.^2)

Need help in plotting lines between points

I need help in plotting lines between points.
Suppose, I start with creating 6 random points-
x = rand(6,1);
y = rand(6,1);
So my points are (x(1),y(1)), (x(2),y(2)), (x(3),y(3)), (x(4),y(4)), (x(5),y(5)), (x(6),y(6))
Now I want to draw straight lines between the points 1 & 5, 2 & 6, 3 & 4
and plot them in a single diagram. So I get 3 straight lines.
Any help would be highly appreciated.
You can do this with one call to PLOT. If you reshape your x and y data into matrices with each column containing a set of coordinates for one line, then PLOT will draw a different colored line for each column:
index = [1 2 3; 5 6 4]; %# The index to reshape x and y into 2-by-3 matrices
plot(x(index),y(index)); %# Plot the lines
Here are two ways to do this:
First way, using hold on. These lines are separate, i.e if you turn one red, the others will stay blue.
%# plot the first line
plot([x(1);x(5)],[y(1);y(5)]);
hold on %# this will prevent the previous plot from disappearing
%# plot the rest
plot([x(2);x(6)],[y(2);y(6)]);
plot([x(3);x(4)],[y(3);y(4)]);
Second way, making use of the fact that NaN does not get plotted. These lines are grouped, i.e. if you turn one red, all will be red.
%# create array for plotting
xy = NaN(8,2);
%# fill in data
xy([1 2 4 5 7 8],1) = x([1 5 2 6 3 4]);
xy([1 2 4 5 7 8],2) = y([1 5 2 6 3 4]);
%# plot
plot(xy(:,1),xy(:,2))