Calculating Average and Standard Deviation using do while loop - java

I am trying to write a program which asks the user for a series of positive values and computes the mean and standard deviation of those values having the input stop when the user enters -1. I seem to have the average part down however. I can't seem to get the standard deviation.
So far this is what I have.
import java.util.Scanner;
public class HW0402
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
double x;
double sum = 0;
double average = 0;
double dev = 0;
double var = 0;
double sqrx = 0;
int n = 0;
do
{
System.out.println("Enter positive values, enter -1 to end");
x = input.nextInt();
if (x == -1)
{
break;
}
sum += x;
n++;
average = sum / n;
sqrx += Math.pow(x-average,2);
var = sqrx / (n-1);
dev = Math.sqrt(var);
} while (x != -1);
System.out.println("Average: " + average);
System.out.println("Deviation: " + dev);
}
}
I seem to get odd results such as decimals when simply calculating sqrx += x- average
I'm new to java and haven't leaned alternatives to this problem, I would love it if someone pointed me in the right direction on what I should do, or explain what I did wrong.
Apologies ahead of time for any novice mistakes I made.

int n = 0;
int K = 0;
double Sum = 0;
double Sum_sqr = 0;
do {
System.out.println("Enter positive values, enter -1 to end");
x = input.nextInt();
if (x == -1)
{
break;
}
if ( n == 0 ) K = x;
n++;
Sum += (x - K);
Sum_sqr += (x - K) * (x - K);
} while (x != -1);
double mean = K + Sum / n;
double varPop = (Sum_sqr - (Sum*Sum)/n) / (n);
double varSample = (Sum_sqr - (Sum*Sum)/n) / (n-1);
double devPop = Math.sqrt(varPop);
double devSample = Math.sqrt(varSample);
Reference Wikipedia: Computing Shifted Data. Also, Population or Sample, makes a difference.

Related

How to calculate the difference of a specific term inside a for loop in each iteration with the previous iteration?

Here i am calculating the value of Pi using Gregory-Leibniz series which is an infinite series.I want to calculate the value of pi in each iteration of for loop and compare is to the previous iteration so i can calculate the difference. Further i want to stop the iteration when the difference is less than or equal to 0.001 . How to do it???Please help me.
import java.util.*;
import java.lang.Math;
class ValueOfPi{
public static void main(String[] args) {
double currentTerm = 0;
double pi = 0.0;
int odd = 1;
Scanner sc = new Scanner(System.in);
System.out.println("Enter number of terms:");
int x = sc.nextInt();
for(int i = 1;i<=x;i++) {
if(i%2 == 0) {
currentTerm = (double) -4/odd;
}
else {
currentTerm = (double) 4/odd;
}
odd=odd+2;
pi=pi+currentTerm;
}
System.out.println("The value of pi:"+pi);
}
}
Just keep a variable(here: previous_pi) from the past calculation and compare it with the new calculation of pi.
double currentTerm = 0;
double pi = 0.0;
double previous_pi = 0.0;
int odd = 1;
Scanner sc = new Scanner(System.in);
System.out.println("Enter number of terms:");
int x = sc.nextInt();
for(int i = 1;i<=x;i++) {
previous_pi = pi;
if(i%2 == 0) {
currentTerm = (double) -4/odd;
}
else {
currentTerm = (double) 4/odd;
}
odd=odd+2;
pi=pi+currentTerm;
//Find the difference from the previous calculation of pi
System.out.println("Difference from previous calculation: " + Math.abs(pi-previous_pi));
//Stop the iteration when the difference is less than or equal to 0.001
if(Math.abs(pi - previous_pi) <= 0.001){
break;
}
}
System.out.println("The value of pi:"+pi);
}

Taylor series. Program does fewer iterations

So I am required to recursively calculate e^x using a factored form of a Taylor series:
equation: e^x = 1 +x + (x^2)/2! + ... + ((x^n)/n!))
U(n) = U(n-1)*(x/n)
break point |U(n)| < eps
package lab2;
import java.util.Scanner;
public class Lab2 {
public static void main(String[] args) {
// TODO code application logic here
Scanner in = new Scanner(System.in);
System.out.println("Enter x: ");
int x = in.nextInt();
System.out.println("Enter 0 < e < 1: ");
double e = in.nextDouble();
double result = 1.0;
int n = 1;
double U = x / n;
while (Math.abs(U) >= e)
{
double fa = 1;
for (int i = 1; i <= n; i++)
fa *= i;
result += Math.pow(x, n) / fa;
U *= x / ++n;
}
System.out.println("e^x = " + result);
}
}
It works only x+1 times and then debug says U equals 0 and its our break point. I can't get why this happens. Can you please help me?
Since x and n are integer, dividing them will be done using integer division. Only after the division is down is the result promoted to a double in order to store in U. In order to perform floating point division you could either define x as a double or explicitly cast it when you divide:
double U = ((double) x) / n;

Return how many terms are necessary entering a level of precision, e.g .001, to come within the specified precision of the value of PI?

Problem: Interactively enter a level of precision, e.g., .001, and then report how many terms are necessary for each of these estimates to come within the specified precision of the value of pi.
My Solution So Far:
Current result does not terminate. The PIEstimator class driver is given. The problem lies inside the PIEstimates class. Some specific questions that I have:
How do you calculate Wallis PI and Leibniz PI in code? The ways for calculating each arithmetically for Wallis is:
pi/4 = (2/3)(4/3)(4/5)(6/5)(6/7)(8/7)(8/9)*...
and for Leibniz:
pi/4 = (1 - 1/3 + 1/5 - 1/7 + 1/9 ...)
Is the current logic of doing this code correct so far? Using a while loop to check if the respective PI calculation is within the limits, with a for loop inside continuing to run until the while requirements are met. Then there is a count that returns the number of times the loop repeated.
For .001, for example, how many terms does it take for each of these formulas to reach a value between 3.14059.. and 3.14259...
import java.util.Scanner;
public class PiEstimator {
public static void main(String[] args) {
System.out.println("Wallis vs Leibnitz:");
System.out.println("Terms needed to estimate pi");
System.out.println("Enter precision sought");
Scanner scan = new Scanner(System.in);
double tolerance = scan.nextDouble();
PiEstimates e = new PiEstimates(tolerance);
System.out.println("Wallis: " + e.wallisEstimate());
System.out.println("Leibnitz: " + e.leibnitzEstimate());
}
}
public class PiEstimates {
double n = 0.0;
double upperLim = 0;
double lowerLim = 0;
public PiEstimates(double tolerance) {
n = tolerance;
upperLim = Math.PI+n;
lowerLim = Math.PI-n;
}
public double wallisEstimate() {
double wallisPi = 4;
int count = 0;
while(wallisPi > upperLim || wallisPi < lowerLim) {
for (int i = 3; i <= n + 2; i += 2) {
wallisPi = wallisPi * ((i - 1) / i) * ((i + 1) / i);
}
count++;
}
return count;
}
public double leibnitzEstimate() {
int b = 1;
double leibnizPi = 0;
int count = 0;
while(leibnizPi > upperLim || leibnizPi < lowerLim) {
for (int i = 1; i < 1000; i += 2) {
leibnizPi += (4/i - 4/i+2);
}
b = -b;
count++;
}
return count;
}
}
At least one mistake in wallisEstimate
for (int i = 3; i <= n + 2; i += 2) {
should be count instead of n:
for (int i = 3; i <= count + 2; i += 2) {
... but still then the algorithm is wrong. This would be better:
public double wallisEstimate() {
double wallisPi = 4;
int count = 0;
int i = 3;
while(wallisPi > upperLim || wallisPi < lowerLim) {
wallisPi = wallisPi * ((i - 1) / i) * ((i + 1) / i);
count++;
i += 2;
}
return count;
}
Similarly, for the Leibniz function:
public double leibnitzEstimate() {
double leibnizPi = 0;
int count = 0;
int i = 1;
while(leibnizPi > upperLim || leibnizPi < lowerLim) {
leibnizPi += (4/i - 4/i+2);
count++;
i += 4;
}
return count;
}
For Leibnitz, I think the inner loop should only run count number of times:
for (int i = 1; i < count; i += 2) {
leibnizPi += (4/i - 4/i+2);
}
If it runs 1000 times every time you can't know when pi was in range.
If the while loops don't terminate, then they don't approach PI.
Wallis: pi/4 = (2/3)(4/3)(4/5)(6/5)(6/7)(8/7)(8/9)*...
The while loop would restart the for loop at i = 3 which would keep adding the same sequence of terms, rather than progressing along with the pattern.
Here's a draft of an alternative solution (no pun intended) based on the pattern of terms.
As you see, the numerators repeat, except for the 2. The divisors repeat aswell, but offset from the numerators: they increment in an alternating fashion.
This way you can actually count each individual terms, instead of pairs of them.
public double wallisEstimate() {
double wallisPi = 1;
int count = 0;
double numerator = 2;
double divisor = 3;
while(wallisPi > upperLim || wallisPi < lowerLim) {
wallisPi *= numerator / divisor;
if ( count++ & 1 == 0 )
numerator+=2;
else
divisor+=2;
}
return count;
}
There is one more change to make, and that is in the initialisation of upperLim and lowerLim. The algorithm approaches PI/2, so:
upperLim = (Math.PI + tolerance)/2;
lowerLim = (Math.PI - tolerance)/2;
Leibniz: pi/4 = (1 - 1/3 + 1/5 - 1/7 + 1/9 ...)
Here the for loop is also unwanted: at best, you will be counting increments of 2000 terms at a time.
The pattern becomes obvious if you write it like this:
1/1 - 1/3 + 1/5 - 1/7 ...
The divisor increments by 2 for every next term.
public double leibnitzEstimate() {
double leibnizPi = 0;
int divisor = 1;
int count = 0;
while(leibnizPi > upperLim || leibnizPi < lowerLim) {
leibnizPi += 1.0 / divisor;
divisor = -( divisor + 2 );
count++;
}
return count;
}
The update of leibnizPi can also be written like this:
leibnizPi += sign * 1.0 / divisor;
divisor += 2;
sign = -sign;
which is more clear, takes one more variable and one more instruction.
An update to the upperLim and lowerLim must be made here aswell: the algorithm approaches PI/4 (different from Leibniz!), so:
upperLim = (Math.PI + tolerance)/4;
lowerLim = (Math.PI - tolerance)/4;

Transferring code from notepad ++ to command prompt

I'm relatively new to java, so I wouldn't be surprised if I'm missing something obvious here. Anyways, I made a code that finds the roots of a polynomial using the Bisection method. I thought the program was all well and dandy until I pasted it from notepad++ to command prompt, where I ended up getting a bunch of "class, interface, or enum expected" errors after compiling it using javac. Everything seems fine in the code itself, so I've deduced that I've made one of the following two errors: either something wrong occurred while I was copying and pasting into command prompt, or I actually did create an error in my code that I didn't catch. Could someone tell me just what I did wrong? It may be a minor fix, but I just don't know how to change it to get my code to work. Here's the code:
import java.util.*;
class Roots {
public static int degree;
public static double[] coArrayC;
public static double[] coArrayD;
public static int coeffVal;
public static void main( String[] args ){
double resolution = 0.01;
double tolerance = 0.0000001;
double threshold = 0.001;
double rightEndPt;
double leftEndPt;
int polyRootPointer = 0;
int diffRootPointer = 0;
boolean rootAns = false;
Scanner sc = new Scanner(System.in);
System.out.println();
System.out.print("Enter the degree: "); //prompts user to enter the correct degree of the polynomial
degree = sc.nextInt();
coeffVal = degree + 1; //the coefficient is one more than the number of degrees
System.out.print("Enter " + coeffVal + " coefficients: "); //adds in the value of the polynomial coefficient in to the line that prompts the user to specify which coefficients are in the function
double[] coefficients = new double[coeffVal]; //initialization of array, a bunch of doubles that represent the coefficients of the user's polynomial
coArrayC = new double[coeffVal]; //naming the array
double[] rootArray = new double[degree];//another array for the degrees of the polynomial
coArrayD = new double[coeffVal]; //and assigning it a name
for(int i = 0; i < coeffVal; i++) {
coefficients[i] = sc.nextDouble();
}
System.out.print("Enter the right and left endpoints, in that order: "); //prompts user to enter the interval limits
rightEndPt = sc.nextDouble();
leftEndPt = sc.nextDouble();
diff(coefficients); //calculates coefficients of derivative polynomial
for (double i = leftEndPt; i < rightEndPt-resolution; i = i + resolution){ //
if (isPositive(coArrayD, i) != isPositive(coArrayD, i+resolution) || isPositive(coArrayD, i) == 0) {
rootArrayDeriv[diffRootPointer] = findRoot(coArrayD, i, i+resolution, tolerance);
diffRootPointer++;
}
}
for (int i = 0; i < rootArrayDeriv.length; i++) {
double tempValue;
tempValue = poly(coefficients, rootArrayDeriv[i]);
tempValue = Math.abs(tempValue);
if (tempValue < threshold) {
rootArray[polyRootPointer] = rootArrayDeriv[i];
polyRootPointer++;
rootAns = true;
}
}
for (double i = leftEndPt; i < rightEndPt-resolution; i = i + resolution){
if (isPositive(coefficients, i) != isPositive(coefficients, i+resolution) || isPositive(coefficients, i) == 0) {
rootArray[polyRootPointer] = findRoot(coefficients, i, i+resolution, tolerance);
polyRootPointer++;
rootAns = true;
}
}
//Arrays.sort(rootArray); //sorts array from lowest to highest
if (rootAns == true) {
System.out.println("Sorry - no roots were found in the specified interval.");
}
}
} else {
for (int i = 0; i < rootArray.length; i++) {
if (rootArray[i] != 0.0) {
System.out.printf("Root found at %.5f\n :" Arrays.sort(rootArray[i])); //if roots are found, list them as an output, with five decimal places of accuracy
}
}
static double poly(double[] C, double x){
double polySum = 0;
coArrayC[0] = C[0];
for (int i = 1; i < coArrayC.length; i++){
coArrayC[i] = C[i]*(Math.pow(x, i)); //multiplies each coefficient by the designated power of X
}
for (int i = 0; i < coArrayC.length; i++){
polySum = polySum + coArrayC[i]; //accumulates the sum of of all the terms, after the coeff. were multiplied to their respective powers.
}
return(polySum);
}
static double[] diff(double[] C){
for (int i = 0; i < degree; i++){
coArrayD[i] = (i+1)*C[i+1]; //newly allocated array D containing coeff. of the polynomial that is the derivative of the polynomial with coeff. array C.
}
return(coArrayD);
}
static double findRoot(double[] C, double a, double b, double tolerance){ //using bisection method; similar to findRoot.java in cmps webpage.
double root = 0.0 , residual;
while ( Math.abs(b - a) > tolerance ) {
root = (a + b) / 2.0;
residual = poly(C, root);
if (poly(C, a) < 0 && poly(C, b) < 0) {
if (residual > 0)
b = root;
else
a = root;
} else if (poly(C, a) > 0 && poly(C, b) > 0) {
if (residual > 0)
a = root; //replace left endpoint
else
b = root; //replace right endpoint
}
}
return(root);
}
static int isPositive(double[] C, double a){
double endpointTempA;
endpointTempA = poly(C, a);
if (endpointTempA < 0) {
return(1);
} else if (endpointTempA > 0) {
return(2);
} else {
return(0);
}
}
}
You have two } too many here:
if (rootAns == true) {
System.out.println("Sorry - no roots were found in the specified interval.");
}
}
} else {
If you indent your code properly, it's easier to see these kinds of errors. Remove the two } that don't belong there:
if (rootAns == true) {
System.out.println("Sorry - no roots were found in the specified interval.");
} else {
There's also a missing , here, and you shouldn't pass a single double to Arrays.sort, but the whole array
System.out.printf("Root found at %.5f\n :"Arrays.sort(rootArray[i]));
Should be:
System.out.printf("Root found at %.5f\n :", Arrays.sort(rootArray));
And a missing }.
Instead of writing a whole program at once and then trying to compile it, write it little by little, and compile it each time you have for example a complete method. That way you avoid getting a mountain of little errors that confuse you.

What is the bug in my "find median" implementation?

I found someone who had a similar problem (How to calculate the median of an array?), but I couldn't figure out how to incororate it in to my own code since I am rather new to java. Right now, my findmedian method is returning 0 instead of the actual median and I can't seem to figure it out. Thanks!
import java.util.Scanner;
import java.util.Arrays;
public class Original
{
public static void main(String[] args)
{
Scanner inputNumber = new Scanner(System.in);
Scanner dataItem = new Scanner(System.in);
Scanner input = new Scanner(System.in);
System.out.print("This stores a list of contirbutions to a charity drive.\n ");
System.out.print("How many contributors will be entered? ");
double contributors = inputNumber.nextDouble();
double contributions[ ] = new double[50];
double contributions_check[] = findData (contributors, contributions);
System.out.print("See if the contributions are correct. ");
// Displays the contributions, loop allows numbers to be displayed correctly
for (int count = 0; count < contributors; count++) {
System.out.print(contributions_check[count] + " ");
}
double median = findmedian(contributors,contributions_check);
System.out.print("\n The median contribution is: " + median);
}
public static double[] findData(double n, double[] contributions2)
{
Scanner dataItem = new Scanner(System.in);
// x must be 0 and x must be < than n
for (int x = 0; x < n; x++) {
System.out.print("Please enter the next contribution: ");
contributions2[x] = dataItem.nextDouble();
}
return contributions2;
}
public static double findmedian(double n, double data[])
{
Arrays.sort(data);
double median;
if (data.length % 2 == 0) {
median = ((double) data[data.length / 2] +
(double) data[data.length / 2 - 1]) / 2;
} else {
median = (double) data[data.length/2];
}
return median;
}
}
I think the issue is you are using data.length in findmedian, where you should be using n. data.length is always going to be 50, even if you only entered 5 items....
Use the number of contributors n to know the valid contributors in your array.
public static double findmedian(double n, double data[])
{
Arrays.sort(data);
double median;
if (data.length % 2 == 0) {
median = ((double) data[n / 2] +
(double) data[n / 2 - 1]) / 2;
} else {
median = (double) data[n/2];
}
return median;
}

Categories