Averaging increasing number of variables - c#

I have to report average value of incoming numbers, how i could do that without using some sort of data structure to keep track of all values and then calculating average by summing them and dividing by number of values?

Just keep running sum and how many numbers you have received, that's all you need to compute the average.

If I'm not totally mistaken, one could calculate the avg(n+1) also this way:
avg(n+1) = (a[1]+ ... + a[n+1]) / (n+1) =
= (a[1]+ ... + a[n])/(n+1) + a[n+1]/(n+1) =
= (n(a[1]+ ... + a[n])/n) / (n+1) + a[n+1]/(n+1) =
= n*avg(n) / (n+1) + a[n+1]/(n+1) =
= n/(n+1) * avg(n) + a[n+1]/(n+1)
so multiply the old avg by n/(n+1) and add the new element divided by n+1. Depending on how high n will get and how big your values are, this could reduce rounding errors...
EDIT: Of course you have to calculate n/(n+1) using floats, otherwise it will always render 0...

If you have the numbers a[1] a[2] ... a[n] and you know their average is avg(n) = (a[1] + ... + a[n]) / n, then when you get another number a[n + 1] you can do:
avg(n + 1) = (avg(n) * n + a[n + 1]) / (n + 1)
Some floating point errors are unavoidable, but you should test this and see if it's good enough.
To avoid overflow, you could do the division first:
avg(n + 1) = (avg(n) / (n + 1)) * n + (a[n + 1] / (n + 1))

Keep the current sum and count. Update both on every incoming number.
avg = sum / count.

you don't need to keep track the total sum, only counter:
class Averager {
float currentAverage;
size_t count;
float addData (float value) {
this->currentAverage += (value - this->currentAverage) / ++count;
return this->currentAverage;
}
}
from-> prevent long running averaging from overflow?

Related

Sum range using loop, calculate sum of odd and even numbers

Hi I am sick of searching I could not find the exact code for my question.
I need to code the sum of the odd numbers from 1 to 100
and sum of the even numbers from 2 to 100.
This is what i have so far.
Thank you so much
// 1) using for statement to Sum Up a Range of values using Interactive
Console.WriteLine(" Sum Up a Range of values entered by User ");
Console.WriteLine();
// 2) Declare the Variables to be used in the Project
string strFromNumber, strToNumber;
int fromNumber, toNumber;
int sum = 0;
int i, even = 0, odd = 0;
int[] array = new int[10];
// 3) Prompt the User to Enter the From Number to Sum From
Console.Write("Enter the From Number to Sum From: ");
strFromNumber = Console.ReadLine();
fromNumber = Convert.ToInt32(strFromNumber);
// 4) Prompt the User to Enter the To Number to Sum To
Console.Write("Enter the To Number to Sum To: ");
strToNumber = Console.ReadLine();
toNumber = Convert.ToInt32(strToNumber);
// 5) Use for statement to Sum up the Range of Numbers
for (i = fromNumber; i <= toNumber; ++i)
{
sum += i;
}
if //(array[i] % 2 == 0) //here if condition to check number
{ // is divided by 2 or not
even = even + array[i]; //here sum of even numbers will be stored in even
}
else
{
odd = odd + array[i]; //here sum of odd numbers will be stored in odd.
}
Console.WriteLine("The Sum of Values from {0} till {1} = {2}",
fromNumber, toNumber, sum);
Console.ReadLine();
There is no need to write the complex code which you have written.
Problem is to calculate the sum of arithmetic progression. The formula to find the sum of an arithmetic progression is Sn = n/2[2a + (n − 1) × d] where, a = first term of arithmetic progression, n = number of terms in the arithmetic progression and d = common difference.
So in case of odd numbers its a = 1, n = 50 and d = 2
and in case of even numbers its a = 2, n = 50 and d = 2
and if you try to normalize these above formulas, it will be more easy based on your problem.
the sum of the first n odd numbers is Sn= n^2
the sum of the first n even numbers is n(n+1).
and obviously, it's very simple to loop from ( 1 to 99 with an increment of 2 ) and ( 2 to 100 with an increment of 2 )
In the simplest case, you can try looping in fromNumber .. toNumber range while adding
number either to even or to odd sum:
// long : since sum of int's can be large (beyond int.MaxValue) let's use long
long evenSum = 0;
long oddSum = 0;
for (int number = fromNumber; number <= toNumber; ++number) {
if (number % 2 == 0)
evenSum += number;
else
oddSum += number;
}
Console.WriteLine($"The Sum of Values from {fromNumber} till {toNumber}");
Console.WriteLine($"is {evenSum + oddSum}: {evenSum} (even) + {oddSum} (odd).");
Note, that you can compute both sums in one go with a help of arithmetics progression:
private static (long even, long odd) ComputeSums(long from, long to) {
if (to < from)
return (0, 0); // Or throw ArgumentOutOfRangeException
long total = (to + from) * (to - from + 1) / 2;
from = from / 2 * 2 + 1;
to = (to + 1) / 2 * 2 - 1;
long odd = (to + from) / 2 * ((to - from) / 2 + 1);
return (total - odd, odd);
}
Then
(long evenSum, long oddSum) = ComputeSums(fromNumber, toNumber);
Console.WriteLine($"The Sum of Values from {fromNumber} till {toNumber}");
Console.WriteLine($"is {evenSum + oddSum}: {evenSum} (even) + {oddSum} (odd).");
From the code snippet you shared, it seems like the user gives the range on which the sum is calculated. Adding to #vivek-nuna's answer,
Let's say the sum of the first N odd numbers is given by, f(n) = n^2 and
the sum of the first N even numbers is given by, g(n) = n(n + 1).
So the sum of odd numbers from (l, r) = f(r) - f(l - 1).
Similarly, the sum of even numbers from (l, r) = g(r) - g(l - 1).
Hope this helps.

C# WinsForm, Frequency Distribution Table [Updated]

Update 01
Thanks to Caius, found the main problem, the logic on the "if" was wrong, now fixed and giving the correct results. The loop still create more positions than needed on the secondary List, an extra position for each number on the main List.
I've updated the code bellow for refence for the following question:
-001 I can figure out why it create positions that needed, the for loop should run only after the foreach finishes its loops correct?
-002 To kind of solving this issue, I've used a List.Remove() to remove all the 0's, so far no crashes, but, the fact that I'm creating the extra indexes, and than removing them, does means a big performance down if I have large list of numbers? Or is an acceptable solution?
Description
It supposed to read all numbers in a central List1 (numberList), and count how many numbers are inside a certain (0|-15 / 15|-20) range, for that I use another List, that each range is a position on the List2 (numberSubList), where each number on List2, tells how many numbers exists inside that range.
-The range changes as the numbers grows or decrease
Code:
void Frequency()
{
int minNumb = numberList.Min();
int maxNumb = numberList.Max();
int size = numberList.Count();
numberSubList.Clear();
dGrdVFrequency.Rows.Clear();
dGrdVFrequency.Refresh();
double k = (1 + 3.3 * Math.Log10(size));
double h = (maxNumb - minNumb) / k;
lblH.Text = $"H: {Math.Round(h, 2)} / Rounded = {Math.Round(h / 5) * 5}";
lblK.Text = $"K: {Math.Round(k, 4)}";
if (h <= 5) { h = 5; }
else { h = Math.Round(h / 5) * 5; }
int counter = 1;
for (int i = 0; i < size; i++)
{
numberSubList.Add(0); // 001 HERE, creating more positions than needed, each per number.
foreach (int number in numberList)
{
if (number >= (h * i) + minNumb && number < (h * (i + 1)) + minNumb)
{
numberSubList[i] = counter++;
}
}
numberSubList.Remove(0); // 002-This to remove all the extra 0's that are created.
counter = 1;
}
txtBoxSubNum.Clear();
foreach (int number in numberSubList)
{
txtBoxSubNum.AppendText($"{number.ToString()} , ");
}
lblSubTotalIndex.Text = $"Total in List: {numberSubList.Count()}";
lblSubSumIndex.Text = $"Sum of List: {numberSubList.Sum()}";
int inc = 0;
int sum = 0;
foreach (int number in numberSubList)
{
sum = sum + number;
int n = dGrdVFrequency.Rows.Add();
dGrdVFrequency.Rows[n].Cells[0].Value = $"{(h * inc) + minNumb} |- {(h * (1 + inc)) + minNumb}";
dGrdVFrequency.Rows[n].Cells[1].Value = $"{number}";
dGrdVFrequency.Rows[n].Cells[2].Value = $"{sum}";
dGrdVFrequency.Rows[n].Cells[3].Value = $"{(number * 100) / size} %";
dGrdVFrequency.Rows[n].Cells[4].Value = $"{(sum * 100) / size} %";
inc++;
}
}
Screen shot showing the updated version.
I think, if your aim is to only store eg 17 in the "15 to 25" slot, this is wonky:
if (number <= (h * i) + minNumb) // Check if number is smaller than the range limit
Because it's found inside a loop that will move on to the next range, "25 to 35" and it only asks if the number 17 is less than the upper limit (and 17 is less than 35) so 17 is accorded to the 25-35 range too
FWIW the range a number should be in can be derived from the number, with (number - min) / number_of_ranges - at the moment you create your eg 10 ranges and then you visit each number 10 times looking to put it in a range, so you do 9 times more operations than you really need to

Iterative Expansion of an Equation

I'm trying to write a method that will perform an iterative expansion of an equation that, after the second iteration, has a defined pattern. I need to get the results for each iteration into a List<T>, so I need to stop at each.
The first few steps look like this:
Fraction step1 = whole + half;
Console.WriteLine(" 1: " + step1);
Fraction step2 = whole + whole / (whole * 2 + half);
Console.WriteLine(" 2: " + step2);
Fraction step3 = whole + whole / (whole * 2 + whole / (whole * 2 + half));
Console.WriteLine(" 3: " + step3);
Fraction step4 = whole + whole / (whole * 2 + whole / (whole * 2 + whole / (whole * 2 + half)));
Console.WriteLine(" 4: " + step4);
Fraction step5 = whole + whole / (whole * 2 + whole / (whole * 2 + whole / (whole * 2 + whole / (whole * 2 + half))));
Console.WriteLine(" 5: " + step5);
Basically after each iteration step >= 2, half gets replaced with whole / (whole * 2 + half) continuing on for n-iterations.
I'm not entirely sure how to write an iterative equation like that in C#, though.
Clarifications: There will be at least 1000 iterations. Only step 1 doesn't follow the pattern (I guess technically step 2 doesn't as it establishes the pattern).
Try this -
List<Fraction> steps = new List<Fraction>();
for (int i = 0; i < 5; i++)
{
if (i > 0)
half = whole / (whole * 2 + half);
var step = whole + half;
steps.Add(step);
Console.WriteLine($" {i + 1}: {step}");
}
All the steps are stored in steps list.

C# for loop that gives sum of i/(i+1) through user specificed number

I need to display sum(i) = 1/2 + 2/3 + 3/4 + ... i/(i+1) where the final i is specified by the user. For some reason I am getting error "use of unassigned variable" for the second "total" in this line of code:
double total = (double) total + (i / (i + 1));
I tried to declare total outside the for loop but then it always comes out equal to 0.
Here is the full code:
public static void DisplaySums(int lastNum)
{
Console.WriteLine("i\tSum(i)");
for (int i=1; i<=(lastNum); i++)
{
double total = (double) total + (i / (i + 1));
Console.WriteLine(i + "\t" + total);
}
}
static void Main(string[] args)
{
Console.Write("Enter an integer: ");
int n = Convert.ToInt32(Console.ReadLine());
DisplaySums(n);
This is my first time ever asking a question on StackOverflow so I hope this makes sense. I can clarify if needed!
Thank you :)
First, you have to declare total outside of the loop. Else you are not summing up any intermediate results.
Second, you're getting zero because
(i / (i + 1))
performs integer division which is automatically truncated. To keep the decimal number, use a double literal:
(i / (i + 1.0))
In this line
double total = (double) total + (i / (i + 1));
You are essentially saying total is equal to itself plus something else. However the compiler doesn't know what total is as you just declared it. You need to assign the variable before you can use it.
Also (i / (i + 1)) is integer division. Which from the docs:
When you divide two integers, the result is always an integer
Anything divided by itself plus one will not be a whole number and the remainder will get thrown away and 0 will be returned. To fix this change (i / (i + 1)) to (i / (i + 1.0))
There are two issues here; the biggest obviously being your compile time error use of unassigned variable. This is because you are trying to assign the value of your newly instantiated variable as it is instantiated. A good idea is to instantiate to zero. You should also do this outside of your loop to retain the value with every iteration.
double total = 0;
Console.WriteLine("i\tSum(i)");
for (int i = 1; i <= lastNum; i++) {
total += (i / (i + 1));
Console.WriteLine(i + "\t" + total);
}
The next issue you are having is the result of zero every time. This is because the division is being performed on integers and integers are any whole number, thus a value such as 0.25 is rounded down to 0. If you revise your loop and your parameter in your method to use the double type instead, this issue will be resolved:
private static void DisplaySums(double lastNum) {
double total = 0;
Console.WriteLine("i\tSum(i)");
for (double d = 1; d <= lastNum; d++) {
total += (d / (d + 1));
Console.WriteLine(d + "\t" + total);
}
}

Order of growth of specific recursive function

What is the order of growth of the following function?
static int counter = 0;
static void Example(int n)
{
if (n == 1) return;
for (int i = 0; i < n; i++)
{
counter++;
}
Example(n / 2);
}
In order to solve it I have done the following:
I first got rid of the inner for loop in order to end up with:
static void Example(int n)
{
if (n == 1) return;
counter++;
Example(n / 2);
}
By analyzing that I was able to tell that the order of growth of that method was log base 2 of n .
so I am thinking that the final answer will be log base 2 times something else. How can I figure it out?
Let's look at both the original and the modified function. In the original function, you have the following amount of work done:
A constant amount of work for the base case check.
O(n) work to count up the number.
The work required for a recursive call to something half the size.
We can express this as a recurrence relation:
T(1) = 1
T(n) = n + T(n / 2)
Let's see what this looks like. We can start expanding this out by noting that
T(n) = n + T(n / 2)
= n + (n / 2 + T(n / 4)
= n + n/2 + T(n / 4)
= n + n/2 + (n / 4 + T(n / 8))
= n + n/2 + n/4 + T(n / 8)
We can start to see a pattern here. If we expand out the T(n / 2) bit k times, we get
T(n) = n + n/2 + n/4 + ... + n/2k + T(n/2k)
Eventually, this stops when n / 2k = 1. When this happens, we have
T(n) = n + n/2 + n/4 + n/8 + ... + 1
What does this evaluate to? Interestingly, this sum is equal to 2n + 1, because the sum n + n/2 + n/4 + n/8 + ... = 2n. Consequently, this first function is O(n). We could have also arrived at this conclusion by using the Master Theorem, but it's interesting to see this approach as well.
So now let's look at the new function. This one does
A constant amount of work for the base case check.
The work required for a recursive call to something half the size.
We can write this recurrence as
T(1) = 1
T(n) = 1 + T(n / 2)
Using the same trick as before, let's expand out T(n):
T(n) = 1 + T(n / 2)
= 1 + 1 + T(n / 4)
= 1 + 1 + 1 + T(n / 8)
More generally, after expanding out k times, we get
T(n) = k + T(n / 2k)
This stops when n / 2k = 1, which happens when k = log2 n (that is, lg n). In this case, we get that
T(n) = lg n + T(1) = lg n + 1
So T(n) = O(lg n) in this case.
Hope this helps!
Let's see now.. this will add 1 to the counter n times.
each call n is reduced by half until it reaches one.
You can get rid of the loop and use
counter+=n;
instead, because basically the loop adds n to counter, 1 by one.
This means that n will be added to the counter each time it runs, and then become smaller by 2 until it reaches one.
so say n = 40.
counter:
40 -> 60 -> 70 -> 75 -> 77 -> 77.
n:
40 -> 20 -> 10 -> 5 -> 2 -> 1.
Just a push in the right direction (counter+=n; being the important part)

Categories