Commits

Gabriel Pichot committed 0389c3e

Register hérité désormais de vector. J'ai enlevé l'option
--print car les graphes auraient été très @@@@ à mettre en place.
Se rabattre sur --tex qui permet un meilleur rendu.

Comments (0)

Files changed (5)

   | 0 -> 0
   | n -> 1 + (nb_bits (n lsr 1))
 
-let order ~print ~texPrint p n = 
+let order ~texPrint p n = 
   log "\n---- Recherche de l'ordre de %i dans %i ----\n" p n; 
   let l = getQ n in
   let q = pow 2 l in
 (*  log "Fin de la transformée de Fourier.\n";*)
   reg1#normalize ();
   (* Si on doit afficher le résultat de la transformée de Fourier *)
-  if print then showProb (reg1#state ());
-  if texPrint then printAsTex (reg1#state ()) p n;
+  if texPrint then printAsTex reg1 p n;
   (* On mesure c sur le premier registre *)
   let c = reg1#measureState () in
  (* log "On trouve pour c : %i.\n" c;*)
   end
 in
 log "Le nombre qui va nous servir (et qui ne divise pas n) est : %i.\n" p;
-(* On peut aussi afficher les graphes d'après de transformée de Fourier avec
- * l'option --print mise en dernière *)
-let printState = nb_args >= 4 && argv.(3) = "--print" in
+(* On peut aussi afficher les graphes après la transformée de Fourier avec
+ * l'option --tex *)
 let texPrint   = nb_args >= 4 && argv.(3) = "--tex" in
 (* }}} *)
 
 let success = ref false 
 and attempts = ref 5 in
 while not !success && !attempts > 0 do
-  let r = order ~print:printState ~texPrint p n in
+  let r = order ~texPrint p n in
   log "Ordre possible trouvé : %i.\n" r; 
   if not (orderFail r p) then begin
     let factor = findFactor r p in
     if factor <> 0 then begin
       log "\n ---- Succès : %i = %i x %i. ----\n" n factor (n / factor);
       success := true
-    end
-  end;
+    end else
+      log "Cet ordre ne permet pas de factoriser %i.\n" n;
+  end; 
   decr attempts
 done;
 if not !success then
     val data = match data with 
       | Some x -> x 
       | None -> Array.make_matrix (fst dims) (snd dims) Ev.zero
-    method rows () = rows
-    method cols () = cols
+    method rows = rows
+    method cols = cols
+    method data = data
     method get row col = data.(row-1).(col-1)
     method set row col value = data.(row-1).(col-1) <- value
     method to_string () =
 open Log;;
-open Graphics;;
 open Quantum;;
 
-let showProb u = 
-  let n = u#rows () in
-  let base = if 800 / n = 0 then 1 else 800 / n in
-  let swidth = base * n
-  and sheight = 300 in
-  open_graph (Printf.sprintf " %ix%i" swidth sheight);
-  for i = 0 to n - 1 do
-    let height = int_of_float (Complex.norm2 (u#row (i + 1)) *. (float_of_int sheight)) in
-    fill_rect (i * base) 0 base height
-  done;
-  let _ = read_key () in
-  close_graph ()
-;;
 
-let printAsTex u n p =
+let printAsTex reg n p =
   (* On récupère la liste des données qui peuvent être vues *)
   let rec obtainList = function
     | 0 -> []
-    | k -> let y = Complex.norm2 (u#row k) in
+    | k -> let y = Complex.norm2 (reg#row k) in
       if y > 0.00001 then (k,y) :: (obtainList (k - 1))
       else obtainList (k - 1)
   and max = List.fold_left (fun a b -> if snd a > snd b then a else b) (0,0.) in
-  let data = obtainList (u#rows ()) in
+  let data = obtainList (reg#rows ) in
   let max = snd (max data) in
-  let m = u#rows () in
+  let m = reg#rows in
   let s = List.fold_left begin fun s (i,y) -> 
     let x = float_of_int i *. 16. /. (float_of_int m) +. 0.01
     and y = y /. max *. 2. in
+
 open Log;;
 open Printf;;
+
+(* Pi *)
+let pi = acos (-1.);;
 (* Quelques fonctions sur les complexes {{{1 *)
 let complex_of_float f = {
   Complex.re = f;
 let ( *! ) = Complex.mul
 let ( +! ) = Complex.add
 let ( -! ) = Complex.sub
-(* }}} *)
-let pi = acos (-1.);;
+
 let c_to_string = fun (c:Complex.t) ->
       Printf.sprintf "%.9F + %.9FI " c.Complex.re c.Complex.im
 let w n = Complex.exp (
   (complex_of_float(2. *. pi /. (float_of_int n)  ) ) *! Complex.i
 )
-
+(* }}} *)
+(* Module Matrix pour les complexes {{{1 *)
 module ComplexMatrix = MatrixFactory.Make( 
   struct
     type t = Complex.t
   end
 );;
 open ComplexMatrix;;
+(* }}} *)
 
 
 (* Register Class {{{1 *)
 exception Quant_Bad_Access of string;;
 class register n = object(self)
+  inherit vector ~rows:(1 lsl n) () as super
   val size = n
-  val state = new vector ~rows:(1 lsl n) () (* Equivalent à 2^n *)
   method size () = size
-  method state () = state
-  method nbStates () = 1 lsl n
-  method norm () = state#norm ()
-  method normalize () = state#normalize ()
+  method nbStates = self#rows
   method setState s = 
-    if Array.length s > state#rows () then raise (Quant_Bad_Access "setState")
+    if Array.length s > self#nbStates then raise (Quant_Bad_Access "setState")
     else begin
       for i = 0 to Array.length s - 1 do
-        state#rowset (i + 1) s.(i)
+        self#rowset (i + 1) s.(i)
       done;
     end
-  method setStateProbability s v = state#rowset (s+1) v
+  method setStateProbability s v = self#rowset (s+1) v
   method getStateProbability s = 
-    if s > state#rows () then raise (Quant_Bad_Access "getStateProbability")
-    else state#row (s+1)
+    if s > self#nbStates then raise (Quant_Bad_Access "getStateProbability")
+    else self#row (s+1)
   method dump () =
     printf "Le registre est dans l'état (norme %f):\n" (self#norm () );
-    for i = 1 to state#rows () do
-      printf "État %i : %s.\n" (i-1) (c_to_string (state#row i));
+    for i = 1 to self#rows do
+      printf "État %i : %s.\n" (i-1) (c_to_string (self#row i));
     done
   (* Met les n premiers états dans un état de superposition uniforme *)
   method setUniformSuperposition n =
-    if n > state#rows () then raise (Quant_Bad_Access "setUniformSuperposition")
+    if n > self#nbStates then raise (Quant_Bad_Access "setUniformSuperposition")
     else begin
       let prob = complex_of_float (sqrt(1. /. (float_of_int n))) in
       for i = 1 to n do
-        state#rowset i prob
+        self#rowset i prob
       done
     end
   (* Transformation de Fourier discrète sur les q premiers états {{{2 *)
     for a = 0 to q - 1 do
       for c = 0 to q - 1 do
         dftvals.(c) <- dftvals.(c) +! (
-          Complex.exp (
-            (complex_of_float(2. *. pi /. (float_of_int q) *. float_of_int(a * c)  ) ) *! Complex.i
-          ) *! (state#row (a + 1))
+          Complex.exp ( (
+              complex_of_float(
+                2. *. pi /. (float_of_int q) *. float_of_int(a * c)  
+              ) 
+            ) *! Complex.i
+          ) *! (self#row (a + 1))
         )
       done
     done;
     self#setState dftvals
   (* }}} *)
-  (* Transformée de Fourier rapide (car q est une puissance de 2 !!!) {{{2 *)
+  (* Transformée de Fourier rapide (q est une puissance de 2) {{{2 *)
   method fft () =
     let rec fft_aux ?(step=1) ?(start=0) () =
-      let n = state#rows () / step in
-      if n = 1 then [| state#row (start + 1) |]
+      let n = self#rows / step in
+      if n = 1 then [| self#row (start + 1) |]
       else begin
         let even = fft_aux ~step:(step * 2) ~start ()
         and odd  = fft_aux ~step:(step * 2) ~start:(start + step) () in
     and alea          = float_of_int (Random.int max_int) /. (float_of_int max_int)
     and bottom        = ref 0. 
     and top           = ref 0. in  
-    for i = 1 to state#rows () do
+    for i = 1 to self#rows do
       if not !measured then begin
-        let norm = (Complex.norm2 (state#row i)) in
+        let norm = (Complex.norm2 (self#row i)) in
         top := !top +. norm;
         if !bottom < alea && alea < !top then begin
           measured := true;
           stateMeasured := i - 1;
-          state#rowset i Complex.one
-        end else begin state#rowset i Complex.zero end;
+          self#rowset i Complex.one
+        end else begin self#rowset i Complex.zero end;
         bottom := !bottom +. norm 
-      end else state#rowset i Complex.zero
+      end else self#rowset i Complex.zero
     done;
     !stateMeasured
   (* }}} *)