-def get_model(data):
- if len(data) == 2:
- return points_to_line(*data)
- else:
- return least_squares(data)
-
-def iterate(data, distance):
- consensus = 0
- consensual = initial_estimate(data)
- while (len(consensual) > consensus):
- consensus = len(consensual)
- model = get_model(consensual)
- consensual = filter_near(data, model, distance)
- return consensus, model, consensual
+class Linear_model:
+ def __init__(self, data):
+ self.data = data
+
+ def get(self, sample):
+ if len(sample) == 2:
+ return points_to_line(*sample)
+ else:
+ return least_squares(sample)
+
+ def initial(self):
+ return random.sample(self.data, 2)
+
+ def score(self, est, dist):
+ cons = []
+ score = 0
+ a, b, c = est
+ dst = lambda (x, y): abs(a * x + b * y + c) / sqrt(a*a+b*b)
+ for p in self.data:
+ d = dst(p)
+ if d <= dist:
+ cons.append(p)
+ score += min(d, dist)
+ return score, cons
+
+def iterate(model, distance):
+ score = float("inf")
+ consensual = model.initial()
+ estimate = model.get(consensual)
+ new_score, consensual = model.score(estimate, distance)
+ while (new_score < score):
+ score = new_score
+ try:
+ estimate = model.get(consensual)
+ except NP.linalg.LinAlgError:
+ pass
+ estimate = model.get(consensual)
+ new_score, consensual = model.score(estimate, distance)
+ return score, estimate, consensual