Work : changement boucle pour stabiliser le convergence

This commit is contained in:
Yann Damour 2020-05-22 09:27:57 +02:00
parent e29ba94200
commit 21155a4af8
3 changed files with 254 additions and 209 deletions

View File

@ -14,6 +14,126 @@
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"(*\n",
"\n",
"(* Localisation de Edminstion ou de Boys *)\n",
"\n",
"(* Calcul de la nouvelle matrice des coefficient après n rotation d'orbitales *)\n",
"let rec localisation m_C methode epsilon n prev_critere_D cc=\n",
"\n",
" Printf.printf \"%i\\n%!\" n;\n",
"\n",
" (*Util.debug_matrix \"m_C\" m_C;*)\n",
"\n",
"if n == 0 \n",
" then m_C\n",
" else\n",
" \n",
" (* Fonction de calcul de la nouvelle matrice de coef après rotation d'un angle alpha *)\n",
" let new_m_C m_C methode =\n",
" \n",
" (* Fonction de pattern matching en fonction de la méthode *)\n",
" let alphad = m_alpha_d methode m_C \n",
" in\n",
" \n",
" (* D critère à maximiser *)\n",
" let critere_D = alphad.d \n",
" in\n",
" \n",
" Printf.printf \"%f\\n%!\" critere_D;\n",
" \n",
" (* Matrice des alphas *)\n",
" let m_alpha = alphad.m_alpha\n",
" in\n",
" let norme_alpha = norme m_alpha\n",
" in\n",
" \n",
" Printf.printf \"%f\\n%!\" norme_alpha;\n",
" \n",
" (*Util.debug_matrix \"m_alpha\" m_alpha;*)\n",
"\n",
" (* alphaij contient le alpha max ainsi que ses indices i et j *)\n",
" let n_rec_alpha = 10 (* Nombre ditération max pour réduire les valeurs de alpha *)\n",
" in\n",
" let alphaij = new_m_alpha m_alpha m_C n_rec_alpha \n",
" in\n",
"\n",
" (* Valeur de alpha max après calcul *) (* Epsilon = Pas <1. , 1. -> normal, sinon Pas plus petit *)\n",
" let alpha = (alphaij.alpha_max) *. epsilon \n",
" in\n",
"\n",
" (*Printf.printf \"%f\\n%!\" alpha;*)\n",
" \n",
" (* Indice i et j du alpha max après calcul *)\n",
" let indice_i = alphaij.indice_ii \n",
" in\n",
" let indice_j = alphaij.indice_jj \n",
" in\n",
"\n",
" (*Printf.printf \"%i %i\\n%!\" indice_i indice_j;*)\n",
" \n",
" (* Matrice de rotation *)\n",
" let m_R = f_R alpha \n",
" in\n",
"\n",
" (*Util.debug_matrix \"m_R\" m_R;*)\n",
"\n",
" (* Matrice qui va subir la rotation *)\n",
" let m_Ksi = f_Ksi indice_i indice_j m_C \n",
" in\n",
"\n",
" (*Util.debug_matrix \"m_Ksi\" m_Ksi;*)\n",
"\n",
" (* Matrice ayant subit la rotation *)\n",
" let m_Ksi_tilde = f_Ksi_tilde m_R m_Ksi m_C \n",
" in\n",
"\n",
" (*Util.debug_matrix \"m_Ksi_tilde\" m_Ksi_tilde;*)\n",
"\n",
" (* Matrice pour supprimerles coef des orbitales i et j dans la matrice des coef *)\n",
" let m_Psi = f_k m_Ksi indice_i indice_j m_C\n",
" in\n",
"\n",
" (*Util.debug_matrix \"m_Psi\" m_Psi;*)\n",
"\n",
" (* Matrice pour ajouter les coef des orbitales i~ et j~ dans la matrice des coef *)\n",
" let m_Psi_tilde = f_k m_Ksi_tilde indice_i indice_j m_C \n",
" in\n",
"\n",
" (*Util.debug_matrix \"m_Psi_tilde\" m_Psi_tilde;*)\n",
"\n",
" (* Matrice avec les coef des orbitales i et j remplacés par 0 *)\n",
" let m_interm = f_interm m_C m_Psi \n",
" in\n",
" \n",
" (*Util.debug_matrix \"m_interm\" m_interm;*)\n",
" \n",
" (* Matrice après rotation *)\n",
" ( Mat.add m_Psi_tilde m_interm, critere_D)\n",
" \n",
" in\n",
" let m_new_m_C , critere_D = new_m_C m_C methode \n",
" in\n",
" let diff = prev_critere_D -. critere_D\n",
"\n",
"in\n",
"\n",
"(*Util.debug_matrix \"new_alpha_m\" (f_alpha m_C);*)\n",
"(*Util.debug_matrix \"m_new_m_C\" m_new_m_C;*)\n",
"\n",
"if diff**2. < cc**2.\n",
" then m_new_m_C\n",
" else\n",
"localisation m_new_m_C methode epsilon (n-1) critere_D cc;;\n",
"*)"
]
},
{
"cell_type": "code",
"execution_count": null,

View File

@ -1813,38 +1813,19 @@
"(* Localisation de Edminstion ou de Boys *)\n",
"\n",
"(* Calcul de la nouvelle matrice des coefficient après n rotation d'orbitales *)\n",
"let rec localisation m_C methode epsilon n prev_critere_D cc=\n",
"let rec localisation m_C methode epsilon n prev_critere_D prev_m_alpha cc max_D=\n",
"\n",
" Printf.printf \"%i\\n%!\" n;\n",
"\n",
" Util.debug_matrix \"m_C\" m_C;\n",
" (*Printf.printf \"%i\\n%!\" n;*)\n",
" (*Printf.printf \"%f\\n%!\" epsilon;*)\n",
" (*Util.debug_matrix \"m_C\" m_C;*)\n",
" (*Util.debug_matrix \"new_alpha_m\" prev_m_alpha;*)\n",
"\n",
"if n == 0 \n",
" then m_C\n",
" else\n",
" \n",
"\n",
" (* Fonction de calcul de la nouvelle matrice de coef après rotation d'un angle alpha *)\n",
" let new_m_C m_C methode =\n",
" \n",
" (* Fonction de pattern matching en fonction de la méthode *)\n",
" let alphad = m_alpha_d methode m_C \n",
" in\n",
" \n",
" (* D critère à maximiser *)\n",
" let critere_D = alphad.d \n",
" in\n",
" \n",
" Printf.printf \"%f\\n%!\" critere_D;\n",
" \n",
" (* Matrice des alphas *)\n",
" let m_alpha = alphad.m_alpha\n",
" in\n",
" (*let norme_alpha = norme m_alpha\n",
" in*)\n",
" (*Util.debug_matrix \"new_alpha_m\" m_alpha;*)\n",
" (*Printf.printf \"%f\\n%!\" norme_alpha;*)\n",
" \n",
" (*Util.debug_matrix \"m_alpha\" m_alpha;*)\n",
" let new_m_C m_C methode m_alpha epsilon =\n",
"\n",
" (* alphaij contient le alpha max ainsi que ses indices i et j *)\n",
" let n_rec_alpha = 10 (* Nombre ditération max pour réduire les valeurs de alpha *)\n",
@ -1857,7 +1838,7 @@
" in\n",
"\n",
" (*Printf.printf \"%f\\n%!\" alpha;*)\n",
" \n",
"\n",
" (* Indice i et j du alpha max après calcul *)\n",
" let indice_i = alphaij.indice_ii \n",
" in\n",
@ -1865,12 +1846,12 @@
" in\n",
"\n",
" (*Printf.printf \"%i %i\\n%!\" indice_i indice_j;*)\n",
" \n",
"\n",
" (* Matrice de rotation *)\n",
" let m_R = f_R alpha \n",
" in\n",
"\n",
" (*Util.debug_matrix \"m_R\" m_R;*)\n",
" (*Util.debug_matrix \"m_R\" m_R;*)\n",
"\n",
" (* Matrice qui va subir la rotation *)\n",
" let m_Ksi = f_Ksi indice_i indice_j m_C \n",
@ -1898,27 +1879,66 @@
"\n",
" (* Matrice avec les coef des orbitales i et j remplacés par 0 *)\n",
" let m_interm = f_interm m_C m_Psi \n",
" in\n",
" \n",
" (*Util.debug_matrix \"m_interm\" m_interm;*)\n",
" \n",
" (* Matrice après rotation *)\n",
" ( Mat.add m_Psi_tilde m_interm, critere_D)\n",
" \n",
" in\n",
" let m_new_m_C , critere_D = new_m_C m_C methode \n",
" in\n",
" let diff = prev_critere_D -. critere_D\n",
" in\n",
"\n",
"in\n",
" (*Util.debug_matrix \"m_interm\" m_interm;*)\n",
"\n",
"(*Util.debug_matrix \"new_alpha_m\" (f_alpha m_C);*)\n",
" (* Matrice après rotation *)\n",
" (Mat.add m_Psi_tilde m_interm, alpha)\n",
"\n",
" in\n",
" let m_new_m_C, alpha_max = new_m_C m_C methode prev_m_alpha epsilon\n",
" in\n",
"\n",
" (* Fonction de pattern matching en fonction de la méthode *)\n",
" let alphad = m_alpha_d methode m_new_m_C\n",
" in\n",
" \n",
" (* Matrice des alphas *)\n",
" let m_alpha = alphad.m_alpha\n",
" in\n",
" \n",
" (* Critères possibles de localisation -> norme_alpha, moyenne_alpha, alpha, diff *)\n",
" \n",
" (* Norme de m_alpha *)\n",
" let norme_alpha = norme m_alpha\n",
" in\n",
" let moyenne_alpha = norme_alpha /. (float_of_int((Mat.dim1 m_C)* (Mat.dim2 m_C)))\n",
" in\n",
" (* Valeur du alpha_max *)\n",
" let alpha = alpha_max /. epsilon\n",
" in\n",
" (* D critère à maximiser *)\n",
" let critere_D = alphad.d \n",
" in\n",
" let diff = max_D -. critere_D \n",
" in\n",
" \n",
" (*Printf.printf \"%f\\n%!\" diff;*)\n",
" Printf.printf \"%i %f %f %f %f %f\\n%!\" n max_D critere_D alpha norme_alpha moyenne_alpha;\n",
" \n",
" (* Stabilisation de la convergence *)\n",
"\n",
" let max_D =\n",
" if diff > 0.\n",
" then max_D\n",
" else critere_D\n",
" in\n",
" \n",
" if diff > 0. && epsilon > 0.001\n",
" then localisation m_C methode (epsilon /. 1000.) (n-1) critere_D prev_m_alpha cc max_D\n",
" else let epsilon = 1.\n",
" in\n",
" \n",
"(*Util.debug_matrix \"new_alpha_m\" m_alpha;*)\n",
"(*Util.debug_matrix \"m_new_m_C\" m_new_m_C;*)\n",
"\n",
"\n",
"(* Critère de conv pour sortir *)\n",
"if diff**2. < cc**2.\n",
" then m_new_m_C\n",
" else\n",
"localisation m_new_m_C methode epsilon (n-1) critere_D cc;;\n"
"localisation m_new_m_C methode epsilon (n-1) critere_D m_alpha cc max_D;;\n"
]
},
{
@ -1927,13 +1947,18 @@
"metadata": {},
"outputs": [],
"source": [
"(* Calcul *)\n",
"(* Fonction / Matrice des coef / Méthode(\"Boys\" ou \"ER\") / Pas(<=1.) \n",
"/ Nombre d'itérations max / 0. (valeur de D pour initier la boucle) / critère de convergence sur D*)\n",
"let localise localisation m_C methode epsilon n cc=\n",
" let alphad = m_alpha_d methode m_C \n",
" in\n",
" let prev_m_alpha = alphad.m_alpha\n",
" in \n",
" let prev_critere_D = 0.\n",
" in\n",
" let max_D = 0.\n",
"in\n",
"localisation m_C methode epsilon n prev_critere_D prev_m_alpha cc max_D;;\n",
"\n",
"let new_m_boys = localisation m_C \"boys\" 1. 20 0. 10e-7;;\n",
"(*let new_m_er = localisation m_C \"ER\" 1. 100 0. 10e-7;;\n",
"*)\n"
"localise localisation m_C \"Boys\" 1. 1000 10e-5;;"
]
},
{

View File

@ -1094,6 +1094,24 @@
"*)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"(* Test choix cc *)\n",
"\n",
"let choix_cc cc = \n",
" let toto cc = \n",
" match cc with \n",
" | \"alpha_max\" -> let toto = alpha_max /. epsilon in {tutu = toto}\n",
" | \"norme_alpha\" -> let toto = norme_alpha in {tutu = toto}\n",
" | \"critere_D\" -> let toto = critere_D in {tutu = toto}\n",
" | _ -> invalid_arg \"Unknown method, please enter alpha_max\"\n",
"in toto_cc;;\n"
]
},
{
"cell_type": "code",
"execution_count": null,
@ -1324,43 +1342,22 @@
"metadata": {},
"outputs": [],
"source": [
"(*\n",
"\n",
"(* Localisation de Edminstion ou de Boys *)\n",
"\n",
"(* Calcul de la nouvelle matrice des coefficient après n rotation d'orbitales *)\n",
"let rec localisation m_C methode epsilon n prev_critere_D cc=\n",
"\n",
" Printf.printf \"%i\\n%!\" n;\n",
"let rec localisation m_C methode epsilon n prev_critere_D prev_m_alpha cc max_D=\n",
"\n",
" (*Printf.printf \"%i\\n%!\" n;*)\n",
" (*Printf.printf \"%f\\n%!\" epsilon;*)\n",
" (*Util.debug_matrix \"m_C\" m_C;*)\n",
" (*Util.debug_matrix \"new_alpha_m\" prev_m_alpha;*)\n",
"\n",
"if n == 0 \n",
" then m_C\n",
" else\n",
" \n",
"\n",
" (* Fonction de calcul de la nouvelle matrice de coef après rotation d'un angle alpha *)\n",
" let new_m_C m_C methode =\n",
" \n",
" (* Fonction de pattern matching en fonction de la méthode *)\n",
" let alphad = m_alpha_d methode m_C \n",
" in\n",
" \n",
" (* D critère à maximiser *)\n",
" let critere_D = alphad.d \n",
" in\n",
" \n",
" Printf.printf \"%f\\n%!\" critere_D;\n",
" \n",
" (* Matrice des alphas *)\n",
" let m_alpha = alphad.m_alpha\n",
" in\n",
" let norme_alpha = norme m_alpha\n",
" in\n",
" \n",
" Printf.printf \"%f\\n%!\" norme_alpha;\n",
" \n",
" (*Util.debug_matrix \"m_alpha\" m_alpha;*)\n",
" let new_m_C m_C methode m_alpha epsilon =\n",
"\n",
" (* alphaij contient le alpha max ainsi que ses indices i et j *)\n",
" let n_rec_alpha = 10 (* Nombre ditération max pour réduire les valeurs de alpha *)\n",
@ -1373,7 +1370,7 @@
" in\n",
"\n",
" (*Printf.printf \"%f\\n%!\" alpha;*)\n",
" \n",
"\n",
" (* Indice i et j du alpha max après calcul *)\n",
" let indice_i = alphaij.indice_ii \n",
" in\n",
@ -1381,12 +1378,12 @@
" in\n",
"\n",
" (*Printf.printf \"%i %i\\n%!\" indice_i indice_j;*)\n",
" \n",
"\n",
" (* Matrice de rotation *)\n",
" let m_R = f_R alpha \n",
" in\n",
"\n",
" (*Util.debug_matrix \"m_R\" m_R;*)\n",
" (*Util.debug_matrix \"m_R\" m_R;*)\n",
"\n",
" (* Matrice qui va subir la rotation *)\n",
" let m_Ksi = f_Ksi indice_i indice_j m_C \n",
@ -1414,163 +1411,66 @@
"\n",
" (* Matrice avec les coef des orbitales i et j remplacés par 0 *)\n",
" let m_interm = f_interm m_C m_Psi \n",
" in\n",
" \n",
" (*Util.debug_matrix \"m_interm\" m_interm;*)\n",
" \n",
" (* Matrice après rotation *)\n",
" ( Mat.add m_Psi_tilde m_interm, critere_D)\n",
" \n",
" in\n",
" let m_new_m_C , critere_D = new_m_C m_C methode \n",
" in\n",
" let diff = prev_critere_D -. critere_D\n",
" in\n",
"\n",
"in\n",
" (*Util.debug_matrix \"m_interm\" m_interm;*)\n",
"\n",
"(*Util.debug_matrix \"new_alpha_m\" (f_alpha m_C);*)\n",
"(*Util.debug_matrix \"m_new_m_C\" m_new_m_C;*)\n",
" (* Matrice après rotation *)\n",
" (Mat.add m_Psi_tilde m_interm, alpha)\n",
"\n",
"if diff**2. < cc**2.\n",
" then m_new_m_C\n",
" else\n",
"localisation m_new_m_C methode epsilon (n-1) critere_D cc;;\n",
"*)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"\n",
"(* Fonction de calcul de la nouvelle matrice de coef après rotation d'un angle alpha *)\n",
"let new_m_C m_C methode m_alpha epsilon =\n",
" \n",
" (* alphaij contient le alpha max ainsi que ses indices i et j *)\n",
" let n_rec_alpha = 10 (* Nombre ditération max pour réduire les valeurs de alpha *)\n",
" in\n",
" let alphaij = new_m_alpha m_alpha m_C n_rec_alpha \n",
" let m_new_m_C, alpha_max = new_m_C m_C methode prev_m_alpha epsilon\n",
" in\n",
"\n",
" (* Valeur de alpha max après calcul *) (* Epsilon = Pas <1. , 1. -> normal, sinon Pas plus petit *)\n",
" let alpha = (alphaij.alpha_max) *. epsilon \n",
" in\n",
"\n",
" (*Printf.printf \"%f\\n%!\" alpha;*)\n",
" \n",
" (* Indice i et j du alpha max après calcul *)\n",
" let indice_i = alphaij.indice_ii \n",
" in\n",
" let indice_j = alphaij.indice_jj \n",
" in\n",
"\n",
" (*Printf.printf \"%i %i\\n%!\" indice_i indice_j;*)\n",
" \n",
" (* Matrice de rotation *)\n",
" let m_R = f_R alpha \n",
" in\n",
"\n",
" (*Util.debug_matrix \"m_R\" m_R;*)\n",
"\n",
" (* Matrice qui va subir la rotation *)\n",
" let m_Ksi = f_Ksi indice_i indice_j m_C \n",
" in\n",
"\n",
" (*Util.debug_matrix \"m_Ksi\" m_Ksi;*)\n",
"\n",
" (* Matrice ayant subit la rotation *)\n",
" let m_Ksi_tilde = f_Ksi_tilde m_R m_Ksi m_C \n",
" in\n",
"\n",
" (*Util.debug_matrix \"m_Ksi_tilde\" m_Ksi_tilde;*)\n",
"\n",
" (* Matrice pour supprimerles coef des orbitales i et j dans la matrice des coef *)\n",
" let m_Psi = f_k m_Ksi indice_i indice_j m_C\n",
" in\n",
"\n",
" (*Util.debug_matrix \"m_Psi\" m_Psi;*)\n",
"\n",
" (* Matrice pour ajouter les coef des orbitales i~ et j~ dans la matrice des coef *)\n",
" let m_Psi_tilde = f_k m_Ksi_tilde indice_i indice_j m_C \n",
" in\n",
"\n",
" (*Util.debug_matrix \"m_Psi_tilde\" m_Psi_tilde;*)\n",
"\n",
" (* Matrice avec les coef des orbitales i et j remplacés par 0 *)\n",
" let m_interm = f_interm m_C m_Psi \n",
" in\n",
" \n",
" (*Util.debug_matrix \"m_interm\" m_interm;*)\n",
" \n",
"(* Matrice après rotation *)\n",
"Mat.add m_Psi_tilde m_interm\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"\n",
"(* Localisation de Edminstion ou de Boys *)\n",
"\n",
"(* Calcul de la nouvelle matrice des coefficient après n rotation d'orbitales *)\n",
"let rec localisation m_C methode epsilon n prev_critere_D prev_m_alpha cc max_D=\n",
"\n",
" (*Printf.printf \"%i\\n%!\" n;\n",
" Printf.printf \"%f\\n%!\" epsilon;*)\n",
"\n",
" (*Util.debug_matrix \"m_C\" m_C;*)\n",
"\n",
" (*Util.debug_matrix \"new_alpha_m\" prev_m_alpha;*)\n",
"\n",
"if n == 0 \n",
" then m_C\n",
" else\n",
"\n",
" let m_new_m_C = new_m_C m_C methode prev_m_alpha epsilon\n",
" in\n",
" (* Fonction de pattern matching en fonction de la méthode *)\n",
" let alphad = m_alpha_d methode m_new_m_C\n",
" in\n",
" \n",
" \n",
" (* Matrice des alphas *)\n",
" let m_alpha = alphad.m_alpha\n",
" in\n",
" \n",
" (* Critères possibles de localisation -> norme_alpha, moyenne_alpha, alpha, diff *)\n",
" \n",
" (* Norme de m_alpha *)\n",
" let norme_alpha = norme m_alpha\n",
" in\n",
" let moyenne_alpha = norme_alpha /. (float_of_int((Mat.dim1 m_C)* (Mat.dim2 m_C)))\n",
" in\n",
" (* Valeur du alpha_max *)\n",
" let alpha = alpha_max /. epsilon\n",
" in\n",
" (* D critère à maximiser *)\n",
" let critere_D = alphad.d \n",
" in\n",
" let diff = max_D -. critere_D \n",
" in\n",
" \n",
" (*Printf.printf \"%f\\n%!\" diff;*)\n",
" Printf.printf \"%i %f %f %f %f %f\\n%!\" n max_D critere_D alpha norme_alpha moyenne_alpha;\n",
" \n",
" (* Stabilisation de la convergence *)\n",
"\n",
" let max_D =\n",
" if diff > 0.\n",
" then max_D\n",
" else critere_D\n",
" in\n",
" (*Printf.printf \"%f\\n%!\" max_D;*)\n",
" Printf.printf \"%e\\n%!\" critere_D;\n",
" (*Printf.printf \"%f\\n%!\" diff;*)\n",
" \n",
" (* Matrice des alphas *)\n",
" let m_alpha = alphad.m_alpha\n",
" in\n",
" (*let norme_alpha = norme m_alpha\n",
" in \n",
" Printf.printf \"%f\\n%!\" norme_alpha;*)\n",
"if diff > 0. && epsilon > 0.09\n",
" then localisation m_C methode (epsilon /. 2.) (n-1) critere_D prev_m_alpha cc max_D\n",
" else\n",
" let epsilon = 1.\n",
" \n",
" if diff > 0. && epsilon > 0.001\n",
" then localisation m_C methode (epsilon /. 1000.) (n-1) critere_D prev_m_alpha cc max_D\n",
" else let epsilon = 1.\n",
" in\n",
" \n",
"(*Util.debug_matrix \"new_alpha_m\" m_alpha;*)\n",
"(*Util.debug_matrix \"m_new_m_C\" m_new_m_C;*)\n",
"\n",
"\n",
"(* Critère de conv pour sortir *)\n",
"if diff**2. < cc**2.\n",
" then m_new_m_C\n",
" else\n",
"localisation m_new_m_C methode epsilon (n-1) critere_D m_alpha cc max_D;;\n"
"localisation m_new_m_C methode epsilon (n-1) critere_D m_alpha cc max_D;;\n"
]
},
{