further clean up
This commit is contained in:
parent
21c072fe7a
commit
a246f8f203
File diff suppressed because it is too large
Load Diff
|
@ -1,27 +1,12 @@
|
||||||
package de.wwwu.awolf;
|
package de.wwwu.awolf;
|
||||||
|
|
||||||
import de.wwwu.awolf.model.Line;
|
|
||||||
import de.wwwu.awolf.model.LineModel;
|
import de.wwwu.awolf.model.LineModel;
|
||||||
import de.wwwu.awolf.model.Point;
|
|
||||||
import de.wwwu.awolf.presenter.Presenter;
|
import de.wwwu.awolf.presenter.Presenter;
|
||||||
import de.wwwu.awolf.presenter.algorithms.advanced.LeastMedianOfSquaresEstimator;
|
|
||||||
import de.wwwu.awolf.presenter.algorithms.advanced.RepeatedMedianEstimator;
|
|
||||||
import de.wwwu.awolf.presenter.algorithms.advanced.TheilSenEstimator;
|
|
||||||
import de.wwwu.awolf.presenter.algorithms.naiv.NaivLeastMedianOfSquaresEstimator;
|
|
||||||
import de.wwwu.awolf.presenter.algorithms.naiv.NaivRepeatedMedianEstimator;
|
|
||||||
import de.wwwu.awolf.presenter.algorithms.naiv.NaivTheilSenEstimator;
|
|
||||||
import de.wwwu.awolf.presenter.generator.DatasetGenerator;
|
|
||||||
import de.wwwu.awolf.presenter.util.IntersectionComputer;
|
|
||||||
import de.wwwu.awolf.presenter.util.Logging;
|
import de.wwwu.awolf.presenter.util.Logging;
|
||||||
import de.wwwu.awolf.view.MainFrame;
|
import de.wwwu.awolf.view.MainFrame;
|
||||||
import org.apache.commons.cli.*;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||||
|
@ -49,62 +34,27 @@ public class App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Die Methode rechnet für gegebene Größen die Algorithmen durch und gibt jeweils die benötigte Zeit
|
|
||||||
*/
|
|
||||||
public static void benchmark() {
|
|
||||||
ExecutorService executorService = Executors.newFixedThreadPool(6);
|
|
||||||
|
|
||||||
Logging.logInfo("---- Datasetgröße: " + 100 + " ----");
|
|
||||||
DatasetGenerator generator = new DatasetGenerator();
|
|
||||||
LinkedList<Line> lines = generator.generateDataCloud(10000);
|
|
||||||
IntersectionComputer computer = new IntersectionComputer(lines);
|
|
||||||
ArrayList<Point> points = computer.compute();
|
|
||||||
|
|
||||||
executorService.submit(new NaivLeastMedianOfSquaresEstimator(lines));
|
|
||||||
executorService.submit(new NaivRepeatedMedianEstimator(lines));
|
|
||||||
executorService.submit(new NaivTheilSenEstimator(lines));
|
|
||||||
executorService.submit(new LeastMedianOfSquaresEstimator(lines, points));
|
|
||||||
executorService.submit(new RepeatedMedianEstimator(lines));
|
|
||||||
executorService.submit(new TheilSenEstimator(lines, points));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maim Methode
|
* Maim Methode
|
||||||
*
|
*
|
||||||
* @param argv
|
* @param argv
|
||||||
*/
|
*/
|
||||||
public static void main(String[] argv) {
|
public static void main(String[] argv) {
|
||||||
|
final Presenter presenter = new Presenter(new LineModel(), null);
|
||||||
Options options = new Options();
|
SwingUtilities.invokeLater(() -> {
|
||||||
options.addOption("benchmark", "Start stresstest");
|
MainFrame view = new MainFrame();
|
||||||
options.addOption("", "default");
|
setUIFont(new javax.swing.plaf.FontUIResource(new Font("SansSerif", Font.PLAIN, 12)));
|
||||||
CommandLineParser parser = new DefaultParser();
|
try {
|
||||||
|
UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
|
||||||
try {
|
} catch (ClassNotFoundException | UnsupportedLookAndFeelException | IllegalAccessException | InstantiationException e) {
|
||||||
CommandLine line = parser.parse(options, argv); // Sensitive
|
Logging.logError("Error with the UI. ", e);
|
||||||
String[] args = line.getArgs();
|
|
||||||
if (args.length > 0 && args[0].equals("benchmark")) {
|
|
||||||
benchmark();
|
|
||||||
} else {
|
|
||||||
final Presenter presenter = new Presenter(new LineModel(), null);
|
|
||||||
SwingUtilities.invokeLater(() -> {
|
|
||||||
MainFrame view = new MainFrame();
|
|
||||||
setUIFont(new javax.swing.plaf.FontUIResource(new Font("SansSerif", Font.PLAIN, 12)));
|
|
||||||
try {
|
|
||||||
UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
|
|
||||||
} catch (ClassNotFoundException | UnsupportedLookAndFeelException | IllegalAccessException | InstantiationException e) {
|
|
||||||
Logging.logError("Error with the UI. ", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
view.setPresenter(presenter);
|
|
||||||
view.setActionListeners();
|
|
||||||
presenter.setView(view);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} catch (ParseException e) {
|
|
||||||
Logging.logError("Error while parsing the command line arguments.", e);
|
view.setPresenter(presenter);
|
||||||
}
|
view.setActionListeners();
|
||||||
|
presenter.setView(view);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,16 +2,44 @@ package de.wwwu.awolf.model.communication;
|
||||||
|
|
||||||
import de.wwwu.awolf.presenter.algorithms.Algorithm;
|
import de.wwwu.awolf.presenter.algorithms.Algorithm;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class EvaluationData implements Data {
|
public class EvaluationData implements Data {
|
||||||
private SubscriberType type;
|
private SubscriberType type;
|
||||||
private List<Algorithm.Type> algorithmtypes;
|
private List<Algorithm.Type> algorithmtypes;
|
||||||
private List<Double> oneColumnresult;
|
private List<Serializable> oneColumnresult;
|
||||||
private List<List<String>> multipleColumnResult;
|
private Map<Algorithm.Type, Map<String, String>> multipleColumnResult;
|
||||||
|
|
||||||
|
private int rowsPerColumn;
|
||||||
private int column;
|
private int column;
|
||||||
private List<String> labels;
|
private List<String> labels;
|
||||||
|
|
||||||
|
public int getRowsPerColumn() {
|
||||||
|
return rowsPerColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRowsPerColumn(int rowsPerColumn) {
|
||||||
|
this.rowsPerColumn = rowsPerColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getColumn() {
|
||||||
|
return column;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setColumn(int col) {
|
||||||
|
this.column = col;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getLabels() {
|
||||||
|
return labels;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLabels(List<String> tableInput) {
|
||||||
|
this.labels = tableInput;
|
||||||
|
}
|
||||||
|
|
||||||
public List<Algorithm.Type> getAlgorithmtypes() {
|
public List<Algorithm.Type> getAlgorithmtypes() {
|
||||||
return algorithmtypes;
|
return algorithmtypes;
|
||||||
}
|
}
|
||||||
|
@ -20,19 +48,19 @@ public class EvaluationData implements Data {
|
||||||
this.algorithmtypes = algorithmtype;
|
this.algorithmtypes = algorithmtype;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Double> getOneColumnresult() {
|
public List<Serializable> getOneColumnresult() {
|
||||||
return oneColumnresult;
|
return oneColumnresult;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOneColumnresult(List<Double> oneColumnresult) {
|
public void setOneColumnresult(List<Serializable> oneColumnresult) {
|
||||||
this.oneColumnresult = oneColumnresult;
|
this.oneColumnresult = oneColumnresult;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<List<String>> getMultipleColumnResult() {
|
public Map<Algorithm.Type, Map<String, String>> getMultipleColumnResult() {
|
||||||
return multipleColumnResult;
|
return multipleColumnResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMultipleColumnResult(List<List<String>> multipleColumnResult) {
|
public void setMultipleColumnResult(Map<Algorithm.Type, Map<String, String>> multipleColumnResult) {
|
||||||
this.multipleColumnResult = multipleColumnResult;
|
this.multipleColumnResult = multipleColumnResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,12 +73,4 @@ public class EvaluationData implements Data {
|
||||||
public void setType(SubscriberType type) {
|
public void setType(SubscriberType type) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setColumn(int col) {
|
|
||||||
this.column = col;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLabels(List<String> tableInput) {
|
|
||||||
this.labels = tableInput;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
package de.wwwu.awolf.model.communication;
|
|
||||||
|
|
||||||
public class ExportData implements Data {
|
|
||||||
|
|
||||||
private SubscriberType type;
|
|
||||||
private String message;
|
|
||||||
|
|
||||||
public String getMessage() {
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMessage(String message) {
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SubscriberType getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setType(SubscriberType type) {
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,17 +2,14 @@ package de.wwwu.awolf.model.communication;
|
||||||
|
|
||||||
public enum SubscriberType {
|
public enum SubscriberType {
|
||||||
|
|
||||||
EVALUATE_DATASET_GENERATED,
|
|
||||||
EVAL_D,
|
EVAL_D,
|
||||||
EVAL_DS,
|
EVALUATION_TABLE_DATA,
|
||||||
EVAL_T,
|
EVAL_T,
|
||||||
LINES_RES,
|
LINES_RES,
|
||||||
LINES_RES_MULT,
|
LINES_RES_MULT,
|
||||||
LMS,
|
LMS,
|
||||||
RM,
|
RM,
|
||||||
TS,
|
TS,
|
||||||
IMPORT,
|
|
||||||
PICTURE,
|
PICTURE,
|
||||||
EXPORT,
|
|
||||||
GENERATOR
|
GENERATOR
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package de.wwwu.awolf.model.evaluation;
|
||||||
|
|
||||||
|
import de.wwwu.awolf.model.Line;
|
||||||
|
import de.wwwu.awolf.presenter.algorithms.Algorithm;
|
||||||
|
|
||||||
|
import java.util.EnumMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class ComparisonResult {
|
||||||
|
|
||||||
|
private final Map<Algorithm.Type, Line> resultMapping;
|
||||||
|
|
||||||
|
public ComparisonResult() {
|
||||||
|
this.resultMapping = new EnumMap<>(Algorithm.Type.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void put(final Algorithm.Type type, final Line lineResult) {
|
||||||
|
this.resultMapping.put(type, lineResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Line get(final Algorithm.Type type) {
|
||||||
|
return this.resultMapping.get(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ package de.wwwu.awolf.presenter;
|
||||||
|
|
||||||
import de.wwwu.awolf.model.LineModel;
|
import de.wwwu.awolf.model.LineModel;
|
||||||
import de.wwwu.awolf.model.communication.Data;
|
import de.wwwu.awolf.model.communication.Data;
|
||||||
|
import de.wwwu.awolf.presenter.data.DataProvider;
|
||||||
import de.wwwu.awolf.presenter.evaluation.EvaluateAlgorithms;
|
import de.wwwu.awolf.presenter.evaluation.EvaluateAlgorithms;
|
||||||
import de.wwwu.awolf.presenter.util.IntersectionComputer;
|
import de.wwwu.awolf.presenter.util.IntersectionComputer;
|
||||||
import de.wwwu.awolf.presenter.util.Logging;
|
import de.wwwu.awolf.presenter.util.Logging;
|
||||||
|
@ -25,6 +26,7 @@ public abstract class AbstractPresenter implements Flow.Subscriber<Data> {
|
||||||
private LineModel model;
|
private LineModel model;
|
||||||
private MainFrame view;
|
private MainFrame view;
|
||||||
private EvaluateAlgorithms eval;
|
private EvaluateAlgorithms eval;
|
||||||
|
private DataProvider dataProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Konstruktor
|
* Konstruktor
|
||||||
|
@ -36,6 +38,7 @@ public abstract class AbstractPresenter implements Flow.Subscriber<Data> {
|
||||||
this.model = model;
|
this.model = model;
|
||||||
this.view = view;
|
this.view = view;
|
||||||
executor = Executors.newCachedThreadPool();
|
executor = Executors.newCachedThreadPool();
|
||||||
|
dataProvider = new DataProvider(this);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,21 +52,9 @@ public abstract class AbstractPresenter implements Flow.Subscriber<Data> {
|
||||||
@Override
|
@Override
|
||||||
public void onNext(Data data) {
|
public void onNext(Data data) {
|
||||||
switch (data.getType()) {
|
switch (data.getType()) {
|
||||||
case EVAL_D:
|
case EVALUATION_TABLE_DATA:
|
||||||
evaluatedData(data);
|
|
||||||
break;
|
|
||||||
case EVAL_DS:
|
|
||||||
evaluatedDatas(data);
|
evaluatedDatas(data);
|
||||||
break;
|
break;
|
||||||
case EVAL_T:
|
|
||||||
evaluatedTypes(data);
|
|
||||||
break;
|
|
||||||
case LINES_RES:
|
|
||||||
visualizeResults(data);
|
|
||||||
break;
|
|
||||||
case LINES_RES_MULT:
|
|
||||||
visualizeMultipleData(data);
|
|
||||||
break;
|
|
||||||
case LMS:
|
case LMS:
|
||||||
visualizeLmsAlgorithm(data);
|
visualizeLmsAlgorithm(data);
|
||||||
break;
|
break;
|
||||||
|
@ -73,12 +64,6 @@ public abstract class AbstractPresenter implements Flow.Subscriber<Data> {
|
||||||
case TS:
|
case TS:
|
||||||
visualizeTsAlgorithm(data);
|
visualizeTsAlgorithm(data);
|
||||||
break;
|
break;
|
||||||
case IMPORT:
|
|
||||||
handleImport(data);
|
|
||||||
break;
|
|
||||||
case EXPORT:
|
|
||||||
handleExport(data);
|
|
||||||
break;
|
|
||||||
case GENERATOR:
|
case GENERATOR:
|
||||||
Logging.logInfo("Generierung war Erfolgreich");
|
Logging.logInfo("Generierung war Erfolgreich");
|
||||||
break;
|
break;
|
||||||
|
@ -87,26 +72,14 @@ public abstract class AbstractPresenter implements Flow.Subscriber<Data> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void handleExport(Data data);
|
|
||||||
|
|
||||||
protected abstract void handleImport(Data data);
|
|
||||||
|
|
||||||
protected abstract void visualizeTsAlgorithm(Data data);
|
protected abstract void visualizeTsAlgorithm(Data data);
|
||||||
|
|
||||||
protected abstract void visualizeRmAlgorithm(Data data);
|
protected abstract void visualizeRmAlgorithm(Data data);
|
||||||
|
|
||||||
protected abstract void visualizeLmsAlgorithm(Data data);
|
protected abstract void visualizeLmsAlgorithm(Data data);
|
||||||
|
|
||||||
protected abstract void visualizeMultipleData(Data data);
|
|
||||||
|
|
||||||
protected abstract void visualizeResults(Data data);
|
|
||||||
|
|
||||||
protected abstract void evaluatedTypes(Data data);
|
|
||||||
|
|
||||||
protected abstract void evaluatedDatas(Data data);
|
protected abstract void evaluatedDatas(Data data);
|
||||||
|
|
||||||
protected abstract void evaluatedData(Data data);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onError(Throwable throwable) {
|
public void onError(Throwable throwable) {
|
||||||
|
|
||||||
|
@ -143,7 +116,7 @@ public abstract class AbstractPresenter implements Flow.Subscriber<Data> {
|
||||||
start = System.currentTimeMillis();
|
start = System.currentTimeMillis();
|
||||||
startIntersectionCalculation();
|
startIntersectionCalculation();
|
||||||
end = System.currentTimeMillis();
|
end = System.currentTimeMillis();
|
||||||
Logging.logInfo("Zeit: " + (end - start) / 1000);
|
Logging.logInfo("Computing intersections took " + (end - start) / 1000 + "ms");
|
||||||
});
|
});
|
||||||
|
|
||||||
//darstellung der Ergebnisse
|
//darstellung der Ergebnisse
|
||||||
|
@ -200,7 +173,15 @@ public abstract class AbstractPresenter implements Flow.Subscriber<Data> {
|
||||||
this.eval = eval;
|
this.eval = eval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DataProvider getDataProvider() {
|
||||||
|
return dataProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public ExecutorService getExecutor() {
|
public ExecutorService getExecutor() {
|
||||||
return executor;
|
if (executor == null)
|
||||||
|
return Executors.newCachedThreadPool();
|
||||||
|
else
|
||||||
|
return executor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,16 +4,12 @@ import de.wwwu.awolf.model.Line;
|
||||||
import de.wwwu.awolf.model.LineModel;
|
import de.wwwu.awolf.model.LineModel;
|
||||||
import de.wwwu.awolf.model.communication.AlgorithmData;
|
import de.wwwu.awolf.model.communication.AlgorithmData;
|
||||||
import de.wwwu.awolf.model.communication.Data;
|
import de.wwwu.awolf.model.communication.Data;
|
||||||
import de.wwwu.awolf.model.communication.ExportData;
|
import de.wwwu.awolf.model.communication.EvaluationData;
|
||||||
import de.wwwu.awolf.model.communication.ImportData;
|
|
||||||
import de.wwwu.awolf.presenter.algorithms.advanced.LeastMedianOfSquaresEstimator;
|
import de.wwwu.awolf.presenter.algorithms.advanced.LeastMedianOfSquaresEstimator;
|
||||||
import de.wwwu.awolf.presenter.algorithms.advanced.RepeatedMedianEstimator;
|
import de.wwwu.awolf.presenter.algorithms.advanced.RepeatedMedianEstimator;
|
||||||
import de.wwwu.awolf.presenter.algorithms.advanced.TheilSenEstimator;
|
import de.wwwu.awolf.presenter.algorithms.advanced.TheilSenEstimator;
|
||||||
|
import de.wwwu.awolf.presenter.data.DataProvider;
|
||||||
import de.wwwu.awolf.presenter.evaluation.EvaluateAlgorithms;
|
import de.wwwu.awolf.presenter.evaluation.EvaluateAlgorithms;
|
||||||
import de.wwwu.awolf.presenter.evaluation.PictureProcessor;
|
|
||||||
import de.wwwu.awolf.presenter.generator.DatasetGenerator;
|
|
||||||
import de.wwwu.awolf.presenter.io.DataExporter;
|
|
||||||
import de.wwwu.awolf.presenter.io.DataImporter;
|
|
||||||
import de.wwwu.awolf.presenter.util.Logging;
|
import de.wwwu.awolf.presenter.util.Logging;
|
||||||
import de.wwwu.awolf.view.MainFrame;
|
import de.wwwu.awolf.view.MainFrame;
|
||||||
|
|
||||||
|
@ -36,33 +32,12 @@ public class Presenter extends AbstractPresenter {
|
||||||
super(model, view);
|
super(model, view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void handleExport(Data data) {
|
|
||||||
ExportData exportData = (ExportData) data;
|
|
||||||
Logging.logInfo(exportData.getMessage());
|
|
||||||
Logging.logInfo("Export der Daten als CSV");
|
|
||||||
Logging.logInfo("Export war Erfolgreich");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void handleImport(Data data) {
|
|
||||||
ImportData importData = (ImportData) data;
|
|
||||||
double max = importData.getNumberOfLines();
|
|
||||||
double current = importData.getCurrent();
|
|
||||||
Integer progress = (int) (100 * (current / max));
|
|
||||||
//100% erreicht
|
|
||||||
Logging.logInfo("Import war erfolgreich!");
|
|
||||||
SwingUtilities.invokeLater(() -> getView().showImportProgress(progress));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void visualizeTsAlgorithm(Data data) {
|
protected void visualizeTsAlgorithm(Data data) {
|
||||||
AlgorithmData algorithmData = (AlgorithmData) data;
|
AlgorithmData algorithmData = (AlgorithmData) data;
|
||||||
SwingUtilities.invokeLater(() -> getView().visualizeTS(algorithmData.getLineData()));
|
SwingUtilities.invokeLater(() -> getView().visualizeTS(algorithmData.getLineData()));
|
||||||
Logging.logInfo("Theil-Sen Estimator");
|
Logging.logInfo("Theil-Sen Estimator");
|
||||||
Logging.logInfo(algorithmData.getLineData().toString());
|
Logging.logInfo(algorithmData.getLineData().toString());
|
||||||
Logging.logInfo("Berechnung wurde Erfolgreich durchgeführt.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -71,7 +46,6 @@ public class Presenter extends AbstractPresenter {
|
||||||
SwingUtilities.invokeLater(() -> getView().visualizeRM(algorithmData.getLineData()));
|
SwingUtilities.invokeLater(() -> getView().visualizeRM(algorithmData.getLineData()));
|
||||||
Logging.logInfo("Repeated Median Estimator");
|
Logging.logInfo("Repeated Median Estimator");
|
||||||
Logging.logInfo(algorithmData.getLineData().toString());
|
Logging.logInfo(algorithmData.getLineData().toString());
|
||||||
Logging.logInfo("Berechnung wurde Erfolgreich durchgeführt.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -80,34 +54,12 @@ public class Presenter extends AbstractPresenter {
|
||||||
SwingUtilities.invokeLater(() -> getView().visualizeLMS(algorithmData.getLineData()));
|
SwingUtilities.invokeLater(() -> getView().visualizeLMS(algorithmData.getLineData()));
|
||||||
Logging.logInfo("Least Median of Squares");
|
Logging.logInfo("Least Median of Squares");
|
||||||
Logging.logInfo(algorithmData.getLineData().toString());
|
Logging.logInfo(algorithmData.getLineData().toString());
|
||||||
Logging.logInfo("Berechnung wurde Erfolgreich durchgeführt.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void visualizeMultipleData(Data data) {
|
|
||||||
//Result:
|
|
||||||
//0:
|
|
||||||
SwingUtilities.invokeLater(() -> getView().drawLineResults(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void visualizeResults(Data data) {
|
|
||||||
SwingUtilities.invokeLater(() -> getView().drawLineResults(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void evaluatedTypes(Data data) {
|
|
||||||
SwingUtilities.invokeLater(() -> getView().appendEvalResult(result, Integer.parseInt(result[1]), true));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void evaluatedDatas(Data data) {
|
protected void evaluatedDatas(Data data) {
|
||||||
SwingUtilities.invokeLater(() -> getView().appendEvalResult(result));
|
EvaluationData evaluationData = (EvaluationData) data;
|
||||||
}
|
SwingUtilities.invokeLater(() -> getView().appendEvalResults(evaluationData.getMultipleColumnResult()));
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void evaluatedData(Data data) {
|
|
||||||
SwingUtilities.invokeLater(() -> getView().appendEvalResult(result, Integer.parseInt(result[1]), false));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -128,14 +80,13 @@ public class Presenter extends AbstractPresenter {
|
||||||
if (input[0] != null && input[1] != null) {
|
if (input[0] != null && input[1] != null) {
|
||||||
//Parameter für den Algortihmus
|
//Parameter für den Algortihmus
|
||||||
Double constant = Double.parseDouble(input[0]);
|
Double constant = Double.parseDouble(input[0]);
|
||||||
Double error = Double.parseDouble(input[1]);
|
double error = Double.parseDouble(input[1]);
|
||||||
LeastMedianOfSquaresEstimator lms = new LeastMedianOfSquaresEstimator(getModel().getLines(), getModel().getNodes(), this);
|
LeastMedianOfSquaresEstimator lms = new LeastMedianOfSquaresEstimator(getModel().getLines(), getModel().getNodes(), this);
|
||||||
//setzen der Parameter
|
//setzen der Parameter
|
||||||
lms.setConstant(constant);
|
lms.setConstant(constant);
|
||||||
lms.setQuantileError(error);
|
lms.setQuantileError(error);
|
||||||
//Presenter soll die Klasse überwachen
|
//Presenter soll die Klasse überwachen
|
||||||
getExecutor().execute(lms);
|
getExecutor().submit(lms);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -151,8 +102,7 @@ public class Presenter extends AbstractPresenter {
|
||||||
Double parameter = Double.parseDouble(input);
|
Double parameter = Double.parseDouble(input);
|
||||||
rm.setBeta(parameter);
|
rm.setBeta(parameter);
|
||||||
//Presenter soll die Klasse überwachen
|
//Presenter soll die Klasse überwachen
|
||||||
|
getExecutor().submit(rm);
|
||||||
getExecutor().execute(rm);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -166,8 +116,7 @@ public class Presenter extends AbstractPresenter {
|
||||||
if (input != null) {
|
if (input != null) {
|
||||||
TheilSenEstimator ts = new TheilSenEstimator(getModel().getLines(), getModel().getNodes(), this);
|
TheilSenEstimator ts = new TheilSenEstimator(getModel().getLines(), getModel().getNodes(), this);
|
||||||
//Presenter soll die Klasse überwachen
|
//Presenter soll die Klasse überwachen
|
||||||
|
getExecutor().submit(ts);
|
||||||
getExecutor().execute(ts);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,41 +130,12 @@ public class Presenter extends AbstractPresenter {
|
||||||
* @param file importierender Datensatz
|
* @param file importierender Datensatz
|
||||||
*/
|
*/
|
||||||
public void startImport(File file) {
|
public void startImport(File file) {
|
||||||
|
List<Line> data = getDataProvider().getData(file);
|
||||||
DataImporter importer = new DataImporter(file, this);
|
if (data != null) {
|
||||||
//Presenter soll die Klasse überwachen
|
//Berechnung der Schnittpunkte und vis. der Ergebnisse (anz. Geraden, anz. Schnittpunkte)
|
||||||
|
getModel().setLines(data);
|
||||||
getExecutor().execute(new Runnable() {
|
computeIntersections();
|
||||||
@Override
|
}
|
||||||
public void run() {
|
|
||||||
List<Line> importedLines = importer.run();
|
|
||||||
if (importedLines != null) {
|
|
||||||
//Berechnung der Schnittpunkte und vis. der Ergebnisse (anz. Geraden, anz. Schnittpunkte)
|
|
||||||
getModel().setLines(importedLines);
|
|
||||||
computeIntersections();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Startet den Import eines Bildes.
|
|
||||||
*
|
|
||||||
* @param file importierendes Bild
|
|
||||||
*/
|
|
||||||
public void startPictureDataImport(File file) {
|
|
||||||
PictureProcessor pictureProcessor = new PictureProcessor(this, file);
|
|
||||||
//Presenter soll die Klasse überwachen
|
|
||||||
|
|
||||||
getExecutor().execute(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
pictureProcessor.run();
|
|
||||||
//Berechnung der Schnittpunkte und vis. der Ergebnisse (anz. Geraden, anz. Schnittpunkte)
|
|
||||||
computeIntersections();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,15 +145,7 @@ public class Presenter extends AbstractPresenter {
|
||||||
* @param file Datei in der die Informationen gespeichert werden sollen
|
* @param file Datei in der die Informationen gespeichert werden sollen
|
||||||
*/
|
*/
|
||||||
public void startExport(File file) {
|
public void startExport(File file) {
|
||||||
DataExporter exporter = new DataExporter(getModel().getLines(), file, this);
|
getDataProvider().exportData(file, getModel().getLines());
|
||||||
//Presenter soll die Klasse überwachen
|
|
||||||
|
|
||||||
getExecutor().execute(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
exporter.export();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -242,15 +154,7 @@ public class Presenter extends AbstractPresenter {
|
||||||
* @param file Datei in der die Informationen gespeichert werden sollen
|
* @param file Datei in der die Informationen gespeichert werden sollen
|
||||||
*/
|
*/
|
||||||
public void startDatasetExportEvaluation(File file) {
|
public void startDatasetExportEvaluation(File file) {
|
||||||
DataExporter exporter = new DataExporter(getEval().getData(), file, this);
|
getDataProvider().exportData(file, getEval().getData());
|
||||||
//Presenter soll die Klasse überwachen
|
|
||||||
|
|
||||||
getExecutor().execute(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
exporter.export();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -259,23 +163,11 @@ public class Presenter extends AbstractPresenter {
|
||||||
* @param n Größe des Datensatzes
|
* @param n Größe des Datensatzes
|
||||||
* @param type Art der Datensatzes
|
* @param type Art der Datensatzes
|
||||||
*/
|
*/
|
||||||
public void generateDataset(int n, int type) {
|
public void generateDataset(int n, DataProvider.DataType type) {
|
||||||
DatasetGenerator generator = new DatasetGenerator(this);
|
List<Line> data = getDataProvider().getData(type, n);
|
||||||
getExecutor().execute(() -> {
|
getModel().setLines(data);
|
||||||
switch (type) {
|
computeIntersections();
|
||||||
case 1:
|
getView().enableFunctionality();
|
||||||
getModel().setLines(generator.generateDataLines(n));
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
getModel().setLines(generator.generateCircle(n));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
getModel().setLines(generator.generateDataCloud(n));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
computeIntersections();
|
|
||||||
getView().enableFunctionality();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -286,14 +178,10 @@ public class Presenter extends AbstractPresenter {
|
||||||
* @param typ Typ der Evaluation
|
* @param typ Typ der Evaluation
|
||||||
* @param n Größe des Datensatzes
|
* @param n Größe des Datensatzes
|
||||||
* @param alg code für die auszuführenden Algorithmen (siehe <code>EvaluationPanel.checkSelection()</code> Method)
|
* @param alg code für die auszuführenden Algorithmen (siehe <code>EvaluationPanel.checkSelection()</code> Method)
|
||||||
* @param datasettyp Typ des Datensatzes (Geradem Punktwolke, Kreis und Gerade)
|
* @param datasetTyp Typ des Datensatzes (Geradem Punktwolke, Kreis und Gerade)
|
||||||
*/
|
*/
|
||||||
public void startEvaluation(int typ, int n, int alg, String datasettyp) {
|
public void startEvaluation(int typ, int n, int alg, DataProvider.DataType datasetTyp) {
|
||||||
setEval(new EvaluateAlgorithms(typ, n, alg, datasettyp, this));
|
getExecutor().submit(new EvaluateAlgorithms(typ, n, alg, datasetTyp, this));
|
||||||
|
|
||||||
getExecutor().submit(() -> {
|
|
||||||
getEval().run();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -306,14 +194,6 @@ public class Presenter extends AbstractPresenter {
|
||||||
* @param file Typ des Datensatzes (Geradem Punktwolke, Kreis und Gerade)
|
* @param file Typ des Datensatzes (Geradem Punktwolke, Kreis und Gerade)
|
||||||
*/
|
*/
|
||||||
public void startEvaluation(int typ, int alg, File file) {
|
public void startEvaluation(int typ, int alg, File file) {
|
||||||
|
getExecutor().submit(new EvaluateAlgorithms(typ, alg, file, this));
|
||||||
EvaluateAlgorithms evaluateAlgorithms = new EvaluateAlgorithms(typ, alg, file);
|
|
||||||
if (evaluateAlgorithms.getData().size() > 0) {
|
|
||||||
setEval(evaluateAlgorithms);
|
|
||||||
|
|
||||||
}
|
|
||||||
getExecutor().submit(() -> {
|
|
||||||
getEval().run();
|
|
||||||
}).isDone();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
package de.wwwu.awolf.presenter.algorithms;
|
package de.wwwu.awolf.presenter.algorithms;
|
||||||
|
|
||||||
|
import de.wwwu.awolf.model.Line;
|
||||||
|
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||||
*
|
*
|
||||||
|
@ -7,7 +11,14 @@ package de.wwwu.awolf.presenter.algorithms;
|
||||||
* @Email: a_wolf28@uni-muenster.de
|
* @Email: a_wolf28@uni-muenster.de
|
||||||
* @Date: 28.05.2017.
|
* @Date: 28.05.2017.
|
||||||
*/
|
*/
|
||||||
public interface Algorithm extends Runnable {
|
public interface Algorithm extends Callable<Line> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Startet die Berechnung des jeweiligen Algorithmus.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
Line call();
|
||||||
|
|
||||||
|
|
||||||
enum Type {
|
enum Type {
|
||||||
LMS,
|
LMS,
|
||||||
|
@ -17,16 +28,4 @@ public interface Algorithm extends Runnable {
|
||||||
NAIV_RM,
|
NAIV_RM,
|
||||||
NAIV_TS
|
NAIV_TS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Startet die Berechnung des jeweiligen Algorithmus.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
void run();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Standardisierung der Lösung in Form (m,b), sodass die Geraden Visualisiert werden können.
|
|
||||||
*/
|
|
||||||
void pepareResult();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@ import de.wwwu.awolf.presenter.algorithms.Algorithm;
|
||||||
import de.wwwu.awolf.presenter.util.IntersectionCounter;
|
import de.wwwu.awolf.presenter.util.IntersectionCounter;
|
||||||
import de.wwwu.awolf.presenter.util.Logging;
|
import de.wwwu.awolf.presenter.util.Logging;
|
||||||
|
|
||||||
import java.security.SecureRandom;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.Flow;
|
import java.util.concurrent.Flow;
|
||||||
|
|
||||||
|
@ -82,7 +81,8 @@ public class LeastMedianOfSquaresEstimator implements Algorithm, Flow.Publisher<
|
||||||
* „A practical approximation algorithm for the LMS line estimator“. 2007
|
* „A practical approximation algorithm for the LMS line estimator“. 2007
|
||||||
* Computational statistics & data Analysis 51.5, S. 2461–2486
|
* Computational statistics & data Analysis 51.5, S. 2461–2486
|
||||||
*/
|
*/
|
||||||
public void run() {
|
@Override
|
||||||
|
public Line call() {
|
||||||
|
|
||||||
Logging.logInfo("=== S T A R T - L M S ===");
|
Logging.logInfo("=== S T A R T - L M S ===");
|
||||||
long start;
|
long start;
|
||||||
|
@ -103,7 +103,7 @@ public class LeastMedianOfSquaresEstimator implements Algorithm, Flow.Publisher<
|
||||||
intervals = new PriorityQueue<>(comparator);
|
intervals = new PriorityQueue<>(comparator);
|
||||||
intervals.add(new Interval(-100000, 100000));
|
intervals.add(new Interval(-100000, 100000));
|
||||||
heightsigmaMin = Double.MAX_VALUE;
|
heightsigmaMin = Double.MAX_VALUE;
|
||||||
List<Point> tmpIntersections = intersections;
|
List<Point> tmpIntersections = new ArrayList<>(intersections);
|
||||||
|
|
||||||
//(3.) Apply the following steps as long as the exists active intervals
|
//(3.) Apply the following steps as long as the exists active intervals
|
||||||
boolean active = true;
|
boolean active = true;
|
||||||
|
@ -120,7 +120,7 @@ public class LeastMedianOfSquaresEstimator implements Algorithm, Flow.Publisher<
|
||||||
} else {
|
} else {
|
||||||
//(c.) otherwise....
|
//(c.) otherwise....
|
||||||
// get random intersections point...
|
// get random intersections point...
|
||||||
Collections.shuffle(tmpIntersections, new SecureRandom());
|
Collections.shuffle(tmpIntersections);
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
for (Point tmpIntersection : tmpIntersections) {
|
for (Point tmpIntersection : tmpIntersections) {
|
||||||
if (tmpIntersection.getX() > interval.getLower()
|
if (tmpIntersection.getX() > interval.getLower()
|
||||||
|
@ -156,7 +156,7 @@ public class LeastMedianOfSquaresEstimator implements Algorithm, Flow.Publisher<
|
||||||
end = System.currentTimeMillis();
|
end = System.currentTimeMillis();
|
||||||
Logging.logInfo("Zeit: " + ((end - start) / 1000));
|
Logging.logInfo("Zeit: " + ((end - start) / 1000));
|
||||||
|
|
||||||
pepareResult();
|
return pepareResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -367,8 +367,7 @@ public class LeastMedianOfSquaresEstimator implements Algorithm, Flow.Publisher<
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private Line pepareResult() {
|
||||||
public void pepareResult() {
|
|
||||||
if (this.subscriber != null) {
|
if (this.subscriber != null) {
|
||||||
double m = (getSigmaMin().getX2() + getSigmaMin().getX1()) * 0.5;
|
double m = (getSigmaMin().getX2() + getSigmaMin().getX1()) * 0.5;
|
||||||
double b = (getSigmaMin().getY2() + getSigmaMin().getY1()) * -0.5;
|
double b = (getSigmaMin().getY2() + getSigmaMin().getY1()) * -0.5;
|
||||||
|
@ -387,6 +386,8 @@ public class LeastMedianOfSquaresEstimator implements Algorithm, Flow.Publisher<
|
||||||
slope = m;
|
slope = m;
|
||||||
yInterception = b;
|
yInterception = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return new Line(getSlope(), getYInterception());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -455,7 +456,7 @@ public class LeastMedianOfSquaresEstimator implements Algorithm, Flow.Publisher<
|
||||||
/**
|
/**
|
||||||
* @return y-Achsenabschnitt
|
* @return y-Achsenabschnitt
|
||||||
*/
|
*/
|
||||||
public Double getyInterception() {
|
public Double getYInterception() {
|
||||||
return yInterception;
|
return yInterception;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -104,7 +104,7 @@ public class RepeatedMedianEstimator implements Algorithm, Flow.Publisher<Data>
|
||||||
* „Efficient Randomized Algorithms for the Repeated Median Line Estimator“. 1998
|
* „Efficient Randomized Algorithms for the Repeated Median Line Estimator“. 1998
|
||||||
* Algorithmica 20.2, S. 136–150
|
* Algorithmica 20.2, S. 136–150
|
||||||
*/
|
*/
|
||||||
public void run() {
|
public Line call() {
|
||||||
|
|
||||||
Logging.logInfo("=== S T A R T - R M ===");
|
Logging.logInfo("=== S T A R T - R M ===");
|
||||||
long start;
|
long start;
|
||||||
|
@ -145,7 +145,7 @@ public class RepeatedMedianEstimator implements Algorithm, Flow.Publisher<Data>
|
||||||
end = System.currentTimeMillis();
|
end = System.currentTimeMillis();
|
||||||
Logging.logInfo("Zeit: " + ((end - start) / 1000));
|
Logging.logInfo("Zeit: " + ((end - start) / 1000));
|
||||||
|
|
||||||
pepareResult();
|
return pepareResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -252,8 +252,7 @@ public class RepeatedMedianEstimator implements Algorithm, Flow.Publisher<Data>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private Line pepareResult() {
|
||||||
public void pepareResult() {
|
|
||||||
if (this.subscriber != null) {
|
if (this.subscriber != null) {
|
||||||
double m = thetaLow;
|
double m = thetaLow;
|
||||||
double b = (-1) * (
|
double b = (-1) * (
|
||||||
|
@ -272,6 +271,8 @@ public class RepeatedMedianEstimator implements Algorithm, Flow.Publisher<Data>
|
||||||
slope = m;
|
slope = m;
|
||||||
yInterception = b;
|
yInterception = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return new Line(getSlope(), getyInterception());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -95,7 +95,7 @@ public class TheilSenEstimator implements Algorithm, Flow.Publisher<Data> {
|
||||||
* "Jiri Matousek, Randomized optimal algorithm for slope selection,
|
* "Jiri Matousek, Randomized optimal algorithm for slope selection,
|
||||||
* Information Processing Letters 39 (1991) 183-187
|
* Information Processing Letters 39 (1991) 183-187
|
||||||
*/
|
*/
|
||||||
public void run() {
|
public Line call() {
|
||||||
//damit eine initiale Ordnung herscht
|
//damit eine initiale Ordnung herscht
|
||||||
//Collections.sort(intervalIntersections);
|
//Collections.sort(intervalIntersections);
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ public class TheilSenEstimator implements Algorithm, Flow.Publisher<Data> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pepareResult();
|
return pepareResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -216,8 +216,7 @@ public class TheilSenEstimator implements Algorithm, Flow.Publisher<Data> {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private Line pepareResult() {
|
||||||
public void pepareResult() {
|
|
||||||
double m, x;
|
double m, x;
|
||||||
double b, y;
|
double b, y;
|
||||||
|
|
||||||
|
@ -248,6 +247,8 @@ public class TheilSenEstimator implements Algorithm, Flow.Publisher<Data> {
|
||||||
data.setLineData(new Line(m, b));
|
data.setLineData(new Line(m, b));
|
||||||
this.subscriber.onNext(data);
|
this.subscriber.onNext(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return new Line(getSlope(), getYInterception());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -260,7 +261,7 @@ public class TheilSenEstimator implements Algorithm, Flow.Publisher<Data> {
|
||||||
/**
|
/**
|
||||||
* @return y-Achsenabschnitt
|
* @return y-Achsenabschnitt
|
||||||
*/
|
*/
|
||||||
public Double getyInterception() {
|
public Double getYInterception() {
|
||||||
return yInterception;
|
return yInterception;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ public class NaivLeastMedianOfSquaresEstimator implements Algorithm {
|
||||||
/**
|
/**
|
||||||
* Crude Algorithmus zum berechnen des LSM-Schätzers.
|
* Crude Algorithmus zum berechnen des LSM-Schätzers.
|
||||||
*/
|
*/
|
||||||
private void crudeAlg() {
|
private Line crudeAlg() {
|
||||||
ds = Double.MAX_VALUE;
|
ds = Double.MAX_VALUE;
|
||||||
b = 0d;
|
b = 0d;
|
||||||
m = 0d;
|
m = 0d;
|
||||||
|
@ -70,6 +70,8 @@ public class NaivLeastMedianOfSquaresEstimator implements Algorithm {
|
||||||
}
|
}
|
||||||
end = System.currentTimeMillis();
|
end = System.currentTimeMillis();
|
||||||
Logging.logInfo("Zeit: " + ((end - start) / 1000));
|
Logging.logInfo("Zeit: " + ((end - start) / 1000));
|
||||||
|
|
||||||
|
return new Line(getSlope(), getYInterception());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -88,26 +90,21 @@ public class NaivLeastMedianOfSquaresEstimator implements Algorithm {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public Line call() {
|
||||||
crudeAlg();
|
return crudeAlg();
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void pepareResult() {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return y-Achsenabschnitt
|
* @return y-Achsenabschnitt
|
||||||
*/
|
*/
|
||||||
public Double getB() {
|
public Double getYInterception() {
|
||||||
return b * -1;
|
return b * -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Steigung
|
* @return Steigung
|
||||||
*/
|
*/
|
||||||
public Double getM() {
|
public Double getSlope() {
|
||||||
return m * -1;
|
return m * -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ public class NaivRepeatedMedianEstimator implements Algorithm {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public Line call() {
|
||||||
//init the List for the slopes
|
//init the List for the slopes
|
||||||
Logging.logInfo("=== S T A R T - naiv R M ===");
|
Logging.logInfo("=== S T A R T - naiv R M ===");
|
||||||
long start;
|
long start;
|
||||||
|
@ -87,11 +87,8 @@ public class NaivRepeatedMedianEstimator implements Algorithm {
|
||||||
medianY = FastElementSelector.randomizedSelect(yMedians, yMedians.size() * 0.5);
|
medianY = FastElementSelector.randomizedSelect(yMedians, yMedians.size() * 0.5);
|
||||||
end = System.currentTimeMillis();
|
end = System.currentTimeMillis();
|
||||||
Logging.logInfo("Zeit: " + ((end - start) / 1000));
|
Logging.logInfo("Zeit: " + ((end - start) / 1000));
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void pepareResult() {
|
|
||||||
|
|
||||||
|
return new Line(getSlope(), getYInterception());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -128,14 +125,14 @@ public class NaivRepeatedMedianEstimator implements Algorithm {
|
||||||
/**
|
/**
|
||||||
* @return Steigung
|
* @return Steigung
|
||||||
*/
|
*/
|
||||||
public double getM() {
|
public double getSlope() {
|
||||||
return medianX * -1;
|
return medianX * -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return y-Achsenabschnitt
|
* @return y-Achsenabschnitt
|
||||||
*/
|
*/
|
||||||
public double getB() {
|
public double getYInterception() {
|
||||||
return medianY * -1;
|
return medianY * -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ public class NaivTheilSenEstimator implements Algorithm {
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public Line call() {
|
||||||
Logging.logInfo("=== S T A R T - naiv T S ===");
|
Logging.logInfo("=== S T A R T - naiv T S ===");
|
||||||
long start;
|
long start;
|
||||||
long end;
|
long end;
|
||||||
|
@ -68,24 +68,22 @@ public class NaivTheilSenEstimator implements Algorithm {
|
||||||
yInterception = median2 - slope * median1;
|
yInterception = median2 - slope * median1;
|
||||||
end = System.currentTimeMillis();
|
end = System.currentTimeMillis();
|
||||||
Logging.logInfo("Zeit: " + ((end - start) / 1000));
|
Logging.logInfo("Zeit: " + ((end - start) / 1000));
|
||||||
|
|
||||||
|
return new Line(getSlope(), getYInterception());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void pepareResult() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Steigung
|
* @return Steigung
|
||||||
*/
|
*/
|
||||||
public double getM() {
|
public double getSlope() {
|
||||||
return slope * -1;
|
return slope * -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return y-Achsenabschnitt
|
* @return y-Achsenabschnitt
|
||||||
*/
|
*/
|
||||||
public double getB() {
|
public double getYInterception() {
|
||||||
return yInterception * -1;
|
return yInterception * -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
package de.wwwu.awolf.presenter.data;
|
||||||
|
|
||||||
|
import de.wwwu.awolf.model.Line;
|
||||||
|
import de.wwwu.awolf.presenter.AbstractPresenter;
|
||||||
|
import de.wwwu.awolf.presenter.data.generator.CircleDatasetGenerator;
|
||||||
|
import de.wwwu.awolf.presenter.data.generator.CloudDatasetGenerator;
|
||||||
|
import de.wwwu.awolf.presenter.data.generator.LineDatasetGenerator;
|
||||||
|
import de.wwwu.awolf.presenter.data.io.DataExporter;
|
||||||
|
import de.wwwu.awolf.presenter.data.io.DataImporter;
|
||||||
|
import de.wwwu.awolf.presenter.util.Logging;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.ExecutorCompletionService;
|
||||||
|
|
||||||
|
public class DataProvider {
|
||||||
|
|
||||||
|
private final AbstractPresenter presenter;
|
||||||
|
|
||||||
|
public DataProvider(AbstractPresenter presenter) {
|
||||||
|
this.presenter = presenter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Line> getData(final File file) {
|
||||||
|
//Presenter soll die Klasse überwachen
|
||||||
|
ExecutorCompletionService<List<Line>> completionService = new ExecutorCompletionService<>(this.presenter.getExecutor());
|
||||||
|
completionService.submit(new DataImporter(file));
|
||||||
|
//wait until future is ready
|
||||||
|
try {
|
||||||
|
return completionService.take().get();
|
||||||
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
|
Logging.logError("Interrupted while importing... ", e);
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List<Line> getData(final DataType type, final int dataSize) {
|
||||||
|
//Presenter soll die Klasse überwachen
|
||||||
|
ExecutorCompletionService<List<Line>> completionService = new ExecutorCompletionService<>(this.presenter.getExecutor());
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case CIRCLE:
|
||||||
|
completionService.submit(new CircleDatasetGenerator(dataSize));
|
||||||
|
break;
|
||||||
|
case LINE:
|
||||||
|
completionService.submit(new LineDatasetGenerator(dataSize));
|
||||||
|
break;
|
||||||
|
case CLOUD:
|
||||||
|
completionService.submit(new CloudDatasetGenerator(dataSize));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return completionService.take().get();
|
||||||
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
|
Logging.logError("Interrupted while generating... ", e);
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void exportData(File file, List<Line> lines) {
|
||||||
|
this.presenter.getExecutor().submit(new DataExporter(lines, file));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public enum DataType {
|
||||||
|
CLOUD,
|
||||||
|
LINE,
|
||||||
|
CIRCLE
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
package de.wwwu.awolf.presenter.data.generator;
|
||||||
|
|
||||||
|
import de.wwwu.awolf.model.Line;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
import static de.wwwu.awolf.presenter.data.generator.DatasetGenerator.generateDataLines;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||||
|
*
|
||||||
|
* @Author: Armin Wolf
|
||||||
|
* @Email: a_wolf28@uni-muenster.de
|
||||||
|
* @Date: 01.08.2017.
|
||||||
|
*/
|
||||||
|
public class CircleDatasetGenerator implements Callable<List<Line>> {
|
||||||
|
|
||||||
|
private final int size;
|
||||||
|
|
||||||
|
public CircleDatasetGenerator(int size) {
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generiert einen Datensatz des typen: Gerade mit zirkulärer Störung. Zuerst wird die
|
||||||
|
* zirkuläre Störung zu der Liste der (dualen-)Geraden hinzugefügt danach wird die wrapper Methode
|
||||||
|
* <code>generateDataLines()</code> aufgerufen.
|
||||||
|
*
|
||||||
|
* @return Liste der Geraden
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<Line> call() throws Exception {
|
||||||
|
List<Line> lines = new LinkedList<>();
|
||||||
|
|
||||||
|
double from = 0;
|
||||||
|
double to = Math.PI * 5;
|
||||||
|
//obere Grenze für die neuen Punkte
|
||||||
|
int n = size / 2 + lines.size();
|
||||||
|
|
||||||
|
//calculate the distance between every two points
|
||||||
|
double distance = (to - from) / ((double) n);
|
||||||
|
|
||||||
|
//create points
|
||||||
|
double currentDistance = from;
|
||||||
|
//an die aktuelle Liste dranhängen
|
||||||
|
for (int i = lines.size(); i < n; i++) {
|
||||||
|
double x = Math.cos(currentDistance);
|
||||||
|
double y = Math.sin(currentDistance);
|
||||||
|
|
||||||
|
Line line = new Line(x, y);
|
||||||
|
line.setId(i + "");
|
||||||
|
lines.add(line);
|
||||||
|
|
||||||
|
//distance for the next iteration
|
||||||
|
currentDistance += distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
int generateSize = (int) (size * 0.5);
|
||||||
|
|
||||||
|
return generateDataLines(lines, generateSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
package de.wwwu.awolf.presenter.data.generator;
|
||||||
|
|
||||||
|
import de.wwwu.awolf.model.Line;
|
||||||
|
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||||
|
*
|
||||||
|
* @Author: Armin Wolf
|
||||||
|
* @Email: a_wolf28@uni-muenster.de
|
||||||
|
* @Date: 01.08.2017.
|
||||||
|
*/
|
||||||
|
public class CloudDatasetGenerator implements Callable<List<Line>> {
|
||||||
|
|
||||||
|
private final int size;
|
||||||
|
|
||||||
|
public CloudDatasetGenerator(int size) {
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generiert zu einer gegebenen Größe einen Datensatz des typen: Punktwolke
|
||||||
|
*
|
||||||
|
* @return Liste der Geraden
|
||||||
|
*/
|
||||||
|
public List<Line> generateDataCloud() {
|
||||||
|
LinkedList<Line> lines = new LinkedList<>();
|
||||||
|
SecureRandom random = new SecureRandom();
|
||||||
|
double m = 1 + random.nextDouble();
|
||||||
|
double b = random.nextDouble();
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 1; i < (size + 1); i++) {
|
||||||
|
double y = (random.nextGaussian() * 100) % 100;
|
||||||
|
double signal = m * i + b;
|
||||||
|
signal *= -1;
|
||||||
|
|
||||||
|
Line line = new Line(i, signal - y);
|
||||||
|
line.setId(i - 1 + "");
|
||||||
|
lines.add(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
return lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Line> call() throws Exception {
|
||||||
|
return generateDataCloud();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
package de.wwwu.awolf.presenter.data.generator;
|
||||||
|
|
||||||
|
import de.wwwu.awolf.model.Line;
|
||||||
|
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||||
|
*
|
||||||
|
* @Author: Armin Wolf
|
||||||
|
* @Email: a_wolf28@uni-muenster.de
|
||||||
|
* @Date: 01.08.2017.
|
||||||
|
*/
|
||||||
|
public class DatasetGenerator {
|
||||||
|
|
||||||
|
private static SecureRandom random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Konstruktor
|
||||||
|
*/
|
||||||
|
private DatasetGenerator() {
|
||||||
|
random = new SecureRandom();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generieren eines Datensatzes des typen: Gerade. Die Geraden werden in eine
|
||||||
|
* übergebene Liste hinzugefügt.
|
||||||
|
*
|
||||||
|
* @param n Größe des Datensatzes
|
||||||
|
* @return Liste des Geraden
|
||||||
|
*/
|
||||||
|
public static List<Line> generateDataLines(List<Line> lines, int n) {
|
||||||
|
double m = 5d;
|
||||||
|
double b = 0d;
|
||||||
|
|
||||||
|
int size = 0;
|
||||||
|
Map<Double, Double> points = new HashMap<>();
|
||||||
|
|
||||||
|
//speichere die Koordinaten in einer HashMap, damit keine Punkte
|
||||||
|
//entstehen deren x-Koordinate zu sehr beieinander liegt.
|
||||||
|
while (size < n) {
|
||||||
|
double y = random.nextGaussian();
|
||||||
|
double signal = m * y + b;
|
||||||
|
signal *= -1;
|
||||||
|
|
||||||
|
if (!points.containsKey(y)) {
|
||||||
|
points.put(y, signal);
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int idx = lines.size();
|
||||||
|
for (Double d : points.keySet()) {
|
||||||
|
Line line = new Line(d, points.get(d));
|
||||||
|
line.setId(idx + "");
|
||||||
|
lines.add(line);
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
package de.wwwu.awolf.presenter.data.generator;
|
||||||
|
|
||||||
|
import de.wwwu.awolf.model.Line;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||||
|
*
|
||||||
|
* @Author: Armin Wolf
|
||||||
|
* @Email: a_wolf28@uni-muenster.de
|
||||||
|
* @Date: 01.08.2017.
|
||||||
|
*/
|
||||||
|
public class LineDatasetGenerator implements Callable<List<Line>> {
|
||||||
|
|
||||||
|
private final int size;
|
||||||
|
|
||||||
|
|
||||||
|
public LineDatasetGenerator(int size) {
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper Methode zum generieren eines Datensatzes des typen: Gerade
|
||||||
|
*
|
||||||
|
* @return Liste des Geraden
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<Line> call() throws Exception {
|
||||||
|
return DatasetGenerator.generateDataLines(new ArrayList<>(), size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,17 +1,14 @@
|
||||||
package de.wwwu.awolf.presenter.io;
|
package de.wwwu.awolf.presenter.data.io;
|
||||||
|
|
||||||
import com.opencsv.CSVWriter;
|
import com.opencsv.CSVWriter;
|
||||||
import de.wwwu.awolf.model.Line;
|
import de.wwwu.awolf.model.Line;
|
||||||
import de.wwwu.awolf.model.communication.Data;
|
import de.wwwu.awolf.model.communication.Data;
|
||||||
import de.wwwu.awolf.model.communication.ExportData;
|
|
||||||
import de.wwwu.awolf.model.communication.SubscriberType;
|
|
||||||
import de.wwwu.awolf.presenter.util.Logging;
|
import de.wwwu.awolf.presenter.util.Logging;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Flow;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||||
|
@ -20,11 +17,10 @@ import java.util.concurrent.Flow;
|
||||||
* @Email: a_wolf28@uni-muenster.de
|
* @Email: a_wolf28@uni-muenster.de
|
||||||
* @Date: 03.08.2017.
|
* @Date: 03.08.2017.
|
||||||
*/
|
*/
|
||||||
public class DataExporter implements Flow.Publisher<Data> {
|
public class DataExporter implements Runnable {
|
||||||
|
|
||||||
private List<Line> lines;
|
private List<Line> lines;
|
||||||
private File file;
|
private File file;
|
||||||
private Flow.Subscriber<? super Data> subscriber;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Konstruktor
|
* Konstruktor
|
||||||
|
@ -32,10 +28,9 @@ public class DataExporter implements Flow.Publisher<Data> {
|
||||||
* @param lines Liste der Geraden
|
* @param lines Liste der Geraden
|
||||||
* @param file Datei in die, die Informationen exportiert werden sollen
|
* @param file Datei in die, die Informationen exportiert werden sollen
|
||||||
*/
|
*/
|
||||||
public DataExporter(List<Line> lines, File file, Flow.Subscriber<Data> subscriber) {
|
public DataExporter(List<Line> lines, File file) {
|
||||||
this.file = file;
|
this.file = file;
|
||||||
this.lines = lines;
|
this.lines = lines;
|
||||||
subscribe(subscriber);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,7 +38,8 @@ public class DataExporter implements Flow.Publisher<Data> {
|
||||||
* Der Aufbau der Datei ist: id, m, b. Wenn der Export beendet wurde wird die Beobachter-Klasse informiert.
|
* Der Aufbau der Datei ist: id, m, b. Wenn der Export beendet wurde wird die Beobachter-Klasse informiert.
|
||||||
* In diesem Fall ist dies die Presenter Klasse.
|
* In diesem Fall ist dies die Presenter Klasse.
|
||||||
*/
|
*/
|
||||||
public void export() {
|
@Override
|
||||||
|
public void run() {
|
||||||
CSVWriter writer = null;
|
CSVWriter writer = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -57,20 +53,11 @@ public class DataExporter implements Flow.Publisher<Data> {
|
||||||
writer.writeNext(entries);
|
writer.writeNext(entries);
|
||||||
}
|
}
|
||||||
writer.close();
|
writer.close();
|
||||||
String[] ret = {"export", "Das aktuelle Modell wurde erfolgreich unter: " + file.getAbsolutePath() + " gespeichert."};
|
|
||||||
|
|
||||||
ExportData data = new ExportData();
|
|
||||||
data.setType(SubscriberType.EXPORT);
|
|
||||||
data.setMessage("Das aktuelle Modell wurde erfolgreich unter: " + file.getAbsolutePath() + " gespeichert.");
|
|
||||||
this.subscriber.onNext(data);
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Logging.logError(e.getMessage(), e);
|
Logging.logError(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
Logging.logInfo("The model has been successfully saved under: " + file.getAbsolutePath() + ".");
|
||||||
|
|
||||||
@Override
|
|
||||||
public void subscribe(Flow.Subscriber<? super Data> subscriber) {
|
|
||||||
this.subscriber = subscriber;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,10 +1,7 @@
|
||||||
package de.wwwu.awolf.presenter.io;
|
package de.wwwu.awolf.presenter.data.io;
|
||||||
|
|
||||||
import com.opencsv.CSVReader;
|
import com.opencsv.CSVReader;
|
||||||
import de.wwwu.awolf.model.Line;
|
import de.wwwu.awolf.model.Line;
|
||||||
import de.wwwu.awolf.model.communication.Data;
|
|
||||||
import de.wwwu.awolf.model.communication.ImportData;
|
|
||||||
import de.wwwu.awolf.model.communication.SubscriberType;
|
|
||||||
import de.wwwu.awolf.presenter.util.Logging;
|
import de.wwwu.awolf.presenter.util.Logging;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
@ -14,7 +11,7 @@ import java.io.FileReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Flow;
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,18 +21,16 @@ import java.util.concurrent.Flow;
|
||||||
* @Email: a_wolf28@uni-muenster.de
|
* @Email: a_wolf28@uni-muenster.de
|
||||||
* @Date: 21.06.2017.
|
* @Date: 21.06.2017.
|
||||||
*/
|
*/
|
||||||
public class DataImporter implements Flow.Publisher<Data> {
|
public class DataImporter implements Callable<List<Line>> {
|
||||||
|
|
||||||
private CSVReader reader;
|
private CSVReader reader;
|
||||||
private Flow.Subscriber<? super Data> subscriber;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Konstruktor
|
* Konstruktor
|
||||||
*
|
*
|
||||||
* @param file Datei aus der die Informationen imortiert werden sollen.
|
* @param file Datei aus der die Informationen imortiert werden sollen.
|
||||||
*/
|
*/
|
||||||
public DataImporter(File file, Flow.Subscriber<? super Data> subscriber) {
|
public DataImporter(File file) {
|
||||||
subscribe(subscriber);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.reader = new CSVReader(new FileReader(file));
|
this.reader = new CSVReader(new FileReader(file));
|
||||||
|
@ -51,7 +46,8 @@ public class DataImporter implements Flow.Publisher<Data> {
|
||||||
*
|
*
|
||||||
* @return Liste der Geraden
|
* @return Liste der Geraden
|
||||||
*/
|
*/
|
||||||
public List<Line> run() {
|
@Override
|
||||||
|
public List<Line> call() throws Exception {
|
||||||
List<Line> list = new LinkedList<>();
|
List<Line> list = new LinkedList<>();
|
||||||
try {
|
try {
|
||||||
List<String[]> lines = reader.readAll();
|
List<String[]> lines = reader.readAll();
|
||||||
|
@ -69,9 +65,6 @@ public class DataImporter implements Flow.Publisher<Data> {
|
||||||
counter++;
|
counter++;
|
||||||
result[2] = counter + "";
|
result[2] = counter + "";
|
||||||
Thread.sleep(10);
|
Thread.sleep(10);
|
||||||
|
|
||||||
|
|
||||||
communicate(counter, lines.size());
|
|
||||||
} else if (nextLine.length == 2) {
|
} else if (nextLine.length == 2) {
|
||||||
double x = Double.parseDouble(nextLine[1]);
|
double x = Double.parseDouble(nextLine[1]);
|
||||||
double y = Double.parseDouble(nextLine[2]) * (-1);
|
double y = Double.parseDouble(nextLine[2]) * (-1);
|
||||||
|
@ -84,8 +77,6 @@ public class DataImporter implements Flow.Publisher<Data> {
|
||||||
counter++;
|
counter++;
|
||||||
result[2] = counter + "";
|
result[2] = counter + "";
|
||||||
Thread.sleep(10);
|
Thread.sleep(10);
|
||||||
|
|
||||||
communicate(counter, lines.size());
|
|
||||||
} else {
|
} else {
|
||||||
JOptionPane.showMessageDialog(null, "Diese Datei kann nicht importiert werden." +
|
JOptionPane.showMessageDialog(null, "Diese Datei kann nicht importiert werden." +
|
||||||
"Es müssen mindestens zwei Spalten enthalten sein (x,y).", "Fehler bei der Eingabe", JOptionPane.ERROR_MESSAGE);
|
"Es müssen mindestens zwei Spalten enthalten sein (x,y).", "Fehler bei der Eingabe", JOptionPane.ERROR_MESSAGE);
|
||||||
|
@ -101,18 +92,4 @@ public class DataImporter implements Flow.Publisher<Data> {
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void communicate(int counter, int size) {
|
|
||||||
// communication
|
|
||||||
ImportData data = new ImportData();
|
|
||||||
data.setType(SubscriberType.IMPORT);
|
|
||||||
data.setCurrent(counter);
|
|
||||||
data.setNumberOfLines(size);
|
|
||||||
this.subscriber.onNext(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void subscribe(Flow.Subscriber<? super Data> subscriber) {
|
|
||||||
this.subscriber = subscriber;
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
package de.wwwu.awolf.presenter.evaluation;
|
||||||
|
|
||||||
|
import de.wwwu.awolf.model.Line;
|
||||||
|
import de.wwwu.awolf.model.Point;
|
||||||
|
import de.wwwu.awolf.model.evaluation.ComparisonResult;
|
||||||
|
import de.wwwu.awolf.presenter.algorithms.Algorithm;
|
||||||
|
import de.wwwu.awolf.presenter.algorithms.advanced.LeastMedianOfSquaresEstimator;
|
||||||
|
import de.wwwu.awolf.presenter.algorithms.advanced.RepeatedMedianEstimator;
|
||||||
|
import de.wwwu.awolf.presenter.algorithms.advanced.TheilSenEstimator;
|
||||||
|
import de.wwwu.awolf.presenter.algorithms.naiv.NaivLeastMedianOfSquaresEstimator;
|
||||||
|
import de.wwwu.awolf.presenter.algorithms.naiv.NaivRepeatedMedianEstimator;
|
||||||
|
import de.wwwu.awolf.presenter.algorithms.naiv.NaivTheilSenEstimator;
|
||||||
|
import de.wwwu.awolf.presenter.util.Logging;
|
||||||
|
|
||||||
|
import java.util.EnumMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
|
public class AlgorithmComparison {
|
||||||
|
|
||||||
|
private final List<Algorithm.Type> types;
|
||||||
|
private final ExecutorService executorService;
|
||||||
|
private final Map<Algorithm.Type, Algorithm> algorithmMap;
|
||||||
|
private final CompletionService<Line> completionService;
|
||||||
|
|
||||||
|
public AlgorithmComparison(List<Algorithm.Type> types, List<Line> lines, List<Point> nodes) {
|
||||||
|
this.types = types;
|
||||||
|
this.executorService = Executors.newFixedThreadPool(3);
|
||||||
|
completionService = new ExecutorCompletionService<>(this.executorService);
|
||||||
|
|
||||||
|
algorithmMap = new EnumMap<>(Algorithm.Type.class);
|
||||||
|
algorithmMap.put(Algorithm.Type.LMS, new LeastMedianOfSquaresEstimator(lines, nodes));
|
||||||
|
algorithmMap.put(Algorithm.Type.RM, new RepeatedMedianEstimator(lines));
|
||||||
|
algorithmMap.put(Algorithm.Type.TS, new TheilSenEstimator(lines, nodes));
|
||||||
|
algorithmMap.put(Algorithm.Type.NAIV_LMS, new NaivLeastMedianOfSquaresEstimator(lines));
|
||||||
|
algorithmMap.put(Algorithm.Type.NAIV_RM, new NaivRepeatedMedianEstimator(lines));
|
||||||
|
algorithmMap.put(Algorithm.Type.NAIV_TS, new NaivTheilSenEstimator(lines));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ComparisonResult compare() {
|
||||||
|
|
||||||
|
ComparisonResult comparisonResult = new ComparisonResult();
|
||||||
|
|
||||||
|
getTypes().forEach(tye -> {
|
||||||
|
completionService.submit(algorithmMap.get(tye));
|
||||||
|
});
|
||||||
|
|
||||||
|
for (Algorithm.Type value : getTypes()) {
|
||||||
|
Algorithm.Type type;
|
||||||
|
synchronized (types) {
|
||||||
|
type = value;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Line line = completionService.take().get();
|
||||||
|
comparisonResult.put(type, line);
|
||||||
|
} catch (InterruptedException interupted) {
|
||||||
|
Logging.logError("Error while waiting for the Line result. Type: " + type, interupted);
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
Logging.logError("Execution failed. Type: " + type, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return comparisonResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Algorithm.Type> getTypes() {
|
||||||
|
return types;
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,27 +2,22 @@ package de.wwwu.awolf.presenter.evaluation;
|
||||||
|
|
||||||
import de.wwwu.awolf.model.Line;
|
import de.wwwu.awolf.model.Line;
|
||||||
import de.wwwu.awolf.model.LineModel;
|
import de.wwwu.awolf.model.LineModel;
|
||||||
import de.wwwu.awolf.model.Point;
|
|
||||||
import de.wwwu.awolf.model.communication.Data;
|
import de.wwwu.awolf.model.communication.Data;
|
||||||
import de.wwwu.awolf.model.communication.EvaluationData;
|
import de.wwwu.awolf.model.communication.EvaluationData;
|
||||||
import de.wwwu.awolf.model.communication.SubscriberType;
|
import de.wwwu.awolf.model.communication.SubscriberType;
|
||||||
|
import de.wwwu.awolf.model.evaluation.ComparisonResult;
|
||||||
import de.wwwu.awolf.presenter.Presenter;
|
import de.wwwu.awolf.presenter.Presenter;
|
||||||
import de.wwwu.awolf.presenter.algorithms.Algorithm;
|
import de.wwwu.awolf.presenter.algorithms.Algorithm;
|
||||||
import de.wwwu.awolf.presenter.algorithms.advanced.LeastMedianOfSquaresEstimator;
|
import de.wwwu.awolf.presenter.data.DataProvider;
|
||||||
import de.wwwu.awolf.presenter.algorithms.advanced.RepeatedMedianEstimator;
|
import de.wwwu.awolf.presenter.data.generator.DatasetGenerator;
|
||||||
import de.wwwu.awolf.presenter.algorithms.advanced.TheilSenEstimator;
|
import de.wwwu.awolf.presenter.evaluation.measures.PercentageErrorBasedMeasure;
|
||||||
import de.wwwu.awolf.presenter.algorithms.naiv.NaivLeastMedianOfSquaresEstimator;
|
import de.wwwu.awolf.presenter.evaluation.measures.ScaleDependentMeasure;
|
||||||
import de.wwwu.awolf.presenter.algorithms.naiv.NaivRepeatedMedianEstimator;
|
import de.wwwu.awolf.presenter.evaluation.measures.ScaledErrorBasedMeasure;
|
||||||
import de.wwwu.awolf.presenter.algorithms.naiv.NaivTheilSenEstimator;
|
|
||||||
import de.wwwu.awolf.presenter.generator.DatasetGenerator;
|
|
||||||
import de.wwwu.awolf.presenter.io.DataImporter;
|
|
||||||
import de.wwwu.awolf.presenter.util.IntersectionComputer;
|
import de.wwwu.awolf.presenter.util.IntersectionComputer;
|
||||||
import de.wwwu.awolf.presenter.util.Logging;
|
import de.wwwu.awolf.presenter.util.Logging;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.Flow;
|
import java.util.concurrent.Flow;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,30 +27,17 @@ import java.util.concurrent.Flow;
|
||||||
* @Email: a_wolf28@uni-muenster.de
|
* @Email: a_wolf28@uni-muenster.de
|
||||||
* @Date: 01.08.2017.
|
* @Date: 01.08.2017.
|
||||||
*/
|
*/
|
||||||
public class EvaluateAlgorithms implements Flow.Publisher<Data> {
|
public class EvaluateAlgorithms implements Runnable, Flow.Publisher<Data> {
|
||||||
|
|
||||||
private LineModel arrangement;
|
private LineModel arrangement;
|
||||||
|
|
||||||
private List<Line> lmsL;
|
|
||||||
private List<Line> rmL;
|
|
||||||
private List<Line> tsL;
|
|
||||||
|
|
||||||
private List<Point> lmsP;
|
|
||||||
private List<Point> tsP;
|
|
||||||
|
|
||||||
private Thread lmsThread;
|
|
||||||
private Thread rmThread;
|
|
||||||
private Thread tsThread;
|
|
||||||
|
|
||||||
private DatasetGenerator generator;
|
private DatasetGenerator generator;
|
||||||
|
|
||||||
private String[][] names = {{"MSE", "RMSE", "MAE", "MDAE", "Steigung", "y-Achsenabschnitt", "S-MSE", "S-RMSE", "S-MAE", "S-MDAE", "Brute-force Steigung", "Brute-force y-Achsenabschnitt"}, {"MAPE", "MDAPE", "RMSPE", "RMDSPE", "Steigung", "y-Achsenabschnitt"}};
|
|
||||||
|
|
||||||
//übergebene Parameter
|
//übergebene Parameter
|
||||||
private int type;
|
private int type;
|
||||||
private int iterations;
|
private int iterations;
|
||||||
private int alg;
|
private int alg;
|
||||||
private Flow.Subscriber<? super Data> subscriber;
|
private Flow.Subscriber<? super Data> subscriber;
|
||||||
|
private Map<Algorithm.Type, Map<String, String>> resultMapping;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Konstruktor zur evaluation
|
* Konstruktor zur evaluation
|
||||||
|
@ -71,34 +53,23 @@ public class EvaluateAlgorithms implements Flow.Publisher<Data> {
|
||||||
* 6 = lms, rm, ts,
|
* 6 = lms, rm, ts,
|
||||||
* @param datasettyp typ der zu generierenden Datensatz
|
* @param datasettyp typ der zu generierenden Datensatz
|
||||||
*/
|
*/
|
||||||
public EvaluateAlgorithms(int type, int n, int alg, String datasettyp, Presenter presenter) {
|
public EvaluateAlgorithms(int type, int n, int alg, DataProvider.DataType datasettyp, Presenter presenter) {
|
||||||
subscribe(presenter);
|
subscribe(presenter);
|
||||||
this.arrangement = new LineModel();
|
this.arrangement = new LineModel();
|
||||||
generator = new DatasetGenerator(presenter);
|
this.resultMapping = new EnumMap<>(Algorithm.Type.class);
|
||||||
switch (datasettyp) {
|
|
||||||
case "Punktwolke":
|
List<Line> data = presenter.getDataProvider().getData(datasettyp, n);
|
||||||
arrangement.setLines(generator.generateDataCloud(n));
|
Logging.logInfo("Starting the Benchmark...");
|
||||||
break;
|
arrangement.setLines(data);
|
||||||
case "Gerade":
|
|
||||||
arrangement.setLines(generator.generateDataLines(n));
|
Logging.logInfo("Benchmark on Dataset: " + datasettyp + " with " + n + " points");
|
||||||
break;
|
|
||||||
case "Kreis und Gerade":
|
|
||||||
arrangement.setLines(generator.generateCircle(n));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.iterations = n;
|
this.iterations = n;
|
||||||
this.alg = alg;
|
this.alg = alg;
|
||||||
|
|
||||||
IntersectionComputer computer = new IntersectionComputer(arrangement.getLines());
|
IntersectionComputer computer = new IntersectionComputer(arrangement.getLines());
|
||||||
arrangement.setNodes(computer.compute());
|
arrangement.setNodes(computer.compute());
|
||||||
|
|
||||||
lmsL = new LinkedList<>(arrangement.getLines());
|
|
||||||
rmL = new LinkedList<>(arrangement.getLines());
|
|
||||||
tsL = new LinkedList<>(arrangement.getLines());
|
|
||||||
|
|
||||||
lmsP = new ArrayList<>(arrangement.getNodes());
|
|
||||||
tsP = new ArrayList<>(arrangement.getNodes());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -114,225 +85,81 @@ public class EvaluateAlgorithms implements Flow.Publisher<Data> {
|
||||||
* 6 = lms, rm, ts,
|
* 6 = lms, rm, ts,
|
||||||
* @param file Datei die importiert werden soll
|
* @param file Datei die importiert werden soll
|
||||||
*/
|
*/
|
||||||
public EvaluateAlgorithms(int type, int alg, File file) {
|
public EvaluateAlgorithms(int type, int alg, File file, Presenter presenter) {
|
||||||
this.arrangement = new LineModel();
|
subscribe(presenter);
|
||||||
|
presenter.startImport(file);
|
||||||
DataImporter importer = new DataImporter(file, this.subscriber);
|
this.arrangement = presenter.getModel();
|
||||||
|
this.resultMapping = new EnumMap<>(Algorithm.Type.class);
|
||||||
List<Line> importedLines = importer.run();
|
|
||||||
if (importedLines != null)
|
|
||||||
arrangement.setLines(importedLines);
|
|
||||||
|
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.alg = alg;
|
this.alg = alg;
|
||||||
|
|
||||||
IntersectionComputer computer = new IntersectionComputer(arrangement.getLines());
|
IntersectionComputer computer = new IntersectionComputer(arrangement.getLines());
|
||||||
arrangement.setNodes(computer.compute());
|
arrangement.setNodes(computer.compute());
|
||||||
|
|
||||||
|
|
||||||
lmsL = new LinkedList<>(arrangement.getLines());
|
|
||||||
rmL = new LinkedList<>(arrangement.getLines());
|
|
||||||
tsL = new LinkedList<>(arrangement.getLines());
|
|
||||||
|
|
||||||
lmsP = new ArrayList<>(arrangement.getNodes());
|
|
||||||
tsP = new ArrayList<>(arrangement.getNodes());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Map<Algorithm.Type, Map<String, String>> benchmarkSameEstimator(final Algorithm.Type advanced, final Algorithm.Type naiv) {
|
||||||
|
Logging.logInfo("AlgorithmComparison with Types: " + advanced.name() + ", " + naiv.name());
|
||||||
|
AlgorithmComparison comparison = new AlgorithmComparison(Arrays.asList(naiv, advanced), Collections.unmodifiableList(arrangement.getLines()), Collections.unmodifiableList(arrangement.getNodes()));
|
||||||
|
ComparisonResult comparisonResult = comparison.compare();
|
||||||
|
|
||||||
|
|
||||||
|
Map<String, String> result = new HashMap<>();
|
||||||
|
result.putAll(getScaleDependentMeasure(arrangement.getLines(), comparisonResult, advanced));
|
||||||
|
result.putAll(getScaledErrorBasedMeasure(arrangement.getLines(), comparisonResult, advanced, naiv));
|
||||||
|
Logging.logInfo("finished with execution of the algorithms.");
|
||||||
|
|
||||||
|
this.resultMapping.put(advanced, result);
|
||||||
|
return this.resultMapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<Algorithm.Type, Map<String, String>> benchmarkDifferentEstimators(List<Algorithm.Type> types) {
|
||||||
|
Logging.logInfo("AlgorithmComparison with Types: " + types);
|
||||||
|
AlgorithmComparison comparison = new AlgorithmComparison(types, Collections.unmodifiableList(arrangement.getLines()), Collections.unmodifiableList(arrangement.getNodes()));
|
||||||
|
ComparisonResult comparisonResult = comparison.compare();
|
||||||
|
|
||||||
|
Map<String, String> multipleResults = new HashMap<>();
|
||||||
|
types.forEach(type -> this.resultMapping.put(type, getPercentigeErrorBasedMeasure(arrangement.getLines(), comparisonResult, type)));
|
||||||
|
Logging.logInfo("finished with execution of the algorithms.");
|
||||||
|
return this.resultMapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Startet die Evaluation zu den passenden Typ. Bei beendigung wird der Beobachter informiert.
|
* Startet die Evaluation zu den passenden Typ. Bei beendigung wird der Beobachter informiert.
|
||||||
*
|
|
||||||
* @throws InterruptedException
|
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
Map<Algorithm.Type, Map<String, String>> result = new EnumMap<>(Algorithm.Type.class);
|
||||||
List<String> result;
|
|
||||||
List<List<String>> multipleResults = new ArrayList<>();
|
|
||||||
ExecutorService executorService = Executors.newCachedThreadPool();
|
|
||||||
|
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 0:
|
case 0:
|
||||||
//der alg der gewählt wurde
|
//der alg der gewählt wurde
|
||||||
if (alg == 0) {
|
if (alg == 0) {
|
||||||
final Line naivEstimator = new Line(0,0);
|
result = benchmarkSameEstimator(Algorithm.Type.LMS, Algorithm.Type.NAIV_LMS);
|
||||||
final Line advancedEstimator = new Line(0,0);
|
|
||||||
executorService.submit(() -> {
|
|
||||||
NaivLeastMedianOfSquaresEstimator l = new NaivLeastMedianOfSquaresEstimator(arrangement.getLines());
|
|
||||||
l.run();
|
|
||||||
naivEstimator.setM(l.getM());
|
|
||||||
naivEstimator.setB(l.getB());
|
|
||||||
});
|
|
||||||
executorService.submit(() -> {
|
|
||||||
LeastMedianOfSquaresEstimator lmsAlg = new LeastMedianOfSquaresEstimator(lmsL, lmsP);
|
|
||||||
lmsAlg.run();
|
|
||||||
lmsAlg.pepareResult();
|
|
||||||
advancedEstimator.setM(lmsAlg.getSlope());
|
|
||||||
advancedEstimator.setB(lmsAlg.getyInterception());
|
|
||||||
});
|
|
||||||
|
|
||||||
result = getScaleDependentMeasure(arrangement.getLines(), advancedEstimator.getM(), advancedEstimator.getB());
|
|
||||||
result.addAll(getScaledErrorBasedMeasure(arrangement.getLines(), advancedEstimator.getM(), advancedEstimator.getB(), naivEstimator.getM(), naivEstimator.getB()));
|
|
||||||
Double[] tmp = {advancedEstimator.getM(), advancedEstimator.getB(), naivEstimator.getM(), naivEstimator.getB()};
|
|
||||||
sendPlotLineResults(Arrays.asList(tmp), Algorithm.Type.LMS);
|
|
||||||
} else if (alg == 1) {
|
} else if (alg == 1) {
|
||||||
final double[] m = new double[1];
|
result = benchmarkSameEstimator(Algorithm.Type.RM, Algorithm.Type.NAIV_RM);
|
||||||
final double[] b = new double[1];
|
|
||||||
Thread t = new Thread(() -> {
|
|
||||||
NaivRepeatedMedianEstimator r = new NaivRepeatedMedianEstimator(arrangement.getLines());
|
|
||||||
r.run();
|
|
||||||
m[0] = r.getM();
|
|
||||||
b[0] = r.getB();
|
|
||||||
});
|
|
||||||
t.start();
|
|
||||||
try {
|
|
||||||
startRM();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
Logging.logError(e.getMessage(), e);
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
|
||||||
result = getScaleDependentMeasure(arrangement.getLines(), Double.valueOf(rmRes[0]), Double.valueOf(rmRes[1]));
|
|
||||||
result.addAll(getScaledErrorBasedMeasure(arrangement.getLines(), Double.valueOf(rmRes[0]), Double.valueOf(rmRes[1]), m[0], b[0]));
|
|
||||||
Double[] tmp = {Double.valueOf(rmRes[0]), Double.valueOf(rmRes[1]), m[0], b[0]};
|
|
||||||
sendPlotLineResults(Arrays.asList(tmp), Algorithm.Type.NAIV_RM);
|
|
||||||
} else {
|
} else {
|
||||||
final double[] m = new double[1];
|
result = benchmarkSameEstimator(Algorithm.Type.TS, Algorithm.Type.NAIV_TS);
|
||||||
final double[] b = new double[1];
|
|
||||||
Thread t = new Thread(() -> {
|
|
||||||
NaivTheilSenEstimator ts = new NaivTheilSenEstimator(arrangement.getLines());
|
|
||||||
ts.run();
|
|
||||||
m[0] = ts.getM();
|
|
||||||
b[0] = ts.getB();
|
|
||||||
});
|
|
||||||
t.start();
|
|
||||||
try {
|
|
||||||
startTS();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
Logging.logError(e.getMessage(), e);
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
|
||||||
result = getScaleDependentMeasure(arrangement.getLines(), Double.valueOf(tsRes[0]), Double.valueOf(tsRes[1]));
|
|
||||||
result.addAll(getScaledErrorBasedMeasure(arrangement.getLines(), Double.valueOf(tsRes[0]), Double.valueOf(tsRes[1]), m[0], b[0]));
|
|
||||||
Double[] tmp = { Double.valueOf(tsRes[0]), Double.valueOf(tsRes[1]), m[0], b[0]};
|
|
||||||
sendPlotLineResults(Arrays.asList(tmp), Algorithm.Type.NAIV_TS);
|
|
||||||
}
|
}
|
||||||
sendTableApproximationTypes();
|
|
||||||
sendTableApproximationData(result, alg);
|
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
List<List<String>> lineRes;
|
|
||||||
switch (alg) {
|
switch (alg) {
|
||||||
case 3:
|
case 3:
|
||||||
try {
|
result = benchmarkDifferentEstimators(Arrays.asList(Algorithm.Type.LMS, Algorithm.Type.RM));
|
||||||
startLMS();
|
|
||||||
startRM();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
Logging.logError(e.getMessage(), e);
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
|
||||||
|
|
||||||
result = getPercentigeErrorBasedMeasure(arrangement.getLines(), lmsRes[0], lmsRes[1]);
|
|
||||||
multipleResults.add(result);
|
|
||||||
result = getPercentigeErrorBasedMeasure(arrangement.getLines(), rmRes[0], rmRes[1]);
|
|
||||||
multipleResults.add(result);
|
|
||||||
result = fillPseudoResults();
|
|
||||||
multipleResults.add(result);
|
|
||||||
|
|
||||||
lineRes = new ArrayList<>();
|
|
||||||
lineRes.add(Arrays.asList(lmsRes));
|
|
||||||
lineRes.add(Arrays.asList(rmRes));
|
|
||||||
sendPloteLineResults(lineRes, Arrays.asList(Algorithm.Type.LMS, Algorithm.Type.RM));
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
try {
|
result = benchmarkDifferentEstimators(Arrays.asList(Algorithm.Type.LMS, Algorithm.Type.TS));
|
||||||
startLMS();
|
|
||||||
startTS();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
Logging.logError(e.getMessage(), e);
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
|
||||||
|
|
||||||
result = getPercentigeErrorBasedMeasure(arrangement.getLines(), lmsRes[0], lmsRes[1]);
|
|
||||||
multipleResults.add(result);
|
|
||||||
result = fillPseudoResults();
|
|
||||||
multipleResults.add(result);
|
|
||||||
result = getPercentigeErrorBasedMeasure(arrangement.getLines(), tsRes[0], tsRes[1]);
|
|
||||||
multipleResults.add(result);
|
|
||||||
|
|
||||||
lineRes = new ArrayList<>();
|
|
||||||
lineRes.add(Arrays.asList(lmsRes));
|
|
||||||
lineRes.add(Arrays.asList(tsRes));
|
|
||||||
sendPloteLineResults(lineRes, Arrays.asList(Algorithm.Type.LMS, Algorithm.Type.TS));
|
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
try {
|
result = benchmarkDifferentEstimators(Arrays.asList(Algorithm.Type.RM, Algorithm.Type.TS));
|
||||||
startRM();
|
|
||||||
startTS();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
Logging.logError(e.getMessage(), e);
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
|
||||||
|
|
||||||
result = fillPseudoResults();
|
|
||||||
multipleResults.add(result);
|
|
||||||
result = getPercentigeErrorBasedMeasure(arrangement.getLines(), rmRes[0], rmRes[1]);
|
|
||||||
multipleResults.add(result);
|
|
||||||
result = getPercentigeErrorBasedMeasure(arrangement.getLines(), tsRes[0], tsRes[1]);
|
|
||||||
multipleResults.add(result);
|
|
||||||
|
|
||||||
lineRes = new ArrayList<>();
|
|
||||||
lineRes.add(Arrays.asList(rmRes));
|
|
||||||
lineRes.add(Arrays.asList(tsRes));
|
|
||||||
sendPloteLineResults(lineRes, Arrays.asList(Algorithm.Type.RM, Algorithm.Type.TS));
|
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
try {
|
result = benchmarkDifferentEstimators(Arrays.asList(Algorithm.Type.LMS, Algorithm.Type.RM, Algorithm.Type.TS));
|
||||||
startLMS();
|
|
||||||
startRM();
|
|
||||||
startTS();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
Logging.logError(e.getMessage(), e);
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
|
||||||
|
|
||||||
result = getPercentigeErrorBasedMeasure(arrangement.getLines(), lmsRes[0], lmsRes[1]);
|
|
||||||
multipleResults.add(result);
|
|
||||||
result = getPercentigeErrorBasedMeasure(arrangement.getLines(), rmRes[0], rmRes[1]);
|
|
||||||
multipleResults.add(result);
|
|
||||||
result = getPercentigeErrorBasedMeasure(arrangement.getLines(), tsRes[0], tsRes[1]);
|
|
||||||
multipleResults.add(result);
|
|
||||||
|
|
||||||
lineRes = new ArrayList<>();
|
|
||||||
lineRes.add(Arrays.asList(lmsRes));
|
|
||||||
lineRes.add(Arrays.asList(rmRes));
|
|
||||||
lineRes.add(Arrays.asList(tsRes));
|
|
||||||
sendPloteLineResults(lineRes, Arrays.asList(Algorithm.Type.LMS, Algorithm.Type.RM, Algorithm.Type.TS));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
sendTableApproximationData(multipleResults);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
sendTableApproximationData(result);
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Die berechneten Ergebnisse werden an den Beobachter übermittelt um dann visualisiert zu werden.
|
|
||||||
*
|
|
||||||
* @param result Ergebnisse
|
|
||||||
* @param col Spalte
|
|
||||||
*/
|
|
||||||
public void sendTableApproximationData(List<String> result, int col) {
|
|
||||||
List<String> tableInput = new ArrayList<>();
|
|
||||||
for (int i = 0; i < names[type].length; i++) {
|
|
||||||
tableInput.add(result.get(i));
|
|
||||||
}
|
|
||||||
tableInput.add("");
|
|
||||||
EvaluationData data = new EvaluationData();
|
|
||||||
data.setColumn(col);
|
|
||||||
data.setLabels(tableInput);
|
|
||||||
tableInput.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -340,145 +167,38 @@ public class EvaluateAlgorithms implements Flow.Publisher<Data> {
|
||||||
*
|
*
|
||||||
* @param result Ergebnisse
|
* @param result Ergebnisse
|
||||||
*/
|
*/
|
||||||
public void sendTableApproximationData(List<List<String>> result) {
|
private void sendTableApproximationData(Map<Algorithm.Type, Map<String, String>> result) {
|
||||||
List<String> tableInput = new ArrayList<>();
|
|
||||||
|
|
||||||
//TODO Hääää? xD
|
|
||||||
//iteration über die ApproximationsGüten -- Zeilen
|
|
||||||
for (int j = 0; j <= result.get(0).size(); j++) {
|
|
||||||
tableInput.add("eval-ds");
|
|
||||||
if (j != result.get(0).size()) {
|
|
||||||
|
|
||||||
tableInput.add(names[type][j]);
|
|
||||||
//iteration über die alg. -- Spalten
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
tableInput.add(result.get(i).get(j));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
tableInput.add("");
|
|
||||||
tableInput.add("");
|
|
||||||
tableInput.add("");
|
|
||||||
tableInput.add("");
|
|
||||||
}
|
|
||||||
|
|
||||||
EvaluationData data = new EvaluationData();
|
|
||||||
data.setType(SubscriberType.EVAL_DS);
|
|
||||||
data.setMultipleColumnResult(result);
|
|
||||||
this.subscriber.onNext(data);
|
|
||||||
|
|
||||||
tableInput.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Die Art der Ergebnisse (MSE, RMSE,...) wird an der Beobachter übermittelt.
|
|
||||||
*/
|
|
||||||
public void sendTableApproximationTypes() {
|
|
||||||
EvaluationData data = new EvaluationData();
|
EvaluationData data = new EvaluationData();
|
||||||
data.setType(SubscriberType.EVAL_T);
|
data.setType(SubscriberType.EVALUATION_TABLE_DATA);
|
||||||
data.setLabels(Arrays.asList(names[type]));
|
data.setMultipleColumnResult(result);
|
||||||
|
data.setRowsPerColumn(result.keySet().size());
|
||||||
this.subscriber.onNext(data);
|
this.subscriber.onNext(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Zur visualisierung der berechneten Geraden wird die Steigung und der y-Achsenabschnitt an den
|
|
||||||
* Beobachter übermittelt.
|
|
||||||
*
|
|
||||||
* @param res Feld mit den Werten für die Steigung und dern y-Achsenabschnitt
|
|
||||||
* @param alg code für welchen Algorithmus sich die Werte beziehen
|
|
||||||
*/
|
|
||||||
public void sendPlotLineResults(List<Double> res, Algorithm.Type alg) {
|
|
||||||
EvaluationData data = new EvaluationData();
|
|
||||||
data.setType(SubscriberType.LINES_RES);
|
|
||||||
data.setAlgorithmtypes(Collections.singletonList(alg));
|
|
||||||
data.setOneColumnresult(res);
|
|
||||||
this.subscriber.onNext(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Zur visualisierung der berechneten Geraden wird die Steigung und der y-Achsenabschnitt an den
|
|
||||||
* Beobachter übermittelt.
|
|
||||||
*
|
|
||||||
* @param res Feld mit den Werten für die Steigung und dern y-Achsenabschnitt (alle)
|
|
||||||
* @param algs codes für welchen Algorithmus sich die Werte beziehen (alle)
|
|
||||||
*/
|
|
||||||
public void sendPloteLineResults(List<List<String>> res, List<Algorithm.Type> algs) {
|
|
||||||
EvaluationData data = new EvaluationData();
|
|
||||||
data.setType(SubscriberType.LINES_RES_MULT);
|
|
||||||
data.setAlgorithmtypes(algs);
|
|
||||||
data.setMultipleColumnResult(res);
|
|
||||||
this.subscriber.onNext(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Startet die Berechnung des Alg. zum LMS-Schätzer
|
|
||||||
*
|
|
||||||
* @throws InterruptedException
|
|
||||||
*/
|
|
||||||
public void startLMS() throws InterruptedException {
|
|
||||||
lmsThread = new Thread(() -> {
|
|
||||||
LeastMedianOfSquaresEstimator lmsAlg = new LeastMedianOfSquaresEstimator(lmsL, lmsP);
|
|
||||||
lmsAlg.run();
|
|
||||||
lmsAlg.pepareResult();
|
|
||||||
lmsRes[0] = lmsAlg.getSlope();
|
|
||||||
lmsRes[1] = lmsAlg.getyInterception();
|
|
||||||
|
|
||||||
});
|
|
||||||
lmsThread.start();
|
|
||||||
lmsThread.join();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Startet die Berechnung des Alg. zum RM-Schätzer
|
|
||||||
*
|
|
||||||
* @throws InterruptedException
|
|
||||||
*/
|
|
||||||
public void startRM() throws InterruptedException {
|
|
||||||
rmThread = new Thread(() -> {
|
|
||||||
RepeatedMedianEstimator rmAlg = new RepeatedMedianEstimator(rmL);
|
|
||||||
rmAlg.run();
|
|
||||||
rmAlg.pepareResult();
|
|
||||||
rmRes[0] = rmAlg.getSlope();
|
|
||||||
rmRes[1] = rmAlg.getyInterception();
|
|
||||||
});
|
|
||||||
rmThread.start();
|
|
||||||
rmThread.join();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Startet die Berechnung des Alg. zum TS-Schätzer
|
|
||||||
*
|
|
||||||
* @throws InterruptedException
|
|
||||||
*/
|
|
||||||
public void startTS() throws InterruptedException {
|
|
||||||
tsThread = new Thread(() -> {
|
|
||||||
TheilSenEstimator tsAlg = new TheilSenEstimator(tsL, tsP);
|
|
||||||
tsAlg.run();
|
|
||||||
tsAlg.pepareResult();
|
|
||||||
tsRes[0] = tsAlg.getSlope();
|
|
||||||
tsRes[1] = tsAlg.getyInterception();
|
|
||||||
});
|
|
||||||
tsThread.start();
|
|
||||||
tsThread.join();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Startet die Berechnung der skalierungsabbhängigen Maße.
|
* Startet die Berechnung der skalierungsabbhängigen Maße.
|
||||||
*
|
*
|
||||||
* @param lines Liste der Geraden
|
* @param lines Liste der Geraden
|
||||||
* @param m Steigung
|
|
||||||
* @param b y-Achsenabschnitt
|
|
||||||
* @return Liste mit den Ergebnissen, bereit zum visualisieren
|
* @return Liste mit den Ergebnissen, bereit zum visualisieren
|
||||||
*/
|
*/
|
||||||
public List<String> getScaleDependentMeasure(final List<Line> lines, final Double m, final Double b) {
|
private Map<String, String> getScaleDependentMeasure(final List<Line> lines, final ComparisonResult comparisonResult, final Algorithm.Type type) {
|
||||||
|
|
||||||
|
Logging.logInfo("Calculating ScaleDependentMeasure for " + type);
|
||||||
|
|
||||||
|
Double m = comparisonResult.get(type).getM();
|
||||||
|
Double b = comparisonResult.get(type).getB();
|
||||||
|
|
||||||
ScaleDependentMeasure scaleDependentMeasure = new ScaleDependentMeasure(lines, m, b);
|
ScaleDependentMeasure scaleDependentMeasure = new ScaleDependentMeasure(lines, m, b);
|
||||||
List<String> ret = new ArrayList<>();
|
Map<String, String> ret = new HashMap<>();
|
||||||
ret.add(scaleDependentMeasure.mse().toString());
|
ret.put(type + " MSE", scaleDependentMeasure.mse().toString());
|
||||||
ret.add(scaleDependentMeasure.rmse().toString());
|
ret.put(type + " RMSE", scaleDependentMeasure.rmse().toString());
|
||||||
ret.add(scaleDependentMeasure.mae().toString());
|
ret.put(type + " MAE", scaleDependentMeasure.mae().toString());
|
||||||
ret.add(scaleDependentMeasure.mdae().toString());
|
ret.put(type + " MDAE", scaleDependentMeasure.mdae().toString());
|
||||||
ret.add(m.toString());
|
ret.put(type + " SLOPE", m.toString());
|
||||||
ret.add(b.toString());
|
ret.put(type + " y-INTERCEPTION", b.toString());
|
||||||
|
|
||||||
|
Logging.logInfo("finished calculating ScaleDependentMeasure.");
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -487,19 +207,22 @@ public class EvaluateAlgorithms implements Flow.Publisher<Data> {
|
||||||
* Startet die Berechnung der Maße die auf dem prozentualen Fehler basieren.
|
* Startet die Berechnung der Maße die auf dem prozentualen Fehler basieren.
|
||||||
*
|
*
|
||||||
* @param lines Liste der Geraden
|
* @param lines Liste der Geraden
|
||||||
* @param m Steigung
|
|
||||||
* @param b y-Achsenabschnitt
|
|
||||||
* @return Liste mit den Ergebnissen, bereit zum visualisieren
|
* @return Liste mit den Ergebnissen, bereit zum visualisieren
|
||||||
*/
|
*/
|
||||||
public List<String> getPercentigeErrorBasedMeasure(final List<Line> lines, final Double m, final Double b) {
|
private Map<String, String> getPercentigeErrorBasedMeasure(final List<Line> lines, final ComparisonResult comparisonResult, final Algorithm.Type type) {
|
||||||
|
Logging.logInfo("Calculating PercentigeErrorBasedMeasure for " + type);
|
||||||
|
Double m = comparisonResult.get(type).getM();
|
||||||
|
Double b = comparisonResult.get(type).getB();
|
||||||
|
|
||||||
PercentageErrorBasedMeasure percentageErrorBasedMeasure = new PercentageErrorBasedMeasure(lines, m, b);
|
PercentageErrorBasedMeasure percentageErrorBasedMeasure = new PercentageErrorBasedMeasure(lines, m, b);
|
||||||
ArrayList<String> ret = new ArrayList<>();
|
Map<String, String> ret = new HashMap<>();
|
||||||
ret.add(percentageErrorBasedMeasure.mape().toString());
|
ret.put(type + " MAPE", percentageErrorBasedMeasure.mape().toString());
|
||||||
ret.add(percentageErrorBasedMeasure.mdape().toString());
|
ret.put(type + " MDAPE", percentageErrorBasedMeasure.mdape().toString());
|
||||||
ret.add(percentageErrorBasedMeasure.rmspe().toString());
|
ret.put(type + " RMSPE", percentageErrorBasedMeasure.rmspe().toString());
|
||||||
ret.add(percentageErrorBasedMeasure.rmdspe().toString());
|
ret.put(type + " RMDSPE", percentageErrorBasedMeasure.rmdspe().toString());
|
||||||
ret.add(m.toString());
|
ret.put(type + " SLOPE", m.toString());
|
||||||
ret.add(b.toString());
|
ret.put(type + " y-INTERCEPTION", b.toString());
|
||||||
|
Logging.logInfo("finished calculating PercentigeErrorBasedMeasure.");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -507,36 +230,30 @@ public class EvaluateAlgorithms implements Flow.Publisher<Data> {
|
||||||
* Startet die Berechnung der skalierungsunabbhängigen Maße.
|
* Startet die Berechnung der skalierungsunabbhängigen Maße.
|
||||||
*
|
*
|
||||||
* @param lines Liste der Geraden
|
* @param lines Liste der Geraden
|
||||||
* @param m Steigung
|
|
||||||
* @param b y-Achsenabschnitt
|
|
||||||
* @return Liste mit den Ergebnissen, bereit zum visualisieren
|
* @return Liste mit den Ergebnissen, bereit zum visualisieren
|
||||||
*/
|
*/
|
||||||
public List<String> getScaledErrorBasedMeasure(final List<Line> lines, final Double m, final Double b, final Double nM, final Double nB) {
|
private Map<String, String> getScaledErrorBasedMeasure(final List<Line> lines, final ComparisonResult comparisonResult, final Algorithm.Type advanced, final Algorithm.Type naiv) {
|
||||||
ScaledErrorBasedMeasure scaledErrorBasedMeasure = new ScaledErrorBasedMeasure(lines, m, b, nM, nB);
|
|
||||||
List<String> ret = new ArrayList<>();
|
|
||||||
ret.add(scaledErrorBasedMeasure.mse().toString());
|
|
||||||
ret.add(scaledErrorBasedMeasure.rmse().toString());
|
|
||||||
ret.add(scaledErrorBasedMeasure.mae().toString());
|
|
||||||
ret.add(scaledErrorBasedMeasure.mdae().toString());
|
|
||||||
ret.add(nM.toString());
|
|
||||||
ret.add(nB.toString());
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
Logging.logInfo("Calculating ScaledErrorBasedMeasure for " + advanced + ", " + naiv);
|
||||||
* Damit es bei der Visualisierung trennende Zeilen gibt.
|
|
||||||
*
|
//first
|
||||||
* @return
|
Double m = comparisonResult.get(advanced).getM();
|
||||||
*/
|
Double b = comparisonResult.get(advanced).getB();
|
||||||
private List<String> fillPseudoResults() {
|
//second
|
||||||
List<String> result = new ArrayList<>();
|
Double naivM = comparisonResult.get(naiv).getM();
|
||||||
result.add(" ");
|
Double naivB = comparisonResult.get(naiv).getB();
|
||||||
result.add(" ");
|
|
||||||
result.add(" ");
|
ScaledErrorBasedMeasure scaledErrorBasedMeasure = new ScaledErrorBasedMeasure(lines, m, b, naivM, naivB);
|
||||||
result.add(" ");
|
Map<String, String> ret = new HashMap<>();
|
||||||
result.add(" ");
|
ret.put(advanced + " MSE", scaledErrorBasedMeasure.mse().toString());
|
||||||
result.add(" ");
|
ret.put(advanced + " RMSE", scaledErrorBasedMeasure.rmse().toString());
|
||||||
return result;
|
ret.put(advanced + " MAE", scaledErrorBasedMeasure.mae().toString());
|
||||||
|
ret.put(advanced + " MDAE", scaledErrorBasedMeasure.mdae().toString());
|
||||||
|
ret.put(advanced + " Naiv-SLOPE", naivM.toString());
|
||||||
|
ret.put(advanced + " Naiv-y-INTERCEPTION", naivB.toString());
|
||||||
|
|
||||||
|
Logging.logInfo("finished calculating ScaledErrorBasedMeasure.");
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package de.wwwu.awolf.presenter.evaluation;
|
package de.wwwu.awolf.presenter.evaluation.measures;
|
||||||
|
|
||||||
import de.wwwu.awolf.model.Line;
|
import de.wwwu.awolf.model.Line;
|
||||||
import de.wwwu.awolf.presenter.util.FastElementSelector;
|
import de.wwwu.awolf.presenter.util.FastElementSelector;
|
|
@ -1,4 +1,4 @@
|
||||||
package de.wwwu.awolf.presenter.evaluation;
|
package de.wwwu.awolf.presenter.evaluation.measures;
|
||||||
|
|
||||||
import de.wwwu.awolf.model.Line;
|
import de.wwwu.awolf.model.Line;
|
||||||
import de.wwwu.awolf.model.communication.Data;
|
import de.wwwu.awolf.model.communication.Data;
|
|
@ -1,4 +1,4 @@
|
||||||
package de.wwwu.awolf.presenter.evaluation;
|
package de.wwwu.awolf.presenter.evaluation.measures;
|
||||||
|
|
||||||
import de.wwwu.awolf.model.Line;
|
import de.wwwu.awolf.model.Line;
|
||||||
import de.wwwu.awolf.presenter.util.FastElementSelector;
|
import de.wwwu.awolf.presenter.util.FastElementSelector;
|
|
@ -1,4 +1,4 @@
|
||||||
package de.wwwu.awolf.presenter.evaluation;
|
package de.wwwu.awolf.presenter.evaluation.measures;
|
||||||
|
|
||||||
import de.wwwu.awolf.model.Line;
|
import de.wwwu.awolf.model.Line;
|
||||||
import de.wwwu.awolf.presenter.util.FastElementSelector;
|
import de.wwwu.awolf.presenter.util.FastElementSelector;
|
|
@ -1,175 +0,0 @@
|
||||||
package de.wwwu.awolf.presenter.generator;
|
|
||||||
|
|
||||||
import de.wwwu.awolf.model.Line;
|
|
||||||
import de.wwwu.awolf.model.communication.Data;
|
|
||||||
import de.wwwu.awolf.model.communication.GeneratorData;
|
|
||||||
import de.wwwu.awolf.model.communication.SubscriberType;
|
|
||||||
import de.wwwu.awolf.presenter.Presenter;
|
|
||||||
|
|
||||||
import java.security.SecureRandom;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.Flow;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
|
||||||
*
|
|
||||||
* @Author: Armin Wolf
|
|
||||||
* @Email: a_wolf28@uni-muenster.de
|
|
||||||
* @Date: 01.08.2017.
|
|
||||||
*/
|
|
||||||
public class DatasetGenerator implements Flow.Publisher<Data> {
|
|
||||||
|
|
||||||
private Double m;
|
|
||||||
private Double b;
|
|
||||||
private SecureRandom random;
|
|
||||||
private Flow.Subscriber<? super Data> subscriber;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Konstruktor
|
|
||||||
*/
|
|
||||||
public DatasetGenerator(Presenter presenter) {
|
|
||||||
random = new SecureRandom();
|
|
||||||
this.subscribe(presenter);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Konstruktor
|
|
||||||
*/
|
|
||||||
public DatasetGenerator() {
|
|
||||||
random = new SecureRandom();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generiert zu einer gegebenen Größe einen Datensatz des typen: Punktwolke
|
|
||||||
*
|
|
||||||
* @param size Größe des Datensatzes
|
|
||||||
* @return Liste der Geraden
|
|
||||||
*/
|
|
||||||
public LinkedList<Line> generateDataCloud(int size) {
|
|
||||||
LinkedList<Line> lines = new LinkedList<>();
|
|
||||||
m = 1 + random.nextDouble();
|
|
||||||
b = random.nextDouble();
|
|
||||||
|
|
||||||
|
|
||||||
for (int i = 1; i < (size + 1); i++) {
|
|
||||||
double y = (random.nextGaussian() * 100) % 100;
|
|
||||||
double signal = m * i + b;
|
|
||||||
signal *= -1;
|
|
||||||
|
|
||||||
Line line = new Line(i, signal - y);
|
|
||||||
line.setId(i - 1 + "");
|
|
||||||
lines.add(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
communicate("Es wurden " + size + " Daten generiert mit den Parametern", m, b);
|
|
||||||
return lines;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper Methode zum generieren eines Datensatzes des typen: Gerade
|
|
||||||
*
|
|
||||||
* @param size Größe des Datensatzes
|
|
||||||
* @return Liste des Geraden
|
|
||||||
*/
|
|
||||||
public List<Line> generateDataLines(int size) {
|
|
||||||
List<Line> lines = new LinkedList<>();
|
|
||||||
return generateDataLines(lines, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generieren eines Datensatzes des typen: Gerade. Die Geraden werden in eine
|
|
||||||
* übergebene Liste hinzugefügt.
|
|
||||||
*
|
|
||||||
* @param lines Liste der Geraden
|
|
||||||
* @param n Größe des Datensatzes
|
|
||||||
* @return Liste des Geraden
|
|
||||||
*/
|
|
||||||
private List<Line> generateDataLines(List<Line> lines, int n) {
|
|
||||||
m = 5d;
|
|
||||||
b = 0d;
|
|
||||||
|
|
||||||
int size = 0;
|
|
||||||
Map<Double, Double> points = new HashMap<>();
|
|
||||||
|
|
||||||
//speichere die Koordinaten in einer HashMap, damit keine Punkte
|
|
||||||
//entstehen deren x-Koordinate zu sehr beieinander liegt.
|
|
||||||
while (size < n) {
|
|
||||||
double y = random.nextGaussian();
|
|
||||||
double signal = m * y + b;
|
|
||||||
signal *= -1;
|
|
||||||
|
|
||||||
if (!points.containsKey(y)) {
|
|
||||||
points.put(y, signal);
|
|
||||||
size++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int idx = lines.size();
|
|
||||||
for (Double d : points.keySet()) {
|
|
||||||
Line line = new Line(d, points.get(d));
|
|
||||||
line.setId(idx + "");
|
|
||||||
lines.add(line);
|
|
||||||
idx++;
|
|
||||||
}
|
|
||||||
|
|
||||||
communicate("Es wurden " + n + " Daten generiert mit den Parametern", m, b);
|
|
||||||
return lines;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generiert einen Datensatz des typen: Gerade mit zirkulärer Störung. Zuerst wird die
|
|
||||||
* zirkuläre Störung zu der Liste der (dualen-)Geraden hinzugefügt danach wird die wrapper Methode
|
|
||||||
* <code>generateDataLines()</code> aufgerufen.
|
|
||||||
*
|
|
||||||
* @param size Größe des Datensatzes
|
|
||||||
* @return Liste der Geraden
|
|
||||||
*/
|
|
||||||
public List<Line> generateCircle(int size) {
|
|
||||||
List<Line> lines = new LinkedList<>();
|
|
||||||
|
|
||||||
double from = 0;
|
|
||||||
double to = Math.PI * 5;
|
|
||||||
//obere Grenze für die neuen Punkte
|
|
||||||
int n = size / 2 + lines.size();
|
|
||||||
|
|
||||||
//calculate the distance between every two points
|
|
||||||
double distance = (to - from) / ((double) n);
|
|
||||||
|
|
||||||
//create points
|
|
||||||
double currentDistance = from;
|
|
||||||
//an die aktuelle Liste dranhängen
|
|
||||||
for (int i = lines.size(); i < n; i++) {
|
|
||||||
double x = Math.cos(currentDistance);
|
|
||||||
double y = Math.sin(currentDistance);
|
|
||||||
|
|
||||||
Line line = new Line(x, y);
|
|
||||||
line.setId(i + "");
|
|
||||||
lines.add(line);
|
|
||||||
|
|
||||||
//distance for the next iteration
|
|
||||||
currentDistance += distance;
|
|
||||||
}
|
|
||||||
|
|
||||||
return generateDataLines(lines, size / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void subscribe(Flow.Subscriber<? super Data> subscriber) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void communicate(final String message, final double m, final double b) {
|
|
||||||
if (this.subscriber != null) {
|
|
||||||
GeneratorData data = new GeneratorData();
|
|
||||||
data.setType(SubscriberType.GENERATOR);
|
|
||||||
data.setMessage(message);
|
|
||||||
data.setM(m);
|
|
||||||
data.setB(b);
|
|
||||||
this.subscriber.onNext(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ package de.wwwu.awolf.view;
|
||||||
import de.wwwu.awolf.model.Line;
|
import de.wwwu.awolf.model.Line;
|
||||||
import de.wwwu.awolf.presenter.AbstractPresenter;
|
import de.wwwu.awolf.presenter.AbstractPresenter;
|
||||||
import de.wwwu.awolf.presenter.Presenter;
|
import de.wwwu.awolf.presenter.Presenter;
|
||||||
|
import de.wwwu.awolf.presenter.algorithms.Algorithm;
|
||||||
import de.wwwu.awolf.presenter.util.Logging;
|
import de.wwwu.awolf.presenter.util.Logging;
|
||||||
import de.wwwu.awolf.view.listener.*;
|
import de.wwwu.awolf.view.listener.*;
|
||||||
import de.wwwu.awolf.view.panels.DualityPanel;
|
import de.wwwu.awolf.view.panels.DualityPanel;
|
||||||
|
@ -19,9 +20,10 @@ import javax.imageio.ImageIO;
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
||||||
|
@ -244,21 +246,14 @@ public class MainFrame extends JFrame {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fügt der Evaluations-Tabelle eine Spalte mit Daten hinzu
|
* Fügt der Evaluations-Tabelle eine Zeile mit Daten hinzu
|
||||||
*
|
*
|
||||||
* @param res Daten der Spalte
|
* @param tableEntries Data of the Table
|
||||||
* @param col Spalte
|
|
||||||
* @param isApprCol <code>true</code>, falls es sich um die Überschirften der Approximationsgüten handelt
|
|
||||||
*/
|
*/
|
||||||
public void appendEvalResult(Object[] res, int col, boolean isApprCol) {
|
public void appendEvalResult(Map<Algorithm.Type, Map<String, String>> tableEntries) {
|
||||||
|
|
||||||
SwingUtilities.invokeLater(() -> {
|
SwingUtilities.invokeLater(() -> {
|
||||||
Object[] tmp = Arrays.copyOfRange(res, 2, res.length);
|
evaluationPanel.addRow(tableEntries);
|
||||||
if (isApprCol) {
|
|
||||||
evaluationPanel.setCurrentRow(tmp.length);
|
|
||||||
evaluationPanel.addColumn(tmp, col, true);
|
|
||||||
} else {
|
|
||||||
evaluationPanel.addColumn(tmp, col + 1, false);
|
|
||||||
}
|
|
||||||
evaluationPanel.repaint();
|
evaluationPanel.repaint();
|
||||||
evaluationPanel.revalidate();
|
evaluationPanel.revalidate();
|
||||||
});
|
});
|
||||||
|
@ -269,65 +264,8 @@ public class MainFrame extends JFrame {
|
||||||
*
|
*
|
||||||
* @param res Daten der Spalte
|
* @param res Daten der Spalte
|
||||||
*/
|
*/
|
||||||
public void appendEvalResult(Object[] res) {
|
public void appendEvalResults(Map<Algorithm.Type, Map<String, String>> res) {
|
||||||
SwingUtilities.invokeLater(() -> {
|
appendEvalResult(res);
|
||||||
Object[] tmp = Arrays.copyOfRange(res, 1, res.length);
|
|
||||||
evaluationPanel.addRow(tmp);
|
|
||||||
evaluationPanel.repaint();
|
|
||||||
evaluationPanel.revalidate();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Visualisiert die Ausgleichsgerade zu gegebenen Algorithmen
|
|
||||||
*
|
|
||||||
* @param res Steigungen und y-Achsenabschnitte
|
|
||||||
* @param alg Kodierung der Alg.
|
|
||||||
*/
|
|
||||||
public void drawLineResult(Object[] res, int alg) {
|
|
||||||
SwingUtilities.invokeLater(() -> {
|
|
||||||
Object[] result = Arrays.copyOfRange(res, 2, res.length);
|
|
||||||
evaluationPanel.drawLines(result, alg);
|
|
||||||
evaluationPanel.repaint();
|
|
||||||
evaluationPanel.revalidate();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Visualisiert die Ausgleichsgerade zu einem gegebenen Algorithmus
|
|
||||||
*
|
|
||||||
* @param res Steigungen und y-Achsenabschnitte
|
|
||||||
*/
|
|
||||||
public void drawLineResults(Object[] res) {
|
|
||||||
SwingUtilities.invokeLater(() -> {
|
|
||||||
Object[] result = Arrays.copyOfRange(res, 1, res.length);
|
|
||||||
List<Double[]> algs = new ArrayList<>();
|
|
||||||
|
|
||||||
for (int i = 0; i < (result.length + 1) / 3; i++) {
|
|
||||||
String name = (String) result[(3 * i)];
|
|
||||||
String m = (String) result[(3 * i) + 1];
|
|
||||||
String b = (String) result[(3 * i) + 2];
|
|
||||||
Double[] tmp = {Double.parseDouble(name), Double.parseDouble(m), Double.parseDouble(b)};
|
|
||||||
algs.add(tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
evaluationPanel.drawLines(algs);
|
|
||||||
evaluationPanel.repaint();
|
|
||||||
evaluationPanel.revalidate();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Evaluations-Datensätze werden Visualisiert
|
|
||||||
*
|
|
||||||
* @param lines Liste der Geraden
|
|
||||||
*/
|
|
||||||
public void addEvalDataset(List<Line> lines) {
|
|
||||||
SwingUtilities.invokeLater(() -> {
|
|
||||||
evaluationPanel.setDualPoints(lines);
|
|
||||||
evaluationPanel.repaint();
|
|
||||||
evaluationPanel.revalidate();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ import de.wwwu.awolf.presenter.Presenter;
|
||||||
import de.wwwu.awolf.view.listener.ExportDataListener;
|
import de.wwwu.awolf.view.listener.ExportDataListener;
|
||||||
import de.wwwu.awolf.view.listener.GenerateDataListener;
|
import de.wwwu.awolf.view.listener.GenerateDataListener;
|
||||||
import de.wwwu.awolf.view.listener.ImportDataListener;
|
import de.wwwu.awolf.view.listener.ImportDataListener;
|
||||||
import de.wwwu.awolf.view.listener.PictureImportListener;
|
|
||||||
import de.wwwu.awolf.view.panels.AboutPanel;
|
import de.wwwu.awolf.view.panels.AboutPanel;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
@ -31,7 +30,6 @@ public class MenuBar {
|
||||||
private JMenuItem generateItem;
|
private JMenuItem generateItem;
|
||||||
private JMenuItem evaluateItem;
|
private JMenuItem evaluateItem;
|
||||||
private JMenuItem aboutItem;
|
private JMenuItem aboutItem;
|
||||||
private JMenuItem importPicture;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Konstruktor
|
* Konstruktor
|
||||||
|
@ -48,7 +46,6 @@ public class MenuBar {
|
||||||
|
|
||||||
this.exitItem = new JMenuItem("Exit");
|
this.exitItem = new JMenuItem("Exit");
|
||||||
this.importItem = new JMenuItem("Import");
|
this.importItem = new JMenuItem("Import");
|
||||||
this.importPicture = new JMenuItem("Bildimport");
|
|
||||||
this.exportItem = new JMenuItem("Export");
|
this.exportItem = new JMenuItem("Export");
|
||||||
this.generateItem = new JMenuItem("Generiere...");
|
this.generateItem = new JMenuItem("Generiere...");
|
||||||
this.aboutItem = new JMenuItem("Über das Programm");
|
this.aboutItem = new JMenuItem("Über das Programm");
|
||||||
|
@ -61,7 +58,6 @@ public class MenuBar {
|
||||||
fileMenu.add(exportItem);
|
fileMenu.add(exportItem);
|
||||||
|
|
||||||
toolsMenu.add(generateItem);
|
toolsMenu.add(generateItem);
|
||||||
toolsMenu.add(importPicture);
|
|
||||||
toolsMenu.add(evaluateItem);
|
toolsMenu.add(evaluateItem);
|
||||||
|
|
||||||
|
|
||||||
|
@ -95,7 +91,6 @@ public class MenuBar {
|
||||||
dialog.setVisible(true);
|
dialog.setVisible(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
this.importPicture.addActionListener(new PictureImportListener((Presenter) view.getPresenter(), view));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package de.wwwu.awolf.view.listener;
|
package de.wwwu.awolf.view.listener;
|
||||||
|
|
||||||
import de.wwwu.awolf.presenter.Presenter;
|
import de.wwwu.awolf.presenter.Presenter;
|
||||||
|
import de.wwwu.awolf.presenter.data.DataProvider;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
@ -57,8 +58,8 @@ public class GenerateDataListener implements ActionListener {
|
||||||
dialog.add(aproveButton);
|
dialog.add(aproveButton);
|
||||||
aproveButton.addActionListener(e1 -> {
|
aproveButton.addActionListener(e1 -> {
|
||||||
int n = Integer.parseInt(textField.getText());
|
int n = Integer.parseInt(textField.getText());
|
||||||
int type = datasetTypeComboBox.getSelectedIndex();
|
int index = datasetTypeComboBox.getSelectedIndex();
|
||||||
Thread t = new Thread(() -> presenter.generateDataset(n, type));
|
Thread t = new Thread(() -> presenter.generateDataset(n, DataProvider.DataType.values()[index]));
|
||||||
t.start();
|
t.start();
|
||||||
dialog.dispose();
|
dialog.dispose();
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
package de.wwwu.awolf.view.listener;
|
|
||||||
|
|
||||||
import de.wwwu.awolf.presenter.Presenter;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
|
||||||
import javax.swing.filechooser.FileSystemView;
|
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
import java.awt.event.ActionListener;
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
|
||||||
*
|
|
||||||
* @Author: Armin Wolf
|
|
||||||
* @Email: a_wolf28@uni-muenster.de
|
|
||||||
* @Date: 17.09.2017.
|
|
||||||
*/
|
|
||||||
public class PictureImportListener implements ActionListener {
|
|
||||||
private Presenter presenter;
|
|
||||||
private Container component;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Konstruktor
|
|
||||||
*
|
|
||||||
* @param presenter Presenter
|
|
||||||
* @param component visuelle Elternkomponente
|
|
||||||
*/
|
|
||||||
public PictureImportListener(Presenter presenter, Container component) {
|
|
||||||
this.presenter = presenter;
|
|
||||||
this.component = component;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
SwingUtilities.invokeLater(() -> {
|
|
||||||
File file = null;
|
|
||||||
JFileChooser chooser = new JFileChooser(FileSystemView.getFileSystemView().getHomeDirectory());
|
|
||||||
chooser.setPreferredSize(new Dimension(800, 700));
|
|
||||||
chooser.setFileFilter(new FileNameExtensionFilter("Bilder", "tiff", "png", "jpg", "jpeg"));
|
|
||||||
|
|
||||||
chooser.setMultiSelectionEnabled(false);
|
|
||||||
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
|
||||||
|
|
||||||
|
|
||||||
if (chooser.showOpenDialog(component) == JFileChooser.APPROVE_OPTION) {
|
|
||||||
//Logging.logInfo ("Datei "+chooser.getSelectedFile()+ " ausgewählt.");
|
|
||||||
file = chooser.getSelectedFile();
|
|
||||||
final File input = file;
|
|
||||||
Thread t = new Thread(() -> presenter.startPictureDataImport(input));
|
|
||||||
t.start();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,25 +2,23 @@ package de.wwwu.awolf.view.panels;
|
||||||
|
|
||||||
import de.wwwu.awolf.model.Line;
|
import de.wwwu.awolf.model.Line;
|
||||||
import de.wwwu.awolf.presenter.Presenter;
|
import de.wwwu.awolf.presenter.Presenter;
|
||||||
|
import de.wwwu.awolf.presenter.algorithms.Algorithm;
|
||||||
|
import de.wwwu.awolf.presenter.data.DataProvider;
|
||||||
|
import de.wwwu.awolf.presenter.util.Logging;
|
||||||
import de.wwwu.awolf.view.MainFrame;
|
import de.wwwu.awolf.view.MainFrame;
|
||||||
import de.wwwu.awolf.view.custom.ButtonGroupAtLeastTwo;
|
import de.wwwu.awolf.view.custom.ButtonGroupAtLeastTwo;
|
||||||
import de.wwwu.awolf.view.custom.ColorColumnRenderer;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.border.TitledBorder;
|
import javax.swing.border.TitledBorder;
|
||||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||||
import javax.swing.filechooser.FileSystemView;
|
import javax.swing.filechooser.FileSystemView;
|
||||||
import javax.swing.plaf.FontUIResource;
|
|
||||||
import javax.swing.table.DefaultTableCellRenderer;
|
|
||||||
import javax.swing.table.DefaultTableModel;
|
import javax.swing.table.DefaultTableModel;
|
||||||
import javax.swing.table.JTableHeader;
|
import javax.swing.table.JTableHeader;
|
||||||
import javax.swing.table.TableColumn;
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.io.Serializable;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by
|
* Created by
|
||||||
|
@ -59,6 +57,7 @@ public class EvaluationPanel extends JPanel {
|
||||||
private int currentRowOfTypes;
|
private int currentRowOfTypes;
|
||||||
private JPanel buttonPanel;
|
private JPanel buttonPanel;
|
||||||
private PlotPanel plotPanel;
|
private PlotPanel plotPanel;
|
||||||
|
private Map<Algorithm.Type, Color> colorMap;
|
||||||
private String[] selections = {"Approximationsgüte", "Least Median of Squares", "Repeated-Median", "Theil-Sen"};
|
private String[] selections = {"Approximationsgüte", "Least Median of Squares", "Repeated-Median", "Theil-Sen"};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -71,6 +70,13 @@ public class EvaluationPanel extends JPanel {
|
||||||
this.view = view;
|
this.view = view;
|
||||||
this.setLayout(new BorderLayout());
|
this.setLayout(new BorderLayout());
|
||||||
this.currentRowOfTypes = 0;
|
this.currentRowOfTypes = 0;
|
||||||
|
this.colorMap = new HashMap<>();
|
||||||
|
this.colorMap.put(Algorithm.Type.LMS, Color.ORANGE);
|
||||||
|
this.colorMap.put(Algorithm.Type.RM, Color.RED);
|
||||||
|
this.colorMap.put(Algorithm.Type.TS, Color.MAGENTA);
|
||||||
|
this.colorMap.put(Algorithm.Type.NAIV_LMS, Color.BLUE);
|
||||||
|
this.colorMap.put(Algorithm.Type.NAIV_RM, Color.GREEN);
|
||||||
|
this.colorMap.put(Algorithm.Type.NAIV_TS, Color.CYAN);
|
||||||
|
|
||||||
init();
|
init();
|
||||||
addListener();
|
addListener();
|
||||||
|
@ -157,7 +163,6 @@ public class EvaluationPanel extends JPanel {
|
||||||
comp.setBorder(new TitledBorder("Konfiguration"));
|
comp.setBorder(new TitledBorder("Konfiguration"));
|
||||||
|
|
||||||
//Tabelle
|
//Tabelle
|
||||||
model.setColumnIdentifiers(selections);
|
|
||||||
table.setDragEnabled(true);
|
table.setDragEnabled(true);
|
||||||
JScrollPane scrollPane = new JScrollPane(table);
|
JScrollPane scrollPane = new JScrollPane(table);
|
||||||
scrollPane.setWheelScrollingEnabled(true);
|
scrollPane.setWheelScrollingEnabled(true);
|
||||||
|
@ -182,14 +187,6 @@ public class EvaluationPanel extends JPanel {
|
||||||
|
|
||||||
this.add(buttonPanel, BorderLayout.SOUTH);
|
this.add(buttonPanel, BorderLayout.SOUTH);
|
||||||
|
|
||||||
TableColumn tm = table.getColumnModel().getColumn(0);
|
|
||||||
tm.setCellRenderer(new ColorColumnRenderer(Color.lightGray, Color.blue));
|
|
||||||
for (int i = 1; i < 4; i++) {
|
|
||||||
DefaultTableCellRenderer rightRenderer = new DefaultTableCellRenderer();
|
|
||||||
rightRenderer.setHorizontalAlignment(SwingConstants.RIGHT);
|
|
||||||
rightRenderer.setFont(new FontUIResource("Courier", Font.PLAIN, 12));
|
|
||||||
table.getColumnModel().getColumn(i).setCellRenderer(rightRenderer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -228,7 +225,7 @@ public class EvaluationPanel extends JPanel {
|
||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
((Presenter) view.getPresenter()).startEvaluation(type, n, alg, datatyp);
|
((Presenter) view.getPresenter()).startEvaluation(type, n, alg, DataProvider.DataType.values()[datasetType.getSelectedIndex()]);
|
||||||
}
|
}
|
||||||
clearTable.setEnabled(true);
|
clearTable.setEnabled(true);
|
||||||
exportData.setEnabled(true);
|
exportData.setEnabled(true);
|
||||||
|
@ -303,13 +300,14 @@ public class EvaluationPanel extends JPanel {
|
||||||
* @param col Spalte
|
* @param col Spalte
|
||||||
* @param isLabel <code>true</code>, falls es sich um die Approximations Überschriften handelt
|
* @param isLabel <code>true</code>, falls es sich um die Approximations Überschriften handelt
|
||||||
*/
|
*/
|
||||||
public void addColumn(Object[] data, int col, boolean isLabel) {
|
public void addColumn(final List<? extends Serializable> data, final int col, final boolean isLabel) {
|
||||||
if (isLabel) {
|
if (isLabel) {
|
||||||
addBlankRows(data.length);
|
addBlankRows(data.size());
|
||||||
}
|
}
|
||||||
for (int i = 0; i < data.length; i++) {
|
|
||||||
int row = currentRowOfTypes - data.length + i;
|
for (int i = 0; i < data.size(); i++) {
|
||||||
model.setValueAt(data[i], row, col);
|
int row = currentRowOfTypes - data.size() + i;
|
||||||
|
model.setValueAt(data.get(i), row, col);
|
||||||
}
|
}
|
||||||
this.repaint();
|
this.repaint();
|
||||||
this.revalidate();
|
this.revalidate();
|
||||||
|
@ -318,55 +316,41 @@ public class EvaluationPanel extends JPanel {
|
||||||
/**
|
/**
|
||||||
* Fügt der Tabelle eine Zeile hinzu
|
* Fügt der Tabelle eine Zeile hinzu
|
||||||
*
|
*
|
||||||
* @param data Daten der Zeile
|
* @param tableEntries Daten der Tabelle
|
||||||
*/
|
*/
|
||||||
public void addRow(Object[] data) {
|
public void addRow(Map<Algorithm.Type, Map<String, String>> tableEntries) {
|
||||||
addBlankRows(1);
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
model.setValueAt(data[i], currentRowOfTypes, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
currentRowOfTypes++;
|
SwingUtilities.invokeLater(() -> {
|
||||||
this.repaint();
|
|
||||||
this.revalidate();
|
Set<Algorithm.Type> types = tableEntries.keySet();
|
||||||
|
List<String> columnlabels = new ArrayList<>();
|
||||||
|
|
||||||
|
types.forEach(type -> {
|
||||||
|
columnlabels.add(" ");
|
||||||
|
});
|
||||||
|
model.setColumnIdentifiers(columnlabels.toArray());
|
||||||
|
tableEntries.entrySet().forEach(row -> {
|
||||||
|
model.addRow(row.getValue().keySet().toArray());
|
||||||
|
model.addRow(row.getValue().values().toArray());
|
||||||
|
});
|
||||||
|
|
||||||
|
this.repaint();
|
||||||
|
this.revalidate();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Visualisierung der Ausgleichsgeraden
|
|
||||||
*
|
|
||||||
* @param alg Steigung und y-Achsenabschnitt der Geraden, bestimmt durch die Schätzer
|
|
||||||
*/
|
|
||||||
public void drawLines(List<Double[]> alg) {
|
|
||||||
Paint[] color = {Color.ORANGE, Color.RED, Color.MAGENTA};
|
|
||||||
String[] name = {"LMS", "RM", "TS"};
|
|
||||||
|
|
||||||
for (Double[] o : alg) {
|
|
||||||
int i = o[0].intValue();
|
|
||||||
Double m = o[1];
|
|
||||||
Double b = o[2];
|
|
||||||
plotPanel.addLineToPlot(m, b, color[i], name[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* <p>
|
||||||
* Visualisierung der Ausgleichsgerade
|
* Visualisierung der Ausgleichsgerade
|
||||||
*
|
*
|
||||||
* @param results Steigung und y-Achsenabschnitt der Gerade, bestimmt durch die Schätzer
|
* @param lines the lines
|
||||||
* @param alg identifizierung des Alg.
|
* @param alg identifizierung des Alg.
|
||||||
*/
|
*/
|
||||||
public void drawLines(Object[] results, int alg) {
|
public void drawLines(final List<Line> lines, final Algorithm.Type alg) {
|
||||||
String[] castedResults = Arrays.copyOf(results, results.length, String[].class);
|
for (Line line : lines) {
|
||||||
Paint[] color = {Color.ORANGE, Color.RED, Color.MAGENTA};
|
plotPanel.addLineToPlot(line.getM(), line.getB(), colorMap.get(alg), alg.name());
|
||||||
String[] name = {"LMS", "RM", "TS"};
|
}
|
||||||
String[] nName = {"Brute-force LMS", "Brute-force RM", "Brute-force TS"};
|
|
||||||
|
|
||||||
double m = Double.parseDouble(castedResults[0]);
|
|
||||||
double b = Double.parseDouble(castedResults[1]);
|
|
||||||
plotPanel.addLineToPlot(m, b, color[alg], name[alg]);
|
|
||||||
|
|
||||||
double nM = Double.parseDouble(castedResults[2]);
|
|
||||||
double nB = Double.parseDouble(castedResults[3]);
|
|
||||||
plotPanel.addLineToPlot(nM, nB, Color.BLACK, nName[alg]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue