algorithms-for-computing-li.../LinearRegressionTool/src/main/java/de/wwwu/awolf/presenter/algorithms/naiv/NaivTheilSenEstimator.java

115 lines
3.5 KiB
Java

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<Line> setOfLines;
private double slope;
private double yInterception;
private Flow.Subscriber<? super Data> 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<Double> 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<Double> list1 = new ArrayList<>();
List<Double> 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<Line> 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<? super Data> subscriber) {
this.subscriber = subscriber;
}
}