Skip to content

Instantly share code, notes, and snippets.

@benwilson512
Last active December 22, 2015 23:09
Show Gist options
  • Save benwilson512/6545215 to your computer and use it in GitHub Desktop.
Save benwilson512/6545215 to your computer and use it in GitHub Desktop.
# http://en.wikipedia.org/wiki/Simple_linear_regression
# Exchange.Calc.Regression.run(self, [{1,1},{2,2},{3,3}])
defmodule Exchange.Calc.Regression do
def run(recipient, points) do
n = length(points)
fn_builder = spawn(Exchange.Calc.Regression, :build_function, [recipient, []])
spawn(Exchange.Calc.Regression, :sum_products_avg, [fn_builder, points, n])
spawn(Exchange.Calc.Regression, :sum_x_sqr_avg, [fn_builder, points, n])
spawn(Exchange.Calc.Regression, :x_y_avg, [fn_builder, points, n])
end
def build_function(recipient, params) when length(params) == 4 do
sop_avg = Keyword.get(params, :sum_products_avg)
x_avg = Keyword.get(params, :x_avg)
y_avg = Keyword.get(params, :y_avg)
sum_x_sqr_avg = Keyword.get(params, :sum_x_sqr_avg)
slope = (
(sop_avg - x_avg * y_avg) /
(sum_x_sqr_avg - x_avg * x_avg)
)
intercept = y_avg - slope * x_avg
function = fn(x) -> slope * x + intercept end
recipient <- { :ok, function }
end
def build_function(recipient, params) do
receive do
{:ok, [{key, value}]} ->
build_function(recipient, Keyword.put(params, key, value))
end
end
def sum_products_avg(fn_builder, points, n) do
result = Enum.reduce(points, 0, fn ({x, y}, sum) -> sum + x * y end )
fn_builder <- {:ok, [sum_products_avg: result / n]}
end
def sum_x_sqr_avg(fn_builder, points, n) do
result = Enum.reduce(points, 0, fn ({x, _y}, sum) -> sum + x * x end )
fn_builder <- {:ok, [sum_x_sqr_avg: result / n]}
end
def x_y_avg(fn_builder, points, n) do
{x_avg, y_avg} = Enum.reduce(points, fn ({x1, y1}, {x2, y2}) -> {x1 + x2, y1 + y2} end)
fn_builder <- {:ok, [x_avg: x_avg / n]}
fn_builder <- {:ok, [y_avg: y_avg / n]}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment