I have been trying to code a program whereby the user inputs an angle, assuming it is degrees, it gets converted from degrees to radians and then calculates its sine or cosine. I tried to do this in a way which is convenient for the user but it turns out I have some issues trying to calculate both of these(cosine and sine) and outputting correct results. I appreciate your help. Also assuming constant number of terms which is 30.
import java.util.Scanner;
public class Question8 {
public static double radians(double angle)
{
double pi = 3.141592653589793238462643;
return angle / 180.0 * pi; //conversion from degrees to radians
}
public static void main( String [] args)
{
Scanner sc = new Scanner(System.in);
int sw = 0, n, j=1, m=-1;
double sine, i=0, r=0, cosine, c=0, rad; //initialising variables of type double and int
do{
System.out.println("Please input either 1 or 2 to calculate Sine or Cosine respectively.");
sw = sc.nextInt();
switch(sw) { //implementing a switch to differentiate between sine and cosine
case 1:{ //this calculates the sine
System.out.println("Please input Angle and n (number of terms) to calculate sine");
sine = sc.nextDouble();
n = sc.nextInt();
rad = radians(sine);
i = rad;
for(int k = 3; k < n; k = k+2) {
double o = Math.pow(rad,k);
j = j*(k-1)*k;
r = o/j;
i=i+m*r;
m=m*(-1);
}
System.out.println("Sine " + sine + " = " + i);
}
break;
case 2:{ //this calculates cosine
System.out.println("Please input angle and n to calculate cosine");
cosine = sc.nextDouble();
n = sc.nextInt();
rad = radians(cosine);
c = 1.0;
for(int k = 2; k < n; k = k+2) {
double o = Math.pow(rad,k);
j = j*(k-1)*k;
r = o/j;
c=c+m*r;
m = m*(-1);
}
System.out.println("Cosine " + cosine + " = " + c);
}
break;
default: {
System.out.println("Invalid choice"); //user selects invalid numbers
}
break;
}
} while(sw != 0);
}
}
Your algorithm for calculating sin and cos is correct. You should reinitialize variables m,j and r after each calculus. You can use CORDIC algorithm or chebyshev polynomial as more accurate substitute for Taylor series.
Related
this is my first post here!
So, as an extra credit project for my Calculus course, the professor offered us an opportunity to write a simple program that calculates the area under a user specified curve. I realize this isn't the best way to implement this, but he say's that's fine, but I think this is giving me the wrong answer. Could anyone help?
import java.util.*;
public class RiemannSum2 {
public static void main(String args []) {
System.out.println("This is a Riemann Sum Calculator. This calculator accepts polynomials in the form of a(x)^ex + b(x)^ex2 + c, where c is a constant.");
System.out.print("Enter the first coeffecient of the polynomial: ");
Scanner sc = new Scanner(System.in);
int firstCoe = sc.nextInt();
System.out.print("Enter the exponent of the first term: ");
int firstExp = sc.nextInt();
System.out.print("Enter the second coeffecient of the polynomial: ");
int secondCoe = sc.nextInt();
System.out.print("Enter the exponent of the second term: ");
int secondExp = sc.nextInt();
System.out.print("Enter the third term of the polynomial: ");
int thirdTerm = sc.nextInt();
System.out.print("Enter the x value that you want to start the Riemann Sum: ");
int startX = sc.nextInt();
System.out.print("Enter the x value to stop the Riemann Sum: ");
int endX = sc.nextInt();
String poly = (firstCoe+"x^"+firstExp+"+"+secondCoe+"x^"+secondExp+"+"+thirdTerm);
System.out.println("Your polynomial is: "+poly);
System.out.print("Enter the number of rectangles you want: ");
int rectangles = sc.nextInt();
double numerator = (endX-startX);
double rectanglesD = (double)rectangles;
double constantWidth = numerator/rectanglesD;
System.out.println("This is the constant width: " + constantWidth);
double totalSum = 0;
//System.out.println(totalSum);
for(int i = 0; i < rectangles ; i++) {
totalSum = totalSum+((Math.pow((firstCoe * (i/constantWidth)), firstExp)) + (Math.pow((secondCoe * (i/constantWidth)), secondExp))+thirdTerm);
}
totalSum = totalSum*constantWidth;
System.out.println("The Riemann Sum of your polynomial is roughly equivalent to: "+ totalSum);
}
}
You use (i/constantWidth) to calculate the argument of your function (x). However, it should be
double x = startX + i * constantWidth;
Furthermore, your coefficients should be outside of the pow function. Otherwise, they will get exponentiated too. Removing some of the superfluous parentheses makes the formula a lot easier to read. Like this:
double x = startX + i * constantWidth;
totalSum = totalSum
+ firstCoe * Math.pow(x, firstExp)
+ secondCoe * Math.pow(x, secondExp)
+ thirdTerm;
Unrelated to the code: Since you have a simple polynomial, you can calculate the antiderivative analytically and simply evaluate that function instead.
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
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 !!!
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.
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);