Haskell big number calculations - haskell

I am trying to do some calculations with big numbers
λ: let r = 291381631919914084
λ: let t = 1165526527679656343
λ: sqrt(4 * r * r - 4 * r + 1 + 8 * t) - 2 * r + 1
1.0
the answer should be 8.0000...
Is there a package that I should be using for such calculations? or is there something I should be doing in prelude?

The correct answer is indeed very close to 8.0. You're running into numerical precision issues: the square root is being computed using IEEE 754 ("double precision") binary64 format, and its 53-bit precision isn't sufficient to give an accurate result here.
In more detail: the true value of sqrt(4 * r * r - 4 * r + 1 + 8 * t) is, to 50 significant figures:
582763263839828175.00000000000000000686385063746811
The closest representable IEEE 754 binary64 value to that quantity is:
582763263839828224.0
... which is off by about 49.0 from the true value. Similarly, the value 2*r loses precision when converted to floating-point.
You might be tempted to fix this by increasing the precision, but as so often happens in numerical work, in this case it's better to rework the algorithm to avoid (or at least ameliorate) the numerical issues. The value you're computing is of the form sqrt(a * a + b) - a (with a = 2 * r - 1 and b = 8 * t). That quantity can be rewritten in the form b / (sqrt(a * a + b) + a), and (assuming that both a and b are positive), the latter expression will give a more accurate result.
Here's a quick demonstration that the two expressions give the same result.
Prelude> let a = 43
Prelude> let b = 7
Prelude> sqrt(a * a + b) - a
8.131845707602992e-2
Prelude> b / (sqrt(a * a + b) + a)
8.131845707603225e-2
We're using smaller values of a and b, so the numerical issues aren't so bad, but note that there's still a discrepancy in the last 4 digits. (The exact value here is 0.081318457076032250005683932322636450, to 35 significant figures.)
And using this form of the expression with your values:
Prelude> let r = 291381631919914084
Prelude> let t = 1165526527679656343
Prelude> let a = 2*r - 1; b = 8*t in b / (sqrt(a*a+b) + a)
8.0
As other answerers have pointed out, the answer isn't exactly 8.0, but 8.0 is the closest IEEE 754 binary64 floating-point value to the true answer.

I believe 8 is not a correct answer, either; the number you have given is not square:
Math.NumberTheory.Powers.Squares> r = 291381631919914084
Math.NumberTheory.Powers.Squares> t = 1165526527679656343
Math.NumberTheory.Powers.Squares> isSquare (4*r*r - 4*r + 1 + 8*t)
False
However, you can get this answer if it's the one you want:
Math.NumberTheory.Powers.Squares> integerSquareRoot (4*r*r - 4*r + 1 + 8*t) - 2*r + 1
8
The arithmoi package provides these functions.
Or, you can get as many digits of the exact answer as you like:
Data.Number.CReal> sqrt (4*r*r - 4*r + 1 + 8*t) - 2*r + 1 :: CReal
8.0000000000000000068638506374681082902485
The numbers package provides this type.

I put these numbers and formula in Rstudio and also got 1. Are you sure the answer is 8? Maybe add more parentheses to make sure you got your order of operation correct.

Related

Splitting an int64 into two int32, performing math, then re-joining

I am working within constraints of hardware that has 64bit integer limit. Does not support floating point. I am dealing with very large integers that I need to multiply and divide. When multiplying I encounter an overflow of the 64bits. I am prototyping a solution in python. This is what I have in my function:
upper = x >> 32 #x is cast as int64 before being passed to this function
lower = x & 0x00000000FFFFFFFF
temp_upper = upper * y // z #Dividing first is not an option, as this is not the actual equation I am working with. This is just to make sure in my testing I overflow unless I do the splitting.
temp_lower = lower * y // z
return temp_upper << 32 | lower
This works, somewhat, but I end up losing a lot of precision (my result is off by sometimes a few million). From looking at it, it appears that this is happening because of the division. If sufficient enough it shifts the upper to the right. Then when I shift it back into place I have a gap of zeroes.
Unfortunately this topic is very hard to google, since anything with upper/lower brings up results about rounding up/down. And anything about splitting ints returns results about splitting them into a char array. Anything about int arithmetic bring up basic algebra with integer math. Maybe I am just not good at googling. But can you guys give me some pointers on how to do this?
Splitting like this is just a thing I am trying, it doesnt have to be the solution. All I need to be able to do is to temporarily go over 64bit integer limit. The final result will be under 64bit (After the division part). I remember learning in college about splitting it up like this and then doing the math and re-combining. But unfortunately as I said I am having trouble finding anything online on how to do the actual math on it.
Lastly, my numbers are sometimes small. So I cant chop off the right bits. I need the results to basically be equivalent to if I used something like int128 or something.
I suppose a different way to look at this problem is this. Since I have no problem with splitting the int64, we can forget about that part. So then we can pretend that two int64's are being fed to me, one is upper and one is lower. I cant combine them, because they wont fit into a single int64. So I need to divide them first by Z. Combining step is easy. How do I do the division?
Thanks.
As I understand it, you want to perform (x*y)//z.
Your numbers x,y,z all fit on 64bits, except that you need 128 bits for intermediate x*y.
The problem you have is indeed related to division: you have
h * y = qh * z + rh
l * y = ql * z + rl
h * y << 32 + l*y = (qh<<32 + ql) * z + (rh<<32 + rl)
but nothing says that (rh<<32 + rl) < z, and in your case high bits of l*y overlap low bits of h * y, so you get the wrong quotient, off by potentially many units.
What you should do as second operation is rather:
rh<<32 + l * y = ql' * z + rl'
Then get the total quotient qh<<32 + ql'
But of course, you must care to avoid overflow when evaluating left operand...
Since you are splitting only one of the operands of x*y, I'll assume that the intermediate result always fits on 96 bits.
If that is correct, then your problem is to divide a 3 32bits limbs x*y by a 2 32bits limbs z.
It is thus like Burnigel - Ziegler divide and conquer algorithm for division.
The algorithm can be decomposed like this:
obtain the 3 limbs a2,a1,a0 of multiplication x*y by using karatsuba for example
split z into 2 limbs z1,z0
perform the div32( (a2,a1,a0) , (z1,z0) )
here is some pseudo code, only dealing with positive operands, and with no guaranty to be correct, but you get an idea of implementation:
p = 1<<32;
function (a1,a0) = split(a)
a1 = a >> 32;
a0 = a - (a1 * p);
function (a2,a1,a0) = mul22(x,y)
(x1,x0) = split(x) ;
(y1,y0) = split(y) ;
(h1,h0) = split(x1 * y1);
assert(h1 == 0); -- assume that results fits on 96 bits
(l1,l0) = split(x0 * y0);
(m1,m0) = split((x1 - x0) * (y0 - y1)); -- karatsuba trick
a0 = l0;
(carry,a1) = split( l1 + l0 + h0 + m0 );
a2 = l1 + m1 + h0 + carry;
function (q,r) = quorem(a,b)
q = a // b;
r = a - (b * q);
function (q1,q0,r0) = div21(a1,a0,b0)
(q1,r1) = quorem(a1,b0);
(q0,r0) = quorem( r1 * p + a0 , b0 );
(q1,q0) = split( q1 * p + q0 );
function q = div32(a2,a1,a0,b1,b0)
(q,r) = quorem(a2*p+a1,b1*p+b0);
q = q * p;
(a2,a1)=split(r);
if a2<b1
(q1,q0,r)=div21(a2,a1,b1);
assert(q1==0); -- since a2<b1...
else
q0=p-1;
r=(a2-b1)*p+a1+b1;
(d1,d0) = split(q0*b0);
r = (r-d1)*p + a0 - d0;
while(r < 0)
q = q - 1;
r = r + b1*p + b0;
function t=muldiv(x,y,z)
(a2,a1,a0) = mul22(x,y);
(z1,z0) = split(z);
if z1 == 0
(q2,q1,r1)=div21(a2,a1,z0);
assert(q2==0); -- otherwise result will not fit on 64 bits
t = q1*p + ( ( r1*p + a0 )//z0);
else
t = div32(a2,a1,a0,z1,z0);

Create a Recursive Function as Well as a Closed Function Definition

The goal of this assignment is to take the recurrence relation given at the bottom, and then create a recursive function under recFunc(n), as well as a closed function definition underneath nonRecFunc(n). A closed function means our function should solely depend on n, and that its output should
match the recursive function's exactly. Then, find the value for n = 15 and n = 20, and use it as instructed below. You should probably need to use a characteristic equation to solve this problem.
What is the value for nonRecFunc(20) (divided by) nonRecFunc(15), rounded to the nearest integer.
Problem:
Solve the recurrence relation a_n = 12a_n-1 - 32a_n-2 with initial conditions a_0 = 1 and a_1 = 4.
I am confused as to how I should attack this problem and how I can use recursion to solve the issue.
def recFunc(n):
if n == 0:
return 1
elif n == 1:
return 2
else:
return recFunc(n - 1) + 6 * recFunc(n - 2)
def nonRecFunc(n):
return 4/5 * 3 ** n + 1/5 * (-2) ** n
for i in range(0,10):
print(recFunc(i))
print(nonRecFunc(i))
print()
As mentioned in a my comment above, I leave the recursive solution to you.
For the more mathematical question of the non-recursive solution consider this:
you have
x_n = a x_(n-1) + b x_(n-2)
This means that the change of x is more or less proportional to x as x_n and x_(n-1) will be of same order of magnitude. In other words we are looking for a function type giving
df(n)/dn ~ f(n)
This is something exponential. So the above assumption is
x_n = alpha t^n + beta s^n
(later when solving for s and t the motivation for this becomes clear) from the start values we get
alpha + beta = 1
and
alpha t + beta s = 2
The recursion provides
alpha t^n + beta s^n = a ( alpa t^(n-1) + beta s^(n-1) ) + b ( alpa t^(n-2) + beta s^(n-2) )
or
t^2 alpha t^(n-2) + s^2 beta s^(n-2) = a ( t alpa t^(n-2) + s beta s^(n-2) ) + b ( alpa t^(n-2) + beta s^(n-2) )
This equation holds for all n such that you can derive an equation for t and s.
Plugging in the results in the above equations gives you the non-recursive solution.
Try to reproduce it and then go for the actual task.
Cheers.

How to find the cube root of a negative integer such that it does not return NaN?

In Haskell, I have tried to find the cube root of a negative integer, for example, -1, without success.
I have used (-1) ** (1/3), but this returns a NaN. I thought that this might have something to do with type of the (1/3) fraction, but using (1/3 :: Double) yielded no success either.
As a result, my question is how can one find the cube root of -1 using Haskell so that it doesn't return NaN?
For real numbers, the Haskell operator (**) is only defined for negative base (left-hand side) values when the exponent (right-hand side) is integer-valued. If this strikes you as strange, note that the C function pow behaves the same way:
printf("%f\n", pow(-1.0, 1.0/3.0)); // prints "-nan", for me
and so does Python's ** operator:
print((-1.0)**(1.0/3.0))
# gives: ValueError: negative number cannot be raised to fractional power
The problem is partially a mathematical one. The "correct answer" for raising a negative base to a non-integral power is far from obvious. See, for example, this question on the Mathematics SO.
If you only need a cube root that can handle negative numbers, the other answers given should work fine, except that #Istvan's answer should use signum instead of sign, like this:
cbrt x = signum x * abs x ** (1/3)
If you want a more general integral root function for real numbers, be warned that for even n, there are no nth roots of negative numbers that are real, so this is about the best you can do:
-- | Calculate nth root of b
root :: (Integral n, RealFloat b) => n -> b -> b
root n b | odd n && b < 0 = - abs b ** overn
| otherwise = b ** overn
where overn = 1 / fromIntegral n
This gives:
> root 3 (-8)
-2.0
> root 4 (-8)
NaN -- correct, as no real root exists
>
I don't know Haskell, but you can do something like this:
sign(x) * abs(x) ** (1/3)
On ghci I've done something that seems to solve your problem:
let cbrt x = if x < 0 then -((-x) ** (1/3)) else x ** (1/3)
A simple cuberoot function.
As I'm still learning I don't know if this is a proper solution, so please let me know if there's something missing or wrong ;)

Arithmetic Mean with exponent of small numbers

Due to rounding error, cannot get mean of three numbers:
a=-1.11e4
b=-1.12e4
c=-1.13e4
Mean=1/3 *[exp(a)+exp(b)+exp(c)]
How to get the results in a log value?
You're trying to find log((exp(a) + exp(b) + exp(c)) / 3), but a, b, and c are so low that the result of exp underflows to 0. You can fix this by adjusting the values so exp doesn't underflow.
Let d = max(a, b, c). Then we have the following equality:
M = log((exp(a) + exp(b) + exp(c)) / 3)
= log(exp(d) * (exp(a-d) + exp(b-d) + exp(c-d)) / 3)
= log(exp(d)) + log((exp(a-d) + exp(b-d) + exp(c-d)) / 3)
= d + log((exp(a-d) + exp(b-d) + exp(c-d)) / 3)
So we can calculate the result as d + log((exp(a-d) + exp(b-d) + exp(c-d)) / 3). Since d is equal to one of a, b, or c, one of the exp arguments is 0, and the rest are at most 0. Thus, one of the exp outputs is 1, and the rest are at most 1. We don't have to worry about overflow or underflow; while an underflow might still occur in one or more exp calls, it won't be a problem any more, since the log argument won't be 0.

Count the Number of Zero's between Range of integers

. Is there any Direct formula or System to find out the Numbers of Zero's between a Distinct Range ... Let two Integer M & N are given . if I have to find out the total number of zero's between this Range then what should I have to do ?
Let M = 1234567890 & N = 2345678901
And answer is : 987654304
Thanks in advance .
Reexamining the Problem
Here is a simple solution in Ruby, which inspects each integer from the interval [m,n], determines the string of its digits in the standard base 10 positional system, and counts the occuring 0 digits:
def brute_force(m, n)
if m > n
return 0
end
z = 0
m.upto(n) do |k|
z += k.to_s.count('0')
end
z
end
If you run it in an interactive Ruby shell you will get
irb> brute_force(1,100)
=> 11
which is fine. However using the interval bounds from the example in the question
m = 1234567890
n = 2345678901
you will recognize that this will take considerable time. On my machine it does need more than a couple of seconds, I had to cancel it so far.
So the real question is not only to come up with the correct zero counts but to do it faster than the above brute force solution.
Complexity: Running Time
The brute force solution needs to perform n-m+1 times searching the base 10 string for the number k, which is of length floor(log_10(k))+1, so it will not use more than
O(n (log(n)+1))
string digit accesses. The slow example had an n of roughly n = 10^9.
Reducing Complexity
Yiming Rong's answer is a first attempt to reduce the complexity of the problem.
If the function for calculating the number of zeros regarding the interval [m,n] is F(m,n), then it has the property
F(m,n) = F(1,n) - F(1,m-1)
so that it suffices to look for a most likely simpler function G with the property
G(n) = F(1,n).
Divide and Conquer
Coming up with a closed formula for the function G is not that easy. E.g.
the interval [1,1000] contains 192 zeros, but the interval [1001,2000] contains 300 zeros, because a case like k = 99 in the first interval would correspond to k = 1099 in the second interval, which yields another zero digit to count. k=7 would show up as 1007, yielding two more zeros.
What one can try is to express the solution for some problem instance in terms of solutions to simpler problem instances. This strategy is called divide and conquer in computer science. It works if at some complexity level it is possible to solve the problem instance and if one can deduce the solution of a more complex problem from the solutions of the simpler ones. This naturally leads to a recursive formulation.
E.g. we can formulate a solution for a restricted version of G, which is only working for some of the arguments. We call it g and it is defined for 9, 99, 999, etc. and will be equal to G for these arguments.
It can be calculated using this recursive function:
# zeros for 1..n, where n = (10^k)-1: 0, 9, 99, 999, ..
def g(n)
if n <= 9
return 0
end
n2 = (n - 9) / 10
return 10 * g(n2) + n2
end
Note that this function is much faster than the brute force method: To count the zeros in the interval [1, 10^9-1], which is comparable to the m from the question, it just needs 9 calls, its complexity is
O(log(n))
Again note that this g is not defined for arbitrary n, only for n = (10^k)-1.
Derivation of g
It starts with finding the recursive definition of the function h(n),
which counts zeros in the numbers from 1 to n = (10^k) - 1, if the decimal representation has leading zeros.
Example: h(999) counts the zero digits for the number representations:
001..009
010..099
100..999
The result would be h(999) = 297.
Using k = floor(log10(n+1)), k2 = k - 1, n2 = (10^k2) - 1 = (n-9)/10 the function h turns out to be
h(n) = 9 [k2 + h(n2)] + h(n2) + n2 = 9 k2 + 10 h(n2) + n2
with the initial condition h(0) = 0. It allows to formulate g as
g(n) = 9 [k2 + h(n2)] + g(n2)
with the intital condition g(0) = 0.
From these two definitions we can define the difference d between h and g as well, again as a recursive function:
d(n) = h(n) - g(n) = h(n2) - g(n2) + n2 = d(n2) + n2
with the initial condition d(0) = 0. Trying some examples leads to a geometric series, e.g. d(9999) = d(999) + 999 = d(99) + 99 + 999 = d(9) + 9 + 99 + 999 = 0 + 9 + 99 + 999 = (10^0)-1 + (10^1)-1 + (10^2)-1 + (10^3)-1 = (10^4 - 1)/(10-1) - 4. This gives the closed form
d(n) = n/9 - k
This allows us to express g in terms of g only:
g(n) = 9 [k2 + h(n2)] + g(n2) = 9 [k2 + g(n2) + d(n2)] + g(n2) = 9 k2 + 9 d(n2) + 10 g(n2) = 9 k2 + n2 - 9 k2 + 10 g(n2) = 10 g(n2) + n2
Derivation of G
Using the above definitions and naming the k digits of the representation q_k, q_k2, .., q2, q1 we first extend h into H:
H(q_k q_k2..q_1) = q_k [k2 + h(n2)] + r (k2-kr) + H(q_kr..q_1) + n2
with initial condition H(q_1) = 0 for q_1 <= 9.
Note the additional definition r = q_kr..q_1. To understand why it is needed look at the example H(901), where the next level call to H is H(1), which means that the digit string length shrinks from k=3 to kr=1, needing an additional padding with r (k2-kr) zero digits.
Using this, we can extend g to G as well:
G(q_k q_k2..q_1) = (q_k-1) [k2 + h(n2)] + k2 + r (k2-kr) + H(q_kr..q_1) + g(n2)
with initial condition G(q_1) = 0 for q_1 <= 9.
Note: It is likely that one can simplify the above expressions like in case of g above. E.g. trying to express G just in terms of G and not using h and H. I might do this in the future. The above is already enough to implement a fast zero calculation.
Test Result
recursive(1234567890, 2345678901) =
987654304
expected:
987654304
success
See the source and log for details.
Update: I changed the source and log according to the more detailed problem description from that contest (allowing 0 as input, handling invalid inputs, 2nd larger example).
You can use a standard approach to find m = [1, M-1] and n = [1, N], then [M, N] = n - m.
Standard approaches are easily available: Counting zeroes.

Resources