How can I plot this Octave\Matlab function output? - matlab

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(:))

Related

Implicit Functions With 2 Variables

Thanks to the fimplicit function, I can plot implicit functions with 2 variables (x,y).
For a particular x, there is a particular y which makes F_imp=0. Now take this y as an input to another function g which produces z.
How can I plot x,z for x's between [0.1 1]?
Of course, I could have found the inverse of g(y) and replace in F(x,y) but there is not closed form of inverse of g(y).
Below are the functions I am dealing with:
F_imp = #(x,y) log(100-x*90) - x*log(10+0.9*y) - (1-x)*log(100-0.1*y);
fimplicit(F_imp,[0.1 1 0 100])
g=0.1*log(10+y*0.9)+0.9*log(100-0.1*y)
You can use the ImplicitFunctionLine object, which is an optional return value of the fimplicit() function. In this way you get access to the correspondent x and y data.
Then just use y to calculate g and plot g against x:
clear;
F_imp = #(x,y) log(100-x*90) - x*log(10+0.9*y) - (1-x)*log(100-0.1*y);
fp = fimplicit(F_imp,[0.1 1 0 100]); %returns the ImplicitFunctionLine object
%get calculated data points from the object
x = fp.XData;
y = fp.YData;
%set y as input for g
g=0.1*log(10+y*0.9)+0.9*log(100-0.1*y);
plot(x, g);
grid minor;
Here is the result:

vectorization Matlab - how to vectorize Gauss function ( code ) without loop

i wrote a function to calculate the integral using gaussian quadrature rule. I need to vectorize the last 2 lines, without using a loop. Any ideas?
function Q = gauss5(f,a,b,n)
% Divide the interval into n parts
y = linspace(a,b,n);
% Create function to use arrayfun
% Sum up the result from the arrayfun with function Fun on particular
% intervals, the first argument is array y without the last value, and
% the second argument is the array y without the first value
a = (y(1:end-1));
b = (y(2:end));
% coefficients - some random numbers
c = [1 2 3 4 5];
% nodes - random numbers too
x = [1 1 1 1 1];
% calculate b-a
w = b-a;
% sum up the result
Q = 0;
for i=1:n-1
Q = Q + sum((w(i)*c.*feval(f,((w(i)*x)+a(i)))));
end
end
If your f can get an array as input, you can replace this:
% sum up the result
Q = 0;
for i=1:n-1
Q = Q + sum((w(i)*c.*feval(f,((w(i)*x)+a(i)))));
end
by this:
wxa = bsxfun(#plus,bsxfun(#times,w,x(:)),a);
Qs = bsxfun(#times,w,c(:)).*feval(f,wxa);
Q = sum(Qs(:))
Or, if you have Matlab 2016b or later, just:
Qs = w.*c(:).*feval(f,w.*x(:)+a);
Q1 = sum(Qs(:));

surface plot in Matlab

I am trying to graph a surface with a diagonal matrix, the equation I am trying graph is f = x^TDx, x is a 2 by 1 vector and D is a 2 by 2 matrix.
Here is what have so far, but I keep getting error.
x = linspace(-10,10);
y = linspace(-10,10);
[X,Y] = meshgrid(x,y);
D = [1 0; 0 1];
f = #(x,y) [x,y]*D*[x,y].'; % [x,y] is 1 by 2
contour (X,Y,f(X,Y))
Can someone tell me how to get rid of the error? Thanks
Since x and y have the same length, your diagonal matrix D must be a square matrix of size n x n, with n equal to two times the length of your x or y vectors. The reason why you need to multiply the length by two is because the operation [x,y] concatenates the arrays horizontally thus duplicating one of the dimensions.
In this example D is the Identity matrix. See eye for more information.
x = linspace(-10,10); % x is 1x100
y = linspace(-10,10); % y is 1x100
[X,Y] = meshgrid(x,y); % X is 100x100 and Y is 100x100
D = eye(2*numel(x)); % D is 2*100x2*100 = 200x200
f = #(x,y) [x,y]*D*[x,y].'; % [X,Y] is 100x200 and [X,Y].' is 200x100
contour (X,Y,f(X,Y))
If you want D to be a random diagonal matrix, you can accomplish this combining diag with one of the Random Number Generation functions available, like for example randn.
On the previous example, replace D with the following instruction:
D = diag(randn(1,2*numel(x)));
You can also give the coefficients you choose to the diagonal matrix. To do so, you will need to create the vector of coefficients manually, making sure that it has the adequate length, so that it satisfies the conditions explained at the beginning of this post.
Try now replacing D with the following instructions:
v = 1:2*numel(x); % vector of coefficients: v = [1 2 ... 200]
D = diag(v);

Using MATLAB to write a function that implements Newton's method in two dimensions

I am trying to write a function that implements Newton's method in two dimensions and whilst I have done this, I have to now adjust my script so that the input parameters of my function must be f(x) in a column vector, the Jacobian matrix of f(x), the initial guess x0 and the tolerance where the function f(x) and its Jacobian matrix are in separate .m files.
As an example of a script I wrote that implements Newton's method, I have:
n=0; %initialize iteration counter
eps=1; %initialize error
x=[1;1]; %set starting value
%Computation loop
while eps>1e-10&n<100
g=[x(1)^2+x(2)^3-1;x(1)^4-x(2)^4+x(1)*x(2)]; %g(x)
eps=abs(g(1))+abs(g(2)); %error
Jg=[2*x(1),3*x(2)^2;4*x(1)^3+x(2),-4*x(2)^3+x(1)]; %Jacobian
y=x-Jg\g; %iterate
x=y; %update x
n=n+1; %counter+1
end
n,x,eps %display end values
So with this script, I had implemented the function and the Jacobian matrix into the actual script and I am struggling to work out how I can actually create a script with the input parameters required.
Thanks!
If you don't mind, I'd like to restructure your code so that it is more dynamic and more user friendly to read.
Let's start with some preliminaries. If you want to make your script truly dynamic, then I would recommend that you use the Symbolic Math Toolbox. This way, you can use MATLAB to tackle derivatives of functions for you. You first need to use the syms command, followed by any variable you want. This tells MATLAB that you are now going to treat this variable as "symbolic" (i.e. not a constant). Let's start with some basics:
syms x;
y = 2*x^2 + 6*x + 3;
dy = diff(y); % Derivative with respect to x. Should give 4*x + 6;
out = subs(y, 3); % The subs command will substitute all x's in y with the value 3
% This should give 2*(3^2) + 6*3 + 3 = 39
Because this is 2D, we're going to need 2D functions... so let's define x and y as variables. The way you call the subs command will be slightly different:
syms x, y; % Two variables now
z = 2*x*y^2 + 6*y + x;
dzx = diff(z, 'x'); % Differentiate with respect to x - Should give 2*y^2 + 1
dzy = diff(z, 'y'); % Differentiate with respect to y - Should give 4*x*y + 6
out = subs(z, {x, y}, [2, 3]); % For z, with variables x,y, substitute x = 2, y = 3
% Should give 56
One more thing... we can place equations into vectors or matrices and use subs to simultaneously substitute all values of x and y into each equation.
syms x, y;
z1 = 3*x + 6*y + 3;
z2 = 3*y + 4*y + 4;
f = [z1; z2];
out = subs(f, {x,y}, [2, 3]); % Produces a 2 x 1 vector with [27; 25]
We can do the same thing for matrices, but for brevity I won't show you how to do that. I will defer to the code and you can see it then.
Now that we have that established, let's tackle your code one piece at a time to truly make this dynamic. Your function requires the initial guess x0, the function f(x) as a column vector, the Jacobian matrix as a 2 x 2 matrix and the tolerance tol.
Before you run your script, you will need to generate your parameters:
syms x y; % Make x,y symbolic
f1 = x^2 + y^3 - 1; % Make your two equations (from your example)
f2 = x^4 - y^4 + x*y;
f = [f1; f2]; % f(x) vector
% Jacobian matrix
J = [diff(f1, 'x') diff(f1, 'y'); diff(f2, 'x') diff(f2, 'y')];
% Initial vector
x0 = [1; 1];
% Tolerance:
tol = 1e-10;
Now, make your script into a function:
% To run in MATLAB, do:
% [n, xout, tol] = Jacobian2D(f, J, x0, tol);
% disp('n = '); disp(n); disp('x = '); disp(xout); disp('tol = '); disp(tol);
function [n, xout, tol] = Jacobian2D(f, J, x0, tol)
% Just to be sure...
syms x, y;
% Initialize error
ep = 1; % Note: eps is a reserved keyword in MATLAB
% Initialize counter
n = 0;
% For the beginning of the loop
% Must transpose into a row vector as this is required by subs
xout = x0';
% Computation loop
while ep > tol && n < 100
g = subs(f, {x,y}, xout); %g(x)
ep = abs(g(1)) + abs(g(2)); %error
Jg = subs(J, {x,y}, xout); %Jacobian
yout = xout - Jg\g; %iterate
xout = yout; %update x
n = n + 1; %counter+1
end
% Transpose and convert back to number representation
xout = double(xout');
I should probably tell you that when you're doing computation using the Symbolic Math Toolbox, the data type of the numbers as you're calculating them are a sym object. You probably want to convert these back into real numbers and so you can use double to cast them back. However, if you leave them in the sym format, it displays your numbers as neat fractions if that's what you're looking for. Cast to double if you want the decimal point representation.
Now when you run this function, it should give you what you're looking for. I have not tested this code, but I'm pretty sure this will work.
Happy to answer any more questions you may have. Hope this helps.
Cheers!

Matlab:output vector giving the x and y values of point of intersection

How do I write a function having 3 inputs (2 vectors consisting of coefficients[a b c] and vector of x values) of two line equations of form ax+by=c that outputs a vector giving x and y values of the point of intersection.
Example: solveSystem([1 -1 -1],[3 1 9],-5:5 ) should produce [2 3]
So far:
function coeff=fitPoly(mat)
% this function takes as an input an nx2 matrix consisting of the
% coordinates of n points in the xy-plane and give as an output the unique
% polynomial (of degree <= n-1) passing through those points.
[n,m]=size(mat); % n=the number of rows=the number of points
% build the matrix C
if m~=2
fprintf('Error: incorrect input');
coeff=0;
else
C=mat(:,2); % c is the vector of y-coordinates which is the 2nd column of mat
% build the matrix A
for i=1:n
for j=1:n
A(i,j)=(mat(i,1))^(n-j);
end
end
coeff=inv(A)*C;
end
You don't need the vector x to solve for the intersection of the two lines:
function xy = solve(c1,c2)
A = [c1(1:2); c2(1:2)];
b = [c1(3); c2(3)];
xy = A\b;
end
which would compute for
xy = solve([1 -1 -1],[3 1 9])
the matrices
A = [1 -1;
3 1]
b = [-1
9]
so that
xy = A^-1 b = [2
3]