summaryrefslogtreecommitdiff
path: root/gi/posterior-regularisation/prjava/src/optimization/projections/BoundsProjection.java
diff options
context:
space:
mode:
Diffstat (limited to 'gi/posterior-regularisation/prjava/src/optimization/projections/BoundsProjection.java')
-rw-r--r--gi/posterior-regularisation/prjava/src/optimization/projections/BoundsProjection.java104
1 files changed, 104 insertions, 0 deletions
diff --git a/gi/posterior-regularisation/prjava/src/optimization/projections/BoundsProjection.java b/gi/posterior-regularisation/prjava/src/optimization/projections/BoundsProjection.java
new file mode 100644
index 00000000..0429d531
--- /dev/null
+++ b/gi/posterior-regularisation/prjava/src/optimization/projections/BoundsProjection.java
@@ -0,0 +1,104 @@
+package optimization.projections;
+
+
+import java.util.Random;
+
+import optimization.util.MathUtils;
+import optimization.util.MatrixOutput;
+
+/**
+ * Implements a projection into a box set defined by a and b.
+ * If either a or b are infinity then that bound is ignored.
+ * @author javg
+ *
+ */
+public class BoundsProjection extends Projection{
+
+ double a,b;
+ boolean ignoreA = false;
+ boolean ignoreB = false;
+ public BoundsProjection(double lowerBound, double upperBound) {
+ if(Double.isInfinite(lowerBound)){
+ this.ignoreA = true;
+ }else{
+ this.a =lowerBound;
+ }
+ if(Double.isInfinite(upperBound)){
+ this.ignoreB = true;
+ }else{
+ this.b =upperBound;
+ }
+ }
+
+
+
+ /**
+ * Projects into the bounds
+ * a <= x_i <=b
+ */
+ public void project(double[] original){
+ for (int i = 0; i < original.length; i++) {
+ if(!ignoreA && original[i] < a){
+ original[i] = a;
+ }else if(!ignoreB && original[i]>b){
+ original[i]=b;
+ }
+ }
+ }
+
+ /**
+ * Generates a random number between a and b.
+ */
+
+ Random r = new Random();
+
+ public double[] samplePoint(int numParams) {
+ double[] point = new double[numParams];
+ for (int i = 0; i < point.length; i++) {
+ double rand = r.nextDouble();
+ if(ignoreA && ignoreB){
+ //Use const to avoid number near overflow
+ point[i] = rand*(1.E100+1.E100)-1.E100;
+ }else if(ignoreA){
+ point[i] = rand*(b-1.E100)-1.E100;
+ }else if(ignoreB){
+ point[i] = rand*(1.E100-a)-a;
+ }else{
+ point[i] = rand*(b-a)-a;
+ }
+ }
+ return point;
+ }
+
+ public static void main(String[] args) {
+ BoundsProjection sp = new BoundsProjection(0,Double.POSITIVE_INFINITY);
+
+
+ MatrixOutput.printDoubleArray(sp.samplePoint(3), "random 1");
+ MatrixOutput.printDoubleArray(sp.samplePoint(3), "random 2");
+ MatrixOutput.printDoubleArray(sp.samplePoint(3), "random 3");
+
+ double[] d = {-1.1,1.2,1.4};
+ double[] original = d.clone();
+ MatrixOutput.printDoubleArray(d, "before");
+
+ sp.project(d);
+ MatrixOutput.printDoubleArray(d, "after");
+ System.out.println("Test projection: " + sp.testProjection(original, d));
+ }
+
+ double epsilon = 1.E-10;
+ public double[] perturbePoint(double[] point, int parameter){
+ double[] newPoint = point.clone();
+ if(!ignoreA && MathUtils.almost(point[parameter], a)){
+ newPoint[parameter]+=epsilon;
+ }else if(!ignoreB && MathUtils.almost(point[parameter], b)){
+ newPoint[parameter]-=epsilon;
+ }else{
+ newPoint[parameter]-=epsilon;
+ }
+ return newPoint;
+ }
+
+
+}