neural net: bias seems to be ignored - java

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

Related

Java: Collections.max return largest number error

Given a loop, I want to print the largest number four times. There are total_A, total_B, total_C and find the largest number among these three. But I'm facing some problems of getting the correct maximum number. The output for data training no.1 and no.4 are correct which return the largest number, but no.2 and no.3 are wrong. Below is my output:
Updated output
Below is my code:
public class Multiclass2 {
public static void main(String args []){
double x [][] = {{3.24,-0.96},
{-1.56,-0.61},
{-1.1,2.5},
{1.36,-4.8};
double [] wA = {0,1.94,3.82};
double [] wB = {0,-4.9,-4.03};
double [] wC = {0,4.48,3.25};
double threshold = 1;
int n = x.length;
double total_A = 0;
double total_B = 0;
double total_C = 0;
List<Double> li = new ArrayList<Double>();
double max = 0;
for(int i=0;i<n;i++){
System.out.println("For training data point no." + (i+1));
total_A = (threshold * wA[0]) + (x[i][0] * wA[1]) + (x[i][1] * wA[2]);
total_B = (threshold * wB[0]) + (x[i][0] * wB[1]) + (x[i][1] * wB[2]);
total_C = (threshold * wC[0]) + (x[i][0] * wC[1]) + (x[i][1] * wC[2]);
li.add(total_A);
li.add(total_B);
li.add(total_C);
max = Collections.max(li);
System.out.println(total_A+", "+total_B+", "+total_C);
System.out.println("MAx is "+max);
}
}
}
You're using the same collection accross the entire loop, so you're calculating the max of ALL data points. You made two code style mistakes which allowed this bug to happen:
firstly, you did not choose the appropriate scope for your variables. Since they're local to the loop, they should be declared inside the loop, not outside
secondly, constructing a collection for calculating the max of a fixed, small number of numbers is overkill. Just use Math.max(a, Math.max(b, c))
The corrected code would be:
public static void main(String args[]) {
double x[][] = {
{ 3.24, -0.96 },
{ -1.56, -0.61 },
{ -1.1, 2.5 },
{ 1.36, -4.8 }
};
double[] wA = { 0, 1.94, 3.82 };
double[] wB = { 0, -4.9, -4.03 };
double[] wC = { 0, 4.48, 3.25 };
double threshold = 1;
int n = x.length;
for (int i = 0; i < n; i++) {
System.out.println("For training data point no." + (i + 1));
double total_A = (threshold * wA[0]) + (x[i][0] * wA[1]) + (x[i][1] * wA[2]);
double total_B = (threshold * wB[0]) + (x[i][0] * wB[1]) + (x[i][1] * wB[2]);
double total_C = (threshold * wC[0]) + (x[i][0] * wC[1]) + (x[i][1] * wC[2]);
double max = Math.max(total_A, Math.max(total_B, total_C));
System.out.println(total_A + ", " + total_B + ", " + total_C);
System.out.println("Max is " + max);
}
}

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.

java Sine(x) Taylor Series

Can someone help me for geting out this code of sin(x) Tailor function to get followings:
The first 4 sin(x) Tailor series.
To calculating the sin function using the sum-formel
How to write a method public static double MySinApproximate( double x)?
That is what i get so far, and it has to be in this way!!
import java.lang.Math;
public class mysin {
public static void main(String[] args){
double x= Math.PI;
System.out.println( MySin(x) + "\t \t" + Math.sin(x) + "\n" );
}
public static double MySin(double x){
double sumNeu, sumOld, sum;
int i = 1;
sum = sumNeu = x; // This should calculating the first term Value
do //the loop do will calculating the Tailor Series
{
sumOld = sumNeu;
i++; sum = + sum * x * x / i;
i++; sum = sum / i;
sumNeu = sumOld + sum;
}
while( sumNeu != sumOld);
return sumNeu;
}
} // 11.548739357257745 1.2246467991473532E-16 (as output)
Your loop isn't calculating the Taylor series correctly. (This is really a Maclaurin series, which is the special case of a Taylor series with a = 0.) For the sine function, the terms need to be added and subtracted in an alternating fashion.
sin(x) = x - x3/3! + x5/5! - ...
Your method only adds the terms.
sin(x) = x + x3/3! + x5/5! + ...
Flip the sign of sum on each iteration, by adding the designated line:
do // The loop will calculate the Taylor Series
{
sumOld = sumNeu;
i++; sum = + sum * x * x / i;
i++; sum = sum / i;
sum = -sum; // Add this line!
sumNeu = sumOld + sum;
}
With this change I get a result that is very close:
2.3489882528577605E-16 1.2246467991473532E-16
Due to the inherent inaccuracies of floating-point math in Java (and IEEE in general), this is likely as close as you'll get by writing your own sine method.
I tested an additional case of π/2:
System.out.println( MySin(x/2) + "\t \t" + Math.sin(x/2) + "\n" );
Again, it's close:
1.0000000000000002 1.0
1.I want to write all again like that -
2.I try to writing the first 4 series from sine Taylor and the proximity all together but anyhow doesn't work correctly -
3.i get this output
0.0 0.8414709848078965
0.8414709848078965 0.9092974268256817
0.8414709848078965 0.1411200080598672
0.9092974268256817 -0.7568024953079282
4.How can i get the same accuracy
1.0000000000000002 1.0
and the series of sine(x)?
public class MySin {
public static void main(String[] args){
double y = 0;
y = 4;
for (int i = 1; i<= y; i++){
System.out.println( MySin(i/2) + "\t \t" + Math.sin(i) + "\n" );
}
}
public static double MySin(double x){
double sumNew, sumOld, sum;
int i = 1;
sum = sumNew = x; // This should calculating the first term Value
do //the loop do will calculating the Tailor Series
{
sumOld = sumNew;
i++; sum = - sum * x * x / i; // i did change the sign to -
i++; sum = sum / i;
sum = - sum; // so i don't need this line anymore
sumNew = sumOld + sum;
}
while( sumNew != sumOld);
return sumNew;
}
public static double MySineProximity ( double x) {
while ( x <= ( Math.PI /2 ) )
{
x = 0;
}
return MySin (x);
}
}

modify perceptron to become gradient descent

According to this video the substantive difference between the perceptron and gradient descent algorithms are quite minor. They specified it as essentially:
Perceptron: Δwi = η(y - &ycirc;)xi
Gradient Descent: Δwi = η(y - α)xi
I've implemented a working version of the perceptron algorithm, but I don't understand what sections I need to change to turn it into gradient descent.
Below is the load-bearing portions of my perceptron code, I suppose that these are the components I need to modify. But where? What do I need to change? I don't understand.
This is left for pedagogical reasons, I've sort of figured this out but am still confused about the gradient, please see UPDATE below
iteration = 0;
do
{
iteration++;
globalError = 0;
//loop through all instances (complete one epoch)
for (p = 0; p < number_of_files__train; p++)
{
// calculate predicted class
output = calculateOutput( theta, weights, feature_matrix__train, p, globo_dict_size );
// difference between predicted and actual class values
localError = outputs__train[p] - output;
//update weights and bias
for (int i = 0; i < globo_dict_size; i++)
{
weights[i] += ( LEARNING_RATE * localError * feature_matrix__train[p][i] );
}
weights[ globo_dict_size ] += ( LEARNING_RATE * localError );
//summation of squared error (error value for all instances)
globalError += (localError*localError);
}
/* Root Mean Squared Error */
if (iteration < 10)
System.out.println("Iteration 0" + iteration + " : RMSE = " + Math.sqrt( globalError/number_of_files__train ) );
else
System.out.println("Iteration " + iteration + " : RMSE = " + Math.sqrt( globalError/number_of_files__train ) );
}
while(globalError != 0 && iteration<=MAX_ITER);
This is the crux of my perceptron:
static int calculateOutput( int theta, double weights[], double[][] feature_matrix, int file_index, int globo_dict_size )
{
//double sum = x * weights[0] + y * weights[1] + z * weights[2] + weights[3];
double sum = 0;
for (int i = 0; i < globo_dict_size; i++)
{
sum += ( weights[i] * feature_matrix[file_index][i] );
}
//bias
sum += weights[ globo_dict_size ];
return (sum >= theta) ? 1 : 0;
}
Is it just that I replace that caculateOutput method with something like this:
public static double [] gradientDescent(final double [] theta_in, final double alpha, final int num_iters, double[][] data )
{
final double m = data.length;
double [] theta = theta_in;
double theta0 = 0;
double theta1 = 0;
for (int i = 0; i < num_iters; i++)
{
final double sum0 = gradientDescentSumScalar0(theta, alpha, data );
final double sum1 = gradientDescentSumScalar1(theta, alpha, data);
theta0 = theta[0] - ( (alpha / m) * sum0 );
theta1 = theta[1] - ( (alpha / m) * sum1 );
theta = new double [] { theta0, theta1 };
}
return theta;
}
UPDATE EDIT
At this point I think I'm very close.
I understand how to calculate the hypothesis and I think I've done that correctly, but nevertheless, something remains terribly wrong with this code. I'm pretty sure it has something to do with my calculation of the gradient. When I run it the error fluctuates wildly and then goes to infinity then just NaaN.
double cost, error, hypothesis;
double[] gradient;
int p, iteration;
iteration = 0;
do
{
iteration++;
error = 0.0;
cost = 0.0;
//loop through all instances (complete one epoch)
for (p = 0; p < number_of_files__train; p++)
{
// 1. Calculate the hypothesis h = X * theta
hypothesis = calculateHypothesis( theta, feature_matrix__train, p, globo_dict_size );
// 2. Calculate the loss = h - y and maybe the squared cost (loss^2)/2m
cost = hypothesis - outputs__train[p];
// 3. Calculate the gradient = X' * loss / m
gradient = calculateGradent( theta, feature_matrix__train, p, globo_dict_size, cost, number_of_files__train);
// 4. Update the parameters theta = theta - alpha * gradient
for (int i = 0; i < globo_dict_size; i++)
{
theta[i] = theta[i] - LEARNING_RATE * gradient[i];
}
}
//summation of squared error (error value for all instances)
error += (cost*cost);
/* Root Mean Squared Error */
if (iteration < 10)
System.out.println("Iteration 0" + iteration + " : RMSE = " + Math.sqrt( error/number_of_files__train ) );
else
System.out.println("Iteration " + iteration + " : RMSE = " + Math.sqrt( error/number_of_files__train ) );
//System.out.println( Arrays.toString( weights ) );
}
while(cost != 0 && iteration<=MAX_ITER);
}
static double calculateHypothesis( double[] theta, double[][] feature_matrix, int file_index, int globo_dict_size )
{
double hypothesis = 0.0;
for (int i = 0; i < globo_dict_size; i++)
{
hypothesis += ( theta[i] * feature_matrix[file_index][i] );
}
//bias
hypothesis += theta[ globo_dict_size ];
return hypothesis;
}
static double[] calculateGradent( double theta[], double[][] feature_matrix, int file_index, int globo_dict_size, double cost, int number_of_files__train)
{
double m = number_of_files__train;
double[] gradient = new double[ globo_dict_size];//one for bias?
for (int i = 0; i < gradient.length; i++)
{
gradient[i] = (1.0/m) * cost * feature_matrix[ file_index ][ i ] ;
}
return gradient;
}
The perceptron rule is just an approximation to the gradient descent when you have non-differentiable activation functions like (sum >= theta) ? 1 : 0. As they ask in the end of the video, you cannot use gradients there because this threshold function isn't differentiable (well, its gradient is not defined for x=0 and the gradient is zero everywhere else). If, instead of this thresholding, you had a smooth function like the sigmoid you could calculate the actual gradients.
In that case your weight update would be LEARNING_RATE * localError * feature_matrix__train[p][i] * output_gradient[i]. For the case of sigmoid, the link I sent you also shows how to calculate the output_gradient.
In summary to change from perceptrons to gradient descent you have to
Use an activation function whose derivative (gradient) is not zero
everywhere.
Apply the chain rule to define the new update rule

finding the length given the coordinates for a polygon

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 !!!

Categories