How to make a set on plot in Matlab like on the photo - Perceptron - matlab

I have a problem to make a set and show like on this photo in attachment.
Where:
Points must to be random in the range of:
Principle to set:
This is first part of exercise about perceptron. Without this I can't make other parts.
There is my code:
clc;
close all;
clear all;
I=400;
x1=-1+rand(I/2,1)+1;
X = [0+rand(I,1)*(2*pi) [-1+rand(I/2,1)+1;
(-1+rand(I/2,1)+1)] ]
Y = [ones((I/2),1)*sin(-1); ones(I/2,1)];
a = X(1:I/2,1);
b = X(1:I/2,2);
c = X(I/2:I,1);
d = X(I/2:I,2);
plot( a, b, 'bx');
hold on;
plot( c, d, 'go');

So you already figured out how to generate the random coordinates within the area of the plot:
N = 400;
x1 = rand(N,1)*(2*pi);
x2 = rand(N,1)*2-1;
Next, you want to find the subset of points that satisfy the equation (this is the set for which y==-1):
I = abs(sin(x1)) > abs(x2);
I is a logical array, with true values where the condition is satisfied. You can use I to index into another array. For example, You can create the vector y like this:
y = ones(N,1);
y(I) = -1;
But you don't really need y to create the plot. You were already plotting two subsets, simply make the subsets using I as index, instead of 1:N/2:
plot(x1(I),x2(I),'bx');
hold on
plot(x1(~I),x2(~I),'go');
The result is a plot exactly like in the question, except with x and o markers instead of . markers.

Related

Matlab element-wise power - can't understand how it works

I have a matched filter, which I want to plot its frequency response in Matlab.
The filter response is: H(f) =
I tried to to plot it with:
%Freqency_Response_of_wiener_filter
f = linspace(-1e3,1e3,1e5);
H = ((2*pi*f)^2+10^6)/(11*(2*pi*f)^2+10^6+10^4);
plot(f,H);
xlabel('f')
ylabel('H(f)')
which not working, giving me error of 'Matrix dimensions must agree' kind.
I then read about 'element-wise power', which seems to fit exactly to what I need, and changed H to:
H = ((2*pi*f).^2+10^6)/(11*(2*pi*f).^2+10^6+10^4);
This indeed plot something, just not what I want :)
I tried also
H = ((2*pi)^2*f.^2+10^6)/(11*(2*pi)^2*f.^2+10^6+10^4);
with no luck.
The only way I got it working is:
%Freqency_Response_of_wiener_filter
f = linspace(-1e3,1e3,1e5);
for i=1:length(f)
H(i) = ((2*pi*f(i))^2+10^6)/(11*(2*pi*f(i))^2+10^6+10^4);
end
plot(f,H);
Why is 'element-wise power' not working for me?
More than that - what exactly the differenece between regular operation to 'element-wise operation'? Because, for example, over here: An Introduction to Matlab, there's this plot:
a = 0:.01:5;
b = cos(2*pi*a);
plot(a,b)
and then this one:
x = 2:.1:4;
y = 1./x;
plot(x,y)
xlabel('x');
ylabel('y');
and I can't tell any difference between them. Why on the first one there was no need of 'element-wise operation', while in the second one there was?
Thanks.
The reason why H = ((2*pi)^2*f.^2+10^6)/(11*(2*pi)^2*f.^2+10^6+10^4); did not work is because you need ./:
H = ((2*pi)^2*f.^2+10^6)./(11*(2*pi)^2*f.^2+10^6+10^4);
In the first case:
a = 0:.01:5;
b = cos(2*pi*a);
plot(a,b)
you do not need an element-wise-operation because there is only one way of doing the cosine of a vector or a matrix.
On the other hand, in another case:
x = 2:.1:4;
y = x.^2;
plot(x,y)
xlabel('x');
ylabel('y');
You need to specify that you want to make the element-wise operation rather than multiplying the matrix by itself (that works only for square matrices).
In the second case you post:
x = 2:.1:4;
y = 1./x;
plot(x,y)
xlabel('x');
ylabel('y');
you need the . so that Matlab understand that 1 has to be a vector of ones with length numel(x).

Why is contour sorting the data in the contour matrix C?

I have a function f(x,y) and I would like to draw the level curves of f with respect to a fixed vector
v=(v1,...,vn) % not sorted
using a meshgrid [X,Y].
This can be done using the function [C,h]=contour(X,Y,f,v).
But then, when I want to recover the data of each level curve, I found that C has sorted my vector v in an increasing way.
I would like to recover C in such a way that it keeps my fixed order of v.
This can be done using a loop over the components on v, one by one, using
[Ci,hi]=contour(X,Y,f,[vi,vi])
but I have found it inefficient, when taking the number of components of v large enough (Lets say, 10000 components).
How can I recover the original unsorted vector v from C(with the corresponding information given by C)?
I think it is easiest to sort the contour levels yourself in advance using
[w,iv,iw] = unique(v)
This will sort your data in v and only keep unique values. iv and iw are index vectors that allow you to redo the sorting from v --> w on any other data set, because w = v(iv) and v = w(iw).
Now use w instead of v to plot your contours. You can then use iw to
'unsort' the data in C. If necessary, take a look at Contour Properties > Contour Matrix for the specifications of C.
I suspect the answer to your question is that MATLAB applies unique to the contour levels before tracking the contours.
I'm not sure that recovering the unsorted vector is going to be helpful since there is not necessarily a single contour line/loop at each level. So in general this contour matrix must be processed in a loop at some point I believe.
Depending on what you intend to do with the contour line data subsequently what I have done in the past may be useful. (I have basically copied the code verbatim from a function I wrote a while ago.)
This code creates a mask matrix which enables me to extract all the points for each level from the contour matrix:
% Create the contours
[c, ch] = contour(X, Y, f, v);
% Create a mask for the contour matrix for each level.
l = numel(v);
n = size(c,2);
cmask = false(l,n);
fCtrNotLoop = false(1,l);
% Don't think this is possible without a loop...
ii = 1;
while ii < n
m = c(2,ii);
cmask(v == c(1,ii), ii+1:ii+m) = true;
% Remove duplicate point of loops.
if all(c(:,ii+1)==c(:,ii+m))
cmask(v == c(1,ii), ii+m) = false;
else
fCtrNotLoop(lvls == c(1,ii)) = true;
end
ii = ii + m + 1;
end
(You may or may not want to remove duplicate points that close loops -- I needed to for my application.)
Then to get the points in the contour(s) at level v(jj) use something like:
pts = c(:,cmask(jj,:));
With a slight modification you could use cmask to reorder your contour matrix: change ii+1:ii+m in the cmask(...) = true line to ii:ii+m and remove the duplicate points if statement. Then loop through each level to populate a copy of c:
% WARNING: Untested code follows!
cnew = c;
kk = 1;
for jj = 1 : l
s = sum(cmask(jj, :));
cnew(:, kk:kk+s-1) = c(:, cmask(jj, :));
kk = kk + s;
end
As cmask has dimensions [length(v),length(c)] if you have a huge number of levels and lots of contour points in each then memory consumption may become a problem and modification of this extraction/reordering method may be required - i.e. process each level separately which of course will be slower.

matlab plotting a family of functions

Generate a plot showing the graphs of
y=(2*a+1)*exp(-x)-(a+1)*exp(2*x)
in the range x ∈ <-2, 4> for all integer values of a between -3 and 3
I know how to make typical plot for 2 values and set a range on the axes, but how to draw the graph dependent on the parameter a?
To elaborate on Ben Voigt's comment: A more advanced technique would be to replace the for-loop with a call to bsxfun to generate a matrix of evaluations of M(i,j) = f(x(i),a(j)) and call plot with this matrix. Matlab will then use the columns of the matrix and plot each column with individual colors.
%%// Create a function handle of your function
f = #(x,a) (2*a+1)*exp(-x)-(a+1)*exp(2*x);
%%// Plot the data
x = linspace(-2, 4);
as = -3:3;
plot(x, bsxfun(f,x(:),as));
%%// Add a legend
legendTexts = arrayfun(#(a) sprintf('a == %d', a), as, 'uni', 0);
legend(legendTexts, 'Location', 'best');
You could also create the evaluation matrix using ndgrid, which explicitly returns all combinations of the values of x and as. Here you have to pay closer attention on properly vectorizing the code. (We were lucky that the bsxfun approach worked without having to change the original f.)
f = #(x,a) (2*a+1).*exp(-x)-(a+1).*exp(2*x); %// Note the added dots.
[X,As] = ndgrid(x,as);
plot(x, f(X,As))
However for starters, you should get familiar with loops.
You can do it using a simple for loop as follows. You basically loop through each value of a and plot the corresponding y function.
clear
clc
close all
x = -2:4;
%// Define a
a = -3:3;
%// Counter for legend
p = 1;
LegendText = cell(1,numel(a));
figure;
hold on %// Important to keep all the lines on the same plot.
for k = a
CurrColor = rand(1,3);
y= (2*k+1).*exp(-x)-(k+1).*exp(2.*x);
plot(x,y,'Color',CurrColor);
%// Text for legend
LegendText{p} = sprintf('a equals %d',k);
p = p+1;
end
legend(LegendText,'Location','best')
Which gives something like this:
You can customize the graph as you like. Hope that helps get you started!

evaluating a self made function for a cector and then plotting in matlab

i have created a function that represents a triangle sign.
this function does not work on vectors. i want to evaluate a vector x:
x=[-2:0.01:2]
and save the answer in vector y, for this purpose i came up with the following code:
for i=1:400, y(i) = triangle(x(i))
after i got the ans i plotted is using plot. in this case it worked ok but i am interested on observing the influence of time shifting and shrinking so when i try to use lets say:
for i=1:200, y(i) = triangle(x(2*i))
i get a vector y not the same length as vector x and i cant even plot them... is there any easy way to achieve it? and how should i plot the answer?
here is my function:
function [ out1 ] = triangle( input1 )
if abs(input1) < 1,
out1 = 1 - abs(input1);
else
out1 = 0;
end
end
y is a different length in each for loop because each loop iterated a different number of times. In the example below, I use the same for loops and plot y2 with the corresponding values of x. i is already defined in matlab so I've changed it to t in the example below.
clear all
x=[-2:0.01:2];
for t=1:400
y(t) = triangle(x(t));
end
for t=1:200
y2(t) = triangle(x(2*t));
end
Or, if you want to see y2 plotted over the same range you can increase the size of x:
clear all
x=[-2:0.01:8];
for t=1:400
y(t) = triangle(x(t));
end
for t=1:400
y2(t) = triangle(x(2*t));
end
plot(x(1:length(y)),y,'r')
hold on
plot(x(1:length(y2)),y2,'b')

Can someone explain how to graph this sum in MATLAB using contourf?

I'm going to start off by stating that, yes, this is homework (my first homework question on stackoverflow!). But I don't want you to solve it for me, I just want some guidance!
The equation in question is this:
I'm told to take N = 50, phi1 = 300, phi2 = 400, 0<=x<=1, and 0<=y<=1, and to let x and y be vectors of 100 equally spaced points, including the end points.
So the first thing I did was set those variables, and used x = linspace(0,1) and y = linspace(0,1) to make the correct vectors.
The question is Write a MATLAB script file called potential.m which calculates phi(x,y) and makes a filled contour plot versus x and y using the built-in function contourf (see the help command in MATLAB for examples). Make sure the figure is labeled properly. (Hint: the top and bottom portions of your domain should be hotter at about 400 degrees versus the left and right sides which should be at 300 degrees).
However, previously, I've calculated phi using either x or y as a constant. How am I supposed to calculate it where both are variables? Do I hold x steady, while running through every number in the vector of y, assigning that to a matrix, incrementing x to the next number in its vector after running through every value of y again and again? And then doing the same process, but slowly incrementing y instead?
If so, I've been using a loop that increments to the next row every time it loops through all 100 values. If I did it that way, I would end up with a massive matrix that has 200 rows and 100 columns. How would I use that in the linspace function?
If that's correct, this is how I'm finding my matrix:
clear
clc
format compact
x = linspace(0,1);
y = linspace(0,1);
N = 50;
phi1 = 300;
phi2 = 400;
phi = 0;
sum = 0;
for j = 1:100
for i = 1:100
for n = 1:N
sum = sum + ((2/(n*pi))*(((phi2-phi1)*(cos(n*pi)-1))/((exp(n*pi))-(exp(-n*pi))))*((1-(exp(-n*pi)))*(exp(n*pi*y(i)))+((exp(n*pi))-1)*(exp(-n*pi*y(i))))*sin(n*pi*x(j)));
end
phi(j,i) = phi1 - sum;
end
end
for j = 1:100
for i = 1:100
for n = 1:N
sum = sum + ((2/(n*pi))*(((phi2-phi1)*(cos(n*pi)-1))/((exp(n*pi))-(exp(-n*pi))))*((1-(exp(-n*pi)))*(exp(n*pi*y(j)))+((exp(n*pi))-1)*(exp(-n*pi*y(j))))*sin(n*pi*x(i)));
end
phi(j+100,i) = phi1 - sum;
end
end
This is the definition of contourf. I think I have to use contourf(X,Y,Z):
contourf(X,Y,Z), contourf(X,Y,Z,n), and contourf(X,Y,Z,v) draw filled contour plots of Z using X and Y to determine the x- and y-axis limits. When X and Y are matrices, they must be the same size as Z and must be monotonically increasing.
Here is the new code:
N = 50;
phi1 = 300;
phi2 = 400;
[x, y, n] = meshgrid(linspace(0,1),linspace(0,1),1:N)
f = phi1-((2./(n.*pi)).*(((phi2-phi1).*(cos(n.*pi)-1))./((exp(n.*pi))-(exp(-n.*pi)))).*((1-(exp(-1.*n.*pi))).*(exp(n.*pi.*y))+((exp(n.*pi))-1).*(exp(-1.*n.*pi.*y))).*sin(n.*pi.*x));
g = sum(f,3);
[x1,y1] = meshgrid(linspace(0,1),linspace(0,1));
contourf(x1,y1,g)
Vectorize the code. For example you can write f(x,y,n) with:
[x y n] = meshgrid(-1:0.1:1,-1:0.1:1,1:10);
f=exp(x.^2-y.^2).*n ;
f is a 3D matrix now just sum over the right dimension...
g=sum(f,3);
in order to use contourf, we'll take only the 2D part of x,y:
[x1 y1] = meshgrid(-1:0.1:1,-1:0.1:1);
contourf(x1,y1,g)
The reason your code takes so long to calculate the phi matrix is that you didn't pre-allocate the array. The error about size happens because phi is not 100x100. But instead of fixing those things, there's an even better way...
MATLAB is a MATrix LABoratory so this type of equation is pretty easy to compute using matrix operations. Hints:
Instead of looping over the values, rows, or columns of x and y, construct matrices to represent all the possible input combinations. Check out meshgrid for this.
You're still going to need a loop to sum over n = 1:N. But for each value of n, you can evaluate your equation for all x's and y's at once (using the matrices from hint 1). The key to making this work is using element-by-element operators, such as .* and ./.
Using matrix operations like this is The Matlab Way. Learn it and love it. (And get frustrated when using most other languages that don't have them.)
Good luck with your homework!