Plotting same elements of two row vectors of different sizes - matlab

Let us have
a=[1 2 3 4 5];
b=[4 2];
I want a plot of 'a' in which same elements(of a and b) get marked. I am trying but all in vain. My result should be plot of a with values 4 and 2 marked.
Please help.

a = [1 2 3 4 5];
x = 1:numel(a);
b = [2 4];
figure
plot(x, a);
hold on;
markIt = ismember(a, b);
plot(x(markIt), a(markIt), 's')
This produces a plot of a, with the elements that also belong to b (found with the ismember function) plotted (again) as a square (that's the 's' in the second plot command).
I am sure you can adapt this to your needs... Sorry I can't test while I'm at home.

I'm unclear as to how you are going to plot a, but you can find the elemnts of a that are also in b using
a(any(bsxfun(#eq,a,b')))

Related

How to solve error while doing interpolation one point with many points in MATLAB

I am trying to interpolate many points to one point in MATLAB. But I am getting error
The grid vectors do not define a grid of points that match the given values.
My code is given below
A = [2 6;3 7]
B = [3 6;4 9]
Xq=[A(:,1) [10;10]]
Yq=interp1(A,B,Xq','linear','extrap')
Actually I want to generate a line passing through one point from many points and as shown in below figure and extend upto axis of plot
'For loop' would be a solution.
One example is this.
A = [2 6;1 6;3 6]
B = [3 6;2 6;3 6]
L=size(A)
xArr=zeros(L(1), L(2));
yArr=zeros(L(1), L(2));
nLine=L(1); %number of lines
for k=1:nLine
Xq=[A(k,:) 10]
Yq=interp1(A(k,:),B(k,:),Xq','linear','extrap')
xArr(:,k)=Xq';
yArr(:,k)=Yq';
end
plot(xArr,yArr,'*-')
If you don't want to use for loop, you could directly calculate gradient and intercept of linear function.
A = [2 6;1 6;3 6]
B = [3 6;2 6;3 6]
L=size(A)
limX=10; %x limit
a=(B(:,2)-B(:,1))./(A(:,2)-A(:,1)); %gradient vector
b=B(:,1)-a.*A(:,1); % intercept vector
y=a*limX+b % linear function
Aq=[A';limX*ones(1,L(1))];
Bq=[B';y'];
figure(2)
plot(Aq,Bq,'*-')

Dividing each slice of a MATLAB 3D array by a different number

I have a 3D MATLAB function.
I want to multiply each slice of the matrix by a different number.
I tried to implement this by bsxfun in the following example code:
a=randi(10,4,3,2);
b=[2 3];
c=bsxfun(#times,a,b)
I intended that the first 4*3 slice of 'a' would be multiplied by 2, and the second 4*3 slice of 'a' would be multiplied by 3.
However, I only got the following error:
??? Error using ==> bsxfun
Non-singleton dimensions of the two
input arrays must match each other.
How to solve the problem without using a loop?
As the error says, you need to make the dimensions of the vector and the matrix match. Since b is a row vector, you can make the slices of the matrix into columns. You can do this with permute:
a = randi(10, 4, 3, 2);
b = [2 3];
ap = permute(a, [1 3 2]);
c = bsxfun(#times, ap, b)
Then, to get the result matrix back into the correct shape, you need to permute again. You can either figure out the correct permutation order (it happens to be the same in this case, i.e. [1 3 2]) or you can use ipermute (inverse permute) and let it figure it out for you. Just give it the same permutation order you gave permute earlier.
c = ipermute(c, [1 3 2]);
Alternatively, you can permute the vector b to be the right shape to multiply the slices by making it extend in the 3rd dimension:
a = randi(10, 4, 3, 2);
b = [2 3];
bp = permute(b, [1 3 2]);
c = bsxfun(#times, a, bp)
In this case, since we didn't change a, we don't have to permute c again to get the correct shape.

How do I add up two scatter points with the same values of x but different values of y?

On a stem plot, how can I add points that have the same values of x but different values of y?
For example, given the following code:
x = [1 2 3 6 6 4 5];
y = [3 6 1 8 9 4 2];
stem(x,y);
If you plot x, and y, this will be the output:
I want to add up (6,8) and (6,9) so it becomes (6,17), just like what the image is showing.
How can I achieve this?
Use accumarray with x and y so you can bin or group like entries together that share the same x. Once these values are binned, you can sum all of the values that share the same bin together. As such, we see that for x = 6, we have y = 8 and y = 9. accumarray allows you to group multiple y values together that share the same x. Once these values are grouped, you then apply a function to all of the values in the same group to produce a final output for each group. In our case, we want to sum them, so we need to use the sum function:
x = [1 2 3 6 6 4 5];
y = [3 6 1 8 9 4 2];
Z = accumarray(x(:), y(:), [], #sum);
stem(unique(x), Z);
xlim([0 7]);
We use unique on X so that we have no repeats for X when plotting the stem plot. unique also has the behaviour of sorting your x values. Doing x(:) and y(:) is so that you can make your input data either as row or column vectors independently. accumarray accepts only column vectors (or matrices, but we won't go there) and so doing x(:) and y(:) ensures that both inputs are column vectors.
We get:
The above code assumes that x is integer and starting at 1. If it isn't, then use the third output of unique to assign each number a unique ID, then run this through accumarray. When you're done, use the output of accumarray like normal:
[xu,~,id] = unique(x);
Z = accumarray(id, y(:), [], #sum);
stem(xu, Z);

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

MATLAB: Matrix containing values of another matrix at specific indices

I need help solving an indexing problem. The assigned problem states: Two matrices (x and y) give the coordinates to form matrix B from matrix A. Produce the matrix B which contains the values of A at the given coordinates in x and y.
For instance:
x = [1 1 1; 2 2 1]
y = [1 2 1; 3 2 4]
%This would read as (1,1),(1,2),(1,1),(2,3),(2,2),(1,4)
% Given matrix:
A = [6 7 8 9; 10 11 12 13];
%This would give us this answer for B (using the coordinate scheme above):
B=[6 7 6; 12 11 9];
I'm guessing I need to use the find function in conjunction with a sub2ind function, but I'm not 100% sure how to translate that into working code. The only thing I can think of would be to do something like this:
B=((x(1),(y(1)), (x(2),y(2)).......
But that would only work for the defined matrix above, not a randomly generated matrix. I tried looking for a similar problem on the site, but I couldn't find one. Your help would be really appreciated!
You can't do it for randomly generated matrices, because you have to ensure that matrix A has lines and columns as required from the values of x and y.
In this case, you can write:
for i=1:length(x(:))
B(i)=A(x(i),y(i));
end
B=reshape(B,size(x));