10
1
mirror of https://gitlab.com/scemama/QCaml.git synced 2024-12-22 04:13:33 +01:00

[@tailcall] statements

This commit is contained in:
Anthony Scemama 2019-09-10 18:39:14 +02:00
parent 316a3df20d
commit 72307bcec8
24 changed files with 89 additions and 75 deletions

View File

@ -27,7 +27,7 @@ let make ?(index=0) contr =
let center = Cs.center contr.(0) in let center = Cs.center contr.(0) in
let rec unique_center = function let rec unique_center = function
| 0 -> true | 0 -> true
| i -> if Cs.center contr.(i) = center then unique_center (i-1) else false | i -> if Cs.center contr.(i) = center then (unique_center [@tailcall]) (i-1) else false
in in
if not (unique_center (Array.length contr - 1)) then if not (unique_center (Array.length contr - 1)) then
invalid_arg "ContractedAtomicShell.make Coordinate.t differ"; invalid_arg "ContractedAtomicShell.make Coordinate.t differ";
@ -35,7 +35,7 @@ let make ?(index=0) contr =
let ang_mom = Cs.ang_mom contr.(0) in let ang_mom = Cs.ang_mom contr.(0) in
let rec unique_angmom = function let rec unique_angmom = function
| 0 -> true | 0 -> true
| i -> if Cs.ang_mom contr.(i) = ang_mom then unique_angmom (i-1) else false | i -> if Cs.ang_mom contr.(i) = ang_mom then (unique_angmom [@tailcall]) (i-1) else false
in in
if not (unique_angmom (Array.length contr - 1)) then if not (unique_angmom (Array.length contr - 1)) then
invalid_arg "ContractedShell.make: AngularMomentum.t differ"; invalid_arg "ContractedShell.make: AngularMomentum.t differ";

View File

@ -27,7 +27,7 @@ let make ?(index=0) lc =
let center = Ps.center prim.(0) in let center = Ps.center prim.(0) in
let rec unique_center = function let rec unique_center = function
| 0 -> true | 0 -> true
| i -> if Ps.center prim.(i) = center then unique_center (i-1) else false | i -> if Ps.center prim.(i) = center then (unique_center [@tailcall]) (i-1) else false
in in
if not (unique_center (Array.length prim - 1)) then if not (unique_center (Array.length prim - 1)) then
invalid_arg "ContractedShell.make Coordinate.t differ"; invalid_arg "ContractedShell.make Coordinate.t differ";
@ -35,7 +35,7 @@ let make ?(index=0) lc =
let ang_mom = Ps.ang_mom prim.(0) in let ang_mom = Ps.ang_mom prim.(0) in
let rec unique_angmom = function let rec unique_angmom = function
| 0 -> true | 0 -> true
| i -> if Ps.ang_mom prim.(i) = ang_mom then unique_angmom (i-1) else false | i -> if Ps.ang_mom prim.(i) = ang_mom then (unique_angmom [@tailcall]) (i-1) else false
in in
if not (unique_angmom (Array.length prim - 1)) then if not (unique_angmom (Array.length prim - 1)) then
invalid_arg "ContractedShell.make: AngularMomentum.t differ"; invalid_arg "ContractedShell.make: AngularMomentum.t differ";

View File

@ -125,7 +125,7 @@ let of_contracted_shell_array ?(cutoff=Constants.epsilon) basis =
| (s_a :: rest) as l -> | (s_a :: rest) as l ->
let new_accu = let new_accu =
(List.map (fun s_b -> make ~cutoff s_a s_b) l) :: accu (List.map (fun s_b -> make ~cutoff s_a s_b) l) :: accu
in loop new_accu rest in (loop [@tailcall]) new_accu rest
in in
loop [] (List.rev (Array.to_list basis)) loop [] (List.rev (Array.to_list basis))
|> List.concat |> List.concat
@ -138,7 +138,7 @@ let equivalent x y =
let rec eqv = function let rec eqv = function
| 0 -> true | 0 -> true
| k -> if Psp.equivalent x.(k) y.(k) then | k -> if Psp.equivalent x.(k) y.(k) then
eqv (k-1) (eqv [@tailcall]) (k-1)
else false else false
in eqv (Array.length x - 1) in eqv (Array.length x - 1)
@ -153,8 +153,13 @@ let unique sp =
let rec aux accu = function let rec aux accu = function
| [] -> accu | [] -> accu
| x::rest -> | x::rest ->
try ignore @@ List.find (fun y -> equivalent x y) accu; aux accu rest let newaccu =
with Not_found -> aux (x::accu) rest try
ignore @@ List.find (fun y -> equivalent x y) accu;
accu
with Not_found -> (x::accu)
in
(aux [@tailcall]) newaccu rest
in in
aux [] sp aux [] sp

View File

@ -28,7 +28,7 @@ module Zm = struct
begin begin
result.(k) <- result.(k) *. accu; result.(k) <- result.(k) *. accu;
let new_accu = -. accu *. exp_pq in let new_accu = -. accu *. exp_pq in
aux new_accu (k+1) (l-1) (aux [@tailcall]) new_accu (k+1) (l-1)
end end
in in
let f = two_over_sq_pi *. (sqrt exp_pq) in let f = two_over_sq_pi *. (sqrt exp_pq) in

View File

@ -167,7 +167,7 @@ let rec hvrr angMom_a angMom_b angMom_c angMom_d
in in
let rec aux accu = function let rec aux accu = function
| 0 -> accu +. coef_g.(0) *. x.(0) *. y.(0) *. z.(0) | 0 -> accu +. coef_g.(0) *. x.(0) *. y.(0) *. z.(0)
| i -> aux (accu +. coef_g.(i) *. x.(i) *. y.(i) *. z.(i)) (i-1) | i -> (aux [@tailcall]) (accu +. coef_g.(i) *. x.(i) *. y.(i) *. z.(i)) (i-1)
in in
aux 0. (Array.length x - 1) aux 0. (Array.length x - 1)

View File

@ -156,15 +156,15 @@ let create_matrix_arbitrary f det_space =
| (js, j_beta)::r_singles -> | (js, j_beta)::r_singles ->
begin begin
match compare js j_dets.(j') with match compare js j_dets.(j') with
| -1 -> aux r_singles j' | -1 -> (aux [@tailcall]) r_singles j'
| 0 -> | 0 ->
let kj = let kj =
Determinant.of_spindeterminants j_alfa j_beta Determinant.of_spindeterminants j_alfa j_beta
in (update in (update
(index_start.(i) + i') (index_start.(j) + j' + 1) (index_start.(i) + i') (index_start.(j) + j' + 1)
1 (Determinant.degree_beta ki kj) ki kj; 1 (Determinant.degree_beta ki kj) ki kj;
aux r_singles (j'+1);) (aux [@tailcall]) r_singles (j'+1);)
| 1 -> if (j' < Array.length j_dets) then aux singles (j'+1) | 1 -> if (j' < Array.length j_dets) then (aux [@tailcall]) singles (j'+1)
| _ -> assert false | _ -> assert false
end end
in aux singles 0 in aux singles 0
@ -180,15 +180,15 @@ let create_matrix_arbitrary f det_space =
| (js, j_beta)::r_doubles -> | (js, j_beta)::r_doubles ->
begin begin
match compare js j_dets.(j') with match compare js j_dets.(j') with
| -1 -> aux r_doubles j' | -1 -> (aux [@tailcall]) r_doubles j'
| 0 -> | 0 ->
let kj = let kj =
Determinant.of_spindeterminants j_alfa j_beta Determinant.of_spindeterminants j_alfa j_beta
in (update in (update
(index_start.(i) + i') (index_start.(j) + j' + 1) (index_start.(i) + i') (index_start.(j) + j' + 1)
0 (Determinant.degree_beta ki kj) ki kj; 0 (Determinant.degree_beta ki kj) ki kj;
aux r_doubles (j'+1);) (aux [@tailcall]) r_doubles (j'+1);)
| 1 -> if (j' < Array.length j_dets) then aux doubles (j'+1) | 1 -> if (j' < Array.length j_dets) then (aux [@tailcall]) doubles (j'+1)
| _ -> assert false | _ -> assert false
end end
in aux doubles 0 in aux doubles 0

View File

@ -41,7 +41,7 @@ let non_zero integrals degree_a degree_b ki kj =
let new_accu = let new_accu =
List.fold_left (fun accu j -> accu +. two_e i j i j spin spin) accu rest List.fold_left (fun accu j -> accu +. two_e i j i j spin spin) accu rest
in in
aux_same spin new_accu rest (aux_same [@tailcall]) spin new_accu rest
in in
let rec aux_opposite accu other = function let rec aux_opposite accu other = function
| [] -> accu | [] -> accu
@ -49,7 +49,7 @@ let non_zero integrals degree_a degree_b ki kj =
let new_accu = let new_accu =
List.fold_left (fun accu j -> accu +. two_e i j i j Spin.Alfa Spin.Beta) accu other List.fold_left (fun accu j -> accu +. two_e i j i j Spin.Alfa Spin.Beta) accu other
in in
aux_opposite new_accu other rest (aux_opposite [@tailcall]) new_accu other rest
in in
(aux_same Spin.Alfa 0. mo_a) +. (aux_same Spin.Beta 0. mo_b) +. (aux_same Spin.Alfa 0. mo_a) +. (aux_same Spin.Beta 0. mo_b) +.
(aux_opposite 0. mo_a mo_b) (aux_opposite 0. mo_a mo_b)

View File

@ -28,7 +28,7 @@ let non_zero integrals degree_a degree_b ki kj =
let new_accu = let new_accu =
List.fold_left (fun accu j -> accu +. two_e i j i j spin spin) accu rest List.fold_left (fun accu j -> accu +. two_e i j i j spin spin) accu rest
in in
aux_same spin new_accu rest (aux_same [@tailcall]) spin new_accu rest
in in
let rec aux_opposite accu other = function let rec aux_opposite accu other = function
| [] -> accu | [] -> accu
@ -36,7 +36,7 @@ let non_zero integrals degree_a degree_b ki kj =
let new_accu = let new_accu =
List.fold_left (fun accu j -> accu +. two_e i j i j Spin.Alfa Spin.Beta) accu other List.fold_left (fun accu j -> accu +. two_e i j i j Spin.Alfa Spin.Beta) accu other
in in
aux_opposite new_accu other rest (aux_opposite [@tailcall]) new_accu other rest
in in
(aux_same Spin.Alfa 0. mo_a) +. (aux_same Spin.Beta 0. mo_b) +. (aux_same Spin.Alfa 0. mo_a) +. (aux_same Spin.Beta 0. mo_b) +.
(aux_opposite 0. mo_a mo_b) (aux_opposite 0. mo_a mo_b)

View File

@ -135,7 +135,7 @@ let determinant t i =
let index_start = a.index_start in let index_start = a.index_start in
let rec loop i_alfa = let rec loop i_alfa =
if index_start.(i_alfa) <= i then if index_start.(i_alfa) <= i then
loop (i_alfa+1) (loop [@tailcall]) (i_alfa+1)
else i_alfa else i_alfa
in loop 0 in loop 0
in in

View File

@ -130,9 +130,9 @@ let p12 det_space =
(Spindeterminant.of_bitstring @@ (Spindeterminant.of_bitstring @@
Bitstring.(logor a (logand not_aux_mask beta)) Bitstring.(logor a (logand not_aux_mask beta))
) ) ) )
(*
| 1, 0 | 1, 0
| 0, 1 -> Some (Determinant.negate_phase k) | 0, 1 -> Some (Determinant.negate_phase k)
(*
| 0, 1 -> Some (Determinant.vac 1) | 0, 1 -> Some (Determinant.vac 1)
*) *)
| _ -> None | _ -> None

View File

@ -109,17 +109,17 @@ let of_list n l =
|> List.fold_left (fun accu p -> creation p accu) (vac n) |> List.fold_left (fun accu p -> creation p accu) (vac n)
let rec to_list = function let to_list = function
| None -> [] | None -> []
| Some spindet -> | Some spindet ->
let rec aux accu z = let rec aux accu z =
if not (Bitstring.is_zero z) then if not (Bitstring.is_zero z) then
let element = ((Bitstring.trailing_zeros z)+1) in let element = ((Bitstring.trailing_zeros z)+1) in
aux (element::accu) (Bitstring.logand z (Bitstring.minus_one z) ) (aux [@tailcall]) (element::accu) (Bitstring.logand z (Bitstring.minus_one z) )
else List.rev accu else List.rev accu
in aux [] spindet.bitstring in aux [] spindet.bitstring
let rec to_array t = let to_array t =
to_list t to_list t
|> Array.of_list |> Array.of_list

View File

@ -188,7 +188,7 @@ let pp_mo ?(start=1) ?finish ppf t =
~print_foot:false ~print_foot:false
() ) (lacpy ~ac:first ~n:(min 5 (cols-first+1)) (t.mo_coef)) ; () ) (lacpy ~ac:first ~n:(min 5 (cols-first+1)) (t.mo_coef)) ;
Format.fprintf ppf "@]@;@;@]"; Format.fprintf ppf "@]@;@;@]";
aux (first+5) (aux [@tailcall]) (first+5)
end end
in in
aux start aux start

View File

@ -52,7 +52,7 @@ let run_parallel_server ~comm ~ordered stream =
let rec wait_and_receive () = let rec wait_and_receive () =
match Mpi.iprobe Mpi.any_source Mpi.any_tag comm with match Mpi.iprobe Mpi.any_source Mpi.any_tag comm with
| Some _ -> Mpi.receive_status Mpi.any_source Mpi.any_tag comm | Some _ -> Mpi.receive_status Mpi.any_source Mpi.any_tag comm
| None -> (Unix.sleepf 0.001 ; wait_and_receive ()) | None -> (Unix.sleepf 0.001 ; (wait_and_receive [@tailcall]) ())
in in
wait_and_receive () wait_and_receive ()
in in
@ -158,7 +158,7 @@ let run_parallel_server ~comm ~ordered stream =
| None -> None | None -> None
| Some (task_id, result) -> | Some (task_id, result) ->
if task_id = i then Some result if task_id = i then Some result
else (Hashtbl.add buffer task_id result; loop () ) else (Hashtbl.add buffer task_id result; (loop [@tailcall]) () )
in loop () in loop ()
end end
@ -204,7 +204,7 @@ let run_parallel_client ~comm f =
debug @@ Printf.sprintf "Before send task_id %d" task_id ; debug @@ Printf.sprintf "Before send task_id %d" task_id ;
Mpi.send (Some (task_id, result)) 0 0 comm; Mpi.send (Some (task_id, result)) 0 0 comm;
debug @@ Printf.sprintf "After send task_id %d" task_id ; debug @@ Printf.sprintf "After send task_id %d" task_id ;
run () (run [@tailcall]) ()
end end
in in
run (); run ();

View File

@ -1,7 +1,7 @@
(* Single process function *) (* Single process function *)
let run_sequential f stream = let run_sequential f stream =
let rec next _ = let next _ =
try try
let task = Stream.next stream in let task = Stream.next stream in
Some (f task) Some (f task)

View File

@ -593,9 +593,7 @@ let make
| Some result -> Some result | Some result -> Some result
| None -> | None ->
begin begin
let data = let data = iteration (n-1) in
(iteration (n-1))
in
match data with match data with
| None -> None | None -> None
| Some data -> | Some data ->

View File

@ -84,7 +84,7 @@ let zkey_array a =
match y with match y with
| 0 -> (create_z xyz)::accu | 0 -> (create_z xyz)::accu
| i -> let ynew = y-1 in | i -> let ynew = y-1 in
create_y ( (create_z xyz)::accu) (Powers.of_int_tuple (x,ynew,z)) (create_y [@tailcall]) ( (create_z xyz)::accu) (Powers.of_int_tuple (x,ynew,z))
in in
let rec create_x accu xyz = let rec create_x accu xyz =
let { x ; y ; z } = xyz in let { x ; y ; z } = xyz in
@ -92,7 +92,7 @@ let zkey_array a =
| 0 -> (create_y [] xyz)@accu | 0 -> (create_y [] xyz)@accu
| i -> let xnew = x-1 in | i -> let xnew = x-1 in
let ynew = l-xnew in let ynew = l-xnew in
create_x ((create_y [] xyz)@accu) (Powers.of_int_tuple (xnew, ynew, z)) (create_x [@tailcall]) ((create_y [] xyz)@accu) (Powers.of_int_tuple (xnew, ynew, z))
in in
create_x [] (Powers.of_int_tuple (l,0,0)) create_x [] (Powers.of_int_tuple (l,0,0))
|> List.rev |> List.rev

View File

@ -164,7 +164,8 @@ let rec to_list ?(accu=[]) = function
| t -> let newlist = | t -> let newlist =
(trailing_zeros t + 1)::accu (trailing_zeros t + 1)::accu
in in
to_list ~accu:newlist (logand t (minus_one t)) logand t @@ minus_one t
|> (to_list [@tailcall]) ~accu:newlist
(** [permtutations m n] generates the list of all possible [n]-bit (** [permtutations m n] generates the list of all possible [n]-bit
@ -186,7 +187,7 @@ let permtutations m n =
let t = (logor u (minus_one u)) in let t = (logor u (minus_one u)) in
let t' = plus_one t in let t' = plus_one t in
let t'' = shift_right (minus_one (logand (lognot t) t')) (trailing_zeros u + 1) in let t'' = shift_right (minus_one (logand (lognot t) t')) (trailing_zeros u + 1) in
aux (k-1) (logor t' t'') (u :: rest) (aux [@tailcall]) (k-1) (logor t' t'') (u :: rest)
in in
aux (Util.binom n m) (minus_one (shift_left_one n m)) [] aux (Util.binom n m) (minus_one (shift_left_one n m)) []

View File

@ -96,9 +96,9 @@ let pivoted_ldl threshold m_A =
if i > n then if i > n then
pos pos
else if v_D.{i} > value then else if v_D.{i} > value then
aux i v_D.{i} (i+1) (aux [@tailcall]) i v_D.{i} (i+1)
else else
aux pos value (i+1) (aux [@tailcall]) pos value (i+1)
in in
aux i v.{i} (i+1) aux i v.{i} (i+1)
in in

View File

@ -45,7 +45,7 @@ let next diis =
a.{m+1,m+1} <- 0.; a.{m+1,m+1} <- 0.;
ignore @@ lacpy ~b:a (gemm ~transa:`T ~m ~n:m e e); ignore @@ lacpy ~b:a (gemm ~transa:`T ~m ~n:m e e);
if m > 1 && sycon (lacpy a) > 1.e-14 then if m > 1 && sycon (lacpy a) > 1.e-14 then
aux (m-1) (aux [@tailcall]) (m-1)
else a else a
in in
aux diis.m aux diis.m

View File

@ -152,7 +152,7 @@ let make
else else
u_next, w_next, (iter+1), macro u_next, w_next, (iter+1), macro
in in
iteration u_next u_proposed w_next iter macro (iteration [@tailcall]) u_next u_proposed w_next iter macro
else else
(m_new_U |> pick_new |> Mat.of_col_vecs_list), lambda (m_new_U |> pick_new |> Mat.of_col_vecs_list), lambda

View File

@ -315,7 +315,7 @@ let to_stream d =
and k = ref 1 and k = ref 1
and l = ref 1 and l = ref 1
in in
let rec f_dense _ = let f_dense _ =
incr i; incr i;
if !i > !k then begin if !i > !k then begin
i := 1; i := 1;
@ -362,7 +362,7 @@ let of_file ~size ~sparsity filename =
with End_of_file -> None with End_of_file -> None
in in
match result with match result with
| Some () -> read_line () | Some () -> (read_line [@tailcall]) ()
| None -> () | None -> ()
in in
read_line (); read_line ();
@ -381,7 +381,7 @@ let to_list data =
in in
match d with match d with
| None -> List.rev accu | None -> List.rev accu
| Some d -> append (d :: accu) | Some d -> (append [@tailcall]) (d :: accu)
in in
append [] append []
@ -415,7 +415,7 @@ t
| Some {i_r1 ; j_r2 ; k_r1 ; l_r2 ; value} -> | Some {i_r1 ; j_r2 ; k_r1 ; l_r2 ; value} ->
set_phys t i_r1 j_r2 k_r1 l_r2 value set_phys t i_r1 j_r2 k_r1 l_r2 value
| None -> () ) buffer; | None -> () ) buffer;
iterate () (iterate [@tailcall]) ()
end end
in iterate (); in iterate ();
t t

View File

@ -566,7 +566,7 @@ let ax_eq_b_conj_grad ?x a b =
let p = let p =
Vector.add r (Vector.scale (rsnew /. (rsold +. 1.e-12) ) p) Vector.add r (Vector.scale (rsnew /. (rsold +. 1.e-12) ) p)
in in
aux rsnew r p x (i-1) (aux [@tailcall]) rsnew r p x (i-1)
in in
aux rsold r p x (Vector.dim b *2) aux rsold r p x (Vector.dim b *2)

View File

@ -68,7 +68,7 @@ let incomplete_gamma ~alpha x =
else if prev = res then res else if prev = res then res
else else
let term = term *. x /. (a +. k) in let term = term *. x /. (a +. k) in
pg_loop res (res +. term) term (k +. 1.) (pg_loop [@tailcall]) res (res +. term) term (k +. 1.)
in in
let r0 = exp (a *. log x -. x -. loggamma_a) *. a_inv in let r0 = exp (a *. log x -. x -. loggamma_a) *. a_inv in
pg_loop min_float r0 r0 1. pg_loop min_float r0 r0 1.
@ -87,7 +87,7 @@ let incomplete_gamma ~alpha x =
in in
let w = w *. kma in let w = w *. kma in
let prev, res = res, res +. w /. (la *. lb) in let prev, res = res, res +. w /. (la *. lb) in
qg_loop prev res la lb w (k +. 1.) (qg_loop [@tailcall]) prev res la lb w (k +. 1.)
in in
let w = exp (a *. log x -. x -. loggamma_a) in let w = exp (a *. log x -. x -. loggamma_a) in
let lb = (1. +. x -. a) in let lb = (1. +. x -. a) in
@ -101,12 +101,12 @@ let incomplete_gamma ~alpha x =
let fact_memo = let fact_memo =
let rec aux accu_l accu = function let rec aux accu_l accu = function
| 0 -> aux [1.] 1. 1 | 0 -> (aux [@tailcall]) [1.] 1. 1
| i when (i = factmax) -> | i when (i = factmax) ->
let x = (float_of_int factmax) *. accu in let x = (float_of_int factmax) *. accu in
List.rev (x::accu_l) List.rev (x::accu_l)
| i -> let x = (float_of_int i) *. accu in | i -> let x = (float_of_int i) *. accu in
aux (x::accu_l) x (i+1) (aux [@tailcall]) (x::accu_l) x (i+1)
in in
aux [] 0. 0 aux [] 0. 0
|> Array.of_list |> Array.of_list
@ -141,7 +141,7 @@ let rec pow a = function
| n when n > 0 -> | n when n > 0 ->
let b = pow a (n / 2) in let b = pow a (n / 2) in
b *. b *. (if n mod 2 = 0 then 1. else a) b *. b *. (if n mod 2 = 0 then 1. else a)
| n when n < 0 -> pow (1./.a) (-n) | n when n < 0 -> (pow [@tailcall]) (1./.a) (-n)
| _ -> assert false | _ -> assert false
@ -212,7 +212,7 @@ let list_range first last =
if last < first then [] else if last < first then [] else
let rec aux accu = function let rec aux accu = function
| 0 -> first :: accu | 0 -> first :: accu
| i -> aux ( (first+i)::accu ) (i-1) | i -> (aux [@tailcall]) ( (first+i)::accu ) (i-1)
in in
aux [] (last-first) aux [] (last-first)
@ -225,8 +225,8 @@ let list_pack n l =
List.rev ((List.rev accu1) :: accu2) List.rev ((List.rev accu1) :: accu2)
| a :: rest -> | a :: rest ->
match i with match i with
| 0 -> aux (n-1) [] ((List.rev (a::accu1)) :: accu2) rest | 0 -> (aux [@tailcall]) (n-1) [] ((List.rev (a::accu1)) :: accu2) rest
| _ -> aux (i-1) (a::accu1) accu2 rest | _ -> (aux [@tailcall]) (i-1) (a::accu1) accu2 rest
in in
aux (n-1) [] [] l aux (n-1) [] [] l
@ -243,18 +243,28 @@ let stream_range first last =
let stream_to_list stream = let stream_to_list stream =
let rec aux accu = let rec aux accu =
try aux (Stream.next stream :: accu) with let new_accu =
Stream.Failure -> List.rev accu try
in aux [] Some (Stream.next stream :: accu)
with Stream.Failure -> None
in
match new_accu with
| Some new_accu -> (aux [@tailcall]) new_accu
| None -> accu
in List.rev @@ aux []
let stream_fold f init stream = let stream_fold f init stream =
let rec aux accu = let rec aux accu =
try let new_accu =
let element = Stream.next stream in try
let new_accu = f accu element in let element = Stream.next stream in
aux new_accu Some (f accu element)
with Stream.Failure -> accu with Stream.Failure -> None
in
match new_accu with
| Some new_accu -> (aux [@tailcall]) new_accu
| None -> accu
in in
aux init aux init
@ -335,7 +345,7 @@ let bit_permtutations m n =
let t = Z.(logor u (u-one)) in let t = Z.(logor u (u-one)) in
let t' = Z.(t+one) in let t' = Z.(t+one) in
let t'' = Z.(shift_right ((logand (lognot t) t') - one)) (Z.trailing_zeros u + 1) in let t'' = Z.(shift_right ((logand (lognot t) t') - one)) (Z.trailing_zeros u + 1) in
aux (k-1) (Z.logor t' t'') (u :: rest) (aux [@tailcall]) (k-1) (Z.logor t' t'') (u :: rest)
in in
aux (binom n m) Z.(shift_left one m - one) [] aux (binom n m) Z.(shift_left one m - one) []
@ -377,7 +387,7 @@ let pp_matrix ppf m =
~print_right:false ~print_right:false
~print_foot:false ~print_foot:false
() ) (lacpy ~ac:first ~n:(min 5 (cols-first+1)) m); () ) (lacpy ~ac:first ~n:(min 5 (cols-first+1)) m);
aux (first+5) last (aux [@tailcall]) (first+5) last
end end
in in
aux 1 cols aux 1 cols
@ -407,7 +417,7 @@ let matrix_of_file filename =
with End_of_file -> None with End_of_file -> None
in in
match result with match result with
| Some accu -> read_line accu | Some accu -> (read_line [@tailcall]) accu
| None -> List.rev accu | None -> List.rev accu
in in
let data = read_line [] in let data = read_line [] in

View File

@ -60,9 +60,9 @@ let sparse_of_dense ?(threshold=epsilon) = function
| i -> | i ->
let x = v.{i} in let x = v.{i} in
if abs_float x < threshold then if abs_float x < threshold then
aux accu (i-1) (aux [@tailcall]) accu (i-1)
else else
aux ({index=i ; value=x}::accu) (i-1) (aux [@tailcall]) ({index=i ; value=x}::accu) (i-1)
in in
let n = Vec.dim v in let n = Vec.dim v in
Sparse { n ; v=aux [] n } Sparse { n ; v=aux [] n }
@ -153,14 +153,14 @@ let axpy ?(threshold=epsilon) ?(alpha=1.) x y =
{index=i ; value=z} :: accu {index=i ; value=z} :: accu
else else
accu accu
in aux new_accu r1 v2 in (aux [@tailcall]) new_accu r1 v2
| 1 -> | 1 ->
let new_accu = let new_accu =
if abs_float y > threshold then if abs_float y > threshold then
{index=j ; value=y} :: accu {index=j ; value=y} :: accu
else else
accu accu
in aux new_accu v1 r2 in (aux [@tailcall]) new_accu v1 r2
| 0 -> | 0 ->
let z = alpha *. x +. y in let z = alpha *. x +. y in
let new_accu = let new_accu =
@ -168,11 +168,11 @@ let axpy ?(threshold=epsilon) ?(alpha=1.) x y =
{index=i ; value=z} :: accu {index=i ; value=z} :: accu
else else
accu accu
in aux new_accu r1 r2 in (aux [@tailcall]) new_accu r1 r2
| _ -> assert false | _ -> assert false
end end
| ({index=i ; value=x}::r1), [] -> aux ({index=i ; value=alpha *. x}::accu) r1 [] | ({index=i ; value=x}::r1), [] -> (aux [@tailcall]) ({index=i ; value=alpha *. x}::accu) r1 []
| [] , ({index=j ; value=y}::r2) -> aux ({index=j ; value=y}::accu) [] r2 | [] , ({index=j ; value=y}::r2) -> (aux [@tailcall]) ({index=j ; value=y}::accu) [] r2
| [] , [] -> {n ; v=List.rev accu} | [] , [] -> {n ; v=List.rev accu}
in in
Sparse (aux [] v v') Sparse (aux [] v v')
@ -213,9 +213,9 @@ let dot v v' =
| (({index=i ; value=v1} :: r1) as s1), (({index=j ; value=v2}::r2) as s2)-> | (({index=i ; value=v1} :: r1) as s1), (({index=j ; value=v2}::r2) as s2)->
begin begin
match compare i j with match compare i j with
| -1 -> aux accu (r1, s2) | -1 -> (aux [@tailcall]) accu (r1, s2)
| 1 -> aux accu (s1, r2) | 1 -> (aux [@tailcall]) accu (s1, r2)
| 0 -> aux (accu +. v1 *. v2) (r1, r2) | 0 -> (aux [@tailcall]) (accu +. v1 *. v2) (r1, r2)
| _ -> assert false | _ -> assert false
end end
| ([], _ ) | ([], _ )