Normalization issue in Java - Android Studio - java

I am gathering 10 acceleration values from an on-board accelerometer on a mobile device. I am then attempting to normalize these values between the range of -1,1. I am unable to figure out why this isn't working correctly.
Here is the normalization code:
class NormUtil {
private double dataHigh;
private double dataLow;
private double normalizedHigh;
private double normalizedLow;
public NormUtil(double dataHigh, double dataLow) {
this(dataHigh, dataLow, 1, -1);
}
public NormUtil(double dataHigh, double dataLow, double normalizedHigh, double normalizedLow) {
this.dataHigh = dataHigh;
this.dataLow = dataLow;
this.normalizedHigh = normalizedHigh;
this.normalizedLow = normalizedLow;
}
public double normalize(double e) {
return ((e - dataLow)
/ (dataHigh - dataLow))
* (normalizedHigh - normalizedLow) + normalizedLow;
}
On a button press, the highest/lowest acceleration values are found in this code:
A = enrolAcc.get(0);
B = enrolAcc.get(0);
for (Float i: enrolAcc) {
if(i < A) A = i;
if(i > B) B = i;
}
Once the highest/lowest values are found a NormUtil instance is created and this instance is used to normalize the array of acceleration values and then add the normalized values to a new array:
NormUtil norm = new NormUtil(B,A,1,-1);
for(int j = 0; j < enrolAcc.size(); j++) {
double start = enrolAcc.get(j);
double x = norm.normalize(start);
nAcc[j] = x;
}
This nAcc array is then put into a string array and then a single string to display in a text view. The issue is the text view is always initialized with the original non-normalized acceleration values, here is the code I use for that:
String normD[] = new String[10];
for (int i = 0; i < 10; i++) {
normD[i] = String.valueOf(nAcc[i]);
}
StringBuilder strBuilder2 = new StringBuilder();
for (int i = 0; i<normD.length; i++) {
strBuilder2.append(normD[i] + ",");
}
normData = strBuilder.toString();
textNorm.setText("Normalised: " + normData);
So my question is, where am I going wrong with adding the normalized values to the normalized array and is this normalization method correct for what I am trying to achieve? Thanks in advance.

Related

Java getting stuck in while loop

So I have created this program to randomly place objects in a room with a number of constraints. One such constraint is that every object has to be at least dis distance away from every other object already placed in the room. My entire code works well, however I often have to problem that the code stays stuck in the while loop. Here is that part of the code:
// distance vector to check whether the distance is kept
double[] dis2 = new double[k+1];
// distance vector to check whether the distance to the input/output is kept
double[] dis4 = new double[2];
dis4[0] = Math.abs(NewObjectX - inputX) + Math.abs(NewObjectY - inputY);
dis4[1] = Math.abs(NewObjectX - outputX) + Math.abs(NewObjectY - outputY);
// Check the distance constraints
int l = 0;
while (l<k+1) {
dis2[l] = Math.abs(NewObjectX - PlacedX[l]) + Math.abs(NewObjectY - PlacedY[l]);
if (dis2[l]<dis || dis3>2.5*dis || dis4[0]<dis || dis4[1]<dis) {
NewObjectX = Math.random()*(dim[1]-dim[0]) + dim[0]*0.5;
NewObjectY = Math.random()*(dim[3]-dim[2]) + dim[2]*0.5;
dis3 = Math.abs(NewObjectX - PlacedX[k]) + Math.abs(NewObjectY - PlacedY[k]);
dis4[0] = Math.abs(NewObjectX - inputX) + Math.abs(NewObjectY - inputY);
dis4[1] = Math.abs(NewObjectX - outputX) + Math.abs(NewObjectY - outputY);
l=0;
} else {
l++;
}
}
What happens: I randomly place a machine in the room and then I check the distance constraints with every already placed object in the while loop:
In the while loop, I check the distance constraint with the first, then second and so on objects that have already been placed.
If the distance constraints are not met, then a new randomly selected spot is selected and I restart the while loop l=0
I am not sure why my code sometimes stays stuck in that loop and most of the time works perfectly.
Could someone help me? Did I make an error?
Thank you so much :)
Sam
EDIT:
Here is a copy of the simplified code with only 1 constraint instead of 4 in the while loop:
public static double[][] initialPop(double[] dim, double dis, int WSNr, double[] ioPlace) {
int[] WStoPlace = new int[WSNr-2];
for (int i=1; i<WSNr-1; i++) {
WStoPlace[i-1] = (i);
}
double[][] placed = new double[WSNr-2][3];
double ObjectX;
double ObjectY;
// now place the first object
ObjectX = dim[1]/2;
ObjectY = dim[3]/2;
placed[0][0] = WStoPlace[0];
placed[0][1] = ObjectX ;
placed[0][2] = ObjectY;
for (int i=1; i<WSNr-2; i++) {
//place the ith object
ObjectX = Math.random()*(dim[1]-dim[0]) + dim[0]*0.5;
ObjectY = Math.random()*(dim[3]-dim[2]) + dim[2]*0.5;
int l=0;
while (l<i) {
double dis2 = Math.abs(ObjectX - placed[l][1]) + Math.abs(ObjectY - placed[l][2]);
if (dis2<dis) {
ObjectX = Math.random()*(dim[1]-dim[0]) + dim[0]*0.5;
ObjectX = Math.random()*(dim[3]-dim[2]) + dim[2]*0.5;
l=0;
} else {
l++;
}
}
// Add the newly placed object
placed[i][0] = WStoPlace[i];
placed[i][1] = ObjectX;
placed[i][2] = ObjectY;
}
return placed;
}
This code is then called by my main program in a for-loop:
public static void main(String[] args) {
// define all the variables ...
int popFlow = 5;
double[] dim = new double [4];
dim[0] = 3; // length of WS (x)
dim[2] = 3; // width of WS (y)
dim[1] = 100; // length of facility (x)
dim[3] = 40;
double dis = 8;
int WSNr = 22;
double[] ioPlace = new double[4];
ioPlace[0] = 0; // int xi = 0;
ioPlace[1] = 5; // int yi = 2;
ioPlace[2] = 100; // int xo = 50;
ioPlace[3] = 35;
double[][] TotalPop = new double[popFlow][2*WSNr];
// Flow-related placed Workstations
for (int i=0; i<popFlow; i++) {
double [][] Pos = initialPop(dim, dis, WSNr, ioPlace);
for (int j=0; j<WSNr-2; j++) {
int Value = (int) Pos[j][0];
TotalPop[i][Value] = Pos[j][1];
TotalPop[i][Value+WSNr] = Pos[j][2];
}
}
}
As mentioned in the question's comments, you need to limit the loop. As a quick solution, you can have a counter that limits the while loop functionality and reset the entire logic which its probability to NOT go into same situation again is high. But that really should be handled better and check in which case exactly the loop would not end.
If the reason found and could be handled by the breaking conditions then it would be better as it would be more definite solution. Nevertheless, limiting the iteration for emergency is almost a must have. Here is simple sample on your code that would do something similar
public static double[][] initialPop(double[] dim, double dis, int WSNr, double[] ioPlace) {
boolean reset = false;
double[][] placed = null;
while (!reset) {
int[] WStoPlace = new int[WSNr - 2];
for (int i = 1; i < WSNr - 1; i++) {
WStoPlace[i - 1] = (i);
}
placed = new double[WSNr - 2][3];
double ObjectX;
double ObjectY;
// now place the first object
ObjectX = dim[1] / 2;
ObjectY = dim[3] / 2;
placed[0][0] = WStoPlace[0];
placed[0][1] = ObjectX;
placed[0][2] = ObjectY;
for (int i = 1; i < WSNr - 2; i++) {
//place the ith object
ObjectX = Math.random() * (dim[1] - dim[0]) + dim[0] * 0.5;
ObjectY = Math.random() * (dim[3] - dim[2]) + dim[2] * 0.5;
// Problem is the while, not the for so we define the limit here
int limit = 100;
int counter = 0;
// Make sure it's false as it might be changed in some iteration before!
// I promised, check the comments below !
reset = false;
int l = 0;
while (l < i) {
double dis2 = Math.abs(ObjectX - placed[l][1]) + Math.abs(ObjectY - placed[l][2]);
if (dis2 < dis) {
ObjectX = Math.random() * (dim[1] - dim[0]) + dim[0] * 0.5;
ObjectX = Math.random() * (dim[3] - dim[2]) + dim[2] * 0.5;
l = 0;
} else {
l++;
}
if (counter >= limit) { // Now that's enough !
reset = true;
break;
}
counter++;
}
if (reset) { // I said it's enough, I want full reset so ...
reset = false; // going to break to the while-loop that checking this, and we want to enter again !
break;
} else {
// Not sure at this point this will be the last execution
// So just make it true, so we do not enter the entire logic again
// after finally settling to our result !!!!
// If it's not the last execution which means we are entering another for-loop iteration then
// we will reset this to false, i promise !
reset = true;
// Add the newly placed object
placed[i][0] = WStoPlace[i];
placed[i][1] = ObjectX;
placed[i][2] = ObjectY;
}
}
}
return placed;
}
You need a breakout. Add a counter or timer or check off coords as you try them until they are all checked. The way it is now there is no way to end the loop if your conditions in the "if" statement are always meet, it will just keep setting 'l' to 0 and your while loop just keeps looping.

Loop a calculation a certain fixed amount

Does anyone know how I can loop through this calculation 7 times?
public static double[] getNumSeedsPerType(String[] treeTypes, int[] numTreesPerType, final double FIR_DIE) {
double numSeeds = 0;
double[] numSeedsPerType = new double[numTreesPerType.length];
for (int i = 0; i < treeTypes.length; i++) {
if (treeTypes[i].equalsIgnoreCase("fir")) {
// This part of the calculation
numSeeds = numTreesPerType[i] - (numTreesPerType[i] * FIR_DIE);
numSeedsPerType[i] = numSeeds + numTreesPerType[i];
}
}
return numSeedsPerType;
}
If my understanding of your code is correct you can do the following:
Use a for loop to do the calculation 7 times.
Inside the loop change this code:
numSeeds = numTreesPerType[i] - (numTreesPerType[i] * FIR_DIE);
to this (so you can keep the results of every calculation):
numSeeds += numTreesPerType[i] - (numTreesPerType[i] * FIR_DIE);

Gradient descent in Java

I've recently started the AI-Class at Coursera and I've a question related to my implementation of the gradient descent algorithm.
Here's my current implementation (I actually just "translated" the mathematical expressions into Java code):
public class GradientDescent {
private static final double TOLERANCE = 1E-11;
private double theta0;
private double theta1;
public double getTheta0() {
return theta0;
}
public double getTheta1() {
return theta1;
}
public GradientDescent(double theta0, double theta1) {
this.theta0 = theta0;
this.theta1 = theta1;
}
public double getHypothesisResult(double x){
return theta0 + theta1*x;
}
private double getResult(double[][] trainingData, boolean enableFactor){
double result = 0;
for (int i = 0; i < trainingData.length; i++) {
result = (getHypothesisResult(trainingData[i][0]) - trainingData[i][1]);
if (enableFactor) result = result*trainingData[i][0];
}
return result;
}
public void train(double learningRate, double[][] trainingData){
int iteration = 0;
double delta0, delta1;
do{
iteration++;
System.out.println("SUBS: " + (learningRate*((double) 1/trainingData.length))*getResult(trainingData, false));
double temp0 = theta0 - learningRate*(((double) 1/trainingData.length)*getResult(trainingData, false));
double temp1 = theta1 - learningRate*(((double) 1/trainingData.length)*getResult(trainingData, true));
delta0 = theta0-temp0; delta1 = theta1-temp1;
theta0 = temp0; theta1 = temp1;
}while((Math.abs(delta0) + Math.abs(delta1)) > TOLERANCE);
System.out.println(iteration);
}
}
The code works quite well but only if I choose an very little alpha, here called learningRate. If it's higher than 0.00001, it diverges.
Do you have any suggestions on how to optimize the implementation, or an explanation for the "Alpha-Issue" and a possible solution for it?
Update:
Here's the main including some sample inputs:
private static final double[][] TDATA = {{200, 20000},{300, 41000},{900, 141000},{800, 41000},{400, 51000},{500, 61500}};
public static void main(String[] args) {
GradientDescent gd = new GradientDescent(0,0);
gd.train(0.00001, TDATA);
System.out.println("THETA0: " + gd.getTheta0() + " - THETA1: " + gd.getTheta1());
System.out.println("PREDICTION: " + gd.getHypothesisResult(300));
}
The mathematical expression of gradient descent is as follows:
To solve this issue, it's necessary to normalize the data with this formular: (Xi-mu)/s.
Xi is the current training set value, mu the average of values in the current column and s the maximum value minus the minimum value of the current column. This formula will get the training data approximately into a range between -1 and 1 which allowes to choose higher learning rates and gradient descent to converge faster.
But it's afterwards necessary to denormalize the predicted result.
private double getResult(double[][] trainingData, boolean enableFactor){
double result = 0;
for (int i = 0; i < trainingData.length; i++) {
result = (getHypothesisResult(trainingData[i][0]) - trainingData[i][1]);
if (enableFactor) result = result*trainingData[i][0];
}
return result;
In this func. result variable overwritten each iteration, the old value being lost. When inputing the values only the last item on array is calculating. Rest of them dont matter.
You should use java.math.BigDecimal for your arithematic operations.
double has its rounding-off issues while performing any arithematic.

Keeping track of previous numbers in a for loop is not working

I know theres another question like this online but I can't get my code to work. I don't know if my if statements is incorrect or if its something else. This is an extension of my earlier questions
Remove duplicates in a 2D array and add the corresponding values
The question is still the same but except instead of using a 2D array I am using a for loop and I wan't to keep track of the previous numbers in the for loop but when I print the numbers on to the console I get duplicate r values. I hope someone can help me see the mistake. Thanks in advance!
Here is the code I am working on:
double rMax = -1;
double previous;
for(int i =1; i< 256; i++){
for(int y =1; y< 256; y++){
//image.getPixel(i, y);
String x = image.getLocationAsString(i, y);
String n = image.getValueAsString(i, y);
String delim = ", value=";
String [] tokens = n.split(delim);
double num = Double.parseDouble(tokens[1]);
//if(image.getR() < 1.43){
String [] t = x.split("r=");
String[] b = t[1].split(" mm/c");
//System.out.print("Meet b: "+b[0]);
double radius = Double.parseDouble(b[0]);
String [] theta = x.split("theta= ");
String [] token2 = theta[1].split(Character.toString(IJ.degreeSymbol));
float thetaNum = Float.parseFloat(token2[0]);
//System.out.print(" This is the theta value: "+thetaNum+" ");
if(radius == rMax){
rMax = radius;
}
String prevX = image.getLocationAsString(i-1, y-1);
String prevN = image.getValueAsString(i-1, y-1);
String [] prevT = prevX.split("r=");
String[] prevB = prevT[1].split(" mm/c");
//System.out.print("Meet b: "+b[0]);
double prev_radius = Double.parseDouble(prevB[0]);
previous = prev_radius;
if(previous == radius){
System.out.println(radius);
}
else{
System.out.println(radius);
}
//if(thetaNum <= 180.00){
data.add(radius, num);
//}
//}
}
}
System.out.println(rMax);
This is what it prints:
1.59
1.59
1.58
1.58
1.57
1.56
1.56
1.55
1.55
1.54
1.54
1.53
1.52
1.52
You're not setting the value of previous anywhere.
Update
Your code has so many problems. It'll never update rMax, for example. I think this code will do what you're trying to achieve, assuming that data is a dictionary of some kind. If not you'll need to modify the code that updates the value stored for the radius.
double rMax = -1;
double previous = -1;
for(int i =1; i< 256; i++){
for(int y =1; y< 256; y++){
String x = image.getLocationAsString(i, y);
String n = image.getValueAsString(i, y);
String delim = ", value=";
String [] tokens = n.split(delim);
double num = Double.parseDouble(tokens[1]);
String [] t = x.split("r=");
String [] b = t[1].split(" mm/c");
double radius = Double.parseDouble(b[0]);
String [] theta = x.split("theta= ");
String [] token2 = theta[1].split(Character.toString(IJ.degreeSymbol));
float thetaNum = Float.parseFloat(token2[0]);
if(radius > rMax){
rMax = radius;
}
if(radius == previous){
data[radius] += num;
}
else {
data.Add(radius, num);
}
}
}
System.out.println(rMax);
And, by the way, this code would be so much easier to read if you used Regex to capture the values from the string rather than all the confusing splits.

Numerically stable way to calculate normal log likelihood

I am trying to calculate the normal log likelihood which is given by:
L = l1+l2+l3+...+ln,
where
lk = log(1/(sqrt(2*PI)*sigma_k))-0.5*e_k*e_k
Sigmas are around 0.2, and e_k are normally distributed with mean 0 and unit variance, so most of them are between -2 and 2;
I tried the following java code (sigma_k mentioned above = sigmas.get(k)*Math.sqrt(dt)):
private double new1(List<Double> residuals, List<Double> sigmas, double dt) {
double a = 0;
for(int i=0; i<sigmas.size(); i++) {
a += Math.log(1.0/(Math.sqrt(2*Math.PI*dt)*sigmas.get(i)));
}
double b = 0;
for(int i=0; i<residuals.size(); i++) {
b += residuals.get(i)*residuals.get(i);
}
return a-0.5*b;
}
but the theoretical maximum is lower than the maximum I got by doing numerical optimisation, so I have some suspicions that my method is suboptimal.
Remark:
In some areas probability/statistics are calculated without taking the log, for instance in linguistic frequencies of combinations.
The following simplifies, becoming less stable, but afterwards one convert it back to a sum of logs or so.
double a = 0;
for(int i=0; i<sigmas.size(); i++) {
a += Math.log(1.0/(Math.sqrt(2*Math.PI*dt)*sigmas.get(i)));
}
log(x) + log(y) = log(x*y)
double a = 1.0;
for(int i=0; i<sigmas.size(); i++) {
a *= 1.0/(Math.sqrt(2*Math.PI*dt)*sigmas.get(i));
}
a = Math.log(a);
(1/x)*(1/y) = 1/(x*y)
double a = 1.0;
for(int i=0; i<sigmas.size(); i++) {
a *= Math.sqrt(2*Math.PI*dt)*sigmas.get(i);
}
a = Math.log(1.0/a);
sqrt(x)^n = (x^0.5)^n = x^(n/2)
static import Math.*;
double a = pow(2*PI*dt, sigmas.size() / 2.0);
for(int i=0; i<sigmas.size(); i++) {
a *= sigmas.get(i);
}
a = -log(a);
I'm not sure if it will greatly improve numerical stability, but your equations can be simplified using logarithm laws:
log(a*b) = log(a) + log(b)
log(1/a) = -log(a)
log(sqrt(a)) = log(a)/2
so you have:
lk = -log(2*pi)/2 - log(sigma_k) - 0.5*e_k*e_k
= -log(2*pi)/2 - log(dt)/2 - log(sigmas.get(k)) - 0.5*e_k*e_k
= -log(2*pi*dt)/2 - log(sigmas.get(k)) - 0.5*e_k*e_k
First is constant, so in the first loop you only need to do a -= log(sigmas.get(k)).
Also, it look suspicious, that first loop is to sigmas.size() and the second to residuals.size() while the equation suggests, that they should have the same length.

Categories

Resources