diff --git a/statistics/code/iv_curve.mat b/statistics/code/iv_curve.mat
new file mode 100644
index 0000000..d551ec7
Binary files /dev/null and b/statistics/code/iv_curve.mat differ
diff --git a/statistics/code/lin_regression.mat b/statistics/code/lin_regression.mat
new file mode 100644
index 0000000..6a21622
Binary files /dev/null and b/statistics/code/lin_regression.mat differ
diff --git a/statistics/code/lsq_error.m b/statistics/code/lsq_error.m
new file mode 100644
index 0000000..8fcaa30
--- /dev/null
+++ b/statistics/code/lsq_error.m
@@ -0,0 +1,6 @@
+function error = lsq_error(parameter, x, y)
+% parameter(1) is the slope
+% parameter(2) is the intercept
+
+f_x = x .* parameter(1) + parameter(2);
+error = mean((f_x - y).^2);
\ No newline at end of file
diff --git a/statistics/code/lsq_gradient.m b/statistics/code/lsq_gradient.m
new file mode 100644
index 0000000..6773c4e
--- /dev/null
+++ b/statistics/code/lsq_gradient.m
@@ -0,0 +1,7 @@
+function gradient = lsq_gradient(parameter, x, y)
+h = 1e-6;
+
+partial_m = (lsq_error([parameter(1)+h, parameter(2)],x,y) - lsq_error(parameter,x,y))/ h;
+partial_n = (lsq_error([parameter(1), parameter(2)+h],x,y) - lsq_error(parameter,x,y))/ h;
+
+gradient = [partial_m, partial_n];
\ No newline at end of file
diff --git a/statistics/code/lsq_gradient_sigmoid.m b/statistics/code/lsq_gradient_sigmoid.m
new file mode 100644
index 0000000..05e9721
--- /dev/null
+++ b/statistics/code/lsq_gradient_sigmoid.m
@@ -0,0 +1,9 @@
+function gradient = lsq_gradient_sigmoid(parameter, x, y)
+h = 1e-6;
+
+gradient = zeros(size(parameter));
+for i = 1:length(parameter)
+    parameter_h = parameter;
+    parameter_h(i) = parameter_h(i) + h;
+    gradient(i) = (lsq_sigmoid_error(parameter_h, x, y) - lsq_sigmoid_error(parameter, x, y)) / h;
+end
\ No newline at end of file
diff --git a/statistics/code/lsq_sigmoid_error.m b/statistics/code/lsq_sigmoid_error.m
new file mode 100644
index 0000000..5f05f21
--- /dev/null
+++ b/statistics/code/lsq_sigmoid_error.m
@@ -0,0 +1,8 @@
+function error = lsq_sigmoid_error(parameter, x, y)
+% p(1) the amplitude
+% p(2) the slope
+% p(3) the x-shift
+% p(4) the y-shift
+
+y_est = parameter(1)./(1+ exp(-parameter(2) .* (x - parameter(3)))) + parameter(4);
+error = mean((y_est - y).^2);
\ No newline at end of file
diff --git a/statistics/code/membraneVoltage.mat b/statistics/code/membraneVoltage.mat
new file mode 100644
index 0000000..26d9f44
Binary files /dev/null and b/statistics/code/membraneVoltage.mat differ
diff --git a/statistics/code/plot_error_surface.m b/statistics/code/plot_error_surface.m
new file mode 100644
index 0000000..1616e50
--- /dev/null
+++ b/statistics/code/plot_error_surface.m
@@ -0,0 +1,112 @@
+clear
+close all
+
+%% first, plot the raw data
+load('lin_regression.mat');
+
+figure()
+plot(x,y, 'o')
+xlabel('Input')
+ylabel('Output')
+
+%% plot the error surface
+clear
+load('lin_regression.mat')
+ms = -5:0.25:5;
+ns = -30:1:30;
+
+error_surf = zeros(length(ms), length(ns));
+
+for i = 1:length(ms)
+    for j = 1:length(ns)
+        error_surf(i,j) = lsq_error([ms(i), ns(j)], x, y);
+    end
+end
+
+
+% plot the error surface
+figure()
+[N,M] = meshgrid(ns, ms);
+s = surface(M,N,error_surf);
+xlabel('slope')
+ylabel('intercept')
+zlabel('error')
+view(3)
+% rotate(s, [1 1 0], 25 )
+
+%% Plot the gradient at different points in the surface
+clear
+load('lin_regression.mat')
+
+ms = -1:0.5:5;
+ns = -10:1:10;
+
+error_surf = zeros(length(ms), length(ns));
+gradient_m = zeros(size(error_surf));
+gradient_n = zeros(size(error_surf));
+
+for i = 1:length(ms)
+    for j = 1:length(ns)
+        error_surf(i,j) = lsq_error([ms(i), ns(j)], x, y);
+        grad = lsq_gradient([ms(i), ns(j)], x, y);
+        gradient_m(i,j) = grad(1);
+        gradient_n(i,j) = grad(2);
+    end
+end
+
+figure()
+hold on
+[N, M] = meshgrid(ns, ms);
+surface(M,N, error_surf, 'FaceAlpha', 0.5);
+contour(M,N, error_surf, 50);
+quiver(M,N, gradient_m, gradient_n)
+view(3)
+xlabel('slope')
+ylabel('intercept')
+zlabel('error')
+
+%% do the gradient descent
+clear 
+close all
+
+load('lin_regression.mat')
+
+ms = -1:0.5:5;
+ns = -10:1:10;
+
+position = [-2. 10.];
+gradient = [];
+error = [];
+eps = 0.01;
+
+% claculate error surface
+error_surf = zeros(length(ms), length(ns));
+for i = 1:length(ms)
+    for j = 1:length(ns)
+        error_surf(i,j) = lsq_error([ms(i), ns(j)], x, y);
+    end
+end
+figure()
+hold on
+[N, M] = meshgrid(ns, ms);
+surface(M,N, error_surf, 'FaceAlpha', 0.5);
+view(3)
+xlabel('slope')
+ylabel('intersection')
+zlabel('error')
+
+% do the descent
+
+while isempty(gradient) || norm(gradient) > 0.1
+    gradient = lsq_gradient(position, x,y);
+    error = lsq_error(position, x, y);
+    plot3(position(1), position(2), error, 'o', 'color', 'red')
+    position = position - eps .* gradient; 
+    pause(0.25)
+end
+disp('gradient descent done!')
+disp(strcat('final position: ', num2str(position)))
+disp(strcat('final error: ', num2str(error)))
+
+
+
diff --git a/statistics/code/sigmoidal_gradient_descent.m b/statistics/code/sigmoidal_gradient_descent.m
new file mode 100644
index 0000000..9763f5a
--- /dev/null
+++ b/statistics/code/sigmoidal_gradient_descent.m
@@ -0,0 +1,44 @@
+
+
+%% fit the sigmoid
+
+clear 
+close all
+
+load('iv_curve.mat')
+
+figure()
+plot(voltage, current, 'o')
+xlabel('voltate [mV]')
+ylabel('current [pA]')
+
+% amplitude, slope, x-shift, y-shift
+%parameter = [10 0.25 -50, 2.5];
+parameter = [20 0.5 -50, 2.5];
+
+eps = 0.1;
+% do the descent
+gradient = [];
+steps = 0;
+error = [];
+
+while isempty(gradient) || norm(gradient) > 0.01
+    steps = steps + 1; 
+    gradient = lsq_gradient_sigmoid(parameter, voltage, current);
+    error(steps) = lsq_sigmoid_error(parameter, voltage, current);
+    parameter = parameter - eps .* gradient; 
+end
+plot(1:steps, error)
+
+disp('gradient descent done!')
+disp(strcat('final position: ', num2str(parameter)))
+disp(strcat('final error: ', num2str(error(end))))
+
+%% use fminsearch
+parameter = [10 0.5 -50, 2.5];
+
+objective_function = @(p)lsq_sigmoid_error(p, voltage, current);
+param = fminunc(objective_function, parameter);
+disp(param)
+param1 = fminsearch(objective_function, parameter);
+disp(param1)