import numpy as np
import matplotlib.pyplot as plt

def generate_data(sigma_error):
	data = dict()
	number_of_data_points = 100
	mu_x = 1.2
	sigma_x = 0.3
	data['x'] = np.random.normal(mu_x, sigma_x, number_of_data_points)
	mu_error = 0.0
	data['y'] = 2.0 * data['x'] + 5.0 + np.random.normal(
			mu_error, sigma_error, number_of_data_points)
	return data

data = dict()
data[1] = generate_data(0.001)
data[2] = generate_data(0.1)
data[3] = generate_data(1.0)

plt.scatter(data[1]['x'], data[1]['y'])
plt.show()
plt.scatter(data[2]['x'], data[2]['y'])
plt.show()
plt.scatter(data[3]['x'], data[3]['y'])
plt.show()

def linear_regression(x_observed, y_observed):
	assert len(x_observed) == len(y_observed)
	a = np.random.normal(0.0, 1.0)
	b = np.random.normal(0.0, 1.0)
	learning_rate = 0.01
	number_of_epochs = 100000
	for idatum in range(number_of_epochs):
		y_predicted = a * x_observed + b
		loss = np.mean((y_observed - y_predicted)**2)   # not used
		dloss_da = -2 * np.mean(x_observed * (y_observed - y_predicted))
		dloss_db = -2 * np.mean(y_observed - y_predicted)
		a -= learning_rate * dloss_da
		b -= learning_rate * dloss_db
	return a, b

print('Fitted parameters:')
print(linear_regression(data[1]['x'], data[1]['y']))
print(linear_regression(data[2]['x'], data[2]['y']))
print(linear_regression(data[3]['x'], data[3]['y']))

