Prove time complexity - analysis

Let T (n) = 1, and let
T(n) = x^k T(n/x)+ Cn^k
where C and k are constants. Prove that
T (n) = O(n^k log(n))
I want to prove the time complexity using Induction and not sure where to start. Can someone please help me.
Thanks in advance...

I think this is pretty straight forward:
Base case, n = 1.
T(1) = 1 is a constant so it is O(n^klog(n))
Induction hypothesis:
T(m) = O(m^k log(m)) for all m < n.
Induction step:
T(n) = x^k T(n/x)+ Cn^k
by IH we have that this is
T(n) = x^k D(n/x)^k log n/x + Cn^k for some constant D
T(n) = D x^k n^k /x^k (log n - log x) + C*n^k , x^k now cancels out
T(n) = D n^k log n - D n^k log x + C*n^k
largest term here is D n^k log n, so in O-notation
T(n) = O( n^k log n)

Related

linsolve in maxima no work for these equations

I am very novice in maxima. I want to get the solution for W using these equations:
e1: A*W + B*Y = I$
e2: C*W + D*Y = 0$
linsolve ([e1, e2], [W]);
But linsolve just generates [].
The example in the manual works:
(%i1) e1: x + z = y$
(%i2) e2: 2*a*x - y = 2*a^2$
(%i3) e3: y - 2*z = 2$
(%i4) linsolve ([e1, e2, e3], [x, y, z]);
(%o4) [x = a + 1, y = 2 a, z = a - 1]
That means that the equation cannot be solved for the variables that you requested. You have to solve in respect to both variables:
linsolve([e1,e2],[W,Y]);
D I C I
[W = - ---------, Y = ---------]
B C - A D B C - A D
You can solve for W for each of your equations separately. For example:
linsolve ([e1],[W]);
B Y - I
[W = - -------]
A

Divide a Point in Elliptic Curve Cryptography

I'm using Elliptic Curve to design a security system. P is a point on elliptic curve. The receiver must obtain P using formula k^-1(kP). The receiver does not know P but knows k. I need to compute k^-1(R) where R=kP. How can I do this using Point Multiplication or Point Addition.
I suggest first learning a bit more about ECC (for example, read some of Paar's book and listen to his course at http://www.crypto-textbook.com/) before tackling something this complex. For this particular question, ask yourself: "What does the inverse of k mean?"
Very interesting question you have! I was happy to implement from scratch Python solution for your task, see code at the bottom of my answer.
Each elliptic curve has an integer order q. If we have any point P on curve then it is well known that q * P = Zero, in other words multiplying any point by order q gives zero-point (infinity point).
Multiplying zero (infinity) point by any number gives zero again, i.e. j * Zero = Zero for any integer j. Adding any point P to zero-point gives P, i.e. Zero + P = P.
In our task we have some k such that R = k * P. We can very easily (very fast) compute Modular Inverse of k modulo order q, using for example Extended Euclidean Algorithm.
Inverse of k modulo q by definition is such that k * k^-1 = 1 (mod q), which by definition of modulus is equal k * k^-1 = j * q + 1 for some integer j.
Then k^-1 * R = k^-1 * k * P = (j * q + 1) * P = j * (q * P) + P = j * Zero + P = Zero + P = P. Thus multiplying R by k^-1 gives P, if k^-1 is inverse of k modulo q.
You can read about point addition and multiplication formulas on this Wiki.
Lets now check our formulas in Python programming language. I decided to implement from scratch simple class ECPoint, which implements all curve operations (addition and multiplication), see code below.
We take any ready-made curve, for example most popular 256-bit curve secp256k1, which is used in Bitcoin. Its parameters can be found here (this doc contains many other popular standard curves), also you can read about this specific curve on Bitcoin Wiki Page.
Following code is fully self-contained Python script, doesn't need any external dependencies and modules. You can run it straight away on any computer. ECPoint class implements all curve arithmetics. Function test() does following operations: we take standard secp256k1 params with some base point G, we compute any random point P = random * G, then we generate random k, compute R = k * P, compute modular inverse k^-1 (mod q) by using function modular_inverse() (which uses extended Euclidean algorithm egcd()), compute found_P = k^-1 * R and check that it is equal to P, i.e. check that k^-1 * R == P, print resulting k^-1 * R. All random values are 256-bit.
Try it online!
def egcd(a, b):
# https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm
ro, r, so, s, to, t = a, b, 1, 0, 0, 1
while r != 0:
ro, (q, r) = r, divmod(ro, r)
so, s = s, so - q * s
to, t = t, to - q * t
return ro, so, to
def modular_inverse(a, mod):
# https://en.wikipedia.org/wiki/Modular_multiplicative_inverse
g, s, t = egcd(a, mod)
assert g == 1, 'Value not invertible by modulus!'
return s % mod
class ECPoint:
#classmethod
def Int(cls, x):
return int(x)
#classmethod
def std_point(cls, name):
if name == 'secp256k1':
# https://en.bitcoin.it/wiki/Secp256k1
# https://www.secg.org/sec2-v2.pdf
p = 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_FFFFFC2F
a = 0
b = 7
x = 0x79BE667E_F9DCBBAC_55A06295_CE870B07_029BFCDB_2DCE28D9_59F2815B_16F81798
y = 0x483ADA77_26A3C465_5DA4FBFC_0E1108A8_FD17B448_A6855419_9C47D08F_FB10D4B8
q = 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_BAAEDCE6_AF48A03B_BFD25E8C_D0364141
else:
assert False
return ECPoint(x, y, a, b, p, q)
def __init__(self, x, y, A, B, N, q, *, prepare = True):
if prepare:
N = self.Int(N)
A, B, x, y, q = [self.Int(e) % N for e in [A, B, x, y, q]]
assert (4 * A ** 3 + 27 * B ** 2) % N != 0
assert (y ** 2 - x ** 3 - A * x - B) % N == 0, (
x, y, A, B, N, (y ** 2 - x ** 3 - A * x) % N)
assert N % 4 == 3
assert y == pow(x ** 3 + A * x + B, (N + 1) // 4, N)
self.A, self.B, self.N, self.x, self.y, self.q = A, B, N, x, y, q
def __add__(self, other):
A, N = self.A, self.N
Px, Py, Qx, Qy = self.x, self.y, other.x, other.y
if Px == Qx and Py == Qy:
s = ((Px * Px * 3 + A) * self.inv(Py * 2, N)) % N
else:
s = ((Py - Qy) * self.inv(Px - Qx, N)) % N
x = (s * s - Px - Qx) % N
y = (s * (Px - x) - Py) % N
return ECPoint(x, y, A, self.B, N, self.q, prepare = False)
def __rmul__(self, other):
other = self.Int(other - 1)
r = self
while True:
if other & 1:
r = r + self
if other == 1:
return r
other >>= 1
self = self + self
#classmethod
def inv(cls, a, n):
return modular_inverse(a, n)
def __repr__(self):
return str(dict(x = self.x, y = self.y, A = self.A,
B = self.B, N = self.N, q = self.q))
def __eq__(self, other):
for i, (a, b) in enumerate([
(self.x, other.x), (self.y, other.y), (self.A, other.A),
(self.B, other.B), (self.N, other.N), (self.q, other.q)]):
if a != b:
return False
return True
def test():
import random
bits = 256
P = random.randrange(1 << bits) * ECPoint.std_point('secp256k1')
k = random.randrange(1 << bits)
R = k * P
found_P = modular_inverse(k, R.q) * R
assert found_P == P
print(found_P)
if __name__ == '__main__':
test()
Output:
{
'x': 108051465657467150531748691374311160382608428790397210924352716318223953013557,
'y': 4462548165448905789984443302412298811224817997977472205419179335194291964455,
'A': 0,
'B': 7,
'N': 115792089237316195423570985008687907853269984665640564039457584007908834671663,
'q': 115792089237316195423570985008687907852837564279074904382605163141518161494337
}

Formal Language syntax

Here is the question:
Show that:
L = {0m1n, m > 1, n > 1, n < m } , where m & n are superscripts
is not regular.
I am not sure what superscripts mean in this situation? Does it mean something like this:
0^5 = 00000 or 1^7 = 1111111
P.S. How can I show superscripts in SO??

F# fails with "Error 4 This expression was expected to have type int but here has type int -> int"

Here is the code that I am trying to get to work last line is where it is failing:
let rec gcd a b =
if b= 0 then
a
else
gcd b (a % b);;
let n = 8051
let mutable d = 0
let mutable c = 1
let mutable xi = 2
let mutable yi = 2
let f x = (pown x 2) + (c % n);;
while c < 100 do
while d = 1 do
xi <- (f xi)
yi <- (f(f(yi)))
printfn "%d%d" xi yi
d <- gcd(abs (xi - yi) n)
---------------------The Following Code works; Except for integer overflow on N---------
module Factorization
let rec gcd a b =
if b= 0 then
a
else
gcd b (a % b);;
let n = 600851475143N
let mutable d, c, xi, yi = 1, 1, 2, 2
let f x = (pown x 2) + (c % n);;
let maxN m =int(ceil(sqrt(float m)))
//if (n > maxN(xi)) && (n > maxN(yi)) then
while c < 100 do
d <- 1
while d = 1 do
if (maxN(n) > xi) && (maxN(n) > yi) then
xi <- f xi
yi <- f(f(yi))
d <- gcd (abs (xi - yi)) n
//fail
if d = n then d<-1
if d <> 1 then printfn "A prime factor of %d x = %d, y = %d, d = %d" n xi yi d
else
xi <- 2
yi <- 2
c <- c + 1;;
In addition to what #Rangoric pointed out, the outer brackets have to go as well otherwise currying won't work:
d <- gcd (abs(xi-yi)) n
Yikes, here are a few unsolicited tips (#BrokenGlass answered the question itself correctly).
First, you can assign all those mutables in one line:
let mutable d, c, xi, yi = 0, 1, 2, 2
Second, go easy on the parentheses:
xi <- f xi
yi <- f (f yi)
And of course, try to get rid of the mutables and while loops. But I'll leave that to you since I'm sure you are aware seeing that you implemented gcd using recursion.
Try:
d <- gcd (abs(xi-yi)) n
It is pointing out that abs is a int->int and not an int by itself. Wrapping it in parentheses causes the abs to be executed before gcd looks at it. This causes gcd to see the result of abs instead of abs itself.

Project Euler Problem 27 in F#

I've been trying to work my way through Problem 27 of Project Euler, but this one seems to be stumping me. Firstly, the code is taking far too long to run (a couple of minutes maybe, on my machine, but more importantly, it's returning the wrong answer though I really can't spot anything wrong with the algorithm after looking through it for a while.
Here is my current code for the solution.
/// Checks number for primality.
let is_prime n =
[|1 .. 2 .. sqrt_int n|] |> Array.for_all (fun x -> n % x <> 0)
/// Memoizes a function.
let memoize f =
let cache = Dictionary<_, _>()
fun x ->
let found, res = cache.TryGetValue(x)
if found then
res
else
let res = f x
cache.[x] <- res
res
/// Problem 27
/// Find a quadratic formula that produces the maximum number of primes for consecutive values of n.
let problem27 n =
let is_prime_mem = memoize is_prime
let range = [|-(n - 1) .. n - 1|]
let natural_nums = Seq.init_infinite (fun i -> i)
range |> Array.map (fun a -> (range |> Array.map (fun b ->
let formula n = n * n + a * n + b
let num_conseq_primes = natural_nums |> Seq.map (fun n -> (n, formula n))
|> Seq.find (fun (n, f) -> not (is_prime_mem f)) |> fst
(a * b, num_conseq_primes)) |> Array.max_by snd)) |> Array.max_by snd |> fst
printn_any (problem27 1000)
Any tips on how to a) get this algorithm actually returning the right answer (I think I'm at least taking a workable approach) and b) improve the performance, as it clearly exceeds the "one minute rule" set out in the Project Euler FAQ. I'm a bit of a newbie to functional programming, so any advice on how I might consider the problem with a more functional solution in mind would also be appreciated.
Two remarks:
You may take advantage of the fact that b must be prime. This follows from the fact that the problem asks for the longest sequence of primes for n = 0, 1, 2, ...
So, formula(0) must be prime to begin with , but formula(0) = b, therefore, b must be prime.
I am not an F# programmer, but it seems to me that the code does not try n= 0 at all. This, of course, does not meet the problem's requirement that n must start from 0, therefore there are neglectable chances a correct answer could be produced.
Right, after a lot of checking that all the helper functions were doing what they should, I've finally reached a working (and reasonably efficient) solution.
Firstly, the is_prime function was completely wrong (thanks to Dimitre Novatchev for making me look at that). I'm not sure quite how I arrived at the function I posted in the original question, but I had assumed it was working since I'd used it in previous problems. (Most likely, I had just tweaked it and broken it since.) Anyway, the working version of this function (which crucially returns false for all integers less than 2) is this:
/// Checks number for primality.
let is_prime n =
if n < 2 then false
else [|2 .. sqrt_int n|] |> Array.for_all (fun x -> n % x <> 0)
The main function was changed to the following:
/// Problem 27
/// Find a quadratic formula that produces the maximum number of primes for consecutive values of n.
let problem27 n =
let is_prime_mem = memoize is_prime
let set_b = primes (int64 (n - 1)) |> List.to_array |> Array.map int
let set_a = [|-(n - 1) .. n - 1|]
let set_n = Seq.init_infinite (fun i -> i)
set_b |> Array.map (fun b -> (set_a |> Array.map (fun a ->
let formula n = n * n + a * n + b
let num_conseq_primes = set_n |> Seq.find (fun n -> not (is_prime_mem (formula n)))
(a * b, num_conseq_primes))
|> Array.max_by snd)) |> Array.max_by snd |> fst
The key here to increase speed was to only generate the set of primes between 1 and 1000 for the values of b (using the primes function, my implementation of the Sieve of Eratosthenes method). I also managed to make this code slightly more concise by eliminating the unnecessary Seq.map.
So, I'm pretty happy with the solution I have now (it takes just under a second), though of course any further suggestions would still be welcome...
You could speed up your "is_prime" function by using a probabilistic algorithm. One of the easiest quick algorithms for this is the Miller-Rabin algorithm.
to get rid of half your computations you could also make the array of possible a´s only contain odd numbers
my superfast python solution :P
flag = [0]*204
primes = []
def ifc(n): return flag[n>>6]&(1<<((n>>1)&31))
def isc(n): flag[n>>6]|=(1<<((n>>1)&31))
def sieve():
for i in xrange(3, 114, 2):
if ifc(i) == 0:
for j in xrange(i*i, 12996, i<<1): isc(j)
def store():
primes.append(2)
for i in xrange(3, 1000, 2):
if ifc(i) == 0: primes.append(i)
def isprime(n):
if n < 2: return 0
if n == 2: return 1
if n & 1 == 0: return 0
if ifc(n) == 0: return 1
return 0
def main():
sieve()
store()
mmax, ret = 0, 0
for b in primes:
for a in xrange(-999, 1000, 2):
n = 1
while isprime(n*n + a*n + b): n += 1
if n > mmax: mmax, ret = n, a * b
print ret
main()

Resources