001
#include <stdio.h>
002
#include <stdlib.h>
003
004
//
005
// Fibonacci.c
006
// Fibonacci
007
//
008
// Created by Thomas Huang on 12-4-05.
009
// Copyright (c) 2012å⊃1;?__MyCompanyName__. All rights reserved.
010
//
011
012
/*******************************************
013
*
014
* matrix A = [[1, 1],
015
* [1, 0]]
016
* A^n = [[F(N+1), F(N)],
017
* [F(N), F(N -1)]];
018
*
019
********************************************/
020
//
021
022
#define fib(n, power) \
023
int
F[2][2] = {{1,1},{1,0}};\
024
if
(n == 0)\
025
return
0;\
026
power(F, n-1);\
027
return
F[0][0];
028
029
void
mul(
int
F[2][2],
int
M[2][2]);
030
void
power1(
int
F[2][2],
int
n);
031
void
power2(
int
F[2][2],
int
n);
032
int
fib1(
int
n);
033
int
fib2(
int
n);
034
035
036
int
main()
037
{
038
int
n = 30;
039
printf
(
"Fibonacci(%03d) = %d\n"
, n, fib2(n));
040
getchar
();
041
042
return
0;
043
}
044
045
void
mul(
int
F[2][2],
int
M[2][2])
046
{
047
// [[l: left, r : right],
048
// [t: top, b : bootom]]
049
int
lt, rt,
050
bl, br;
051
052
// parallel setions by order {
053
054
//parallel section 1 {
055
lt = F[0][0]*M[0][0] + F[0][1]*M[1][0], rt = F[0][0]*M[0][1] + F[0][1]*M[1][1];
056
bl = F[1][0]*M[0][0] + F[1][1]*M[1][0], br = F[1][0]*M[0][1] + F[1][1]*M[1][1];
057
//}
058
//parallel section 2 {
059
F[0][0] = lt, F[0][1] = rt;
060
F[1][0] = bl, F[1][1] = br;
061
//}
062
//}
063
064
}
065
066
// func : power1
067
// params :
068
// todo(matrix power)
069
// Time Complexity: O(n)
070
// Extra Space: O(1)
071
void
power1(
int
F[2][2],
int
n)
072
{
073
int
i;
074
int
M[2][2] = {{1,1},{1,0}};
075
076
for
( i = 2; i <= n; i++ )
077
mul(F, M);
078
079
}
080
081
// func : power2
082
// params :
083
// todo(matrix power)
084
// Time Complexity: O(Logn)
085
// Extra Space: {'fuction stack size' : O(Logn),
086
// 'otherwise' : O(1)}
087
void
power2(
int
F[2][2],
int
n)
088
{
089
if
( n == 0 || n == 1)
090
return
;
091
int
M[2][2] = {{1,1},{1,0}};
092
093
power2(F, n/2);
094
mul(F, F);
095
096
if
( n%2 != 0 )
097
mul(F, M);
098
}
099
100
101
int
fib1(
int
n)
102
{
103
fib(n, power1)
104
}
105
106
int
fib2(
int
n)
107
{
108
fib(n, power2);
109
}