Lets say for example we have this array:
x =
0.5920 0.4635
0.6451 0.2118
-0.1206 -0.6036
0.2417 0.4773
0.3029 0.5172
What code would I need to write in order to print in such a way that it looks like this:
coords
x1 0.5920 y1 0.4635
x2 0.6451 y2 0.2118
x3 -0.1206 y3 -0.6036
x4 0.2417 y4 0.4773
x5 0.3029 y5 0.5172
I've tried this:
x = gallery('uniformdata',[1,10],0);
y = gallery('uniformdata',[1,10],1);
[v,c] = voronoin([x(:) y(:)]); %returns an array V with vertices and a cell array C with a matrix for each cell of the diagram.
c
for k = 1 : numel(c)
c{k} = c{k}(c{k} ~= 1)
end
fileID = fopen('cords.txt' , 'w');
for i=1:10
coord = v(c{i},:);
fprintf(fileID,'shape %d:\nx \t y\n', i);
fprintf(fileID,'%.4f %.4f\n', coord(:,1), coord(:,2));
end
fclose(fileID);
but im getting an output like this:
shape 10:
x y
0.5920 0.6451 %notice how the .6451 is on the right side when it should be on the bottom
-0.1206 0.2417
0.3029 0.4635
0.2118 -0.6036
0.4773 0.5172
The fprintf function reads the input variables in a column first manner and sends each value to its appropriate place in the string. So, in your code what happens is that even when you specify two different vectors per %.4f in your code, Matlab ignores that ordering. It puts the first value of coord(:, 1) in the first %.4f and the second value of coord(:, 1) in the second %.4f. Then it breaks the line. Then it again picks up the third value from coord(:, 1) and puts it in the first %.4f and so on. It only picks values from coord(:, 2) when all values of the first vector are exhausted.
The simplest fix is to transpose the coord matrix and then input it to Matlab like this:
fprintf(fileID,'%.4f %.4f\n', coord.'); % .' tranposes the matrix
Edit:
To get the format as x1 0.5920 y1 0.4635, we can make use of the column first ordering that Matlab follows to access a variable
% First we make a new matrix that has each of the required elements for the desired format
% The index of x, the value of x, the index of y and the value of y
tempCoord = [1:size(coord, 1); coord(:, 1).'; 1:size(coord, 1); coord(:, 2).'];
% Now we change the string specification for fprintf
fprintf(fileID,'x%d %.4f y%d %.4f\n', tempCoord);
Why does this work?
If you look at tempCoord, you will see that each of its columns has the format needed for the string specifier, i.e., the index of x, the value of x, the index of y and the value of y
tempCoord =
1.000000000000000 2.000000000000000 3.000000000000000 4.000000000000000 5.000000000000000
0.592000000000000 0.645100000000000 -0.120600000000000 0.241700000000000 0.302900000000000
1.000000000000000 2.000000000000000 3.000000000000000 4.000000000000000 5.000000000000000
0.463500000000000 0.211800000000000 -0.603600000000000 0.477300000000000 0.517200000000000
Now each column becomes each row of the printed file and you get the following output:
x1 0.5920 y1 0.4635
x2 0.6451 y2 0.2118
x3 -0.1206 y3 -0.6036
x4 0.2417 y4 0.4773
x5 0.3029 y5 0.5172
Related
I everyone,
I am pretty new in Octave\MatLab and I have the following doubt. I have this code calculating a sigmoid function for a parameter z:
function g = sigmoid(z)
%SIGMOID Compute sigmoid function
% g = SIGMOID(z) computes the sigmoid of z.
% You need to return the following variables correctly
g = zeros(size(z));
% ====================== YOUR CODE HERE ======================
% Instructions: Compute the sigmoid of each value of z (z can be a matrix,
% vector or scalar).
g = 1 ./ (1 + exp(-z));
% =============================================================
end
z could be a scalar, a vector or a matrix.
For example doing something like this:
>> X = [1 2; 0 5]
X =
1 2
0 5
>> g = 1 ./ (1 + exp(-X));
>> g
g =
0.73106 0.88080
0.50000 0.99331
Given the matrix X having 2 features X1 and X2 (the 2 column) how can I plot this function? The output is a three dimensional function?
The output is not a 3D function because you have one input X, and one output g, it's 2D.
You can display it column by column , displaying each column as a separate function on the same plot:
plot(X, g)
which is equivalent to:
figure
hold on
for i = 1:size(X,2)
plot(X(:,i), g(:,i))
end
hold off
You can display it row by row, displaying each row as a separate function on the same plot:
plot(X', g')
which is equivalent to:
figure
hold on
for i = 1:size(X,1)
plot(X(i,:), g(i,:))
end
hold off
You can display it as an array:
plot(X(:), g(:))
y1=tanh(3*x+5*t);
y2=5*cos(x+3*t);
y3=exp(-x)*sin(2*x+t);
How can I plot y1, y2 and y3 into a single 3D plot for the fixed value of t=0.5?
Assuming yn and x are arrays of values and have been evaluated with t=0.5, the following code will plot all 3 functions on one figure:
figure
plot(x,y1,x,y2,x,y3)
I'm guessing you are additionally asking how to evaluate yn for a range of x. Simply define yn as an array and loop over all values of x:
y1 = [];
x = [1 5 8 17];
t=0.5;
for xi = x
y1 = [y1 ; tanh(3*xi+5*t)];
end
I am creating a matrix of symbols and I declare a function using them:
x = syms('x', [1 2]);
f = x(1) + x(2)
So x and f are:
x = [x1 x2];
f = x1 + x2
Now I want to give values to x1 and x2 in a for loop and evaluate f. But when I use:
x(1) = value;
then x becomes:
x = [1 x2]
and x1 is lost, so I cannot evaluate f. How can I assign a value to x1, x2, ..., xn and then evaluate f?
You should use subs like the following:
subs(f,x1,value)
instead of replacing symbol of x1 with a value.
You can see the details of the function here.
How can I plot the vector w with the projected data onto this vector?
Here is the code - and my trials to plot the weight vector with y1 and y2.
x1=[1 2;2 3;3 3;4 5;5 5] % the first class 5 observations
x2=[1 0;2 1;3 1;3 2;5 3;6 5]
m1 = mean(x1);
m2 = mean(x2);
m = m1 + m2;
d1=x1-repmat(m1,5,1);
d2=x2-repmat(m2,6,1);
c = 0.5.*m;
Sw1 = d1'*d1;
Sw2 = d2'*d2;
Sw = Sw1 + Sw2;
invSw = inv(Sw);
w= invSw*(m1-m2)' %this is my vector projected
scatter(x1(:,1), x1(:,2), 10, 'ro');
hold on;
scatter(x2(:,1), x2(:,2), 10,'bo');
%this is how i plot the decision boundary, but it doesn't seems correct.
quiver(c(1,1), c(1,2), 1, -w(1,1)/w(2,1));
quiver(c(1,1), c(1,2), -1, w(1,1)/w(2,1));
auxw= w/norm(w);
plot([0 auxw(1)], [0 auxw(2)])
hold off;
figure;
y1 = x1*w;
y2 = x2*w;
hist([y1' y2'])
You are very close. You've only calculated (or tried to calculate) the scalar projection or the amount of scale you apply to each vector in order to project each vector in x1 and x2 onto w though what you have is incomplete. If you recall from linear algebra, to determine the scalar projection between two vectors a and b, or the scalar projection of b onto a, the formula is:
Source: Oregon State Mathematics: Calculus for Undergraduates
In our case, a would be w and b would be each of the vectors seen in x1 and x2. I'm assuming each row of these matrices is a vector. The scalar projections are seen in y1 and y2. You need to compute the vector projection, which is defined as taking the scalar projections and multiplying by the unit vectors of a, or simply:
Source: Oregon State Mathematics: Calculus for Undergraduates
Therefore, the calculation of the scalar projections in y1 and y2 are incorrect. You have to multiply by the normalized vector w, then when you find these scalar projection values, you multiply each of these scalar values with the corresponding normalized vector w. However, plotting these all simultaneously on a graph will be confusing. You will have many lines that will overlap onto the original vector w so what I did was I looped through plotting w, a vector in either x1 or x2 and the corresponding projected vector. Each time we loop, we pause and show the data then clear the figure and start again.
As such, I've added and changed the following to your code.
%// Your data
w = [-0.7936; 0.8899];
x1 = [1 2; 2 3; 3 3; 4 5; 5 5];
x2 = [1 0; 2 1; 3 1; 3 2; 5 3; 6 5];
%// Compute scalar projection
auxw = w/norm(w);
s1 = x1*auxw;
s2 = x2*auxw; %// Change for correctness
%// Compute the vector projection
y1 = bsxfun(#times, s1, auxw.');
y2 = bsxfun(#times, s2, auxw.');
%// Place the original vectors and corresponding projections
%// in one matrix
y = [y1; y2];
x = [x1; x2];
%// Loop through and plot w, a point in either x1 or x2
%// and the corresponding projection
for ii = 1 : size(y,1)
plot([0 w(1)], [0 w(2)]);
hold on;
plot([0 y(ii,1)], [0 y(ii,2)], 'r');
plot([0 x(ii,1)], [0 x(ii,2)], 'g');
pause(0.5);
clf;
end
The function bsxfun allows us to multiply each vector in x1 and x2 by their corresponding scalar values. Specifically, it will take the vectors s1 and s2 and when we transpose auxw to be a 1 x 2 vector, we will create new matrices y1 and y2 where each row of either will compute the vector projections of x1 and x2 and place them into the rows of y1 and y2.
The loop at the end cycles through w, a vector in either x1 or x2 and the corresponding projected vector one at a time and we pause for 0.5 seconds each time to see what the results look like. The vector w is in blue, the projected vector is in green and the original vector from either x1 or x2 is in red.
We get these series of figures:
We can see that the red line, which is the projected vector from either x1 or x2 onto w. The green line is the original vector from either x1 or x2.
I need to transpose a vector into a 2D matrix according to a group of values that are equal in another column of a matrix. For example:
1 x1
1 x2
1 x3
1 x4
2 x5
2 x6
2 x7
2 x8
Should look like:
x1 x2 x3 x4;
x5 x6 x7 x8;
This is the same procedure you would do in SAS using proc tabulate. Reshape didn't work for me because it doesn't transpose it, and tried permute with no luck either. Is there any built in command that does this besides having to program it in using find, transpose, and vertcat?
If for some reason you want to avoid reshape, although the solution in comments will work, you can use sub2ind to get the linear indices of the new matrix V, given that your first column will always provide the new line sub:
X = [[1,1,1,1,2,2,2,2]' (1:8)'];
subs = X(:,1);
M = length(unique(subs)); % count unique ids
N = length(X)./M; % Problem assumption: M sets of size N (MxN=length(X))
V = zeros(M, N);
i = sub2ind([M, N], subs, repmat(1:N,1,M)');
V(i) = X(:,2);
The above, according to your specs, will work as long as there is an equal number of unique elements in X, so you can form an MxN matrix.