A Solution for Returning Derivative = Infinity - c#

This is a Math question, but to try to solve a C# Programming issue so I am not sure if here is the best place for it.
In the following code, I can get the Derivative:
var x = 13.399E+153;
var d = ((1 + x) * (1 - x));
Console.WriteLine("d = {0:0}", d);
Console.ReadLine();
Where 13.399E+153; the 9's are recurring. But if x becomes:
var x = 14.00E+153;
I get -Infinity. I have done some research already but do not understand any possible solution.
URL: Mathematical function differentiation with C#?
also: Limit of the derivative of a function as x goes to infinity
I do understand why this is ocurring however:
If the limit of f(x) f(x) exists, there is a horizontal asymptote.
Therefore as the function approaches infinity it becomes more linear and
...thus the derivative approaches zero.
.
My question is, if I am returning the Derivative as a double for example, what would a solution be to prevent it being returned as Infinity? Should I return 1, or Zero?
if (double.IsInfinity(Derivative))
{
return ?;
}

You get the result of negative Infinity because the mathematical value of the result is less than the least value that can be represented using 64 bit floating point numbers. This is completely normal, I see nothing that needs to be fixed.

Related

Large factorial using BigIntegers losing precision

It'sa me, with another problem.
I need to calculate a factorial of a really huge number, lets assume it is 95.
So as we all know 95! equals to:
10329978488239062144133688859495761720042551046933218543167809699858950620982142410696539365993509132394773015016946331626553858953528454377577119744
I have used a simple method calculating factorials using BigIntegers that I found somewhere around here few months ago:
public static BigInteger FactorialTest(BigInteger x)
{
if (x == 0)
return 1;
BigInteger res = x;
x--;
while (x > 1)
{
res *= x;
x--;
}
return res;
}
And only got a rounded up number:
10329978488239059262599702099394727095397746340117372869212250571234293987594703124871765375385424468563282236864226607350415360000000000000000000000
Next step was using the builtin BigInteger methods for addition, multiplication etc, hoping it will fix the problem - no still did not work.
Last thing I tried was using code of someone smarter, so reached for SolverFoundation, unfortunately
Microsoft.SolverFoundation.Common.BigInteger.Factorial(95)
still returns the rounded up number.
Is there anything I am missing that could get me the proper result? I really hoped BigIntegers would not lose precision like that.
According to http://2000clicks.com/MathHelp/BasicFactorialTable.aspx and other sites the number you are getting from your calculation is correct.

C# Math.Net Matrix Determinant, returns wrong number

I wanted to simplify my program a little bit and I am testing math.net, so for example I got matrix 2x2,
det(A) = a * d - b * c = 71 * 137 - 130 * 107 = -4183
Can sb tell me what is going on here, on the second screenshot, you can see that Math.Net Determinant() Function returns -4183,00000000000000018. How is it correct for the given matrix? Where this result came from? If it is double, it should be -4183.0.
Is it some kind of algorithm which count "well enough" but "much faster" for large data?
Screenshot 1
Screenshot 2
Second question, out of curiosity, what would be the quickest way to invert matrix modulo 256, using EXACTLY this method:
A^(-1) = 1/det(A) * (A^D)^T
where by (A^D)^T I mean transposed matrix of cofactors (I believe how it is called in English)
I wrote a method doing that, which works for Matrices or Multidimensional arrays, but I am curious what is the proper way of doing it in math.net, but using the equation I mentioned.
And as always, I truly appreciate every answer guys.
(btw yes, I am aware that I am doing to many casts, vars are declared many times, but try to ignore that, this is simply a testing field)
To make my 1st question more clear
(You can click '-' all you want, I don't care :))
#Szab
Thank you for the answer, I know that there is such behavior for decimal numbers, but to be more precise: I would like to know, why the result - 4183,00000000000000018 is different than:
This Result
There are no decimal places here, C# show very clearly that
det(A) = a * d - b * c = 71.0 * 137.0 - 130.0 * 107.0 = -4183.0
for a, b, c, d and det being all doubles.
/edit
Question answered, thank you all very much.
I think the first problem occurs just because the algorithm you are using is working with values of type double. As you may know, every number is represented in computer's memory as a binary value. The problem with this representation is that not every decimal value may be represented as binary number with 100% accuracy (just like you can't represent 1/3 with 100% accuracy). It's not the algorithm's fault.
Another example of this behaviour:
double a = 86.24;
double b = 86.25;
double c = b - a; // Should be 0.01, but is equal to 0.010000000000005116

Trouble raising -1 to a rational fraction-based power

On my TI-84 Plus (Silver Edition), I can enter the following without error: (-1)^(1/3) = -1
I also know that entering some expressions like the following would yield a non-real -imaginary- number like: (-1)^.5
Now, my problem is with C#'s Math object. If I send any fractions like these: {1.667, 109.667, 0.667, 120.667} OR {4/3, 111/3, 2/3, 122/3}, I would get: {NaN, NaN, NaN, NaN}.
Do I have to write a new object MathHelper that checks the rational value and returns an answer according to a limited input switch? Or is there a feature to the Math object I am missing. I can do this on the calculator...
PS, I did not come across any similar questions online yet; so if this is a duplicate, please inform me ;)
[My new views]
Thank you all for your help! I had finished upgrading the "Microsoft.Solver.Foundation.dll" to the 4.0 targeted framework and it turned out that the 'Rational' object seemed to return only -1's and 'Indeterminate'. Then after entering (-1)^(1/2) [nonreal ans] on Google, it dawned on me that I was working with nth-roots!! So, it turned out that I had already managed imaginary numbers in the past in C#, hence having solved my problem:
Any even root 2n of a negative number -m will always equal an imaginary number i. (2n√-m)=i
I can't believe I forgot this simple algebra property
You will have to write your own Math helper to do functions like this (at least for Math.Pow). EDIT: Or you can use the Rational library like mentioned in the comments.
According to the documentation:
Input: x < 0 but not NegativeInfinity; y is not an integer, NegativeInfinity, or PositiveInfinity.
Result: NaN
Review the docs here: http://msdn.microsoft.com/en-us/library/system.math.pow.aspx
In C#, (-1)^R isn't defined for non-integer values of R.
If you try to calculate (-1)^(1/3), C# will calculate 1/3 first, resulting in a non-integer floating point number for R.
Solution:
Use the mathematical identity:
a^(x/y) = a^x * a^(1/y) x,y integers
For negative a, use:
a^1/y = -(|a|^1/y) // only works if y is odd
Or put together:
if (a < 0) {
if (y % 2 = 1) {
result = a^x * -1 * (-a)^(1.0/y); // Replace ^ with the correct C# call.
} else {
// NaN
}
} else {
result = a^(x/y);
}

C# isPowerOf function

I have the next function:
static bool isPowerOf(int num, int power)
{
double b = 1.0 / power;
double a = Math.Pow(num, b);
Console.WriteLine(a);
return a == (int)a;
}
I inserted the print function for analysis.
If I call the function:
isPowerOf(25, 2)
It return true since 5^2 equals 25.
But, if I call 16807, which is 7^5, the next way:
isPowerOf(16807, 5)
In this case, it prints '7' but a == (int)a return false.
Can you help? Thanks!
Try using a small epsilon for rounding errors:
return Math.Abs(a - (int)a) < 0.0001;
As harold suggested, it will be better to round in case a happens to be slightly smaller than the integer value, like 3.99999:
return Math.Abs(a - Math.Round(a)) < 0.0001;
Comparisons that fix the issue have been suggested, but what's actually the problem here is that floating point should not be involved at all. You want an exact answer to a question involving integers, not an approximation of calculations done on inherently inaccurate measurements.
So how else can this be done?
The first thing that comes to mind is a cheat:
double guess = Math.Pow(num, 1.0 / power);
return num == exponentiateBySquaring((int)guess, power) ||
num == exponentiateBySquaring((int)Math.Ceil(guess), power);
// do NOT replace exponentiateBySquaring with Math.Pow
It'll work as long as the guess is less than 1 off. But I can't guarantee that it will always work for your inputs, because that condition is not always met.
So here's the next thing that comes to mind: a binary search (the variant where you search for the upper boundary first) for the base in exponentiateBySquaring(base, power) for which the result is closest to num. If and only if the closest answer is equal to num (and they are both integers, so this comparison is clean), then num is a power-th power. Unless there is overflow (there shouldn't be), that should always work.
Math.Pow operates on doubles, so rounding errors come into play when taking roots. If you want to check that you've found an exact power:
perform the Math.Pow as currently, to extract the root
round the result to the nearest integer
raise this integer to the supplied power, and check you get the supplied target. Math.Pow will be exact for numbers in the range of int when raising to integer powers
If you debug the code and then you can see that in first comparison:
isPowerOf(25, 2)
a is holding 5.0
Here 5.0 == 5 => that is why you get true
and in 2nd isPowerOf(16807, 5)
a is holding 7.0000000000000009
and since 7.0000000000000009 != 7 => you are getting false. and Console.WriteLine(a) is truncating/rounding the double and only show 7
That is why you need to compare the nearest value like in Dani's solution

Why Math.Atan(Math.Tan(x)) != x?

If tan(x) = y and atan(y) = x why Math.Atan(Math.Tan(x)) != x?
I´m trying to calculate x in something like:
tan(2/x +3) = 5
so
atan(tan(2/x + 3) = atan(5)
and so on... but I´ve tried this:
double d = Math.Atan(Math.Tan(10));
and d != 10. Why?
The tangent function is periodic with period pi, and is invertible only if you restrict it to a subset of its domain over which it is injective. Usually the choice of such set is the open interval ]-pi/2, pi/2[, hence the arctan function will always return a point in that interval. In your case, 10 = 3*pi + 0.57522... Thus, the arctan of the tangent of 10 will return 0.57522...
Note that the arctan function, defined as above, is injective and defined over all the real numbers, hence the converse of your problem math.tan(math.atan(x)) == x
indeed holds for each x (except for numerical errors).
In order to deal with numerical errors, you should never perform comparisons between the results of floating point computations using == or !=. Use abs(number1 - number2) < epsilon // ==
abs(number1 - number2) >= epsilon // !=
instead, where epsilon is a small positive constant.
A graph might help explain why you are not getting the result you expected.
(source: wolfram.com)
http://mathworld.wolfram.com/Tangent.html
That shows the graph of Tan, but if you imagine reading off a value of x for a given y, (e.g. y = 0) then depending on which "strand" of Tan you read, you will get a different answer (-pi, 0, pi...). That's the point about Arctan(x) having more than one solution.
If arctan was restricted to only one of those strands, e.g. -pi/2 < x < pi/2 then Arctan(tan(x)) will return x providing you have accounted for floating point errors.
EDIT: However, according to http://msdn.microsoft.com/en-us/library/system.math.atan.aspx, the atan method already returns -pi/2 < x < pi/2 or NaN if your input is undefined. So the problem must soley be down to floating point rounding.
EDIT (F.R.): Added figure
I dont know any C#, but maths says that tan is not invertable, only in a small intervall.
e.g. tan(pi) = 0 and tan(0) = 0. When asking for atan(0) it could be 0 or pi (or every multiple of pi), so the result is in the range from -pi/2 .. pi/2.
Even if you start with an x in the invertable range i doesnt has to work, because of rounding errors with the floating points (it has not unlimmited precision).
tan-1(tan(x)) == x for all x in (-PI/2, PI/2).
Because the tangent function is periodic we need to normalize input angle. Math.Atan returns an angle, θ, measured in radians, such that -π/2 ≤ θ ≤ π/2, so it makes sense to normalize to that range (since it obviously won't anything within that range anyway):
double normalizedAngle = (angle + Math.PI / 2) % Math.PI - Math.PI / 2;
Doubles should be compared with some error margin. But in fact for this case Double.Epsilon is too small and "If you create a custom algorithm that determines whether two floating-point numbers can be considered equal, you must use a value that is greater than the Epsilon constant to establish the acceptable absolute margin of difference for the two values to be considered equal. (Typically, that margin of difference is many times greater than Epsilon.)" For instance, Math.Atan(Math.Tan(-0.49999632679501449)) + 0.49999632679501449 will be greater than Double.Epsilon for 1.1235582092889474E+307 times.
It might be helpful if you posted what you are trying to accomplish. I have recollections of discovering trig functions that handled the issue if what quadrant the inputs were in for me when I tried playing with angles, for example.
In general, when you are dealing with floating point numbers, you are dealing with approximations. There are numbers that cannot be represented exactly, and the tan and arctan operations are themselves only approximate.
If you want to compare floating point numbers, you need to ask if they are nearly equal, or equivalently, if the difference is less than some small value, and think carefully what you are doing.
Here is are some FAQS (for c++, but the idea is the same), that talk a bit about some of the oddities of floating point numbers:
FAQ 29.16
FAQ 29.17
FAQ 29.18
Edit: Looking at the other answers, I realise that the main problem is probably that tan isn't invertible, but the approximation issue is worth considering too, whenever you test floating point numbers for equality.
Looking at the .net documentation for Math.Atan, atan produces a value between -π/2 and ≤ π/2, which doesn't include 10. That I think is the usual range for arctan.
double d = Math.Atan(1) * (180 / Math.PI);
so d will be 45 in degrees

Categories

Resources