Implementing partial recursive function in C# - c#

I am having trouble with somwhow implementing a partial recursive function (at least in my mind though).
for any given p and arbitrary maxsteps = 100, calculate L:

You could pass the maxsteps down to the recursive function and subtract 1 on each step until you reach 0, with is the end condition:
public double L(double p, int maxSteps)
{
if (maxSteps == 0)
{
return 1 / (p + 1);
}
return 1 / (p + L(p, maxSteps - 1));
}

I appreciate you want a recursive function, but I figured I'd provide a non-recursive alternative in case it turns out to be preferred:
private static double CalculateL(double p, int maxsteps)
{
double val = 1 / (p + 1);
for (int i = 1; i <= maxsteps; ++i)
{
val = 1 / (p + val);
}
return val;
}
I'm not 100% sure about maxsteps, based on the other answers. If the answer isn't right, then you probably want < maxsteps where I've got <= maxsteps.
Also, please read Is floating point math broken? if you're expecting very precise results.

There I left you the code for the recursive approach:
class Program
{
static void Main(string[] args)
{
double recursiveL = CalculateL(100, 100);
double notRecursiveLWrong = NotRecursiveCalculateLWrong(100, 100);
double notRecursiveLRight = NotRecursiveCalculateLRight(100, 100);
}
private static double CalculateL(double p, int maxSteps)
{
if (maxSteps == 0)
{
return (1 / (p + 1));
}
else
{
return (1 / (p + CalculateL(p, maxSteps - 1)));
}
}
private static double NotRecursiveCalculateLWrong(double p, int maxSteps)
{
double result = 0;
for (int i = 0; i < maxSteps; i++)
{
result = (1 / (p + result));
}
return result;
}
private static double NotRecursiveCalculateLRight(double p, int maxSteps)
{
double result = 1 / (p + 1);
for (int i = 0; i < maxSteps; i++)
{
result = (1 / (p + result));
}
return result;
}
}
While making it I was thinking about the fact that for this problem, recursion isn't needed and now I can see that I'm not the only one.
I added my not recursive approach.
Edit:
If you try my code you will see that every method returns the same value, WATCHOUT, this is cause of the low precision in floating points.
The correct approach is NotRecursiveCalculateLRight which is stated in #John 's answer.

Related

How to convert a growing recursive math function to code?

static void Main(string[] args)
{
var k0 = Convert.ToInt32(Console.ReadLine());
var kn = Convert.ToInt32(Console.ReadLine());
var result = Calculate(k0, kn);
}
private static double Calculate(int k0, int kn)
{
var k1 = Math.Round(Math.Pow(Math.Sqrt(k0) + Math.Sqrt(Math.PI), 2)); // first iteration
var k2 = Math.Round(Math.Pow(Math.Sqrt(k1) + Math.Sqrt(Math.PI), 2)); // 2nd iteration
var k3 = Math.Round(Math.Pow(Math.Sqrt(k2) + Math.Sqrt(Math.PI), 2)); // 3rd iteration
// calculate until kn
return k3; // this should return kn
}
How should I change this code so it can recursively calculate until kn'th iteration?
To avoid confusion, I don't think you're asking about recursive functions/methods that call themselves until some desired condition and then return a value.
This is easy enough using a for loop
private static double Calculate(int k0, int kn)
{
double result = k0;
for (var i = 0; i < kn; i++){
result = Math.Round(Math.Pow(Math.Sqrt(result) + Math.Sqrt(Math.PI), 2));
}
return result;
}
You could do this with recursion but in this case that would be overkill and it's not necessary.
Recursive which has the same signature, since you asked for it
private static double Calculate(int k, int n)
{
return n == 0 ? k : Math.Round(Math.Pow(Math.Sqrt(Calculate(k, n - 1)) + Math.Sqrt(Math.PI), 2));
}
If you want a recursive solution:
private static double Calculate(int k0, int kn)
{
return CalculateInternal(k0, kn, 1);
}
private static double CalculateInternal(int ki, int kn, int n)
{
// Base case: exit when we've completed all iterations
if (n > kn) return ki;
// Current iteration
var x = Math.Round(Math.Pow(Math.Sqrt(ki) + Math.Sqrt(Math.PI), 2));
// Pass current iteration to next iteration
return CalculateInternal(x, kn, n + 1);
}
Well you could try to do this by adding in an optional argument.
private static double Calculate(int k0, int kn, int i = 0)
{
if(i < kn)
{
return Calculate( Math.Round(Math.Pow(Math.Sqrt(k0) + Math.Sqrt(Math.PI), 2)) , kn, ++i);
}
return k0;
}

A function to get which number shall 2 be raised to to get x

Find x in 2^x = n.
This is what I am trying to do.(It is not for any specific purpose. It just looks good.)
This is what I wrote but it doesn't work.
public double f(double x)
{
double result = 0;
double increaser = 1;
double subtract = result - increaser;
double add = result + increaser;
while(true)
{
if((Math.Pow(2,result) == x) || increaser == 0.0001)
{
break;
}
double sP = Math.Abs(Math.Pow(2,subtract) - x);
double aP = Math.Abs(Math.Pow(2,add) - x);
double nP = Math.Abs(Math.Pow(2,result) - x);
if((sP < nP) && (sP < aP))
{
result -= increaser;
}
else if((aP < nP) && (aP < sP))
{
result += increaser;
}
else if((nP < sP) && (nP < aP))
{
increaser = increaser / 10;
}
}
return result;
}
This function is called the logarithm:
return Math.Log2(n);
For the general case, you can use two formulae for this:
if bx = n, then x = logbn; and
logba = logxa/logxb.
Since what you're looking for is x in 2x = n, that is x = log2n = logen/loge2, something that can be done with:
public double f(double x) {
return Math.Log(x) / Math.Log(2);
}
Of course, that's for the case where you have a limited set of logarithm bases (such as 10 or e). Since C# provides a call that will handle any base, you can bypass the division operation:
public double f(double x) {
return Math.Log(x, 2);
}
or even use the base-2 one:
public double f(double x) {
return Math.Log2(x);
}

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

How to shift all the whole numbers in a double to the right of the point

How to shift all the whole numbers in a double to the right of the point ?
Example i have 5342, i want the function to return 0.5342. I do not know the number of digits in the double, it's randomly generated. Should be fairly easy but i can't find any answers.
private static void Main(string[] args)
{
Console.WriteLine(MyFunction(5127));
Console.WriteLine(MyFunction(1));
Console.WriteLine(MyFunction(51283271));
Console.WriteLine(MyFunction(-512));
Console.WriteLine(MyFunction(0));
}
public static double MyFunction(double myNumber)
{
return Math.Floor(myNumber) / Math.Pow(10, Math.Abs(myNumber).ToString().Length);
}
This sounds like a pretty bizarre task, to be honest, but you could use:
while (Math.Abs(value) >= 1)
{
value = value / 10;
}
That will go into an infinite loop if the input is infinity though - and you may well lose information as you keep dividing. The latter point is important - if what you're really interested in is the decimal representation, you should consider using decimal instead of double.
You could potentially use a mixture of Math.Log and Math.Pow to do it, but the above is probably what I'd start with.
This will get you most of the way there
public static string test()
{
double dub = 5432;
string dubTxt = dub.ToString();
string text = "0.";
string test = string.Concat(text + dubTxt);
if (1 == 1)
{
MessageBox.Show(test);
return test;
}
}
You will have to develop more if statements to handle the negative numbers.
public static string test()
{
double dub = 5432;
string dubTxt = dub.ToString();
string text = "0.";
string test = string.Concat(text + dubTxt);
if (dub < 0)
{
//Do this code instead
}
}
Good Luck. Please bump me if you choose it!! I need the cred so I can do other junk. :-D
Just divide by 10 until the number is less than 1.
public static double SomeMethod(double n)
{
double d = n;
bool isNegative = (d < 0);
if(isNegative)
d = d * -1;
while(d >= 1)
d = d/10;
if(isNegative)
d = d * -1;
return d;
}
Alternative (and more precise) option:
public static double SomeMethod2(double n)
{
double d = n;
bool isNegative = (d < 0);
if(isNegative)
d = d * -1;
int numberOfDigits = ((int)d).ToString().Length;
int divisor = 1;
for(int i = 0; i < numberOfDigits; i++)
divisor = divisor * 10;
d = d/divisor;
if(isNegative)
d = d * -1;
return d;
}

Problem with return in C#

Because of asking my last question, I've changed my code to use return. I always have this problem with return: I know I should use return (where I comment in code below) but I dont know how should I define it to work? Thanks for your help.
public double bigzarb(int u, int v)
{
double n;
int x=0;
int y;
int w=0;
int z;
string[] i = textBox7.Text.Split(',');
int[] nums = new int[i.Length];
for (int counter = 0; counter < i.Length; counter++)
{
nums[counter] = Convert.ToInt32(i[counter]);
}
u = nums[0];
double firstdigits =Math.Floor(Math.Log10(u) + 1);
v = nums[1];
double seconddigits = Math.Floor(Math.Log10(v) + 1);
if (firstdigits >= seconddigits)
{
n = firstdigits;
}
else
{
n = seconddigits;
}
if (u == 0 || v == 0)
{
MessageBox.Show("the Multiply is 0");
}
string threshold = textBox9.Text;
int intthreshold = Convert.ToInt32(threshold);
int intn = Convert.ToInt32(n);
if (intn <= intthreshold)
{
double uv = u * v;
string struv = uv.ToString();
MessageBox.Show(struv);
///i know here should be a return but i dont know how to define it to work
}
else
{
int m = Convert.ToInt32(Math.Floor(n / 2));
x = u % 10 ^ m;
y = u / 10 ^ m;
w = v % 10 ^ m;
z = v / 10 ^ m;
return bigzarb(x, w) *Math.Pow(10,m) +(bigzarb(x,w)+bigzarb(w,y))*Math.Pow(10,m) +bigzarb(y,z);
}
}
arash, your problem isn't with that return, your problem is bigzarb() is declared as void which means it has no returning value yet you use it in your last line as bigzarb(x,w) * .... which will give you an error. Also, since you declared your bigzarb() as void, you cant return a value in it. Also ^ doesn't mean power of in .net, you should use Math.Power instead.
Edit: You should change your method from void bigzarb() to double bigzarb() and replace ^ with Math.Power and retry to see if yit works.
Last edit: Change your method return type to double from int and change the last line to:
return bigzarb(x, w) * Math.Pow(Convert.ToDouble(10), Convert.ToDouble(m)) + (bigzarb(x, w) + bigzarb(w, y)) * Math.Pow(Convert.ToDouble(10), Convert.ToDouble(m)) + bigzarb(y, z);
If your method is defined to "return void", you can't return some value.
So change that "void" into "int" or "double", whatever type of value you want to return.
The next question is what value do you want to return in that spot? Return that.
By the way: if you really don't want to return a value (ever!) then that "void" is correct and you should only use "return" without value (or let the method run until the last line of the method).
my tip to you is to structure your code, extract some of the code to separate functions with meaningful names and also rename your variables to sometging meaningful. That would make it easier to read, understand and you get a better "flow" in your code. Also, you should complement your text with an actual question. Try to insert an extra return statement in the if code block, it is perfectly fine to have multiple return statements.
if(logic check)
{
return something;
}
else
{
return something else;
}
You need to have return either in both statements or one return after the if-else block, otherwise you'll get somekind of compiler error saying that not all code paths returns a result or something similar.
You have only one return and it's a recursive call (calling itself) --> stack overflow! You need to have another return somewhere without a recursive call
public int bigzarb(int u, int v)
{
double n;
int x = 0;
int y;
int w = 0;
int z;
string[] i = textBox1.Text.Split(',');
int[] nums = new int[i.Length];
for (int counter = 0; counter < i.Length; counter++)
{
nums[counter] = Convert.ToInt32(i[counter]);
}
u = nums[0];
double firstdigits = Math.Floor(Math.Log10(u) + 1);
v = nums[1];
double seconddigits = Math.Floor(Math.Log10(v) + 1);
if (firstdigits >= seconddigits)
{
n = firstdigits;
}
else
{
n = seconddigits;
}
if (u == 0 || v == 0)
{
MessageBox.Show("the Multiply is 0");
}
//string threshold = textBox9.Text;
int intthreshold = Convert.ToInt32(textBox9.Text);//Edited by me
int intn = Convert.ToInt32(n);
if (intn <= intthreshold)
{
double uv = u * v;
string struv = uv.ToString();
MessageBox.Show(struv);
///i know i should use return here but how can i implement that to work?
}
else
{
int m = Convert.ToInt32(Math.Floor(n / 2));
x = u % 10 ^ m;
y = u / 10 ^ m;
w = v % 10 ^ m;
z = v / 10 ^ m;
return bigzarb(x, w) * (10 ^ m) + (bigzarb(x, w) + bigzarb(w, y)) * 10 ^ m + bigzarb(y, z);
}
return 0;
}
Its a confusing one.since your function contains Void as return type
Declare the integer variable for returning the values
Ex:
public int func()
{
int l_nData = 0;
if(condition)
{
l_nData = 1;
return l_nData;
}
else
{
l_nData = 2;
return l_nData;
}
return l_nData;
}

Categories

Resources