mirror of
https://gitlab.com/scemama/QCaml.git
synced 2024-06-30 00:44:18 +02:00
61 lines
983 B
OCaml
61 lines
983 B
OCaml
|
open Lacaml.D
|
||
|
open Util
|
||
|
|
||
|
type t =
|
||
|
{
|
||
|
p : Vec.t list;
|
||
|
e : Vec.t list;
|
||
|
m : int;
|
||
|
mmax : int;
|
||
|
}
|
||
|
|
||
|
let make ?mmax:(mmax=15) () =
|
||
|
assert (mmax > 1);
|
||
|
{
|
||
|
p = [];
|
||
|
e = [];
|
||
|
m = 0 ;
|
||
|
mmax;
|
||
|
}
|
||
|
|
||
|
|
||
|
let append ~p ~e diis =
|
||
|
let update v l =
|
||
|
if diis.m < diis.mmax then
|
||
|
v :: l
|
||
|
else
|
||
|
match List.rev l with
|
||
|
| [] -> assert false
|
||
|
| _ :: rest -> v :: List.rev rest
|
||
|
in
|
||
|
{ diis with
|
||
|
p = update p diis.p;
|
||
|
e = update e diis.e;
|
||
|
m = min diis.mmax (diis.m+1);
|
||
|
}
|
||
|
|
||
|
|
||
|
let next diis =
|
||
|
let e = Mat.of_col_vecs_list diis.e
|
||
|
and p = Mat.of_col_vecs_list diis.p
|
||
|
in
|
||
|
let a =
|
||
|
let rec aux m =
|
||
|
let a = Mat.make (m+1) (m+1) 1. in
|
||
|
a.{m+1,m+1} <- 0.;
|
||
|
ignore @@ lacpy ~b:a (gemm ~transa:`T ~m ~n:m e e);
|
||
|
if sycon (lacpy a) > 1.e-10 then a
|
||
|
else aux (m-1)
|
||
|
in
|
||
|
aux diis.m
|
||
|
in
|
||
|
let m = Mat.dim1 a - 1 in
|
||
|
let c = Mat.make0 (m+1) 1 in
|
||
|
c.{m+1,1} <- 1.;
|
||
|
sysv a c;
|
||
|
gemm p c ~k:m
|
||
|
|> Mat.as_vec
|
||
|
|
||
|
|
||
|
|