(* versão matricial, e uso de representação numérica de precisão arbitrária (num, em vez de big_int)

/      \  n   /   \    /       \
| 0 1 0 |     | 3 |    | P(n)  |
| 0 0 1 |  X  | 0 |  = | P(n+1)| 
| 1 1 0 |     | 2 |    | P(n+2)|
\       /     \   /     \      /

*)


(* compilation : ocamlopt nums.cmxa perrin_mat.ml -o perrin_mat *)

open Array
open Num
       
let m = make_matrix 3 3 (Int 0)
let () = (m.(0).(1) <- (Int 1);  m.(1).(2) <- (Int 1);  m.(2).(0) <- (Int 1); m.(2).(1) <- (Int 1))

(*  multiplicação de matrizes 3 por 3*)
let ( +*+ ) a b =
  let m = make_matrix 3 3 (Int 0) in
  let () = m.(0).(0) <-  a.(0).(0) */ b.(0).(0) +/ a.(0).(1) */ b.(1).(0) +/  a.(0).(2) */ b.(2).(0);
           m.(0).(1) <-  a.(0).(0) */ b.(0).(1) +/ a.(0).(1) */ b.(1).(1) +/  a.(0).(2) */ b.(2).(1) ;
           m.(0).(2) <-  a.(0).(0) */ b.(0).(2) +/ a.(0).(1) */ b.(1).(2) +/  a.(0).(2) */ b.(2).(2) ;
           m.(1).(0) <-  a.(1).(0) */ b.(0).(0) +/ a.(1).(1) */ b.(1).(0) +/  a.(1).(2) */ b.(2).(0) ;
           m.(1).(1) <-  a.(1).(0) */ b.(0).(1) +/ a.(1).(1) */ b.(1).(1) +/  a.(1).(2) */ b.(2).(1) ;
           m.(1).(2) <-  a.(1).(0) */ b.(0).(2) +/ a.(1).(1) */ b.(1).(2) +/  a.(1).(2) */ b.(2).(2) ;
           m.(2).(0) <-  a.(2).(0) */ b.(0).(0) +/ a.(2).(1) */ b.(1).(0) +/  a.(2).(2) */ b.(2).(0) ;
           m.(2).(1) <-  a.(2).(0) */ b.(0).(1) +/ a.(2).(1) */ b.(1).(1) +/  a.(2).(2) */ b.(2).(1) ;
           m.(2).(2) <-  a.(2).(0) */ b.(0).(2) +/ a.(2).(1) */ b.(1).(2) +/  a.(2).(2) */ b.(2).(2) in
  m;;

(* exponenciação *rápida* de matrizes: M^n *)
let rec ( +^+ ) a = function
  0 -> [|[|(Int 1);(Int 1);(Int 1)|];[|(Int 1);(Int 1);(Int 1)|];[|(Int 1);(Int 1);(Int 1)|]|]
  | 1 -> a
  | n  ->let m =  a +^+ (n/2) in
    if  (n mod 2) = 0 then  m +*+ m else  a +*+ (m +*+ m)
     
let perrin n =
  if n<0 then  failwith "Argumento inválido"
  else
    let mm = m +^+ n in
    mm.(0).(0) */ (Int 3) +/ mm.(0).(2) */ (Int 2);;

let () = print_endline (string_of_num (perrin (read_int ())))
  

This document was generated using caml2html