Summing infinite series 1/n - c#
I just started taking my first steps in learning coding and general (starting with c#)and I'm learning from a book currently. The book leaves questions at the end of every chapter. I'm currently unsure on how to proceed with this specific question. The question is as follows:
Question: Write a program that calculates the sum (with precision of 0.001) of the following sequence: 1 + 1/2 - 1/3 + 1/4 - 1/5 + … 1/n
The book has given the following guidelines for this problem:
Guide Lines: Accumulate the sum of the sequence in a variable inside a while-loop (see the chapter "Loops"). At each step compare the old sum with the new sum. If the difference between the two sums Math.Abs(current_sum – old_sum) is less than the required precision (0.001), the calculation should finish because the difference is constantly decreasing and the precision is constantly increasing at each step of the loop. The expected result is 1.307
I have an idea on how to implement this but I do not know how or where to initiate and break the loop when the sum has reached the required precision. I currently use user input to enter n. I would like to know how to automate this process.
Here is my code so far. I know its a cop out to use the format {N:2} but i am not sure how to proceed. Would very much appreciate the help! Thanks!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Demo
{
class Program
{
static void Main()
{
Console.Write("Please enter n: ");
double counter = double.Parse(Console.ReadLine());
double sum = 1 + AddSum(counter); // calculate infinite sum
Console.WriteLine("Sum = {0:N3}", sum);
}
static double AddSum(double n)
{
double a = 0;
for (double i = 1; i < n; i++)
{
if(i % 2 == 0)
{
a -= 1 / (i +1); // calculates negative fractions
}
else
{
a += 1 / (i +1); // calculates positive fractions
}
}
return a;
}
}
Here's an example that doesn't suffer from subtractive cancellation:
static double AddSum()
{
double pos = 1.0;
double neg = 0.0;
double delta = 0.001;
double current = pos + neg;
double previous = pos + 2.0 * delta;
int i = 2;
while (Math.Abs(current - previous) >= delta)
{
if (i % 2 == 0)
{
pos += 1.0 / i;
}
else
{
neg -= 1.0 / i;
}
previous = current;
current = pos + neg;
i++;
}
return current;
}
You may want to follow the given guideline: don't enter n as the program shall finish automatically. Where is the suggested while loop? You'll figure the answer out quickly yourself then :-)
Maybe start with this:
static void Main()
{
decimal result = 1;
int n = 1;
do
{
// remember the current result
result += 1 / (++n * DetermineMultiplier(n));
} while ( /* precision calculation here */ );
// print result and n
}
private int DetermineMultiplier(int n)
{
// return -1 if n is odd, 1 if it is even
}
As you not want to specify n and the only exit condition is a precision check, you could do this.
static double AddSum()
{
double a = 0;
double oldvalue;
int i = 1;
do
{
oldvalue = a;
a += (i % 2 == 0) ? (double)-1 / (i + 1) : (double)1 / (i + 1);
i++;
}while (!(i != 1 && Math.Abs(a - oldvalue) < 0.0001)); // we can remove i!=1 if we know and hard code first default value
return a;
}
Working Example
Related
Specify a starting index for continuation of calculating Pi
This C# code will calculate Pi to whatever length I specify. I want to be able to start at a given index without recalculating to that point. Precision is not a great concern as this is a puzzle project but I do need this code to reproduce the same results over and over. It works fine as is but I haven't been able to figure out how to modify for a starting point. //Looking to pass BigInteger to specify a starting index for continuation of calculating Pi public static BigInteger GetPi(int digits, int iterations) { return 16 * ArcTan1OverX(5, digits).ElementAt(iterations) - 4 * ArcTan1OverX(239, digits).ElementAt(iterations); } public static IEnumerable<BigInteger> ArcTan1OverX(int x, int digits) { var mag = BigInteger.Pow(10, digits); var sum = BigInteger.Zero; bool sign = true; for (int i = 1; true; i += 2) { var cur = mag / (BigInteger.Pow(x, i) * i); if (sign) { sum += cur; } else { sum -= cur; } yield return sum; sign = !sign; } }
You are using the Machin formula with the Taylor serie expansion for Arctan. It should give you about 1.4 digits of precision for each "cycle" (see here). You can't "shortcut" the calculation of the Taylor serie. You can speed-up a little the program removing the IEnumerable<BigInteger> part and simply returning the nth iteration (the yield instruction has a cost) and by changing the BigInteger.Pow with a fixed multiplication. But the calculation will still be made iteratively. There is no known way for calculating PI with a precision of n digits in O(1) time. Note that there are algorithms (see the wiki) that converge in a smaller number of cycles, but I'm not sure if they converge in a smaller number of operations (their cycles are much more complex). An optimized version of the code: public static BigInteger GetPi2(int digits, int iterations) { return 16 * ArcTan1OverX2(5, digits, iterations) - 4 * ArcTan1OverX2(239, digits, iterations); } public static BigInteger ArcTan1OverX2(int x, int digits, int iterations) { var mag = BigInteger.Pow(10, digits); var sum = BigInteger.Zero; bool sign = true; int imax = 1 + (2 * iterations); int xsquared = x * x; BigInteger pow = x; for (int i = 1; i <= imax; i += 2) { if (i != 1) { pow *= xsquared; } var cur = mag / (pow * i); if (sign) { sum += cur; } else { sum -= cur; } sign = !sign; } return sum; }
Riemann Midpoint Sum getting crazy numbers
I'm working on a Midpoint Riemann Sum program, and it finds the integral of a randomly generated function called f. Here's what wrote: public static double FindIntegral (double start, double end, function f) { double sum = 0; double stepsize = 1E-2; int numSteps = (int)((end - start) / stepsize); for (int i = 0; i < numSteps; i++) { sum += f(start + (stepsize * (i + 0.5))); } return sum * stepsize; } The function returns numbers that are too low (I have a reliable checking mechanism). I put in x^3 for f, and I got the right answer. I tried a couple of more integrable functions and got a good answer. But somehow once I put in f it doesn't work.
I got the math formula for "Riemann Midpoint Sum" from here. My implementation below seems to get the right answer (using the example function on the page). I used a class because 1) I could make the algorithm work specifying either the step size or the number of rectangles (I preferred the latter) and 2) I didn't see any reason to hard-code either into the algorithm. As it turns out your code seemed to work just fine (see below); Make sure the code you have here in your question is what you're executing and make sure your expected result is accurate and that you're supplying good inputs (i.e. you don't have start and end backwards or the wrong function f or something). In other words what you provided in your question looks fine. Note double is approximate in C# (floating point arithmetic, in general) so to compare equality you can't use == unless you want exact if you're using unit tests or something. public class Program { public static void Main() { function f = x => 50 / (10 + x * x); // 9.41404285216233 Console.Out.WriteLine(new RiemannMidpointSum(6).FindIntegral(1, 4, f)); // 9.41654853716462 Console.Out.WriteLine(new RiemannMidpointSum(1E-2).FindIntegral(1, 4, f)); // 9.41654853716462 Console.Out.WriteLine(Program.FindIntegral(1, 4, f)); } // This is your function. public static double FindIntegral (double start, double end, function f) { double sum = 0; double stepsize = 1E-2; int numSteps = (int)((end - start) / stepsize); for (int i = 0; i < numSteps; i++) { sum += f(start + (stepsize * (i + 0.5))); } return sum * stepsize; } } public delegate double function(double d); public class RiemannMidpointSum { private int? _numberOfRectangles; private double? _widthPerRectangle; public RiemannMidpointSum(int numberOfRectangles) { // TODO: Handle non-positive input. this._numberOfRectangles = numberOfRectangles; } public RiemannMidpointSum(double widthPerRectangle) { // TODO: Handle non-positive input. this._widthPerRectangle = widthPerRectangle; } public double FindIntegral(double a, double b, function f) { var totalWidth = b - a; var widthPerRectangle = this._widthPerRectangle ?? (totalWidth / this._numberOfRectangles.Value); var numberOfRectangles = this._numberOfRectangles ?? ((int)Math.Round(totalWidth / this._widthPerRectangle.Value, 0)); double sum = 0; foreach (var i in Enumerable.Range(0, numberOfRectangles)) { var rectangleMidpointX = a + widthPerRectangle * i + widthPerRectangle / 2; var rectangleHeightY = f(rectangleMidpointX); var rectangleArea = widthPerRectangle * rectangleHeightY; sum += rectangleArea; } return sum; } }
code for finding biggest factor of the number
I'm improving my C# skills and now I'm writing code for finding biggest factor of the number. However, it doesn't display anything static void Main(string[] args) { Int64 a = 600851475143; List<Int64> dividers = new List<Int64>(); for (Int64 b = 2; b < a; b++) { if (a % b == 0) { dividers.Add(b); } } Int64 max = dividers.Max(); Console.WriteLine(max); Console.ReadLine(); }
Your program works fine - it just takes a really long time to execute. You need to find a more efficient means of doing this. A trick you can use is to only factor up to the square root - factors always come in pairs. Int64 a = 600851475143; List<Int64> dividers = new List<Int64>(); for (Int64 b = 2; b <= Math.Sqrt(a); b++) { if (a % b == 0) { dividers.Add(b); dividers.Add(a / b); } } Int64 max = dividers.Max(); You can further improve this - you can instead of keeping a list of all of the factors, just keep track of the biggest one seen so far.
Knowing now that you're trying to solve Euler Problem 3 I'm not going to give a direct answer. Things to consider when solving this problem: ## 1 ## You only have to check up to the sqrt() of that number. double limit = Math.Sqrt(number); for (int i = 2; i <= limit; i++) ## 2 ## An IsPrime function public static bool IsPrime(long number) { if ((number & 1) == 0) { return number == 2; } double limit = Math.Sqrt(number); for (int i = 3; i <= limit; i += 2) { if ((number % i) == 0) { return false; } } return number != 1; } ## 3 ## When you find a factor (a % b == 0), check if b or (a/b) are prime and keep the largest one that exceeds the currently known largest prime factor
Double the alternative digits in a number and add each digit
I am using the following code to double alternative digits from a number and add every digit but its not working in c# int sum=0,r,number; Console.WriteLine("Enter the number"); number = int.Parse(Console.ReadLine()); if (number % 2!= 0) { number = number * 2; number++; } Console.WriteLine("numbers:" + number); Console.ReadLine(); while (number!= 0) { r = number % 10; number= number/ 10; sum = sum + r; } Console.WriteLine("sum of digits of the number:" + sum); Console.ReadLine(); Kindly help me. Thank you in advance.
As StevieB said "You're not doubling alternative digits. You're doubling the number and adding 1 if the original number is odd. Then you're summing the digits of the number." The following code should work for you. I have not tested it for all possible scenarios so please do so. Also tweek it a little as per your requirements. Console.WriteLine("Enter a number:"); char[] enteredNumber = Console.ReadLine().ToArray(); int finalNumber = 0; for (int i = 0; i < enteredNumber.Count(); i++) { if (i % 2 != 0)//This condition might need tweeking { finalNumber = finalNumber + (Convert.ToInt32(enteredNumber[i].ToString()) * 2); } else { finalNumber = finalNumber + Convert.ToInt32(enteredNumber[i].ToString()); } } Console.WriteLine(finalNumber);
What you are looking for is Luhn Algorithm which I have reproduced here for you. Luhn Algorithm - C# Luhn Algorithm uses the last digit (rightmost digit) as a checksum digit. Hence in my first iteration I skip it since it's not required in the first parts of the function. Since the length of a given number can vary, I have used int a to check my position and know which number I should double and which I should skip. Read more about the Luhn Algorithm here. using System; public class Program { public void Main() { int sum=0,d; string oNum = "79927398713"; int a = 0; for(int i = oNum.Length-2; i>=0;i--) { d = Convert.ToInt32(oNum.Substring(i,1)); if (a % 2 == 0) d = d*2; if (d > 9) d -= 9; sum += d; a++; } if ((10 - (sum%10)) == Convert.ToInt32(oNum.Substring(oNum.Length-1))) { Console.WriteLine("Valid"); } else { Console.WriteLine("Invalid"); } Console.WriteLine("sum of digits of the number:" + sum); } } There are three places where the Console writes a line. And at least two of those are visible for any given number. The line that you wanted, "sum of digits of the number:" will always show.
How can I improve this square root method?
I know this sounds like a homework assignment, but it isn't. Lately I've been interested in algorithms used to perform certain mathematical operations, such as sine, square root, etc. At the moment, I'm trying to write the Babylonian method of computing square roots in C#. So far, I have this: public static double SquareRoot(double x) { if (x == 0) return 0; double r = x / 2; // this is inefficient, but I can't find a better way // to get a close estimate for the starting value of r double last = 0; int maxIters = 100; for (int i = 0; i < maxIters; i++) { r = (r + x / r) / 2; if (r == last) break; last = r; } return r; } It works just fine and produces the exact same answer as the .NET Framework's Math.Sqrt() method every time. As you can probably guess, though, it's slower than the native method (by around 800 ticks). I know this particular method will never be faster than the native method, but I'm just wondering if there are any optimizations I can make. The only optimization I saw immediately was the fact that the calculation would run 100 times, even after the answer had already been determined (at which point, r would always be the same value). So, I added a quick check to see if the newly calculated value is the same as the previously calculated value and break out of the loop. Unfortunately, it didn't make much of a difference in speed, but just seemed like the right thing to do. And before you say "Why not just use Math.Sqrt() instead?"... I'm doing this as a learning exercise and do not intend to actually use this method in any production code.
First, instead of checking for equality (r == last), you should be checking for convergence, wherein r is close to last, where close is defined by an arbitrary epsilon: eps = 1e-10 // pick any small number if (Math.Abs(r-last) < eps) break; As the wikipedia article you linked to mentions - you don't efficiently calculate square roots with Newton's method - instead, you use logarithms.
float InvSqrt (float x){ float xhalf = 0.5f*x; int i = *(int*)&x; i = 0x5f3759df - (i>>1); x = *(float*)&i; x = x*(1.5f - xhalf*x*x); return x;} This is my favorite fast square root. Actually it's the inverse of the square root, but you can invert it after if you want....I can't say if it's faster if you want the square root and not the inverse square root, but it's freaken cool just the same. http://www.beyond3d.com/content/articles/8/
What you are doing here is you execute Newton's method of finding a root. So you could just use some more efficient root-finding algorithm. You can start searching for it here.
Replacing the division by 2 with a bit shift is unlikely to make that big a difference; given that the division is by a constant I'd hope the compiler is smart enough to do that for you, but you may as well try it to see. You're much more likely to get an improvement by exiting from the loop early, so either store new r in a variable and compare with old r, or store x/r in a variable and compare that against r before doing the addition and division.
Instead of breaking the loop and then returning r, you could just return r. May not provide any noticable increase in performance.
With your method, each iteration doubles the number of correct bits. Using a table to obtain the initial 4 bits (for example), you will have 8 bits after the 1st iteration, then 16 bits after the second, and all the bits you need after the fourth iteration (since a double stores 52+1 bits of mantissa). For a table lookup, you can extract the mantissa in [0.5,1[ and exponent from the input (using a function like frexp), then normalize the mantissa in [64,256[ using multiplication by a suitable power of 2. mantissa *= 2^K exponent -= K After this, your input number is still mantissa*2^exponent. K must be 7 or 8, to obtain an even exponent. You can obtain the initial value for the iterations from a table containing all the square roots of the integral part of mantissa. Perform 4 iterations to get the square root r of mantissa. The result is r*2^(exponent/2), constructed using a function like ldexp. EDIT. I put some C++ code below to illustrate this. The OP's function sr1 with improved test takes 2.78s to compute 2^24 square roots; my function sr2 takes 1.42s, and the hardware sqrt takes 0.12s. #include <math.h> #include <stdio.h> double sr1(double x) { double last = 0; double r = x * 0.5; int maxIters = 100; for (int i = 0; i < maxIters; i++) { r = (r + x / r) / 2; if ( fabs(r - last) < 1.0e-10 ) break; last = r; } return r; } double sr2(double x) { // Square roots of values in 0..256 (rounded to nearest integer) static const int ROOTS256[] = { 0,1,1,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12, 12,12,12,12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, 13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, 14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, 15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16 }; // Normalize input int exponent; double mantissa = frexp(x,&exponent); // MANTISSA in [0.5,1[ unless X is 0 if (mantissa == 0) return 0; // X is 0 if (exponent & 1) { mantissa *= 128; exponent -= 7; } // odd exponent else { mantissa *= 256; exponent -= 8; } // even exponent // Here MANTISSA is in [64,256[ // Initial value on 4 bits double root = ROOTS256[(int)floor(mantissa)]; // Iterate for (int it=0;it<4;it++) { root = 0.5 * (root + mantissa / root); } // Restore exponent in result return ldexp(root,exponent>>1); } int main() { // Used to generate the table // for (int i=0;i<=256;i++) printf(",%.0f",sqrt(i)); double s = 0; int mx = 1<<24; // for (int i=0;i<mx;i++) s += sqrt(i); // 0.120s // for (int i=0;i<mx;i++) s += sr1(i); // 2.780s for (int i=0;i<mx;i++) s += sr2(i); // 1.420s }
Define a tolerance and return early when subsequent iterations fall within that tolerance.
Since you said the code below was not fast enough, try this: static double guess(double n) { return Math.Pow(10, Math.Log10(n) / 2); } It should be very accurate and hopefully fast. Here is code for the initial estimate described here. It appears to be pretty good. Use this code, and then you should also iterate until the values converge within an epsilon of difference. public static double digits(double x) { double n = Math.Floor(x); double d; if (d >= 1.0) { for (d = 1; n >= 1.0; ++d) { n = n / 10; } } else { for (d = 1; n < 1.0; ++d) { n = n * 10; } } return d; } public static double guess(double x) { double output; double d = Program.digits(x); if (d % 2 == 0) { output = 6*Math.Pow(10, (d - 2) / 2); } else { output = 2*Math.Pow(10, (d - 1) / 2); } return output; }
I have been looking at this as well for learning purposes. You may be interested in two modifications I tried. The first was to use a first order taylor series approximation in x0: Func<double, double> fNewton = (b) => { // Use first order taylor expansion for initial guess // http://www27.wolframalpha.com/input/?i=series+expansion+x^.5 double x0 = 1 + (b - 1) / 2; double xn = x0; do { x0 = xn; xn = (x0 + b / x0) / 2; } while (Math.Abs(xn - x0) > Double.Epsilon); return xn; }; The second was to try a third order (more expensive), iterate Func<double, double> fNewtonThird = (b) => { double x0 = b/2; double xn = x0; do { x0 = xn; xn = (x0*(x0*x0+3*b))/(3*x0*x0+b); } while (Math.Abs(xn - x0) > Double.Epsilon); return xn; }; I created a helper method to time the functions public static class Helper { public static long Time( this Func<double, double> f, double testValue) { int imax = 120000; double avg = 0.0; Stopwatch st = new Stopwatch(); for (int i = 0; i < imax; i++) { // note the timing is strictly on the function st.Start(); var t = f(testValue); st.Stop(); avg = (avg * i + t) / (i + 1); } Console.WriteLine("Average Val: {0}",avg); return st.ElapsedTicks/imax; } } The original method was faster, but again, might be interesting :)
Replacing "/ 2" by "* 0.5" makes this ~1.5 times faster on my machine, but of course not nearly as fast as the native implementation.
Well, the native Sqrt() function probably isn't implemented in C#, it'll most likely be done in a low-level language, and it'll certainly be using a more efficient algorithm. So trying to match its speed is probably futile. However, in regard to just trying to optimize your function for the heckuvit, the Wikipedia page you linked recommends the "starting guess" to be 2^floor(D/2), where D represents the number of binary digits in the number. You could give that an attempt, I don't see much else that could be optimized significantly in your code.
You can try r = x >> 1; instead of / 2 (also in the other place you device by 2). It might give you a slight edge. I would also move the 100 into the loop. Probably nothing, but we are talking about ticks in here. just checking it now. EDIT: Fixed the > into >>, but it doesn't work for doubles, so nevermind. the inlining of the 100 gave me no speed increase.