EDIT: I have edited in the output of the program.
The program calls for estimating a given value mu. User gives a value of mu, and also provides four different numbers not equal to 1 (call them w, x, y, z). The program then attempts to find an estimate of the mu value by using the de Jaeger formula.
If I enter values of 238,900 for mu, and w=14, x=102329, y=1936, z=13
then the value of estimate should be 239,103, and the error about .08%.
My code with the for loops works perfectly fine:
public static void main(String[] args) {
SimpleReader in = new SimpleReader1L();
SimpleWriter out = new SimpleWriter1L();
double bestEstimate = 0; // used to hold the estimate the computer while return
double bestA = 0, bestB = 0, bestC = 0, bestD = 0; // to hold the values of the exponents for each number
double[] exponents = { -5, -4, -3, -2, -1, -1.0 / 2.0, -1.0 / 3.0,
-1.0 / 4.0, 0, 1.0 / 4.0, 1.0 / 3.0, 1.0 / 2.0, 1, 2, 3, 4, 5 };
double[] userNumbers = new double[4];
double mu = getPositiveDouble(in, out);
for (int i = 0; i < 4; i++) {
userNumbers[i] = getPositiveDoubleNotOne(in, out);
}
for (int a = 0; a < exponents.length; a++) {
double a1 = Math.pow(userNumbers[0], exponents[a]);
for (int b = 0; b < exponents.length; b++) {
double b1 = Math.pow(userNumbers[1], exponents[b]);
for (int c = 0; c < exponents.length; c++) {
double c1 = Math.pow(userNumbers[2], exponents[c]);
for (int d = 0; d < exponents.length; d++) {
double d1 = Math.pow(userNumbers[3], exponents[d]);
double currentEstimate = a1 * b1 * c1 * d1;
if (Math.abs(mu - currentEstimate) < Math
.abs(mu - bestEstimate)) {
bestEstimate = currentEstimate;
bestA = exponents[a];
bestB = exponents[b];
bestC = exponents[c];
bestD = exponents[d];
}
}
}
}
}
out.println("Best estimate: " + bestEstimate);
out.println(userNumbers[0] + "^" + bestA + ", " + userNumbers[1] + "^"
+ bestB + ", " + userNumbers[2] + "^" + bestC + ", "
+ userNumbers[3] + "^" + bestD);
out.println("Error: " + calculateError(mu, bestEstimate) * 100 + "%");
}
Output:
Enter a positive real number: 238900
Enter a positive real number that isn't 1: 14
Enter a positive real number that isn't 1: 102329
Enter a positive real number that isn't 1: 1936
Enter a positive real number that isn't 1: 13
Best estimate: 239102.78648033558
14.0^-5.0, 102329.0^1.0, 1936.0^0.5, 13.0^4.0
Error: 0.08488341579555334%
However, with the while loops, I am unable to replicate this.
while (a < exponents.length) {
double a1 = Math.pow(userNumbers[0], exponents[a]);
while (b < exponents.length) {
double b1 = Math.pow(userNumbers[1], exponents[b]);
while (c < exponents.length) {
double c1 = Math.pow(userNumbers[2], exponents[c]);
while (d < exponents.length) {
double d1 = Math.pow(userNumbers[3], exponents[d]);
double currentEstimate = a1 * b1 * c1 * d1;
if (Math.abs(mu - currentEstimate) < Math
.abs(mu - bestEstimate)) {
bestEstimate = currentEstimate;
bestA = exponents[a];
bestB = exponents[b];
bestC = exponents[c];
bestD = exponents[d];
}
d++;
}
c++;
}
b++;
}
a++;
}
Output:
Enter a positive real number: 238900
Enter a positive real number that isn't 1: 14
Enter a positive real number that isn't 1: 102329
Enter a positive real number that isn't 1: 1936
Enter a positive real number that isn't 1: 13
Best estimate: 0.0
14.0^0.0, 102329.0^0.0, 1936.0^0.0, 13.0^0.0
You haven't initialized the variables for the next few iterations.
You need to reinitialize the variables used for while loop's condition check outside their respective while loops. i.e
b = 0;
while(b < exponents.length){
}
Similarly do it for the while loops which use variables c & d.
Daniel's answer is correct : the
structure of the while loop should be:
int a=0, b=0, c=0, d=0;
while (a < length) {
b=0;
while (b < length) {
c=0;
while (c < length) {
d=0;
while (d < length) {
d++;
}
c++;
}
b++;
}
a++;
}
Related
The problem is to determine the number of hours required before the second method becomes more beneficial than the first. I've been looking at this all day and don't know why I can't get it to print.
public class BestMethod{
public static void main(String[] args){
double earnings1 = 10.00;
double earnings2 = 0.10;
double totalHours1 = 0;
double totalHours2 = 0;
double x = 0;
double y = 0;
for (int i = 1; i <= 10; i++)
{
totalHours1++;
x = totalHours1 * earnings1;
totalHours2++;
earnings2 *= 1;
y = (earnings2 * 1) * 2 + earnings2;
}
if (y > x){
System.out.println ("It will take the second method " + totalHours2 + " hours before it becomes more beneficial than the first method ");
}
}
}
Based on your code, the value of earnings1 and earnings2 are remaining the same.
After the first iteration (i = 1) how values are changing (use pen and paper)
totalHours1 = 1.0, totalHours2 = 1.0, x = 10.0 and y = 0.30000000000000004
After completing the loop (i = 10)
totalHours1 = 10.0, totalHours2 = 10.0, x = 100.0 and y = 0.30000000000000004
So, the value of y is less than the value of x and the condition is going to false.
So, (in case if you want to) print the value use this in your program if (y < x) or you have to change the mathematical (calculation) method.
I have to write a Taylor series until the 16th element that calculates sin and compare the values returned values with Math.sin. Well , everything works fine until the last time when instead of 0.00000 i get 0.006941.Where is my error and if somebody have an idea how to write this in a more professional way I would be very happy.
import java.text.NumberFormat;
import java.text.DecimalFormat;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
NumberFormat formatter = new DecimalFormat("#0.000000");
double val[] = {0, Math.PI / 3, Math.PI / 4, Math.PI / 6, Math.PI / 2, Math.PI};
for (int i = 0; i < val.length; i++) {
System.out.println("With Taylor method: " + formatter.format(Taylor(val[i])));
System.out.println("With Math.sin method: " + formatter.format(Math.sin(val[i])));
}
}
public static double Taylor ( double val){
ArrayList<Double> memory = new ArrayList<Double>();
double row = val;
for (int i = 0, s = 3; i < 16; i++, s = s + 2) {
double mth = Math.pow(val, s);
double result = mth / factorial(s);
memory.add(result);
}
for (int i = 0; i < 16; i++) {
if (i % 2 == 0) {
double d = memory.get(i);
row = row - d;
} else {
double d = memory.get(i);
row = row + d;
}
}
return row;
}
public static long factorial ( double n){
long fact = 1;
for (int i = 2; i <= n; i++) {
fact = fact * i;
}
return fact;
}
}
Your math is correct, but your factorials are overflowing once you get to calculating 21!. I printed out the factorials calculated.
factorial(3) = 6
factorial(5) = 120
factorial(7) = 5040
factorial(9) = 362880
factorial(11) = 39916800
factorial(13) = 6227020800
factorial(15) = 1307674368000
factorial(17) = 355687428096000
factorial(19) = 121645100408832000
factorial(21) = -4249290049419214848 // Overflow starting here!
factorial(23) = 8128291617894825984
factorial(25) = 7034535277573963776
factorial(27) = -5483646897237262336
factorial(29) = -7055958792655077376
factorial(31) = 4999213071378415616
factorial(33) = 3400198294675128320
It appears that your raising val to ever higher powers isn't significant enough to make a difference with the overflow until you get to the highest value in your array, Math.PI itself. There the error due to overflow is significant.
Instead, calculate each term using the last term as a starting point. If you have the last value you entered into memory, then just multiply val * val into that value and then divide the next two numbers in sequence for the factorial part.
That's because memory.get(i) is equal to memory.get(i - 1) * (val * val) / ((s - 1) * s). This also makes your calculation more efficient. It avoids the multiplication repetition when calculating the numerator (power part) and the denominator (the factorial calculation). This will also avoid the overflow which results from how you calculated the denominator separately.
My implementation of this idea substitutes this for the first for loop:
double mth = val;
for (int i = 0, s = 3; i < 16; i++, s = s + 2) {
mth = mth * val * val;
mth = mth / ((s - 1) * s);
memory.add(mth);
}
and places
double row = val;
between the for loops, to ensure that the first term is the initial sum as you had it before. Then you don't even need the factorial method.
This this I get 0.000000 for Math.PI.
I made the arithmetic mean for whole the sorted array, but now i want to make the arithmetic mean for first sorted half and second sorted half of array.
Ex: My array is: 77, 99, 44, 55, 22, 88, 11, 00, 66, 33.
My code make in first place the sort.
The outcome of program is: 00 11 22 33 44 55 66 77 88 99.
Now i want to make the mean for first half:
00 11 22 33 44 and print it.
Then i want to make the mean for the second half:
55 66 77 88 99 and print it.
public class Array {
private double[] a;
private int NrElmts;
public Array(int max)
{ a = new double[max];
NrElmts = 0;
}
public void elements(double value)
{ a[NrElmts] = value;
NrElmts++;
}
public void print()
{ for(int j=0; j<NrElmts; j++)
System.out.print(a[j] + " ");
System.out.println("");
}
public void selectionSort()
{
int out, in, min;
for(out=0; out< NrElmts -1; out++)
{ min = out;
for(in=out+1; in< NrElmts; in++)
if(a[in] < a[min] )
min = in;
invertPositions(out, min); }
}
private void invertPositions(int one, int two)
{ double temp = a[one];
a[one] = a[two];
a[two] = temp;
}
public void mean()
{
int i;
double sum = 0;
for(i = 0; i < NrElmts; i++) {
sum+=a[i];}
double medie = sum/NrElmts;
System.out.format("Mean is: %.1f", mean);
System.out.println("");
}
}
Try this
public void firstHalfMean(){
int i;
double sum = 0;
int numberOFElements = NrElmts/2;
for (i = 0; i < NrElmts/2; i++) { // take sum only till half.
sum += a[i];
}
double mean = sum / numberOFElements; // sum/half the elements
System.out.format("Mean is: %.1f", mean);
System.out.println("");
}
public void secondHalfMean(){
int i;
double sum = 0;
int numberOFElements = NrElmts % 2 == 0 ? NrElmts/2 : NrElmts/2 + 1; // If odd, this second array will contain one more element.
for (i = NrElmts/2; i < NrElmts; i++) { // take sum for the next half
sum += a[i];
}
double mean = sum / numberOFElements; // sum/half elements (half + 1) in case of odd length.
System.out.format("Mean is: %.1f", mean);
System.out.println("");
}
To calculate the mean for 9, 2 and 7 you have to firstly add them all up, which equals 18 and then divide by how many there are - so 18 / 3 which is 6.
Although, you will have to account for the possibility of an odd list - if there's an odd amount of elements, say for example 1, 2, 3 the middle point of 3 - is 1.5 - and if you're iterating through indexes the iterative variable will count the middle point as 1. So it's a bit tricky, not sure what you'd want to do.Consider the following code though - it does exactly what you want, but with odd list sizes, it will just divide by a decimal value
LinkedList<Integer> numbers = new LinkedList<>();
numbers.add(10);
numbers.add(20);
numbers.add(30);
numbers.add(40);
int size = numbers.size();
int iterativeHalf = size / 2;
float meanHalf = (float) size / 2;
float lowerMean = 0;
float upperMean = 0;
for (int i = 0; i < size; i++) {
int realRef = i + 1;
Integer value = numbers.get(i);
if (realRef > iterativeHalf) { //Should be calculating upper mean
if (upperMean == 0) { //if lowerMean is just a running total, not divided yet to get the mean
System.out.println("the lower mean for numbers is " + lowerMean + " / " + meanHalf);
lowerMean = (lowerMean) / meanHalf; //add last value + divide to set it to the mean
}
System.out.println("upper mean = " + upperMean + " + " + value + " = " + (upperMean + value));
upperMean = upperMean + value; //keep the upper values up total going
} else {
System.out.println("lower mean = " + lowerMean + " + " + value + " = " + (lowerMean + value));
lowerMean = lowerMean + value; //keep adding the lower halfs values up
}
}
//When it breaks, must divide upperMean by size to get mean
System.out.println("the upper mean for numbers is " + upperMean + " / " + meanHalf);
upperMean = (upperMean) / meanHalf;
System.out.println(" ");
System.out.println("FINAL lower mean = " + lowerMean);
System.out.println("FINAL upper mean = " + upperMean);
Output is:
lower mean = 0.0 + 10 = 10.0
lower mean = 10.0 + 20 = 30.0
the lower mean for numbers is 30.0 / 2.0
upper mean = 0.0 + 30 = 30.0
upper mean = 30.0 + 40 = 70.0
the upper mean for numbers is 70.0 / 2.0
FINAL upper mean = 35.0
FINAL lower mean = 15.0
This, for a [10, 20, 30, 40] will yield the output shown above but essentially (10+20)/2 as the lower mean and (30+40)/2 for the upper mean.
For [10, 20, 30, 40, 50] will yield (10 + 20) / 2.5 the lower mean and (30+40+50)/2.5 for the upper mean
Only take sum of half the array. Give one more element to your second or first half in case if your array size is odd.
public void firstHalfMean(){
int i;
double sum = 0;
int numberOFElements = NrElmts/2;
for (i = 0; i < NrElmts/2; i++) { // take sum only till half.
sum += a[i];
}
double mean = sum / numberOFElements; // sum/half the elements
System.out.format("Mean is: %.1f", mean);
System.out.println("");
}
public void secondHalfMean(){
int i;
double sum = 0;
int numberOFElements = NrElmts % 2 == 0 ? NrElmts/2 : NrElmts/2 + 1; // If odd, this second array will contain one more element.
for (i = NrElmts/2; i < NrElmts; i++) { // take sum for the next half
sum += a[i];
}
double mean = sum / numberOFElements; // sum/half elements (half + 1) in case of odd length.
System.out.format("Mean is: %.1f", mean);
System.out.println("");
}
Since you already have way to make mean for entire array, all you need to do is find mid position of array and then run from and to that point.
In your example: NrElmts is 10, so divide your NrElmnts by 2, so you can get mean for 1 to 5, and then 6 to 10 both 5 each.
Think about situation where you have odd number of elements in array, how do u want to do it, whether in first array or second. let me know if this need help as well.
Steps:
1) create a new variable say a1 to NrElmts/2, and go with your mean function from 1 to a1
2) go from a1+1 to NrElmnts
Let me know if you need any help.
At the comment step 4 I am trying to add the current array element to sum, compare the current array element to max_test and if it is larger, save it in the variable max_test. and compare the current element to min_test, if it is smaller save it in min_test. HOWEVER i keep on getting the errors
Grades5.java:55: error: bad operand types for binary operator '>'
if (grades[r] > grades[max_test])
^
first type: int[]
second type: int[]
Grades5.java:57: error: bad operand types for binary operator '<'
if (grades[r] < grades[min_test])
^
first type: int[]
second type: int[]
Grades5.java:59: error: bad operand types for binary operator '+'
sum += grades[r];
^
first type: int
second type: int[]
3 errors
The code:
import java.util.Scanner;
public class Grades5
{
public static void main(String[] args)
{
int[][] grades = {
{ 87, 96, 100},
{ 68, 75, 72},
{ 99, 100, 95},
{100, 96, 70},
{ 75, 60, 79},
};
int how_many_grades = grades.length * grades[0].length;
// -----------------
// Output the grades
// -----------------
System.out.print(" ");
for (int i = 0; i < grades[0].length; i++)
System.out.print("Test " + (i + 1) + " ");
System.out.println("Average");
for (int r = 0; r < grades.length; r++)
{
int sum = 0; // Sum of one student's tests
// -------------------
// Process one student
// -------------------
System.out.print("Student " + (r + 1) + " ");
for (int c = 0; c < grades[r].length; c++)
{
System.out.printf("%6d ", grades[r]); // Step 1
//sum += grades[c]; // Step 2
}
System.out.printf("%7.2f\n", (double)sum / grades[r].length);
}
// ----------------
// Output a summary
// ----------------
int max_test, // Maximum test score
min_test, // Minimum test score
sum = 0; // Sum of all student tests
max_test = min_test = grades[0][0]; // Step 3
for (int r = 0; r < grades.length; r++)
{
// -------------------
// Process one student
// -------------------
for (int c = 0; c < grades[r].length; c++)
{
// Step 4
if (grades[r] > grades[max_test])
max_test = c;
if (grades[r] < grades[min_test])
min_test = c;
sum += grades[r];
}
}
System.out.println("Highest test score: " + max_test);
System.out.println("Lowest test score: " + min_test);
System.out.printf("Average test score: %.1f\n",
(double)sum / how_many_grades);
}
}
Your problem is that grades[r] is not an integer. It is an array of integers. You'd have to address two indices
sum += grades[i][j];
in order to get rid of the compilation error.
It appears to be the same for the other errors. In general you can imagine it as follows:
grades[1] -> { 87, 96, 100}
grades[2] -> { 68, 75, 72}
and
grades[1][1] -> 87;
grades[1][2] -> 96;
etc ..
If the grades for one test are horizontal in your array, then you only need two loops, not three.
for (int test = 0; test < grades.length; test++) {
System.out.print("Test " + (test + 1) + " ");
System.out.println("Average");
int sum = 0; // Sum all grades on this test
for (int student = 0; student < grades[test].length; student++)
{
System.out.print("Student " + (student + 1) + " ");
sum += grades[student];
}
System.out.println();
System.out.printf("%7.2f\n", (double)sum / grades[test].length);
}
You cannot use operator > to compare int[] types. Java doesn't support operator overloading. Those relational operators (>, <, >=, <=) are applied to numeric primitive data types only.
Do you mean something like grades[r][c] > grades[r][max_test] or grades[r][c] < grades[r][min_test]?
This works because grades needs 2 parts when comparing
if (grades[r][c] > max_test)
max_test = grades[r][c];
if (grades[r][c] < min_test)
min_test = grades[r][c];
sum += grades[r][c];
I couldn't figure out how the decrement operator (e--)
works in code below, so i wrote the other class below it
to get the same result. I want to know how the decrement operator
achieves that result in the Power class. - Newbie.
int result, e;
for(int i=0; i < 10; i++) {
result = 1;
e = i;
while(e > 0) {
result *= 2;
e--;
}
System.out.println("2 to the " + i +
" power is " + result);
}
Code written to achieve same result
int result = 1;
for(int i=0; i < 10; i++) {
if (i > 0) {
result*=2;
}
System.out.println("2 to the " + i +
" power is " + result);
}
So the first example is resetting result for each iteration of the main for loop, so it needs to recalculate from scratch each time, where as the second example is keeping the previous computed value. The if in the second example is not needed is it.
The decrement operator modifies the variable on which it's called. So e-- is effectively e = e - 1 (except the overall result of the expression is different, see below).
This code:
result = 1;
e = i;
while(e > 0) {
result *= 2;
e--;
}
starts with result = 1 and then loops for i iterations doubling the value in result. Equivalent code using for which you seem more comfortable with:
result = 1;
for (e = 0; e < i; e++) {
result *= 2;
}
There are two forms of the decrement (and increment) operator: Prefix and postfix, depending on whether the operator is before (prefix) or after (postfix) its operand. Either could be used in the code you were asking about, because the only difference is the result of the expression.
Prefix: Suppose we have x = 5. The expression --x has the value 4: First we decrement x, then we take its new value as the result of the expression.
Postfix: Suppose we had x = 5 (again). The expression x-- has the value 5, with x ending up containing 4: First we grab the current value of x as the result of the expression, then we decrement it (because the -- is after x).
int x, r;
x = 5;
r = --x; // Prefix
System.out.println("r = " + r + ", x = " + x); // "r = 4, x = 4"
x = 5;
r = x--; // Postfix
System.out.println("r = " + r + ", x = " + x); // "r = 5, x = 4"
i figure out that by placing a System.out.println(e) i could "see" the variable "e" behavior in order to make sense of the decrement.
class Power {
public static void main(String args[]) {
int e;
int result;
for(int i=0; i < 10; i++) {
result =1 ;
e = i;
while(e > 0) {
System.out.println(e); // not part of the original program
result *= 2 ;
e--;
System.out.println(e); // not part of the original program
}
//System.out.println("2 to the " + i +
//" power is " + result);
}
This is the output:
C:\Users\enrique\Desktop\Hello.java>java Power: 1, 0, 2, 1, 1, 0, 3
e = 1(iteration 1), 2^1, e (1) decremented to 0, e = 2 (iteration 2), 2^2, e(2) decremented to 1, e = 1 re-enter The while but is ignored as 2^1 is already registered, e (1) decremented to 0, e = 3 (iteration 3), 2^3…