package de.wwwu.awolf.presenter.algorithms.naiv; import de.wwwu.awolf.model.Line; import de.wwwu.awolf.model.communication.AlgorithmData; import de.wwwu.awolf.model.communication.Data; import de.wwwu.awolf.model.communication.SubscriberType; import de.wwwu.awolf.presenter.AbstractPresenter; import de.wwwu.awolf.presenter.algorithms.Algorithm; import de.wwwu.awolf.presenter.util.FastElementSelector; import de.wwwu.awolf.presenter.util.Logging; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.concurrent.Flow; /** * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. * * @Author: Armin Wolf * @Email: a_wolf28@uni-muenster.de * @Date: 15.09.2017. */ public class NaivTheilSenEstimator implements Algorithm { private static final Algorithm.Type type = Type.NAIV_TS; private List setOfLines; private double slope; private double yInterception; private Flow.Subscriber subscriber; private AbstractPresenter presenter; @Override public Line call() { this.slope = 0d; this.yInterception = 0d; Logging.logInfo("=== S T A R T - naiv T S ==="); long start; long end; start = System.currentTimeMillis(); List slopesList = new ArrayList<>(); int cnt = 0; for (int i = 0; i < setOfLines.size(); i++) { double x = setOfLines.get(i).getM(); double y = setOfLines.get(i).getB(); for (int j = i + 1; j < setOfLines.size(); j++) { if (x != setOfLines.get(j).getM()) { // x must be different, otherwise slope becomes infinite Double slope = (setOfLines.get(j).getB() - y) / (setOfLines.get(j).getM() - x); slopesList.add(slope); ++cnt; } } } List list1 = new ArrayList<>(); List list2 = new ArrayList<>(); for (Line line : setOfLines) { list1.add(line.getM()); list2.add(line.getB()); } double median1 = FastElementSelector.randomizedSelect(list1, list1.size() * 0.5); double median2 = FastElementSelector.randomizedSelect(list2, list2.size() * 0.5); slope = FastElementSelector.randomizedSelect(slopesList, slopesList.size() * 0.5); yInterception = median2 - slope * median1; end = System.currentTimeMillis(); Logging.logInfo("=== E N D - naiv T S ==="); Logging.logInfo("Slope: " + getSlope() + ", y-Interception: " + getYInterception()); AlgorithmData data = new AlgorithmData(); data.setAlgorithmType(getType()); data.setType(SubscriberType.ALGORITHM); data.setLineData(new Line(getSlope(), getYInterception())); this.subscriber.onNext(data); return new Line(getSlope(), getYInterception()); } @Override public void setInput(Set lines) { this.setOfLines = new ArrayList<>(lines); } @Override public Type getType() { return type; } @Override public void setPresenter(AbstractPresenter presenter) { this.presenter = presenter; subscribe(presenter); } /** * @return Steigung */ public double getSlope() { return slope * -1; } /** * @return y-Achsenabschnitt */ public double getYInterception() { return yInterception * -1; } @Override public void subscribe(Flow.Subscriber subscriber) { this.subscriber = subscriber; } }