#include <iostream>
#include <vector>
using namespace std;
template <typename _type>
class fibonacci {
private :
//vecotr<_type> m_mat;
int m_num;
public :
fibonacci (_type n) : m_num(n){
}
~fibonacci () {}
_type fn () ;
vector<_type> fibo (const vector<_type>& mat, _type n);
if (n < 0 )
return false;
this->m_num = n;
return true;
}
vector <_type> multiMat (const vector<_type>& lhsMat, const vector<_type>& rhsMat ) {
/*
* |a b| |e f|
* |c d| |g h|
* */
vector<_type> ansMat(4,0);
_type ae = lhsMat[0]*rhsMat[0];
_type bg = lhsMat[1]*rhsMat[2];
_type af = lhsMat[0]*rhsMat[1];
_type bh = lhsMat[1]*rhsMat[3];
_type ce = lhsMat[2]*rhsMat[0];
_type dg = lhsMat[3]*rhsMat[2];
_type cf = lhsMat[2]*rhsMat[1];
_type dh = lhsMat[3]*rhsMat[3];
ansMat.at(0) = ae + bg;
ansMat.at(1) = af + bh;
ansMat.at(2) = ce + dg;
ansMat.at(3) = cf + dh;
return ansMat;
}
_type orgFn () ;
};
template <typename _type >
vector<_type>
fibonacci<_type>::fibo (const vector<_type>& mat, _type n) {
if (n < 2)
return static_cast<vector<_type> > (mat);
return (n % 2 == 0 ? multiMat(fibo(mat, n>>1), fibo(mat, n>>1)) : multiMat(mat, multiMat(fibo(mat, (n-1)>>1), fibo(mat, (n-1)>>1))));
}
template <typename _type> _type
fibonacci<_type>::fn() {
if (this->m_num == 0 )
return 0;
else if (this->m_num == 1) {
return 1;
}
vector<int> orgMat;
orgMat.push_back(1);
orgMat.push_back(1);
orgMat.push_back(1);
orgMat.push_back(0); // 1 1
// 1 0
_type n = this->m_num - 1;
orgMat = fibo(orgMat, n);
return orgMat.at(0);
}
template <typename _type> _type
fibonacci<_type>::orgFn (){
if (this->m_num == 0)
return 0;
if (this->m_num == 1) {
return 1;
}
_type a = 0;
_type b = 1;
_type fn = a + b;
for (int i = 1; i < this->m_num; ++i ) {
fn = a + b;
a = b;
b = fn;
}
return fn;
}
int
main (void) {
fibonacci<int> fn (0);
for (int i = 0; i < 40; ++i ) {
fn.setN(i);
cout << "n -> " << i << "\tfn : " << fn.fn() << "\torgFn : " << fn.orgFn () << endl;
}
return 0;
}