2020-04-05 20:27:56 +00:00
|
|
|
package de.wwwu.awolf.presenter.algorithms.naive;
|
2020-04-05 19:11:50 +00:00
|
|
|
|
2020-04-05 20:27:56 +00:00
|
|
|
import de.wwwu.awolf.model.dao.Line;
|
|
|
|
import de.wwwu.awolf.model.communication.AlgorithmMessage;
|
|
|
|
import de.wwwu.awolf.model.communication.Message;
|
2020-04-05 19:11:50 +00:00
|
|
|
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.Collections;
|
2020-04-05 20:27:56 +00:00
|
|
|
import java.util.HashMap;
|
2020-04-05 19:11:50 +00:00
|
|
|
import java.util.LinkedList;
|
|
|
|
import java.util.List;
|
2020-04-05 20:27:56 +00:00
|
|
|
import java.util.Map;
|
2020-04-05 19:11:50 +00:00
|
|
|
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.
|
|
|
|
*/
|
2020-04-05 20:27:56 +00:00
|
|
|
public class NaiveLeastMedianOfSquaresEstimator implements Algorithm {
|
2020-04-05 19:11:50 +00:00
|
|
|
|
|
|
|
private static final Algorithm.Type type = Type.NAIVE_LMS;
|
|
|
|
private List<Line> setOfLines = new ArrayList<>();
|
|
|
|
|
|
|
|
private int n;
|
|
|
|
private double ds, b, m;
|
2020-04-05 20:27:56 +00:00
|
|
|
private Flow.Subscriber<? super Message> subscriber;
|
2020-04-05 19:11:50 +00:00
|
|
|
private AbstractPresenter presenter;
|
2020-04-06 11:07:10 +00:00
|
|
|
private Map<String, String> parameter;
|
2020-04-05 19:11:50 +00:00
|
|
|
|
2020-04-05 20:27:56 +00:00
|
|
|
public NaiveLeastMedianOfSquaresEstimator() {
|
|
|
|
parameter = new HashMap<>();
|
|
|
|
}
|
2020-04-05 19:11:50 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Crude Algorithmus zum berechnen des LSM-Schätzers.
|
|
|
|
*/
|
|
|
|
private Line crudeAlg() {
|
|
|
|
ds = Double.MAX_VALUE;
|
|
|
|
b = 0d;
|
|
|
|
m = 0d;
|
|
|
|
List<Line> triple = new ArrayList<>();
|
|
|
|
double beta;
|
|
|
|
double alpha;
|
|
|
|
double dijk;
|
|
|
|
Logging.logInfo("=== S T A R T - naiv L M S ===");
|
|
|
|
long start;
|
|
|
|
long end;
|
|
|
|
start = System.currentTimeMillis();
|
|
|
|
for (Line i : setOfLines) {
|
|
|
|
for (Line j : setOfLines) {
|
|
|
|
for (Line k : setOfLines) {
|
|
|
|
triple.add(i);
|
|
|
|
triple.add(j);
|
|
|
|
triple.add(k);
|
|
|
|
Collections.sort(triple);
|
|
|
|
beta =
|
|
|
|
(triple.get(0).getB() - triple.get(2).getB()) / (
|
|
|
|
triple.get(0).getM() - triple.get(2)
|
|
|
|
.getM());
|
|
|
|
alpha =
|
|
|
|
(triple.get(1).getB() + triple.get(2).getB() - (beta * (
|
|
|
|
triple.get(1).getM() + triple
|
|
|
|
.get(2).getM()))) * 0.5;
|
|
|
|
dijk = f(alpha, beta);
|
|
|
|
if (dijk < ds) {
|
|
|
|
ds = dijk;
|
|
|
|
b = alpha;
|
|
|
|
m = beta;
|
|
|
|
}
|
|
|
|
triple.clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
end = System.currentTimeMillis();
|
|
|
|
Logging.logInfo("=== E N D - naiv L M S ===");
|
|
|
|
Logging.logInfo("Slope: " + getSlope() + ", y-Interception: " + getYInterception());
|
|
|
|
|
2020-04-05 20:27:56 +00:00
|
|
|
AlgorithmMessage data = new AlgorithmMessage();
|
2020-04-05 19:11:50 +00:00
|
|
|
data.setAlgorithmType(getType());
|
|
|
|
data.setType(SubscriberType.ALGORITHM);
|
|
|
|
data.setLineData(new Line(getSlope(), getYInterception()));
|
|
|
|
this.subscriber.onNext(data);
|
|
|
|
|
|
|
|
return new Line(getSlope(), getYInterception());
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Berechnet die Gerade mit dem medianen Fehler
|
|
|
|
*
|
|
|
|
* @param a y-Achsenabschnitt
|
|
|
|
* @param b Steigung
|
|
|
|
* @return medianer Fehler
|
|
|
|
*/
|
|
|
|
private Double f(double a, double b) {
|
|
|
|
List<Double> res = new ArrayList<>();
|
|
|
|
for (Line p : setOfLines) {
|
|
|
|
res.add(Math.abs(p.getB() - (a + b * p.getM())));
|
|
|
|
}
|
|
|
|
return FastElementSelector.randomizedSelect(res, res.size() * 0.5);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Line call() {
|
|
|
|
return crudeAlg();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void setInput(Set<Line> lines) {
|
|
|
|
this.setOfLines = new LinkedList<>(lines);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Type getType() {
|
|
|
|
return type;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void setPresenter(AbstractPresenter presenter) {
|
|
|
|
this.presenter = presenter;
|
|
|
|
subscribe(presenter);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return y-Achsenabschnitt
|
|
|
|
*/
|
|
|
|
public Double getYInterception() {
|
|
|
|
return b * -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return Steigung
|
|
|
|
*/
|
|
|
|
public Double getSlope() {
|
|
|
|
return m * -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-04-05 20:27:56 +00:00
|
|
|
public void subscribe(Flow.Subscriber<? super Message> subscriber) {
|
2020-04-05 19:11:50 +00:00
|
|
|
this.subscriber = subscriber;
|
|
|
|
}
|
2020-04-05 20:27:56 +00:00
|
|
|
|
|
|
|
@Override
|
2020-04-06 11:07:10 +00:00
|
|
|
public Map<String, String> getParameter() {
|
2020-04-05 20:27:56 +00:00
|
|
|
return this.parameter;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-04-06 11:07:10 +00:00
|
|
|
public void setParameter(Map<String, String> parameter) {
|
2020-04-05 20:27:56 +00:00
|
|
|
this.parameter = parameter;
|
|
|
|
}
|
2020-04-05 19:11:50 +00:00
|
|
|
}
|