How to incrementally increase a variable using an equation in c#? - c#

sorry if this is quite a simple question, I am just currently in the process of teaching myself C#.
foreach(int n in Enumerable.Range(0, Range)) {
double s += (1 / Math.Pow(n, 2));
double s6 = s * 6;
double pi = Math.Sqrt(s6);
Console.WriteLine("Pi is equal to {0}", pi);
}
This returns the error "invalid expression term '+='".
I previously wrote a program in python which performs the same task however, I want the line;
double s = (1 / Math.Pow(n, 2));
to add to itself while the foreach loop is true, in a similar fashion to my python variation;
s += 1/n**2;
Thanks in advance for any help!

As mentioned in the comments, there is a scope issue. s must be declared outside the loop and set an initial value to use += in the intended way.
double s = 0;
foreach(int n in Enumerable.Range(0, Range))
{
s += (1 / Math.Pow(n, 2));
double s6 = s * 6;
double pi = Math.Sqrt(s6);
Console.WriteLine("Pi is equal to {0}", pi);
}

Just need to initialize it first.
double s = 0;
foreach(int n in Enumerable.Range(0, Range)) {
s += (1 / Math.Pow(n, 2));
double s6 = s * 6;
double pi = Math.Sqrt(s6);
Console.WriteLine("Pi is equal to {0}", pi);
}

Related

I can't write a complex equation in code

I have been trying to turn this one conplex equation into code and it appears that I might have done something wrong. Here's the image of the equation:
Here's is the first code I tried using to convert the equation into code.
double answer = 1 - (Math.Pow(f, n) * ((s * l / f) + Math.Pow((20 / f), w) / Math.Pow(20, n)));
Here is the code that I used in my second attempt:
double answer = 1 - Math.Pow(f, n) * ((s * l) / f) + Math.Pow((20 / f), w) / Math.Pow(20, n);
If I assume that every variable of the equation is 2, than I get -.02. But when I ran the code, the first attempt code returned a value of -8, while the second attempt returned -6.75.
Is there anything I'm doing wrong in my code right now? And also sorry if I'm bad at explaining stuffs.
I tested this out and got the result of -0.02. Try splitting up the code to make it more legible. It might help you diagnose the syntax of your complex equation on one line.
double f = 2;
double n = 2;
double s = 2;
double w = 2;
double l = 2;
double A = Math.Pow(f, n);
double B = (s * l) / f;
double C = Math.Pow((20 / f), w);
double bottom = Math.Pow(20, n);
double top = A * (B + C);
double answer = 1 - top / bottom;
In both attempts you just got your brackets in the wrong spot.
Try this:
double answer =
1 - Math.Pow(f, n) * (s * l / f + Math.Pow((20 / f), w)) / Math.Pow(20, n);
Try to use the formula below instead :
double answer = (1 - Math.pow((Math.pow(f,n)*[s*l/f+20/f})),w)/Math.pow(20,f)

BBP algorithm get nth digit of PI?

I am trying to turn the BBP Formula (Bailey-Borwein-Plouffe) in to C# code, it is digit extraction of pi in base 16 (spigot algorithm), the idea is give the input of what index/decimal place you want of pi then get that single digit. Let's say I want the digit that are at the decimal place/index 40000 (in base 16) without having to calculate pi with 40000 decimals because I don't care about the other digits.
Anyhow here is the math formula, (doesn't look like it should be to much code? )
Can't say I understand 100% what the formal mean, if I did I probably be able to make it in to code, but from my understanding looking at it.
Is this correct?
pseudo code
Pi = SUM = (for int n = 0; n < infinity;n++) { SUM += ((4/((8*n)+1))
- (2/((8*n)+4)) - (1/((8*n)+5)) - (1/((8*n)+6))*((1/16)^n)) }
Capital sigma basically is like a "for loop" to sum sequences together?
example
and in C# code:
static int CapSigma(int _start, int _end)
{
int sum = 0;
for(int n = _start; n <= _end; n++)
{
sum += n;
}
return (sum);
}
Code so far (not working):
static int BBPpi(int _precision)
{
int pi = 0;
for(int n = 0; n < _precision; n++)
{
pi += ((16 ^ -n) * (4 / (8 * n + 1) - 2 / (8 * n + 4) - 1 / (8 * n + 5) - 1 / (8 * n + 6)));
}
return (pi);
}
I'm not sure how to make it in to actual code also if my pseudo code math is correct?
How to sum 0 to infinity? Can't do it in a for loop and also where in the formula is the part ("input") that specify what nth (index) digit you want to get out? is it the start n (n = 0)? so too get digit 40000 would be n =40000?
You need to cast to double :
class Program
{
static void Main(string[] args)
{
double sum = 0;
for (int i = 1; i < 100; i++)
{
sum += BBPpi(i);
Console.WriteLine(sum.ToString());
}
Console.ReadLine();
}
static double BBPpi(int n)
{
double pi = ((16 ^ -n) * (4.0 / (8.0 * (double)n + 1.0) - 2 / (8.0 * (double)n + 4.0) - 1 / (8.0 * (double)n + 5.0) - 1.0 / (8.0 * (double)n + 6.0)));
return (pi);
}
}

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;
}
}

Summing infinite series 1/n

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

C# - Index was out of range

I am trying to convert a C++ class to C# and in the process learn something of C++. I had never run into a vector<> before and my understanding is this is like a List<> function in C#. During the conversion of the class I re-wrote the code using List futures_price = New List(Convert.ToInt32(no_steps) + 1);. As soon as I run the code, I get a "Index was out of range" error.
Having looked around on SOF, I believe the issue is regarding the parameter being out of index range relating to this, but I do not see a simple solution to solve this with the below code.
In particular, this is the line that is triggering the error: futures_prices[0] = spot_price * Math.Pow(d, no_steps);
Below is the full code:
public double futures_option_price_call_american_binomial(double spot_price, double option_strike, double r, double sigma, double time, double no_steps)
{
//double spot_price, // price futures contract
//double option_strike, // exercise price
//double r, // interest rate
//double sigma, // volatility
//double time, // time to maturity
//int no_steps
List<double> futures_prices = new List<double>(Convert.ToInt32(no_steps) + 1);
//(no_steps+1);
//double call_values = (no_steps+1);
List<double> call_values = new List<double>(Convert.ToInt32(no_steps) + 1);
double t_delta = time/no_steps;
double Rinv = Math.Exp(-r*(t_delta));
double u = Math.Exp(sigma * Math.Sqrt(t_delta));
double d = 1.0/u;
double uu= u*u;
double pUp = (1-d)/(u-d); // note how probability is calculated
double pDown = 1.0 - pUp;
futures_prices[0] = spot_price * Math.Pow(d, no_steps);
int i;
for (i=1; i<=no_steps; ++i) futures_prices[i] = uu*futures_prices[i-1]; // terminal tree nodes
for (i=0; i<=no_steps; ++i) call_values[i] = Math.Max(0.0, (futures_prices[i]-option_strike));
for (int step = Convert.ToInt32(no_steps) - 1; step >= 0; --step)
{
for (i = 0; i <= step; ++i)
{
futures_prices[i] = d * futures_prices[i + 1];
call_values[i] = (pDown * call_values[i] + pUp * call_values[i + 1]) * Rinv;
call_values[i] = Math.Max(call_values[i], futures_prices[i] - option_strike); // check for exercise
};
};
return call_values[0];
}
Here is the original source in C++:
double futures_option_price_call_american_binomial(const double& F, // price futures contract
const double& K, // exercise price
const double& r, // interest rate
const double& sigma, // volatility
const double& time, // time to maturity
const int& no_steps) { // number of steps
vector<double> futures_prices(no_steps+1);
vector<double> call_values (no_steps+1);
double t_delta= time/no_steps;
double Rinv = exp(-r*(t_delta));
double u = exp(sigma*sqrt(t_delta));
double d = 1.0/u;
double uu= u*u;
double pUp = (1-d)/(u-d); // note how probability is calculated
double pDown = 1.0 - pUp;
futures_prices[0] = F*pow(d, no_steps);
int i;
for (i=1; i<=no_steps; ++i) futures_prices[i] = uu*futures_prices[i-1]; // terminal tree nodes
for (i=0; i<=no_steps; ++i) call_values[i] = max(0.0, (futures_prices[i]-K));
for (int step=no_steps-1; step>=0; --step) {
for (i=0; i<=step; ++i) {
futures_prices[i] = d*futures_prices[i+1];
call_values[i] = (pDown*call_values[i]+pUp*call_values[i+1])*Rinv;
call_values[i] = max(call_values[i], futures_prices[i]-K); // check for exercise
};
};
return call_values[0];
};
A List<double> starts out empty until you add items to it. (passing the constructor argument just sets the capacity, preventing costly resizes)
You can't access [0] until you Add() it.
To use it the way you are, use an array instead.
As SLaks says, it's better to use an Array in this situation. C# lists are filled with Add method and values are removed through Remove method... this would be more complicated and memory/performance expensive as you are also replacing values.
public Double FuturesOptionPriceCallAmericanBinomial(Double spotPrice, Double optionStrike, Double r, Double sigma, Double time, Double steps)
{
// Avoid calling Convert multiple times as it can be quite performance expensive.
Int32 stepsInteger = Convert.ToInt32(steps);
Double[] futurePrices = new Double[(stepsInteger + 1)];
Double[] callValues = new Double[(stepsInteger + 1)];
Double tDelta = time / steps;
Double rInv = Math.Exp(-r * (tDelta));
Double u = Math.Exp(sigma * Math.Sqrt(tDelta));
Double d = 1.0 / u;
Double uu = u * u;
Double pUp = (1 - d) / (u - d);
Double pDown = 1.0 - pUp;
futurePrices[0] = spotPrice * Math.Pow(d, steps);
for (Int32 i = 1; i <= steps; ++i)
futurePrices[i] = uu * futurePrices[(i - 1)];
for (Int32 i = 0; i <= steps; ++i)
callValues[i] = Math.Max(0.0, (futurePrices[i] - optionStrike));
for (Int32 step = stepsInteger - 1; step >= 0; --step)
{
for (Int32 i = 0; i <= step; ++i)
{
futurePrices[i] = d * futurePrices[(i + 1)];
callValues[i] = ((pDown * callValues[i]) + (pUp * callValues[i + 1])) * rInv;
callValues[i] = Math.Max(callValues[i], (futurePrices[i] - option_strike));
}
}
return callValues[0];
}

Categories

Resources