Checking approximation of E - math

MathWorld page gives a simple numeric formula for e that's allegedly correct for first 10^25 digits. It states that e is approximately
(1 + 9^-4^(7*6))^3^2^85
Any idea how to check whether this formula is correct even for the first 10 digits?
Here's another way of writing the right hand side
Power[Plus[1, Power[9, Times[-1, Power[4, Times[7, 6]]]]], Power[3, Power[2, 85]]]

This problem does not need Mathematica at all. First, it is easy to show that 9^(4^(7*6)) is exactly equal to 3^2^85, since
9^(4^(7*6)) = 3^(2*4^(7*6)) = 3^(2^(1+2*(7*6))) = 3^2^85
Then, we know that one of the ways to represent e is as a limit
e = lim (1+1/n)^n, n->infinity
The only question is what is the error given that n is very large but finite. We have
(1+1/n)^n = e^log((1+1/n)^n) = e^(n*log(1+1/n)) = e^(1-1/(2n)+O(1/n^2)) = e + O(1/n),
Given the n = 3^2^85, i we take the log(10,n) = 2^85 log(10,3) ~ 1.85 *10^25, we get an estimate
similar to the quoted one

Repeatedly taking logs is a nice (usually) generally-applicable solution to problems of this sort. Here's a more special-case approach to this problem: recall that e = lim(n->infinity, (1+1/n)^n). So to be a good approximation to e, all we need is for 9^(4^(42)) (the denominator of the fractional part) to be sufficiently close to 3^(2^85) and big.
In this case, they're identical, so we have n=3^(2^85), and it's going to be a very good approximation to e. These are big numbers, but not unworkably so:
>>> from mpmath import *
>>> iv.dps = 50 # let's use interval arithmetic, just for fun
>>> x = mpi(9)**(-(4**(42)))
>>> up = (mpi(3)**(2**85))
>>> x
mpi('1.4846305545498656772753385085652043615636250118238876e-18457734525360901453873570',
'1.4846305545498656772753385085652043615636250118238899e-18457734525360901453873570')
>>> 1/x
mpi('6.7356824695231749871315222528985858700759934154677854e+18457734525360901453873569',
'6.7356824695231749871315222528985858700759934154678156e+18457734525360901453873569')
>>> up
mpi('6.7356824695231749871315222528985858700759934154678005e+18457734525360901453873569',
'6.7356824695231749871315222528985858700759934154678156e+18457734525360901453873569')
>>> 0 in (1/x-up)
True
Working out the exact error bounds on e is left as an exercise for the reader ;-) -- hint: compare the number of digits of accuracy the mathworld page claims and the above numbers, and ask why that might be, thinking of the series of approximations (1+1/1)^1, (1+1/2)^2, etc.

Related

is there any Cryptographic loop function that returns first input?

I want to use cryptographic function that returns the initial input or something related to it like its hash,
the function should work like Encrypting some data, then Encrypt the output of the data, and encrypt it again another time, and the loop continue to specific number of iterations and finally it can produce the first input after iterating it.
assuming that we can use any different keys or same key if required in encryption and the function can only go in one way it can't be reversible so i can't run this process from the back loop and finally it should return the first input or something related to its first input by checking the hash of it or something like that.
thanks for help
rsa has this property if you only look at the encryption...
this is because of how rsa works:
n = p * q
e * d = 1 mod phi(n)
x = (x^e)^d = x^(e * d) mod n
if you are calculating mod n, all exponents are mod phi(n), hence d is the multiplicative inverse of e (fermat's little theorem)
since that's a cyclic group and e and d are choosen to generate that group, there's your cyclic property
if phi(n) is secret, calculating d from e is seemingly a hard problem (that's what makes it hard to break RSA)
to reverse the cycle you need the inverse exponent.
but here's the catch: you won't have control over the size of the cycle, and by trying to create small cycles, you will end up with weak keys that can potentially be bruteforced to get the inverse element which will break the one way property
and speaking about cycle sizes... with sufficiently sized rsa keys the cycle sizes are probably too large for you... like not-within-your-lifetime large... phi(n) ... with phi being eulers phi function ... n being p * q ... and p and q being primes with like 1200 digits

Finding power of exponent without known base in python

From an exponent xa, I am trying to get 'a' without a known value of 'x' using logarithm law logx(xa) = a
Originally I tried:
from sympy import *
x = Symbol('x')
print(log(x,x))
Which returns 1 as expected. But when raised to any other power, does not give single value e.g.
print(log(x**2,x))
Which returns:
log(x**2)/log(x)
instead of 2.
Is there any alternative way to get the exponent or fix to my original code?
If you use expand it will give you the result you are looking for. In addition, you can just get the exponent directly:
>>> log(x**2,x).expand() # or expand_log(log(x**2,x))
2
>>> (x**2).exp
2
>>> (x**2).as_base_exp()[1] # works for x**1, too, which is not a Pow

Using MPFR And Adding - How many Digits are Correct?

I have a pretty easy question (I think). As much as I've tried, I can not find an answer to this question.
I am creating a function, for which I want the user to enter two numbers. The first is the the number of terms of a certain infinite series to add together. The second is the number of digits the user would like the truncated sum to be accurate to.
Say the terms of the sequence are a_i. How much precision n, would be required in mpfr to ensure the result of adding these a_i from i=0 up to the user's entered value would be needed to guarantee the number of digits the user needs?
By the way, I'm adding the a_i in a naive way.
Any help will be much appreciated.
Thanks,
Rick
You can convert between decimal digits of precision, d, and binary digits of precision, b, with logarithms
b = d × log(10) / log(2)
A little rearranging shows why
b × log(2) = d × log(10)
log(2b) = log(10d)
2b = 10d
Each term of the series (and each addition) will introduce a rounding error at the least significant digit so, assuming each of the t terms involves n (two argument) arithmetic operations, you will want to add an extra
log(t * (n+2))/log(2)
bits.
You'll need to round the number of bits of precision up to be sure that you have enough room for your decimal digits of precision
b = ceil((d*log(10.0) + log(t*(n+2)))/log(2.0));
Finally, you should be aware that the terms may introduce cancellation errors, in which case this simple calculation will dramatically underestimate the required number of bits, even assuming I've got it right in the first place ;-)

Efficient Multiplication of Varying-Length #s [Conceptual]

EDIT
So it seems I "underestimated" what varying length numbers meant. I didn't even think about situations where the operands are 100 digits long. In that case, my proposed algorithm is definitely not efficient. I'd probably need an implementation who's complexity depends on the # of digits in each operands as opposed to its numerical value, right?
As suggested below, I will look into the Karatsuba algorithm...
Write the pseudocode of an algorithm that takes in two arbitrary length numbers (provided as strings), and computes the product of these numbers. Use an efficient procedure for multiplication of large numbers of arbitrary length. Analyze the efficiency of your algorithm.
I decided to take the (semi) easy way out and use the Russian Peasant Algorithm. It works like this:
a * b = a/2 * 2b if a is even
a * b = (a-1)/2 * 2b + a if a is odd
My pseudocode is:
rpa(x, y){
if x is 1
return y
if x is even
return rpa(x/2, 2y)
if x is odd
return rpa((x-1)/2, 2y) + y
}
I have 3 questions:
Is this efficient for arbitrary length numbers? I implemented it in C and tried varying length numbers. The run-time in was near-instant in all cases so it's hard to tell empirically...
Can I apply the Master's Theorem to understand the complexity...?
a = # subproblems in recursion = 1 (max 1 recursive call across all states)
n / b = size of each subproblem = n / 1 -> b = 1 (problem doesn't change size...?)
f(n^d) = work done outside recursive calls = 1 -> d = 0 (the addition when a is odd)
a = 1, b^d = 1, a = b^d -> complexity is in n^d*log(n) = log(n)
this makes sense logically since we are halving the problem at each step, right?
What might my professor mean by providing arbitrary length numbers "as strings". Why do that?
Many thanks in advance
What might my professor mean by providing arbitrary length numbers "as strings". Why do that?
This actually change everything about the problem (and make your algorithm incorrect).
It means than 1234 is provided as 1,2,3,4 and you cannot operate directly on the whole number. You need to analyze your algorithm in terms of #additions, #multiplications, #divisions.
You should expect a division to be a bit more expensive than a multiplication, and a multiplication to be lot more expensive than an addition. So a good algorithm try to reduce the number of divisions and multiplications.
Check out the Karatsuba algorithm, (ps don't copy it that's not what your teacher want) is one of the fastest for this specification.
Add 3): Native integers are limited in how large (or small) numbers they can represent (32- or 64-bit integers for example). To represent arbitrary length numbers you can choose strings, because then you are not really limited by this. The problem is then, of course, that your arithmetic units are not really made to add strings ;-)

Geometrical progression with any number row

I can have any number row which consists from 2 to 10 numbers. And from this row, I have to get geometrical progression.
For example:
Given number row: 125 5 625 I have to get answer 5. Row: 128 8 512 I have to get answer 4.
Can you give me a hand? I don't ask for a program, just a hint, I want to understand it by myself and write a code by myself, but damn, I have been thinking the whole day and couldn't figure this out.
Thank you.
DON'T WRITE THE WHOLE PROGRAM!
Guys, you don't get it, I can't just simple make a division. I actually have to get geometrical progression + show all numbers. In 128 8 512 row all numbers would be: 8 32 128 512
Seth's answer is the right one. I'm leaving this answer here to help elaborate on why the answer to 128 8 512 is 4 because people seem to be having trouble with that.
A geometric progression's elements can be written in the form c*b^n where b is the number you're looking for (b is also necessarily greater than 1), c is a constant and n is some arbritrary number.
So the best bet is to start with the smallest number, factorize it and look at all possible solutions to writing it in the c*b^n form, then using that b on the remaining numbers. Return the largest result that works.
So for your examples:
125 5 625
Start with 5. 5 is prime, so it can be written in only one way: 5 = 1*5^1. So your b is 5. You can stop now, assuming you know the row is in fact geometric. If you need to determine whether it's geometric then test that b on the remaining numbers.
128 8 512
8 can be written in more than one way: 8 = 1*8^1, 8 = 2*2^2, 8 = 2*4^1, 8 = 4*2^1. So you have three possible values for b, with a few different options for c. Try the biggest first. 8 doesn't work. Try 4. It works! 128 = 2*4^3 and 512 = 2*4^4. So b is 4 and c is 2.
3 15 375
This one is a bit mean because the first number is prime but isn't b, it's c. So you'll need to make sure that if your first b-candidate doesn't work on the remaining numbers you have to look at the next smallest number and decompose it. So here you'd decompose 15: 15 = 15*?^0 (degenerate case), 15 = 3*5^1, 15 = 5*3^1, 15 = 1*15^1. The answer is 5, and 3 = 3*5^0, so it works out.
Edit: I think this should be correct now.
This algorithm does not rely on factoring, only on the Euclidean Algorithm, and a close variant thereof. This makes it slightly more mathematically sophisticated then a solution that uses factoring, but it will be MUCH faster. If you understand the Euclidean Algorithm and logarithms, the math should not be a problem.
(1) Sort the set of numbers. You have numbers of the form ab^{n1} < .. < ab^{nk}.
Example: (3 * 2, 3*2^5, 3*2^7, 3*2^13)
(2) Form a new list whose nth element of the (n+1)st element of the sorted list divided by the (n)th. You now have b^{n2 - n1}, b^{n3 - n2}, ..., b^{nk - n(k-1)}.
(Continued) Example: (2^4, 2^2, 2^6)
Define d_i = n_(i+1) - n_i (do not program this -- you couldn't even if you wanted to, since the n_i are unknown -- this is just to explain how the program works).
(Continued) Example: d_1 = 4, d_2 = 2, d_3 = 6
Note that in our example problem, we're free to take either (a = 3, b = 2) or (a = 3/2, b = 4). The bottom line is any power of the "real" b that divides all entries in the list from step (2) is a correct answer. It follows that we can raise b to any power that divides all the d_i (in this case any power that divides 4, 2, and 6). The problem is we know neither b nor the d_i. But if we let m = gcd(d_1, ... d_(k-1)), then we CAN find b^m, which is sufficient.
NOTE: Given b^i and b^j, we can find b^gcd(i, j) using:
log(b^i) / log(b^j) = (i log b) / (j log b) = i/j
This permits us to use a modified version of the Euclidean Algorithm to find b^gcd(i, j). The "action" is all in the exponents: addition has been replaced by multiplication, multiplication with exponentiation, and (consequently) quotients with logarithms:
import math
def power_remainder(a, b):
q = int(math.log(a) / math.log(b))
return a / (b ** q)
def power_gcd(a, b):
while b != 1:
a, b = b, power_remainder(a, b)
return a
(3) Since all the elements of the original set differ by powers of r = b^gcd(d_1, ..., d_(k-1)), they are all of the form cr^n, as desired. However, c may not be an integer. Let me know if this is a problem.
The simplest approach would be to factorize the numbers and find the greatest number they have in common. But be careful, factorization has an exponential complexity so it might stop working if you get big numbers in the row.
What you want is to know the Greatest Common Divisor of all numbers in a row.
One method is to check if they all can be divided by the smaller number in the row.
If not, try half the smaller number in the row.
Then keep going down until you find a number that divides them all or your divisor equals 1.
Seth Answer is not correct, applyin that solution does not solves 128 8 2048 row for example (2*4^x), you get:
8 128 2048 =>
16 16 =>
GCD = 16
It is true that the solution is a factor of this result but you will need to factor it and check one by one what is the correct answer, in this case you will need to check the solutions factors in reverse order 16, 8, 4, 2 until you see 4 matches all the conditions.

Resources