finding the length given the coordinates for a polygon - java

I'm working on a question where i need to find the length of the side given the coordinates of a polygon.
N is the number of rows and 2 is number of columns ( x and y coordinates) and i've collected the coordinates in a multi-dimensional array.
what my idea was to collect the x coordinates in a array say x1 and collect y coordinates in a array say y1. now find the difference between the numbers in the array and perform the distance formula operation. but im not able to proceed any further. im not able to find the length using it as the answer is always short of the actual number. kindly help on how can i find the length of the sides of a given polygon. please find my code below:
import java.util.Scanner;
public class Rope {
public static void main(String[] args) {
int N = 1, R=1;
double AoN=1;
float d=0 , e=0, f=0, h=0, s=0, length=0, g=0;;
Scanner in = new Scanner(System.in);
int[] arr = new int[2];
System.out.println("Enter number of Nails (N) and Radius of Nail (R) seperated by space: ");
for (int i=0;i<arr.length;i++) {
arr[i]=in.nextInt();
}
if (arr[0]>=1 && arr[0]<=100) {
N=arr[0]; // N is the number of rows of the multi-dimensional array and rows is fixed to 2 as coordinates are fixed to x and y so 2.
}
R=arr[1]; // kindly ignore R as it is used for other purpose.
float[ ][ ] arr1 = new float[N][2];
System.out.println("Enter Coordinates separated by spaces: ");
for(int i=0; i<N;i++) {
for (int j=0;j<2;j++) {
arr1[i][j]=in.nextFloat();
//System.out.println(arr1[i][j]);
}
}
float[] x = new float[N];
float[] y = new float[N];
for(int i=0; i<N;i++) {
x[i] = arr1[i][0];
}
for (int j=0;j<N;j++) {
y[j] = arr1[j][1];
}
for (int i=0; i<x.length-1;i++) {
d = (float) (d + (Math.pow((x[i+1] - x[i]),2)));
}
for (int i=0; i<y.length-1;i++) {
e = (float) (e + (Math.pow((y[i+1] - y[i]),2)));
}
g = d+e;
s = (float) Math.sqrt(g);
sysout(s);
in.close();
}
}

because you have a logical glitch in your code. Here if you notice in the following section :
for (int i=0; i<x.length-1;i++) {
d = (float) (d + (Math.pow((x[i+1] - x[i]),2)));
}
for (int i=0; i<y.length-1;i++) {
e = (float) (e + (Math.pow((y[i+1] - y[i]),2)));
}
Lets say,
x1-x2 = X1
x2-x3 = X2
and so on
similarly,
y1-y2 = Y1
y2-y3 = Y2
and so on
now what your code does is it calculates
sqrt(X1*X1 + X2*X2.... +Y1*Y1 + Y2*Y2....)
But what actually it is supposed to do is,
sqrt(Math.pow((X1-X2),2) + Math.pow(Y1-Y2),2)) + sqrt (Math.pow((X2-X3),2) + Math.pow((Y2-Y3), 2) + ...
thus your code generates wrong values.
You should try the following :
for (int i=0; i<x.length-1;i++) {
float temp;
temp = (Math.pow((x[i+1] - x[i]),2)) + (Math.pow((y[i+1] - y[i]),2));
d = (float) (d + sqrt(temp));
}
// for first and last values / coordinates w.r.t distance formula
for (int i=x.length-1; i<x.length;i++) {
float temp;
temp = (float) ((Math.pow((x[i] - x[0]),2)) + (Math.pow((y[i] - y[0]),2)));
d = (float) (d + Math.sqrt(temp));
}
Instead of that above mentioned two lines.
Hope this helps !!!

Related

neural net: bias seems to be ignored

I coded a very simple neural net with 1 neuron and 2 inputs and 1 bias in java, trying to classify dots on either the left or right side of a line. The problem is that the neural net recognizes the slope of the line but not the y-intercept (e.g. the function of the line may be y = m*x + c and the NN recognizes the m but not the c).
I tried to use a bias value=1 in order to enable the NN to calculate the weight for the bias which should be the y-intercept. But it doesnt. You will see that I am very new to Java programming. Unfortunately also new to NN. In that case I guess my problem is rather in the understanding of the underlying methodology of the bias in the NN.
Remark: In the output line at the very end of the code, I would expect in case of the function y = 3*x + 5 following figures: weight[0]=3 (which is the m) , weight[1]=1 (which is the factor for y) and weight[2]=5 (this is c). The weight[2] is always wrong.
package nn2;
public class anfang_eng {
public static void main(String[] args)
{
double[][] points = new double[5][10000];
double[] weights = new double[3];
double[][] normpoints = new double[5][10000];
// create 1000 dots with desired result for training afterwards
points = createPoints();
// the before randomly created x and y values of the 1000 dots
// shall be normalized between 0 and 1
normpoints = normalize(points);
// create two random initial weights
weights = createinitialWeights();
// training function, calculation of three different weights
calculateWeights(normpoints, weights);
testnewPoints(weights);
}
// thats the function of the line, that seperates all dots in
// two groups: all the dots at the left side of the line and all the dots
// at the right side.
static double function(double x, double y)
{
double result;
result = 3*x - y + 5;
return result;
}
static double[][] createPoints()
{
// 1. step: lets create for training reasons some dots and calculate
// the result for each dot (result is either "1" or "-1").
// point[0] is x, point[1] is y, point[2] is bias and point[3] is
// result (left or right side of the function above
int x;
int y;
int quantity= 1000;
double[][] point = new double[5][quantity];
for (int i=0; i<quantity; i++)
{
x = (int) (2000 * Math.random()-1000);
y = (int) (2000 * Math.random()-1000);
point[0][i] = x;
point[1][i] = y;
// point[2] is our bias
point[2][i] = 1;
// all dots which are at the right side of the function above get
// result "1". otherwise "-1"
if ( function(x,y) > 0)
point[3][i] = 1;
else
point[3][i] =-1;
// point[3] contains the result
}
// in the variable point, there are e.g. 1000 or 5000 dots with x, y,
// bias and the result (1=left side and -1=right side)
return point;
}
// normalize x and y values between 0 and 1
static double[][] normalize(double[][]points)
{
int quantity = points[0].length;
double minpoint_x=1000;
double minpoint_y=1000;
double maxpoint_x=-1000;
double maxpoint_y=-1000;
double[][] normpoints = new double[5][quantity];
minpoint_x= points[0][0];
minpoint_y = points[1][0];
maxpoint_x = points[0][0];
maxpoint_y = points[1][0];
for (int i=0; i<quantity;i++)
{
if (points[0][i]<minpoint_x)
minpoint_x=points[0][i];
if (points[1][i]<minpoint_y)
minpoint_y=points[1][i];
if (points[0][i]>maxpoint_x)
maxpoint_x=points[0][i];
if (points[1][i]>maxpoint_y)
maxpoint_y=points[1][i];
}
for (int u=0; u<quantity; u++)
{
normpoints [0][u]= (points[0][u]-minpoint_x)/(maxpoint_x-minpoint_x);
normpoints [1][u]= (points[1][u]-minpoint_y)/(maxpoint_y-minpoint_y);
normpoints [2][u] = 1; //bias is always 1
normpoints [3][u] = points[3][u];
}
return normpoints;
}
static double[] createinitialWeights()
{
// creation of initial weights between -1 and 1
double[] weight = new double[3];
weight[0] = 2*Math.random()-1;
weight[1] = 2*Math.random()-1;
weight[2] = 2*Math.random()-1;
return weight;
}
static void calculateWeights(double[][] normpoints, double[] weight)
// new weight = weight + error * input * learning constant
// c is learning constant
{
double c = 0.01;
double error = 0;
double sumguess = 0;
double guess = 0;
int quantity = normpoints[0].length;
for (int i=0; i < quantity; i++)
{
// normpoint[0][i] stands for the factor at x, normpoint[0][i] is
// for y and normpoint[2][i] is for bias
sumguess = normpoints[0][i] * weight[0] + normpoints[1][i]*weight[1] + normpoints[2][i]*weight[2];
if (sumguess > 0)
guess = 1;
else
guess = -1;
error = normpoints[3][i]- guess;
weight[0] = weight[0] + error * normpoints[0][i] * c;
weight[1] = weight[1] + error * normpoints[1][i] * c;
weight[2] = weight[2] + error * normpoints[2][i] * c;
System.out.println("i: " + i + " ;value_normpoint[0]:" + normpoints[0][i]+ " ;value_normpoint[1]" + normpoints[1][i]+ " ;value_normpoint[2]" + normpoints[2][i] + " result:" + normpoints[3][i]);
System.out.println("weight[0]: " + Math.round(weight[0]*100)/100.0 + " ;weight[1]: " +Math.round(weight[1]*100)/100.0 + " ;weight[2]: " + Math.round(weight[2]*100)/100.0 );
System.out.println("guess: "+ guess+ " result " + normpoints[3][i] + " error: " + error);
System.out.println();
}
System.out.println("final weights: x: " + weight[0] + " y: "+ weight[1] + " bias: " +weight[2]);
System.out.println("final weights normalized on y=1: x:" + weight[0]/weight[1] + " y: "+ weight[1]/weight[1] + " bias: " +weight[2]/weight[1]);
}
// lets test if the trained weights classify the test dot on the correct side of the line y=4*x+3
// again 500 random dots with "x", "y" and "results" are created and tested if the NN calculated correct weights
static void testnewPoints(double[] weights)
{
int x;
int y;
double[][] testpoint = new double[5][10000];
double[][] normalizedtestpoint = new double[5][10000];
int quantity = 500;
double sumcheck = 0;
double sumtest = 0;
int correct = 0;
int wrong = 0;
for (int i=0; i<quantity; i++)
{
// calculation of test points with x and y between -100 and 100
x = (int) (200 * Math.random()-100);
y = (int) (200 * Math.random()-100);
testpoint[0][i] = x;
testpoint[1][i] = y;
testpoint[2][i] = 1;
// lets classify the points: at the rights side of the line the result for each point is "1", on the left side "-1"
if (function(x,y) > 0)
testpoint[3][i] = 1;
else
testpoint[3][i] = -1;
// punkt[3] is the result
}
normalizedtestpoint= normalize(testpoint);
// are the test points with our calculated weights classified on the correct side of the line?
for (int i=0; i<quantity; i++)
{
sumcheck = normalizedtestpoint[0][i] * weights[0] + normalizedtestpoint[1][i] * weights[1] + normalizedtestpoint[2][i] * weights[2];
if (sumcheck > 0)
sumtest = 1;
else
sumtest = -1;
if (sumtest == normalizedtestpoint[3][i])
correct++;
else
wrong++;
}
System.out.println("correct: "+ correct + " wrong: " + wrong);
}
}
Please let me also know if you see some major issues in my coding style, quite an beginner style I guess.
Many thanks in advance!
Lonko

Reducing time complexity of bilinear interpolation

I use bilinear interpolation in my android application. It runs perfectly, but takes a lot of time to get the result.
I test it when xi = 259,920, and yi also = 259,920. The time to response was: Galaxy Note 4 takes 3 sec,
and HTC One M8 takes about 8 sec !. So what I can change or use to reduce the time?!
The code I use for bilinear interpolation:
public static double[] BiInterp(Mat z, ArrayList < Double > xi, ArrayList < Double > yi) {
// Declare matrix indeces
int xi_i, yi_i;
// Initialize output vector
double zi[] = new double[xi.size()];
double s00, s01, s10, s11;
for (int i = 0; i < xi.size(); i++) { // Note: xi.length = yi.length !
xi_i = xi.get(i).intValue(); // X index without round
yi_i = yi.get(i).intValue(); // Y index without round
if (xi_i < z.rows() - 1 && yi_i < z.cols() - 1 && xi_i >= 0 && yi_i >= 0) {
// Four neighbors of sample pixel
s00 = z.get(xi_i,yi_i)[0]; s01 = z.get(xi_i,yi_i + 1)[0];
s10 = z.get(xi_i + 1,yi_i)[0];s11 = z.get(xi_i + 1,yi_i + 1)[0];
int neighbor_no = 4; // As bilinear interpolation take 4 neighbors
double A[][] = new double[neighbor_no][neighbor_no];
A[0][0]=xi_i; A[0][1]=yi_i; A[0][2]=xi_i*yi_i; A[0][3]=1;
A[1][0]=xi_i; A[1][1]=yi_i+1; A[1][2]=xi_i*(yi_i+1); A[1][3]=1;
A[2][0]=xi_i+1; A[2][1]=yi_i; A[2][2]=(xi_i+1)*yi_i; A[2][3]=1;
A[3][0]=xi_i+1; A[3][1]=yi_i+1; A[3][2]=(xi_i+1)*(yi_i+1); A[3][3]=1;
GaussianElimination solveE = new GaussianElimination();
double b[] = {s00,s01,s10,s11};
double x[] = solveE.solve(A, b);
zi[i] = xi.get(i)*x[0] + yi.get(i)*x[1] + xi.get(i)*yi.get(i)*x[2] + x[3];
}
}
return zi;
}
and I use Gaussian elimination to solve the equation of 4 unknown
private static final double EPSILON = 1e-10;
// Gaussian elimination with partial pivoting
public static double[] solve(double[][] A, double[] b) {
int N = b.length;
for (int p = 0; p < N; p++) {
// find pivot row and swap
int max = p;
for (int i = p + 1; i < N; i++) {
if (Math.abs(A[i][p]) > Math.abs(A[max][p])) {
max = i;
}
}
double[] temp = A[p];
A[p] = A[max];
A[max] = temp;
double t = b[p];
b[p] = b[max];
b[max] = t;
// singular or nearly singular
if (Math.abs(A[p][p]) <= EPSILON) {
throw new RuntimeException("Matrix is singular or nearly singular");
}
// pivot within A and b
for (int i = p + 1; i < N; i++) {
double alpha = A[i][p] / A[p][p];
b[i] -= alpha * b[p];
for (int j = p; j < N; j++) {
A[i][j] -= alpha * A[p][j];
}
}
}
// back substitution
double[] x = new double[N];
for (int i = N - 1; i >= 0; i--) {
double sum = 0.0;
for (int j = i + 1; j < N; j++) {
sum += A[i][j] * x[j];
}
x[i] = (b[i] - sum) / A[i][i];
}
return x;
}
As you see in the bilinear code, I take the pixels intensities immediately from the Mat object. However, when I used matrix it takes much less time, such as with note 4 takes 1 sec.
But to convert from Mat image to matrix takes 4 sec. So I preferred to use Mat.
Here is a more simple bilinear interpolation algorithm:
Find the fractional part of yi and use it to interpolate between s00 and s01 to find s0, and between s10 and s11 to find s1
Find the fractional part of xi and use it to interpolate between s0 and s1 to find zi
Basically you are decomposing it into three simple linear interpolations. You can visualize it as an H shape. First you interpolate down the left and right posts of the H to get values part way down each. Then you interpolate along the cross-beam to get the final value in the middle.
The code would be something like this:
xi_i = xi.get(i).intValue(); // X index without round
yi_i = yi.get(i).intValue(); // Y index without round
if (xi_i < z.rows() - 1 && yi_i < z.cols() - 1 && xi_i >= 0 && yi_i >= 0) {
// Four neighbors of sample pixel
s00 = z.get(xi_i,yi_i)[0]; s01 = z.get(xi_i,yi_i + 1)[0];
s10 = z.get(xi_i + 1,yi_i)[0];s11 = z.get(xi_i + 1,yi_i + 1)[0];
// find fractional part of yi:
double yi_frac = yi.get(i) - (double)yi_i;
// interpolate between s00 and s01 to find s0:
double s0 = s00 + ((s01 - s00) * yi_frac);
// interpolate between s10 and s11 to find s1:
double s1 = s10 + ((s11 - s10) * yi_frac);
// find fractional part of xi:
double xi_frac = xi.get(i) - (double)xi_i;
// interpolate between s0 and s1 to find zi:
zi[i] = s0 + ((s1 - s0) * xi_frac);
}
You could also speed the whole thing up (at the expense of accuracy) by using fixed point integers instead of doubles.

Monte Carlo Simulation of Pi in simple java?

I am trying to do the famous Monte Carlo simulation to estimate pi for my Java course.
Here is the Simulation:
public class Darts
{
//"throwing" a dart
public static boolean [] dartThrow(int r, int d){
boolean [] booleanArray = new boolean[d];
for(int i = 0; i < d; i++){
double xCoord = Math.random() * 2;
double yCoord = Math.random() * 2;
if((Math.pow(xCoord,2) + Math.pow(yCoord,2)) <= r){
booleanArray[i] = true;
}
else{
booleanArray [i] = false;
}
}
return booleanArray;
}
//calculating pi from throwing results
public static double piEstimater(boolean [] h, int d){
int trueCounter = 0;
for(int i = 0; i < h.length; i++){
if(h[i] == true){
trueCounter++;
}
}
return 4 * ((double)trueCounter / d);
}
//printing results
public static void printer(double [] a){
System.out.println(" Pi Estimation Tool ");
System.out.println("---------------------------");
for(int i = 0; i < a.length; i++){
System.out.print("Trial [" + i + "]: pi = ");
System.out.printf("%6f\n", a[i]);
}
}
public static void main(String[] args){
//variables
Scanner in = new Scanner(System.in);
int radius = 1;
int darts;
int trials;
System.out.println("Enter the number of darts to calculate for: ");
darts = in.nextInt();
System.out.println("Enter the number of trials to calculate for: ");
trials = in.nextInt();
double [] arrayOfEstimates = new double [trials];
int i = 0;
for(double a : arrayOfEstimates){
boolean [] hitCounter = dartThrow(radius, darts);
double piEstimate = piEstimater(hitCounter, darts);
arrayOfEstimates[i] = piEstimate;
i++;
}
printer(arrayOfEstimates);
}
}
I have created code that executes correctly, except for that the results never go above ~ .8. I would like to just assume that this is happening because the random numbers are so low, but if it happens every time something HAS to be wrong, right? Please keep in mind that this code contains about all the Java techniques I know, so I would appreciate it if you kept from including anything more "advanced." Thanks!
The idea of the calculation of PI using the Monte Carlo method is to sample random points in a square, and count the fraction of them that fall within the area of a circle bound by that square. If enough points are uniformly sampled, the fraction would be close to the area of the circle divided by the area of the bounding square :
fraction = PI*r^2/(2r)^2
and therefore
PI = fraction * 4.
Now, since you are sampling only positive coordinates, if we assume that the circle is centered at the origin (0,0), we only sample points within the top-right quarter of the circle and its bounding square, but the equation remains the same.
If your circle has radius r, you should sample coordinates between 0 and r.
Therefore you should change this :
double xCoord = Math.random() * 2;
double yCoord = Math.random() * 2;
To this :
double xCoord = Math.random() * r;
double yCoord = Math.random() * r;
In addition the condition should be ((Math.pow(xCoord,2) + Math.pow(yCoord,2)) <= r*r).
Of course, you can simplify it by eliminating r and assuming the radius is 1.
In that case the condition would be ((Math.pow(xCoord,2) + Math.pow(yCoord,2)) <= 1) and the coordinates would be sampled between 0 and 1.

making a range for data points in java

If a user enters a value for
x y and z coordinates, what steps would need to take in order to create a range from -x/y/z to +x/y/z? Is there a function that will give the numbers in that range even though a double is entered?
This is my code so far im not finished yet, I'm not sure if its right. After it gets the x,y,z points and the number of data points the user wants, it will then print the n number of points with random points (x , y, z) x, y, z being anywhere from -x to x etc.
import java.io.*;
public class MultiDimArray
{
public static void main (String [] args) throws IOException
{
BufferedReader myInput = new BufferedReader (new InputStreamReader (System.in));// Buffered Reader reads the number inputed
double range;
System.out.println("How many points do you want returned? ");
String numPointsA = myInput.readLine();
int numPoints = Integer.parseInt(numPointsA);
System.out.println("Enter X length: ");
String xlengthA = myInput.readLine();
double xlength = Double.parseDouble(xlengthA);
System.out.println("Enter Y length: ");
String ylengthA = myInput.readLine();
double ylength = Double.parseDouble(ylengthA);
System.out.println("Enter Z length: ");
String zlengthA = myInput.readLine();
double zlength = Double.parseDouble(zlengthA);
int[][][][] dataPoint = new int[3][xlength][ylength][zlength];
for (int i = 0; i < (xlength * 2); i++){
range = (0 -( xlength - i) + 1);
System.out.println(range);
}
for (int i = 0; i < (ylength * 2); i++){
range = (0 -( ylength - i) + 1);
}
for (int i = 0; i < (zlength * 2); i++){
range = (0 -( zlength - i) + 1);
}
}
}
range is infinite if you want to include all fractional numbers otherwise you can do that manually.
for (int i=-x; i<=x; i++)
operate(i, y, z);
another solution for your problem is that you don't generate range.
you just store those values x y and z.
then, when you need to test if a number is in range you can do it easily with if statement.
what I mean that this a wrong way to design your solution. try to get values you want in another way. something like reverse engineering. then you test if those values are in range.
post your problem. then we can help you.
Code that generates numPointsA random numbers between -x and x:
Random random = new Random();
double start = -x;
double end = x;
for (int i=0;i<numPointsA;i++)
{
double ran = random.nextDouble();
double result = start + (ran * (end - start));
System.out.println(result);
}
To get a random number between 0 and n-1, use
Random rand = new Random();
int r = rand.nextInt(n);

Hill Climbing Code - Random Mutation

This code should compare two fitnesses, use the best one to find the solution and then it uses the best one in the next iteration. However the problem I get is that it is just using the newest fitness regardless of whether it is bigger or smaller. Can anyone help me spot if there are any mistakes in my code, thanks!
This was a little tricky to explain, so if anyone needs more clarification please ask and I'll post up my entire project, though I believe that the error has something to do with this small section of code:
public static ScalesSolution RMHC(ArrayList<Double> weights, int n, int iter) {
ScalesSolution sol = new ScalesSolution(n);
ScalesSolution oldSol = new ScalesSolution(sol.GetSol());
for (int i = 0; i < iter; i++) {
System.out.println("Iteration number: " + i);
System.out.println("Old Solution : ");
oldSol.println();
double f = oldSol.ScalesFitness(weights);
System.out.println("Old Fitness: ");
System.out.println(f);
// the new solution after copying the string from scalesolution
sol.SmallChange();
System.out.println("New Solution : ");
sol.println();
double f1 = sol.ScalesFitness(weights);
System.out.println("New Fitness: ");
System.out.println(f1);
if (oldSol.ScalesFitness(weights) > sol.ScalesFitness(weights)) {
oldSol = new ScalesSolution(sol.GetSol());
}
}
return (oldSol);
}
Here is SmallChange:
public void SmallChange() {
int n = scasol.length();
Random rand = new Random();
int p = (rand.nextInt(n));
String x;
x = scasol.substring(0, p);
if (scasol.charAt(p) == '0') {
x += '1';
} else {
x += '0';
}
x += scasol.substring(p + 1, n);
scasol = x;
}
Here is ScalesFitness and ScalesSolution:
public ScalesSolution(int n) {
scasol = RandomBinaryString(n);
}
// This is the fitness function for the Scales problem
// This function returns -1 if the number of weights is less than the size of the current solution
// Exercise 3
public static double ScalesFitness(ArrayList<Double> weights) {
int n = scasol.length(); // Assigns the length of scasol to n
double lhs = 0.0; // Initialises lhs to 0.0, type double
double rhs = 0.0; // Initialises rhs to 0.0, type double
if (n > weights.size()) // If statement, compares n and weight size
return (-1); // Returns -1 when the if statement is true
// Code goes here
for (int i = 0; i < n; i++) { // For loop which goes from i=0 to n
if (scasol.charAt(i) == '0') { // If statement which checks if the character at position i is equal to a 0
lhs += weights.get(i); // Adds weight at position i to lhs
} else { // If the character in position i is not a 0 do the following
rhs += weights.get(i); // Adds the weight at position i to rhs
}
}
return (Math.abs(lhs - rhs)); // Calculates the absolute value of lhs-rhs and returns the value
}

Categories