0% found this document useful (0 votes)
16 views93 pages

2 AlgorithmsAnalysis

This code analyzes the runtime complexity of a nested for loop. The innermost loop runs in O(n) time. The middle loop runs O(i) times, where i increases exponentially from 1 to n. So the middle loop runs in O(n log n) time. The outermost loop runs in O(log n) time. Therefore, the overall runtime complexity is O(n log2 n).

Uploaded by

Anas Alajati
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views93 pages

2 AlgorithmsAnalysis

This code analyzes the runtime complexity of a nested for loop. The innermost loop runs in O(n) time. The middle loop runs O(i) times, where i increases exponentially from 1 to n. So the middle loop runs in O(n log n) time. The outermost loop runs in O(log n) time. Therefore, the overall runtime complexity is O(n log2 n).

Uploaded by

Anas Alajati
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 93

SUMMARY

• PROBLEM, ALGORITHM, PROGRAM

• RESOURCE (Running Time, Memory Used)

• ENGINEERING APPROXIMATIONS
– Just count program steps
– Only worry about “hot spots”
– Figure out how resource usage varies
as a function of the input size
1
MATHEMATICAL FRAMEWORK
• Establish a relative order among the growth
rate of functions.

• Use functions to model the “approximate”


and “asymptotic” (running time) behaviour of
algorithms.

2
MATHEMATICAL FRAMEWORK
• DEFN: We say T(N) = O(f(N)) (order or (big)
o(h) f(N)) if there are positive constants c and
n0 such that
T(N)  c • f(N)
when N  n0

3
MATHEMATICAL FRAMEWORK
• DEFN: We say T(N) = O(f(N)) (order or (big)
o(h) f(N)) if there are positive constants c and
n0 such that
T(N)  c • f(N)
cf(N)
when N  n0

T(N)

n0 4 N
MATHEMATICAL FRAMEWORK
• DEFN: We say T(N) = (f(N)) (omega of f(N))
if there are positive constants c and n0 such
that
T(N)  c • f(N)
when N  n0

5
MATHEMATICAL FRAMEWORK
• DEFN: We say T(N) = (f(N)) (omega of f(N)) if
there are positive constants c and n0 such that
T(N)  c • f(N)
when N  n0
T(N)

cf(N)

n0 N
6
MATHEMATICAL FRAMEWORK
• DEFN: We say T(N) = (f(N)) (theta of f(N)) if
T(N) = O(f(N)) and T(N) = (f(N))
c’f(N)

T(N)

cf(N)

n0 n0’ N
7
MATHEMATICAL FRAMEWORK
• DEFN: We say T(N) = o(f(N)) (little o(h) of
f(N)) if T(N) = O(f(N)) and T(N)  (f(N))

• T(N) grows strictly slower than f(N)

8
MATHEMATICAL FRAMEWORK
• DEFN: We say T(N) = o(f(N)) (little o(h) of
f(N)) if T(N) = O(f(N)) and T(N)  (f(N))

cf(N)

T(N)

n0 N
9
EXAMPLES
• Let’s see whether 1000N = O(N2)
• 1000N  c • N2 when N  n0
• 1000N is larger than N2 for small values of N but
eventually N2 dominates.
• For n0 =1000 and c = 1,
 1000N  N2 when N  1000
• So 1000 N = O(N2)

10
EXAMPLES
• Let’s see whether 1000N = O(N2)
– 1000N  c • N2 when N  n0
• 1000N is larger than N2 for small values of N but
eventually N2 dominates. For n0  1000 and c =
1, N2  1000 N , so 1000 N = O(N2)
• Note that we have other choices for c and n0
(c = 100 and n0 = 10), but only one pair is
sufficient.

11
EXAMPLES
• 1000N = O(N2)
• 1000N is larger than N2 for small values of N but
eventually N2 dominates. For n0  1000 and c =
1, N2  1000 N , so 1000 N = O(N2)
• Note that we have other choices for c and n0
(c = 100 and n0 = 10), but only one pair is
sufficient.
• Basically what we are saying is that 1000N
grows slower than N2.
12
EXAMPLES
• Let’s see whether 0.001 N2 =(N)
– 0.001N2  c • N when N  n0
• 0.001 N2 is smaller than N for small values of N ,
but eventually 0.001 N2 dominates.
• For n0 =1000 and c = 1
– 0.001 N2  N when N  1000
• So, 0.001 N2 = (N)
• So, 0.001 N2 grows at a faster rate than that of
N.
13
EXAMPLES
• 5 N2 = O(N2) (c = 6 and n0 = 1)

• 5 N2 = (N2) (c = 4 and n0 = 1)

• So 5N2 = (N2), both functions grow at the


same rate.

14
SOME USEFUL FUNCTIONS
• Growth rate of some useful functions
Function Name
c Constant
log N Logarithmic
log2 N Log-squared
N Linear
N log N
N2 Quadratic
N3 Cubic
cN Exponential
15
SOME USEFUL FUNCTIONS
• Growth rate of some useful functions
Function Name
c Constant
SUBLINEAR
log N Logarithmic
log2 N Log-squared
N Linear
N log N
N2 Quadratic
N3 Cubic
cN Exponential
16
SOME USEFUL FUNCTIONS
• Growth rate of some useful functions
Function Name
c Constant
log N Logarithmic
log2 N Log-squared
N Linear
N log N
N2 Quadratic POLYNOMIAL
N3 Cubic
cN Exponential
17
How Large is Really Large?

18
OBSERVATIONS
• Never include constants or lower-order terms in
the big-oh notation
– Constants do NOT matter!
• E.g., instead of O(2N + 2) use O(N)
– Lower order terms do NOT matter!
• E.g., instead of O(N2 + 2N + 2) use O(N2)
• Get as tight as possible in the big-oh notation
– N = O(N) = O(N2) = O(N3) = O (N4) = O(NN) = …
– But, N = O(N) is as tight as possible

19
RULES
• Rule 1
If T1(N) = O(f(N)) and T2(N) = O(g(N)) then

(a) T1(N) + T2(N) = max (O(f(N)) , O(g(N)) )

(b) T1(N) * T2(N) = O( f(N) * g (N))

20
RULES
• Rule 2
If T(N) is a polynomial of degree k, then
T(N) =  (N k)

21
RULES
• Rule 3
log k N = O(N) for any constant k.

• Logarithms grow very slowly.

22
ANALYZING COMPLEXITY
• Rule : for loops
The running time is at most the running time
of the statements in the loop (including the
tests) times the number of iterations.

23
ANALYZING COMPLEXITY
• Rule 1: for loops
The running time is at most the running time
of the statements in the loop (including the
tests) times the number of iterations.
for (i = 1; i <= N; i++) {

}
........
........ O(F(N)) O(N•F(N))
}
24
ANALYZING COMPLEXITY
• Rule 1: for loops
The running time is at most the running time of the
statements in the loop (including the tests) times the
number of iterations.
for (i = 1; i <= N; i++) {

}O(F(N))
........
........
}
O(N•F(N))
• Be careful when the loop time depends on the
index
25
For-loop example


for (i = 0 ; i < N ; i++)
for (j

= 0 ; j < N; j++) {


k = i+j; 
x = 2 * k;

 O(1) O(N•1) = O(N)


}

O(N•N) = O(N 2)

26
For-loop example


for (i = 1 ; i < N ; i = i*2)
for (j = 0 ; j < N; j++)


{
k = i+j;  O(1)
  O(N•1)=O(N)


x = 2 * k; 
}

O( log2N•N)=O(N • logN)

27
ANALYZING COMPLEXITY
• Rule: Consecutive Statements
– The running time is the sum of the running times
of individual statements,
• Remember that
If T1(N) = O(f(N)) and T2(N) = O(g(N)) then
T1(N) + T2(N) = max (O(f(N)) , O(g(N)) )
• Which means that you have to take the
maximum of the running times of the
statements.
28
Example


Statement 1 O(N)

Statement 2 O(N 2)
 O( N )
2

Statement 3 O(N log N)



29
ANALYZING COMPLEXITY
• Rule: If statements
– if (condition) then O(fc(N))
S1 O(fthen(N))
else
S2 O(felse(N))
How can we bound the
running time of the if
statement?
max(O(fc(N)), O(fthen(N)), O(felse(N)) )
30
AN EXAMPLE
{
1 int i,j;
2 for (i=1; i <= n ; i=i*2) {
3 for (j = 0; j < i; j++) {
4 foo[i][j] = 0; O(1)
5 for (k = 0; k < n; k++) {
6 foo[i][j] = bar[k][i+j] + foo[i][j]; O(1) O(n) O(n)
7 }
8 }
9 }
}

31
AN EXAMPLE
Although this loop is executed about log
{ n times, at each iteration the time of the
1 int i,j; inner loop changes!
2 for(i=1; i <= n ; i=i*2) {
3 for(j = 0; j < i; j++) {
4 foo[i][j] = 0;
5 for (k = 0; k < n; k++) {
O(i • n)
6 foo[i][j] = bar[k][i+j] + foo[i][j]; O(n)
7 }
8 }
9 }
}

32
AN EXAMPLE
{ Although this loop is executed about log
1 int i,j; n times, at each iteration the time of the
inner loop changes!
2 for (i=1; i <= n ; i=i*2) {
3 for (j = 0; j < i; j++) {
4 foo[i][j] = 0;
5 for (k = 0; k < n; k++) { O(i•n)
6 foo[i][j] = bar[k][i+j] + foo[i][j]; O(n)
7 }
8 } j n n 1
r 1
9
}
}

j 0
r 
j

r 1
Assume n is a power of 2 that is n = 2m for some positive integer m
O(1•n) + O(2•n) + O(4•n) + .... + O(2m • n) = O(n2)
Avoid the log N trap! 33
RECURSIVE PROGRAMS
• Fibonacci Numbers
– F(0) = 0, F (1) = 1
– F(N) = F(N-1) + F(N-2) for N > 1

34
RECURSIVE PROGRAMS
• Fibonacci Numbers
– F(0) = 0, F (1) = 1
– F(N) = F(N-1) + F(N-2) for N > 1

• Fact (that you will learn in MATH 204)


– F(N) = (1/5) ( N -  N )
•  = (1 + 5) / 2,  = (1 - 5) / 2
• (3/2) N  F(N) < (5 / 3) N ( for N > 4)
• So F(N) is an exponentially growing function

35
COMPUTING FIBONACCI NUMBERS
• The obvious algorithm (assume n  0)
long int fib ( int n )
{
if (n <= 1)
return ( n );
else
return ( fib (n – 1) + fib (n –
2) );
}

• How good is this algorithm? 36


COMPUTING FIBONACCI NUMBERS
• The obvious algorithm (assume n  0)
long int fib ( int n )
{
if (n <= 1)
return ( n );
else
return ( fib (n – 1) + fib (n – 2) );
}

• Let T(N) is the number of statements we need to


execute to compute the Nth Fibonacci number.
37
COMPUTING FIBONACCI NUMBERS
• The obvious algorithm (assume n  0)

long int fib( int n)


{
if (n <= 1)
return( n );
else
return( fib (n – 1) + fib (n –
2) );
}

• T(0) = T(1) = 2 38
COMPUTING FIBONACCI NUMBERS
• The obvious algorithm
long int fib( int n)
{
if (n <= 1)
return ( n );
else
return ( fib (n – 1) + fib (n – 2)
);
}

• T(0) = T(1) = 2
• T(N) = T(N-1) + T(N-2) + 2 39
COMPUTING FIBONACCI NUMBERS
• Running time
– T(0) = T(1) = 2
– T(N) = T(N-1) + T(N-2) + 2
• Fibonacci Numbers
– F(0) = 0, F (1) = 1
– F(N) = F(N-1) + F(N-2)
• By induction you can show T(N)  F(N) (Why is that?)
• (3/2) N  F(N) < (5 / 3) N ( for N > 4)
• T(N)  (5/3) N
• Which means T(N) is exponential!
• Not good !!!

40
COMPUTING FIBONACCI NUMBERS
• What is going on?

41
COMPUTING FIBONACCI NUMBERS
• What is going on?
F(6)

F (5) F(4)
F(3) F(2)
F(4) F(3)
F(2) F(1) F(1) F(0)
F(3) F(2) F(2) F(1)
F(1) F(0)
F(2) F(1) F(1) F(0) F(1) F(0)
F(1) F(0)

Too much redundant computation


42
COMPUTING FIBONACCI NUMBERS
• The next obvious algorithm (assume n  0)

int fib( int n)


{
int X[3];
if (n <= 1) return(n);
X[0]=0; X[1]=1;
for (i = 2; i <= n; i++)
X[i % 3] = X[(i-1) % 3] + X[(i-2) % 3];
return X[(i-1) % 3] ;
}

• % is the mod operator i%3  i mod 3 43


COMPUTING FIBONACCI NUMBERS
• The next obvious algorithm (assume n  0)
int fib( int n) when i=2
{ 0 X[0]
int X[3]; fib(0)
if (n <= 1) return(n); 1 X[1]
X[2]
X[0]=0; X[1]=1;
fib(1)
for (i = 2; i <= n; i++)
X[i % 3] = X[(i-1) % 3] + X[(i-2) % 3];
return X[(i-1) % 3] ;
}

44
COMPUTING FIBONACCI NUMBERS
• The next obvious algorithm (assume n  0)
int fib( int n) when i=2
{ 0 X[0]
int X[3]; fib(0)
if (n <= 1) return(n); 1 X[1]
X[2] 1
X[0]=0; X[1]=1;
fib(2) fib(1)
for (i = 2; i <= n; i++)
X[i % 3] = X[(i-1) % 3] + X[(i-2) % 3];
return X[(i-1) % 3] ;
}

45
COMPUTING FIBONACCI NUMBERS
• The next obvious algorithm (assume n  0)
int fib( int n) fib(3)
{ 2 X[0]
int X[3];
if (n <= 1) return(n);
X[2] 1 1 X[1]
X[0]=0; X[1]=1;
fib(2) fib(1)
for (i = 2; i <= n; i++)
X[i % 3] = X[(i-1) % 3] + X[(i-2) % 3];
return X[(i-1) % 3] ;
}

46
COMPUTING FIBONACCI NUMBERS
• The next obvious algorithm (assume n  0)
int fib( int n) fib(3)
{ 2 X[0]
int X[3];
if (n <= 1) return(n);
X[2] 1 3 X[1]
X[0]=0; X[1]=1;
fib(2) fib(4)
for (i = 2; i <= n; i++)
X[i % 3] = X[(i-1) % 3] + X[(i-2) % 3];
return X[(i-1) % 3] ;
}

47
COMPUTING FIBONACCI NUMBERS
• The next obvious algorithm (assume n  0)
int fib( int n) fib(3)
{ 2 X[0]
int X[3];
if (n <= 1) return(n);
X[2] 5 3 X[1]
X[0]=0; X[1]=1;
fib(5) fib(4)
for (i = 2; i <= n; i++)
X[i % 3] = X[(i-1) % 3] + X[(i-2) % 3];
return X[(i-1) % 3] ;
}

48
COMPUTING FIBONACCI NUMBERS
• The next obvious algorithm (assume n  0)
int fib( int n)
{
int X[3];
if (n <= 1) return(n);
X[0]=0; X[1]=1;
for (i = 2; i <= n; i++)
X[i % 3] = X[(i-1) % 3] + X[(i-2) % 3];
return X[(i-1) % 3] ;
}

• Because i is incremented at the end of the loop before


exit.
• ~N iterations each taking constant time → O(N)
• Much better than the O(cN) algorithm, but .... 49
COMPUTING FIBONACCI NUMBERS
• Can we do any better?

• Yes, it turns out we can compute F(N) in about


O(log N) steps.

• Basically we can compute


– F(N) = (1/5) ( N -  N )
directly without doing any real arithmetic.
50
COMPUTING FIBONACCI NUMBERS
• But how????

• It turns out that

• So if we can compute the nth power of


something fast, we can compute Fn fast.
51
COMPUTING FIBONACCI NUMBERS
• But how????

• First let’s look at a simple problem.

• How can we compute X N fast ?

52
COMPUTING FIBONACCI NUMBERS
• Let’s compute X4

• The obvious algorithm


– X 4 = X * X * X *X (3 multiplications)
– X N requires N-1 multiplications

• A clever algorithm
–A=X*X
– X 4= A * A (requires 2 multiplications)
53
COMPUTING X N

long pow (long x, int n)


{
if (n == 0) return (1);
if (isEven(n))
return(pow(x*x, n/2));
else
return(x * pow( x, n –
1));
} 54
COMPUTING X N

long pow (long x, int n) pow(x,17) =


{ x * pow(x,16) =
if (n == 0) return (1);
x * pow (x*x, 8) =
if (isEven(n))
x * pow((x2)*(x2), 4) =
return(pow(x*x, n/2));
else x * pow((x4)*(x4), 2) =
return x * pow((x8)*(x8),1) =
(x * pow( x, n – 1)); x * pow((x16), 0) * x16 =
} x * x16

55
COMPUTING X N

long pow (long x, int n) • At most 1


{ multiplication per
if (n == 0) return (1); halving
if (isEven(n))
return(pow(x*x, n/2));
• log N halving calls
else
return
(x * pow( x, n – 1)); • O(log N) algorithm
}

56
COMPUTING X N

• There is nothing special about taking a matrix


to the nth power.
• Each matrix multiplication is a fixed number of
scalar multiplications and additions.

57
BACK TO FIBONACCI
• Can we prove that

• Proof by Induction
– Basis case n=1

58
COMPUTING FIBONACCI

• Assume that

• Inductive case n >1

59
PROBLEMS, ALGORITHMS AND BOUNDS

• To show a problem is O(f(N)): demonstrate a


correct algorithm which solves the problem
and takes O(f(N)) time. (Usually easy!)

• To show a problem is (f(N)): Show that ALL


algorithms solving the problem must take at
least f(N)) time. (Usually very hard!)

60
(Back to) MULTIPLICATION
• Elementary school addition : (N)
– We have an algorithm which runs in O(N) time
– We need at least (N) time
• Elementary school multiplication: O(N2)
– We have an algorithm which runs in O(N2) time.

61
MULTIPLICATION

*******
X *******
*******
*******
*******
*******
*******
*******
*******
************** 62
MULTIPLICATION




N
*******
X *******
*******
*******
*******  N 2
*******
*******

*******
*******

************** 63
MULTIPLICATION
• Elementary school addition : (N)
• Elementary school multiplication: O(N2)

• Is there a clever algorithm to multiply two


numbers in linear time?
• Possible Ph.D. Thesis!

64
FAST(ER) MULTIPLICATION
• Divide and Conquer
– Divide the problem into smaller problems
– Conquer (solve) the smaller problems
recursively
– Combine the answers of the smaller problems
to obtain the answer for the larger problems.

• Fundamental technique in algorithm design.

65
MULTIPLICATION

X= a b (N bits)

Y= c d (N bits)

X = a 2N/2 + b Y = c 2N/2 + d

66
MULTIPLICATION

X= a b (N bits)

Y= c d (N bits)

X = a 2N/2 + b Y = c 2N/2 + d

Note that these are NOT really multiplications but actually shifts!

67
SHIFTS
• Multiply by 2 is the same as shift left by 1 bit.

• Just as Multiply by 10 is the same as shift left


by 1 digit
– 40 * 10 = 400

68
SHIFTS
• Multiply by 2 is the same as shift left by 1 bit.
– 1012 = 510
• Shifting left by 1 we get
– 10102 = 1010
• Shift left by n-bits = multiply by 2n

• Shift right by n-bits is divide by 2n

69
BRIEF DIGRESSION

X= a b (N bits)

X = a 2N/2 + b
X = 25010 = 1·128 + 1· 64 + 1· 32 + 1· 16 + 1· 8 + 0 · 4+1 · 2 + 0·1

70
BRIEF DIGRESSION

X= a b (N bits)

X = a 2N/2 + b
X = 25010 = 1·128 + 1· 64 + 1· 32 + 1· 16 + 1· 8 + 0 · 4+1 · 2 + 0·1
X = 111110102 X = 1111 1010

a = 11112 = 1510 b = 10102=1010

71
BRIEF DIGRESSION

X= a b (N bits)

X = a 2N/2 + b
X = 25010 = 1·128 + 1· 64 + 1· 32 + 1· 16 + 1· 8 + 0 · 4+1 · 2 + 0·1
X = 111110102 X = 1111 1010

a = 11112 = 1510 b = 10102=1010

a 28/2 = 111100002= 24010 X = 25010 = 240 + 10


You just shift 4 0s in. Takes 4 steps. 72
(Back to) MULTIPLICATION

X= a b (N bits)

Y= c d (N bits)

X = a 2N/2 + b Y = c 2N/2 + d
XY = ac 2N + (ad+bc)2N/2 + bd

73
MULTIPLICATION
X = a 2N/2 + b Y = c 2N/2 + d
XY = ac 2N + (ad+bc) 2N/2 + bd
Length of the numbers
This is either 0 or 1
Mult(X,Y):
if |X| = |Y| = 1 return (XY);
Break X into a:b and Y into c:d;
return ( Mult(a,c)·2N + (Mult(a,d) + Mult(b,c)) ·2N/2 +
Mult(b,d));
This is an example of divide and conquer.
74
MULTIPLICATION
Mult(X,Y):
if |X| = |Y| = 1 return (XY);
Break X into a:b and Y into c:d;
return (Mult(a,c)·2N+ (Mult(a,d)+Mult(b,c)) ·2N/2 +
Mult(b,d));

What is T(N), the time taken by Mult(X,Y) on two


N-bit numbers?

75
MULTIPLICATION
Mult(X,Y):
if |X| = |Y| = 1 return (XY);
Break X into a:b and Y into c:d;
return (Mult(a,c)·2N+ (Mult(a,d)+Mult(b,c)) ·2N/2 +
Mult(b,d));

T(1) = k for some constant k

T(N) = 4 T(N/2) + k’ N for some constant k’

76
MULTIPLICATION
Mult(X,Y):
if |X| = |Y| = 1 return (XY);
Break X into a:b and Y into c:d;
return (Mult(a,c)·2N + (Mult(a,d)+Mult(b,c)) ·2N/2 +
Mult(b,d));

T(1) = k for some constant k

T(N) = 4 T(N/2) + k’ N for some constant k’

77
MULTIPLICATION
• Let us be more concrete and assume k=1 and
k’ = 1.
– T(1) = 1
– T(N) = 4 T(N/2) + N

• Note T(N) is inductively defined on powers of


2.

78
MULTIPLICATION
• T(N) = 4 T(N/2) + N
= 4 (4 T(N/4) + N/2) + N
= 16 T(N/4) + 2N + N

79
MULTIPLICATION
• T(N) = 4 T(N/2) + N
= 4 (4 T(N/4) + N/2) + N
= 4 (4 (4 T(N/8) + N/4)+N/2)+N
= 64 T(N/8) + 4N + 2N + N

80
MULTIPLICATION
• T(N) = 4 T(N/2) + N
= 4 (4 T(N/4) + N/2) + N
= 4 (4 (4 T(N/8) + N/4)+N/2)+N
......
= 4 i T(N/2 i) + 2 i-1 N + ... + 21N + 20N

81
MULTIPLICATION
• T(N) = 4 T(N/2) + N
= 4 (4 T(N/4) + N/2) + N
= 4 (4 (4 T(N/8) + N/4)+N/2)+N
......
= 4 i T(N/2 i) + 2 i-1 N + ... + 21N + 20N
j=i-1

= 4 i T(N/2 i) + N · 2
j=0
j

82
MULTIPLICATION
• T(N) = 4i T(N/2i) + 2i-1 N + ... + 21N + 20N
j=i-1

= 4i T(N/2i) + N · 2
j=0
j

...... j=log2N -1

= 4 log2N · T(N/2log2N)+ N · 2 j=0


j

j=log2N -1

= 4 log2N · T(1) + N · 2j=0


j

83
MULTIPLICATION
j=log2N -1

• T(N) = 4 log2N · T(1) + N ·


j=0
2j

= N2 · 1 + N · ( 2 log2N – 1)
=
Geometric series
j n n 1
r 1

j 0
r 
j

r 1
84
MULTIPLICATION
j=log2N -1

• T(N) = 4 log2N · T(1) + N · 


j=0
2j

log2N
= N ·1+N·(2
2
– 1)
= N2 · 1 + N · ( N – 1)
= 2 N2 – N
• So T(N) = O(N2)

85
MULTIPLICATION

• T(N) = O(N2)

• Looks like divide and conquer did not buy us


anything.

• All that work for nothing!

86
MULTIPLICATION
• But what about Gauss’ Hack?
– X1 = a + b
– X2 = c + d
– X3 = X1* X2 = ac+ad+bc+bd
– X4 = ac
– X5 = bd
– X6 = X4 – X5 = ac - bd
– X7 = X3 – X4 – X5 = ad + bc
87
MULTIPLICATION
• Gaussified Multiplication (Karatsuba 1962)
Mult(X,Y):
if |X| = |Y| = 1 return (XY)
Break X into a:b and Y into c:d;
e = Mult(a,c), f = Mult(b,d);
return (e2N+ (Mult(a+b,c+d) – e –f) 2N/2 + f)

• T(N) = 3 T(N/2) + N
Actually T(N) = 2 T(N/2) +T(N/2+1)+ kN (Why?)

88
MULTIPLICATION
• T(N) = 3 T(N/2) + N
T(1) = 1

• If we do the algebra right as we did for the first


case

T(N) = N + 3/2 N + ... + (3/2) log2N N


= N ( 1 + 3/2 + .... + (3/2) log2N)
= 3 N log23 – 2N
= 3 N 1.58 – 2N
• FFT-based Multiplication
89
MULTIPLICATION

• Compare TFAST(N)= 3 N1.58 – 2N with


TSLOW(N)= 2 N2 – N

N TSLOW(N) / TFAST(N)
32 3.09
64 4.03
128 5.31
512 9.20
1024 12.39
65536 ~330
90
FAST MULTIPLICATION

• Why is this important?

• Modern cryptography systems (RSA,DES etc)


require multiplication of very large numbers
(1024 bit or 2048 bit).

• The fast multiplication algorithm improves


these systems substantially.
91
Summary
• Problems, Algorithms, Programs

• Complexity of an algorithm: The (worst-case) time


used by an algorithm. (Upper bound)
– Bubble sort is an O(N 2) algorithm for sorting.

• Complexity of a Problem: The minimum complexity


among all possible algorithms for solving the
problem. (Lower bound)
– Sorting problem has complexity (N log N).

92
Summary
• Optimal Algorithm: An algorithm whose
complexity matches the complexity of the
problem.
– Merge Sort is an optimal algorithm for sorting
because its complexity is (N log N)

93

You might also like