How to plot a contour graph for a linear regression cost function? - octave

I'm following the machine learning course on Coursera, and one of the lectures provides a contour plot of a cost function for linear regression on one variable:
Source: https://www.coursera.org/learn/machine-learning/lecture/nwpe2/cost-function-intuition-ii
I thought it would be useful from an educational standpoint to be able to reproduce this chart. I don't have any octave experience, so I would need step by step instructions that I could paste into the octave command window.
Anyone here able to help with this?
Update:
I ended up with the following:
function cost = calc_cost (theta0, theta1)
x = 1:10;
y = x.*2;
cost = arrayfun( #(t0, t1) ( 1/(length(x)) * sum( ((t0 + t1*x) - y).^2 )), theta0, theta1);
endfunction
[xx, yy] = meshgrid( -3000:50:3000, -3000:50:3000) ;
zz = calc_cost(xx, yy);
contour(xx, yy, zz )

If you are no able to rewrite your cost funktion so that it accepts matrix inputs you can use arrayfun:
function cost = calc_cost (theta0, theta1)
x = 1:10;
y = x.*2;
cost = ( 1/(length(x)) * sum( ((theta0 + theta1*x) - y).^2 ) );
endfunction
[x,y] = meshgrid (linspace(-5000,5000,20), linspace(-500,500,20));
z = arrayfun (#calc_cost, x, y);
contour (x, y, z)
print out.png
gives

Related

How to find variables in Julia using Linear Regression for Interpolation method?

There is an unknown function ,
and there are unknown coefficients k, l. Task is to estimate k, l using linear regression, through the data table.
-2.0 1.719334581463762
-1.0 1.900158577875515
0.0 2.1
1.0 2.3208589279588603
2.0 2.5649457921363568
Till now mathematically I did like, taking logarithm on both sides
Then using the data table, 5 equations will be formed
Now apply the linear regressor, to this logarithm-transformed data, to estimate the coefficients k and l.
I have built a linear regresor,
using DataFrames, GLM
function LinearRegression(X)
x = X[:,1]
y = X[:,2]
data = DataFrame(y = y, x = x)
reg = lm(#formula(y ~ x), data)
return coef(reg)[2], coef(reg)[1]
end
Any solution to how to find l and k values using this technique?
You're almost there, but I think you have a misconception mathematically in your code. You are right that taking the log of f(x) makes this essentially a linear fit (of form y = mx + b) but you haven't told the code that, i.e. your LinearRegression function should read:
function LinearRegression(X)
x = X[:,1]
y = X[:,2]
data = DataFrame(y = log.(y), x = x)
reg = lm(#formula(y ~ x), data)
return coef(reg)[2], coef(reg)[1]
end
Note that I have written y = log.(y) to match the formula as otherwise you are fitting a line to exponential data. We don't take the log of x because it has negative values. Your function will then return the correct coefficients l and log(k) (so if you want just k itself you need to take the exponential) -- see this plot as proof that it fits the data perfectly!
You need to convert the intercept with exp and the slope keeps as it is.
using Statistics #mean
#Data
X = [-2.0 1.719334581463762
-1.0 1.900158577875515
0.0 2.1
1.0 2.3208589279588603
2.0 2.5649457921363568]
x = X[:,1]
y = X[:,2]
yl = log.(y)
#Get a and b for: log.(y) = a + b*x
b = x \ yl
a = mean(yl) - b * mean(x)
l = b
#0.10000000000000005
k = exp(a)
#2.1
k*exp.(l.*x)
#5-element Vector{Float64}:
# 1.719334581463762
# 1.900158577875515
# 2.1
# 2.3208589279588603
# 2.5649457921363568

Plotting a 2D graph in Octave: getting nonconformant arguments error with graph not coming correctly

I'm making a graph out of calculations by putting energy over the overall distance traveled. I used the equation E/D = F (Energy/Distance = Force) to try and got values in order to create a 2D line graph from them. However, I'm getting errors such as "nonconformant arguments", one of my variables being randomly turned to 0 and that the vector lengths aren't matching, here's the code:
% Declaring all the variables for the drag equation
p = 1.23;
v = 0:30;
C = 0.32;
A = 3.61;
D = 100000;
% This next line of code uses the variables above in order to get the force.
Fd = (p*(v.^2)*C*A)/2
% This force is then used to calculate the energy used to overcome the drag force
E = Fd*D
kWh = (E/3.6e+6);
Dist = (D/1000);
x = 0:Dist
y = 0:kWh
plot(x,y)
xlabel('x, Distance( km )')
ylabel('y, Energy Used Per Hour ( kWh )')
The outputs:

How to pass variadic arguments in Octave

I would like to implement a function duration = timer(n, f, arguments_of_f) that would measure how much time does a method f with arguments arguments_of_f need to run n times. My attempt was the following:
function duration = timer(n, f, arguments_of_f)
duration = 0;
for i=1:n
t0 = cputime;
f(arguments_of_f);
t1 = cputime;
duration += t1 - t0;
end
In another file, I have
function y = f(x)
y = x + 1;
end
The call d1 = timer(100, #f, 3); works as expected.
In another file, I have
function y = g(x1, x2)
y = x1 + x2;
end
but the call d2 = timer(100, #g, 1, 2); gives an error about undefined
argument x2, which is, when I look back, somehow expected, since I pass only
1 to g and 2 is never used.
So, how to implement the function timer in Octave, so that the call like
timer(4, #g, x1, ... , xK) would work? How can one pack the xs together?
So, I am looking for the analogue of Pythons *args trick:
def use_f(f, *args):
f(*args)
works if we define def f(x, y): return x + y and call use_f(f, 3, 4).
You don't need to pack all the arguments together, you just need to tell Octave that there is more than one argument coming and that they are all necessary. This is very easy to do using variadic arguments.
Your original implementation is nearly spot on: the necessary change is minimal. You need to change the variable arguments_to_f to the special name varargin, which is a magical cell array containing all your arbitrary undeclared arguments, and pass it with expansion instead of directly:
function duration = timer(n, f, varargin)
duration = 0;
for i=1:n
t0 = cputime;
f(varargin{:});
t1 = cputime;
duration += t1 - t0;
end
That's it. None of the other functions need to change.

Scilab plotting functions with if

I have a problen in scilab
How can I plot functions containing if and < like
function y = alpha(t)
if (t < 227.8) then
y = 0.75;
elseif (t < 300) then
y = 2.8 - 0.009 .* t;
else
y = 0.1;
end
endfunction
and
function [r]=minus_alpha(t)
r = 1 - alpha(t)
endfunction
When I use
x = linspace(0,300)
plot(x, alpha(x))
I got the error message
WARNING: Transposing row vector X to get compatible dimensions
plot2d: falsche Größe für Eingangsargument: inkompatible Größen.
Error 999 : in plot2d called by plot
Sorry for german mix. Thank you.
You can avoid explicit loop and be more efficient using the followin code
function y = alpha(t)
y=0.1*ones(t);
y(t<227.8)=0.75;
i=t>=227.8&t<300;
y(i)=2.8 - 0.009 .* t(i);
endfunction
It is really sad to see a great majority of Scilab community is not aware of vectorized operations. You can change your function to:
function y = alpha(t)
y = 0.1;
if t < 227.8 then
y = 0.75;
elseif t < 300 then
y = 2.8 - 0.009 * t;
end
y = 1 - y;
endfunction
and then use feval to broadcast the function over the sequence:
x = linspace(0, 300);
plot2d(x, feval(x, alpha));
which results:
rule of thumb if you are using for loop you need to revise your code and if someone is offering you a code where there is unnecessary for loop you shouldn't probably use it.
All the proposed answers are overcomplicated considering that the function alpha in the original demand is piecewise-affine. In Scilab in can be coded that way:
x = linspace(0,400,1000);
plot(x,linear_interpn(x,[227.8 300],[0.75 0.1]))
i.e. you just have to know the nodes coordinates (here abscissae) and value of the function at nodes. The function linear_interpn does also multilinear interpolation, it is worth knowing it guys...
If you check the output of your alpha(x), you will see that it is just a scalar (not a vector). I guess you wanted something like this, so it's necessary to iterate through t to compute each value of y based on the value of t:
clc;
clear;
function y = alpha(t)
for i=1:size(t,"*")
if t(i) < 227.8 then
y(i) = 0.75;
elseif t(i) < 300 then
y(i) = 2.8 - 0.009 * t(i);
else
y(i) = 0.1;
end
end
endfunction
x = linspace(0,300);
plot2d(x,alpha(x));
If you find the answer useful, please do not forget to accept it, so others will see that your problem is solved.
Before your answers (thank you) my workaround was a combination of indicator functions composed with floor and exp( -t^2):
function y = alpha(t)
y = floor(exp(-(t .* (t-T1)) / (T1*T1))) * 0.75
+ floor(exp(-((t-T2) .* (t- T1) / (2000)))) .* (2.8-0.009 .* t)
+ floor(exp(-((t-T2) .* (t-1000) / (200000))))*0.1
endfunction

Solving two coupled non-linear second order differentially equations numerically

I have encountered the following system of differential equations in lagrangian mechanics. Can you suggest a numerical method, with relevant links and references on how can I solve it. Also, is there a shorter implementation on Matlab or Mathematica?
mx (y dot)^2 + mgcosy - Mg - (M=m)(x double dot) =0
gsiny + 2(x dot)(y dot + x (y double dot)=0
where (x dot) or (y dot)= dx/dt or dy/dt, and the double dot indicated a double derivative wrt time.
You can create a vector Y = (x y u v)' so that
dx/dt = u
dy/dt = v
du/dt = d²x/dt²
dv/dt = d²y/dt²
It is possible to isolate the second derivatives from the equations, so you get
d²x/dt² = (m*g*cos(y) + m*x*v² - M*g)/(M-m)
d²y/dt² = -(g*sin(y) - 2*u*v)/x
Now, you can try to solve it using standard ODE solvers, such as Runge-Kutta methods. Matlab has a set of solvers, such as ode23. I didn't test he following, but it would be something like it:
function f = F(Y)
x = Y(1); y = Y(2); u = Y(3); v = Y(4);
f = [0,0,0,0];
f(1) = u;
f(2) = v;
f(3) = (m*g*cos(y) + m*x*v*v - M*g)/(M-m);
f(4) = -(g*sin(y) - 2*u*v)/x;
[T,Y] = ode23(F, time_period, Y0);