Java - finding the variance - would this work? - java

Link to exercise: mooc.cs.helsinki.fi/programming-part1/material-2013/week-3?noredirect=1#e67
Would this work? I feel like my math is correct, but I can't test my code because I'm at work.
SUM:
int a = 0;
int sum = 0;
while (a < list.size()) {
sum += list.get(a);
a++;
}
return sum;
AVERAGE:
double average = sum(list)/list.size();
return average;
VARIANCE:
int a = 0;
double b = list.get(a) - average(list);
double sum = 0;
while (a < list.size()) {
sum += Math.pow(b, 2);
a++;
}
double variance = sum / (list.size() - 1);
return variance;
Would that work?
FOLLOW UP QUESTION:
This is apparently the "correct" way to do it...
double sumDiffSquared = 0.0;
double avg = average(list);
for (int value : list) {
double difference = value - avg;
difference *= difference;
sumDiffSquared += difference;
double variance = difference / (list.size() - 1);
}
return variance;
Okay so I THINK I understand most of it (notes below)...
double difference = value - avg;
Everything from "list" was put into the variable "value" and now we are subtracting the previously calculated average from each number within the variable "value" one-by-one and putting the new values into the variable "difference". Makes perfect sense.
difference *= difference;
We are now multiplying each number within the variable "difference" by itself. Once again, one-by-one. Makes sense.
Here's where I get lost...
sumDiffSquared += difference
This is what makes no sense to me. Why/how does this add the values together? To me it looks like the value of the variable "sumDiffSquared" is 0, so this would just be adding 0 to each of the values in the variable "difference"...

The variable sumDiffSquared does not get reset for each loop, therefore it is accumulating the value of difference for each loop.

Related

Does order of operators matter when using compound assignment in Java? (+= vs =+)

I have this test code and I am trying to check if sum =+ value is equal to sum = sum + value. In Java, is this acceptable? It compiles and runs on my machine.
public class sum {
public static void main(String[] args) {
int sum = 0;
int value = 5;
sum =+ value;
System.out.println(sum);
sum = 0;
sum = sum + value;
System.out.println(sum);
}
}
Yes, it matters.
There is no =+ operator. It's, in fact, two operators - = (assignment), followed by + (unary plus).
sum =+ value could be written as sum = (+value), which just evaluates to sum = value.
On the other hand += is a proper operator using for addition sum += value means sum = sum + value.

Clarification on "Calculate e^x without inbuilt functions in Java"

The question was basically to calculate e^x without inbuilt functions in Java.
The sequence to code was e^x = 1+x+x2/2!+x3/3!+x4/4!+ ...
Here was my attempt at the question:
public static void myexp(double x, double i){
double j = 1.0;
double sum = x;
while (j <= i){
j = j + 1;
sum = sum + (sum * (x / (j)));
System.out.println(sum + 1 + x);
}
}
public static void main(String[] args) {
double x = 1;
double i = 5.0;
myexp(x, i);
}
Now it wasn't working, and eventually I gave in and looked up what a model answer should look like (I know, I know). Here is what it is (in the style of my code):
public static void myexp(double x, double i){
double j = 1.0;
double sum = x;
double result = 1.0;
while (j <= i){
j = j + 1;
sum = sum * (x / (j));
result = result + sum;
System.out.println(result + x);
}
}
Now the difference is the inclusion of the 'results' variable, which delineates the summation of the sequence. However, I thought I had incorporated that when I wrote
"sum = sum+(sum*(x/(j)));".
But the machine recognises one style and not the other. What gives?
In each iteration you are supposed to add to the total sum the term
sum * x / j
where sum is the term added in the previous iteration.
This means you must store the term added in the previous iteration in a separate variable.
If you use the same variable for the total result (which is supposed to be the sum of all the terms of all iterations) and for the term of the current iteration (sum), you get an entirely different result.
In other words
sum = sum + (sum * (x / (j)));
is not equivalent to
sum = sum * (x / (j));
result = result + sum;
since the value of sum depends on the previous value of sum, and therefore you can't eliminate that variable.

Java - Finding the average of an array while excluding a particular value.

I am trying to calculate and return the average of an array of integer values. The problem is, the array I am calculating the average from has values I need to find the average of, and values I need to exclude.
For example, take this as being my data set in the array.
20, -999, -10, 50, -999, 40, 30
I need to find the average but exclude any -999 value from the calculation.
How can I go about removing the -999 value from my sums and then find the new value to divide by at the end? Is there a way to keep count of the values I exclude? How can I exclude a value and move on to the next?
public static double averageTemperature(int[] temperatures)
{
double sum = 0.0;
double avg = 0.0;
for (int i =0; i < temperatures.length; i++)
{
if (i == -999)
{
// what technique is there to exlude and keep counting?
}
else
{
sum += i;
}
}
avg = sum / temperatures.length;
return avg;
}
This should be pretty straightforward - just use a variable as counter for the "valid" entries. You also need to access the values in the array properly. Here's a proposal (untested), which assumes "valid" entries are those not equal t0 -999 (modify the condition as you like):
public static double averageTemperature(int[] temperatures)
{
double sum = 0.0;
double avg = 0.0;
int validEntries = 0;
for (int i =0; i < temperatures.length; i++)
{
// process only "valid" entries
if (temperatures[i] != -999)
{
sum += temperatures[i];
++validEntries;
}
}
avg = sum / validEntries;
return avg;
}
Using Java 8 you can do;
temperatures = Arrays.stream(temperatures).filter(x -> x != -999).toArray();
You can exclude any array value this way using predicate statements.
Calculating the mean is as simple as just looping the array and dividing by the length then.
float mean;
for (int i = 0; i < temperatures.length; ++i) {
mean += (float) temperatures[i];
}
mean /= (float) temperatures.length;
Note to use a float for the mean and cast your integer array values to float also to avoid integer division, as well as the length of the array.
suppose you are correct with the logic but you are not getting the sum of the temperature values.
public static double averageTemperature(int[] temperatures)
{
double sum = 0.0;
double avg = 0.0;
for (int i =0; i < temperatures.length; i++)
{
if (temperatures[i] == -999)
{
continue;
}
else
{
sum += temperatures[i];
}
}
avg = sum / temperatures.length;
return avg;
}
hope this is what you are looking for.
The easiest way to compute the average while filtering out any unwanted values would be:
double average = Arrays.stream(temperatures)
.filter(i -> i != -999)
.average();

Why does my code return 1 always?

double formula1, formula2;
int plus;
int VALUE = 10000;
private void processFormula2()
{
for (int k = 0; k <= VALUE; k++) {
if (k % 2 != 0) {
if (plus % 2 == 0) {
double math = 1/k;
formula2 += math;
System.out.println("Getting Formula: "+ formula2);
plus++;
} else {
formula2 -= 1/k;
plus++;
}
// System.out.println("Term: " + formula2);
}
}
}
I am trying to get my formula to print out the result of Pi based off this formula that my teacher gave us. But for some reason it just returns 1.0, not really sure why. Any help or suggestions would be appreciated :)
Here's the problem:
double math = 1/k;
and
formula2 -= 1/k;
k is an int variable, so the JVM won't never return a decimal number in this statement. It will take only two possible values: 0 (if k > 1) or 1 (if k == 1) because the JVM performs the division before promoting the result to double.
Try this:
formula2 -= 1/(double)k;
Take a look at Numeric Promotions
Firstly, there are multiple errors with variable declaration.
double math = 1/k;will not truly work in Java due to how integer division is handled. You must either cast '1' to a double like double math = (double)1/k; or specify that you are using mixed mode arithmetic by using double math = 1.0/k;. This is also a problem for your formula2 variable (Along with you should always initialize your variables like formula1, formula2, and plus). You must also do the same thing with formula2 -= 1/k;.
Secondly, we have no idea what you are setting those variables to in the first place, nor do we have any test cases to compare to.

How to write 1+1/2+1/3....+1/4999+1/5000 in java?

How to write 1+1/2+1/3....+1/4999+1/5000 in java?
I have tried this but didnt work.
public class Harmonic{
public static void main(String[] args){
double sum = 0;
for(int i=1; i<=5000; i++){
sum+=1/i;
}
System.out.println(sum);
}
}
Adding numbers from smallest to largest will have a lower rounding error. If you compare the result with higher precision, you can see smaller to larger is closer.
double sum = 0;
for (int i = 1; i <= 5000; i++) {
sum += 1.0 / i;
}
System.out.println("From largest to smallest " + sum);
double sum2 = 0;
for (int i = 5000; i >= 1; i--) {
sum2 += 1.0 / i;
}
System.out.println("From smallest to largest " + sum2);
BigDecimal sum3 = BigDecimal.ZERO;
for (int i = 5000; i >= 1; i--) {
sum3 = sum3.add(BigDecimal.ONE.divide(BigDecimal.valueOf(i), 30, BigDecimal.ROUND_HALF_UP));
}
System.out.println("BigDecimal " + sum3);
prints
From largest to smallest 9.094508852984404
From smallest to largest 9.09450885298443
BigDecimal 9.094508852984436967261245533401
1 is an int constant, so 1 / (any int bigger than 1) is 0. You need to specify that you want a floating point division, by using 1.0 (float):
sum+=1.0/i;
^
That's a homework, then I just help you with a tip: be careful of variable types. 1/10 is equal to 0 if we consider it as an integer.
Try this instead:
sum += 1.0 / i;
How about:
public class Harmonic{
public static void main(String[] args){
double sum = 0;
for(int i=1; i<=5000; i++){
sum+=1.0/(double)i;
}
System.out.println(sum);
}
}
After the first iteration 1/i will always be 0 since it's done in integer arithmetic. Therefore you're final answer will just be 1. Change it to 1.0/i to get double arithmetic, and keep in mind that when you're loop finishes you may have a fair amount of error due to precision loss while using doubles. You can try it out and see how accurate it is though.
because i is an int so the division will be truncated... try putting sum+ = 1/(double)i
java-8 solution for calculating Harmonic sum:
public static double harmonicSum(int n) {
return IntStream.rangeClosed(1, n)
.mapToDouble(i -> (double) 1 / i)
.sum();
}

Categories