aureooms/js-fibonacci Home Manual Reference Source Test Repository

src/matrix.js

  1.  
  2. export function __matrix__ ( zero , one , mul , add ) {
  3. /**
  4. * @param {nth} n > 0
  5. */
  6. var matrix = function ( n ) {
  7.  
  8. // We can compute simultaneously,
  9. //
  10. // a = b
  11. // b = a + b
  12. //
  13. // Using matrix multiplication,
  14. //
  15. // X M
  16. // : :
  17. // | a | | 0 1 |
  18. // | b | . | 1 1 |
  19. //
  20. // With this we can compute F_{n-1} and F_n using matrix exponentiation
  21. //
  22. // n
  23. // | F_{n-1} | | 0 | | 0 1 |
  24. // | F_n | = | 1 | . | 1 1 |
  25. //
  26. // Matrix exponentiation can be achieved in log n steps using the
  27. // binary decomposition of n
  28. //
  29. // n = ( n % 2 ) * 1 + ( ( n >> 1 ) % 2 ) * 2 + ... + ( ( n >> i ) % 2 ) * ( i + 1 ) + ...
  30. //
  31. // And computing M raised to successive powers of 2,
  32. //
  33. // 2
  34. // n / (n//2) \ (n%2)
  35. // | 0 1 | | | 0 1 | | | 0 1 |
  36. // | 1 1 | = \ | 1 1 | / . | 1 1 |
  37. //
  38. // The matrix is encoded as
  39. //
  40. // | t u |
  41. // | v w |
  42.  
  43. var a , b , t , u , v , w , a2 , b2 , t2 , u2 , v2 , w2 ;
  44.  
  45. a = zero( ) ; b = one( ) ;
  46. t = zero( ) ; u = one( ) ; v = one( ) ; w = one( ) ;
  47.  
  48. while ( true ) {
  49.  
  50. if ( n % 2 === 1 ) {
  51.  
  52. a2 = add( mul( a , t ) , mul( b , u ) ) ;
  53. b2 = add( mul( a , v ) , mul( b , w ) ) ;
  54.  
  55. a = a2 ; b = b2 ;
  56.  
  57. if ( n === 1 ) break ;
  58.  
  59. }
  60.  
  61.  
  62. t2 = add( mul( t , t ) , mul( u , v ) ) ;
  63. u2 = add( mul( t , u ) , mul( u , w ) ) ;
  64. v2 = add( mul( v , t ) , mul( w , v ) ) ;
  65. w2 = add( mul( v , u ) , mul( w , w ) ) ;
  66.  
  67. t = t2 ; u = u2 ; v = v2 ; w = w2 ;
  68.  
  69. n >>>= 1 ;
  70.  
  71. }
  72.  
  73. return [ a , b ] ;
  74.  
  75. } ;
  76.  
  77. return matrix ;
  78.  
  79. }
  80.