bisschen refactor :D About Page müsste noch mit Text gefüllt werden. Theil-Sen läuft stabieler. Menubar ist aufgefüllt. DataExport muss noch bei der Evaluation eingeflegt werden.

This commit is contained in:
Armin Wolf 2017-09-10 17:45:47 +02:00
parent ccd6160745
commit 634d9361ea
86 changed files with 5222 additions and 5076 deletions

View File

@ -1,6 +1,6 @@
import Model.LineModel;
import Presenter.Presenter;
import View.MainFrame;
import model.LineModel;
import presenter.Presenter;
import view.MainFrame;
import javax.swing.*;
import java.awt.*;
@ -14,46 +14,48 @@ import java.awt.*;
*/
public class App {
private static void setUIFont(javax.swing.plaf.FontUIResource f)
{
java.util.Enumeration<Object> keys = UIManager.getDefaults().keys();
while (keys.hasMoreElements())
{
Object key = keys.nextElement();
Object value = UIManager.get(key);
if (value instanceof javax.swing.plaf.FontUIResource)
{
UIManager.put(key, f);
}
private static void setUIFont(javax.swing.plaf.FontUIResource f) {
java.util.Enumeration<Object> keys = UIManager.getDefaults().keys();
while (keys.hasMoreElements()) {
Object key = keys.nextElement();
Object value = UIManager.get(key);
if (value instanceof javax.swing.plaf.FontUIResource) {
UIManager.put(key, f);
}
}
}
}
private static void setLookAndFeel(JFrame view){
try {
UIManager.setLookAndFeel("com.jtattoo.plaf.aluminium.AluminiumLookAndFeel");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (UnsupportedLookAndFeelException e) {
e.printStackTrace();
private static void setLookAndFeel(JFrame view) {
String[] laf = {"com.jtattoo.plaf.aluminium.AluminiumLookAndFeel",
"com.jtattoo.plaf.acryl.AcrylLookAndFeel",
"com.jtattoo.plaf.aero.AeroLookAndFeel",
"com.jtattoo.plaf.fast.FastLookAndFeel",
"com.jtattoo.plaf.graphite.GraphiteLookAndFeel"};
try {
UIManager.setLookAndFeel(laf[4]);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
SwingUtilities.updateComponentTreeUI(view);
}
SwingUtilities.updateComponentTreeUI(view);
}
public static void main(String[] args) {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame.setDefaultLookAndFeelDecorated(true);
MainFrame view = new MainFrame();
setLookAndFeel(view);
setUIFont (new javax.swing.plaf.FontUIResource(new Font("Verdana",Font.PLAIN, 12)));
SwingUtilities.invokeLater(() -> {
JFrame.setDefaultLookAndFeelDecorated(true);
MainFrame view = new MainFrame();
setLookAndFeel(view);
setUIFont(new javax.swing.plaf.FontUIResource(new Font("Verdana", Font.PLAIN, 12)));
view.setPresenter(new Presenter(new LineModel(), view));
view.setActionListeners();
});
view.setPresenter(new Presenter(new LineModel(), view));
});
}
}
}

View File

@ -1,153 +0,0 @@
package Model.DCEL;
import Model.Point;
import java.util.LinkedList;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 30.05.2017.
*/
public class DoublyConnectedEdgeList {
private LinkedList<Node> nodes;
private LinkedList<Edge> edges;
private LinkedList<Face> faces;
public DoublyConnectedEdgeList() {
this.nodes = new LinkedList<>();
this.edges = new LinkedList<>();
this.faces = new LinkedList<>();
}
public Node createNode(Point point, String id) {
Node node = new Node();
node.setPoint(point);
node.setID(id);
return node;
}
public Edge createEdge(Node source, Node destination, String id) {
Edge edge = new Edge();
Edge twin = new Edge();
edge.setOrigin(source);
edge.setID(id);
edge.setTwin(twin);
twin.setOrigin(destination);
twin.setID("#" + id);
twin.setTwin(edge);
source.setIncidentEdge(edge);
destination.setIncidentEdge(twin);
return edge;
}
public Face createFace(Edge outerComponent, Edge innerComponent, String id) {
Face face = new Face(outerComponent, null);
face.setID(id);
Edge tempEdge;
if (outerComponent != null) {
tempEdge = outerComponent;
do {
tempEdge.setIncidentFace(face);
tempEdge = tempEdge.getNext();
} while (!tempEdge.equals(outerComponent));
}
if (innerComponent != null) {
LinkedList<Edge> componentlist;
componentlist = face.getInnerComponents();
componentlist.add(innerComponent);
tempEdge = innerComponent;
do {
tempEdge.setIncidentFace(face);
tempEdge = tempEdge.getNext();
} while (!tempEdge.equals(innerComponent));
}
return face;
}
public void createConnection(Edge edge, Edge succ) {
edge.setNext(succ);
succ.setPrev(edge);
edge.getTwin().setPrev(succ.getTwin());
succ.getTwin().setNext(edge.getTwin());
}
public LinkedList<Edge> getEdgesOfInnerComponents(Face face) {
LinkedList<Edge> list = new LinkedList();
LinkedList<Edge> innerComponents = face.getInnerComponents();
Edge it;
for (Edge e : innerComponents) {
it = e;
do {
list.add(it);
//System.out.println("Current Edge: "+it.getID()+"\tNext Edge: "+it.getNext().getID());
it = it.getNext();
} while (it != e);
}
return list;
}
public LinkedList<Edge> getEdgesOfOuterComponents(Face face) {
LinkedList<Edge> list = new LinkedList();
Edge it = face.getOuterComponent();
do {
list.add(it);
//System.out.println("Current Edge: "+it.getID()+"\tNext Edge: "+it.getNext().getID());
it = it.getNext();
} while (it != face.getOuterComponent());
return list;
}
public LinkedList<Edge> getConnectedEdges(Node node) {
Edge edge = node.getIncidentEdge();
LinkedList list = new LinkedList();
do {
list.add(edge);
edge = edge.getNext();
} while (node != edge.getOrigin());
return list;
}
public LinkedList<Node> getNodes() {
return nodes;
}
public void setNodes(LinkedList<Node> nodes) {
this.nodes = nodes;
}
public LinkedList<Edge> getEdges() {
return edges;
}
public void setEdges(LinkedList<Edge> edges) {
this.edges = edges;
}
public LinkedList<Face> getFaces() {
return faces;
}
public void setFaces(LinkedList<Face> faces) {
this.faces = faces;
}
}

View File

@ -1,117 +0,0 @@
package Model.DCEL;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 30.05.2017.
*/
public class Edge {
private Node origin;
private Edge twin;
private Face incidentFace;
private Edge next;
private Edge prev;
private String id;
public Edge() {
new Edge(null, null, null, null, null);
}
public Edge(Node origin, Edge twin, Edge next, Edge prev, Face incidentFace) {
this.origin = origin;
this.twin = twin;
this.next = next;
this.prev = prev;
this.incidentFace = incidentFace;
}
public Node getOrigin() {
return origin;
}
public void setOrigin(Node origin) {
this.origin = origin;
}
public Edge getTwin() {
return twin;
}
public void setTwin(Edge twin) {
this.twin = twin;
}
public Face getIncidentFace() {
return incidentFace;
}
public void setIncidentFace(Face incidentFace) {
this.incidentFace = incidentFace;
}
public Edge getNext() {
return next;
}
public void setNext(Edge next) {
this.next = next;
}
public Edge getPrev() {
return prev;
}
public void setPrev(Edge prev) {
this.prev = prev;
}
public boolean hasNext() {
if (getNext() == null) {
return false;
} else {
return true;
}
}
public Edge insertNode(Node node) {
Edge edge = new Edge();
Edge twin = new Edge();
edge.setOrigin(node);
edge.setNext(this.getNext());
edge.setPrev(this);
edge.setTwin(twin);
edge.setIncidentFace(this.getIncidentFace());
twin.setOrigin(this.getTwin().getOrigin());
twin.setPrev(this.getTwin().getPrev());
twin.setNext(this.getTwin());
twin.setTwin(edge);
twin.setIncidentFace(this.getTwin().getIncidentFace());
Node twinOrigin = this.getTwin().getOrigin();
twinOrigin.setIncidentEdge(twin);
node.setIncidentEdge(edge);
this.getTwin().setOrigin(node);
this.getTwin().getPrev().setNext(twin);
this.getNext().setPrev(edge);
this.setNext(edge);
this.getTwin().setPrev(twin);
return edge;
}
public String getID() {
return this.id;
}
public void setID(String id) {
this.id = id;
}
}

View File

@ -1,125 +0,0 @@
package Model.DCEL;
import java.util.LinkedList;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 30.05.2017.
*/
public class Face {
private LinkedList<Edge> innerComponents;
private Edge outerComponent;
private String id;
public Face() {
this.outerComponent = null;
this.innerComponents = new LinkedList<>();
}
public Face(Edge outerComponent, LinkedList<Edge> innerComponents) {
this.outerComponent = outerComponent;
if (innerComponents != null) {
this.innerComponents = innerComponents;
} else {
this.innerComponents = new LinkedList<>();
}
}
public LinkedList<Edge> getInnerComponents() {
return innerComponents;
}
public void setInnerComponents(LinkedList<Edge> innerComponents) {
this.innerComponents = innerComponents;
}
public Edge getOuterComponent() {
return outerComponent;
}
public void setOuterComponent(Edge outerComponent) {
this.outerComponent = outerComponent;
}
public Face insertEdge(Edge edgeWithSameDestination, Edge edgeToMySource) {
if (edgeWithSameDestination.getIncidentFace().equals(this) || edgeToMySource.getIncidentFace()
.equals(this)) {
LinkedList<Edge> components = new LinkedList<Edge>();
for (Edge e : innerComponents) {
components.add(e);
}
Face face = new Face(getOuterComponent(), components);
Edge edge = new Edge();
Edge twin = new Edge();
edge.setOrigin(edgeWithSameDestination.getOrigin());
edge.setTwin(twin);
edge.setNext(edgeToMySource);
edge.setPrev(edgeWithSameDestination.getPrev());
twin.setOrigin(edgeToMySource.getOrigin());
twin.setTwin(edge);
twin.setNext(edgeWithSameDestination);
twin.setPrev(edgeToMySource.getPrev());
Edge tempEdge = edge.getNext();
Edge tempTwin = twin.getNext();
//kreis umlaufen um festzustellen welche fläche kleiner ist
while ((tempEdge.equals(edge) == false) && (tempTwin.equals(twin) == false)) {
tempEdge = tempEdge.getNext();
tempTwin = tempTwin.getNext();
}
if (tempEdge.equals(edge)) {
setOuterComponent(twin);
twin.setIncidentFace(this);
face.setOuterComponent(edge);
} else {
setOuterComponent(edge);
edge.setIncidentFace(this);
face.setOuterComponent(twin);
}
LinkedList<Edge> bla = new LinkedList<Edge>();
Edge iterEdge = face.getOuterComponent();
bla.add(face.getOuterComponent());
while (iterEdge.hasNext()) {
bla.add(iterEdge.getNext());
iterEdge = iterEdge.getNext();
}
for (Edge e : face.getInnerComponents()) {
iterEdge = e;
while (iterEdge.hasNext()) {
bla.add(iterEdge.getNext());
iterEdge = iterEdge.getNext();
}
}
for (Edge e : bla) {
e.setIncidentFace(face);
}
return face;
} else {
throw new IllegalArgumentException(
"Die angegebenen Kanten haben keinen zusammenhang mit der Fläche!");
}
}
public String getID() {
return this.id;
}
public void setID(String id) {
this.id = id;
}
}

View File

@ -1,50 +0,0 @@
package Model.DCEL;
import Model.Point;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 30.05.2017.
*/
public class Node {
private Point point;
private Edge incidentEdge;
private String id;
public Node() {
new Node(null, null);
}
public Node(Point point, Edge incidentEdge) {
this.point = point;
this.incidentEdge = incidentEdge;
}
public Point getPoint() {
return point;
}
public void setPoint(Point point) {
this.point = point;
}
public Edge getIncidentEdge() {
return incidentEdge;
}
public void setIncidentEdge(Edge incidentEdge) {
this.incidentEdge = incidentEdge;
}
public String getID() {
return this.id;
}
public void setID(String id) {
this.id = id;
}
}

View File

@ -1,51 +0,0 @@
package Model;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 16.06.2017.
*/
public class Interval {
private double upper;
private double lower;
private Boolean activity;
public Interval(double lower, double upper) {
this.upper = upper;
this.lower = lower;
this.activity = true;
}
public Boolean getActivity() {
return activity;
}
public void setActivity(Boolean isActive) {
this.activity = isActive;
}
public double getUpper() {
return upper;
}
public void setUpper(double upper) {
this.upper = upper;
}
public double getLower() {
return lower;
}
public void setLower(double lower) {
this.lower = lower;
}
public Double getDistance() {
return Math.abs(this.upper - this.lower);
}
}

View File

@ -1,107 +0,0 @@
package Model;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 12.06.2017.
*/
public class Line {
private final Double MAX = 9999d;
private final Double MIN = -9999d;
private Double m;
private Double b;
private Double x1;
private Double x2;
private Double y1;
private Double y2;
private String id;
public Line(double m, double b, String id) {
this.m = m;
this.b = b;
this.x1 = MIN;
this.y1 = (MIN * m) + b;
this.x2 = MAX * 0.5;
this.y2 = ((MAX * 0.5) * m) + b;
this.id = id;
}
public Line(double m, double b) {
this.m = m;
this.b = b;
this.x1 = MIN;
this.y1 = (MIN * m) + b;
this.x2 = MAX * 0.5;
this.y2 = ((MAX * 0.5) * m) + b;
}
public Line(double x1, double x2, double y1, double y2) {
this.x1 = x1;
this.x2 = x2;
this.y1 = y1;
this.y2 = y2;
this.m = (y2 - y1) / (x2 - x1);
this.b = y2 - (x2 * m);
}
public Double getM() {
return m;
}
public void setM(double m) {
this.m = m;
}
public Double getB() {
return b;
}
public void setB(double b) {
this.b = b;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Double getX1() {
return x1;
}
public Double getX2() {
return x2;
}
public Double getY1() {
return y1;
}
public Double getY2() {
return y2;
}
public void setEndPoints(double x1, double y1, double x2, double y2) {
this.x1 = x1;
this.x2 = x2;
this.y1 = y1;
this.y2 = y2;
}
}

View File

@ -1,98 +0,0 @@
package Model;
import java.util.Collections;
import java.util.LinkedList;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 28.05.2017.
*/
public class LineModel {
private LinkedList<Point> nodes;
private LinkedList<Line> lines;
private Double xMinimum;
private Double xMaximum;
private Double yMinimum;
private Double yMaximum;
public LineModel() {
nodes = new LinkedList<>();
lines = new LinkedList<>();
}
public void setXbounds(){
LinkedList<Double> xlist = new LinkedList<>();
for (Point p : nodes){
xlist.add(p.getX());
}
xMaximum = Collections.max(xlist);
xMinimum = Collections.min(xlist);
}
public void setYbounds(){
LinkedList<Double> ylist = new LinkedList<>();
for (Point p : nodes){
ylist.add(p.getY());
}
yMaximum = Collections.max(ylist);
yMinimum = Collections.min(ylist);
}
public void addNode(Point node) {
this.nodes.add(node);
}
public void addLine(Line line) {
this.lines.add(line);
}
public LinkedList<Point> getNodes() {
return nodes;
}
public LinkedList<Line> getLines() {
return lines;
}
public void setLines(LinkedList<Line> lines) {
this.lines = lines;
}
public Double getxMinimum() {
return xMinimum;
}
public void setxMinimum(Double xMinimum) {
this.xMinimum = xMinimum;
}
public Double getxMaximum() {
return xMaximum;
}
public void setxMaximum(Double xMaximum) {
this.xMaximum = xMaximum;
}
public Double getyMinimum() {
return yMinimum;
}
public void setyMinimum(Double yMinimum) {
this.yMinimum = yMinimum;
}
public Double getyMaximum() {
return yMaximum;
}
public void setyMaximum(Double yMaximum) {
this.yMaximum = yMaximum;
}
}

View File

@ -1,35 +0,0 @@
package Model;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 19.06.2017.
*/
public class Pair {
private Integer p1;
private Integer p2;
public Pair(Integer p1, Integer p2) {
this.p1 = p1;
this.p2 = p2;
}
public Integer getP1() {
return p1;
}
public void setP1(Integer p1) {
this.p1 = p1;
}
public Integer getP2() {
return p2;
}
public void setP2(Integer p2) {
this.p2 = p2;
}
}

View File

@ -1,65 +0,0 @@
package Model;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 28.05.2017.
*/
public class Point implements Comparable<Point> {
private Double x;
private Double y;
private String id;
public Point(Double x, Double y) {
this.x = x;
this.y = y;
}
public Point(Double x, Double y, String id) {
this.x = x;
this.y = y;
this.id = id;
}
public Double getX() {
return x;
}
public void setX(Double x) {
this.x = x;
}
public Double getY() {
return y;
}
public void setY(Double y) {
this.y = y;
}
@Override
public int compareTo(Point o) {
if (this.getX() == o.getX()) {
if (this.getY() <= o.getY()) {
return -1;
} else {
return 1;
}
} else if (this.getX() < o.getX()) {
return -1;
} else {
return 1;
}
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}

View File

@ -1,30 +0,0 @@
package Presenter.Algorithms;
import Presenter.Presenter;
import java.util.Collections;
import java.util.LinkedList;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 26.06.2017.
*/
public class BinomialCoeffizient {
public static Double run(int n, int k) {
int res = 1;
if ( k > n - k )
k = n - k;
for (int i = 0; i < k; ++i){
res *= (n - i);
res /= (i + 1);
}
return Double.valueOf(res);
}
}

View File

@ -1,272 +0,0 @@
package Presenter.Algorithms;
import Model.*;
import Presenter.Algorithms.Comparators.YOrderLineComparatorBegin;
import Presenter.Algorithms.Comparators.YOrderLineComparatorEnd;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 18.06.2017.
*/
public class IntersectionCounter {
private HashMap<Integer, Integer> dictionaryTO;
private HashMap<Integer, Integer> dictionaryBACK;
private ArrayList<Integer> substituted;
private ArrayList<Pair> inversions;
private List<Line> set;
//indexieren der Punkte damit die schnittpunkte berechnet werden können
private HashMap<Line, Integer> secondaryDictionaryTO;
private HashMap<Integer, Line> secondaryDictionaryBACK;
private ArrayList<Line> umin;
/**
* Berechnet die Inversionen zwischen zwei Listen mit Integer Werten. Diese Methode dient als
* Wrapper Methode. Die Logik steht in der <code>countInversions</code> Funktion.
*
* @param a Liste
* @param b Liste
* @return Anzahl an Inversionen
*/
public int run(List<Integer> a, List<Integer> b) {
dictionaryTO = new HashMap<>();
dictionaryBACK = new HashMap<>();
substituted = new ArrayList<>();
inversions = new ArrayList<>();
ArrayList<Integer> temp = new ArrayList<>();
temp.addAll(a);
for (int i = 0; i < a.size(); i++) {
dictionaryTO.put(a.get(i), i + 1);
dictionaryBACK.put(i + 1, a.get(i));
}
for (int j = 0; j < b.size(); j++) {
substituted.add(dictionaryTO.get(b.get(j)));
}
int ret = countInversions(substituted, 0, substituted.size() - 1, temp);
return ret;
}
/**
* Wrapper Methode um herauszufinden wieviele Inversionen zwischen den Schnittpunkten der Werte
* in der Liste und den Endpunkten des Intervalls entstehen.
*
* @param set Liste mit Werten (m,b) um Schnittpunkte zu berechnen
* @param interval Interval
* @return Anzahl an Inversionen
*/
public int run(List<Line> set, Interval interval) {
ArrayList<Integer> listA = new ArrayList<>();
ArrayList<Integer> listB = new ArrayList<>();
prepareData(set, interval, listA, listB);
return run(listA, listB);
}
/**
* Methode die, die Daten für die Funktion <code>run</code> vorbereitet. Es werden die Schnittpunkte
* bzgl. der unteren und oberen Grenze des Intervals und den Werten der Liste (m,b) berechnet. Diese
* Werte haben die selbe x Koordinate aber verschiedene y Koordinaten.
*
* @param set Liste mit Werten m,b
* @param interval Interval
* @param listA Schnittpunkte bzgl. unteren Grenze
* @param listB Schnittpunkte bzgl. oberen Grenze
*/
private void prepareData(List<Line> set, Interval interval, ArrayList<Integer> listA,
ArrayList<Integer> listB) {
secondaryDictionaryTO = new HashMap<>();
secondaryDictionaryBACK = new HashMap<>();
this.set = set;
umin = new ArrayList<>();
Line tmpLine;
for (Line p : set) {
//vertauscht das Point standardmäßig die x lexikografische Ordnung betrachtet
tmpLine = new Line(p.getM(), p.getM(), interval.getLower() * p.getM() + p.getB(),
interval.getUpper() * p.getM() + p.getB());
//wird benötigt um späer die Schnittpunkte ermitteln zu können
tmpLine.setB(p.getB());
tmpLine.setM(p.getM());
umin.add(tmpLine);
}
for (int i = 0; i < umin.size(); i++) {
secondaryDictionaryTO.put(umin.get(i), i);
secondaryDictionaryBACK.put(i, this.set.get(i));
}
Collections.sort(umin, new YOrderLineComparatorBegin());
for (Line q : umin) {
listA.add(secondaryDictionaryTO.get(q));
}
Collections.sort(umin, new YOrderLineComparatorEnd());
for (Line q : umin) {
listB.add(secondaryDictionaryTO.get(q));
}
}
/**
* Angepasster Merge-Sort Algorithmus.
* Die Funktion bekommt neben den standard Parametern zusätzlich eine Liste mit Elementen
* die als Groundtruth dienen.
*
* @param a Eingabefeld mit den Elementen die überprüft werden sollen.
* @param start Startpunkt des Eingabefeldes.
* @param end Endpunkt des Eingabefeldes.
* @param aux Temporäres Array das beim Mergen eine Kopie des original Arrays ist.
* @return Anzahl der inversionen zwischen a und aux.
*/
public int countInversions(List<Integer> a, int start, int end, List<Integer> aux) {
if (start >= end) {
return 0;
}
int invCount = 0;
int mid = start + (end - start) / 2;
int invCountLeft = countInversions(a, start, mid, aux); // divide and conquer
int invCountRight = countInversions(a, mid + 1, end, aux); // divide and conquer
invCount += (invCountLeft + invCountRight);
for (int i = start; i <= end; i++) {
aux.set(i, a.get(i));
}
int left = start;
int right = mid + 1;
int index = start;
//hier beginnt das merging
//iteriere über die Teillisten
//Two-way Merge - Knuth Vol 3 The Art of Computer Programming -
while (left <= mid && right <= end) {
//wenn die linke Teilliste das kleinere Element besitzt kopiere
//das Element in das neue Array
if (aux.get(left) < aux.get(right)) {
a.set(index++, aux.get(left++));
} else {
//merke die inversionspaare
for (int i = left; i <= mid; i++) {
// System.out.println(aux.get(i)+" -- "+ aux.get(right));
inversions.add(new Pair(aux.get(i), aux.get(right)));
}
a.set(index++, aux.get(right++));
invCount += mid - left + 1; // number of inversions for aux[right]
}
}
while (left <= mid) {
a.set(index++, aux.get(left++));
}
// no need to copy over remaining aux[right++] because they are already inside a
return invCount;
}
/**
* Diese Methode liefert nur nach dem Ausführen der <code>run</code> Funktion Sinnvolle Werte.
*
* @return Map mit Schnittpunkt Paaren.
*/
public HashMap<Line, ArrayList<Line>> getIntersectionLinePairs() {
ArrayList<Pair> result = new ArrayList<>();
HashMap<Line, ArrayList<Line>> ret = new HashMap<>();
for (int i = 0; i < inversions.size(); i++) {
result.add(new Pair(dictionaryBACK.get(inversions.get(i).getP1()),
dictionaryBACK.get(inversions.get(i).getP2())));
}
ArrayList<Line> linePairs;
for (Pair p : result) {
Line l1 = secondaryDictionaryBACK.get(p.getP1());
Line l2 = secondaryDictionaryBACK.get(p.getP2());
if (ret.get(l2) == null){
linePairs = new ArrayList<>();
} else {
linePairs = ret.get(l2);
}
linePairs.add(l1);
ret.put(l2, linePairs);
//Symetrie
if (ret.get(l1) == null){
linePairs = new ArrayList<>();
} else {
linePairs = ret.get(l1);
}
linePairs.add(l2);
ret.put(l1, linePairs);
}
/*System.out.println("----------------------------------------------------------");
for (Line outerLine : ret.keySet()){
System.out.println("Linie: "+outerLine);
for (Line innerLine : ret.get(outerLine)){
System.out.println("\t\t -> "+innerLine);
}
}
System.out.println("----------------------------------------------------------");*/
return ret;
}
/**
* Diese Methode liefert nur nach dem Ausführen der <code>run</code> Funktion Sinnvolle Werte.
*/
public void calculateIntersectionAbscissas(LineModel model){
ArrayList<Pair> result = new ArrayList<>();
for (int i = 0; i < inversions.size(); i++) {
result.add(new Pair(dictionaryBACK.get(inversions.get(i).getP1()),
dictionaryBACK.get(inversions.get(i).getP2())));
}
for (Pair p : result) {
Line line = secondaryDictionaryBACK.get(p.getP1());
Line sampledLine = secondaryDictionaryBACK.get(p.getP2());
if (!line.equals(sampledLine)){
double intersection = (line.getB() - sampledLine.getB()) / (sampledLine.getM() - line.getM());
double yintercept = sampledLine.getM() * intersection + sampledLine.getB();
model.addNode(new Point(intersection, yintercept));
}
}
}
/**
* Berechnet die Schnittpunkte zwischen einer gegebenen Gerade und einer Menge an Geraden.
*
* @param set Menge an Geraden
* @param sampledLine eine spezielle Gerade
* @return Liste mit x Koordinaten der Schnittpunkte
*/
public ArrayList<Double> calculateIntersectionAbscissas(ArrayList<Line> set, Line sampledLine){
LinkedList<Line> lines = new LinkedList<>(set);
ArrayList<Double> intersections = new ArrayList<>();
double intersection;
for (Line line : lines) {
if (line != sampledLine) {
intersection = (line.getB() - sampledLine.getB()) / (sampledLine.getM() - line.getM());
intersections.add(intersection);
}
}
return intersections;
}
}

View File

@ -1,484 +0,0 @@
package Presenter.Algorithms;
import Model.Interval;
import Model.Line;
import Model.Point;
import Presenter.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.Observable;
import java.util.PriorityQueue;
import java.util.Random;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 28.05.2017.
*/
public class LeastMedianOfSquaresEstimator extends Observable implements Algorithm {
private Presenter presenter;
private LinkedList<Line> set = new LinkedList<>();
private LinkedList<Point> intersections = new LinkedList<>();
private IntersectionCounter invCounter = new IntersectionCounter();
private int n;
private double quantileError;
private int kPlus;
private int kMinus;
private PriorityQueue<Interval> intervals;
private Interval subSlabU1;
private Interval subSlabU2;
private Line sigmaMin;
private double heightsigmaMin;
private Double intersectionsPoint;
private Double constant = 0.5;
private Double slope;
private Double yInterception;
public LeastMedianOfSquaresEstimator(LinkedList<Line> set, LinkedList<Point> intersections,
Presenter presenter) {
this.set = set;
this.intersections = intersections;
//(1.) Let n <- |S|; q+ <- q; q- <- q+ * (1 - quantileError);....
n = set.size();
double quantile = 0.5;
double qPlus = quantile;
quantileError = 0.1;
double qMinus = qPlus * (1 - quantileError);
kMinus = (int) Math.ceil(n * qMinus);
kPlus = (int) Math.ceil(n * qPlus);
this.presenter = presenter;
}
public LeastMedianOfSquaresEstimator(LinkedList<Line> set, LinkedList<Point> intersections) {
this(set, intersections, null);
}
/**
*
*/
public void run() {
//(2.) Let U <- (-inf, inf) be the initial active intervals...
Comparator<Interval> comparator = (o1, o2) -> {
if (o1.getDistance() < o2.getDistance()) {
return -1;
}
if (o1.getDistance() > o2.getDistance()) {
return 1;
} else {
return 0;
}
};
intervals = new PriorityQueue<>(comparator);
intervals.add(new Interval(-100000, 100000));
heightsigmaMin = Double.MAX_VALUE;
LinkedList<Point> tmpIntersections = intersections;
//(3.) Apply the following steps as long as the exists active intervals
boolean active = true;
Interval interval;
while (!this.intervals.isEmpty()) {
interval = this.intervals.peek();
if (interval.getActivity()) {
//(a.) Select any active Interval and calc. the inversions
int numberOfIntersections = countInversions(interval);
//(b.) apply plane sweep
if ((constant * n) >= numberOfIntersections) {
sigmaMin = planeSweep(interval);
} else {
//(c.) otherwise....
// get random intersections point...
Collections.shuffle(tmpIntersections, new Random());
for (int i = 0; i < tmpIntersections.size(); i++) {
if (tmpIntersections.get(i).getX() > interval.getLower()
&& tmpIntersections.get(i).getX() < interval.getUpper()) {
intersectionsPoint = tmpIntersections.get(i).getX();
break;
} else {
intersectionsPoint = null;
}
}
if (intersectionsPoint != null) {
splitActiveSlab(intersectionsPoint, interval);
//(d.) this may update sigma min
upperBound(intersectionsPoint);
//(e.) for i={1,2}, call lower bound(Ui)
lowerBound(subSlabU1);
lowerBound(subSlabU2);
if (subSlabU1.getActivity()) {
this.intervals.add(subSlabU1);
}
if (subSlabU2.getActivity()) {
this.intervals.add(subSlabU2);
}
} else {
this.intervals.poll();
}
}
} else {
this.intervals.remove(interval);
}
}
}
/**
* @param interval
* @return
*/
public int countInversions(Interval interval) {
int numberOfInversions = 0;
// debug
//for (int i=0;i<listA.size();i++){
// System.out.println(listA.get(i)+", "+listB.get(i));
//}
numberOfInversions = invCounter.run(set, interval);
return numberOfInversions;
}
/**
* @param interval
* @return
*/
public Line planeSweep(Interval interval) {
//initialisiere die x-Queue mit den 2D Punkten und sortiere nach x-Lexikographischer Ordnung
ArrayList<Point> xQueue = new ArrayList<>();
for (Point point : intersections) {
if (point.getX() >= interval.getLower() && point.getX() < interval.getUpper()) {
xQueue.add(point);
}
}
Collections.sort(xQueue);
Line bracelet = sigmaMin;
double heightOfBracelet = heightsigmaMin;
for (Point current : xQueue) {
Double[] currentBracelet = calcKMinusBracelet(current, kMinus);
if (currentBracelet == null) {
continue;
} else if (currentBracelet[0] < heightOfBracelet) {
heightOfBracelet = currentBracelet[0];
bracelet = new Line(current.getX(), current.getX(), currentBracelet[1], currentBracelet[2]);
}
}
interval.setActivity(false);
return bracelet;
}
/**
* Diese Methode spaltet den aktiven Interval an der x Koordinate point. Es werden zwei neue Slabs
* erzeugt.
*
* @param point x Koordinate an der, der Split geschieht.
*/
public void splitActiveSlab(double point, Interval active) {
subSlabU1 = new Interval(active.getLower() + 0.01, point);
subSlabU2 = new Interval(point, active.getUpper());
this.intervals.remove(active);
}
/**
*
* @param point
*/
public void upperBound(double point) {
double height = heightsigmaMin;
double tmpHeight;
ArrayList<Double> sortedLineSequence = getEjValues(point);
int itnbr = ((n - kMinus) + 1);
for (int i = 0; i < itnbr; i++) {
tmpHeight = sortedLineSequence.get((i + kMinus) - 1) - sortedLineSequence.get(i);
if (tmpHeight < height) {
height = tmpHeight;
}
if (height < heightsigmaMin) {
heightsigmaMin = height;
if (sigmaMin != null) {
sigmaMin.setEndPoints(point, sortedLineSequence.get(i)
, point, sortedLineSequence.get((i + kMinus) - 1));
} else {
sigmaMin = new Line(point, point, sortedLineSequence.get(i),
sortedLineSequence.get((i + kMinus) - 1));
}
}
}
}
/**
* @param pslab
* @return
*/
public void lowerBound(Interval pslab) {
int[] alpha = new int[n];
int[] beta = new int[n];
int strictlyGreater = 0;
//Teil I.
ArrayList<Double> umaxList;
ArrayList<Double> uminList;
//y koordinaten der Schnittpunkte
ArrayList<Line> lines = new ArrayList<>();
for (Line p : set) {
lines.add(
new Line(pslab.getLower(), pslab.getUpper(), ((pslab.getLower() * p.getM()) + p.getB()),
((pslab.getUpper() * p.getM()) + p.getB())));
}
umaxList = getEjValues(pslab.getUpper());
uminList = getEjValues(pslab.getLower());
for (int i = 0; i < n; i++) {
Line level = new Line(pslab.getLower(), pslab.getUpper(), uminList.get(i), umaxList.get(i));
for (Line line : lines) {
if ((line.getY1() < level.getY1()) && (line.getY2() < level.getY2())) {
alpha[i]++;
}
if ((line.getY1() > level.getY1()) && (line.getY2() > level.getY2())) {
strictlyGreater++;
}
}
beta[i] = n - (alpha[i] + strictlyGreater);
strictlyGreater = 0;
}
//TEST der Alpha und Beta werte, siehe JUnit Test
//for (int i=0;i<alpha.length;i++){
// System.out.println("Alpha["+i+"]: "+alpha[i]+"\t Beta["+i+"]: "+beta[i]);
//}
//Test
//Teil II.
int i = 0;
double h;
pslab.setActivity(false);
for (int j = 0; j < n; j++) {
while ((i < n && (Math.abs(beta[i] - alpha[j]) < kPlus))) {
i++;
}
//test
//if (i < n)
// System.out.println("i: "+i+", j:"+j+"\t "+Math.abs(beta[i] - alpha[j])+"\t kPlus: "+kPlus);
if (i >= n) {
//System.out.println("i: "+i+", j:"+j+". ungültig");
pslab.setActivity(false);
break;
} else {
h = Math.min(Math.abs(uminList.get(j) - uminList.get(i)),
Math.abs(umaxList.get(j) - umaxList.get(i)));
double error = 0.01;
if (((1 + error) * h) < heightsigmaMin) {
//System.out.println("h: "+ h +" ist kleiner als height(sigmaMin): "+heightsigmaMin);
pslab.setActivity(true);
return;
}
}
i = 0;
}
}
/**
* Berechnet die Schnittpunkte der Geraden und der vertikalen Gerade u. Im paper sind diese Werte
* als e_j Werte bekannt.
*
* @param u vertikale Gerade
* @return Liste der Schnittpunkte (da u bekannt werden nur die y Werte zurück gegeben)
*/
public ArrayList<Double> getEjValues(double u) {
ArrayList<Double> ret = new ArrayList<>();
for (Line p : set) {
ret.add((p.getM() * u) + p.getB());
}
Collections.sort(ret);
return ret;
}
/**
* Die Funktion berechnet anhand einer vertikalen Gerade x = px das sogenannte kleinste kMinus
* Bracelet. Mit anderen Worten es wird eine vertikale Teilgerade berechnet die mindestens kMinus
* Geraden schneidet und dabei minimal ist.
*
* @param px Koordinate um die "vertikale Gerade" zu simulieren.
* @return Das Array enthält höhe des Bracelet, e_j und e_(j + kMinus - 1)
*/
public Double[] calcKMinusBracelet(Point px, int kMinusValue) {
//y Koordinaten für das kMinus brecalet
LinkedList<Double> intersections = new LinkedList<>();
for (Line line : set) {
intersections.add((px.getX() * line.getM()) + line.getB());
}
if (intersections.size() >= kMinusValue) {
Collections.sort(intersections);
double height = Math.abs(intersections.get(0) - intersections.get(0 + kMinusValue - 1));
Double[] ret = {height, intersections.get(0), intersections.get(0 + kMinusValue - 1)};
return ret;
} else {
return null;
}
}
@Override
public void getResult() {
if (presenter != null) {
setChanged();
double m = (getSigmaMin().getX2() + getSigmaMin().getX1()) * 0.5;
double b = (getSigmaMin().getY2() + getSigmaMin().getY1()) * -0.5;
slope = m;
yInterception = b;
String[] result = {"lms", m+"", b+""};
notifyObservers(result);
} else {
double m = (getSigmaMin().getX2() + getSigmaMin().getX1()) * 0.5;
double b = (getSigmaMin().getY2() + getSigmaMin().getY1()) * -0.5;
slope = m;
yInterception = b;
}
}
/**
* Im Allgemeinen werden keine Getter und Setter Methoden benötigt aber sie sind nützlich bei den
* JUnit Testfällen.
*/
public LinkedList<Line> getSet() {
return set;
}
public void setSet(LinkedList<Line> set) {
this.set = set;
}
public LinkedList<Point> getIntersections() {
return intersections;
}
public void setIntersections(LinkedList<Point> intersections) {
this.intersections = intersections;
}
public int getN() {
return n;
}
public void setN(int n) {
this.n = n;
}
public double getQuantileError() {
return quantileError;
}
public void setQuantileError(double quantileError) {
this.quantileError = quantileError;
}
public int getkPlus() {
return kPlus;
}
public void setkPlus(int kPlus) {
this.kPlus = kPlus;
}
public int getkMinus() {
return kMinus;
}
public void setkMinus(int kMinus) {
this.kMinus = kMinus;
}
public Interval getSubSlabU1() {
return subSlabU1;
}
public void setSubSlabU1(Interval subSlabU1) {
this.subSlabU1 = subSlabU1;
}
public Interval getSubSlabU2() {
return subSlabU2;
}
public void setSubSlabU2(Interval subSlabU2) {
this.subSlabU2 = subSlabU2;
}
public Line getSigmaMin() {
return sigmaMin;
}
public void setSigmaMin(Line sigmaMin) {
this.sigmaMin = sigmaMin;
}
public double getHeightsigmaMin() {
return heightsigmaMin;
}
public void setHeightsigmaMin(double heightsigmaMin) {
this.heightsigmaMin = heightsigmaMin;
}
public double getIntersectionsPoint() {
return intersectionsPoint;
}
public void setIntersectionsPoint(double intersectionsPoint) {
this.intersectionsPoint = intersectionsPoint;
}
public Double getConstant() {
return constant;
}
public void setConstant(Double constant) {
this.constant = constant;
}
public Double getSlope() {
return slope;
}
public Double getyInterception() {
return yInterception;
}
}

View File

@ -1,52 +0,0 @@
package Presenter.Algorithms;
import Model.Line;
import Model.Point;
import java.util.ArrayList;
import java.util.concurrent.ThreadLocalRandom;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 26.06.2017.
*/
public class RandomSampler {
/**
* Diese Methode liefert eine <code>r</code> Elementige zufällige Stichprobe an Geraden.
* @param set Die gesammtmenge der Geraden aus denen gewählt werden soll
* @param r Anzahl der zu wählenden Geraden
* @return <code>r</code> Elementige zufällige Stichprobe an Geraden
*/
public static ArrayList<Line> run(ArrayList<Line> set, Double r, Integer indexOfEnd) {
ArrayList<Line> sampledLines = new ArrayList<>();
for (int i = 0; i < r; i++) {
sampledLines.add(set.get(ThreadLocalRandom.current().nextInt(0, indexOfEnd)));
}
return sampledLines;
}
/**
* Diese Methode liefert eine <code>r</code> Elementige zufällige Stichprobe van Schnittpunkten.
* @param set Die gesammtmenge der Geraden aus denen gewählt werden soll
* @param r Anzahl der zu wählenden Geraden
* @return <code>r</code> Elementige zufällige Stichprobe an Schnittpunkten
*/
public static ArrayList<Double> run(ArrayList<Point> set, Double r) {
ArrayList<Double> sampledLines = new ArrayList<>();
Integer indexOfEnd = set.size();
for (int i = 0; i < r; i++) {
sampledLines.add(set.get(ThreadLocalRandom.current().nextInt(0, indexOfEnd)).getX());
}
return sampledLines;
}
}

View File

@ -1,459 +0,0 @@
package Presenter.Algorithms;
import Model.Interval;
import Model.Line;
import Presenter.*;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 28.05.2017.
*/
public class RepeatedMedianEstimator extends Observable implements Algorithm {
private Presenter presenter;
private LinkedList<Line> set;
private HashMap<Line, ArrayList<Line>> linePairs;
private HashMap<Line, Double> medianIntersections = new HashMap<>();
private HashMap<Line, ArrayList<Double>> intersectionAbscissas = new HashMap<>();
private Interval interval;
//in der Literatur als L_i, C_i, und R_i bekannt
private ArrayList<Double> countLeftSlab;
private ArrayList<Double> countCenterSlab;
private ArrayList<Double> countRightSlab;
//die Mengen L,C und R
private ArrayList<Line> linesInLeftSlab;
private ArrayList<Line> linesInCenterSlab;
private ArrayList<Line> linesInRightSlab;
private Double r;
private Integer n;
private Double k;
private Double kLow;
private Double kHigh;
private Double beta;
private Double thetaLow;
private Double thetaHigh;
private Double slope;
private Double yInterception;
public RepeatedMedianEstimator(LinkedList<Line> set, Presenter presenter) {
this.set = set;
this.presenter = presenter;
interval = new Interval(-10000, 10000);
n = set.size();
beta = 0.5;
countLeftSlab = new ArrayList<>();
countCenterSlab = new ArrayList<>();
countRightSlab = new ArrayList<>();
for (int i = 0; i < n; i++) {
countLeftSlab.add(0d);
countRightSlab.add(0d);
countCenterSlab.add(n - 1.0);
intersectionAbscissas.put(set.get(i), new ArrayList<>());
}
linesInLeftSlab = new ArrayList<>();
linesInCenterSlab = new ArrayList<>(set);
linesInRightSlab = new ArrayList<>();
linePairs = new HashMap<>();
}
public RepeatedMedianEstimator(LinkedList<Line> set) {
this(set,null);
}
/**
*
*/
public void run() {
while (linesInCenterSlab.size() != 1) {
n = linesInCenterSlab.size();
r = Math.ceil(Math.pow(n, beta));
ArrayList<Line> lines = RandomSampler.run(linesInCenterSlab, r, linesInCenterSlab.size());
//For each Sampled Line, compute its median intersection abscissa
ArrayList<Double> medianIntersectionAbscissas = new ArrayList<>();
for (Line l : lines) {
Double abscissa = estimateMedianIntersectionAbscissas(l);
medianIntersections.put(l, abscissa);
medianIntersectionAbscissas.add(abscissa);
}
//rank of the repeated median in C
k = Math.max(1,Math.min(set.size(),(Math.ceil(n * 0.5) - linesInLeftSlab.size())));
//compute k_lo and k_hi
computeSlabBorders();
// if (medianIntersectionAbscissas.size() < kLow || medianIntersectionAbscissas.size()<kHigh || kLow < 0 || kHigh<0 )
// System.err.print("#medianIntersectionAbscissa: "+medianIntersectionAbscissas.size()+"\t\t klow: "+kLow+" kHigh: "+kHigh+"\n\n");
//Employ fast selection algorithm to determine the Elements Theta_lo and Theta_hi
thetaLow = FastElementSelector.randomizedSelect(medianIntersectionAbscissas, kLow);
thetaHigh = FastElementSelector.randomizedSelect(medianIntersectionAbscissas, kHigh);
//For each dual Line in C count the number of intersection abscissas that lie
//in each of the intervals.
countNumberOfIntersectionsAbscissas();
//Based on this 3 counts, determine which of the subintervals contains the repeated median
//and contract to this subiinterval.
contractIntervals();
}
}
/**
*
* @param set
* @param r
* @return
*/
public ArrayList<Line> sampleLines(ArrayList<Line> set, Double r) {
ArrayList<Line> sampledLines = new ArrayList<>();
for (int i = 0; i < r; i++) {
sampledLines.add(set.get(ThreadLocalRandom.current().nextInt(0, linesInCenterSlab.size())));
}
return sampledLines;
}
/**
*
* @param sampledLine
* @return
*/
public Double estimateMedianIntersectionAbscissas(Line sampledLine) {
Integer index = Integer.parseInt(sampledLine.getId());
ArrayList<Double> intersections = new ArrayList<>();
double intersection;
IntersectionCounter intersectionCounter = new IntersectionCounter();
intersections = intersectionCounter.calculateIntersectionAbscissas(linesInCenterSlab, sampledLine);
//Collections.sort(intersections);
//double ki = Math.ceil((n - 1) / 2) - countLeftSlab.get(index);
//double i = (Math.ceil((Math.sqrt(n) * ki) / countCenterSlab.get(index)));
double ki = Math.ceil((n - 1) / 2) - FastElementSelector.randomizedSelect(countLeftSlab, index);
double i = (Math.ceil((Math.sqrt(n) * ki) / FastElementSelector.randomizedSelect(countCenterSlab, index)));
int accessIndex;
if (i < 0)
accessIndex = 0;
else if (i >= intersections.size())
accessIndex = intersections.size()-1;
else
accessIndex = (int) i;
//System.out.println(accessIndex);
//return intersections.get(accessIndex);
return FastElementSelector.randomizedSelect(intersections, accessIndex);
}
/**
*
*/
public void computeSlabBorders() {
kLow = Math
.max(1, Math.floor(
( (r * k) / (linesInCenterSlab.size()))
- ( (3 * Math.sqrt(r)) / (2))
)
);
kHigh = Math
.min(r, Math.floor(
((r * k) / (linesInCenterSlab.size()))
+ ((3 * Math.sqrt(r)) / (2))
)
);
}
/**
*
*/
public void countNumberOfIntersectionsAbscissas() {
for (Line line : linesInCenterSlab) {
ArrayList<Double> intersections = intersectionAbscissas.get(line);
Integer index = Integer.parseInt(line.getId());
int left = 0;
int center = 0;
int right = 0;
for (Double intersection : intersections) {
if (intersection <= thetaLow) {
left++;
} else if (intersection > thetaLow && intersection <= thetaHigh) {
center++;
} else if (intersection > thetaHigh){
right++;
}
}
//System.out.println("Linie: "+line.getId()+"\tLeft: "+left+"\t Center: "+center+"\t Right: "+right);
countLeftSlab.set(index, (double) left);
countCenterSlab.set(index, (double) center);
countRightSlab.set(index, (double) right);
}
}
/**
*
*/
public void contractIntervals() {
for (int i = 0; i < linesInCenterSlab.size(); i++) {
double left = countLeftSlab.get(i);
double center = countCenterSlab.get(i);
double right = countRightSlab.get(i);
double max = Math.max(left, Math.max(center, right));
if (left == max){
linesInLeftSlab.add(linesInCenterSlab.get(i));
linesInCenterSlab.remove(i);
} else if (right == max) {
linesInRightSlab.add(linesInCenterSlab.get(i));
linesInCenterSlab.remove(i);
}
// if (medianIntersections.get(linesInCenterSlab.get(i)) != null) {
// if (medianIntersections.get(linesInCenterSlab.get(i)) <= thetaLow) {
// linesInLeftSlab.add(linesInCenterSlab.get(i));
// linesInCenterSlab.remove(i);
// countLeftSlab.set(i, countLeftSlab.get(i) + 1);
// countCenterSlab.set(i, countCenterSlab.get(i) - 1);
// } else if (medianIntersections.get(linesInCenterSlab.get(i)) > thetaHigh) {
// linesInRightSlab.add(linesInCenterSlab.get(i));
// linesInCenterSlab.remove(i);
// countRightSlab.set(i, countRightSlab.get(i) + 1);
// countCenterSlab.set(i, countCenterSlab.get(i) - 1);
// }
// }
// }
//
}
//wähle C als C
if (linesInLeftSlab.size() < Math.ceil(n/2) && Math.ceil(n/2) <= linesInLeftSlab.size()+linesInCenterSlab.size()){
interval.setLower(thetaLow + 0.1);
interval.setUpper(thetaHigh);
}
// wähle L als C
else if (Math.ceil(n/2) <= linesInLeftSlab.size()){
interval.setUpper(thetaLow);
}
//wähle R als C
else if (linesInLeftSlab.size()+linesInCenterSlab.size() < Math.ceil(n/2) && Math.ceil(n/2) <= (linesInLeftSlab.size()+linesInCenterSlab.size()+linesInRightSlab.size()) ){
interval.setLower(thetaHigh - 0.1);
}
}
@Override
public void getResult() {
if (presenter != null) {
setChanged();
double m = thetaLow;
double b = (-1)*(
(linesInCenterSlab.get(0).getM() * (thetaLow)) + linesInCenterSlab.get(0)
.getB());
slope = m;
yInterception = b;
String[] result = new String[]{"rm", m+"", b+""};
notifyObservers(result);
}else {
double m = thetaLow;
double b = (-1)*((linesInCenterSlab.get(0).getM() * (thetaLow)) + linesInCenterSlab.get(0).getB());
slope = m;
yInterception = b;
}
}
/*******************************************************************************************************************
* Getter und Setter Methoden
******************************************************************************************************************/
public LinkedList<Line> getSet() {
return set;
}
public void setSet(LinkedList<Line> set) {
this.set = set;
}
public HashMap<Line, ArrayList<Line>> getLinePairs() {
return linePairs;
}
public void setLinePairs(HashMap<Line, ArrayList<Line>> linePairs) {
this.linePairs = linePairs;
}
public HashMap<Line, Double> getMedianIntersections() {
return medianIntersections;
}
public void setMedianIntersections(HashMap<Line, Double> medianIntersections) {
this.medianIntersections = medianIntersections;
}
public HashMap<Line, ArrayList<Double>> getIntersectionAbscissas() {
return intersectionAbscissas;
}
public void setIntersectionAbscissas(
HashMap<Line, ArrayList<Double>> intersectionAbscissas) {
this.intersectionAbscissas = intersectionAbscissas;
}
public Interval getInterval() {
return interval;
}
public void setInterval(Interval interval) {
this.interval = interval;
}
public ArrayList<Double> getCountLeftSlab() {
return countLeftSlab;
}
public void setCountLeftSlab(ArrayList<Double> countLeftSlab) {
this.countLeftSlab = countLeftSlab;
}
public ArrayList<Double> getCountCenterSlab() {
return countCenterSlab;
}
public void setCountCenterSlab(ArrayList<Double> countCenterSlab) {
this.countCenterSlab = countCenterSlab;
}
public ArrayList<Double> getCountRightSlab() {
return countRightSlab;
}
public void setCountRightSlab(ArrayList<Double> countRightSlab) {
this.countRightSlab = countRightSlab;
}
public ArrayList<Line> getLinesInLeftSlab() {
return linesInLeftSlab;
}
public void setLinesInLeftSlab(ArrayList<Line> linesInLeftSlab) {
this.linesInLeftSlab = linesInLeftSlab;
}
public ArrayList<Line> getLinesInCenterSlab() {
return linesInCenterSlab;
}
public void setLinesInCenterSlab(ArrayList<Line> linesInCenterSlab) {
this.linesInCenterSlab = linesInCenterSlab;
}
public ArrayList<Line> getLinesInRightSlab() {
return linesInRightSlab;
}
public void setLinesInRightSlab(ArrayList<Line> linesInRightSlab) {
this.linesInRightSlab = linesInRightSlab;
}
public Double getR() {
return r;
}
public void setR(Double r) {
this.r = r;
}
public Integer getN() {
return n;
}
public void setN(Integer n) {
this.n = n;
}
public Double getK() {
return k;
}
public void setK(Double k) {
this.k = k;
}
public Double getkLow() {
return kLow;
}
public void setkLow(Double kLow) {
this.kLow = kLow;
}
public Double getkHigh() {
return kHigh;
}
public void setkHigh(Double kHigh) {
this.kHigh = kHigh;
}
public Double getBeta() {
return beta;
}
public void setBeta(Double beta) {
this.beta = beta;
}
public Double getThetaLow() {
return thetaLow;
}
public void setThetaLow(Double thetaLow) {
this.thetaLow = thetaLow;
}
public Double getThetaHigh() {
return thetaHigh;
}
public void setThetaHigh(Double thetaHigh) {
this.thetaHigh = thetaHigh;
}
public Double getSlope() {
return slope;
}
public Double getyInterception() {
return yInterception;
}
}

View File

@ -1,82 +0,0 @@
package Presenter.Evaluation;
import Model.Line;
import Presenter.Algorithms.FastElementSelector;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 07.09.2017.
*/
public class PercentageErrorBasedMeasure {
private ArrayList<Double> percentageError;
public PercentageErrorBasedMeasure(final LinkedList<Line> lines, Double m, Double b){
ArrayList<Double> sampson = new ArrayList<>();
for (Line line : lines) {
Double e = Math.pow(m * line.getM() - line.getB() + b, 2) / (Math.pow(m, 2) + 1);
sampson.add(e);
}
percentageError = new ArrayList<>();
for (int j=0;j<sampson.size();j++){
percentageError.add(100 * sampson.get(j) / lines.get(j).getB());
}
}
/* Percentege Error Approximation Measures */
//verschiedene Eingaben für einen Alg.
public Double mape(){
double error = 0;
for (Double d : percentageError) {
error += Math.abs(d);
}
error /= percentageError.size();
return error;
}
public Double mdape(){
ArrayList<Double> abs = new ArrayList<>();
for (Double d : percentageError){
abs.add(Math.abs(d));
}
return FastElementSelector.randomizedSelect(abs, abs.size() * 0.5);
}
public Double rmspe(){
double error = 0;
for (Double d : percentageError) {
error += Math.pow(d, 2);
}
error /= percentageError.size();
return Math.sqrt(error);
}
public Double rmdspe(){
ArrayList squares = new ArrayList();
for (Double d : percentageError){
squares.add(Math.pow(d,2));
}
return Math.sqrt(FastElementSelector.randomizedSelect(squares, squares.size() * 0.5));
}
}

View File

@ -1,60 +0,0 @@
package Presenter.Evaluation;
import Model.Line;
import Presenter.Algorithms.FastElementSelector;
import java.util.ArrayList;
import java.util.LinkedList;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 07.09.2017.
*/
public class ScaleDependentMeasure {
private ArrayList<Double> errorValues;
public ScaleDependentMeasure(final LinkedList<Line> lines, Double m, Double b){
//Liste mit den Fehler zu jedem Punkt
errorValues = new ArrayList<>();
for (Line line : lines) {
Double e = Math.pow(m * line.getM() - line.getB() + b, 2) / (Math.pow(m, 2) + 1);
errorValues.add(e);
}
}
/* Skalierungs Abhängige Approximationsgüten */
//unterschiedliche Alg.- auf einem Datensatz
public Double mse() {
double error = 0;
for (Double d : errorValues) {
error += Math.pow(d, 2);
}
error /= errorValues.size();
return error;
}
public Double rmse() {
return Math.sqrt(mse());
}
public Double mae() {
double error = 0;
for (Double d : errorValues) {
error += Math.abs(d);
}
error /= errorValues.size();
return error;
}
public Double mdae() {
return FastElementSelector
.randomizedSelect(errorValues, errorValues.size() * 0.5);
}
}

View File

@ -1,71 +0,0 @@
package Presenter.Evaluation;
import Model.Line;
import Presenter.Algorithms.FastElementSelector;
import java.util.ArrayList;
import java.util.LinkedList;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 07.09.2017.
*/
public class ScaledErrorBasedMeasure {
private ArrayList<Double> scaledError;
public ScaledErrorBasedMeasure(final LinkedList<Line> lines, Double m, Double b){
//Liste mit den Fehler zu jedem Punkt
ArrayList<Double> sampson = new ArrayList<>();
Double denum = 0d;
for (int i=2;i<lines.size();i++){
denum += Math.abs(lines.get(i).getM() - lines.get(i-1).getM());
}
denum *= 1/(lines.size() - 1);
for (Line line : lines) {
Double e = Math.pow(m * line.getM() - line.getB() + b, 2) / (Math.pow(m, 2) + 1);
sampson.add(e);
Double val = e / (denum);
scaledError.add(val);
}
}
/* Skalierungs Abhängige Approximationsgüten */
//unterschiedliche Alg.- auf einem Datensatz
public Double mse() {
double error = 0;
for (Double d : scaledError) {
error += Math.pow(d, 2);
}
error /= scaledError.size();
return error;
}
public Double rmse() {
return Math.sqrt(mse());
}
public Double mae() {
double error = 0;
for (Double d : scaledError) {
error += Math.abs(d);
}
error /= scaledError.size();
return error;
}
public Double mdae() {
return FastElementSelector
.randomizedSelect(scaledError, scaledError.size() * 0.5);
}
}

View File

@ -1,77 +0,0 @@
package Presenter.ImportExport;
import Model.LineModel;
import Model.Line;
import Presenter.Presenter;
import com.opencsv.CSVReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;
import java.util.Observable;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 21.06.2017.
*/
public class DataImporter extends Observable{
private File file;
private CSVReader reader;
private LineModel model;
private Presenter presenter;
public DataImporter(File file, Presenter presenter) {
this.model = new LineModel();
this.presenter = presenter;
this.presenter.setModel(this.model);
//System.out.println(this.model.getLines().size()+ " die Anzahl der aktuellen Lines.");
this.file = file;
try {
this.reader = new CSVReader(new FileReader(file));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public void run(){
try {
List<String[]> lines = reader.readAll();
int counter = 0;
String[] result = {"import", lines.size()+"", ""};
//System.out.println("+-------------------------------------------------------------------------------+");
for(String[] nextLine : lines) {
// nextLine[] is an array of values from the line
Double x = Double.parseDouble(nextLine[1]);
Double y = Double.parseDouble(nextLine[2]) * (-1);
Line line = new Line(x,y);
line.setId(counter+"");
this.presenter.getModel().addLine(line);
//System.out.format("|\t\t\t\t\t %-11d \t|\t\t\t\t\t %-11f \t|\t\t\t\t\t %-11f \t\t\t\t\t|\n", id,x,y);
setChanged();
counter++;
result[2] = counter + "";
Thread.sleep(1);
notifyObservers(result);
}
//System.out.println("+-------------------------------------------------------------------------------+");
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

View File

@ -1,98 +0,0 @@
package Presenter.ImportExport;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 08.09.2017.
*/
public class EvalResultLatexExport {
private DefaultTableModel model;
private File file;
public EvalResultLatexExport(DefaultTableModel model, File file ) {
this.model = model;
this.file = file;
}
/**
* e.g. Source: <url>https://en.wikibooks.org/wiki/LaTeX/Tables</url>
* \begin{tabular}{l*{3}{c}}
* Team & P & W & D & L & F & A & Pts \\\hline
* Manchester United & 6 & 4 & 0 & 2 & 10 & 5 & 12 \\
* Celtic & 6 & 3 & 0 & 3 & 8 & 9 & 9 \\
* Benfica & 6 & 2 & 1 & 3 & 7 & 8 & 7 \\
* FC Copenhagen & 6 & 2 & 1 & 3 & 5 & 8 & 7 \\
* \end{tabular}
*
*
* @return
*/
private String createOutputData(){
String split = "&";
StringBuilder doc = new StringBuilder();
doc.append("\\begin{tabular}{l|*{3}{r}}"+"\r\n");
for (int i=0;i<model.getColumnCount();i++){
if (model.getValueAt(0,i).toString() != "" || model.getRowCount() > 5)
doc.append("\\textsc{" + model.getColumnName(i) + "}"+split);
}
doc.deleteCharAt(doc.lastIndexOf(split));
doc.append("\\\\\\hline\\hline"+"\r\n");
for (int i=0;i<model.getRowCount()-1;i++){
for (int j=0;j<model.getColumnCount();j++){
if (model.getValueAt(i,j).toString() != "") {
if (j == 0){
doc.append("\\textbf{"+model.getValueAt(i, j).toString()+ "}" + split);
} else {
Double val = Double.parseDouble((String) model.getValueAt(i, j));
doc.append(String.format("%.3f",val) + split);
}
}
}
if (model.getValueAt(i,0) != "") {
doc.deleteCharAt(doc.lastIndexOf(split));
}
doc.append("\\\\"+"\r\n");
}
doc.append("\\end{tabular}");
return doc.toString();
}
public void writeFile(){
FileWriter fileWriter = null;
BufferedWriter bufferedWriter = null;
try {
fileWriter = new FileWriter(file);
bufferedWriter = new BufferedWriter(fileWriter);
bufferedWriter.write(createOutputData());
SwingUtilities.invokeLater(()->{
JOptionPane.showMessageDialog(null,"Export war Erfolgreich!");
});
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bufferedWriter.close();
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

View File

@ -1,384 +0,0 @@
package Presenter;
import Model.LineModel;
import Model.Interval;
import Model.Line;
import Presenter.Algorithms.IntersectionCounter;
import Presenter.Algorithms.LeastMedianOfSquaresEstimator;
import Presenter.Algorithms.RepeatedMedianEstimator;
import Presenter.Algorithms.TheilSenEstimator;
import Presenter.Evaluation.EvaluateAlgorithms;
import Presenter.Generator.DatasetGenerator;
import Presenter.ImportExport.DataExporter;
import Presenter.ImportExport.DataImporter;
import Presenter.ImportExport.EvalResultLatexExport;
import View.MainFrame;
import javax.swing.*;
import java.io.File;
import java.util.LinkedList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import javax.swing.table.DefaultTableModel;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 28.05.2017.
*/
public class Presenter implements Observer {
private LineModel model;
private MainFrame view;
private EvaluateAlgorithms eval;
/* Threads */
private Thread tsThread;
private Thread rmThread;
private Thread lmsThread;
private Thread importThread;
private Thread exportThread;
private Thread exportResultThread;
private Thread generatorThread;
private Thread evalThread;
public Presenter(LineModel model, MainFrame view) {
this.model = model;
this.view = view;
}
@Override
public void update(Observable o, Object arg) {
String[] result = ((String[]) arg);
if (result[0] == "eval-dataset-generated"){
SwingUtilities.invokeLater(() -> getView().addEvalDataset(eval.getData()));
}
if (result[0] == "eval-d"){
SwingUtilities.invokeLater(() -> getView().appendEvalResult(result,Integer.parseInt(result[1]),false));
}
if (result[0] == "eval-ds"){
SwingUtilities.invokeLater(() -> getView().appendEvalResult(result));
}
if (result[0] == "eval-t"){
SwingUtilities.invokeLater(() -> getView().appendEvalResult(result,Integer.parseInt(result[1]),true));
}
if (result[0] == "lines-res"){
SwingUtilities.invokeLater(() -> getView().drawLineResult(result, Integer.parseInt(result[1])));
}
if (result[0] == "lines-res-mult"){
SwingUtilities.invokeLater(() -> getView().drawLineResults(result));
}
if (result[0] == "lms"){
SwingUtilities.invokeLater(() -> {
getView().visualizeLMS(Double.parseDouble(result[1]), Double.parseDouble(result[2]));
//getView().setLmsIsComplete(true);
getView().logHeading("Least Median of Squares");
getView().log("<b>m:</b> " + result[1]);
getView().log("<b>b:</b> " + result[2]);
getView().logSuccess("Berechnung wurde Erfolgreich durchgeführt <hr>");
});
}
if (result[0] == "rm"){
SwingUtilities.invokeLater(() -> {
getView().visualizeRM(Double.parseDouble(result[1]), Double.parseDouble(result[2]));
getView().logHeading("Repeated Median Estimator");
getView().log("<b>m:</b> " + result[1]);
getView().log("<b>b:</b> " + result[2]);
getView().logSuccess("Berechnung wurde Erfolgreich durchgeführt <hr>");
});
}
if (result[0] == "ts"){
SwingUtilities.invokeLater(() -> {
getView().visualizeTS(Double.parseDouble(result[1]), Double.parseDouble(result[2]));
getView().logHeading("Theil-Sen Estimator");
getView().log("<b>m:</b> " + result[1]);
getView().log("<b>b:</b> " + result[2]);
getView().logSuccess("Berechnung wurde Erfolgreich durchgeführt <hr>");
});
}
if (result[0] == "import"){
Double max = Double.parseDouble(result[1]);
Double current = Double.parseDouble(result[2]);
Integer progress = (int) (100 * (current/max));
//100% erreicht
if (progress == 100){
SwingUtilities.invokeLater(() -> {
getView().showImportProgress(progress);
getView().enableFunctionality();
getView().getProgressDialog().dispose();
});
setup();
Thread t = new Thread(() -> {
calculateIntersections();
});
t.start();
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
SwingUtilities.invokeLater(() -> {
getView().showImportProgress(progress);
});
}
}
if (result[0] == "export"){
SwingUtilities.invokeLater(() -> {
getView().logSuccess("Export Erfolgreich");
getView().log(result[1]+"<hr>");
});
}
if (result[0] == "generator"){
SwingUtilities.invokeLater(() -> {
getView().logSuccess("Generierung Erfolgreich");
getView().log(result[1]);
getView().log(result[2]);
getView().log(result[3] + "<hr>");
});
}
}
public void visualizeDualLines() {
view.createDualityDialog();
}
/***************************************************************************************************************************
* Ausführung der Algorithmen
***************************************************************************************************************************/
public void calculateLMS(String[] input) {
if (input[0] != null && input[1] != null){
if (lmsThread == null || !lmsThread.isAlive()){
lmsThread = new Thread(() -> {
Double constant = Double.parseDouble(input[0]);
Double error = Double.parseDouble(input[1]);
LeastMedianOfSquaresEstimator lms = new LeastMedianOfSquaresEstimator(getModel().getLines(), getModel().getNodes(), this);
lms.setConstant(constant);
lms.setQuantileError(error);
lms.addObserver(this);
lms.run();
lms.getResult();
});
lmsThread.start();
try {
lmsThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void calculateRM(String input){
if (input != null){
if (rmThread == null || !rmThread.isAlive()){
rmThread = new Thread(() -> {
RepeatedMedianEstimator rm = new RepeatedMedianEstimator(getModel().getLines(), this);
Double parameter = Double.parseDouble(input);
rm.setBeta(parameter);
rm.addObserver(this);
rm.run();
rm.getResult();
});
rmThread.start();
try {
rmThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void calculateTS(String input){
if (input != null){
if (tsThread == null || !tsThread.isAlive()){
tsThread = new Thread(() ->{
TheilSenEstimator ts = new TheilSenEstimator(getModel().getLines(), getModel().getNodes(),this);
ts.addObserver(this);
ts.run();
ts.getResult();
});
tsThread.start();
try {
tsThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/***************************************************************************************************************************
* Hilfsmethoden
***************************************************************************************************************************/
public void setup(){
//Darstellung der Schnittpunkte in einer Tabelle
List<String> heading = new LinkedList<>();
List<List<String>> rows = new LinkedList<>();
heading.add("Geraden");
for (int j = 0; j < getModel().getLines().size()-2; j++) {
LinkedList<String> rowEntry = new LinkedList<>();
Line p1 = getModel().getLines().get(j);
rowEntry.add("f(x) = " + p1.getM() + "x + " + p1.getB());
if (j+1 < getModel().getLines().size()){
Line p2 = getModel().getLines().get(j+1);
rowEntry.add("f(x) = " + p2.getM() + "x + " + p2.getB());
}
if (j+2 < getModel().getLines().size()){
Line p3 = getModel().getLines().get(j+2);
rowEntry.add("f(x) = " + p3.getM() + "x + " + p3.getB());
}
rows.add(rowEntry);
}
getView().logHeading("Schnittpunkte der Dualen Geraden:");
getView().createTable(heading, rows);
getView().log("<hr>");
}
public void calculateIntersections() {
try {
Thread thread = new Thread(() -> {
IntersectionCounter counter = new IntersectionCounter();
counter.run(getLines(), new Interval(-99999,99999));
counter.calculateIntersectionAbscissas(getModel());
getModel().setXbounds();
getModel().setYbounds();
});
thread.start();
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void startImport(File file){
if (importThread == null || !importThread.isAlive()){
importThread = new Thread(()->{
DataImporter importer = new DataImporter(file, this);
importer.addObserver(this);
importer.run();
});
importThread.start();
try {
importThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void startExport(File file){
if (exportThread == null || !exportThread.isAlive()){
exportThread = new Thread(()->{
DataExporter exporter = new DataExporter(getModel(), file);
exporter.addObserver(this);
exporter.export();
});
exportThread.start();
try {
exportThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void startResultExport(DefaultTableModel model, File file){
if (exportResultThread == null || !exportResultThread.isAlive()){
exportResultThread = new Thread(()->{
EvalResultLatexExport exporter = new EvalResultLatexExport(model, file);
exporter.writeFile();
});
exportResultThread.start();
try {
exportResultThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void generateDataset(){
if (generatorThread == null || !generatorThread.isAlive()){
generatorThread = new Thread(() -> {
DatasetGenerator generator = new DatasetGenerator();
generator.addObserver(this);
getModel().setLines(generator.generateCircle(100));
calculateIntersections();
getView().enableFunctionality();
});
generatorThread.start();
try {
generatorThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void startEvaluation(int typ, int n, int alg, String datasettyp){
if (evalThread == null || !evalThread.isAlive()){
evalThread = new Thread(() ->{
try {
eval = new EvaluateAlgorithms(typ,n,alg,datasettyp);
eval.addObserver(this);
eval.run();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
evalThread.start();
}
}
/***************************************************************************************************************************
* Getter und Setter Methoden
***************************************************************************************************************************/
public LineModel getModel() {
return model;
}
public void setModel(LineModel model) {
this.model = model;
}
public MainFrame getView() {
return view;
}
public void setView(MainFrame view) {
this.view = view;
}
public LinkedList<Line> getLines() {
return this.model.getLines();
}
public void setLines(LinkedList<Line> lines) {
this.model.setLines(lines);
}
}

View File

@ -1,232 +0,0 @@
package View;
import Model.Line;
import Model.Point;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.time.DateRange;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.util.ShapeUtilities;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.util.LinkedList;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 28.05.2017.
*/
public class DualityDialog extends JPanel {
private LinkedList<Line> lines;
private LinkedList<Point> points;
private JFreeChart chart;
private ChartPanel panel;
private XYSeriesCollection dataset;
private JScrollPane scrollPane;
private double domainMin, domainMax;
private double rangeMin, rangeMax;
private ValueAxis domain;
private ValueAxis range;
private Double delta = 1d;
private Boolean ctrlPressed = false;
private Boolean shiftPressed = false;
public DualityDialog() {
super();
this.setPreferredSize(new Dimension(800, 800));
this.setMinimumSize(new Dimension(800, 800));
this.setLayout(new BorderLayout());
}
public void setPrameters(LinkedList<Line> lines, LinkedList<Point> points, Double xmin, Double xmax, Double ymin, Double ymax) {
this.lines = new LinkedList<>(lines);
this.points = new LinkedList<>(points);
this.domainMin = xmin;
this.domainMax = xmax;
this.rangeMin = ymin;
this.rangeMax = ymax;
}
public void createArrangement() {
dataset = new XYSeriesCollection();
for (Line p : lines) {
XYSeries series = new XYSeries(p.getId()+"#"+p.getX1()+"---"+p.getY1());
series.add(p.getX1(), p.getY1());
series.add(p.getX2(), p.getY2());
dataset.addSeries(series);
}
XYSeries intersections = new XYSeries("intersections");
for (Point p : points) {
intersections.add(p.getX(), p.getY());
}
dataset.addSeries(intersections);
chart = ChartFactory.createXYLineChart(null, null, null, dataset,
PlotOrientation.HORIZONTAL, false, false, false);
chart.setRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON));
chart.setAntiAlias(true);
final XYPlot plot = chart.getXYPlot();
domain = plot.getDomainAxis();
range = plot.getRangeAxis();
domain.setRange(domainMin - 1, domainMax + 1);
range.setRange(rangeMin - 1, rangeMax + 1);
plot.setBackgroundPaint(Color.WHITE);
plot.setDomainGridlinePaint(Color.white);
plot.setRangeGridlinePaint(Color.white);
final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
renderer.setSeriesLinesVisible(dataset.indexOf(intersections), false);
plot.setRenderer(renderer);
for (int i = 0; i < lines.size(); i++) {
// Setze die Shapes für die Schnittpunkte
renderer.setSeriesPaint(i, Color.BLUE);
renderer.setBaseSeriesVisible(true);
}
Shape shape = ShapeUtilities.createDiagonalCross(4, 1);
renderer.setSeriesPaint(lines.size(), Color.BLACK);
renderer.setSeriesShape(lines.size(), shape);
panel = new ChartPanel(chart);
panel.setPreferredSize(new Dimension(800, 800));
addKeyListener(this);
addZooming(panel);
this.setFocusable(true);
JTextArea info = new JTextArea();
info.setText("Um in dem Plot hineinzuzoomen kann das Mausrad verwendett werden. \nUm sich anschließen vertikal bzw. horizontal zu bewegen kann die Kombination (Umschalt/Steuerung)\nund Mausrad verwendett werden.");
Font font = new Font("Serif", Font.ITALIC, 12);
info.setFont(font);
info.setForeground(Color.DARK_GRAY);
info.setEditable(false);
info.setWrapStyleWord(true);
this.add(info, BorderLayout.SOUTH);
this.add(panel, BorderLayout.CENTER);
}
public void addKeyListener(JComponent component){
component.addKeyListener(new KeyListener() {
@Override
public void keyReleased(KeyEvent e) {
ctrlPressed = false;
shiftPressed = false;
}
@Override
public void keyTyped(KeyEvent e) {}
@Override
public void keyPressed(KeyEvent e) {
if (e.isControlDown()){
ctrlPressed = true;
}
if (e.isShiftDown()){
shiftPressed = true;
}
}
});
}
protected void addZooming(ChartPanel chartPanel) {
chartPanel.addMouseWheelListener(new MouseWheelListener() {
public void mouseWheelMoved(MouseWheelEvent e) {
Double min;
Double max;
Double val = e.getPreciseWheelRotation() * -1;
if(ctrlPressed == true){
//System.out.println("CTRL + ZOOM");
min = range.getLowerBound();
max = range.getUpperBound();
DateRange dateRangeX = move(val, min, max);
range.setRange(dateRangeX);
} else if (shiftPressed == true){
//System.out.println("SHIFT + ZOOM");
min = domain.getLowerBound();
max = domain.getUpperBound();
DateRange dateRangeY = move(val, min, max);
domain.setRange(dateRangeY);
} else {
Double x = Double.valueOf(e.getY());
Double y = Double.valueOf(e.getY());
if (e.getScrollType() != MouseWheelEvent.WHEEL_UNIT_SCROLL)
return;
if (e.getWheelRotation() < 0)
increaseZoom((ChartPanel) e.getComponent(), true, x, y);
else
decreaseZoom((ChartPanel) e.getComponent(), true, x, y);
}
}
private DateRange move(Double val, Double min, Double max){
Double minimum = min;
Double maximum = max;
delta = Math.abs(maximum - minimum) * 0.01 * val;
minimum = minimum + delta;
maximum = maximum + delta;
return new DateRange(minimum,maximum);
}
public synchronized void increaseZoom(JComponent chart, boolean saveAction, Double x, Double y) {
ChartPanel ch = (ChartPanel) chart;
zoomChartAxis(ch, true, x, y);
}
public synchronized void decreaseZoom(JComponent chart, boolean saveAction, Double x, Double y) {
ChartPanel ch = (ChartPanel) chart;
zoomChartAxis(ch, false, x, y);
}
private void zoomChartAxis(ChartPanel chartP, boolean increase, Double x, Double y) {
int width = chartP.getMaximumDrawWidth() - chartP.getMinimumDrawWidth();
int height = chartP.getMaximumDrawHeight() - chartP.getMinimumDrawWidth();
if (increase) {
chartP.zoomInBoth(width / 2, height / 2);
} else {
chartP.zoomOutBoth(width / 2, height / 2);
}
}
});
}
public void clear(){
if (dataset != null)
dataset.removeAllSeries();
}
}

View File

@ -1,604 +0,0 @@
package View;
import Model.Line;
import Presenter.Presenter;
import View.Panels.*;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.LinkedList;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 28.05.2017.
*/
public class MainFrame extends JFrame {
private Presenter presenter;
private Boolean lmsIsComplete = false;
private Boolean rmIsComplete = false;
private Boolean tsIsComplete = false;
private JButton arrangementButton;
private JButton importButton;
private JButton generateButton;
private JButton exportButton;
private OutputPanel output;
private MenuPanel menupanel;
private LMSPanel lmsPanel;
private RMPanel rmPanel;
private TSPanel tsPanel;
private JPanel pane;
private JPanel northPanel;
private DualityDialog arrangement;
private JDialog arrangementDialog;
private PlotDialog plotLMS;
private PlotDialog plotRM;
private PlotDialog plotTS;
private JDialog progressDialog;
private JDialog evaluationDialog;
private Container progressContent;
private JProgressBar progressBar;
private JSplitPane splitpane;
private JScrollPane scrollPane;
private JTabbedPane tabbedPane;
private EvaluationPanel evaluationPanel;
public MainFrame() {
initializeComponents();
setDimensions();
setLayouts();
setTitles();
addComponents();
setCloseOperations();
setActionListeners();
setIcons();
disableFunctionality();
this.setVisible(true);
}
/*******************************************************************************************************************
* visualisierungs methoden
******************************************************************************************************************/
public void createDualityDialog() {
arrangement = new DualityDialog();
arrangementDialog = new JDialog();
arrangementDialog.setTitle("Dual Representation - Dialog");
arrangementDialog.setSize(new Dimension(800, 800));
arrangementDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
arrangement.clear();
arrangement.setPrameters(getPresenter().getLines(),
getPresenter().getModel().getNodes(),
getPresenter().getModel().getxMinimum(),
getPresenter().getModel().getxMaximum(),
getPresenter().getModel().getyMinimum(),
getPresenter().getModel().getyMaximum());
arrangement.createArrangement();
SwingUtilities.invokeLater(() -> {
arrangementDialog.add(arrangement);
arrangementDialog.revalidate();
arrangementDialog.repaint();
arrangementDialog.setVisible(true);
});
}
public void visualizeLMS(double m, double b) {
plotLMS = new PlotDialog();
lmsPanel.setPlotDialog(plotLMS);
createPlot(m,b,plotLMS,lmsPanel, "LMS");
}
public void visualizeRM(double m, double b) {
plotRM = new PlotDialog();
rmPanel.setPlotDialog(plotRM);
createPlot(m,b,plotRM,rmPanel, "RM");
}
public void visualizeTS(double m, double b){
plotTS = new PlotDialog();
tsPanel.setPlotDialog(plotTS);
createPlot(m,b,plotTS, tsPanel, "TS");
}
public void createPlot(double m, double b, PlotDialog plot, JPanel panel, String name){
SwingUtilities.invokeLater(() -> {
plot.clear();
plot.createPlot(getPresenter().getLines());
plot.addLineToPlot(m, b, name);
panel.revalidate();
});
}
public void showImportProgress(Integer progress){
progressBar.setValue(progress);
progressBar.setStringPainted(true);
progressDialog.setVisible(true);
}
public void showEvauluationDialog(){
if (evaluationDialog == null){
SwingUtilities.invokeLater(() -> {
evaluationDialog = new JDialog();
evaluationDialog.setTitle("Evaluation");
evaluationDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
evaluationDialog.setSize(1800,800);
evaluationDialog.setLocationRelativeTo(null);
evaluationPanel = new EvaluationPanel(this);
evaluationDialog.add(evaluationPanel);
evaluationDialog.setVisible(true);
});
} else {
SwingUtilities.invokeLater(()->{
evaluationDialog.setVisible(true);
});
}
}
public void appendEvalResult(Object[] res,int col, boolean isApprCol){
SwingUtilities.invokeLater(() -> {
Object[] tmp = Arrays.asList(res).subList(2,res.length).toArray();
if (isApprCol){
evaluationPanel.setCurrentRow(tmp.length);
evaluationPanel.addColumn(tmp, col,true);
} else {
evaluationPanel.addColumn(tmp, col+1, false);
}
evaluationPanel.repaint();
evaluationPanel.revalidate();
});
}
public void appendEvalResult(Object[] res){
SwingUtilities.invokeLater(() -> {
Object[] tmp = Arrays.asList(res).subList(1,res.length).toArray();
evaluationPanel.addRow(tmp);
evaluationPanel.repaint();
evaluationPanel.revalidate();
});
}
public void drawLineResult(Object[] res, int alg){
SwingUtilities.invokeLater(() -> {
Object[] result = Arrays.asList(res).subList(2,res.length).toArray();
evaluationPanel.drawLines(result, alg);
evaluationPanel.repaint();
evaluationPanel.revalidate();
});
}
public void drawLineResults(Object[] res){
SwingUtilities.invokeLater(() -> {
Object[] result = Arrays.asList(res).subList(1,res.length).toArray();
ArrayList<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();
});
}
public void addEvalDataset(LinkedList<Line> lines){
SwingUtilities.invokeLater(() -> {
evaluationPanel.setDualPoints(lines);
evaluationPanel.repaint();
evaluationPanel.revalidate();
});
}
/*******************************************************************************************************************
* init GUI
******************************************************************************************************************/
private void setTitles() {
this.setTitle("Algorithmen zur Berechnung von Ausgleichgeraden");
importButton.setText("Import");
exportButton.setText("Export");
generateButton.setText("Generiere");
arrangementButton.setText("Dualraum");
}
private void setupTabbedPane() {
tabbedPane.add("Least Median of Squares", lmsPanel);
tabbedPane.add("Repeated Median", rmPanel);
tabbedPane.add("Theil-Sen", tsPanel);
}
private void addComponents() {
pane.add(arrangementButton);
pane.add(importButton);
pane.add(exportButton);
pane.add(generateButton);
northPanel.add(menupanel);
northPanel.add(pane);
setupSplitPane();
setupTabbedPane();
progressContent.add(progressBar, BorderLayout.NORTH);
progressBar.setBorder(BorderFactory.createTitledBorder("Import..."));
this.add(northPanel, BorderLayout.NORTH);
this.add(splitpane, BorderLayout.CENTER);
}
private void setupSplitPane() {
splitpane.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
splitpane.setResizeWeight(.5d);
splitpane.setContinuousLayout(true);
splitpane.setLeftComponent(output);
splitpane.setRightComponent(tabbedPane);
}
private void setCloseOperations() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
progressDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
}
private void setDimensions() {
this.setExtendedState(JFrame.MAXIMIZED_BOTH);
this.setResizable(false);
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
this.setMaximizedBounds(env.getMaximumWindowBounds());
lmsPanel.setMinimumSize(new Dimension(400, 500));
rmPanel.setMinimumSize(new Dimension(400, 500));
tsPanel.setMinimumSize(new Dimension(400, 500));
output.setMinimumSize(new Dimension(400, 500));
progressDialog.setSize(300, 80);
progressDialog.setResizable(false);
}
private void setLayouts() {
this.setLayout(new BorderLayout());
pane.setLayout(new FlowLayout(FlowLayout.LEFT));
northPanel.setLayout(new BoxLayout(northPanel, BoxLayout.Y_AXIS));
}
private void initializeComponents() {
//Panels
pane = new JPanel();
lmsPanel = new LMSPanel();
rmPanel = new RMPanel();
tsPanel = new TSPanel();
menupanel = new MenuPanel(this);
northPanel = new JPanel();
//Dialogs
progressDialog = new JDialog();
progressDialog.setLocationRelativeTo(null);
progressContent = progressDialog.getContentPane();
progressBar = new JProgressBar();
//Panes
tabbedPane = new JTabbedPane();
output = new OutputPanel();
splitpane = new JSplitPane();
//Buttons
arrangementButton = new JButton();
importButton = new JButton();
generateButton = new JButton();
exportButton = new JButton();
}
private void setIcons(){
try {
ClassLoader classLoader = getClass().getClassLoader();
Image imgImport = ImageIO.read(classLoader.getResource("import.png")).getScaledInstance(16,16,Image.SCALE_SMOOTH);
Image imgPlot = ImageIO.read(classLoader.getResource("plot.png")).getScaledInstance(16,16,Image.SCALE_SMOOTH);
Image imgStart = ImageIO.read(classLoader.getResource("start.png")).getScaledInstance(32,32,Image.SCALE_SMOOTH);
Image imgGenerate = ImageIO.read(classLoader.getResource("generate.png")).getScaledInstance(16,16,Image.SCALE_SMOOTH);
Image imgExport = ImageIO.read(classLoader.getResource("export.png")).getScaledInstance(16,16,Image.SCALE_SMOOTH);
Image imgFrame = ImageIO.read(classLoader.getResource("frame.png")).getScaledInstance(32,23,Image.SCALE_SMOOTH);
importButton.setIcon(new ImageIcon(imgImport));
exportButton.setIcon(new ImageIcon(imgExport));
generateButton.setIcon(new ImageIcon(imgGenerate));
arrangementButton.setIcon(new ImageIcon(imgPlot));
lmsPanel.getStartButton().setIcon(new ImageIcon(imgStart));
rmPanel.getStartButton().setIcon(new ImageIcon(imgStart));
tsPanel.getStartButton().setIcon(new ImageIcon(imgStart));
this.setIconImage(imgFrame);
} catch (IOException e) {
e.printStackTrace();
}
}
private void setActionListeners() {
arrangementButton.addActionListener((ActionEvent e) -> {
Thread t = new Thread(() -> getPresenter().visualizeDualLines());
t.start();
});
lmsPanel.getStartButton().addActionListener((ActionEvent e) -> {
if (lmsPanel.getInput() != null){
Thread t = new Thread(
() -> this.getPresenter().calculateLMS(lmsPanel.getInput()));
t.start();
}
});
rmPanel.getStartButton().addActionListener((ActionEvent e) -> {
if (rmPanel.getInput() != null){
Thread t = new Thread(
() -> this.getPresenter().calculateRM(rmPanel.getInput()));
t.start();
}
});
tsPanel.getStartButton().addActionListener((ActionEvent e) -> {
Thread t = new Thread(
() -> this.getPresenter().calculateTS(""));
t.start();
});
importButton.addActionListener((ActionEvent e) -> {
SwingUtilities.invokeLater(() -> {
File file = null;
JFileChooser chooser = new JFileChooser();
chooser.setPreferredSize(new Dimension(800,700));
File workingDirectory = new File(System.getProperty("user.dir"));
chooser.setCurrentDirectory(workingDirectory);
chooser.setFileFilter(new FileNameExtensionFilter("Comma-Separated Value", "csv", "text"));
chooser.setMultiSelectionEnabled(false);
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION){
//System.out.println ("Datei "+chooser.getSelectedFile()+ " ausgewählt.");
file = chooser.getSelectedFile();
final File input = file;
Thread t = new Thread(() -> this.getPresenter().startImport(input));
t.start();
}
});
});
exportButton.addActionListener((ActionEvent e) -> {
SwingUtilities.invokeLater(() -> {
File file = null;
JFileChooser chooser = new JFileChooser();
chooser.setPreferredSize(new Dimension(800,700));
File workingDirectory = new File(System.getProperty("user.dir"));
chooser.setCurrentDirectory(workingDirectory);
chooser.setFileFilter(new FileNameExtensionFilter("Comma-Separated Value", "csv", "text"));
chooser.setMultiSelectionEnabled(false);
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
if (chooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION){
//System.out.println ("Datei "+chooser.getSelectedFile()+ " ausgewählt.");
file = chooser.getSelectedFile();
String filename = file.getAbsolutePath().contains(".csv") ? file.getAbsolutePath() : file.getAbsolutePath().concat(".csv");
File withExtension = new File(filename);
final File input = withExtension;
Thread t = new Thread(() -> this.getPresenter().startExport(input));
t.start();
}
});
});
generateButton.addActionListener((ActionEvent e) -> {
SwingUtilities.invokeLater(() -> {
getPresenter().generateDataset();
});
});
}
public void enableFunctionality(){
this.getLmsPanel().getStartButton().setEnabled(true);
this.getRmPanel().getStartButton().setEnabled(true);
this.getTsPanel().getStartButton().setEnabled(true);
this.getArrangementButton().setEnabled(true);
this.getExportButton().setEnabled(true);
}
public void disableFunctionality(){
this.getLmsPanel().getStartButton().setEnabled(false);
this.getRmPanel().getStartButton().setEnabled(false);
this.getTsPanel().getStartButton().setEnabled(false);
this.getArrangementButton().setEnabled(false);
this.getExportButton().setEnabled(false);
}
/*******************************************************************************************************************
* log Methode
******************************************************************************************************************/
public void log(String s) {
SwingUtilities.invokeLater(() -> output.appendParagraph(s));
}
public void logError(String s) {
SwingUtilities.invokeLater(() -> output.appendParagraphRed(s));
}
public void logSuccess(String s) {
SwingUtilities.invokeLater(() -> output.appendParagraphGreen(s));
}
public void logHeading(String s) {
SwingUtilities.invokeLater(() -> output.appendParagraphWithHeading(s));
}
public void createTable(List<String> heading, List<List<String>> rows) {
SwingUtilities.invokeLater(() -> output.logTable(heading, rows));
}
/*******************************************************************************************************************
* Getter und Setter Methoden
******************************************************************************************************************/
public Boolean getLmsIsComplete() {
return lmsIsComplete;
}
public void setLmsIsComplete(Boolean lmsIsComplete) {
this.lmsIsComplete = lmsIsComplete;
}
public Boolean getRmIsComplete() {
return rmIsComplete;
}
public void setRmIsComplete(Boolean rmIsComplete) {
this.rmIsComplete = rmIsComplete;
}
public Boolean getTsIsComplete() {
return tsIsComplete;
}
public void setTsIsComplete(Boolean tsIsComplete) {
this.tsIsComplete = tsIsComplete;
}
public JButton getArrangementButton() {
return arrangementButton;
}
public void setArrangementButton(JButton arrangementButton) {
this.arrangementButton = arrangementButton;
}
public JButton getImportButton() {
return importButton;
}
public void setImportButton(JButton importButton) {
this.importButton = importButton;
}
public JPanel getPane() {
return pane;
}
public void setPane(JPanel pane) {
this.pane = pane;
}
public JDialog getArrangementDialog() {
return arrangementDialog;
}
public void setArrangementDialog(JDialog arrangementDialog) {
this.arrangementDialog = arrangementDialog;
}
public OutputPanel getOutput() {
return output;
}
public void setOutput(OutputPanel output) {
this.output = output;
}
public MenuPanel getMenupanel() {
return menupanel;
}
public LMSPanel getLmsPanel() {
return lmsPanel;
}
public JSplitPane getSplitpane() {
return splitpane;
}
public void setSplitpane(JSplitPane splitpane) {
this.splitpane = splitpane;
}
public JScrollPane getScrollPane() {
return scrollPane;
}
public void setScrollPane(JScrollPane scrollPane) {
this.scrollPane = scrollPane;
}
public RMPanel getRmPanel() {
return rmPanel;
}
public void setRmPanel(RMPanel rmPanel) {
this.rmPanel = rmPanel;
}
public PlotDialog getPlotLMS() {
return plotLMS;
}
public void setPlotLMS(PlotDialog plotLMS) {
this.plotLMS = plotLMS;
}
public Presenter getPresenter() {
return presenter;
}
public void setPresenter(Presenter presenter) {
this.presenter = presenter;
}
public JDialog getProgressDialog() {
return progressDialog;
}
public void setProgressDialog(JDialog progressDialog) {
this.progressDialog = progressDialog;
}
public TSPanel getTsPanel() {
return tsPanel;
}
public void setTsPanel(TSPanel tsPanel) {
this.tsPanel = tsPanel;
}
public JButton getExportButton() {
return exportButton;
}
public void setExportButton(JButton exportButton) {
this.exportButton = exportButton;
}
}

View File

@ -1,153 +0,0 @@
package View.Panels;
import View.PlotDialog;
import com.sun.istack.internal.Nullable;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 02.06.2017.
*/
public class LMSPanel extends JPanel {
private JLabel[] labels;
private JTextField[] input;
private JButton startButton;
private JPanel continer;
private JPanel northPanel;
private JPanel centerPanel;
private PlotDialog plotDialog;
private GridBagConstraints gbc;
public LMSPanel() {
this.labels = new JLabel[2];
this.input = new JTextField[2];
this.setLayout(new BorderLayout());
this.northPanel = new JPanel(new BorderLayout());
this.centerPanel = new JPanel(new BorderLayout());
this.northPanel.setBorder(new TitledBorder("Konfiguration"));
this.centerPanel.setBorder(new TitledBorder("Visualisierung"));
this.continer = new JPanel();
this.continer.setLayout(new GridBagLayout());
this.gbc = new GridBagConstraints();
this.gbc.anchor = GridBagConstraints.NORTH;
this.gbc.fill = GridBagConstraints.HORIZONTAL;
addTextfieldAndInput(0, "Konstante", 0.5);
addTextfieldAndInput(1, "Fehler", 0.05);
this.startButton = new JButton("Start");
this.startButton.setFont(new Font("Verdana",Font.PLAIN, 16));
addButton(2, startButton);
this.northPanel.add(continer, BorderLayout.CENTER);
this.add(northPanel, BorderLayout.NORTH);
this.add(centerPanel, BorderLayout.CENTER);
}
private void addTextfieldAndInput(int row, String name, Double value) {
this.labels[row] = new JLabel(name);
this.labels[row].setFont(new Font("SansSerif", Font.PLAIN, 12));
this.input[row] = new JTextField();
this.input[row].setText("" + value);
gbc.insets = new Insets(0, 5, 0, 0);
gbc.gridx = 0;
gbc.gridy = row;
gbc.weightx = 0.05;
gbc.weighty = 0.05;
continer.add(this.labels[row], gbc);
gbc.gridx = 1;
gbc.gridy = row;
gbc.weightx = 0.9;
gbc.weighty = 0.05;
gbc.insets = new Insets(0, 0, 0, 5);
continer.add(this.input[row], gbc);
}
private void addButton(int row, JButton button) {
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
gbc.insets = new Insets(30, 0, 5, 0);
gbc.gridx = 0;
gbc.gridy = row;
gbc.weightx = 0.05;
gbc.weighty = 0.05;
gbc.gridwidth = 1;
buttonPanel.add(button);
continer.add(buttonPanel, gbc);
}
public JButton getStartButton() {
return startButton;
}
@Nullable
public String[] getInput() {
String[] input = new String[3];
input[0] = this.input[0].getText();
input[1] = this.input[1].getText();
if (isNumeric(input[0]) && isNumeric(input[1])){
return input;
} else {
JOptionPane.showMessageDialog(null, "Bitte geben Sie numerische Werte als Parameter an.","Fehler bei der Eingabe", JOptionPane.ERROR_MESSAGE);
return null;
}
}
public void setInput(JTextField[] input) {
this.input = input;
}
public PlotDialog getPlotDialog() {
return plotDialog;
}
public void setPlotDialog(PlotDialog plotDialog) {
this.plotDialog = plotDialog;
if (this.centerPanel.getComponents().length > 0)
this.centerPanel.remove(0);
this.centerPanel.add(plotDialog, BorderLayout.CENTER);
this.plotDialog.setVisible(true);
this.repaint();
this.revalidate();
}
public boolean isNumeric(String str) {
try{
double d = Double.parseDouble(str);
}
catch(NumberFormatException nfe){
return false;
}
return true;
}
}

View File

@ -1,52 +0,0 @@
package View.Panels;
import View.MainFrame;
import javax.swing.*;
import java.awt.*;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 29.05.2017.
*/
public class MenuPanel extends JPanel {
private MainFrame view;
private JMenuBar menuBar;
private JMenu fileMenu;
private JMenu toolsMenu;
private JMenuItem item;
private JMenuItem evaluate;
public MenuPanel(MainFrame view) {
this.view = view;
this.setLayout(new BorderLayout());
this.menuBar = new JMenuBar();
this.fileMenu = new JMenu("Datei");
this.toolsMenu = new JMenu("Extras");
this.item = new JMenuItem("Exit");
this.item.addActionListener(e -> {
System.exit(0);
});
this.evaluate = new JMenuItem("Evaluation");
this.evaluate.addActionListener(e -> {
view.showEvauluationDialog();
});
fileMenu.add(item);
toolsMenu.add(evaluate);
menuBar.add(fileMenu);
menuBar.add(toolsMenu);
this.add(menuBar, BorderLayout.WEST);
this.add(new JSeparator(SwingConstants.HORIZONTAL), BorderLayout.SOUTH);
}
}

View File

@ -1,93 +0,0 @@
package View.Panels;
import java.awt.BorderLayout;
import java.util.List;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.border.TitledBorder;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 02.06.2017.
*/
public class OutputPanel extends JPanel {
private JTextPane output;
private JScrollPane scrollPane;
private StringBuilder content;
public OutputPanel() {
this.setBorder(new TitledBorder("Ausgabekanal"));
this.setLayout(new BorderLayout());
output = new JTextPane();
output.setEditable(false);
output.setContentType("text/html");
content = new StringBuilder();
scrollPane = new JScrollPane(output);
scrollPane.setWheelScrollingEnabled(true);
this.add(scrollPane, BorderLayout.CENTER);
}
public void appendParagraph(String p) {
content.append("<p>" + p + "</p>");
output.setText(content.toString());
}
public void appendParagraphWithHeading(String h1) {
content.append("<h1>" + h1 + "</h1>");
output.setText(content.toString());
}
public void appendParagraphRed(String p) {
content.append("<p style=\" color:red \"><em><strong>" + p + "</strong></em></p>");
output.setText(content.toString());
}
public void appendParagraphGreen(String p) {
content.append("<p style=\" color:green \"><em><strong>" + p + "</strong></em></p>");
output.setText(content.toString());
}
public void logTable(List<String> heading, List<List<String>> rows) {
content.append("<center>");
content.append("<table style=\" width:80%; border: 1px solid black; \">");
content.append("<tr>");
if (heading.size()>1){
for (String str : heading) {
content.append("<th style=\" border: 1px solid black; \">" + str + "</th>");
}
} else {
content.append("<th style=\" border: 1px solid black;\" colspan=\""+ rows.get(0).size() +"\"; >" + heading.get(0) + "</th>");
}
content.append("</tr>");
for (List<String> row : rows) {
content.append("<tr>");
for (String entry : row) {
content.append("<td style=\" border: 1px solid black; \">" + entry + "</td>");
}
content.append("</tr>");
}
content.append("</table>");
content.append("</center>");
output.setText(content.toString());
}
}

View File

@ -1,141 +0,0 @@
package View.Panels;
import View.PlotDialog;
import com.sun.istack.internal.Nullable;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 21.06.2017.
*/
public class RMPanel extends JPanel {
private JLabel labels;
private JTextField input;
private JButton startButton;
private JPanel continer;
private JPanel northPanel;
private JPanel centerPanel;
private PlotDialog plotDialog;
private GridBagConstraints gbc;
public RMPanel() {
this.labels = new JLabel();
this.input = new JTextField();
this.setLayout(new BorderLayout());
this.northPanel = new JPanel(new BorderLayout());
this.centerPanel = new JPanel(new BorderLayout());
this.northPanel.setBorder(new TitledBorder("Konfiguration"));
this.centerPanel.setBorder(new TitledBorder("Visualisierung"));
this.continer = new JPanel();
this.continer.setLayout(new GridBagLayout());
this.gbc = new GridBagConstraints();
this.gbc.anchor = GridBagConstraints.NORTH;
this.gbc.fill = GridBagConstraints.HORIZONTAL;
addTextfieldAndInput(0, "\u00df (0 < \u00df < 1)", 0.5);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
this.startButton = new JButton("Start");
this.startButton.setFont(new Font("Verdana",Font.PLAIN, 16));
gbc.insets = new Insets(30, 0, 10, 0);
gbc.gridx = 0;
gbc.gridy = 2;
gbc.weightx = 0.05;
gbc.weighty = 0.05;
buttonPanel.add(startButton);
continer.add(buttonPanel, gbc);
this.northPanel.add(continer, BorderLayout.CENTER);
this.add(northPanel, BorderLayout.NORTH);
this.add(centerPanel, BorderLayout.CENTER);
}
private void addTextfieldAndInput(int row, String name, Double value) {
this.labels = new JLabel(name);
this.labels.setFont(new Font("SansSerif", Font.PLAIN, 13));
this.input = new JTextField();
this.input.setText("" + value);
gbc.insets = new Insets(0, 5, 0, 0);
gbc.gridx = 0;
gbc.gridy = row;
gbc.weightx = 0.05;
gbc.weighty = 0.05;
continer.add(this.labels, gbc);
gbc.gridx = 1;
gbc.gridy = row;
gbc.weightx = 0.9;
gbc.weighty = 0.05;
gbc.insets = new Insets(0, 0, 0, 5);
continer.add(this.input, gbc);
}
public JButton getStartButton() {
return startButton;
}
@Nullable
public String getInput() {
String input = "";
input = this.input.getText();
if (isNumeric(input))
return input;
else
JOptionPane.showMessageDialog(null, "Bitte geben Sie numerische Werte als Parameter an.","Fehler bei der Eingabe", JOptionPane.ERROR_MESSAGE);
return null;
}
public void setInput(JTextField input) {
this.input = input;
}
public PlotDialog getPlotDialog() {
return plotDialog;
}
public void setPlotDialog(PlotDialog plotDialog) {
this.plotDialog = plotDialog;
if (this.centerPanel.getComponents().length > 0)
this.centerPanel.remove(0);
this.centerPanel.add(plotDialog, BorderLayout.CENTER);
this.plotDialog.setVisible(true);
this.repaint();
this.revalidate();
}
public boolean isNumeric(String str) {
try{
double d = Double.parseDouble(str);
}
catch(NumberFormatException nfe){
return false;
}
return true;
}
}

View File

@ -1,130 +0,0 @@
package View.Panels;
import View.PlotDialog;
import com.sun.istack.internal.Nullable;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import java.awt.*;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 26.06.2017.
*/
public class TSPanel extends JPanel{
private JLabel labels;
private JTextField input;
private JButton startButton;
private JPanel continer;
private JPanel northPanel;
private JPanel centerPanel;
private PlotDialog plotDialog;
private GridBagConstraints gbc;
public TSPanel() {
this.labels = new JLabel();
this.input = new JTextField();
this.setLayout(new BorderLayout());
this.northPanel = new JPanel(new BorderLayout());
this.centerPanel = new JPanel(new BorderLayout());
this.northPanel.setBorder(new TitledBorder("Konfiguration"));
this.centerPanel.setBorder(new TitledBorder("Visualisierung"));
this.continer = new JPanel();
this.continer.setLayout(new GridBagLayout());
this.gbc = new GridBagConstraints();
this.gbc.anchor = GridBagConstraints.NORTH;
this.gbc.fill = GridBagConstraints.HORIZONTAL;
//addTextfieldAndInput(0, "\u00df (0 < \u00df < 1)", 0.5);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
this.startButton = new JButton("Start");
this.startButton.setFont(new Font("Verdana",Font.PLAIN, 16));
gbc.insets = new Insets(10, 0, 10, 0);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 0.05;
gbc.weighty = 0.05;
buttonPanel.add(startButton);
continer.add(buttonPanel, gbc);
this.northPanel.add(continer, BorderLayout.CENTER);
this.add(northPanel, BorderLayout.NORTH);
this.add(centerPanel, BorderLayout.CENTER);
}
private void addTextfieldAndInput(int row, String name, Double value) {
this.labels = new JLabel(name);
this.labels.setFont(new Font("SansSerif", Font.PLAIN, 13));
this.input = new JTextField();
this.input.setText("" + value);
gbc.insets = new Insets(0, 5, 0, 0);
gbc.gridx = 0;
gbc.gridy = row;
gbc.weightx = 0.05;
gbc.weighty = 0.05;
continer.add(this.labels, gbc);
gbc.gridx = 0;
gbc.gridy = row;
gbc.weightx = 0.9;
gbc.weighty = 0.05;
gbc.insets = new Insets(0, 0, 0, 5);
continer.add(this.input, gbc);
}
public JButton getStartButton() {
return startButton;
}
@Nullable
public String getInput() {
String input = "";
input = this.input.getText();
if (isNumeric(input))
return input;
else
JOptionPane.showMessageDialog(null, "Bitte geben Sie numerische Werte als Parameter an.","Fehler bei der Eingabe", JOptionPane.ERROR_MESSAGE);
return null;
}
public void setInput(JTextField input) {
this.input = input;
}
public PlotDialog getPlotDialog() {
return plotDialog;
}
public void setPlotDialog(PlotDialog plotDialog) {
this.plotDialog = plotDialog;
if (this.centerPanel.getComponents().length > 0)
this.centerPanel.remove(0);
this.centerPanel.add(plotDialog, BorderLayout.CENTER);
this.plotDialog.setVisible(true);
this.repaint();
this.revalidate();
}
public boolean isNumeric(String str) {
try{
double d = Double.parseDouble(str);
}
catch(NumberFormatException nfe){
return false;
}
return true;
}
}

View File

@ -1,144 +0,0 @@
package View;
import Model.Line;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.util.ShapeUtilities;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 29.05.2017.
*/
public class PlotDialog extends JPanel {
private JFreeChart chart;
private ChartPanel panel;
private XYSeriesCollection datapoints;
private XYSeries series;
private Double min;
private Double max;
private XYPlot xyPlot;
private int seriesCount;
private XYLineAndShapeRenderer renderer;
private Shape diamond;
public PlotDialog() {
super();
// this.setPreferredSize(new Dimension(1000, 1000));
// this.setMinimumSize(new Dimension(1000, 800));
this.setLayout(new BorderLayout());
seriesCount = 1;
}
public void createPlot(LinkedList<Line> points) {
if (!points.isEmpty()) {
try {
Thread thread = new Thread(() -> convertData(points));
thread.start();
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//createScatterPlot
chart = ChartFactory.createXYLineChart("",
"X", "Y", datapoints, PlotOrientation.VERTICAL, true, true, false);
diamond = ShapeUtilities.createDiamond(2f);
chart.setBorderVisible(false);
chart.setAntiAlias(true);
chart.getPlot().setBackgroundPaint(Color.WHITE);
chart.setBorderVisible(false);
xyPlot = (XYPlot) chart.getPlot();
xyPlot.setDomainCrosshairVisible(true);
xyPlot.setRangeCrosshairVisible(true);
renderer = (XYLineAndShapeRenderer) xyPlot.getRenderer();
renderer.setSeriesLinesVisible(0, false);
renderer.setSeriesShapesVisible(0, true);
renderer.setSeriesLinesVisible(1, true);
renderer.setSeriesLinesVisible(1, true);
renderer.setSeriesPaint(0, Color.blue);
renderer.setSeriesShape(0, diamond);
renderer.setBaseSeriesVisible(true);
xyPlot.setDomainCrosshairVisible(true);
xyPlot.setRangeCrosshairVisible(true);
panel = new ChartPanel(chart);
panel.setMouseZoomable(false);
this.add(panel, BorderLayout.CENTER);
}
public void clear(){
if (datapoints != null)
datapoints.removeAllSeries();
}
public void addLineToPlot(double m, double b, Paint color, String name) {
XYSeries linesA = new XYSeries(name);
linesA.add(min.doubleValue(), min * m + b);
linesA.add(max.doubleValue(), max * m + b);
datapoints.addSeries(linesA);
renderer.setSeriesPaint(seriesCount, color);
renderer.setSeriesStroke(seriesCount, new BasicStroke(2.0f));
renderer.setBaseSeriesVisible(true);
renderer.setSeriesLinesVisible(seriesCount, true);
seriesCount++;
}
public void addLineToPlot(double m, double b, String name) {
XYSeries linesA = new XYSeries(name);
linesA.add(min.intValue(), min.intValue() * m + b);
linesA.add(max.intValue(), max.intValue() * m + b);
datapoints.addSeries(linesA);
seriesCount = xyPlot.getSeriesCount();
renderer.setSeriesPaint(seriesCount, Color.red);
renderer.setSeriesStroke(seriesCount, new BasicStroke(2.0f));
renderer.setBaseSeriesVisible(true);
renderer.setSeriesLinesVisible(seriesCount, true);
}
private void convertData(LinkedList<Line> points) {
datapoints = new XYSeriesCollection();
ArrayList<Double> coordinates = new ArrayList<>();
series = new XYSeries("points");
for (Line p : points) {
series.add(p.getM().doubleValue(), p.getB().doubleValue() * (-1));
coordinates.add(p.getM());
}
this.max = series.getMaxX();
this.min = series.getMinX();
datapoints.addSeries(series);
}
}

View File

@ -1,78 +0,0 @@
package View.custom;
import java.util.HashSet;
import java.util.Set;
import javax.swing.AbstractButton;
import javax.swing.ButtonGroup;
import javax.swing.ButtonModel;
/**
* Source: <url>https://stackoverflow.com/questions/14892515/how-to-enforce-at-least-one-checkbox-in-a-group-is-selected</url>
*
* A ButtonGroup for check-boxes enforcing that at least two remains selected.
*
* When the group has exactly two buttons, deselecting the last selected one
* automatically selects the other.
*
* When the group has more buttons, deselection of the last selected one is denied.
*/
public class ButtonGroupAtLeastOne extends ButtonGroup {
private final Set<ButtonModel> selected = new HashSet<>();
@Override
public void setSelected(ButtonModel model, boolean b) {
if (b && !this.selected.contains(model) ) {
select(model, true);
} else if (!b && this.selected.contains(model)) {
if (this.buttons.size() == 3 && this.selected.size() == 2) {
select(model, false);
AbstractButton otherOne = this.buttons.get(0).getModel() == model ?
this.buttons.get(1) : this.buttons.get(0);
AbstractButton otherTwo = this.buttons.get(1).getModel() == model ?
this.buttons.get(2) : this.buttons.get(1);
AbstractButton otherThree = this.buttons.get(2).getModel() == model ?
this.buttons.get(1) : this.buttons.get(2);
select(otherOne.getModel(), true);
select(otherTwo.getModel(), true);
select(otherThree.getModel(), true);
} else if (this.selected.size() > 2) {
this.selected.remove(model);
model.setSelected(false);
}
}
}
private void select(ButtonModel model, boolean b) {
if (b) {
this.selected.add(model);
} else {
this.selected.remove(model);
}
model.setSelected(b);
}
@Override
public boolean isSelected(ButtonModel m) {
return this.selected.contains(m);
}
public void addAll(AbstractButton... buttons) {
for (AbstractButton button : buttons) {
add(button);
}
}
@Override
public void add(AbstractButton button) {
if (button.isSelected()) {
this.selected.add(button.getModel());
}
super.add(button);
}
}

View File

@ -1,38 +0,0 @@
package View.custom;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
/**
* Source: <url> http://esus.com/creating-a-jtable-with-a-different-background-color-per-column/ </url>
*
* Applied background and foreground color to single column of a JTable
* in order to distinguish it apart from other columns.
*/
public class ColorColumnRenderer extends DefaultTableCellRenderer {
Color bkgndColor, fgndColor;
public ColorColumnRenderer(Color bkgnd, Color foregnd) {
super();
bkgndColor = bkgnd;
fgndColor = foregnd;
}
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
Component cell = super.getTableCellRendererComponent
(table, value, isSelected, hasFocus, row, column);
cell.setBackground(bkgndColor);
cell.setForeground(fgndColor);
cell.setFont(new Font("SansSerif", Font.BOLD, 12));
this.setHorizontalAlignment(JLabel.CENTER);
return cell;
}
}

View File

@ -0,0 +1,154 @@
package model.DCEL;
import model.Point;
import java.util.LinkedList;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 30.05.2017.
*/
public class DoublyConnectedEdgeList {
private LinkedList<Node> nodes;
private LinkedList<Edge> edges;
private LinkedList<Face> faces;
public DoublyConnectedEdgeList() {
this.nodes = new LinkedList<>();
this.edges = new LinkedList<>();
this.faces = new LinkedList<>();
}
public Node createNode(Point point, String id) {
Node node = new Node();
node.setPoint(point);
node.setID(id);
return node;
}
public Edge createEdge(Node source, Node destination, String id) {
Edge edge = new Edge();
Edge twin = new Edge();
edge.setOrigin(source);
edge.setID(id);
edge.setTwin(twin);
twin.setOrigin(destination);
twin.setID("#" + id);
twin.setTwin(edge);
source.setIncidentEdge(edge);
destination.setIncidentEdge(twin);
return edge;
}
public Face createFace(Edge outerComponent, Edge innerComponent, String id) {
Face face = new Face(outerComponent, null);
face.setID(id);
Edge tempEdge;
if (outerComponent != null) {
tempEdge = outerComponent;
do {
tempEdge.setIncidentFace(face);
tempEdge = tempEdge.getNext();
} while (!tempEdge.equals(outerComponent));
}
if (innerComponent != null) {
LinkedList<Edge> componentlist;
componentlist = face.getInnerComponents();
componentlist.add(innerComponent);
tempEdge = innerComponent;
do {
tempEdge.setIncidentFace(face);
tempEdge = tempEdge.getNext();
} while (!tempEdge.equals(innerComponent));
}
return face;
}
public void createConnection(Edge edge, Edge succ) {
edge.setNext(succ);
succ.setPrev(edge);
edge.getTwin().setPrev(succ.getTwin());
succ.getTwin().setNext(edge.getTwin());
}
public LinkedList<Edge> getEdgesOfInnerComponents(Face face) {
LinkedList<Edge> list = new LinkedList();
LinkedList<Edge> innerComponents = face.getInnerComponents();
Edge it;
for (Edge e : innerComponents) {
it = e;
do {
list.add(it);
//System.out.println("Current Edge: "+it.getID()+"\tNext Edge: "+it.getNext().getID());
it = it.getNext();
} while (it != e);
}
return list;
}
public LinkedList<Edge> getEdgesOfOuterComponents(Face face) {
LinkedList<Edge> list = new LinkedList();
Edge it = face.getOuterComponent();
do {
list.add(it);
//System.out.println("Current Edge: "+it.getID()+"\tNext Edge: "+it.getNext().getID());
it = it.getNext();
} while (it != face.getOuterComponent());
return list;
}
public LinkedList<Edge> getConnectedEdges(Node node) {
Edge edge = node.getIncidentEdge();
LinkedList list = new LinkedList();
do {
list.add(edge);
edge = edge.getNext();
} while (node != edge.getOrigin());
return list;
}
public LinkedList<Node> getNodes() {
return nodes;
}
public void setNodes(LinkedList<Node> nodes) {
this.nodes = nodes;
}
public LinkedList<Edge> getEdges() {
return edges;
}
public void setEdges(LinkedList<Edge> edges) {
this.edges = edges;
}
public LinkedList<Face> getFaces() {
return faces;
}
public void setFaces(LinkedList<Face> faces) {
this.faces = faces;
}
}

View File

@ -0,0 +1,117 @@
package model.DCEL;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 30.05.2017.
*/
public class Edge {
private Node origin;
private Edge twin;
private Face incidentFace;
private Edge next;
private Edge prev;
private String id;
public Edge() {
new Edge(null, null, null, null, null);
}
public Edge(Node origin, Edge twin, Edge next, Edge prev, Face incidentFace) {
this.origin = origin;
this.twin = twin;
this.next = next;
this.prev = prev;
this.incidentFace = incidentFace;
}
public Node getOrigin() {
return origin;
}
public void setOrigin(Node origin) {
this.origin = origin;
}
public Edge getTwin() {
return twin;
}
public void setTwin(Edge twin) {
this.twin = twin;
}
public Face getIncidentFace() {
return incidentFace;
}
public void setIncidentFace(Face incidentFace) {
this.incidentFace = incidentFace;
}
public Edge getNext() {
return next;
}
public void setNext(Edge next) {
this.next = next;
}
public Edge getPrev() {
return prev;
}
public void setPrev(Edge prev) {
this.prev = prev;
}
public boolean hasNext() {
if (getNext() == null) {
return false;
} else {
return true;
}
}
public Edge insertNode(Node node) {
Edge edge = new Edge();
Edge twin = new Edge();
edge.setOrigin(node);
edge.setNext(this.getNext());
edge.setPrev(this);
edge.setTwin(twin);
edge.setIncidentFace(this.getIncidentFace());
twin.setOrigin(this.getTwin().getOrigin());
twin.setPrev(this.getTwin().getPrev());
twin.setNext(this.getTwin());
twin.setTwin(edge);
twin.setIncidentFace(this.getTwin().getIncidentFace());
Node twinOrigin = this.getTwin().getOrigin();
twinOrigin.setIncidentEdge(twin);
node.setIncidentEdge(edge);
this.getTwin().setOrigin(node);
this.getTwin().getPrev().setNext(twin);
this.getNext().setPrev(edge);
this.setNext(edge);
this.getTwin().setPrev(twin);
return edge;
}
public String getID() {
return this.id;
}
public void setID(String id) {
this.id = id;
}
}

View File

@ -0,0 +1,125 @@
package model.DCEL;
import java.util.LinkedList;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 30.05.2017.
*/
public class Face {
private LinkedList<Edge> innerComponents;
private Edge outerComponent;
private String id;
public Face() {
this.outerComponent = null;
this.innerComponents = new LinkedList<>();
}
public Face(Edge outerComponent, LinkedList<Edge> innerComponents) {
this.outerComponent = outerComponent;
if (innerComponents != null) {
this.innerComponents = innerComponents;
} else {
this.innerComponents = new LinkedList<>();
}
}
public LinkedList<Edge> getInnerComponents() {
return innerComponents;
}
public void setInnerComponents(LinkedList<Edge> innerComponents) {
this.innerComponents = innerComponents;
}
public Edge getOuterComponent() {
return outerComponent;
}
public void setOuterComponent(Edge outerComponent) {
this.outerComponent = outerComponent;
}
public Face insertEdge(Edge edgeWithSameDestination, Edge edgeToMySource) {
if (edgeWithSameDestination.getIncidentFace().equals(this) || edgeToMySource.getIncidentFace()
.equals(this)) {
LinkedList<Edge> components = new LinkedList<Edge>();
for (Edge e : innerComponents) {
components.add(e);
}
Face face = new Face(getOuterComponent(), components);
Edge edge = new Edge();
Edge twin = new Edge();
edge.setOrigin(edgeWithSameDestination.getOrigin());
edge.setTwin(twin);
edge.setNext(edgeToMySource);
edge.setPrev(edgeWithSameDestination.getPrev());
twin.setOrigin(edgeToMySource.getOrigin());
twin.setTwin(edge);
twin.setNext(edgeWithSameDestination);
twin.setPrev(edgeToMySource.getPrev());
Edge tempEdge = edge.getNext();
Edge tempTwin = twin.getNext();
//kreis umlaufen um festzustellen welche fläche kleiner ist
while ((tempEdge.equals(edge) == false) && (tempTwin.equals(twin) == false)) {
tempEdge = tempEdge.getNext();
tempTwin = tempTwin.getNext();
}
if (tempEdge.equals(edge)) {
setOuterComponent(twin);
twin.setIncidentFace(this);
face.setOuterComponent(edge);
} else {
setOuterComponent(edge);
edge.setIncidentFace(this);
face.setOuterComponent(twin);
}
LinkedList<Edge> bla = new LinkedList<Edge>();
Edge iterEdge = face.getOuterComponent();
bla.add(face.getOuterComponent());
while (iterEdge.hasNext()) {
bla.add(iterEdge.getNext());
iterEdge = iterEdge.getNext();
}
for (Edge e : face.getInnerComponents()) {
iterEdge = e;
while (iterEdge.hasNext()) {
bla.add(iterEdge.getNext());
iterEdge = iterEdge.getNext();
}
}
for (Edge e : bla) {
e.setIncidentFace(face);
}
return face;
} else {
throw new IllegalArgumentException(
"Die angegebenen Kanten haben keinen zusammenhang mit der Fläche!");
}
}
public String getID() {
return this.id;
}
public void setID(String id) {
this.id = id;
}
}

View File

@ -0,0 +1,50 @@
package model.DCEL;
import model.Point;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 30.05.2017.
*/
public class Node {
private Point point;
private Edge incidentEdge;
private String id;
public Node() {
new Node(null, null);
}
public Node(Point point, Edge incidentEdge) {
this.point = point;
this.incidentEdge = incidentEdge;
}
public Point getPoint() {
return point;
}
public void setPoint(Point point) {
this.point = point;
}
public Edge getIncidentEdge() {
return incidentEdge;
}
public void setIncidentEdge(Edge incidentEdge) {
this.incidentEdge = incidentEdge;
}
public String getID() {
return this.id;
}
public void setID(String id) {
this.id = id;
}
}

View File

@ -0,0 +1,51 @@
package model;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 16.06.2017.
*/
public class Interval {
private double upper;
private double lower;
private Boolean activity;
public Interval(double lower, double upper) {
this.upper = upper;
this.lower = lower;
this.activity = true;
}
public Boolean getActivity() {
return activity;
}
public void setActivity(Boolean isActive) {
this.activity = isActive;
}
public double getUpper() {
return upper;
}
public void setUpper(double upper) {
this.upper = upper;
}
public double getLower() {
return lower;
}
public void setLower(double lower) {
this.lower = lower;
}
public Double getDistance() {
return Math.abs(this.upper - this.lower);
}
}

View File

@ -0,0 +1,107 @@
package model;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 12.06.2017.
*/
public class Line {
private final Double MAX = 9999d;
private final Double MIN = -9999d;
private Double m;
private Double b;
private Double x1;
private Double x2;
private Double y1;
private Double y2;
private String id;
public Line(double m, double b, String id) {
this.m = m;
this.b = b;
this.x1 = MIN;
this.y1 = (MIN * m) + b;
this.x2 = MAX * 0.5;
this.y2 = ((MAX * 0.5) * m) + b;
this.id = id;
}
public Line(double m, double b) {
this.m = m;
this.b = b;
this.x1 = MIN;
this.y1 = (MIN * m) + b;
this.x2 = MAX * 0.5;
this.y2 = ((MAX * 0.5) * m) + b;
}
public Line(double x1, double x2, double y1, double y2) {
this.x1 = x1;
this.x2 = x2;
this.y1 = y1;
this.y2 = y2;
this.m = (y2 - y1) / (x2 - x1);
this.b = y2 - (x2 * m);
}
public Double getM() {
return m;
}
public void setM(double m) {
this.m = m;
}
public Double getB() {
return b;
}
public void setB(double b) {
this.b = b;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Double getX1() {
return x1;
}
public Double getX2() {
return x2;
}
public Double getY1() {
return y1;
}
public Double getY2() {
return y2;
}
public void setEndPoints(double x1, double y1, double x2, double y2) {
this.x1 = x1;
this.x2 = x2;
this.y1 = y1;
this.y2 = y2;
}
}

View File

@ -0,0 +1,98 @@
package model;
import java.util.Collections;
import java.util.LinkedList;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 28.05.2017.
*/
public class LineModel {
private LinkedList<Point> nodes;
private LinkedList<Line> lines;
private Double xMinimum;
private Double xMaximum;
private Double yMinimum;
private Double yMaximum;
public LineModel() {
nodes = new LinkedList<>();
lines = new LinkedList<>();
}
public void setXbounds() {
LinkedList<Double> xlist = new LinkedList<>();
for (Point p : nodes) {
xlist.add(p.getX());
}
xMaximum = Collections.max(xlist);
xMinimum = Collections.min(xlist);
}
public void setYbounds() {
LinkedList<Double> ylist = new LinkedList<>();
for (Point p : nodes) {
ylist.add(p.getY());
}
yMaximum = Collections.max(ylist);
yMinimum = Collections.min(ylist);
}
public void addNode(Point node) {
this.nodes.add(node);
}
public void addLine(Line line) {
this.lines.add(line);
}
public LinkedList<Point> getNodes() {
return nodes;
}
public LinkedList<Line> getLines() {
return lines;
}
public void setLines(LinkedList<Line> lines) {
this.lines = lines;
}
public Double getxMinimum() {
return xMinimum;
}
public void setxMinimum(Double xMinimum) {
this.xMinimum = xMinimum;
}
public Double getxMaximum() {
return xMaximum;
}
public void setxMaximum(Double xMaximum) {
this.xMaximum = xMaximum;
}
public Double getyMinimum() {
return yMinimum;
}
public void setyMinimum(Double yMinimum) {
this.yMinimum = yMinimum;
}
public Double getyMaximum() {
return yMaximum;
}
public void setyMaximum(Double yMaximum) {
this.yMaximum = yMaximum;
}
}

View File

@ -0,0 +1,35 @@
package model;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 19.06.2017.
*/
public class Pair {
private Integer p1;
private Integer p2;
public Pair(Integer p1, Integer p2) {
this.p1 = p1;
this.p2 = p2;
}
public Integer getP1() {
return p1;
}
public void setP1(Integer p1) {
this.p1 = p1;
}
public Integer getP2() {
return p2;
}
public void setP2(Integer p2) {
this.p2 = p2;
}
}

View File

@ -0,0 +1,65 @@
package model;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 28.05.2017.
*/
public class Point implements Comparable<Point> {
private Double x;
private Double y;
private String id;
public Point(Double x, Double y) {
this.x = x;
this.y = y;
}
public Point(Double x, Double y, String id) {
this.x = x;
this.y = y;
this.id = id;
}
public Double getX() {
return x;
}
public void setX(Double x) {
this.x = x;
}
public Double getY() {
return y;
}
public void setY(Double y) {
this.y = y;
}
@Override
public int compareTo(Point o) {
if (this.getX() == o.getX()) {
if (this.getY() <= o.getY()) {
return -1;
} else {
return 1;
}
} else if (this.getX() < o.getX()) {
return -1;
} else {
return 1;
}
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}

View File

@ -0,0 +1,210 @@
package presenter;
import model.Interval;
import model.Line;
import model.LineModel;
import presenter.algorithms.IntersectionCounter;
import presenter.evaluation.EvaluateAlgorithms;
import view.MainFrame;
import javax.swing.*;
import java.util.LinkedList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 10.09.2017.
*/
public abstract class AbstractPresenter implements Observer {
private LineModel model;
private MainFrame view;
private EvaluateAlgorithms eval;
public AbstractPresenter(LineModel model, MainFrame view) {
this.model = model;
this.view = view;
}
@Override
public void update(Observable o, Object arg) {
String[] result = ((String[]) arg);
if (result[0] == "eval-dataset-generated") {
SwingUtilities.invokeLater(() -> getView().addEvalDataset(getEval().getData()));
}
if (result[0] == "eval-d") {
SwingUtilities.invokeLater(() -> getView().appendEvalResult(result, Integer.parseInt(result[1]), false));
}
if (result[0] == "eval-ds") {
SwingUtilities.invokeLater(() -> getView().appendEvalResult(result));
}
if (result[0] == "eval-t") {
SwingUtilities.invokeLater(() -> getView().appendEvalResult(result, Integer.parseInt(result[1]), true));
}
if (result[0] == "lines-res") {
SwingUtilities.invokeLater(() -> getView().drawLineResult(result, Integer.parseInt(result[1])));
}
if (result[0] == "lines-res-mult") {
SwingUtilities.invokeLater(() -> getView().drawLineResults(result));
}
if (result[0] == "lms") {
SwingUtilities.invokeLater(() -> {
getView().visualizeLMS(Double.parseDouble(result[1]), Double.parseDouble(result[2]));
//getView().setLmsIsComplete(true);
getView().logHeading("Least Median of Squares");
getView().log("<b>m:</b> " + result[1]);
getView().log("<b>b:</b> " + result[2]);
getView().logSuccess("Berechnung wurde Erfolgreich durchgeführt <hr>");
});
}
if (result[0] == "rm") {
SwingUtilities.invokeLater(() -> {
getView().visualizeRM(Double.parseDouble(result[1]), Double.parseDouble(result[2]));
getView().logHeading("Repeated Median Estimator");
getView().log("<b>m:</b> " + result[1]);
getView().log("<b>b:</b> " + result[2]);
getView().logSuccess("Berechnung wurde Erfolgreich durchgeführt <hr>");
});
}
if (result[0] == "ts") {
SwingUtilities.invokeLater(() -> {
getView().visualizeTS(Double.parseDouble(result[1]), Double.parseDouble(result[2]));
getView().logHeading("Theil-Sen Estimator");
getView().log("<b>m:</b> " + result[1]);
getView().log("<b>b:</b> " + result[2]);
getView().logSuccess("Berechnung wurde Erfolgreich durchgeführt <hr>");
});
}
if (result[0] == "import") {
Double max = Double.parseDouble(result[1]);
Double current = Double.parseDouble(result[2]);
Integer progress = (int) (100 * (current / max));
//100% erreicht
if (progress == 100) {
SwingUtilities.invokeLater(() -> {
getView().showImportProgress(progress);
getView().enableFunctionality();
getView().getProgressDialog().dispose();
});
setup();
Thread t = new Thread(() -> {
calculateIntersections();
});
t.start();
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
SwingUtilities.invokeLater(() -> {
getView().showImportProgress(progress);
});
}
}
if (result[0] == "export") {
SwingUtilities.invokeLater(() -> {
getView().logSuccess("Export Erfolgreich");
getView().log(result[1] + "<hr>");
});
}
if (result[0] == "generator") {
SwingUtilities.invokeLater(() -> {
getView().logSuccess("Generierung Erfolgreich");
getView().log(result[1] + "<hr>");
setup();
});
}
}
public void setup() {
//Darstellung der Schnittpunkte in einer Tabelle
List<String> heading = new LinkedList<>();
List<List<String>> rows = new LinkedList<>();
heading.add("Geraden im Dualraum");
for (int j = 0; j < getModel().getLines().size() - 2; j++) {
LinkedList<String> rowEntry = new LinkedList<>();
Line p1 = getModel().getLines().get(j);
String sign = p1.getB() < 0 ? "" : "+";
rowEntry.add("f(x) = " +String.format("%.3f", p1.getM()) + "x "+ sign + String.format("%.3f",p1.getB()));
if (j + 1 < getModel().getLines().size()) {
Line p2 = getModel().getLines().get(j + 1);
sign = p2.getB() < 0 ? "" : "+";
rowEntry.add("f(x) = " +String.format("%.3f",p2.getM()) + "x" + sign + String.format("%.3f", p2.getB()));
}
if (j + 2 < getModel().getLines().size()) {
Line p3 = getModel().getLines().get(j + 2);
sign = p3.getB() < 0 ? "" : "+";
rowEntry.add("f(x) = " + String.format("%.3f",p3.getM()) + "x"+ sign + String.format("%.3f",p3.getB()));
}
rows.add(rowEntry);
}
getView().createTable(heading, rows);
getView().log("<hr>");
}
public void calculateIntersections() {
try {
Thread thread = new Thread(() -> {
IntersectionCounter counter = new IntersectionCounter();
counter.run(getModel().getLines(), new Interval(-99999, 99999));
counter.calculateIntersectionAbscissas(getModel());
getModel().setXbounds();
getModel().setYbounds();
});
thread.start();
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public LineModel getModel() {
return model;
}
public void setModel(LineModel model) {
this.model = model;
}
public MainFrame getView() {
return view;
}
public void setView(MainFrame view) {
this.view = view;
}
public EvaluateAlgorithms getEval() {
return eval;
}
public void setEval(EvaluateAlgorithms eval) {
this.eval = eval;
}
}

View File

@ -0,0 +1,196 @@
package presenter;
import model.LineModel;
import presenter.algorithms.LeastMedianOfSquaresEstimator;
import presenter.algorithms.RepeatedMedianEstimator;
import presenter.algorithms.TheilSenEstimator;
import presenter.evaluation.EvaluateAlgorithms;
import presenter.generator.DatasetGenerator;
import presenter.io.DataExporter;
import presenter.io.DataImporter;
import presenter.io.EvalResultLatexExport;
import view.MainFrame;
import javax.swing.table.DefaultTableModel;
import java.io.File;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 28.05.2017.
*/
public class Presenter extends AbstractPresenter{
/* Threads */
private Thread tsThread;
private Thread rmThread;
private Thread lmsThread;
private Thread importThread;
private Thread exportThread;
private Thread exportResultThread;
private Thread generatorThread;
private Thread evalThread;
public Presenter(LineModel model, MainFrame view) {
super(model, view);
}
public void visualizeDualLines() {
getView().createDualityDialog();
}
/***************************************************************************************************************************
* Ausführung der Algorithmen
***************************************************************************************************************************/
public void calculateLMS(String[] input) {
if (input[0] != null && input[1] != null) {
if (lmsThread == null || !lmsThread.isAlive()) {
lmsThread = new Thread(() -> {
Double constant = Double.parseDouble(input[0]);
Double error = Double.parseDouble(input[1]);
LeastMedianOfSquaresEstimator lms = new LeastMedianOfSquaresEstimator(getModel().getLines(), getModel().getNodes(), this);
lms.setConstant(constant);
lms.setQuantileError(error);
lms.addObserver(this);
lms.run();
lms.getResult();
});
lmsThread.start();
try {
lmsThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void calculateRM(String input) {
if (input != null) {
if (rmThread == null || !rmThread.isAlive()) {
rmThread = new Thread(() -> {
RepeatedMedianEstimator rm = new RepeatedMedianEstimator(getModel().getLines(), this);
Double parameter = Double.parseDouble(input);
rm.setBeta(parameter);
rm.addObserver(this);
rm.run();
rm.getResult();
});
rmThread.start();
try {
rmThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void calculateTS(String input) {
if (input != null) {
if (tsThread == null || !tsThread.isAlive()) {
tsThread = new Thread(() -> {
TheilSenEstimator ts = new TheilSenEstimator(getModel().getLines(), getModel().getNodes(), this);
ts.addObserver(this);
ts.run();
ts.getResult();
});
tsThread.start();
try {
tsThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/***************************************************************************************************************************
* Hilfsmethoden
***************************************************************************************************************************/
public void startImport(File file) {
if (importThread == null || !importThread.isAlive()) {
importThread = new Thread(() -> {
DataImporter importer = new DataImporter(file, this);
importer.addObserver(this);
importer.run();
});
importThread.start();
try {
importThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void startExport(File file) {
if (exportThread == null || !exportThread.isAlive()) {
exportThread = new Thread(() -> {
DataExporter exporter = new DataExporter(getModel(), file);
exporter.addObserver(this);
exporter.export();
});
exportThread.start();
try {
exportThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void startResultExport(DefaultTableModel model, File file) {
if (exportResultThread == null || !exportResultThread.isAlive()) {
exportResultThread = new Thread(() -> {
EvalResultLatexExport exporter = new EvalResultLatexExport(model, file);
exporter.writeFile();
});
exportResultThread.start();
try {
exportResultThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void generateDataset() {
if (generatorThread == null || !generatorThread.isAlive()) {
generatorThread = new Thread(() -> {
DatasetGenerator generator = new DatasetGenerator();
generator.addObserver(this);
getModel().setLines(generator.generateCircle(100));
calculateIntersections();
getView().enableFunctionality();
});
generatorThread.start();
try {
generatorThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void startEvaluation(int typ, int n, int alg, String datasettyp) {
if (evalThread == null || !evalThread.isAlive()) {
evalThread = new Thread(() -> {
try {
setEval(new EvaluateAlgorithms(typ, n, alg, datasettyp));
getEval().addObserver(this);
getEval().run();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
evalThread.start();
}
}
}

View File

@ -1,4 +1,4 @@
package Presenter.Algorithms;
package presenter.algorithms;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
@ -9,6 +9,7 @@ package Presenter.Algorithms;
*/
public interface Algorithm {
void run();
void getResult();
void run();
void getResult();
}

View File

@ -0,0 +1,25 @@
package presenter.algorithms;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 26.06.2017.
*/
public class BinomialCoeffizient {
public static Double run(int n, int k) {
int res = 1;
if (k > n - k)
k = n - k;
for (int i = 0; i < k; ++i) {
res *= (n - i);
res /= (i + 1);
}
return Double.valueOf(res);
}
}

View File

@ -1,6 +1,7 @@
package Presenter.Algorithms.Comparators;
package presenter.algorithms.Comparators;
import model.Line;
import Model.Line;
import java.util.Comparator;
/**
@ -12,8 +13,8 @@ import java.util.Comparator;
*/
public class YOrderLineComparatorBegin implements Comparator<Line> {
@Override
public int compare(Line o1, Line o2) {
@Override
public int compare(Line o1, Line o2) {
// if (o1.getY1() == o2.getY1()) {
// if (o1.getX1() <= o2.getX1()) {
// return -1;
@ -25,6 +26,6 @@ public class YOrderLineComparatorBegin implements Comparator<Line> {
// } else {
// return 1;
// }
return o1.getY1().compareTo(o2.getY1());
}
return o1.getY1().compareTo(o2.getY1());
}
}

View File

@ -1,6 +1,7 @@
package Presenter.Algorithms.Comparators;
package presenter.algorithms.Comparators;
import model.Line;
import Model.Line;
import java.util.Comparator;
/**
@ -12,8 +13,8 @@ import java.util.Comparator;
*/
public class YOrderLineComparatorEnd implements Comparator<Line> {
@Override
public int compare(Line o1, Line o2) {
@Override
public int compare(Line o1, Line o2) {
// if (o1.getY2() == o2.getY2()) {
// if (o1.getX2() <= o2.getX2()) {
// return -1;
@ -25,6 +26,6 @@ public class YOrderLineComparatorEnd implements Comparator<Line> {
// } else {
// return 1;
// }
return o1.getY2().compareTo(o2.getY2());
}
return o1.getY2().compareTo(o2.getY2());
}
}

View File

@ -1,6 +1,4 @@
package Presenter.Algorithms;
import Presenter.Presenter;
package presenter.algorithms;
import java.util.ArrayList;
import java.util.Collections;
@ -12,43 +10,39 @@ import java.util.Random;
public class FastElementSelector {
/**
*
* @param a
* @param i
* @return
*/
public static Double randomizedSelect(ArrayList<Double> a, double i) {
int start = 0;
int end = a.size()-1;
int end = a.size() - 1;
if (i >= end+1){
if (i >= end + 1) {
return a.get(end);
}
while(true){
if(start == end){
while (true) {
if (start >= end) {
return a.get(start);
}
int q = randomizedPartition(a, start, end);
int k = q-start+1;
int k = q - start + 1;
if(i == k){
if (i == k) {
return a.get(q);
}
else{
if(i <k){
} else {
if (i < k) {
end = q - 1;
}else{
i = i - k;
} else {
start = q + 1;
i = i - k;
}
}
}
}
/**
*
* @param a
* @param start
* @param end
@ -59,10 +53,10 @@ public class FastElementSelector {
Random random = new Random(System.currentTimeMillis());
//alternative: ThreadLocalRandom.current()
if(start < end){
i = start + random.nextInt(end-start);
}else{
i = end + random.nextInt(start-end);
if (start < end) {
i = start + random.nextInt(end - start);
} else {
i = end + random.nextInt(start - end);
}
Collections.swap(a, end, i);
@ -70,7 +64,6 @@ public class FastElementSelector {
}
/**
*
* @param a
* @param start
* @param end
@ -79,13 +72,13 @@ public class FastElementSelector {
private static int partition(ArrayList<Double> a, int start, int end) {
Double x = a.get(end);
int i = start - 1;
for (int j = start; j <= end-1; j++) {
for (int j = start; j <= end - 1; j++) {
if (a.get(j) <= x) {
i++;
Collections.swap(a, i, j);
}
}
Collections.swap(a, i+1, end);
return i+1;
Collections.swap(a, i + 1, end);
return i + 1;
}
}

View File

@ -0,0 +1,268 @@
package presenter.algorithms;
import model.*;
import presenter.algorithms.Comparators.YOrderLineComparatorBegin;
import presenter.algorithms.Comparators.YOrderLineComparatorEnd;
import java.util.*;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 18.06.2017.
*/
public class IntersectionCounter {
private HashMap<Integer, Integer> dictionaryTO;
private HashMap<Integer, Integer> dictionaryBACK;
private ArrayList<Integer> substituted;
private ArrayList<Pair> inversions;
private List<Line> set;
//indexieren der Punkte damit die schnittpunkte berechnet werden können
private HashMap<Line, Integer> secondaryDictionaryTO;
private HashMap<Integer, Line> secondaryDictionaryBACK;
private ArrayList<Line> umin;
/**
* Berechnet die Inversionen zwischen zwei Listen mit Integer Werten. Diese Methode dient als
* Wrapper Methode. Die Logik steht in der <code>countInversions</code> Funktion.
*
* @param a Liste
* @param b Liste
* @return Anzahl an Inversionen
*/
public int run(List<Integer> a, List<Integer> b) {
dictionaryTO = new HashMap<>();
dictionaryBACK = new HashMap<>();
substituted = new ArrayList<>();
inversions = new ArrayList<>();
ArrayList<Integer> temp = new ArrayList<>();
temp.addAll(a);
for (int i = 0; i < a.size(); i++) {
dictionaryTO.put(a.get(i), i + 1);
dictionaryBACK.put(i + 1, a.get(i));
}
for (int j = 0; j < b.size(); j++) {
substituted.add(dictionaryTO.get(b.get(j)));
}
int ret = countInversions(substituted, 0, substituted.size() - 1, temp);
return ret;
}
/**
* Wrapper Methode um herauszufinden wieviele Inversionen zwischen den Schnittpunkten der Werte
* in der Liste und den Endpunkten des Intervalls entstehen.
*
* @param set Liste mit Werten (m,b) um Schnittpunkte zu berechnen
* @param interval Interval
* @return Anzahl an Inversionen
*/
public int run(List<Line> set, Interval interval) {
ArrayList<Integer> listA = new ArrayList<>();
ArrayList<Integer> listB = new ArrayList<>();
prepareData(set, interval, listA, listB);
return run(listA, listB);
}
/**
* Methode die, die Daten für die Funktion <code>run</code> vorbereitet. Es werden die Schnittpunkte
* bzgl. der unteren und oberen Grenze des Intervals und den Werten der Liste (m,b) berechnet. Diese
* Werte haben die selbe x Koordinate aber verschiedene y Koordinaten.
*
* @param set Liste mit Werten m,b
* @param interval Interval
* @param listA Schnittpunkte bzgl. unteren Grenze
* @param listB Schnittpunkte bzgl. oberen Grenze
*/
private void prepareData(List<Line> set, Interval interval, ArrayList<Integer> listA,
ArrayList<Integer> listB) {
secondaryDictionaryTO = new HashMap<>();
secondaryDictionaryBACK = new HashMap<>();
this.set = set;
umin = new ArrayList<>();
Line tmpLine;
for (Line p : set) {
//vertauscht das Point standardmäßig die x lexikografische Ordnung betrachtet
tmpLine = new Line(p.getM(), p.getM(), interval.getLower() * p.getM() + p.getB(),
interval.getUpper() * p.getM() + p.getB());
//wird benötigt um späer die Schnittpunkte ermitteln zu können
tmpLine.setB(p.getB());
tmpLine.setM(p.getM());
umin.add(tmpLine);
}
for (int i = 0; i < umin.size(); i++) {
secondaryDictionaryTO.put(umin.get(i), i);
secondaryDictionaryBACK.put(i, this.set.get(i));
}
Collections.sort(umin, new YOrderLineComparatorBegin());
for (Line q : umin) {
listA.add(secondaryDictionaryTO.get(q));
}
Collections.sort(umin, new YOrderLineComparatorEnd());
for (Line q : umin) {
listB.add(secondaryDictionaryTO.get(q));
}
}
/**
* Angepasster Merge-Sort Algorithmus.
* Die Funktion bekommt neben den standard Parametern zusätzlich eine Liste mit Elementen
* die als Groundtruth dienen.
*
* @param a Eingabefeld mit den Elementen die überprüft werden sollen.
* @param start Startpunkt des Eingabefeldes.
* @param end Endpunkt des Eingabefeldes.
* @param aux Temporäres Array das beim Mergen eine Kopie des original Arrays ist.
* @return Anzahl der inversionen zwischen a und aux.
*/
public int countInversions(List<Integer> a, int start, int end, List<Integer> aux) {
if (start >= end) {
return 0;
}
int invCount = 0;
int mid = start + (end - start) / 2;
int invCountLeft = countInversions(a, start, mid, aux); // divide and conquer
int invCountRight = countInversions(a, mid + 1, end, aux); // divide and conquer
invCount += (invCountLeft + invCountRight);
for (int i = start; i <= end; i++) {
aux.set(i, a.get(i));
}
int left = start;
int right = mid + 1;
int index = start;
//hier beginnt das merging
//iteriere über die Teillisten
//Two-way Merge - Knuth Vol 3 The Art of Computer Programming -
while (left <= mid && right <= end) {
//wenn die linke Teilliste das kleinere Element besitzt kopiere
//das Element in das neue Array
if (aux.get(left) < aux.get(right)) {
a.set(index++, aux.get(left++));
} else {
//merke die inversionspaare
for (int i = left; i <= mid; i++) {
// System.out.println(aux.get(i)+" -- "+ aux.get(right));
inversions.add(new Pair(aux.get(i), aux.get(right)));
}
a.set(index++, aux.get(right++));
invCount += mid - left + 1; // number of inversions for aux[right]
}
}
while (left <= mid) {
a.set(index++, aux.get(left++));
}
// no need to copy over remaining aux[right++] because they are already inside a
return invCount;
}
/**
* Diese Methode liefert nur nach dem Ausführen der <code>run</code> Funktion Sinnvolle Werte.
*
* @return Map mit Schnittpunkt Paaren.
*/
public HashMap<Line, ArrayList<Line>> getIntersectionLinePairs() {
ArrayList<Pair> result = new ArrayList<>();
HashMap<Line, ArrayList<Line>> ret = new HashMap<>();
for (int i = 0; i < inversions.size(); i++) {
result.add(new Pair(dictionaryBACK.get(inversions.get(i).getP1()),
dictionaryBACK.get(inversions.get(i).getP2())));
}
ArrayList<Line> linePairs;
for (Pair p : result) {
Line l1 = secondaryDictionaryBACK.get(p.getP1());
Line l2 = secondaryDictionaryBACK.get(p.getP2());
if (ret.get(l2) == null) {
linePairs = new ArrayList<>();
} else {
linePairs = ret.get(l2);
}
linePairs.add(l1);
ret.put(l2, linePairs);
//Symetrie
if (ret.get(l1) == null) {
linePairs = new ArrayList<>();
} else {
linePairs = ret.get(l1);
}
linePairs.add(l2);
ret.put(l1, linePairs);
}
/*System.out.println("----------------------------------------------------------");
for (Line outerLine : ret.keySet()){
System.out.println("Linie: "+outerLine);
for (Line innerLine : ret.get(outerLine)){
System.out.println("\t\t -> "+innerLine);
}
}
System.out.println("----------------------------------------------------------");*/
return ret;
}
/**
* Diese Methode liefert nur nach dem Ausführen der <code>run</code> Funktion Sinnvolle Werte.
*/
public void calculateIntersectionAbscissas(LineModel model) {
ArrayList<Pair> result = new ArrayList<>();
for (int i = 0; i < inversions.size(); i++) {
result.add(new Pair(dictionaryBACK.get(inversions.get(i).getP1()),
dictionaryBACK.get(inversions.get(i).getP2())));
}
for (Pair p : result) {
Line line = secondaryDictionaryBACK.get(p.getP1());
Line sampledLine = secondaryDictionaryBACK.get(p.getP2());
if (!line.equals(sampledLine)) {
double intersection = (line.getB() - sampledLine.getB()) / (sampledLine.getM() - line.getM());
double yintercept = sampledLine.getM() * intersection + sampledLine.getB();
model.addNode(new Point(intersection, yintercept));
}
}
}
/**
* Berechnet die Schnittpunkte zwischen einer gegebenen Gerade und einer Menge an Geraden.
*
* @param set Menge an Geraden
* @param sampledLine eine spezielle Gerade
* @return Liste mit x Koordinaten der Schnittpunkte
*/
public ArrayList<Double> calculateIntersectionAbscissas(ArrayList<Line> set, Line sampledLine) {
LinkedList<Line> lines = new LinkedList<>(set);
ArrayList<Double> intersections = new ArrayList<>();
double intersection;
for (Line line : lines) {
if (line != sampledLine) {
intersection = (line.getB() - sampledLine.getB()) / (sampledLine.getM() - line.getM());
intersections.add(intersection);
}
}
return intersections;
}
}

View File

@ -0,0 +1,478 @@
package presenter.algorithms;
import model.Interval;
import model.Line;
import model.Point;
import presenter.Presenter;
import java.util.*;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 28.05.2017.
*/
public class LeastMedianOfSquaresEstimator extends Observable implements Algorithm {
private Presenter presenter;
private LinkedList<Line> set = new LinkedList<>();
private LinkedList<Point> intersections = new LinkedList<>();
private IntersectionCounter invCounter = new IntersectionCounter();
private int n;
private double quantileError;
private int kPlus;
private int kMinus;
private PriorityQueue<Interval> intervals;
private Interval subSlabU1;
private Interval subSlabU2;
private Line sigmaMin;
private double heightsigmaMin;
private Double intersectionsPoint;
private Double constant = 0.5;
private Double slope;
private Double yInterception;
public LeastMedianOfSquaresEstimator(LinkedList<Line> set, LinkedList<Point> intersections,
Presenter presenter) {
this.set = set;
this.intersections = intersections;
//(1.) Let n <- |S|; q+ <- q; q- <- q+ * (1 - quantileError);....
n = set.size();
double quantile = 0.5;
double qPlus = quantile;
quantileError = 0.1;
double qMinus = qPlus * (1 - quantileError);
kMinus = (int) Math.ceil(n * qMinus);
kPlus = (int) Math.ceil(n * qPlus);
this.presenter = presenter;
}
public LeastMedianOfSquaresEstimator(LinkedList<Line> set, LinkedList<Point> intersections) {
this(set, intersections, null);
}
/**
*
*/
public void run() {
//(2.) Let U <- (-inf, inf) be the initial active intervals...
Comparator<Interval> comparator = (o1, o2) -> {
if (o1.getDistance() < o2.getDistance()) {
return -1;
}
if (o1.getDistance() > o2.getDistance()) {
return 1;
} else {
return 0;
}
};
intervals = new PriorityQueue<>(comparator);
intervals.add(new Interval(-100000, 100000));
heightsigmaMin = Double.MAX_VALUE;
LinkedList<Point> tmpIntersections = intersections;
//(3.) Apply the following steps as long as the exists active intervals
boolean active = true;
Interval interval;
while (!this.intervals.isEmpty()) {
interval = this.intervals.peek();
if (interval.getActivity()) {
//(a.) Select any active Interval and calc. the inversions
int numberOfIntersections = countInversions(interval);
//(b.) apply plane sweep
if ((constant * n) >= numberOfIntersections) {
sigmaMin = planeSweep(interval);
} else {
//(c.) otherwise....
// get random intersections point...
Collections.shuffle(tmpIntersections, new Random());
for (int i = 0; i < tmpIntersections.size(); i++) {
if (tmpIntersections.get(i).getX() > interval.getLower()
&& tmpIntersections.get(i).getX() < interval.getUpper()) {
intersectionsPoint = tmpIntersections.get(i).getX();
break;
} else {
intersectionsPoint = null;
}
}
if (intersectionsPoint != null) {
splitActiveSlab(intersectionsPoint, interval);
//(d.) this may update sigma min
upperBound(intersectionsPoint);
//(e.) for i={1,2}, call lower bound(Ui)
lowerBound(subSlabU1);
lowerBound(subSlabU2);
if (subSlabU1.getActivity()) {
this.intervals.add(subSlabU1);
}
if (subSlabU2.getActivity()) {
this.intervals.add(subSlabU2);
}
} else {
this.intervals.poll();
}
}
} else {
this.intervals.remove(interval);
}
}
}
/**
* @param interval
* @return
*/
public int countInversions(Interval interval) {
int numberOfInversions = 0;
// debug
//for (int i=0;i<listA.size();i++){
// System.out.println(listA.get(i)+", "+listB.get(i));
//}
numberOfInversions = invCounter.run(set, interval);
return numberOfInversions;
}
/**
* @param interval
* @return
*/
public Line planeSweep(Interval interval) {
//initialisiere die x-Queue mit den 2D Punkten und sortiere nach x-Lexikographischer Ordnung
ArrayList<Point> xQueue = new ArrayList<>();
for (Point point : intersections) {
if (point.getX() >= interval.getLower() && point.getX() < interval.getUpper()) {
xQueue.add(point);
}
}
Collections.sort(xQueue);
Line bracelet = sigmaMin;
double heightOfBracelet = heightsigmaMin;
for (Point current : xQueue) {
Double[] currentBracelet = calcKMinusBracelet(current, kMinus);
if (currentBracelet == null) {
continue;
} else if (currentBracelet[0] < heightOfBracelet) {
heightOfBracelet = currentBracelet[0];
bracelet = new Line(current.getX(), current.getX(), currentBracelet[1], currentBracelet[2]);
}
}
interval.setActivity(false);
return bracelet;
}
/**
* Diese Methode spaltet den aktiven Interval an der x Koordinate point. Es werden zwei neue Slabs
* erzeugt.
*
* @param point x Koordinate an der, der Split geschieht.
*/
public void splitActiveSlab(double point, Interval active) {
subSlabU1 = new Interval(active.getLower() + 0.01, point);
subSlabU2 = new Interval(point, active.getUpper());
this.intervals.remove(active);
}
/**
* @param point
*/
public void upperBound(double point) {
double height = heightsigmaMin;
double tmpHeight;
ArrayList<Double> sortedLineSequence = getEjValues(point);
int itnbr = ((n - kMinus) + 1);
for (int i = 0; i < itnbr; i++) {
tmpHeight = sortedLineSequence.get((i + kMinus) - 1) - sortedLineSequence.get(i);
if (tmpHeight < height) {
height = tmpHeight;
}
if (height < heightsigmaMin) {
heightsigmaMin = height;
if (sigmaMin != null) {
sigmaMin.setEndPoints(point, sortedLineSequence.get(i)
, point, sortedLineSequence.get((i + kMinus) - 1));
} else {
sigmaMin = new Line(point, point, sortedLineSequence.get(i),
sortedLineSequence.get((i + kMinus) - 1));
}
}
}
}
/**
* @param pslab
* @return
*/
public void lowerBound(Interval pslab) {
int[] alpha = new int[n];
int[] beta = new int[n];
int strictlyGreater = 0;
//Teil I.
ArrayList<Double> umaxList;
ArrayList<Double> uminList;
//y koordinaten der Schnittpunkte
ArrayList<Line> lines = new ArrayList<>();
for (Line p : set) {
lines.add(
new Line(pslab.getLower(), pslab.getUpper(), ((pslab.getLower() * p.getM()) + p.getB()),
((pslab.getUpper() * p.getM()) + p.getB())));
}
umaxList = getEjValues(pslab.getUpper());
uminList = getEjValues(pslab.getLower());
for (int i = 0; i < n; i++) {
Line level = new Line(pslab.getLower(), pslab.getUpper(), uminList.get(i), umaxList.get(i));
for (Line line : lines) {
if ((line.getY1() < level.getY1()) && (line.getY2() < level.getY2())) {
alpha[i]++;
}
if ((line.getY1() > level.getY1()) && (line.getY2() > level.getY2())) {
strictlyGreater++;
}
}
beta[i] = n - (alpha[i] + strictlyGreater);
strictlyGreater = 0;
}
//TEST der Alpha und Beta werte, siehe JUnit Test
//for (int i=0;i<alpha.length;i++){
// System.out.println("Alpha["+i+"]: "+alpha[i]+"\t Beta["+i+"]: "+beta[i]);
//}
//Test
//Teil II.
int i = 0;
double h;
pslab.setActivity(false);
for (int j = 0; j < n; j++) {
while ((i < n && (Math.abs(beta[i] - alpha[j]) < kPlus))) {
i++;
}
//test
//if (i < n)
// System.out.println("i: "+i+", j:"+j+"\t "+Math.abs(beta[i] - alpha[j])+"\t kPlus: "+kPlus);
if (i >= n) {
//System.out.println("i: "+i+", j:"+j+". ungültig");
pslab.setActivity(false);
break;
} else {
h = Math.min(Math.abs(uminList.get(j) - uminList.get(i)),
Math.abs(umaxList.get(j) - umaxList.get(i)));
double error = 0.01;
if (((1 + error) * h) < heightsigmaMin) {
//System.out.println("h: "+ h +" ist kleiner als height(sigmaMin): "+heightsigmaMin);
pslab.setActivity(true);
return;
}
}
i = 0;
}
}
/**
* Berechnet die Schnittpunkte der Geraden und der vertikalen Gerade u. Im paper sind diese Werte
* als e_j Werte bekannt.
*
* @param u vertikale Gerade
* @return Liste der Schnittpunkte (da u bekannt werden nur die y Werte zurück gegeben)
*/
public ArrayList<Double> getEjValues(double u) {
ArrayList<Double> ret = new ArrayList<>();
for (Line p : set) {
ret.add((p.getM() * u) + p.getB());
}
Collections.sort(ret);
return ret;
}
/**
* Die Funktion berechnet anhand einer vertikalen Gerade x = px das sogenannte kleinste kMinus
* Bracelet. Mit anderen Worten es wird eine vertikale Teilgerade berechnet die mindestens kMinus
* Geraden schneidet und dabei minimal ist.
*
* @param px Koordinate um die "vertikale Gerade" zu simulieren.
* @return Das Array enthält höhe des Bracelet, e_j und e_(j + kMinus - 1)
*/
public Double[] calcKMinusBracelet(Point px, int kMinusValue) {
//y Koordinaten für das kMinus brecalet
LinkedList<Double> intersections = new LinkedList<>();
for (Line line : set) {
intersections.add((px.getX() * line.getM()) + line.getB());
}
if (intersections.size() >= kMinusValue) {
Collections.sort(intersections);
double height = Math.abs(intersections.get(0) - intersections.get(0 + kMinusValue - 1));
Double[] ret = {height, intersections.get(0), intersections.get(0 + kMinusValue - 1)};
return ret;
} else {
return null;
}
}
@Override
public void getResult() {
if (presenter != null) {
setChanged();
double m = (getSigmaMin().getX2() + getSigmaMin().getX1()) * 0.5;
double b = (getSigmaMin().getY2() + getSigmaMin().getY1()) * -0.5;
slope = m;
yInterception = b;
String[] result = {"lms", m + "", b + ""};
notifyObservers(result);
} else {
double m = (getSigmaMin().getX2() + getSigmaMin().getX1()) * 0.5;
double b = (getSigmaMin().getY2() + getSigmaMin().getY1()) * -0.5;
slope = m;
yInterception = b;
}
}
/**
* Im Allgemeinen werden keine Getter und Setter Methoden benötigt aber sie sind nützlich bei den
* JUnit Testfällen.
*/
public LinkedList<Line> getSet() {
return set;
}
public void setSet(LinkedList<Line> set) {
this.set = set;
}
public LinkedList<Point> getIntersections() {
return intersections;
}
public void setIntersections(LinkedList<Point> intersections) {
this.intersections = intersections;
}
public int getN() {
return n;
}
public void setN(int n) {
this.n = n;
}
public double getQuantileError() {
return quantileError;
}
public void setQuantileError(double quantileError) {
this.quantileError = quantileError;
}
public int getkPlus() {
return kPlus;
}
public void setkPlus(int kPlus) {
this.kPlus = kPlus;
}
public int getkMinus() {
return kMinus;
}
public void setkMinus(int kMinus) {
this.kMinus = kMinus;
}
public Interval getSubSlabU1() {
return subSlabU1;
}
public void setSubSlabU1(Interval subSlabU1) {
this.subSlabU1 = subSlabU1;
}
public Interval getSubSlabU2() {
return subSlabU2;
}
public void setSubSlabU2(Interval subSlabU2) {
this.subSlabU2 = subSlabU2;
}
public Line getSigmaMin() {
return sigmaMin;
}
public void setSigmaMin(Line sigmaMin) {
this.sigmaMin = sigmaMin;
}
public double getHeightsigmaMin() {
return heightsigmaMin;
}
public void setHeightsigmaMin(double heightsigmaMin) {
this.heightsigmaMin = heightsigmaMin;
}
public double getIntersectionsPoint() {
return intersectionsPoint;
}
public void setIntersectionsPoint(double intersectionsPoint) {
this.intersectionsPoint = intersectionsPoint;
}
public Double getConstant() {
return constant;
}
public void setConstant(Double constant) {
this.constant = constant;
}
public Double getSlope() {
return slope;
}
public Double getyInterception() {
return yInterception;
}
}

View File

@ -0,0 +1,56 @@
package presenter.algorithms;
import model.Line;
import model.Point;
import java.util.ArrayList;
import java.util.concurrent.ThreadLocalRandom;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 26.06.2017.
*/
public class RandomSampler {
/**
* Diese Methode liefert eine <code>r</code> Elementige zufällige Stichprobe an Geraden.
*
* @param set Die gesammtmenge der Geraden aus denen gewählt werden soll
* @param r Anzahl der zu wählenden Geraden
* @return <code>r</code> Elementige zufällige Stichprobe an Geraden
*/
public static ArrayList<Line> run(ArrayList<Line> set, Double r, Integer indexOfEnd) {
ArrayList<Line> sampledLines = new ArrayList<>();
for (int i = 0; i < r; i++) {
sampledLines.add(set.get(ThreadLocalRandom.current().nextInt(0, indexOfEnd)));
}
return sampledLines;
}
/**
* Diese Methode liefert eine <code>r</code> Elementige zufällige Stichprobe van Schnittpunkten.
*
* @param set Die gesammtmenge der Geraden aus denen gewählt werden soll
* @param r Anzahl der zu wählenden Geraden
* @return <code>r</code> Elementige zufällige Stichprobe an Schnittpunkten
*/
public static ArrayList<Double> run(ArrayList<Point> set, Double r) {
ArrayList<Double> sampledLines = new ArrayList<>();
Integer indexOfEnd = set.size();
for (int i = 0; i < r; i++) {
Double px = set.get(ThreadLocalRandom.current().nextInt(0, indexOfEnd)).getX();
if (!sampledLines.contains(px))
sampledLines.add(px);
}
return sampledLines;
}
}

View File

@ -0,0 +1,459 @@
package presenter.algorithms;
import model.Interval;
import model.Line;
import presenter.Presenter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Observable;
import java.util.concurrent.ThreadLocalRandom;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 28.05.2017.
*/
public class RepeatedMedianEstimator extends Observable implements Algorithm {
private Presenter presenter;
private LinkedList<Line> set;
private HashMap<Line, ArrayList<Line>> linePairs;
private HashMap<Line, Double> medianIntersections = new HashMap<>();
private HashMap<Line, ArrayList<Double>> intersectionAbscissas = new HashMap<>();
private Interval interval;
//in der Literatur als L_i, C_i, und R_i bekannt
private ArrayList<Double> countLeftSlab;
private ArrayList<Double> countCenterSlab;
private ArrayList<Double> countRightSlab;
//die Mengen L,C und R
private ArrayList<Line> linesInLeftSlab;
private ArrayList<Line> linesInCenterSlab;
private ArrayList<Line> linesInRightSlab;
private Double r;
private Integer n;
private Double k;
private Double kLow;
private Double kHigh;
private Double beta;
private Double thetaLow;
private Double thetaHigh;
private Double slope;
private Double yInterception;
public RepeatedMedianEstimator(LinkedList<Line> set, Presenter presenter) {
this.set = set;
this.presenter = presenter;
interval = new Interval(-10000, 10000);
n = set.size();
beta = 0.5;
countLeftSlab = new ArrayList<>();
countCenterSlab = new ArrayList<>();
countRightSlab = new ArrayList<>();
for (int i = 0; i < n; i++) {
countLeftSlab.add(0d);
countRightSlab.add(0d);
countCenterSlab.add(n - 1.0);
intersectionAbscissas.put(set.get(i), new ArrayList<>());
}
linesInLeftSlab = new ArrayList<>();
linesInCenterSlab = new ArrayList<>(set);
linesInRightSlab = new ArrayList<>();
linePairs = new HashMap<>();
}
public RepeatedMedianEstimator(LinkedList<Line> set) {
this(set, null);
}
/**
*
*/
public void run() {
while (linesInCenterSlab.size() != 1) {
n = linesInCenterSlab.size();
r = Math.ceil(Math.pow(n, beta));
ArrayList<Line> lines = RandomSampler.run(linesInCenterSlab, r, linesInCenterSlab.size());
//For each Sampled Line, compute its median intersection abscissa
ArrayList<Double> medianIntersectionAbscissas = new ArrayList<>();
for (Line l : lines) {
Double abscissa = estimateMedianIntersectionAbscissas(l);
medianIntersections.put(l, abscissa);
medianIntersectionAbscissas.add(abscissa);
}
//rank of the repeated median in C
k = Math.max(1, Math.min(set.size(), (Math.ceil(n * 0.5) - linesInLeftSlab.size())));
//compute k_lo and k_hi
computeSlabBorders();
// if (medianIntersectionAbscissas.size() < kLow || medianIntersectionAbscissas.size()<kHigh || kLow < 0 || kHigh<0 )
// System.err.print("#medianIntersectionAbscissa: "+medianIntersectionAbscissas.size()+"\t\t klow: "+kLow+" kHigh: "+kHigh+"\n\n");
//Employ fast selection algorithm to determine the Elements Theta_lo and Theta_hi
thetaLow = FastElementSelector.randomizedSelect(medianIntersectionAbscissas, kLow);
thetaHigh = FastElementSelector.randomizedSelect(medianIntersectionAbscissas, kHigh);
//For each dual Line in C count the number of intersection abscissas that lie
//in each of the intervals.
countNumberOfIntersectionsAbscissas();
//Based on this 3 counts, determine which of the subintervals contains the repeated median
//and contract to this subiinterval.
contractIntervals();
}
}
/**
* @param set
* @param r
* @return
*/
public ArrayList<Line> sampleLines(ArrayList<Line> set, Double r) {
ArrayList<Line> sampledLines = new ArrayList<>();
for (int i = 0; i < r; i++) {
sampledLines.add(set.get(ThreadLocalRandom.current().nextInt(0, linesInCenterSlab.size())));
}
return sampledLines;
}
/**
* @param sampledLine
* @return
*/
public Double estimateMedianIntersectionAbscissas(Line sampledLine) {
Integer index = Integer.parseInt(sampledLine.getId());
ArrayList<Double> intersections = new ArrayList<>();
double intersection;
IntersectionCounter intersectionCounter = new IntersectionCounter();
intersections = intersectionCounter.calculateIntersectionAbscissas(linesInCenterSlab, sampledLine);
//Collections.sort(intersections);
//double ki = Math.ceil((n - 1) / 2) - countLeftSlab.get(index);
//double i = (Math.ceil((Math.sqrt(n) * ki) / countCenterSlab.get(index)));
double ki = Math.ceil((n - 1) / 2) - FastElementSelector.randomizedSelect(countLeftSlab, index);
double i = (Math.ceil((Math.sqrt(n) * ki) / FastElementSelector.randomizedSelect(countCenterSlab, index)));
int accessIndex;
if (i < 0)
accessIndex = 0;
else if (i >= intersections.size())
accessIndex = intersections.size() - 1;
else
accessIndex = (int) i;
//System.out.println(accessIndex);
//return intersections.get(accessIndex);
return FastElementSelector.randomizedSelect(intersections, accessIndex);
}
/**
*
*/
public void computeSlabBorders() {
kLow = Math
.max(1, Math.floor(
((r * k) / (linesInCenterSlab.size()))
- ((3 * Math.sqrt(r)) / (2))
)
);
kHigh = Math
.min(r, Math.floor(
((r * k) / (linesInCenterSlab.size()))
+ ((3 * Math.sqrt(r)) / (2))
)
);
}
/**
*
*/
public void countNumberOfIntersectionsAbscissas() {
for (Line line : linesInCenterSlab) {
ArrayList<Double> intersections = intersectionAbscissas.get(line);
Integer index = Integer.parseInt(line.getId());
int left = 0;
int center = 0;
int right = 0;
for (Double intersection : intersections) {
if (intersection <= thetaLow) {
left++;
} else if (intersection > thetaLow && intersection <= thetaHigh) {
center++;
} else if (intersection > thetaHigh) {
right++;
}
}
//System.out.println("Linie: "+line.getId()+"\tLeft: "+left+"\t Center: "+center+"\t Right: "+right);
countLeftSlab.set(index, (double) left);
countCenterSlab.set(index, (double) center);
countRightSlab.set(index, (double) right);
}
}
/**
*
*/
public void contractIntervals() {
for (int i = 0; i < linesInCenterSlab.size(); i++) {
double left = countLeftSlab.get(i);
double center = countCenterSlab.get(i);
double right = countRightSlab.get(i);
double max = Math.max(left, Math.max(center, right));
if (left == max) {
linesInLeftSlab.add(linesInCenterSlab.get(i));
linesInCenterSlab.remove(i);
} else if (right == max) {
linesInRightSlab.add(linesInCenterSlab.get(i));
linesInCenterSlab.remove(i);
}
// if (medianIntersections.get(linesInCenterSlab.get(i)) != null) {
// if (medianIntersections.get(linesInCenterSlab.get(i)) <= thetaLow) {
// linesInLeftSlab.add(linesInCenterSlab.get(i));
// linesInCenterSlab.remove(i);
// countLeftSlab.set(i, countLeftSlab.get(i) + 1);
// countCenterSlab.set(i, countCenterSlab.get(i) - 1);
// } else if (medianIntersections.get(linesInCenterSlab.get(i)) > thetaHigh) {
// linesInRightSlab.add(linesInCenterSlab.get(i));
// linesInCenterSlab.remove(i);
// countRightSlab.set(i, countRightSlab.get(i) + 1);
// countCenterSlab.set(i, countCenterSlab.get(i) - 1);
// }
// }
// }
//
}
//wähle C als C
if (linesInLeftSlab.size() < Math.ceil(n / 2) && Math.ceil(n / 2) <= linesInLeftSlab.size() + linesInCenterSlab.size()) {
interval.setLower(thetaLow + 0.1);
interval.setUpper(thetaHigh);
}
// wähle L als C
else if (Math.ceil(n / 2) <= linesInLeftSlab.size()) {
interval.setUpper(thetaLow);
}
//wähle R als C
else if (linesInLeftSlab.size() + linesInCenterSlab.size() < Math.ceil(n / 2) && Math.ceil(n / 2) <= (linesInLeftSlab.size() + linesInCenterSlab.size() + linesInRightSlab.size())) {
interval.setLower(thetaHigh - 0.1);
}
}
@Override
public void getResult() {
if (presenter != null) {
setChanged();
double m = thetaLow;
double b = (-1) * (
(linesInCenterSlab.get(0).getM() * (thetaLow)) + linesInCenterSlab.get(0)
.getB());
slope = m;
yInterception = b;
String[] result = new String[]{"rm", m + "", b + ""};
notifyObservers(result);
} else {
double m = thetaLow;
double b = (-1) * ((linesInCenterSlab.get(0).getM() * (thetaLow)) + linesInCenterSlab.get(0).getB());
slope = m;
yInterception = b;
}
}
/*******************************************************************************************************************
* Getter und Setter Methoden
******************************************************************************************************************/
public LinkedList<Line> getSet() {
return set;
}
public void setSet(LinkedList<Line> set) {
this.set = set;
}
public HashMap<Line, ArrayList<Line>> getLinePairs() {
return linePairs;
}
public void setLinePairs(HashMap<Line, ArrayList<Line>> linePairs) {
this.linePairs = linePairs;
}
public HashMap<Line, Double> getMedianIntersections() {
return medianIntersections;
}
public void setMedianIntersections(HashMap<Line, Double> medianIntersections) {
this.medianIntersections = medianIntersections;
}
public HashMap<Line, ArrayList<Double>> getIntersectionAbscissas() {
return intersectionAbscissas;
}
public void setIntersectionAbscissas(
HashMap<Line, ArrayList<Double>> intersectionAbscissas) {
this.intersectionAbscissas = intersectionAbscissas;
}
public Interval getInterval() {
return interval;
}
public void setInterval(Interval interval) {
this.interval = interval;
}
public ArrayList<Double> getCountLeftSlab() {
return countLeftSlab;
}
public void setCountLeftSlab(ArrayList<Double> countLeftSlab) {
this.countLeftSlab = countLeftSlab;
}
public ArrayList<Double> getCountCenterSlab() {
return countCenterSlab;
}
public void setCountCenterSlab(ArrayList<Double> countCenterSlab) {
this.countCenterSlab = countCenterSlab;
}
public ArrayList<Double> getCountRightSlab() {
return countRightSlab;
}
public void setCountRightSlab(ArrayList<Double> countRightSlab) {
this.countRightSlab = countRightSlab;
}
public ArrayList<Line> getLinesInLeftSlab() {
return linesInLeftSlab;
}
public void setLinesInLeftSlab(ArrayList<Line> linesInLeftSlab) {
this.linesInLeftSlab = linesInLeftSlab;
}
public ArrayList<Line> getLinesInCenterSlab() {
return linesInCenterSlab;
}
public void setLinesInCenterSlab(ArrayList<Line> linesInCenterSlab) {
this.linesInCenterSlab = linesInCenterSlab;
}
public ArrayList<Line> getLinesInRightSlab() {
return linesInRightSlab;
}
public void setLinesInRightSlab(ArrayList<Line> linesInRightSlab) {
this.linesInRightSlab = linesInRightSlab;
}
public Double getR() {
return r;
}
public void setR(Double r) {
this.r = r;
}
public Integer getN() {
return n;
}
public void setN(Integer n) {
this.n = n;
}
public Double getK() {
return k;
}
public void setK(Double k) {
this.k = k;
}
public Double getkLow() {
return kLow;
}
public void setkLow(Double kLow) {
this.kLow = kLow;
}
public Double getkHigh() {
return kHigh;
}
public void setkHigh(Double kHigh) {
this.kHigh = kHigh;
}
public Double getBeta() {
return beta;
}
public void setBeta(Double beta) {
this.beta = beta;
}
public Double getThetaLow() {
return thetaLow;
}
public void setThetaLow(Double thetaLow) {
this.thetaLow = thetaLow;
}
public Double getThetaHigh() {
return thetaHigh;
}
public void setThetaHigh(Double thetaHigh) {
this.thetaHigh = thetaHigh;
}
public Double getSlope() {
return slope;
}
public Double getyInterception() {
return yInterception;
}
}

View File

@ -1,11 +1,10 @@
package Presenter.Algorithms;
package presenter.algorithms;
import Model.Interval;
import Model.Line;
import Model.Point;
import Presenter.Presenter;
import model.Interval;
import model.Line;
import model.Point;
import presenter.Presenter;
import com.sun.org.apache.bcel.internal.generic.FASTORE;
import java.util.*;
/**
@ -19,20 +18,15 @@ public class TheilSenEstimator extends Observable implements Algorithm {
private final Double POSITIV_INF = 99999.0;
private final Double NEGATIV_INF = -99999.0;
private final Double EPSILON = 0.00001;
private Presenter presenter;
private ArrayList<Line> setOfLines;
private ArrayList<Point> setOfIntersections;
private ArrayList<Point> intervalIntersections;
private ArrayList<Double> sampledIntersections;
//wird benötigt um den y Achsenabschnitt zu Berechnen
private ArrayList<Double> yCoordinates;
private ArrayList<Double> xCoordinates;
//Hilfsvariablen (siehe original Paper)
private Double j;
private Integer jA;
@ -41,17 +35,13 @@ public class TheilSenEstimator extends Observable implements Algorithm {
private Integer n;
private Double N;
private Integer k;
//Intervall und die temporaeren Grenzen
private Interval interval;
private Double aVariant;
private Double bVariant;
private Double slope;
private Double yInterception;
private final Double EPSILON = 0.00001;
public TheilSenEstimator(LinkedList<Line> setOfLines, LinkedList<Point> setOfIntersections, Presenter presenter) {
this.presenter = presenter;
@ -64,11 +54,11 @@ public class TheilSenEstimator extends Observable implements Algorithm {
this.yCoordinates = new ArrayList<>();
this.xCoordinates = new ArrayList<>();
this.N = BinomialCoeffizient.run(n, 2);
this.k = Integer.valueOf((int) (N * 0.5))-1;
this.k = Integer.valueOf((int) (N * 0.5)) - 1;
}
public TheilSenEstimator(LinkedList<Line> setOfLines, LinkedList<Point> setOfIntersections) {
this(setOfLines,setOfIntersections,null);
this(setOfLines, setOfIntersections, null);
}
/**
@ -134,9 +124,9 @@ public class TheilSenEstimator extends Observable implements Algorithm {
Boolean cond1 = conda && condb;
Boolean cond2 = (higherCount-lowerCount) <= ((11 * N) / Math.sqrt(r));
Boolean cond2 = (higherCount - lowerCount) <= ((11 * N) / Math.sqrt(r));
return cond1 && cond2;
return (cond1 && cond2) || (aVariant == bVariant);
}
@ -168,7 +158,7 @@ public class TheilSenEstimator extends Observable implements Algorithm {
*/
public int getOpenIntervalSize(double a, double b, ArrayList<Point> set) {
int counter = 0;
for (int i=0;i<set.size();i++) {
for (int i = 0; i < set.size(); i++) {
Point x = set.get(i);
if (x.getX() > a && x.getX() < b) {
counter++;
@ -188,7 +178,7 @@ public class TheilSenEstimator extends Observable implements Algorithm {
*/
public ArrayList<Point> getOpenIntervalElements(double a, double b) {
ArrayList<Point> list = new ArrayList<>();
for (int i=0;i<intervalIntersections.size();i++) {
for (int i = 0; i < intervalIntersections.size(); i++) {
Point x = intervalIntersections.get(i);
if ((x.getX() > a && x.getX() < b) || (Math.abs(interval.getUpper() - interval.getLower())) < EPSILON) {
list.add(x);
@ -207,21 +197,21 @@ public class TheilSenEstimator extends Observable implements Algorithm {
ArrayList<Point> resultSt = getOpenIntervalElements(interval.getLower(), interval.getUpper());
ArrayList<Double> resultAbscissas = new ArrayList<>();
for (Point p : resultSt){
for (Point p : resultSt) {
resultAbscissas.add(p.getX());
}
for (Point p: setOfIntersections) {
for (Point p : setOfIntersections) {
yCoordinates.add(p.getY());
}
int pseudoIndex = (int) getOpenIntervalSize(NEGATIV_INF, interval.getLower(), setOfIntersections);
m = FastElementSelector.randomizedSelect(resultAbscissas, k-pseudoIndex);
m = FastElementSelector.randomizedSelect(resultAbscissas, k - pseudoIndex);
Set<Double> unique = new LinkedHashSet<>(yCoordinates);
yCoordinates.clear();
yCoordinates.addAll(unique);
b = FastElementSelector.randomizedSelect(yCoordinates, yCoordinates.size()*0.5) * -1;
b = FastElementSelector.randomizedSelect(yCoordinates, yCoordinates.size() * 0.5) * -1;
slope = m;
yInterception = b;

View File

@ -1,16 +1,17 @@
package Presenter.Evaluation;
package presenter.evaluation;
import Model.Interval;
import Model.Line;
import Model.LineModel;
import Presenter.Algorithms.*;
import Presenter.Generator.DatasetGenerator;
import model.Interval;
import model.Line;
import model.LineModel;
import presenter.algorithms.IntersectionCounter;
import presenter.algorithms.LeastMedianOfSquaresEstimator;
import presenter.algorithms.RepeatedMedianEstimator;
import presenter.algorithms.TheilSenEstimator;
import presenter.generator.DatasetGenerator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Observable;
import javax.swing.JOptionPane;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
@ -41,21 +42,22 @@ public class EvaluateAlgorithms extends Observable {
private int alg;
/**
* Konstruktor zur Evaluation
* @param type Typ der Evaluation
* @param n Größe des Datensatzes
* @param alg 0 = lms,
* 1 = rm,
* 2 = ts,
* 3 = lms, rm,
* 4 = lms, ts,
* 5 = rm, ts,
* 6 = lms, rm, ts,
* Konstruktor zur evaluation
*
* @param type Typ der evaluation
* @param n Größe des Datensatzes
* @param alg 0 = lms,
* 1 = rm,
* 2 = ts,
* 3 = lms, rm,
* 4 = lms, ts,
* 5 = rm, ts,
* 6 = lms, rm, ts,
*/
public EvaluateAlgorithms(int type, int n, int alg, String datasettyp){
public EvaluateAlgorithms(int type, int n, int alg, String datasettyp) {
this.arrangement = new LineModel();
generator = new DatasetGenerator();
switch (datasettyp){
switch (datasettyp) {
case "Punktwolke":
arrangement.setLines(generator.generateDataCloud(n));
break;
@ -83,30 +85,30 @@ public class EvaluateAlgorithms extends Observable {
ArrayList<String> result;
ArrayList<ArrayList<String>> multipleResults = new ArrayList<>();
switch (type){
switch (type) {
case 0:
result = new ArrayList<>();
//der alg der gewählt wurde
if (alg == 0) {
startLMS();
result = getScaleDependentMeasure(arrangement.getLines(), lmsRes[0], lmsRes[1]);
sendPlotLineResults(lmsRes,0);
} else if (alg == 1) {
startRM();
result = getScaleDependentMeasure(arrangement.getLines(), rmRes[0], rmRes[1]);
sendPlotLineResults(rmRes,1);
} else {
startTS();
result = getScaleDependentMeasure(arrangement.getLines(), tsRes[0], tsRes[1]);
sendPlotLineResults(tsRes,2);
}
result = new ArrayList<>();
//der alg der gewählt wurde
if (alg == 0) {
startLMS();
result = getScaleDependentMeasure(arrangement.getLines(), lmsRes[0], lmsRes[1]);
sendPlotLineResults(lmsRes, 0);
} else if (alg == 1) {
startRM();
result = getScaleDependentMeasure(arrangement.getLines(), rmRes[0], rmRes[1]);
sendPlotLineResults(rmRes, 1);
} else {
startTS();
result = getScaleDependentMeasure(arrangement.getLines(), tsRes[0], tsRes[1]);
sendPlotLineResults(tsRes, 2);
}
sendTableApproximationTypes();
sendTableApproximationData(result, alg);
break;
case 1:
result = new ArrayList<>();
ArrayList<Double[]> lineRes;
switch (alg){
switch (alg) {
case 3:
startLMS();
startRM();
@ -121,7 +123,7 @@ public class EvaluateAlgorithms extends Observable {
lineRes = new ArrayList<>();
lineRes.add(lmsRes);
lineRes.add(rmRes);
sendPloteLineResults(lineRes, new Integer[]{0,1});
sendPloteLineResults(lineRes, new Integer[]{0, 1});
break;
case 4:
startLMS();
@ -137,7 +139,7 @@ public class EvaluateAlgorithms extends Observable {
lineRes = new ArrayList<>();
lineRes.add(lmsRes);
lineRes.add(tsRes);
sendPloteLineResults(lineRes, new Integer[]{0,2});
sendPloteLineResults(lineRes, new Integer[]{0, 2});
break;
case 5:
startRM();
@ -153,7 +155,7 @@ public class EvaluateAlgorithms extends Observable {
lineRes = new ArrayList<>();
lineRes.add(rmRes);
lineRes.add(tsRes);
sendPloteLineResults(lineRes, new Integer[]{1,2});
sendPloteLineResults(lineRes, new Integer[]{1, 2});
break;
case 6:
startLMS();
@ -171,7 +173,7 @@ public class EvaluateAlgorithms extends Observable {
lineRes.add(lmsRes);
lineRes.add(rmRes);
lineRes.add(tsRes);
sendPloteLineResults(lineRes, new Integer[]{0,1,2});
sendPloteLineResults(lineRes, new Integer[]{0, 1, 2});
break;
}
@ -180,14 +182,13 @@ public class EvaluateAlgorithms extends Observable {
}
}
public void sendTableApproximationData(ArrayList<String> result, int col){
public void sendTableApproximationData(ArrayList<String> result, int col) {
ArrayList<String> tableInput = new ArrayList<>();
tableInput.add("eval-d");
tableInput.add(""+col);
for (int i=0;i<names[type].length;i++) {
tableInput.add("" + col);
for (int i = 0; i < names[type].length; i++) {
tableInput.add(result.get(i));
}
tableInput.add("");
@ -196,13 +197,13 @@ public class EvaluateAlgorithms extends Observable {
tableInput.clear();
}
public void sendTableApproximationData(ArrayList<ArrayList<String>> result){
public void sendTableApproximationData(ArrayList<ArrayList<String>> result) {
ArrayList<String> tableInput = new ArrayList<>();
//iteration über die ApproximationsGüten -- Zeilen
for (int j=0;j<=result.get(0).size();j++){
for (int j = 0; j <= result.get(0).size(); j++) {
tableInput.add("eval-ds");
if(j != result.get(0).size()) {
if (j != result.get(0).size()) {
tableInput.add(names[type][j]);
//iteration über die alg. -- Spalten
@ -223,11 +224,11 @@ public class EvaluateAlgorithms extends Observable {
}
public void sendTableApproximationTypes(){
public void sendTableApproximationTypes() {
ArrayList<String> tableInput = new ArrayList<>();
tableInput.add("eval-t");
tableInput.add(""+0);
for (int i=0;i<names[type].length;i++) {
tableInput.add("" + 0);
for (int i = 0; i < names[type].length; i++) {
tableInput.add(names[type][i]);
}
tableInput.add("");
@ -236,29 +237,29 @@ public class EvaluateAlgorithms extends Observable {
tableInput.clear();
}
public void sendPlotLineResults(Double[] res, int alg){
public void sendPlotLineResults(Double[] res, int alg) {
//visualisiere m,b
ArrayList<String> lines = new ArrayList<>();
lines.add("lines-res");
lines.add(""+alg);
lines.add("" + alg);
//lms res
lines.add(res[0]+"");
lines.add(res[1]+"");
lines.add(res[0] + "");
lines.add(res[1] + "");
setChanged();
notifyObservers(lines.stream().toArray(String[]::new));
}
public void sendPloteLineResults(ArrayList<Double[]> res, Integer[] algs){
public void sendPloteLineResults(ArrayList<Double[]> res, Integer[] algs) {
ArrayList<String> lines = new ArrayList<>();
lines.add("lines-res-mult");
for (int i=0;i<algs.length;i++){
lines.add(""+algs[i]);
for (int i = 0; i < algs.length; i++) {
lines.add("" + algs[i]);
//lms res
Double[] tmp = res.get(i);
lines.add(tmp[0]+"");
lines.add(tmp[1]+"");
lines.add(tmp[0] + "");
lines.add(tmp[1] + "");
}
setChanged();
notifyObservers(lines.stream().toArray(String[]::new));
@ -322,7 +323,7 @@ public class EvaluateAlgorithms extends Observable {
return ret;
}
public ArrayList<String> getScaledErrorBasedMeasure(LinkedList<Line> lines, Double m, Double b){
public ArrayList<String> getScaledErrorBasedMeasure(LinkedList<Line> lines, Double m, Double b) {
ScaledErrorBasedMeasure scaledErrorBasedMeasure = new ScaledErrorBasedMeasure(lines, m, b);
ArrayList<String> ret = new ArrayList<>();
ret.add(scaledErrorBasedMeasure.mse().toString());
@ -332,17 +333,17 @@ public class EvaluateAlgorithms extends Observable {
return ret;
}
private ArrayList<String> fillPseudoResults(){
private ArrayList<String> fillPseudoResults() {
ArrayList<String> result = new ArrayList<>();
result.add(" ");
result.add(" ");
result.add(" ");
result.add(" ");
return result;
return result;
}
public LinkedList<Line> getData(){
public LinkedList<Line> getData() {
return arrangement.getLines();
}
}

View File

@ -0,0 +1,82 @@
package presenter.evaluation;
import model.Line;
import presenter.algorithms.FastElementSelector;
import java.util.ArrayList;
import java.util.LinkedList;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 07.09.2017.
*/
public class PercentageErrorBasedMeasure {
private ArrayList<Double> percentageError;
public PercentageErrorBasedMeasure(final LinkedList<Line> lines, Double m, Double b) {
ArrayList<Double> sampson = new ArrayList<>();
for (Line line : lines) {
Double e = Math.pow(m * line.getM() - line.getB() + b, 2) / (Math.pow(m, 2) + 1);
sampson.add(e);
}
percentageError = new ArrayList<>();
for (int j = 0; j < sampson.size(); j++) {
percentageError.add(100 * sampson.get(j) / lines.get(j).getB());
}
}
/* Percentege Error Approximation Measures */
//verschiedene Eingaben für einen Alg.
public Double mape() {
double error = 0;
for (Double d : percentageError) {
error += Math.abs(d);
}
error /= percentageError.size();
return error;
}
public Double mdape() {
ArrayList<Double> abs = new ArrayList<>();
for (Double d : percentageError) {
abs.add(Math.abs(d));
}
return FastElementSelector.randomizedSelect(abs, abs.size() * 0.5);
}
public Double rmspe() {
double error = 0;
for (Double d : percentageError) {
error += Math.pow(d, 2);
}
error /= percentageError.size();
return Math.sqrt(error);
}
public Double rmdspe() {
ArrayList squares = new ArrayList();
for (Double d : percentageError) {
squares.add(Math.pow(d, 2));
}
return Math.sqrt(FastElementSelector.randomizedSelect(squares, squares.size() * 0.5));
}
}

View File

@ -0,0 +1,61 @@
package presenter.evaluation;
import model.Line;
import presenter.algorithms.FastElementSelector;
import java.util.ArrayList;
import java.util.LinkedList;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 07.09.2017.
*/
public class ScaleDependentMeasure {
private ArrayList<Double> errorValues;
public ScaleDependentMeasure(final LinkedList<Line> lines, Double m, Double b) {
//Liste mit den Fehler zu jedem Punkt
errorValues = new ArrayList<>();
for (Line line : lines) {
Double e = Math.pow(m * line.getM() - line.getB() + b, 2) / (Math.pow(m, 2) + 1);
errorValues.add(e);
}
}
/* Skalierungs Abhängige Approximationsgüten */
//unterschiedliche Alg.- auf einem Datensatz
public Double mse() {
double error = 0;
for (Double d : errorValues) {
error += Math.pow(d, 2);
}
error /= errorValues.size();
return error;
}
public Double rmse() {
return Math.sqrt(mse());
}
public Double mae() {
double error = 0;
for (Double d : errorValues) {
error += Math.abs(d);
}
error /= errorValues.size();
return error;
}
public Double mdae() {
return FastElementSelector
.randomizedSelect(errorValues, errorValues.size() * 0.5);
}
}

View File

@ -0,0 +1,72 @@
package presenter.evaluation;
import model.Line;
import presenter.algorithms.FastElementSelector;
import java.util.ArrayList;
import java.util.LinkedList;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 07.09.2017.
*/
public class ScaledErrorBasedMeasure {
private ArrayList<Double> scaledError;
public ScaledErrorBasedMeasure(final LinkedList<Line> lines, Double m, Double b) {
//Liste mit den Fehler zu jedem Punkt
ArrayList<Double> sampson = new ArrayList<>();
Double denum = 0d;
for (int i = 2; i < lines.size(); i++) {
denum += Math.abs(lines.get(i).getM() - lines.get(i - 1).getM());
}
denum *= 1 / (lines.size() - 1);
for (Line line : lines) {
Double e = Math.pow(m * line.getM() - line.getB() + b, 2) / (Math.pow(m, 2) + 1);
sampson.add(e);
Double val = e / (denum);
scaledError.add(val);
}
}
/* Skalierungs Abhängige Approximationsgüten */
//unterschiedliche Alg.- auf einem Datensatz
public Double mse() {
double error = 0;
for (Double d : scaledError) {
error += Math.pow(d, 2);
}
error /= scaledError.size();
return error;
}
public Double rmse() {
return Math.sqrt(mse());
}
public Double mae() {
double error = 0;
for (Double d : scaledError) {
error += Math.abs(d);
}
error /= scaledError.size();
return error;
}
public Double mdae() {
return FastElementSelector
.randomizedSelect(scaledError, scaledError.size() * 0.5);
}
}

View File

@ -1,9 +1,7 @@
package Presenter.Generator;
package presenter.generator;
import Model.Line;
import model.Line;
import Model.Point;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Observable;
@ -16,53 +14,53 @@ import java.util.Random;
* @Email: a_wolf28@uni-muenster.de
* @Date: 01.08.2017.
*/
public class DatasetGenerator extends Observable{
public class DatasetGenerator extends Observable {
private Double m;
private Double b;
private Random random;
public DatasetGenerator(Double m, Double b){
public DatasetGenerator(Double m, Double b) {
this.m = m;
this.b = b;
random = new Random();
random.setSeed(9999);
}
public DatasetGenerator(){
public DatasetGenerator() {
random = new Random();
}
public LinkedList<Line> generateDataCloud(int size){
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++){
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((double) i, signal - y);
line.setId(i-1+"");
line.setId(i - 1 + "");
lines.add(line);
}
String[] ret = {"generator","Es wurden "+100+" Daten generiert mit den Parametern",
"</br> <b>m</b> = "+m+"",
"</br> <b>b</b> = "+b+""};
String[] ret = {"generator", "Es wurden " + 100 + " Daten generiert mit den Parametern",
"</br> <b>m</b> = " + m + "",
"</br> <b>b</b> = " + b + ""};
setChanged();
notifyObservers(ret);
return lines;
}
public LinkedList<Line> generateDataLines(int size){
public LinkedList<Line> generateDataLines(int size) {
LinkedList<Line> lines = new LinkedList<>();
return generateDataLines(lines, size);
}
private LinkedList<Line> generateDataLines(LinkedList<Line> lines, int n){
private LinkedList<Line> generateDataLines(LinkedList<Line> lines, int n) {
m = 5d;
b = 0d;
@ -72,28 +70,26 @@ public class DatasetGenerator extends Observable{
//speichere die Koordinaten in einer HashMap, damit keine Punkte
//entstehen deren x-Koordinate zu sehr beieinander liegt.
while (size < n){
while (size < n) {
double y = random.nextGaussian();
double signal = m * y + b;
signal *= -1;
if (!points.containsKey(y)){
points.put(y,signal);
if (!points.containsKey(y)) {
points.put(y, signal);
size++;
}
}
int idx = lines.size();
for (Double d :points.keySet()) {
for (Double d : points.keySet()) {
Line line = new Line((double) d, points.get(d));
line.setId(idx+"");
line.setId(idx + "");
lines.add(line);
idx++;
}
String[] ret = {"generator","Es wurden "+100+" Daten generiert mit den Parametern",
"</br> <b>m</b> = "+m+"",
"</br> <b>b</b> = "+b+""};
String[] ret = {"generator", "Es wurden " + 100 + " Daten generiert mit den Parametern"};
setChanged();
notifyObservers(ret);
return lines;
@ -106,22 +102,21 @@ public class DatasetGenerator extends Observable{
double from = 0;
double to = Math.PI * 5;
//obere Grenze für die neuen Punkte
int n = size/2 + lines.size();
int n = size / 2 + lines.size();
//calculate the distance between every two points
double distance = (to - from) / ((double) n);
//create points
double currentDistance= from;
double currentDistance = from;
//an die aktuelle Liste dranhängen
for(int i=lines.size(); i < n; i++)
{
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+"");
Line line = new Line(x, y);
line.setId(i + "");
lines.add(line);
//distance for the next iteration
@ -129,7 +124,7 @@ public class DatasetGenerator extends Observable{
}
return generateDataLines(lines,size/2);
return generateDataLines(lines, size / 2);
}
}

View File

@ -1,7 +1,7 @@
package Presenter.ImportExport;
package presenter.io;
import Model.Line;
import Model.LineModel;
import model.Line;
import model.LineModel;
import com.opencsv.CSVWriter;
import java.io.File;
@ -16,24 +16,24 @@ import java.util.Observable;
* @Email: a_wolf28@uni-muenster.de
* @Date: 03.08.2017.
*/
public class DataExporter extends Observable{
public class DataExporter extends Observable {
private LineModel lineModel;
private File file;
public DataExporter(LineModel model, File file){
public DataExporter(LineModel model, File file) {
this.file = file;
this.lineModel = model;
}
public void export(){
public void export() {
CSVWriter writer = null;
try {
writer = new CSVWriter(new FileWriter(file), ',');
// feed in your array (or convert your data to an array)
String[] entries = new String[3];
for (Line line : lineModel.getLines()){
for (Line line : lineModel.getLines()) {
entries[0] = line.getId();
entries[1] = line.getM().toString();
Double tmp = (-1) * line.getB();
@ -41,7 +41,7 @@ public class DataExporter extends Observable{
writer.writeNext(entries);
}
writer.close();
String[] ret = {"export","Das aktuelle Modell wurde erfolgreich unter: "+file.getAbsolutePath()+" gespeichert."};
String[] ret = {"export", "Das aktuelle Modell wurde erfolgreich unter: " + file.getAbsolutePath() + " gespeichert."};
setChanged();
notifyObservers(ret);
} catch (IOException e) {

View File

@ -0,0 +1,77 @@
package presenter.io;
import model.Line;
import model.LineModel;
import presenter.Presenter;
import com.opencsv.CSVReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;
import java.util.Observable;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 21.06.2017.
*/
public class DataImporter extends Observable {
private File file;
private CSVReader reader;
private LineModel model;
private Presenter presenter;
public DataImporter(File file, Presenter presenter) {
this.model = new LineModel();
this.presenter = presenter;
this.presenter.setModel(this.model);
//System.out.println(this.model.getLines().size()+ " die Anzahl der aktuellen Lines.");
this.file = file;
try {
this.reader = new CSVReader(new FileReader(file));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public void run() {
try {
List<String[]> lines = reader.readAll();
int counter = 0;
String[] result = {"import", lines.size() + "", ""};
//System.out.println("+-------------------------------------------------------------------------------+");
for (String[] nextLine : lines) {
// nextLine[] is an array of values from the line
Double x = Double.parseDouble(nextLine[1]);
Double y = Double.parseDouble(nextLine[2]) * (-1);
Line line = new Line(x, y);
line.setId(counter + "");
this.presenter.getModel().addLine(line);
//System.out.format("|\t\t\t\t\t %-11d \t|\t\t\t\t\t %-11f \t|\t\t\t\t\t %-11f \t\t\t\t\t|\n", id,x,y);
setChanged();
counter++;
result[2] = counter + "";
Thread.sleep(10);
notifyObservers(result);
}
//System.out.println("+-------------------------------------------------------------------------------+");
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,96 @@
package presenter.io;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 08.09.2017.
*/
public class EvalResultLatexExport {
private DefaultTableModel model;
private File file;
public EvalResultLatexExport(DefaultTableModel model, File file) {
this.model = model;
this.file = file;
}
/**
* e.g. Source: <url>https://en.wikibooks.org/wiki/LaTeX/Tables</url>
* \begin{tabular}{l*{3}{c}}
* Team & P & W & D & L & F & A & Pts \\\hline
* Manchester United & 6 & 4 & 0 & 2 & 10 & 5 & 12 \\
* Celtic & 6 & 3 & 0 & 3 & 8 & 9 & 9 \\
* Benfica & 6 & 2 & 1 & 3 & 7 & 8 & 7 \\
* FC Copenhagen & 6 & 2 & 1 & 3 & 5 & 8 & 7 \\
* \end{tabular}
*
* @return
*/
private String createOutputData() {
String split = "&";
StringBuilder doc = new StringBuilder();
doc.append("\\begin{tabular}{l|*{3}{r}}" + "\r\n");
for (int i = 0; i < model.getColumnCount(); i++) {
if (model.getValueAt(0, i).toString() != "" || model.getRowCount() > 5)
doc.append("\\textsc{" + model.getColumnName(i) + "}" + split);
}
doc.deleteCharAt(doc.lastIndexOf(split));
doc.append("\\\\\\hline\\hline" + "\r\n");
for (int i = 0; i < model.getRowCount() - 1; i++) {
for (int j = 0; j < model.getColumnCount(); j++) {
if (model.getValueAt(i, j).toString() != "") {
if (j == 0) {
doc.append("\\textbf{" + model.getValueAt(i, j).toString() + "}" + split);
} else {
Double val = Double.parseDouble((String) model.getValueAt(i, j));
doc.append(String.format("%.3f", val) + split);
}
}
}
if (model.getValueAt(i, 0) != "") {
doc.deleteCharAt(doc.lastIndexOf(split));
}
doc.append("\\\\" + "\r\n");
}
doc.append("\\end{tabular}");
return doc.toString();
}
public void writeFile() {
FileWriter fileWriter = null;
BufferedWriter bufferedWriter = null;
try {
fileWriter = new FileWriter(file);
bufferedWriter = new BufferedWriter(fileWriter);
bufferedWriter.write(createOutputData());
SwingUtilities.invokeLater(() -> {
JOptionPane.showMessageDialog(null, "Export war Erfolgreich!");
});
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bufferedWriter.close();
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

View File

@ -0,0 +1,547 @@
package view;
import model.Line;
import presenter.AbstractPresenter;
import presenter.Presenter;
import view.listener.*;
import view.panels.*;
import view.panels.tabs.LMSPanel;
import view.panels.tabs.RMPanel;
import view.panels.tabs.TSPanel;
import view.panels.tabs.TabPanel;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 28.05.2017.
*/
public class MainFrame extends JFrame {
private AbstractPresenter presenter;
private Boolean lmsIsComplete = false;
private Boolean rmIsComplete = false;
private Boolean tsIsComplete = false;
private JButton arrangementButton;
private JButton importButton;
private JButton generateButton;
private JButton exportButton;
private InfoPanel output;
private MenuBar menu;
private JToolBar toolBar;
private TabPanel lmsPanel;
private TabPanel rmPanel;
private TabPanel tsPanel;
private DualityPanel arrangement;
private JDialog arrangementDialog;
private PlotPanel plotLMS;
private PlotPanel plotRM;
private PlotPanel plotTS;
private JDialog progressDialog;
private JDialog evaluationDialog;
private Container progressContent;
private JProgressBar progressBar;
private JSplitPane splitpane;
private JScrollPane scrollPane;
private JTabbedPane tabbedPane;
private EvaluationPanel evaluationPanel;
public MainFrame() {
super();
initializeComponents();
setDimensions();
setLayouts();
setTitles();
addComponents();
setCloseOperations();
setIcons();
disableFunctionality();
this.setVisible(true);
}
/*******************************************************************************************************************
* visualisierungs methoden
******************************************************************************************************************/
public void createDualityDialog() {
arrangement = new DualityPanel();
arrangementDialog = new JDialog();
arrangementDialog.setTitle("Dualraum - Dialog");
arrangementDialog.setMinimumSize(new Dimension(1024, 768));
arrangementDialog.setPreferredSize(new Dimension(800, 800));
arrangementDialog.setLocationRelativeTo(this);
arrangementDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
arrangementButton.addActionListener(new DualityVisualizerListener((Presenter) getPresenter()));
arrangement.clear();
arrangement.setPrameters(getPresenter().getModel().getLines(),
getPresenter().getModel().getNodes(),
getPresenter().getModel().getxMinimum(),
getPresenter().getModel().getxMaximum(),
getPresenter().getModel().getyMinimum(),
getPresenter().getModel().getyMaximum());
arrangement.createArrangement();
SwingUtilities.invokeLater(() -> {
arrangementDialog.add(arrangement);
arrangementDialog.setLocationRelativeTo(this);
arrangementDialog.revalidate();
arrangementDialog.repaint();
arrangementDialog.setVisible(true);
});
}
public void visualizeLMS(double m, double b) {
plotLMS = new PlotPanel();
lmsPanel.setPlotPanel(plotLMS);
createPlot(m, b, plotLMS, lmsPanel, "LMS");
}
public void visualizeRM(double m, double b) {
plotRM = new PlotPanel();
rmPanel.setPlotPanel(plotRM);
createPlot(m, b, plotRM, rmPanel, "RM");
}
public void visualizeTS(double m, double b) {
plotTS = new PlotPanel();
tsPanel.setPlotPanel(plotTS);
createPlot(m, b, plotTS, tsPanel, "TS");
}
public void createPlot(double m, double b, PlotPanel plot, JPanel panel, String name) {
SwingUtilities.invokeLater(() -> {
plot.clear();
plot.createPlot(getPresenter().getModel().getLines());
plot.addLineToPlot(m, b, name);
panel.revalidate();
});
}
public void showImportProgress(Integer progress) {
progressBar.setValue(progress);
progressBar.setStringPainted(true);
progressDialog.setVisible(true);
}
public void showEvauluationDialog() {
if (evaluationDialog == null) {
SwingUtilities.invokeLater(() -> {
evaluationDialog = new JDialog();
evaluationDialog.setTitle("evaluation");
evaluationDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
evaluationDialog.setSize(new Dimension(1800, 800));
evaluationDialog.setLocationRelativeTo(null);
evaluationPanel = new EvaluationPanel(this);
evaluationDialog.setLocationRelativeTo(this);
evaluationDialog.add(evaluationPanel);
evaluationDialog.setVisible(true);
});
} else {
SwingUtilities.invokeLater(() -> {
evaluationDialog.setLocationRelativeTo(this);
evaluationDialog.setVisible(true);
});
}
}
public void appendEvalResult(Object[] res, int col, boolean isApprCol) {
SwingUtilities.invokeLater(() -> {
Object[] tmp = Arrays.asList(res).subList(2, res.length).toArray();
if (isApprCol) {
evaluationPanel.setCurrentRow(tmp.length);
evaluationPanel.addColumn(tmp, col, true);
} else {
evaluationPanel.addColumn(tmp, col + 1, false);
}
evaluationPanel.repaint();
evaluationPanel.revalidate();
});
}
public void appendEvalResult(Object[] res) {
SwingUtilities.invokeLater(() -> {
Object[] tmp = Arrays.asList(res).subList(1, res.length).toArray();
evaluationPanel.addRow(tmp);
evaluationPanel.repaint();
evaluationPanel.revalidate();
});
}
public void drawLineResult(Object[] res, int alg) {
SwingUtilities.invokeLater(() -> {
Object[] result = Arrays.asList(res).subList(2, res.length).toArray();
evaluationPanel.drawLines(result, alg);
evaluationPanel.repaint();
evaluationPanel.revalidate();
});
}
public void drawLineResults(Object[] res) {
SwingUtilities.invokeLater(() -> {
Object[] result = Arrays.asList(res).subList(1, res.length).toArray();
ArrayList<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();
});
}
public void addEvalDataset(LinkedList<Line> lines) {
SwingUtilities.invokeLater(() -> {
evaluationPanel.setDualPoints(lines);
evaluationPanel.repaint();
evaluationPanel.revalidate();
});
}
/*******************************************************************************************************************
* init GUI
******************************************************************************************************************/
private void setTitles() {
this.setTitle("Algorithmen zur Berechnung von Ausgleichgeraden");
importButton.setText("Import");
exportButton.setText("Export");
generateButton.setText("Generiere");
arrangementButton.setText("Dualraum");
}
private void setupTabbedPane() {
tabbedPane.add("Least Median of Squares", lmsPanel);
tabbedPane.add("Repeated Median", rmPanel);
tabbedPane.add("Theil-Sen", tsPanel);
}
private void addComponents() {
toolBar.add(arrangementButton);
toolBar.add(importButton);
toolBar.add(exportButton);
toolBar.add(generateButton);
toolBar.setFloatable(false);
setJMenuBar(menu.getMenuBar());
add(toolBar);
//northPanel.add(toolBar);
setupSplitPane();
setupTabbedPane();
progressContent.add(progressBar, BorderLayout.CENTER);
progressBar.setBorder(BorderFactory.createTitledBorder("Import..."));
progressDialog.setLocationRelativeTo(null);
((JPanel) progressDialog.getContentPane()).setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY));
this.add(toolBar, BorderLayout.NORTH);
this.add(splitpane, BorderLayout.CENTER);
}
private void setupSplitPane() {
splitpane.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
splitpane.setResizeWeight(.5d);
splitpane.setContinuousLayout(true);
splitpane.setLeftComponent(output);
splitpane.setRightComponent(tabbedPane);
}
private void setCloseOperations() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
progressDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
}
private void setDimensions() {
this.setExtendedState(JFrame.MAXIMIZED_BOTH);
this.setMinimumSize(new Dimension(1024,768));
this.setResizable(true);
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
this.setMaximizedBounds(env.getMaximumWindowBounds());
lmsPanel.setMinimumSize(new Dimension(400, 500));
rmPanel.setMinimumSize(new Dimension(400, 500));
tsPanel.setMinimumSize(new Dimension(400, 500));
output.setMinimumSize(new Dimension(400, 500));
progressDialog.setSize(300, 45);
progressDialog.setResizable(false);
progressDialog.setUndecorated(true);
}
private void setLayouts() {
this.setLayout(new BorderLayout());
toolBar.setLayout(new FlowLayout(FlowLayout.LEFT));
}
private void initializeComponents() {
//panels
toolBar = new JToolBar();
lmsPanel = new LMSPanel();
rmPanel = new RMPanel();
tsPanel = new TSPanel();
menu = new MenuBar(this);
//Dialogs
progressDialog = new JDialog();
progressDialog.setLocationRelativeTo(null);
progressContent = progressDialog.getContentPane();
progressBar = new JProgressBar();
//Panes
tabbedPane = new JTabbedPane();
output = new InfoPanel();
splitpane = new JSplitPane();
//Buttons
arrangementButton = new JButton();
importButton = new JButton();
generateButton = new JButton();
exportButton = new JButton();
}
private void setIcons() {
try {
ClassLoader classLoader = getClass().getClassLoader();
Image imgImport = ImageIO.read(classLoader.getResource("import.png")).getScaledInstance(16, 16, Image.SCALE_SMOOTH);
Image imgPlot = ImageIO.read(classLoader.getResource("plot.png")).getScaledInstance(16, 16, Image.SCALE_SMOOTH);
Image imgStart = ImageIO.read(classLoader.getResource("start.png")).getScaledInstance(32, 32, Image.SCALE_SMOOTH);
Image imgGenerate = ImageIO.read(classLoader.getResource("generate.png")).getScaledInstance(16, 16, Image.SCALE_SMOOTH);
Image imgExport = ImageIO.read(classLoader.getResource("export.png")).getScaledInstance(16, 16, Image.SCALE_SMOOTH);
Image imgFrame = ImageIO.read(classLoader.getResource("frame.png")).getScaledInstance(32, 23, Image.SCALE_SMOOTH);
importButton.setIcon(new ImageIcon(imgImport));
exportButton.setIcon(new ImageIcon(imgExport));
generateButton.setIcon(new ImageIcon(imgGenerate));
arrangementButton.setIcon(new ImageIcon(imgPlot));
lmsPanel.getStartButton().setIcon(new ImageIcon(imgStart));
rmPanel.getStartButton().setIcon(new ImageIcon(imgStart));
tsPanel.getStartButton().setIcon(new ImageIcon(imgStart));
this.setIconImage(imgFrame);
} catch (IOException e) {
e.printStackTrace();
}
}
public void setActionListeners() {
//action listener für MenuItems
menu.addActionListeners();
//action listener für diese Klasse
arrangementButton.addActionListener(new DualityVisualizerListener((Presenter) getPresenter()));
lmsPanel.getStartButton().addActionListener(new StartAlgorithmListener(((Presenter) getPresenter()), lmsPanel));
rmPanel.getStartButton().addActionListener(new StartAlgorithmListener(((Presenter) getPresenter()), rmPanel));
tsPanel.getStartButton().addActionListener(new StartAlgorithmListener(((Presenter) getPresenter()), tsPanel));
importButton.addActionListener(new ImportDataListener((Presenter) this.getPresenter() , this));
exportButton.addActionListener(new ExportDataListener((Presenter) this.getPresenter() , this));
generateButton.addActionListener(new GenerateDataListener((Presenter) this.getPresenter()));
}
public void enableFunctionality() {
this.getLmsPanel().getStartButton().setEnabled(true);
this.getRmPanel().getStartButton().setEnabled(true);
this.getTsPanel().getStartButton().setEnabled(true);
this.getArrangementButton().setEnabled(true);
this.getExportButton().setEnabled(true);
}
public void disableFunctionality() {
this.getLmsPanel().getStartButton().setEnabled(false);
this.getRmPanel().getStartButton().setEnabled(false);
this.getTsPanel().getStartButton().setEnabled(false);
this.getArrangementButton().setEnabled(false);
this.getExportButton().setEnabled(false);
}
/*******************************************************************************************************************
* log Methode
******************************************************************************************************************/
public void log(String s) {
SwingUtilities.invokeLater(() -> output.appendParagraph(s));
}
public void logError(String s) {
SwingUtilities.invokeLater(() -> output.appendParagraphRed(s));
}
public void logSuccess(String s) {
SwingUtilities.invokeLater(() -> output.appendParagraphGreen(s));
}
public void logHeading(String s) {
SwingUtilities.invokeLater(() -> output.appendParagraphWithHeading(s));
}
public void createTable(List<String> heading, List<List<String>> rows) {
SwingUtilities.invokeLater(() -> output.logTable(heading, rows));
}
/*******************************************************************************************************************
* Getter und Setter Methoden
******************************************************************************************************************/
public Boolean getLmsIsComplete() {
return lmsIsComplete;
}
public void setLmsIsComplete(Boolean lmsIsComplete) {
this.lmsIsComplete = lmsIsComplete;
}
public Boolean getRmIsComplete() {
return rmIsComplete;
}
public void setRmIsComplete(Boolean rmIsComplete) {
this.rmIsComplete = rmIsComplete;
}
public Boolean getTsIsComplete() {
return tsIsComplete;
}
public void setTsIsComplete(Boolean tsIsComplete) {
this.tsIsComplete = tsIsComplete;
}
public JButton getArrangementButton() {
return arrangementButton;
}
public void setArrangementButton(JButton arrangementButton) {
this.arrangementButton = arrangementButton;
}
public JButton getImportButton() {
return importButton;
}
public void setImportButton(JButton importButton) {
this.importButton = importButton;
}
public JToolBar getToolBar() {
return toolBar;
}
public void setToolBar(JToolBar toolBar) {
this.toolBar = toolBar;
}
public JDialog getArrangementDialog() {
return arrangementDialog;
}
public void setArrangementDialog(JDialog arrangementDialog) {
this.arrangementDialog = arrangementDialog;
}
public InfoPanel getOutput() {
return output;
}
public void setOutput(InfoPanel output) {
this.output = output;
}
public MenuBar getMenu() {
return menu;
}
public TabPanel getLmsPanel() {
return lmsPanel;
}
public JSplitPane getSplitpane() {
return splitpane;
}
public void setSplitpane(JSplitPane splitpane) {
this.splitpane = splitpane;
}
public JScrollPane getScrollPane() {
return scrollPane;
}
public void setScrollPane(JScrollPane scrollPane) {
this.scrollPane = scrollPane;
}
public TabPanel getRmPanel() {
return rmPanel;
}
public void setRmPanel(TabPanel rmPanel) {
this.rmPanel = rmPanel;
}
public PlotPanel getPlotLMS() {
return plotLMS;
}
public void setPlotLMS(PlotPanel plotLMS) {
this.plotLMS = plotLMS;
}
public AbstractPresenter getPresenter() {
return presenter;
}
public void setPresenter(AbstractPresenter presenter) {
this.presenter = presenter;
}
public JDialog getProgressDialog() {
return progressDialog;
}
public void setProgressDialog(JDialog progressDialog) {
this.progressDialog = progressDialog;
}
public TabPanel getTsPanel() {
return tsPanel;
}
public void setTsPanel(TabPanel tsPanel) {
this.tsPanel = tsPanel;
}
public JButton getExportButton() {
return exportButton;
}
public void setExportButton(JButton exportButton) {
this.exportButton = exportButton;
}
}

View File

@ -0,0 +1,87 @@
package view;
import presenter.Presenter;
import view.MainFrame;
import view.listener.ExportDataListener;
import view.listener.GenerateDataListener;
import view.listener.ImportDataListener;
import view.panels.AboutPanel;
import javax.swing.*;
import java.awt.*;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 29.05.2017.
*/
public class MenuBar {
private MainFrame view;
private JMenuBar menuBar;
private JMenu fileMenu;
private JMenu toolsMenu;
private JMenu aboutMenu;
private JMenuItem exitItem;
private JMenuItem importItem;
private JMenuItem exportItem;
private JMenuItem generateItem;
private JMenuItem evaluateItem;
private JMenuItem aboutItem;
public MenuBar(MainFrame view) {
this.menuBar = new JMenuBar();
this.view = view;
this.fileMenu = new JMenu("Datei");
this.toolsMenu = new JMenu("Extras");
this.aboutMenu = new JMenu("Info");
this.exitItem = new JMenuItem("Exit");
this.importItem = new JMenuItem("Import");
this.exportItem = new JMenuItem("Export");
this.generateItem = new JMenuItem("Generiere...");
this.aboutItem = new JMenuItem("Über das Programm");
this.evaluateItem = new JMenuItem("Evaluation");
fileMenu.add(exitItem);
fileMenu.add(importItem);
fileMenu.add(exportItem);
toolsMenu.add(generateItem);
toolsMenu.add(evaluateItem);
aboutMenu.add(aboutItem);
menuBar.add(fileMenu);
menuBar.add(toolsMenu);
menuBar.add(aboutMenu);
}
public void addActionListeners(){
this.exitItem.addActionListener(e -> {System.exit(0);});
this.evaluateItem.addActionListener(e -> {view.showEvauluationDialog();});
this.importItem.addActionListener(new ImportDataListener((Presenter) view.getPresenter(), view));
this.exportItem.addActionListener(new ExportDataListener((Presenter) view.getPresenter(), view));
this.generateItem.addActionListener(new GenerateDataListener((Presenter) view.getPresenter()));
this.aboutItem.addActionListener(e -> {
SwingUtilities.invokeLater(() -> {
JDialog dialog = new JDialog();
dialog.setSize(410,420);
dialog.setResizable(false);
dialog.add(new AboutPanel());
dialog.setVisible(true);
});
});
}
public JMenuBar getMenuBar() {
return menuBar;
}
}

View File

@ -0,0 +1,76 @@
package view.custom;
import javax.swing.*;
import java.util.HashSet;
import java.util.Set;
/**
* Source: <url>https://stackoverflow.com/questions/14892515/how-to-enforce-at-least-one-checkbox-in-a-group-is-selected</url>
* <p>
* A ButtonGroup for check-boxes enforcing that at least two remains selected.
* <p>
* When the group has exactly two buttons, deselecting the last selected one
* automatically selects the other.
* <p>
* When the group has more buttons, deselection of the last selected one is denied.
*/
public class ButtonGroupAtLeastTwo extends ButtonGroup {
private final Set<ButtonModel> selected = new HashSet<>();
@Override
public void setSelected(ButtonModel model, boolean b) {
if (b && !this.selected.contains(model)) {
select(model, true);
} else if (!b && this.selected.contains(model)) {
if (this.buttons.size() == 3 && this.selected.size() == 2) {
select(model, false);
AbstractButton otherOne = this.buttons.get(0).getModel() == model ?
this.buttons.get(1) : this.buttons.get(0);
AbstractButton otherTwo = this.buttons.get(1).getModel() == model ?
this.buttons.get(2) : this.buttons.get(1);
AbstractButton otherThree = this.buttons.get(2).getModel() == model ?
this.buttons.get(1) : this.buttons.get(2);
select(otherOne.getModel(), true);
select(otherTwo.getModel(), true);
select(otherThree.getModel(), true);
} else if (this.selected.size() > 2) {
this.selected.remove(model);
model.setSelected(false);
}
}
}
private void select(ButtonModel model, boolean b) {
if (b) {
this.selected.add(model);
} else {
this.selected.remove(model);
}
model.setSelected(b);
}
@Override
public boolean isSelected(ButtonModel m) {
return this.selected.contains(m);
}
public void addAll(AbstractButton... buttons) {
for (AbstractButton button : buttons) {
add(button);
}
}
@Override
public void add(AbstractButton button) {
if (button.isSelected()) {
this.selected.add(button.getModel());
}
super.add(button);
}
}

View File

@ -0,0 +1,35 @@
package view.custom;
import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import java.awt.*;
/**
* Source: <url> http://esus.com/creating-a-jtable-with-a-different-background-color-per-column/ </url>
* <p>
* Applied background and foreground color to single column of a JTable
* in order to distinguish it apart from other columns.
*/
public class ColorColumnRenderer extends DefaultTableCellRenderer {
Color bkgndColor, fgndColor;
public ColorColumnRenderer(Color bkgnd, Color foregnd) {
super();
bkgndColor = bkgnd;
fgndColor = foregnd;
}
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
Component cell = super.getTableCellRendererComponent
(table, value, isSelected, hasFocus, row, column);
cell.setBackground(bkgndColor);
cell.setForeground(fgndColor);
cell.setFont(new Font("SansSerif", Font.BOLD, 12));
this.setHorizontalAlignment(JLabel.CENTER);
return cell;
}
}

View File

@ -0,0 +1,30 @@
package view.listener;
import presenter.Presenter;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 10.09.2017.
*/
public class DualityVisualizerListener implements ActionListener {
private Presenter presenter;
public DualityVisualizerListener(Presenter presenter) {
this.presenter = presenter;
}
@Override
public void actionPerformed(ActionEvent e) {
SwingUtilities.invokeLater(() -> {
presenter.visualizeDualLines();
});
}
}

View File

@ -0,0 +1,52 @@
package view.listener;
import 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: 10.09.2017.
*/
public class ExportDataListener implements ActionListener {
private Presenter presenter;
private Container component;
public ExportDataListener(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("Comma-Separated Value", "csv", "text"));
chooser.setMultiSelectionEnabled(false);
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
if (chooser.showSaveDialog(component) == JFileChooser.APPROVE_OPTION) {
//System.out.println ("Datei "+chooser.getSelectedFile()+ " ausgewählt.");
file = chooser.getSelectedFile();
String filename = file.getAbsolutePath().contains(".csv") ? file.getAbsolutePath() : file.getAbsolutePath().concat(".csv");
File withExtension = new File(filename);
final File input = withExtension;
Thread t = new Thread(() -> presenter.startExport(input));
t.start();
}
});
}
}

View File

@ -0,0 +1,30 @@
package view.listener;
import presenter.Presenter;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 10.09.2017.
*/
public class GenerateDataListener implements ActionListener {
private Presenter presenter;
public GenerateDataListener(Presenter presenter) {
this.presenter = presenter;
}
@Override
public void actionPerformed(ActionEvent e) {
Thread t = new Thread(() -> presenter.generateDataset());
t.start();
}
}

View File

@ -0,0 +1,51 @@
package view.listener;
import 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: 10.09.2017.
*/
public class ImportDataListener implements ActionListener {
private Presenter presenter;
private Container component;
public ImportDataListener(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("Comma-Separated Value", "csv", "text"));
chooser.setMultiSelectionEnabled(false);
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
if (chooser.showOpenDialog(component) == JFileChooser.APPROVE_OPTION) {
//System.out.println ("Datei "+chooser.getSelectedFile()+ " ausgewählt.");
file = chooser.getSelectedFile();
final File input = file;
Thread t = new Thread(() -> presenter.startImport(input));
t.start();
}
});
}
}

View File

@ -0,0 +1,54 @@
package view.listener;
import presenter.Presenter;
import presenter.algorithms.Algorithm;
import presenter.algorithms.LeastMedianOfSquaresEstimator;
import view.panels.tabs.LMSPanel;
import view.panels.tabs.RMPanel;
import view.panels.tabs.TSPanel;
import view.panels.tabs.TabPanel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 10.09.2017.
*/
public class StartAlgorithmListener implements ActionListener {
private Presenter presenter;
private TabPanel tabPanel;
public StartAlgorithmListener(Presenter presenter, TabPanel tabPanel) {
this.presenter = presenter;
this.tabPanel = tabPanel;
}
@Override
public void actionPerformed(ActionEvent e) {
if (tabPanel instanceof LMSPanel){
if ( ((LMSPanel) tabPanel).getInput() != null) {
Thread t = new Thread(
() -> presenter.calculateLMS(((LMSPanel) tabPanel).getInput()));
t.start();
}
} else if (tabPanel instanceof RMPanel){
if ( ((RMPanel) tabPanel).getInput() != null) {
Thread t = new Thread(
() -> presenter.calculateRM(((RMPanel) tabPanel).getInput()));
t.start();
}
} else if(tabPanel instanceof TSPanel){
Thread t = new Thread(
() -> presenter.calculateTS(""));
t.start();
} else {
throw new IllegalArgumentException("Unknown Algortihm representation Panel!");
}
}
}

View File

@ -0,0 +1,45 @@
package view.panels;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.io.IOException;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 10.09.2017.
*/
public class AboutPanel extends JPanel {
private JTextArea textArea;
private JLabel imageContainer;
private JPanel contentPane;
private ImageIcon image;
public AboutPanel(){
super();
this.setSize(new Dimension(410,400));
this.setLayout(new BorderLayout());
contentPane = new JPanel(new BorderLayout());
this.textArea = new JTextArea();
this.textArea.setEditable(false);
this.textArea.setBackground(new Color(0,0,0,0));
contentPane.add(this.textArea, BorderLayout.CENTER);
ClassLoader classLoader = getClass().getClassLoader();
try {
image = new ImageIcon(ImageIO.read(classLoader.getResource("wwu.png")).getScaledInstance(300, 87, Image.SCALE_SMOOTH));
} catch (IOException e) {
e.printStackTrace();
}
this.imageContainer = new JLabel(image);
contentPane.add(imageContainer, BorderLayout.NORTH);
this.add(new JPanel(), BorderLayout.NORTH);
this.add(contentPane, BorderLayout.CENTER);
this.setVisible(true);
}
}

View File

@ -0,0 +1,233 @@
package view.panels;
import model.Line;
import model.Point;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.time.DateRange;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.util.ShapeUtilities;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.util.LinkedList;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 28.05.2017.
*/
public class DualityPanel extends JPanel {
private LinkedList<Line> lines;
private LinkedList<Point> points;
private JFreeChart chart;
private ChartPanel panel;
private XYSeriesCollection dataset;
private JScrollPane scrollPane;
private double domainMin, domainMax;
private double rangeMin, rangeMax;
private ValueAxis domain;
private ValueAxis range;
private Double delta = 1d;
private Boolean ctrlPressed = false;
private Boolean shiftPressed = false;
public DualityPanel() {
super();
this.setPreferredSize(new Dimension(800, 800));
this.setMinimumSize(new Dimension(800, 800));
this.setLayout(new BorderLayout());
}
public void setPrameters(LinkedList<Line> lines, LinkedList<Point> points, Double xmin, Double xmax, Double ymin, Double ymax) {
this.lines = new LinkedList<>(lines);
this.points = new LinkedList<>(points);
this.domainMin = xmin;
this.domainMax = xmax;
this.rangeMin = ymin;
this.rangeMax = ymax;
}
public void createArrangement() {
dataset = new XYSeriesCollection();
for (Line p : lines) {
XYSeries series = new XYSeries(p.getId() + "#" + p.getX1() + "---" + p.getY1());
series.add(p.getX1(), p.getY1());
series.add(p.getX2(), p.getY2());
dataset.addSeries(series);
}
XYSeries intersections = new XYSeries("intersections");
for (Point p : points) {
intersections.add(p.getX(), p.getY());
}
dataset.addSeries(intersections);
chart = ChartFactory.createXYLineChart(null, null, null, dataset,
PlotOrientation.HORIZONTAL, false, false, false);
chart.setRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON));
chart.setAntiAlias(true);
final XYPlot plot = chart.getXYPlot();
domain = plot.getDomainAxis();
range = plot.getRangeAxis();
domain.setRange(domainMin - 1, domainMax + 1);
range.setRange(rangeMin - 1, rangeMax + 1);
plot.setBackgroundPaint(Color.WHITE);
plot.setDomainGridlinePaint(Color.white);
plot.setRangeGridlinePaint(Color.white);
final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
renderer.setSeriesLinesVisible(dataset.indexOf(intersections), false);
plot.setRenderer(renderer);
for (int i = 0; i < lines.size(); i++) {
// Setze die Shapes für die Schnittpunkte
renderer.setSeriesPaint(i, Color.BLUE);
renderer.setBaseSeriesVisible(true);
}
Shape shape = ShapeUtilities.createDiagonalCross(4, 1);
renderer.setSeriesPaint(lines.size(), Color.BLACK);
renderer.setSeriesShape(lines.size(), shape);
panel = new ChartPanel(chart);
panel.setPreferredSize(new Dimension(800, 800));
addKeyListener(this);
addZooming(panel);
this.setFocusable(true);
JTextArea info = new JTextArea();
info.setText("Um in dem Plot hineinzuzoomen kann das Mausrad verwendett werden. \nUm sich anschließen vertikal bzw. horizontal zu bewegen kann die Kombination (Umschalt/Steuerung)\nund Mausrad verwendett werden.");
Font font = new Font("Serif", Font.ITALIC, 12);
info.setFont(font);
info.setForeground(Color.DARK_GRAY);
info.setEditable(false);
info.setWrapStyleWord(true);
this.add(info, BorderLayout.SOUTH);
this.add(panel, BorderLayout.CENTER);
}
public void addKeyListener(JComponent component) {
component.addKeyListener(new KeyListener() {
@Override
public void keyReleased(KeyEvent e) {
ctrlPressed = false;
shiftPressed = false;
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
if (e.isControlDown()) {
ctrlPressed = true;
}
if (e.isShiftDown()) {
shiftPressed = true;
}
}
});
}
protected void addZooming(ChartPanel chartPanel) {
chartPanel.addMouseWheelListener(new MouseWheelListener() {
public void mouseWheelMoved(MouseWheelEvent e) {
Double min;
Double max;
Double val = e.getPreciseWheelRotation() * -1;
if (ctrlPressed == true) {
//System.out.println("CTRL + ZOOM");
min = range.getLowerBound();
max = range.getUpperBound();
DateRange dateRangeX = move(val, min, max);
range.setRange(dateRangeX);
} else if (shiftPressed == true) {
//System.out.println("SHIFT + ZOOM");
min = domain.getLowerBound();
max = domain.getUpperBound();
DateRange dateRangeY = move(val, min, max);
domain.setRange(dateRangeY);
} else {
Double x = Double.valueOf(e.getY());
Double y = Double.valueOf(e.getY());
if (e.getScrollType() != MouseWheelEvent.WHEEL_UNIT_SCROLL)
return;
if (e.getWheelRotation() < 0)
increaseZoom((ChartPanel) e.getComponent(), true, x, y);
else
decreaseZoom((ChartPanel) e.getComponent(), true, x, y);
}
}
private DateRange move(Double val, Double min, Double max) {
Double minimum = min;
Double maximum = max;
delta = Math.abs(maximum - minimum) * 0.01 * val;
minimum = minimum + delta;
maximum = maximum + delta;
return new DateRange(minimum, maximum);
}
public synchronized void increaseZoom(JComponent chart, boolean saveAction, Double x, Double y) {
ChartPanel ch = (ChartPanel) chart;
zoomChartAxis(ch, true, x, y);
}
public synchronized void decreaseZoom(JComponent chart, boolean saveAction, Double x, Double y) {
ChartPanel ch = (ChartPanel) chart;
zoomChartAxis(ch, false, x, y);
}
private void zoomChartAxis(ChartPanel chartP, boolean increase, Double x, Double y) {
int width = chartP.getMaximumDrawWidth() - chartP.getMinimumDrawWidth();
int height = chartP.getMaximumDrawHeight() - chartP.getMinimumDrawWidth();
if (increase) {
chartP.zoomInBoth(width / 2, height / 2);
} else {
chartP.zoomOutBoth(width / 2, height / 2);
}
}
});
}
public void clear() {
if (dataset != null)
dataset.removeAllSeries();
}
}

View File

@ -1,31 +1,30 @@
package View.Panels;
package view.panels;
import Model.Line;
import View.MainFrame;
import model.Line;
import presenter.Presenter;
import view.MainFrame;
import view.custom.ButtonGroupAtLeastTwo;
import view.custom.ColorColumnRenderer;
import View.PlotDialog;
import View.custom.ButtonGroupAtLeastOne;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.filechooser.FileSystemView;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumn;
import java.awt.*;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import javax.swing.*;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import View.custom.ColorColumnRenderer;
/**
* Created by
* Armin Wolf
* on 02.08.17.
*/
public class EvaluationPanel extends JPanel{
public class EvaluationPanel extends JPanel {
private final MainFrame view;
private JTable table;
@ -38,11 +37,11 @@ public class EvaluationPanel extends JPanel{
private JRadioButton evalTypeTwo; //N: Alg - 1: Data
private ButtonGroup radiobuttonGroup;
private ButtonGroup checkboxGroup;
private ButtonGroupAtLeastOne checkboxAtLeastOne;
private ButtonGroupAtLeastTwo checkboxAtLeastOne;
private JCheckBox lms; //1: Alg - N: Data
private JCheckBox rm; //N: Alg - 1: Data
private JCheckBox ts; //1: Alg - N: Data
private JCheckBox lms; //1: Alg - N: Data
private JCheckBox rm; //N: Alg - 1: Data
private JCheckBox ts; //1: Alg - N: Data
private JPanel comp;
private JPanel algorithmPanel;
@ -57,10 +56,10 @@ public class EvaluationPanel extends JPanel{
private DefaultTableModel model;
private int currentRowOfTypes;
private JPanel buttonPanel;
private PlotDialog plotDialog;
private String[] selections = { "Approximationsgüte","Least Median of Squares","Repeated-Median","Theil-Sen"};
private PlotPanel plotPanel;
private String[] selections = {"Approximationsgüte", "Least Median of Squares", "Repeated-Median", "Theil-Sen"};
public EvaluationPanel(MainFrame view){
public EvaluationPanel(MainFrame view) {
super();
this.view = view;
this.setLayout(new BorderLayout());
@ -72,9 +71,9 @@ public class EvaluationPanel extends JPanel{
}
private void init(){
datasetCountLabel = new JLabel("Größe des Datensatzes");
Integer[] choice = {50,100,200,500,1000,1500};
private void init() {
datasetCountLabel = new JLabel("Größe des Datensatzes");
Integer[] choice = {50, 100, 200, 500, 1000, 1500};
datasetCountChoice = new JComboBox(choice);
String[] datatypes = {"Punktwolke", "Gerade", "Kreis und Gerade"};
datasetType = new JComboBox<>(datatypes);
@ -88,17 +87,17 @@ public class EvaluationPanel extends JPanel{
exportData.setEnabled(false);
evalTypeOne = new JRadioButton("Algorithmus evaluieren");
evalTypeTwo = new JRadioButton("Algorithmen vergleichen");
lms = new JCheckBox ("Least Median of Squares");
rm = new JCheckBox ("Repeated Median");
ts = new JCheckBox ("Theil-Sen");
lms = new JCheckBox("Least Median of Squares");
rm = new JCheckBox("Repeated Median");
ts = new JCheckBox("Theil-Sen");
radiobuttonGroup = new ButtonGroup();
checkboxGroup = new ButtonGroup();
checkboxAtLeastOne = new ButtonGroupAtLeastOne();
checkboxAtLeastOne = new ButtonGroupAtLeastTwo();
buttonPanel = new JPanel(new FlowLayout());
leftSidePanel = new JPanel(new BorderLayout());
comp = new JPanel(new GridLayout(0,1));
plotDialog = new PlotDialog();
model = new DefaultTableModel(){
comp = new JPanel(new GridLayout(0, 1));
plotPanel = new PlotPanel();
model = new DefaultTableModel() {
@Override
public boolean isCellEditable(int row, int column) {
//all cells false
@ -117,7 +116,7 @@ public class EvaluationPanel extends JPanel{
}
private void addComponents(){
private void addComponents() {
evalTypeOne.setSelected(true);
lms.setSelected(true);
checkboxGroup.add(lms);
@ -159,8 +158,8 @@ public class EvaluationPanel extends JPanel{
//Plot
plotDialog.createPlot(new LinkedList<>());
plotDialog.setBorder(new TitledBorder("Plot"));
plotPanel.createPlot(new LinkedList<>());
plotPanel.setBorder(new TitledBorder("Plot"));
leftSidePanel.add(comp, BorderLayout.NORTH);
leftSidePanel.add(scrollPane, BorderLayout.CENTER);
@ -170,7 +169,7 @@ public class EvaluationPanel extends JPanel{
splitPane.setResizeWeight(.5d);
splitPane.setContinuousLayout(true);
splitPane.setLeftComponent(leftSidePanel);
splitPane.setRightComponent(plotDialog);
splitPane.setRightComponent(plotPanel);
this.add(splitPane, BorderLayout.CENTER);
@ -180,12 +179,12 @@ public class EvaluationPanel extends JPanel{
tm.setCellRenderer(new ColorColumnRenderer(Color.lightGray, Color.blue));
}
private void addListener(){
private void addListener() {
start.addActionListener(e -> {
int type;
int alg;
int n;
if (radiobuttonGroup.isSelected(evalTypeOne.getModel())){
if (radiobuttonGroup.isSelected(evalTypeOne.getModel())) {
type = 0;
} else {
type = 1;
@ -193,7 +192,7 @@ public class EvaluationPanel extends JPanel{
alg = checkSelection();
n = (Integer) datasetCountChoice.getSelectedItem();
String datatyp = (String) datasetType.getSelectedItem();
view.getPresenter().startEvaluation(type,n,alg,datatyp);
((Presenter) view.getPresenter()).startEvaluation(type, n, alg, datatyp);
clearTable.setEnabled(true);
latexExport.setEnabled(true);
exportData.setEnabled(true);
@ -215,7 +214,7 @@ public class EvaluationPanel extends JPanel{
checkboxGroup.remove(rm);
checkboxGroup.remove(ts);
checkboxAtLeastOne.addAll(lms,rm,ts);
checkboxAtLeastOne.addAll(lms, rm, ts);
lms.setSelected(true);
rm.setSelected(true);
@ -224,30 +223,28 @@ public class EvaluationPanel extends JPanel{
latexExport.addActionListener(e -> {
SwingUtilities.invokeLater(() -> {
File file = null;
JFileChooser chooser = new JFileChooser();
chooser.setPreferredSize(new Dimension(800,700));
File workingDirectory = new File(System.getProperty("user.dir"));
chooser.setCurrentDirectory(workingDirectory);
JFileChooser chooser = new JFileChooser(FileSystemView.getFileSystemView().getHomeDirectory());
chooser.setPreferredSize(new Dimension(800, 700));
chooser.setFileFilter(new FileNameExtensionFilter("LaTeX-Datei", "tex", "text"));
chooser.setMultiSelectionEnabled(false);
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
if (chooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION){
if (chooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
//System.out.println ("Datei "+chooser.getSelectedFile()+ " ausgewählt.");
file = chooser.getSelectedFile();
String filename = file.getAbsolutePath().contains(".tex") ? file.getAbsolutePath() : file.getAbsolutePath().concat(".tex");
File withExtension = new File(filename);
final File input = withExtension;
view.getPresenter().startResultExport(model, input);
((Presenter) view.getPresenter()).startResultExport(model, input);
}
});
});
clearTable.addActionListener(e -> {
SwingUtilities.invokeLater(() ->{
SwingUtilities.invokeLater(() -> {
int n = model.getDataVector().size();
for (int i=0;i<n;i++){
for (int i = 0; i < n; i++) {
model.removeRow(0);
currentRowOfTypes--;
}
@ -261,29 +258,29 @@ public class EvaluationPanel extends JPanel{
exportData.addActionListener(e -> {
SwingUtilities.invokeLater(() -> {
JOptionPane.showMessageDialog(null, "Boooooooooooooooooooooooooooooooooooooooooooooooooooooo! :)");
JOptionPane.showMessageDialog(this, "Boooooooooooooooooooooooooooooooooooooooooooooooooooooo! :)");
});
});
}
public void addColumn(Object[] data, int col, boolean b){
if (b){
public void addColumn(Object[] data, int col, boolean b) {
if (b) {
addBlankRows(data.length);
}
for (int i=0;i<data.length;i++){
for (int i = 0; i < data.length; i++) {
int row = currentRowOfTypes - data.length + i;
model.setValueAt(data[i],row,col);
model.setValueAt(data[i], row, col);
}
this.repaint();
this.revalidate();
}
public void addRow(Object[] data){
public void addRow(Object[] data) {
addBlankRows(1);
for (int i=0;i<4;i++){
model.setValueAt(data[i],currentRowOfTypes,i);
for (int i = 0; i < 4; i++) {
model.setValueAt(data[i], currentRowOfTypes, i);
}
currentRowOfTypes++;
@ -291,63 +288,63 @@ public class EvaluationPanel extends JPanel{
this.revalidate();
}
public void drawLines(ArrayList<Double[]> alg){
public void drawLines(ArrayList<Double[]> alg) {
Paint[] color = {Color.ORANGE, Color.RED, Color.MAGENTA};
String[] name = {"LMS","RM", "TS"};
String[] name = {"LMS", "RM", "TS"};
for (Double[] o : alg){
Double m = o[1];
Double b = o[1];
int i = o[0].intValue();
plotDialog.addLineToPlot(m,b,color[i],name[i]);
for (Double[] o : alg) {
Double m = o[1];
Double b = o[1];
int i = o[0].intValue();
plotPanel.addLineToPlot(m, b, color[i], name[i]);
}
}
public void drawLines(Object[] results, int alg){
String[] castedResults = Arrays.copyOf(results, results.length, String[].class);
public void drawLines(Object[] results, int alg) {
String[] castedResults = Arrays.copyOf(results, results.length, String[].class);
Paint[] color = {Color.ORANGE, Color.RED, Color.MAGENTA};
String[] name = {"LMS","RM", "TS"};
String[] name = {"LMS", "RM", "TS"};
Double m = Double.parseDouble(castedResults[0]);
Double b = Double.parseDouble(castedResults[1]);
plotDialog.addLineToPlot(m,b,color[alg],name[alg]);
Double m = Double.parseDouble(castedResults[0]);
Double b = Double.parseDouble(castedResults[1]);
plotPanel.addLineToPlot(m, b, color[alg], name[alg]);
}
public void setDualPoints(LinkedList<Line> points){
plotDialog = new PlotDialog();
plotDialog.setBorder(new TitledBorder("Plot"));
splitPane.setRightComponent(plotDialog);
plotDialog.createPlot(points);
plotDialog.repaint();
plotDialog.revalidate();
public void setDualPoints(LinkedList<Line> points) {
plotPanel = new PlotPanel();
plotPanel.setBorder(new TitledBorder("Plot"));
splitPane.setRightComponent(plotPanel);
plotPanel.createPlot(points);
plotPanel.repaint();
plotPanel.revalidate();
}
private void addBlankRows(int n){
for (int i=0;i<n;i++){
String[] tmp = {"","","","",};
private void addBlankRows(int n) {
for (int i = 0; i < n; i++) {
String[] tmp = {"", "", "", "",};
model.addRow(tmp);
}
}
public void setCurrentRow(int val){
public void setCurrentRow(int val) {
this.currentRowOfTypes += val;
}
private int checkSelection(){
if (lms.isSelected() && rm.isSelected() && ts.isSelected()){
private int checkSelection() {
if (lms.isSelected() && rm.isSelected() && ts.isSelected()) {
return 6;
} else if (!lms.isSelected() && rm.isSelected() && ts.isSelected()){
} else if (!lms.isSelected() && rm.isSelected() && ts.isSelected()) {
return 5;
} else if (lms.isSelected() && !rm.isSelected() && ts.isSelected()){
} else if (lms.isSelected() && !rm.isSelected() && ts.isSelected()) {
return 4;
} else if (lms.isSelected() && rm.isSelected() && !ts.isSelected()){
} else if (lms.isSelected() && rm.isSelected() && !ts.isSelected()) {
return 3;
} else if (!lms.isSelected() && !rm.isSelected() && ts.isSelected()){
} else if (!lms.isSelected() && !rm.isSelected() && ts.isSelected()) {
return 2;
} else if (!lms.isSelected() && rm.isSelected() && !ts.isSelected()){
} else if (!lms.isSelected() && rm.isSelected() && !ts.isSelected()) {
return 1;
} else if (lms.isSelected() && !rm.isSelected() && !ts.isSelected()){
} else if (lms.isSelected() && !rm.isSelected() && !ts.isSelected()) {
return 0;
} else {
throw new IllegalStateException("Mindestens ein Algortihmus muss selektiert werden");

View File

@ -0,0 +1,91 @@
package view.panels;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import java.awt.*;
import java.util.List;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 02.06.2017.
*/
public class InfoPanel extends JPanel {
private JTextPane output;
private JScrollPane scrollPane;
private StringBuilder content;
public InfoPanel() {
this.setBorder(new TitledBorder("Ausgabekanal"));
this.setLayout(new BorderLayout());
output = new JTextPane();
output.setEditable(false);
output.setContentType("text/html");
content = new StringBuilder();
scrollPane = new JScrollPane(output);
scrollPane.setWheelScrollingEnabled(true);
this.add(scrollPane, BorderLayout.CENTER);
}
public void appendParagraph(String p) {
content.append("<p>" + p + "</p>");
output.setText(content.toString());
}
public void appendParagraphWithHeading(String h1) {
content.append("<h1>" + h1 + "</h1>");
output.setText(content.toString());
}
public void appendParagraphRed(String p) {
content.append("<p style=\" color:red \"><em><strong>" + p + "</strong></em></p>");
output.setText(content.toString());
}
public void appendParagraphGreen(String p) {
content.append("<p style=\" color:green \"><em><strong>" + p + "</strong></em></p>");
output.setText(content.toString());
}
public void logTable(List<String> heading, List<List<String>> rows) {
content.append("<center>");
content.append("<table style=\" width:80%; border: 1px solid black; \">");
content.append("<tr>");
if (heading.size() > 1) {
for (String str : heading) {
content.append("<th style=\" border: 1px solid black; \">" + str + "</th>");
}
} else {
content.append("<th style=\" border: 1px solid black;\" colspan=\"" + rows.get(0).size() + "\"; >" + heading.get(0) + "</th>");
}
content.append("</tr>");
for (List<String> row : rows) {
content.append("<tr>");
for (String entry : row) {
content.append("<td style=\" border: 1px solid black; \">" + entry + "</td>");
}
content.append("</tr>");
}
content.append("</table>");
content.append("</center>");
output.setText(content.toString());
}
}

View File

@ -0,0 +1,142 @@
package view.panels;
import model.Line;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.util.ShapeUtilities;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.LinkedList;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 29.05.2017.
*/
public class PlotPanel extends JPanel {
private JFreeChart chart;
private ChartPanel panel;
private XYSeriesCollection datapoints;
private XYSeries series;
private Double min;
private Double max;
private XYPlot xyPlot;
private int seriesCount;
private XYLineAndShapeRenderer renderer;
private Shape diamond;
public PlotPanel() {
super();
this.setLayout(new BorderLayout());
seriesCount = 1;
}
public void createPlot(LinkedList<Line> points) {
if (!points.isEmpty()) {
try {
Thread thread = new Thread(() -> convertData(points));
thread.start();
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//createScatterPlot
chart = ChartFactory.createXYLineChart("",
"X", "Y", datapoints, PlotOrientation.VERTICAL, true, true, false);
diamond = ShapeUtilities.createDiamond(2f);
chart.setBorderVisible(false);
chart.setAntiAlias(true);
chart.getPlot().setBackgroundPaint(Color.WHITE);
chart.setBorderVisible(false);
xyPlot = (XYPlot) chart.getPlot();
xyPlot.setDomainCrosshairVisible(true);
xyPlot.setRangeCrosshairVisible(true);
renderer = (XYLineAndShapeRenderer) xyPlot.getRenderer();
renderer.setSeriesLinesVisible(0, false);
renderer.setSeriesShapesVisible(0, true);
renderer.setSeriesLinesVisible(1, true);
renderer.setSeriesLinesVisible(1, true);
renderer.setSeriesPaint(0, Color.blue);
renderer.setSeriesShape(0, diamond);
renderer.setBaseSeriesVisible(true);
xyPlot.setDomainCrosshairVisible(true);
xyPlot.setRangeCrosshairVisible(true);
panel = new ChartPanel(chart);
panel.setMouseZoomable(false);
this.add(panel, BorderLayout.CENTER);
}
public void clear() {
if (datapoints != null)
datapoints.removeAllSeries();
}
public void addLineToPlot(double m, double b, Paint color, String name) {
XYSeries linesA = new XYSeries(name);
linesA.add(min.doubleValue(), min * m + b);
linesA.add(max.doubleValue(), max * m + b);
datapoints.addSeries(linesA);
renderer.setSeriesPaint(seriesCount, color);
renderer.setSeriesStroke(seriesCount, new BasicStroke(2.0f));
renderer.setBaseSeriesVisible(true);
renderer.setSeriesLinesVisible(seriesCount, true);
seriesCount++;
}
public void addLineToPlot(double m, double b, String name) {
XYSeries linesA = new XYSeries(name);
linesA.add(min.doubleValue(), min * m + b);
linesA.add(max.doubleValue(), max * m + b);
datapoints.addSeries(linesA);
seriesCount = xyPlot.getSeriesCount();
renderer.setSeriesPaint(seriesCount, Color.red);
renderer.setSeriesStroke(seriesCount, new BasicStroke(2.0f));
renderer.setBaseSeriesVisible(true);
renderer.setSeriesLinesVisible(seriesCount, true);
}
private void convertData(LinkedList<Line> points) {
datapoints = new XYSeriesCollection();
ArrayList<Double> coordinates = new ArrayList<>();
series = new XYSeries("points");
for (Line p : points) {
series.add(p.getM().doubleValue(), p.getB().doubleValue() * (-1));
coordinates.add(p.getM());
}
this.max = series.getMaxX();
this.min = series.getMinX();
datapoints.addSeries(series);
}
}

View File

@ -0,0 +1,109 @@
package view.panels.tabs;
import com.sun.istack.internal.Nullable;
import view.panels.PlotPanel;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import java.awt.*;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 02.06.2017.
*/
public class LMSPanel extends TabPanel {
private JLabel[] labels;
private JTextField[] input;
private JPanel continer;
private GridBagConstraints gbc;
public LMSPanel() {
super();
this.labels = new JLabel[2];
this.input = new JTextField[2];
this.continer = new JPanel();
this.continer.setLayout(new GridBagLayout());
this.gbc = new GridBagConstraints();
this.gbc.anchor = GridBagConstraints.NORTH;
this.gbc.fill = GridBagConstraints.HORIZONTAL;
addTextfieldAndInput(0, "Konstante", 0.5);
addTextfieldAndInput(1, "Fehler", 0.05);
addButton(2, getStartButton());
getNorthPanel().add(continer, BorderLayout.CENTER);
this.add(getNorthPanel(), BorderLayout.NORTH);
this.add(getCenterPanel(), BorderLayout.CENTER);
}
@Override
protected void addTextfieldAndInput(int row, String name, Double value) {
this.labels[row] = new JLabel(name);
this.labels[row].setFont(new Font("SansSerif", Font.PLAIN, 12));
this.input[row] = new JTextField();
this.input[row].setText("" + value);
gbc.insets = new Insets(0, 5, 0, 0);
gbc.gridx = 0;
gbc.gridy = row;
gbc.weightx = 0.05;
gbc.weighty = 0.05;
continer.add(this.labels[row], gbc);
gbc.gridx = 1;
gbc.gridy = row;
gbc.weightx = 0.9;
gbc.weighty = 0.05;
gbc.insets = new Insets(0, 0, 0, 5);
continer.add(this.input[row], gbc);
}
private void addButton(int row, JButton button) {
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
gbc.insets = new Insets(30, 0, 5, 0);
gbc.gridx = 0;
gbc.gridy = row;
gbc.weightx = 0.05;
gbc.weighty = 0.05;
gbc.gridwidth = 1;
buttonPanel.add(button);
continer.add(buttonPanel, gbc);
}
@Nullable
public String[] getInput() {
String[] input = new String[3];
input[0] = this.input[0].getText();
input[1] = this.input[1].getText();
if (isNumeric(input[0]) && isNumeric(input[1])) {
return input;
} else {
JOptionPane.showMessageDialog(this, "Bitte geben Sie numerische Werte als Parameter an.", "Fehler bei der Eingabe", JOptionPane.ERROR_MESSAGE);
return null;
}
}
public boolean isNumeric(String str) {
try {
double d = Double.parseDouble(str);
} catch (NumberFormatException nfe) {
return false;
}
return true;
}
}

View File

@ -0,0 +1,104 @@
package view.panels.tabs;
import com.sun.istack.internal.Nullable;
import view.panels.PlotPanel;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import java.awt.*;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 21.06.2017.
*/
public class RMPanel extends TabPanel {
private JLabel labels;
private JTextField input;
private JPanel continer;
private GridBagConstraints gbc;
public RMPanel() {
super();
this.labels = new JLabel();
this.input = new JTextField();
this.setLayout(new BorderLayout());
this.continer = new JPanel();
this.continer.setLayout(new GridBagLayout());
this.gbc = new GridBagConstraints();
this.gbc.anchor = GridBagConstraints.NORTH;
this.gbc.fill = GridBagConstraints.HORIZONTAL;
addTextfieldAndInput(0, "\u00df (0 < \u00df < 1)", 0.5);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
gbc.insets = new Insets(30, 0, 10, 0);
gbc.gridx = 0;
gbc.gridy = 2;
gbc.weightx = 0.05;
gbc.weighty = 0.05;
buttonPanel.add(getStartButton());
continer.add(buttonPanel, gbc);
getNorthPanel().add(continer, BorderLayout.CENTER);
this.add(getNorthPanel(), BorderLayout.NORTH);
this.add(getCenterPanel(), BorderLayout.CENTER);
}
@Override
protected void addTextfieldAndInput(int row, String name, Double value) {
this.labels = new JLabel(name);
this.labels.setFont(new Font("SansSerif", Font.PLAIN, 13));
this.input = new JTextField();
this.input.setText("" + value);
gbc.insets = new Insets(0, 5, 0, 0);
gbc.gridx = 0;
gbc.gridy = row;
gbc.weightx = 0.05;
gbc.weighty = 0.05;
continer.add(this.labels, gbc);
gbc.gridx = 1;
gbc.gridy = row;
gbc.weightx = 0.9;
gbc.weighty = 0.05;
gbc.insets = new Insets(0, 0, 0, 5);
continer.add(this.input, gbc);
}
@Nullable
public String getInput() {
String input = "";
input = this.input.getText();
if (isNumeric(input))
return input;
else
JOptionPane.showMessageDialog(this, "Bitte geben Sie numerische Werte als Parameter an.", "Fehler bei der Eingabe", JOptionPane.ERROR_MESSAGE);
return null;
}
public void setInput(JTextField input) {
this.input = input;
}
public boolean isNumeric(String str) {
try {
double d = Double.parseDouble(str);
} catch (NumberFormatException nfe) {
return false;
}
return true;
}
}

View File

@ -0,0 +1,47 @@
package view.panels.tabs;
import com.sun.istack.internal.Nullable;
import view.panels.PlotPanel;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import java.awt.*;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 26.06.2017.
*/
public class TSPanel extends TabPanel {
private JPanel continer;
private GridBagConstraints gbc;
public TSPanel() {
super();
this.continer = new JPanel();
this.continer.setLayout(new GridBagLayout());
this.gbc = new GridBagConstraints();
this.gbc.anchor = GridBagConstraints.NORTH;
this.gbc.fill = GridBagConstraints.HORIZONTAL;
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
gbc.insets = new Insets(10, 0, 10, 0);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 0.05;
gbc.weighty = 0.05;
buttonPanel.add(getStartButton());
continer.add(buttonPanel, gbc);
getNorthPanel().add(continer, BorderLayout.CENTER);
this.add(getNorthPanel(), BorderLayout.NORTH);
}
}

View File

@ -0,0 +1,86 @@
package view.panels.tabs;
import view.panels.PlotPanel;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import java.awt.*;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 10.09.2017.
*/
public abstract class TabPanel extends JPanel{
private PlotPanel plotPanel;
private JPanel northPanel;
private JPanel centerPanel;
private JButton startButton;
public TabPanel() {
super();
this.centerPanel = new JPanel(new BorderLayout());
this.centerPanel.setBorder(new TitledBorder("Visualisierung"));
this.setLayout(new BorderLayout());
this.northPanel = new JPanel(new BorderLayout());
this.centerPanel = new JPanel(new BorderLayout());
this.northPanel.setBorder(new TitledBorder("Konfiguration"));
this.centerPanel.setBorder(new TitledBorder("Visualisierung"));
this.add(centerPanel, BorderLayout.CENTER);
this.add(northPanel, BorderLayout.NORTH);
this.startButton = new JButton("Start");
this.startButton.setFont(new Font("Verdana", Font.PLAIN, 16));
}
public void setPlotPanel(PlotPanel plotPanel) {
this.plotPanel = plotPanel;
if (this.centerPanel.getComponents().length > 0)
this.centerPanel.remove(0);
this.centerPanel.add(plotPanel, BorderLayout.CENTER);
this.plotPanel.setVisible(true);
this.repaint();
this.revalidate();
}
protected void addTextfieldAndInput(int row, String name, Double value){
//muss nicht obligatorisch implementiert werden
}
public PlotPanel getPlotPanel() {
return plotPanel;
}
public JButton getStartButton() {
return startButton;
}
public void setStartButton(JButton startButton) {
this.startButton = startButton;
}
public JPanel getNorthPanel() {
return northPanel;
}
public void setNorthPanel(JPanel northPanel) {
this.northPanel = northPanel;
}
public JPanel getCenterPanel() {
return centerPanel;
}
public void setCenterPanel(JPanel centerPanel) {
this.centerPanel = centerPanel;
}
}

Binary file not shown.

BIN
src/main/resources/wwu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -1,99 +0,0 @@
package Model;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import Model.DCEL.DoublyConnectedEdgeList;
import Model.DCEL.Edge;
import Model.DCEL.Face;
import Model.DCEL.Node;
import java.util.LinkedList;
import org.junit.Before;
import org.junit.Test;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 30.05.2017.
*/
public class DoublyConnectedEdgeListTest {
private static DoublyConnectedEdgeList dcel;
private static Node v1, v2, v3, v4, v5;
private static Edge e1, e2, e3, e4, e5;
private static Face f1, f2;
@Before
public void setUp() throws Exception {
dcel = new DoublyConnectedEdgeList();
//initialisiere die TestKnoten im Graphen
v1 = dcel.createNode(new Point(2.5, 7.5), "v1");
v2 = dcel.createNode(new Point(2.5, 4.0), "v2");
v3 = dcel.createNode(new Point(6.5, 3.5), "v3");
v4 = dcel.createNode(new Point(8.5, 6.5), "v4");
v5 = dcel.createNode(new Point(6.0, 8.0), "v5");
//initialisere Kanten im Graph
e1 = dcel.createEdge(v1, v5, "e1");
e2 = dcel.createEdge(v5, v4, "e2");
e3 = dcel.createEdge(v4, v3, "e3");
e4 = dcel.createEdge(v3, v2, "e4");
e5 = dcel.createEdge(v2, v1, "e5");
dcel.createConnection(e1, e2);
dcel.createConnection(e2, e3);
dcel.createConnection(e3, e4);
dcel.createConnection(e4, e5);
dcel.createConnection(e5, e1);
//intialisiere die Flaechen
f1 = dcel.createFace(null, e1, "f1");
f2 = dcel.createFace(e1.getTwin(), null, "f2");
}
@Test
public void testInnerComponentsAccess() {
System.out.println("Test: testInnerComponentAccess();");
Edge[] expected = {e1, e2, e3, e4, e5};
LinkedList<Edge> list = dcel.getEdgesOfInnerComponents(f1);
assertArrayEquals(expected, list.toArray());
}
@Test
public void testOuterComponentsAccess() {
System.out.println("Test: testOuterComponentAccess();");
String[] expected = {"#e1", "#e5", "#e4", "#e3", "#e2"};
LinkedList<Edge> list = dcel.getEdgesOfOuterComponents(f2);
for (int i = 0; i < list.size(); i++) {
assertEquals(expected[i], list.get(i).getID());
}
}
@Test
public void testNodeEdgeAccess() {
System.out.println("Test: testNodeEdgeAccess();");
assertEquals(5, dcel.getConnectedEdges(v4).size());
}
@Test
public void testDCELAccess() {
System.out.println("Test: testDCELAccess();");
assertEquals(e1, e1.getTwin().getTwin());
assertEquals(e1, e1.getPrev().getNext());
assertEquals(e2.getID(), e1.getTwin().getPrev().getTwin().getID());
assertEquals(e1, e1.getNext().getNext().getNext().getNext().getNext());
assertEquals(e1.getTwin(), e1.getTwin().getNext().getNext().getNext().getNext().getNext());
}
}

View File

@ -1,119 +0,0 @@
package Presenter.Algorithms;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import Model.Line;
import Model.Point;
import Model.Interval;
import java.util.ArrayList;
import java.util.LinkedList;
import org.junit.Before;
import org.junit.Test;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 12.06.2017.
*/
public class LeastMedianOfSquaresEstimatorTest {
private LeastMedianOfSquaresEstimator lms;
@Before
public void setUp() throws Exception {
Double[] x = {18d, 24d, 30d, 34d, 38d};
Double[] y = {18d, 26d, 30d, 40d, 70d};
LinkedList<Line> lines = new LinkedList<>();
LinkedList<Point> intersections = new LinkedList<>();
for (int i = 0; i < 5; i++) {
lines.add(new Line(x[i], y[i]));
}
lms = new LeastMedianOfSquaresEstimator(lines, intersections);
}
@Test
public void approximateLMS() throws Exception {
}
@Test
public void mergeSort() throws Exception {
// double[] umin = {6,3,4,1,2,5};
// double[] umax = {3,5,2,6,1,4};
double[] umin = {1, 2, 3, 4};
double[] umax = {2, 3, 4, 1};
ArrayList<Integer> a = new ArrayList<>();
ArrayList<Integer> b = new ArrayList<>();
for (double d : umin) {
a.add((int) d);
}
for (double d : umax) {
b.add((int) d);
}
IntersectionCounter invCounter = new IntersectionCounter();
int ret = invCounter.run(a, b);
assertEquals(3d, ret, 0.001);
}
@Test
public void geEjValues() throws Exception {
Double[] expected = {36d, 50d, 60d, 74d, 108d};
ArrayList<Double> actual = lms.getEjValues(1d);
assertArrayEquals(expected, actual.toArray());
}
@Test
public void calcKMinusBracelet() throws Exception {
Point point = new Point(1d, 1d);
Double[] expected = {24d, 36d, 60d};
Double[] actual = lms.calcKMinusBracelet(point, 3);
assertArrayEquals(expected, actual);
}
@Test
public void upperBound() throws Exception {
lms.setkMinus(3);
lms.setHeightsigmaMin(500);
lms.setSigmaMin(new Line(0, 0, 0, 0));
lms.setN(5);
Line expected = new Line(5, 5, 146, 210);
lms.upperBound(5d);
assertEquals(expected.getX1(), lms.getSigmaMin().getX1(), 0.01);
assertEquals(expected.getX2(), lms.getSigmaMin().getX2(), 0.01);
assertEquals(expected.getY1(), lms.getSigmaMin().getY1(), 0.01);
assertEquals(expected.getY2(), lms.getSigmaMin().getY2(), 0.01);
}
@Test
public void lowerBound() throws Exception {
//kann nur über sout geprüft werden test passt aber
Double[] expectedAlpha = {0d, 0d, 0d, 2d, 4d};
Double[] expectedBeta = {2d, 4d, 4d, 2d, 1d};
lms.setHeightsigmaMin(500);
Interval interval = new Interval(-2, 0);
lms.lowerBound(interval);
assertTrue(interval.getActivity());
}
}

View File

@ -1,27 +0,0 @@
package Presenter.ImportExport;
import org.junit.Before;
import org.junit.Test;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 21.06.2017.
*/
public class DataImporterTest {
private DataImporter importer;
@Before
public void setUp() throws Exception {
//importer = new DataImporter("C:\\Users\\Armin\\Desktop\\test.csv", null);
}
@Test
public void run() throws Exception {
//importer.run();
}
}

View File

@ -0,0 +1,100 @@
package model;
import model.DCEL.DoublyConnectedEdgeList;
import model.DCEL.Edge;
import model.DCEL.Face;
import model.DCEL.Node;
import org.junit.Before;
import org.junit.Test;
import java.util.LinkedList;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 30.05.2017.
*/
public class DoublyConnectedEdgeListTest {
private static DoublyConnectedEdgeList dcel;
private static Node v1, v2, v3, v4, v5;
private static Edge e1, e2, e3, e4, e5;
private static Face f1, f2;
@Before
public void setUp() throws Exception {
dcel = new DoublyConnectedEdgeList();
//initialisiere die TestKnoten im Graphen
v1 = dcel.createNode(new Point(2.5, 7.5), "v1");
v2 = dcel.createNode(new Point(2.5, 4.0), "v2");
v3 = dcel.createNode(new Point(6.5, 3.5), "v3");
v4 = dcel.createNode(new Point(8.5, 6.5), "v4");
v5 = dcel.createNode(new Point(6.0, 8.0), "v5");
//initialisere Kanten im Graph
e1 = dcel.createEdge(v1, v5, "e1");
e2 = dcel.createEdge(v5, v4, "e2");
e3 = dcel.createEdge(v4, v3, "e3");
e4 = dcel.createEdge(v3, v2, "e4");
e5 = dcel.createEdge(v2, v1, "e5");
dcel.createConnection(e1, e2);
dcel.createConnection(e2, e3);
dcel.createConnection(e3, e4);
dcel.createConnection(e4, e5);
dcel.createConnection(e5, e1);
//intialisiere die Flaechen
f1 = dcel.createFace(null, e1, "f1");
f2 = dcel.createFace(e1.getTwin(), null, "f2");
}
@Test
public void testInnerComponentsAccess() {
System.out.println("Test: testInnerComponentAccess();");
Edge[] expected = {e1, e2, e3, e4, e5};
LinkedList<Edge> list = dcel.getEdgesOfInnerComponents(f1);
assertArrayEquals(expected, list.toArray());
}
@Test
public void testOuterComponentsAccess() {
System.out.println("Test: testOuterComponentAccess();");
String[] expected = {"#e1", "#e5", "#e4", "#e3", "#e2"};
LinkedList<Edge> list = dcel.getEdgesOfOuterComponents(f2);
for (int i = 0; i < list.size(); i++) {
assertEquals(expected[i], list.get(i).getID());
}
}
@Test
public void testNodeEdgeAccess() {
System.out.println("Test: testNodeEdgeAccess();");
assertEquals(5, dcel.getConnectedEdges(v4).size());
}
@Test
public void testDCELAccess() {
System.out.println("Test: testDCELAccess();");
assertEquals(e1, e1.getTwin().getTwin());
assertEquals(e1, e1.getPrev().getNext());
assertEquals(e2.getID(), e1.getTwin().getPrev().getTwin().getID());
assertEquals(e1, e1.getNext().getNext().getNext().getNext().getNext());
assertEquals(e1.getTwin(), e1.getTwin().getNext().getNext().getNext().getNext().getNext());
}
}

View File

@ -0,0 +1,117 @@
package presenter.algorithms;
import model.Interval;
import model.Line;
import model.Point;
import org.junit.Before;
import org.junit.Test;
import java.util.ArrayList;
import java.util.LinkedList;
import static org.junit.Assert.*;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 12.06.2017.
*/
public class LeastMedianOfSquaresEstimatorTest {
private LeastMedianOfSquaresEstimator lms;
@Before
public void setUp() throws Exception {
Double[] x = {18d, 24d, 30d, 34d, 38d};
Double[] y = {18d, 26d, 30d, 40d, 70d};
LinkedList<Line> lines = new LinkedList<>();
LinkedList<Point> intersections = new LinkedList<>();
for (int i = 0; i < 5; i++) {
lines.add(new Line(x[i], y[i]));
}
lms = new LeastMedianOfSquaresEstimator(lines, intersections);
}
@Test
public void approximateLMS() throws Exception {
}
@Test
public void mergeSort() throws Exception {
// double[] umin = {6,3,4,1,2,5};
// double[] umax = {3,5,2,6,1,4};
double[] umin = {1, 2, 3, 4};
double[] umax = {2, 3, 4, 1};
ArrayList<Integer> a = new ArrayList<>();
ArrayList<Integer> b = new ArrayList<>();
for (double d : umin) {
a.add((int) d);
}
for (double d : umax) {
b.add((int) d);
}
IntersectionCounter invCounter = new IntersectionCounter();
int ret = invCounter.run(a, b);
assertEquals(3d, ret, 0.001);
}
@Test
public void geEjValues() throws Exception {
Double[] expected = {36d, 50d, 60d, 74d, 108d};
ArrayList<Double> actual = lms.getEjValues(1d);
assertArrayEquals(expected, actual.toArray());
}
@Test
public void calcKMinusBracelet() throws Exception {
Point point = new Point(1d, 1d);
Double[] expected = {24d, 36d, 60d};
Double[] actual = lms.calcKMinusBracelet(point, 3);
assertArrayEquals(expected, actual);
}
@Test
public void upperBound() throws Exception {
lms.setkMinus(3);
lms.setHeightsigmaMin(500);
lms.setSigmaMin(new Line(0, 0, 0, 0));
lms.setN(5);
Line expected = new Line(5, 5, 146, 210);
lms.upperBound(5d);
assertEquals(expected.getX1(), lms.getSigmaMin().getX1(), 0.01);
assertEquals(expected.getX2(), lms.getSigmaMin().getX2(), 0.01);
assertEquals(expected.getY1(), lms.getSigmaMin().getY1(), 0.01);
assertEquals(expected.getY2(), lms.getSigmaMin().getY2(), 0.01);
}
@Test
public void lowerBound() throws Exception {
//kann nur über sout geprüft werden test passt aber
Double[] expectedAlpha = {0d, 0d, 0d, 2d, 4d};
Double[] expectedBeta = {2d, 4d, 4d, 2d, 1d};
lms.setHeightsigmaMin(500);
Interval interval = new Interval(-2, 0);
lms.lowerBound(interval);
assertTrue(interval.getActivity());
}
}

View File

@ -0,0 +1,27 @@
package presenter.io;
import org.junit.Before;
import org.junit.Test;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 21.06.2017.
*/
public class DataImporterTest {
private DataImporter importer;
@Before
public void setUp() throws Exception {
//importer = new DataImporter("C:\\Users\\Armin\\Desktop\\test.csv", null);
}
@Test
public void run() throws Exception {
//importer.run();
}
}