WIP: lms...
This commit is contained in:
parent
7e6977b086
commit
23c9ecdba9
|
@ -1,7 +1,6 @@
|
||||||
package Presenter.Algorithms;
|
package Presenter.Algorithms;
|
||||||
|
|
||||||
import Model.Coordinates;
|
import Model.Coordinates;
|
||||||
import sun.awt.image.ImageWatched;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
@ -16,9 +15,11 @@ public class LeastMedianOfSquaresEstimator extends Algorithm {
|
||||||
|
|
||||||
|
|
||||||
private LinkedList<Coordinates> set = new LinkedList<>();
|
private LinkedList<Coordinates> set = new LinkedList<>();
|
||||||
private LinkedList<Coordinates> sortedIntersections = new LinkedList<>();
|
private LinkedList<Coordinates> intersections = new LinkedList<>();
|
||||||
|
|
||||||
private int n;
|
private int n;
|
||||||
private double quantile = 0.5;
|
private final double quantile = 0.5;
|
||||||
|
private final double error = 0.01;
|
||||||
private double quantileError;
|
private double quantileError;
|
||||||
private double qPlus;
|
private double qPlus;
|
||||||
private double qMinus;
|
private double qMinus;
|
||||||
|
@ -28,8 +29,7 @@ public class LeastMedianOfSquaresEstimator extends Algorithm {
|
||||||
private Slab activeSlab;
|
private Slab activeSlab;
|
||||||
private Slab subSlabU1;
|
private Slab subSlabU1;
|
||||||
private Slab subSlabU2;
|
private Slab subSlabU2;
|
||||||
private double umin;
|
private ArrayList<Double> sortedLineSequence = new ArrayList<>();
|
||||||
private double umax;
|
|
||||||
private double heightsigmaMin;
|
private double heightsigmaMin;
|
||||||
private Coordinates sigmaMinStart;
|
private Coordinates sigmaMinStart;
|
||||||
private Coordinates sigmaMinEnd;
|
private Coordinates sigmaMinEnd;
|
||||||
|
@ -42,58 +42,67 @@ public class LeastMedianOfSquaresEstimator extends Algorithm {
|
||||||
* Hilfsklasse um die Slabs zu verteilen, private Klasse da sonst nicht verwendett wird und somit eine
|
* Hilfsklasse um die Slabs zu verteilen, private Klasse da sonst nicht verwendett wird und somit eine
|
||||||
* äußere Klasse überflüssig ist...
|
* äußere Klasse überflüssig ist...
|
||||||
*/
|
*/
|
||||||
private static class Slab {
|
private static class Slab {
|
||||||
private double upper;
|
private double upper;
|
||||||
private double lower;
|
private double lower;
|
||||||
|
private Boolean activity;
|
||||||
public Slab(double lower, double upper) {
|
|
||||||
this.upper = upper;
|
|
||||||
this.lower = lower;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 Slab(double lower, double upper) {
|
||||||
|
this.upper = upper;
|
||||||
|
this.lower = lower;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Boolean getActivity() {
|
||||||
|
return activity;
|
||||||
|
}
|
||||||
|
|
||||||
public void approximateLMS(){
|
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 void approximateLMS() {
|
||||||
//(1.) Let n <- |S|; q+ <- q; q- <- q+ * (1 - quantileError);....
|
//(1.) Let n <- |S|; q+ <- q; q- <- q+ * (1 - quantileError);....
|
||||||
n = set.size();
|
n = set.size();
|
||||||
qPlus = quantile;
|
qPlus = quantile;
|
||||||
qMinus = qPlus * (1 - quantileError);
|
qMinus = qPlus * (1 - quantileError);
|
||||||
kMinus = Math.ceil(n * qMinus);
|
kMinus = Math.ceil(n * qMinus);
|
||||||
kPlus = Math.ceil(n * qPlus);
|
kPlus = Math.ceil(n * qPlus);
|
||||||
|
|
||||||
//(2.) Let U <- (-inf, inf) be the initial active slab...
|
//(2.) Let U <- (-inf, inf) be the initial active slab...
|
||||||
slab = new TreeSet<>();
|
slab = new TreeSet<>();
|
||||||
slab.add(new Slab(Double.MAX_VALUE, Double.MIN_VALUE));
|
slab.add(new Slab(Double.MAX_VALUE, Double.MIN_VALUE));
|
||||||
heightsigmaMin = Double.MAX_VALUE;
|
heightsigmaMin = Double.MAX_VALUE;
|
||||||
|
|
||||||
//(3.) Apply the following steps as long as the exists active slabs
|
//(3.) Apply the following steps as long as the exists active slabs
|
||||||
for(Iterator<Slab> it = slab.iterator(); it.hasNext();){
|
for (Iterator<Slab> it = slab.iterator(); it.hasNext(); ) {
|
||||||
//(a.) Select any active Slab and calc. the inversions
|
//(a.) Select any active Slab and calc. the inversions
|
||||||
activeSlab = it.next();
|
activeSlab = it.next();
|
||||||
numberOfIntersections = countInversions(activeSlab);
|
numberOfIntersections = countInversions(activeSlab);
|
||||||
|
|
||||||
//(b.) apply plane sweep
|
//(b.) apply plane sweep
|
||||||
if ( numberOfIntersections < (constant * n)){
|
if (numberOfIntersections < (constant * n)) {
|
||||||
kMinusBracelet = planeSweep(activeSlab);
|
kMinusBracelet = planeSweep(activeSlab);
|
||||||
} else {//(c.) otherwise....
|
} else {//(c.) otherwise....
|
||||||
//get random intersections point...
|
//get random intersections point...
|
||||||
splitActiveSlab(intersectionsPoint);
|
splitActiveSlab(intersectionsPoint);
|
||||||
}
|
}
|
||||||
//(d.) this may update sigma min
|
//(d.) this may update sigma min
|
||||||
|
@ -106,50 +115,221 @@ public class LeastMedianOfSquaresEstimator extends Algorithm {
|
||||||
}
|
}
|
||||||
|
|
||||||
//Parameter anpassen
|
//Parameter anpassen
|
||||||
public int countInversions(Slab slab){
|
|
||||||
return 0;
|
/**
|
||||||
|
* @param slab
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int countInversions(Slab slab) {
|
||||||
|
|
||||||
|
int numberOfInversions = 0;
|
||||||
|
|
||||||
|
ArrayList<Double> umin = new ArrayList<>();
|
||||||
|
ArrayList<Double> umax = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Coordinates p : set) {
|
||||||
|
umin.add((slab.getLower() * p.getX()) + p.getY());
|
||||||
|
umax.add((slab.getUpper() * p.getX()) + p.getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
numberOfInversions = mergeSort(umin, 0, umin.size() - 1, umax);
|
||||||
|
|
||||||
|
for (Coordinates point : intersections) {
|
||||||
|
if (point.getX() >= slab.getLower() && point.getX() < slab.getUpper()) {
|
||||||
|
intersectionsPoint = point.getX();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return numberOfInversions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Coordinates planeSweep(Slab slab){
|
public int mergeSort(List<Double> a, int start, int end, List<Double> aux) {
|
||||||
|
if (start >= end) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int invCount = 0;
|
||||||
|
int mid = start + (end - start) / 2;
|
||||||
|
int invCountLeft = mergeSort(a, start, mid, aux); // divide and conquer
|
||||||
|
int invCountRight = mergeSort(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;
|
||||||
|
while (left <= mid && right <= end) {
|
||||||
|
if (aux.get(left) < aux.get(right)) {
|
||||||
|
a.set(index++, aux.get(left++));
|
||||||
|
} else {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param slab
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Coordinates planeSweep(Slab slab) {
|
||||||
|
Comparator<Coordinates> queueComparator = (o1, o2) -> {
|
||||||
|
if (o1.getX() == o2.getX()) {
|
||||||
|
if (o1.getY() <= o2.getY()) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else if (o1.getX() < o2.getX()) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
PriorityQueue<Coordinates> xQueue = new PriorityQueue<>(queueComparator);
|
||||||
|
Comparator<Coordinates> treeComparator = (o1, o2) -> {
|
||||||
|
if (o1.getY() == o2.getY()) {
|
||||||
|
if (o1.getX() <= o2.getX()) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else if (o1.getY() < o2.getY()) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
TreeMap<Double,Coordinates> yStruct = new TreeMap(treeComparator);
|
||||||
|
|
||||||
|
for (Coordinates point : intersections) {
|
||||||
|
if (point.getX() >= slab.getLower() && point.getX() < slab.getUpper()) {
|
||||||
|
xQueue.add(point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return new Coordinates(.0, .0);
|
return new Coordinates(.0, .0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void splitActiveSlab(double point){
|
/**
|
||||||
|
* @param point
|
||||||
|
*/
|
||||||
|
public void splitActiveSlab(double point) {
|
||||||
|
|
||||||
subSlabU1 = new Slab(activeSlab.getLower(), point);
|
subSlabU1 = new Slab(activeSlab.getLower(), point);
|
||||||
subSlabU2 = new Slab(point, activeSlab.getUpper());
|
subSlabU2 = new Slab(point, activeSlab.getUpper());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void upperBound(double point){
|
/**
|
||||||
ArrayList<Coordinates> temp = new ArrayList<>();
|
* @param point
|
||||||
|
*/
|
||||||
|
public void upperBound(double point) {
|
||||||
|
|
||||||
ArrayList<Double> min = new ArrayList<>();
|
ArrayList<Double> min = new ArrayList<>();
|
||||||
double height;
|
double height;
|
||||||
for (Coordinates p : set) {
|
|
||||||
temp.add(new Coordinates(point, (p.getX() * point) + p.getY()));
|
|
||||||
}
|
|
||||||
|
|
||||||
Collections.sort(temp);
|
sortedLineSequence = getEjValues(point);
|
||||||
|
|
||||||
for (int i=1;i<(n-(kMinus+1));i++){
|
for (int i = 1; i < (n - (kMinus + 1)); i++) {
|
||||||
height = temp.get(i+(((int) kMinus) - 1)).getY() - temp.get(i).getY();
|
height = sortedLineSequence.get(i + (((int) kMinus) - 1)) - sortedLineSequence.get(i);
|
||||||
|
|
||||||
if (height < heightsigmaMin)
|
if (height < heightsigmaMin) {
|
||||||
sigmaMinStart = new Coordinates(point, temp.get(i+(((int) kMinus) - 1)).getY());
|
sigmaMinStart = new Coordinates(point, sortedLineSequence.get(i + (((int) kMinus) - 1)));
|
||||||
sigmaMinEnd = new Coordinates(point, temp.get(i).getY());
|
sigmaMinEnd = new Coordinates(point, sortedLineSequence.get(i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void lowerBound(Slab slab){
|
/**
|
||||||
double[] alpha = new double[n];
|
* @param slab
|
||||||
double[] beta = new double[n];
|
* @return
|
||||||
|
*/
|
||||||
|
public Slab lowerBound(Slab slab) {
|
||||||
|
|
||||||
|
boolean active = false;
|
||||||
|
int[] alpha = new int[n];
|
||||||
|
int[] beta = new int[n];
|
||||||
alpha[0] = 0;
|
alpha[0] = 0;
|
||||||
beta[0] = 0;
|
beta[0] = 0;
|
||||||
|
int strictlyGreater = 0;
|
||||||
|
|
||||||
for (int i=1;i < n; i++){
|
//Teil I.
|
||||||
|
ArrayList<Double> umaxList;
|
||||||
|
ArrayList<Double> uminList;
|
||||||
|
|
||||||
|
//y koordinaten der Schnittpunkte
|
||||||
|
ArrayList<Coordinates> lines = new ArrayList<>();
|
||||||
|
for (Coordinates p : set) {
|
||||||
|
lines.add(new Coordinates(((slab.getLower() * p.getX()) + p.getY()), ((slab.getUpper() * p.getX()) + p.getY())));
|
||||||
}
|
}
|
||||||
|
|
||||||
// if Ui is active on return add it to the list of active slabs..!!!
|
|
||||||
|
umaxList = getEjValues(slab.getUpper());
|
||||||
|
uminList = getEjValues(slab.getLower());
|
||||||
|
|
||||||
|
for (int i = 1; i < n; i++) {
|
||||||
|
Coordinates level = new Coordinates(uminList.get(i), umaxList.get(i));
|
||||||
|
for (Coordinates point : lines) {
|
||||||
|
if ((point.getX() < level.getX()) && (point.getY() < level.getY())) {
|
||||||
|
alpha[i]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((point.getX() > level.getX()) && (point.getY() > level.getY())) {
|
||||||
|
strictlyGreater++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
beta[i] = n - (alpha[i] + strictlyGreater);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Teil II.
|
||||||
|
int i = 1;
|
||||||
|
double h = Double.MAX_VALUE;
|
||||||
|
active = false;
|
||||||
|
for (int j = 0; j < n; j++) {
|
||||||
|
do {
|
||||||
|
i++;
|
||||||
|
} while ((i < n) && (beta[i] - alpha[j] < kPlus));
|
||||||
|
|
||||||
|
if (i > n) {
|
||||||
|
slab.setActivity(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
h = Math.min((uminList.get(j) - uminList.get(i)), (umaxList.get(j) - umaxList.get(i)));
|
||||||
|
}
|
||||||
|
if (((1 + error) * h) < heightsigmaMin) {
|
||||||
|
slab.setActivity(true);
|
||||||
|
}
|
||||||
|
return slab;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 (Coordinates p : set) {
|
||||||
|
ret.add((p.getX() * u) + p.getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
Collections.sort(ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
package Presenter.Algorithms;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
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 {
|
||||||
|
lms = new LeastMedianOfSquaresEstimator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void approximateLMS() throws Exception {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mergeSort() throws Exception {
|
||||||
|
double[] umin = {1,5,6,4,20};
|
||||||
|
double[] umax = {1,4,6,5,20};
|
||||||
|
|
||||||
|
ArrayList<Double> a = new ArrayList<>();
|
||||||
|
ArrayList<Double> b = new ArrayList<>();
|
||||||
|
|
||||||
|
for (double d :umin) {
|
||||||
|
a.add(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (double d :umax) {
|
||||||
|
b.add(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ret = lms.mergeSort(a,0,a.size()-1,b);
|
||||||
|
assertEquals(2, ret);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void planeSweep() throws Exception {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void splitActiveSlab() throws Exception {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void upperBound() throws Exception {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void lowerBound() throws Exception {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getEjValues() throws Exception {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue