Theil-Sen Schätzer nochmal angepasst, y-Achsenabschnitt verbessert

This commit is contained in:
Armin Wolf 2017-09-09 19:41:32 +02:00
parent 92f8820361
commit ccd6160745
4 changed files with 76 additions and 55 deletions

View File

@ -5,6 +5,7 @@ import Model.Line;
import Model.Point;
import Presenter.Presenter;
import com.sun.org.apache.bcel.internal.generic.FASTORE;
import java.util.*;
/**
@ -64,13 +65,6 @@ public class TheilSenEstimator extends Observable implements Algorithm {
this.xCoordinates = new ArrayList<>();
this.N = BinomialCoeffizient.run(n, 2);
this.k = Integer.valueOf((int) (N * 0.5))-1;
//Koordinaten werden gespeichert damit am ende
//der y Achsenabschnitt berechnet werden kann
for (Point l : setOfIntersections) {
yCoordinates.add(l.getY());
xCoordinates.add(l.getX());
}
}
public TheilSenEstimator(LinkedList<Line> setOfLines, LinkedList<Point> setOfIntersections) {
@ -90,7 +84,7 @@ public class TheilSenEstimator extends Observable implements Algorithm {
interval = new Interval(NEGATIV_INF, POSITIV_INF);
r = (double) n;
while (true) {
if (this.N <= n || (interval.getUpper() - interval.getLower()) < EPSILON) {
if (this.N <= n || (Math.abs(interval.getUpper() - interval.getLower())) < EPSILON) {
break;
} else {
//Anzahl der Schnittpunkte im Intervall [-Inf, a)
@ -98,8 +92,8 @@ public class TheilSenEstimator extends Observable implements Algorithm {
//Randomized Interpolating Search
j = (r / N) * (double) (k - numberOfIntersections);
jA = (int) Math.max(1, Math.floor(j - (3.0 * Math.sqrt(r))));
jB = (int) Math.min(r, Math.floor(j + (3.0 * Math.sqrt(r))));
jA = (int) Math.max(1, Math.floor(j - (1.5 * Math.sqrt(r))));
jB = (int) Math.min(r, Math.floor(j + (1.5 * Math.sqrt(r))));
/* Suche nach einem passenderen und kleineren Intervall
@ -115,7 +109,7 @@ public class TheilSenEstimator extends Observable implements Algorithm {
interval.setLower(aVariant);
interval.setUpper(bVariant);
intervalIntersections = getOpenIntervalElements(interval.getLower(), interval.getUpper());
N = Double.valueOf(getOpenIntervalSize(interval.getLower(), interval.getUpper()));
N = (double) getOpenIntervalSize(interval.getLower(), interval.getUpper(), intervalIntersections);
}
}
}
@ -174,26 +168,8 @@ public class TheilSenEstimator extends Observable implements Algorithm {
*/
public int getOpenIntervalSize(double a, double b, ArrayList<Point> set) {
int counter = 0;
for (Point x : set) {
if (x.getX() >= a && x.getX() < b) {
counter++;
}
}
return counter;
}
/**
* Berechne wieviele von den Schnittpunkten in dem Interval zwischen <code>a</code> und <code>b</code>
* enthalten sind.
*
* @param a untere Grenze des Intervals
* @param b obere Grenze des Intrvals
* @return Anzahl der Schnittpunkte im Interval [a,b)
*/
public int getOpenIntervalSize(double a, double b) {
int counter = 0;
for (int i=0;i<intervalIntersections.size();i++) {
Point x = intervalIntersections.get(i);
for (int i=0;i<set.size();i++) {
Point x = set.get(i);
if (x.getX() > a && x.getX() < b) {
counter++;
}
@ -214,7 +190,7 @@ public class TheilSenEstimator extends Observable implements Algorithm {
ArrayList<Point> list = new ArrayList<>();
for (int i=0;i<intervalIntersections.size();i++) {
Point x = intervalIntersections.get(i);
if (x.getX() > a && x.getX() < b) {
if ((x.getX() > a && x.getX() < b) || (Math.abs(interval.getUpper() - interval.getLower())) < EPSILON) {
list.add(x);
}
}
@ -228,27 +204,24 @@ public class TheilSenEstimator extends Observable implements Algorithm {
double m, x;
double b, y;
Collections.sort(xCoordinates);
Collections.sort(yCoordinates);
int n = xCoordinates.size();
if (n % 2 == 0) {
x = 0.5 * (xCoordinates.get((n / 2) - 1) + xCoordinates.get((n / 2)));
y = 0.5 * (yCoordinates.get((n / 2) - 1) + yCoordinates.get((n / 2)));
} else {
x = xCoordinates.get(((n + 1) / 2) - 1);
y = yCoordinates.get(((n + 1) / 2) - 1);
}
ArrayList<Point> resultSt = getOpenIntervalElements(interval.getLower(), interval.getUpper());
int size = resultSt.size();
if (size % 2 == 0) {
m = 0.5 * (resultSt.get((size / 2) - 1).getX() + resultSt.get((size / 2)).getX());
} else {
m = resultSt.get(((size + 1) / 2) - 1).getX();
ArrayList<Double> resultAbscissas = new ArrayList<>();
for (Point p : resultSt){
resultAbscissas.add(p.getX());
}
b = (x * m) - y;
for (Point p: setOfIntersections) {
yCoordinates.add(p.getY());
}
int pseudoIndex = (int) getOpenIntervalSize(NEGATIV_INF, interval.getLower(), setOfIntersections);
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;
slope = m;
yInterception = b;

View File

@ -41,16 +41,29 @@ public class EvalResultLatexExport {
private String createOutputData(){
String split = "&";
StringBuilder doc = new StringBuilder();
doc.append("\\begin{tabular}{l*{3}{c}}"+"\r\n");
doc.append("Approximationsgüte"+split+"LMS"+split+"RM"+split+"TS"+"\\\\\\hline"+"\r\n");
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() != "") {
doc.append(model.getValueAt(i, j).toString() + split);
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);
}
}
}
doc.deleteCharAt(doc.lastIndexOf(split));
if (model.getValueAt(i,0) != "") {
doc.deleteCharAt(doc.lastIndexOf(split));
}
doc.append("\\\\"+"\r\n");
}
doc.append("\\end{tabular}");

View File

@ -406,7 +406,7 @@ public class MainFrame extends JFrame {
if (chooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION){
//System.out.println ("Datei "+chooser.getSelectedFile()+ " ausgewählt.");
file = chooser.getSelectedFile();
String filename = file.getAbsolutePath().concat(".csv");
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));

View File

@ -32,6 +32,8 @@ public class EvaluationPanel extends JPanel{
private JTableHeader header;
private JButton start;
private JButton latexExport;
private JButton clearTable;
private JButton exportData;
private JRadioButton evalTypeOne; //1: Alg - N: Data
private JRadioButton evalTypeTwo; //N: Alg - 1: Data
private ButtonGroup radiobuttonGroup;
@ -79,6 +81,11 @@ public class EvaluationPanel extends JPanel{
start = new JButton("Start");
latexExport = new JButton("LaTex Export");
clearTable = new JButton("Löschen");
exportData = new JButton("Datenexport");
latexExport.setEnabled(false);
clearTable.setEnabled(false);
exportData.setEnabled(false);
evalTypeOne = new JRadioButton("Algorithmus evaluieren");
evalTypeTwo = new JRadioButton("Algorithmen vergleichen");
lms = new JCheckBox ("Least Median of Squares");
@ -121,6 +128,8 @@ public class EvaluationPanel extends JPanel{
radiobuttonGroup.add(evalTypeTwo);
buttonPanel.add(start);
buttonPanel.add(clearTable);
buttonPanel.add(exportData);
buttonPanel.add(latexExport);
algorithmPanel.add(lms);
@ -185,6 +194,9 @@ public class EvaluationPanel extends JPanel{
n = (Integer) datasetCountChoice.getSelectedItem();
String datatyp = (String) datasetType.getSelectedItem();
view.getPresenter().startEvaluation(type,n,alg,datatyp);
clearTable.setEnabled(true);
latexExport.setEnabled(true);
exportData.setEnabled(true);
});
evalTypeOne.addActionListener(e -> {
@ -224,13 +236,36 @@ public class EvaluationPanel extends JPanel{
if (chooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION){
//System.out.println ("Datei "+chooser.getSelectedFile()+ " ausgewählt.");
file = chooser.getSelectedFile();
String filename = file.getAbsolutePath().concat(".tex");
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);
}
});
});
clearTable.addActionListener(e -> {
SwingUtilities.invokeLater(() ->{
int n = model.getDataVector().size();
for (int i=0;i<n;i++){
model.removeRow(0);
currentRowOfTypes--;
}
this.revalidate();
latexExport.setEnabled(false);
clearTable.setEnabled(false);
exportData.setEnabled(false);
});
});
exportData.addActionListener(e -> {
SwingUtilities.invokeLater(() -> {
JOptionPane.showMessageDialog(null, "Boooooooooooooooooooooooooooooooooooooooooooooooooooooo! :)");
});
});
}
public void addColumn(Object[] data, int col, boolean b){