Linear Regression using fminunc Implementation - octave

I'm trying to implement linear regression with only one feature using fminunc in Octave.
Here is my code.
x = load('/home/battousai/Downloads/ex2Data/ex2x.dat');
y = load('/home/battousai/Downloads/ex2Data/ex2y.dat');
m = length(y);
x = [ones(m , 1) , x];
theta = [0 , 0]';
X0 = [x , y , theta];
options = optimset('GradObj' , 'on' , 'MaxIter' , 1500);
[x , val] = fminunc(#computeCost , X0 , options)
And here is the cost function which returns the gradient as well as the value of the cost function.
function [J , gradient] = computeCost(x , y , theta)
m = length(y);
J = (0.5 / m) .* (x * theta - y )' * (x * theta - y );
gradient = (1/m) .* x' * (x * theta - y);
end
The length of the data set is 50, i.e., the dimensions are 50 x 1. I'm not getting the part that how should I pass X0 to the fminunc.
Updated Driver Code:
x = load('/home/battousai/Downloads/ex2Data/ex2x.dat');
y = load('/home/battousai/Downloads/ex2Data/ex2y.dat');
m = length(y);
x = [ones(m , 1) x];
theta_initial = [0 , 0];
options = optimset('Display','iter','GradObj','on' , 'MaxIter' , 100);
[X , Cost] = fminunc(#(t)(computeCost(x , y , theta)), theta_initial , options)
Updated Code for Cost function:
function [J , gradient] = computeCost(x , y , theta)
m = length(y);
J = (1/(2*m)) * ((x * theta) - y )' * ((x * theta) - y) ;
gradient = (1 / m) .* x' * ((x * theta) - y);
end
Now I'm getting values of theta to be [0,0] but when I used normal equation, values of theta turned out to be [0.750163 , 0.063881].

From the documentation for fminunc:
FCN should accept a vector (array) defining the unknown variables
and
X0 determines a starting guess.
Since your input is a cost function (i.e. it associates your choice of parameter vector with a cost), the input argument to your cost function, that needs to be optimised via fminunc is only theta, since x and y (i.e. your observations and your targets) are considered 'given' aspects of the problem and are not things you're trying to optimise. So you either declare x and y global and access them from your function like so:
function [J , gradient] = computeCost(theta_0)
global x; global y;
% ...
and then call fminunc as: fminunc (#computeCost, t_0, options)
or, keep your computeCost function as computeCost(x, y, theta), and change your fminunc call to something like this:
[x , val] = fminunc(# (t) computeCost(x, y, t) , t0 , options)
UPDATE Not sure what you were doing wrong. Here is the full code and an octave session running it. Seems fine.
%% in file myscript.m
x = load('ex2x.dat');
y = load('ex2y.dat');
m = length(y);
x = [ones(m , 1) , x];
theta_0 = [0 , 0]';
options = optimset('GradObj' , 'on' , 'MaxIter' , 1500);
[theta_opt, cost] = fminunc(# (t) computeCost(x,y,t) , theta_0 , options)
%% in file computeCost.m
function [J , gradient] = computeCost(x , y , theta)
m = length(y);
J = (0.5 / m) .* (x * theta - y )' * (x * theta - y );
gradient = (1/m) .* x' * (x * theta - y);
end
%% in the octave terminal:
>> myscript
theta_opt =
0.750163
0.063881
cost = 9.8707e-04

Related

Octave changes scale of y axis when I change the x-axis

When I used this code, it plots two functions like this:
a = 2;
t0 = 1;
N = 100;
epsilon = 1e-5;
function t = metodoDeNewton(a, t0, N, epsilon)
t = zeros(1, N+1);
t(1) = t0;
for i = 1:N
t(i+1) = t(i) - (t(i).^2 - (a - sin(t(i)))) ./ (2 .* t(i) - cos(t(i)));
if abs(t(i+1) - t(i)) < epsilon
break;
endif
endfor
endfunction
t = metodoDeNewton(a, t0, N, epsilon);
x = 0:0.01:1;
y1 = t;
y2 = a - sin(t);
l = plot(x, y1, x, y2);
legend({'g(a)', 'h(a)'});
xlabel('a');
ylabel('y');
But, when I try to change the x to x = 0:0.01:0.2 the graph's y-axis scale changes and I'm no longer able to see the functions I believe.
How can I fix this, any help would be appreciated!

Weird errors on Gradient Descent in Octave (Syntax errors on known command)

I'm trying to implement Gradient descent in octave. I know I can do it by calculating every value of theta by itself like this
function [theta, J_history] = gradientDescent(X, y, theta, alpha, num_iters)
m = length(y); % number of training examples
J_history = zeros(num_iters, 1);
for iter = 1:num_iters
theta_0 = theta(1) - alpha / m * sum(X * theta - y);
theta_1 = theta(2) - alpha / m * sum((X * theta - y) .* X(:, 2));
theta = [theta_0; theta_1];
% Save the cost J in every iteration
J_history(iter) = computeCost(X, y, theta);
end
end
But I want to implement it with vectors in one step like this:
function [theta, J_history] = gradientDescent(X, y, theta, alpha, num_iters)
m = length(y); % number of training examples
J_history = zeros(num_iters, 1);
for iter = 1:num_iters
theta = theta - (alpha/m * sum(((X * theta) - y).*X)
% Save the cost J in every iteration
J_history(iter) = computeCost(X, y, theta);
end
end
The problem is when I run the second piece of code I get this error:
syntax error
>>> J_history(iter) = computeCost(X, y, theta);
^
What have I done wrong / how can I fix this?

Implementing Euler's Method in GNU Octave

I am reading "Numerical Methods for Engineers" by Chapra and Canale. In it, they've provided pseudocode for the implementation of Euler's method (for solving ordinary differential equations). Here is the pseucode:
Pseucode for implementing Euler's method
I tried implementing this code in GNU Octave, but depending on the input values, I am getting one of two errors:
The program doesn't give any output at all. I have to press 'Ctrl + C' in order to break execution.
The program gives this message:
error: 'ynew' undefined near line 5 column 21
error: called from
Integrator at line 5 column 9
main at line 18 column 7
I would be very grateful if you could get this program to work for me. I am actually an amateur in GNU Octave. Thank you.
Edit 1: Here is my code. For main.m:
%prompt user
y = input('Initial value of y:');
xi = input('Initial value of x:');
xf = input('Final value of x:');
dx = input('Step size:');
xout = input('Output interval:');
x = xi;
m = 0;
xpm = x;
ypm = y;
while(1)
xend = x + xout;
if xend > xf
xend = xf;
h = dx;
Integrator(x,y,h,xend);
m = m + 1;
xpm = x;
ypm = y;
if x >= xf
break;
endif
endif
end
For Integrator.m:
function Integrator(x,y,h,xend)
while(1)
if xend - x < h
h = xend - x;
Euler(x,y,h,ynew);
y = ynew;
if x >= xend
break;
endif
endif
end
endfunction
For Euler.m:
function Euler(x,y,h,ynew)
Derivs(x,y,dydx);
ynew = y + dydx * h;
x = x + h;
endfunction
For Derivs.m:
function Derivs(x,y,dydx)
dydx = -2 * x^3 + 12 * x^2 - 20 * x + 8.5;
endfunction
Edit 2: I shoud mention that the differential equation which Chapra and Canale have given as an example is:
y'(x) = -2 * x^3 + 12 * x^2 - 20 * x + 8.5
That is why the 'Derivs.m' script shows dydx to be this particular polynomial.
Here is my final code. It has four different M-files:
main.m
%prompt the user
y = input('Initial value of y:');
x = input('Initial value of x:');
xf = input('Final value of x:');
dx = input('Step size:');
xout = dx;
%boring calculations
m = 1;
xp = [x];
yp = [y];
while x < xf
[x,y] = Integrator(x,y,dx,min(xf, x+xout));
m = m+1;
xp(m) = x;
yp(m) = y;
end
%plot the final result
plot(xp,yp);
title('Solution using Euler Method');
ylabel('Dependent variable (y)');
xlabel('Independent variable (x)');
grid on;
Integrator.m
%This function takes in 4 inputs (x,y,h,xend) and returns 2 outputs [x,y]
function [x,y] = Integrator(x,y,h,xend)
while x < xend
h = min(h, xend-x);
[x,y] = Euler(x,y,h);
end
endfunction
Euler.m
%This function takes in 3 inputs (x,y,h) and returns 2 outputs [x,ynew]
function [x,ynew] = Euler(x,y,h)
dydx = Derivs(x,y);
ynew = y + dydx * h;
x = x + h;
endfunction
Derivs.m
%This function takes in 2 inputs (x,y) and returns 1 output [dydx]
function [dydx] = Derivs(x,y)
dydx = -2 * x^3 + 12 * x^2 - 20 * x + 8.5;
endfunction
Your functions should look like
function [x, y] = Integrator(x,y,h,xend)
while x < xend
h = min(h, xend-x)
[x,y] = Euler(x,y,h);
end%while
end%function
as an example. Depending on what you want to do with the result, your main loop might need to collect all the results from the single steps. One variant for that is
m = 1;
xp = [x];
yp = [y];
while x < xf
[x,y] = Integrator(x,y,dx,min(xf, x+xout));
m = m+1;
xp(m) = x;
yp(m) = y;
end%while

Vectorization of function contains the numerical computation of definite integral in octave

I'm trying to fit my data using a formula containing a numerical calculation of definite integrals with infinite limits of integration. For fitting I use octave function leasqr that requires vectorization model function. The following code generates error, that occurs when calling a numerical integration.
nonconformant arguments (op1 is 1x387, op2 is 10x2)
function [fGsAb] = GsAbs (x, p)
Hw = 3108.0 ;
fGsAb = Hw ./ (2.4 .* p(1) .*p(2)) .^2 .* (exp ( - (Hw - p(1) .* x) .^2 ...
./ (2.4 .* p(1) .*p(2)) .^2 ) - exp ( - (Hw + p(1) .* x) .^2 ...
./ (2.4 .* p(1) .*p(2)) .^2 )) ;
endfunction
function [GsDisp] = gauss_disp(x, p)
[GsDisp1, err] = quadgk ( #(z) GsAbs(z, p) ./(z-x), - inf, x - 0.000001 );
[GsDisp2, err] = quadgk ( #(z) GsAbs(z, p) ./(z-x), x + 0.000001 , inf );
GsDisp = GsDisp1 +GsDisp2;
endfunction
h = [200:15:6000];
pin =[1 250];
dd = gauss_disp (h, pin);
If I'm using loop:
for i = 1 : length (h)
dd (i) = gauss_disp (h (i), pin)
endfor
I have no errors, but I cannot use this construction in leasqr. How can I get around this restriction?
Thank you in advance!
Change your gauss_disp.m file from this:
function [GsDisp] = gauss_disp(x, p)
[GsDisp1, err] = quadgk ( #(z) GsAbs(z, p) ./(z-x), - inf, x - 0.000001 );
[GsDisp2, err] = quadgk ( #(z) GsAbs(z, p) ./(z-x), x + 0.000001 , inf );
GsDisp = GsDisp1 +GsDisp2;
endfunction
to this:
function [GsDisp] = gauss_disp(x, p)
GsDisp = arrayfun(#(z) gauss_disp_elementwise(z, p), x)
endfunction
function GsDisp = gauss_disp_elementwise(x, p)
[GsDisp1, err] = quadgk ( #(z) GsAbs(z, p) ./(z-x), - inf, x - 0.000001 );
[GsDisp2, err] = quadgk ( #(z) GsAbs(z, p) ./(z-x), x + 0.000001 , inf );
GsDisp = GsDisp1 +GsDisp2;
endfunction
I.e. make your original function into a helper subfunction that only deals with scalar values, and then use that with arrayfun to get outputs for the entire range of x. This way you can use this in your leasqr function, e.g.:
y = leasqr(h, dd, pin, #gauss_disp);
PS: the arrayfun syntax is just for convenience. you could have easily used a for loop similar to what you used in your question instead.

Storing cost history in a vector

I wrote following code for gradientDescent in Octave in .m file as follows:
function [theta, J_history] = gradientDescent(X, y, theta, alpha, num_iters)
% Test values:
X = [1 5; 1 2; 1 4; 1 5];
y = [1 6 4 2]';
theta = [0 0]';
alpha = 0.01;
num_iters = 1000;
% Initialize some useful values:
m = length(y); % number of training examples
J_history = zeros(num_iters, 1);
for iter = 1:num_iters
x = X(:,2);
h = theta(1) + (theta(2)*x);
theta_zero = theta(1) - alpha * (1/m) * sum(h-y);
theta_one = theta(2) - alpha * (1/m) * sum((h - y) .* x);
theta = [theta_zero; theta_one];
% ============================================================
% Save the cost J in every iteration
J_history(iter) = computeCost(X, y, theta); % History of J
end
disp(min(J_history));
end
% Code for computeCost function is as follows:
function J = computeCost(X, y, theta)
data =
6.1101 17.5920
5.5277 9.1302
8.5186 13.6620
7.0032 11.8540
5.8598 6.8233
8.3829 11.8860
7.4764 4.3483
8.5781 12.0000
6.4862 6.5987
m = length(y);
J = 0;
X = data(:, 1);
y = data(:, 2);
predictions = X*theta'; % predictions of hypothesis on examples
sqrErrors = (predictions - y).^2; % squared errors
J = 1/(2*m) * sum(sqrErrors);
end
When I run this from octave workspace I get the following error:
Error: A(I) = X: X must have the same size as I
error: called from
gradientDescent at line 55 column 21
I tried many things but unsuccessfully and mentors never replied properly.
Can you please tell me where I may be making a mistake.
Thanks in advance.
Bharat.