JWS C Library
C language utility library
|
00001 /* 00002 * This work is licensed under a Creative Commons 00003 * Attribution-Noncommercial-Share Alike 3.0 United States License. 00004 * 00005 * http://creativecommons.org/licenses/by-nc-sa/3.0/us/ 00006 * 00007 * You are free: 00008 * 00009 * to Share - to copy, distribute, display, and perform the work 00010 * to Remix - to make derivative works 00011 * 00012 * Under the following conditions: 00013 * 00014 * Attribution. You must attribute the work in the manner specified by the 00015 * author or licensor (but not in any way that suggests that they endorse you 00016 * or your use of the work). 00017 * 00018 * Noncommercial. You may not use this work for commercial purposes. 00019 * 00020 * Share Alike. If you alter, transform, or build upon this work, you may 00021 * distribute the resulting work only under the same or similar license to 00022 * this one. 00023 * 00024 * For any reuse or distribution, you must make clear to others the license 00025 * terms of this work. The best way to do this is by including this header. 00026 * 00027 * Any of the above conditions can be waived if you get permission from the 00028 * copyright holder. 00029 * 00030 * Apart from the remix rights granted under this license, nothing in this 00031 * license impairs or restricts the author's moral rights. 00032 */ 00033 00034 00047 #include <jwsc/config.h> 00048 00049 #include <stdlib.h> 00050 #include <stdio.h> 00051 #include <inttypes.h> 00052 #include <math.h> 00053 #include <assert.h> 00054 00055 #include "jwsc/base/error.h" 00056 #include "jwsc/base/limits.h" 00057 #include "jwsc/vector/vector.h" 00058 #include "jwsc/vector/vector_math.h" 00059 #include "jwsc/vector/vector_io.h" 00060 #include "jwsc/matrix/matrix.h" 00061 #include "jwsc/prob/pdf.h" 00062 #include "jwsc/prob/mv_pdf.h" 00063 #include "jwsc/stat/dynamics.h" 00064 00065 00096 Error* stochastic_dynamics_1_d 00097 ( 00098 uint32_t iterations, 00099 double delta_t, 00100 double alpha, 00101 uint32_t kick, 00102 void* params, 00103 void (*get_pt_from_params)(Vector_d** p_out, const void* params), 00104 Error* (*grad_energy_func)(Vector_d** grad_out, void* params), 00105 Error* (*accept_sample)(const Vector_d* sample, const Vector_d* momenta, void* params) 00106 ) 00107 { 00108 uint32_t D; 00109 00110 Vector_d* p = NULL; 00111 Vector_d* delta_t_v = NULL; 00112 Error* err; 00113 00114 get_pt_from_params(&p, params); 00115 D = p->num_elts; 00116 00117 create_init_vector_d(&delta_t_v, D, delta_t); 00118 00119 err = stochastic_dynamics_2_d(iterations, delta_t_v, alpha, kick, params, 00120 get_pt_from_params, grad_energy_func, accept_sample); 00121 00122 free_vector_d(p); 00123 free_vector_d(delta_t_v); 00124 00125 return err; 00126 } 00127 00128 00151 Error* stochastic_dynamics_2_d 00152 ( 00153 uint32_t iterations, 00154 const Vector_d* delta_t, 00155 double alpha, 00156 uint32_t kick, 00157 void* params, 00158 void (*get_pt_from_params)(Vector_d** p_out, const void* params), 00159 Error* (*grad_energy_func)(Vector_d** grad_out, void* params), 00160 Error* (*accept_sample)(const Vector_d* sample, const Vector_d* momenta, void* params) 00161 ) 00162 { 00163 uint32_t i; 00164 uint32_t d, D; 00165 00166 Vector_d* g = NULL; 00167 Vector_d* p = NULL; 00168 Vector_d* p_stoch = NULL; 00169 Vector_d* pp = NULL; 00170 Vector_d* q = NULL; 00171 Vector_d* gauss = NULL; 00172 Error* err; 00173 00174 get_pt_from_params(&q, params); 00175 D = q->num_elts; 00176 00177 sample_standard_mv_gaussian_pdf_d(&p, D); 00178 00179 if ((err = grad_energy_func(&g, params))) 00180 { 00181 free_vector_d(g); 00182 free_vector_d(p); 00183 free_vector_d(q); 00184 free_vector_d(gauss); 00185 return err; 00186 } 00187 for (d = 0; d < D; d++) 00188 { 00189 g->elts[ d ] *= 0.5 * delta_t->elts[ d ]; 00190 } 00191 subtract_vectors_d(&p, p, g); 00192 copy_vector_d(&p_stoch, p); 00193 00194 for (i = 0; i < iterations; i++) 00195 { 00196 if (kick > 0 && ((i+1) % kick == 0)) 00197 { 00198 copy_vector_d(&p_stoch, p); 00199 } 00200 00201 copy_vector_d(&pp, p_stoch); 00202 for (d = 0; d < D; d++) 00203 { 00204 pp->elts[ d ] *= delta_t->elts[ d ]; 00205 } 00206 add_vectors_d(&q, q, pp); 00207 00208 if ((err = accept_sample(q, p_stoch, params))) 00209 { 00210 free_vector_d(g); 00211 free_vector_d(p); 00212 free_vector_d(p_stoch); 00213 free_vector_d(pp); 00214 free_vector_d(q); 00215 free_vector_d(gauss); 00216 return err; 00217 } 00218 00219 /* The params might range limit the point, so get it again. */ 00220 get_pt_from_params(&q, params); 00221 00222 if ((err = grad_energy_func(&g, params))) 00223 { 00224 free_vector_d(g); 00225 free_vector_d(p); 00226 free_vector_d(p_stoch); 00227 free_vector_d(pp); 00228 free_vector_d(q); 00229 free_vector_d(gauss); 00230 return err; 00231 } 00232 for (d = 0; d < D; d++) 00233 { 00234 g->elts[ d ] *= delta_t->elts[ d ]; 00235 } 00236 subtract_vectors_d(&p, p, g); 00237 subtract_vectors_d(&p_stoch, p_stoch, g); 00238 00239 multiply_vector_by_scalar_d(&p_stoch, p_stoch, alpha); 00240 sample_standard_mv_gaussian_pdf_d(&gauss, D); 00241 multiply_vector_by_scalar_d(&gauss, gauss, sqrt(1 - alpha*alpha)); 00242 add_vectors_d(&p_stoch, p_stoch, gauss); 00243 } 00244 00245 // Ignore the last half-step update of the momenta. 00246 00247 free_vector_d(g); 00248 free_vector_d(p); 00249 free_vector_d(p_stoch); 00250 free_vector_d(pp); 00251 free_vector_d(q); 00252 free_vector_d(gauss); 00253 00254 return NULL; 00255 } 00256 00300 Error* hybrid_monte_carlo_1_d 00301 ( 00302 uint32_t iterations, 00303 uint32_t leap_iter, 00304 double delta_t, 00305 double alpha, 00306 uint32_t kick, 00307 void* params, 00308 void (*get_pt_from_params)(Vector_d** p_out, const void* params), 00309 Error* (*set_params_from_pt)(const Vector_d* p, void* params), 00310 Error* (*energy_func)(double* energy_out, void* params), 00311 Error* (*grad_energy_func)(Vector_d** grad_out, void* params), 00312 Error* (*accept_sample)(const Vector_d* sample, const Vector_d* momenta, void* params), 00313 Error* (*reject_sample)(const Vector_d* sample, const Vector_d* momenta, void* params) 00314 ) 00315 { 00316 uint32_t D; 00317 00318 Vector_d* p = NULL; 00319 Vector_d* delta_t_v = NULL; 00320 Error* err; 00321 00322 get_pt_from_params(&p, params); 00323 D = p->num_elts; 00324 00325 create_init_vector_d(&delta_t_v, D, delta_t); 00326 00327 err = hybrid_monte_carlo_2_d(iterations, leap_iter, delta_t_v, alpha, 00328 kick, params, get_pt_from_params, set_params_from_pt, energy_func, 00329 grad_energy_func, accept_sample, reject_sample); 00330 00331 free_vector_d(p); 00332 free_vector_d(delta_t_v); 00333 00334 return err; 00335 } 00336 00367 Error* hybrid_monte_carlo_2_d 00368 ( 00369 uint32_t iterations, 00370 uint32_t leap_iter, 00371 const Vector_d* delta_t, 00372 double alpha, 00373 uint32_t kick, 00374 void* params, 00375 void (*get_pt_from_params)(Vector_d** p_out, const void* params), 00376 Error* (*set_params_from_pt)(const Vector_d* p, void* params), 00377 Error* (*energy_func)(double* energy_out, void* params), 00378 Error* (*grad_energy_func)(Vector_d** grad_out, void* params), 00379 Error* (*accept_sample)(const Vector_d* sample, const Vector_d* momenta, void* params), 00380 Error* (*reject_sample)(const Vector_d* sample, const Vector_d* momenta, void* params) 00381 ) 00382 { 00383 uint32_t i, l; 00384 uint32_t d, D; 00385 double lambda; 00386 double E, K; 00387 double E_prop, K_prop; 00388 double log_alpha; 00389 double log_u; 00390 00391 Vector_d* g = NULL; 00392 Vector_d* p = NULL; 00393 Vector_d* p_stoch = NULL; 00394 Vector_d* p_prop = NULL; 00395 Vector_d* p_stoch_prop = NULL; 00396 Vector_d* pp_prop = NULL; 00397 Vector_d* q = NULL; 00398 Vector_d* q_prop = NULL; 00399 Vector_d* gauss = NULL; 00400 Vector_d* delta_t_0 = NULL; 00401 Error* err; 00402 00403 get_pt_from_params(&q, params); 00404 D = q->num_elts; 00405 00406 sample_standard_mv_gaussian_pdf_d(&p, D); 00407 00408 if ((err = energy_func(&E, params))) 00409 { 00410 free_vector_d(p); 00411 free_vector_d(q); 00412 return err; 00413 } 00414 00415 copy_vector_d(&p_stoch, p); 00416 calc_vector_dot_prod_d(&K, p, p); 00417 K *= 0.5; 00418 00419 copy_vector_d(&delta_t_0, delta_t); 00420 00421 for (i = 0; i < iterations; i++) 00422 { 00423 copy_vector_d(&q_prop, q); 00424 copy_vector_d(&p_prop, p); 00425 copy_vector_d(&p_stoch_prop, p_stoch); 00426 00427 lambda = (sample_uniform_pdf_d(0, 1) < 0.5) ? -1 : 1; 00428 for (d = 0; d < D; d++) 00429 { 00430 delta_t->elts[ d ] = delta_t_0->elts[ d ] * lambda; 00431 } 00432 00433 if ((err = grad_energy_func(&g, params))) 00434 { 00435 free_vector_d(g); 00436 free_vector_d(p); free_vector_d(p_prop); free_vector_d(pp_prop); 00437 free_vector_d(p_stoch); free_vector_d(p_stoch_prop); 00438 free_vector_d(q); free_vector_d(q_prop); 00439 free_vector_d(gauss); 00440 free_vector_d(delta_t_0); 00441 return err; 00442 } 00443 for (d = 0; d < D; d++) 00444 { 00445 g->elts[ d ] *= 0.5*delta_t->elts[ d ]; 00446 } 00447 subtract_vectors_d(&p_prop, p_prop, g); 00448 subtract_vectors_d(&p_stoch_prop, p_stoch_prop, g); 00449 00450 for (l = 0; l < leap_iter; l++) 00451 { 00452 copy_vector_d(&pp_prop, p_stoch_prop); 00453 for (d = 0; d < D; d++) 00454 { 00455 pp_prop->elts[ d ] *= delta_t->elts[ d ]; 00456 } 00457 add_vectors_d(&q_prop, q_prop, pp_prop); 00458 00459 if ((err = set_params_from_pt(q_prop, params)) || 00460 (err = grad_energy_func(&g, params))) 00461 { 00462 assert(set_params_from_pt(q, params) == NULL); 00463 free_vector_d(g); 00464 free_vector_d(p); free_vector_d(p_prop); free_vector_d(pp_prop); 00465 free_vector_d(p_stoch); free_vector_d(p_stoch_prop); 00466 free_vector_d(q); free_vector_d(q_prop); 00467 free_vector_d(gauss); 00468 free_vector_d(delta_t_0); 00469 return err; 00470 } 00471 00472 /* The params might range limit the point, so get it again. */ 00473 get_pt_from_params(&q_prop, params); 00474 00475 for (d = 0; d < D; d++) 00476 { 00477 g->elts[ d ] *= delta_t->elts[ d ]; 00478 } 00479 subtract_vectors_d(&p_prop, p_prop, g); 00480 subtract_vectors_d(&p_stoch_prop, p_stoch_prop, g); 00481 00482 multiply_vector_by_scalar_d(&p_stoch_prop, p_stoch_prop, alpha); 00483 sample_standard_mv_gaussian_pdf_d(&gauss, D); 00484 multiply_vector_by_scalar_d(&gauss, gauss, sqrt(1 - alpha*alpha)); 00485 add_vectors_d(&p_stoch_prop, p_stoch_prop, gauss); 00486 } 00487 00488 if ((err = energy_func(&E_prop, params)) || 00489 (err = set_params_from_pt(q, params))) 00490 { 00491 free_vector_d(g); 00492 free_vector_d(p); free_vector_d(p_prop); free_vector_d(pp_prop); 00493 free_vector_d(p_stoch); free_vector_d(p_stoch_prop); 00494 free_vector_d(q); free_vector_d(q_prop); 00495 free_vector_d(gauss); 00496 free_vector_d(delta_t_0); 00497 return err; 00498 } 00499 00500 calc_vector_dot_prod_d(&K_prop, p_stoch_prop, p_stoch_prop); 00501 K_prop *= 0.5; 00502 00503 log_alpha = - E_prop - K_prop + E + K; 00504 log_u = log(sample_uniform_pdf_d(JWSC_MIN_LOG_ARG, 1.0)); 00505 00506 if (log_u <= log_alpha) 00507 { 00508 copy_vector_d(&q, q_prop); 00509 copy_vector_d(&p, p_prop); 00510 copy_vector_d(&p_stoch, p_stoch_prop); 00511 00512 if ((err = accept_sample(q, p_stoch, params))) 00513 { 00514 free_vector_d(g); 00515 free_vector_d(p); free_vector_d(p_prop); free_vector_d(pp_prop); 00516 free_vector_d(p_stoch); free_vector_d(p_stoch_prop); 00517 free_vector_d(q); free_vector_d(q_prop); 00518 free_vector_d(gauss); 00519 free_vector_d(delta_t_0); 00520 return err; 00521 } 00522 00523 /* The params might range limit the point, so get it again. */ 00524 get_pt_from_params(&q, params); 00525 00526 E = E_prop; 00527 00528 if (kick > 0 && ((i+1) % kick == 0)) 00529 { 00530 copy_vector_d(&p_stoch, p); 00531 calc_vector_dot_prod_d(&K, p_stoch, p_stoch); 00532 K *= 0.5; 00533 } 00534 else 00535 { 00536 K = K_prop; 00537 } 00538 } 00539 else if (reject_sample) 00540 { 00541 if ((err = reject_sample(q_prop, p_stoch_prop, params))) 00542 { 00543 free_vector_d(g); 00544 free_vector_d(p); free_vector_d(p_prop); free_vector_d(pp_prop); 00545 free_vector_d(p_stoch); free_vector_d(p_stoch_prop); 00546 free_vector_d(q); free_vector_d(q_prop); 00547 free_vector_d(gauss); 00548 free_vector_d(delta_t_0); 00549 return err; 00550 } 00551 } 00552 } 00553 00554 free_vector_d(g); 00555 free_vector_d(p); 00556 free_vector_d(p_stoch); 00557 free_vector_d(p_prop); 00558 free_vector_d(p_stoch_prop); 00559 free_vector_d(pp_prop); 00560 free_vector_d(q); 00561 free_vector_d(q_prop); 00562 free_vector_d(gauss); 00563 free_vector_d(delta_t_0); 00564 00565 return NULL; 00566 } 00567 00597 Error* langevin_1_f 00598 ( 00599 uint32_t iterations, 00600 float delta_t, 00601 void* params, 00602 void (*get_pt_from_params)(Vector_f** p_out, const void* params), 00603 Error* (*grad_energy_func)(Vector_f** grad_out, void* params), 00604 Error* (*accept_sample)(const Vector_f* sample, void* params) 00605 ) 00606 { 00607 uint32_t D; 00608 00609 Vector_f* p = NULL; 00610 Vector_f* delta_t_v = NULL; 00611 Error* err; 00612 00613 get_pt_from_params(&p, params); 00614 D = p->num_elts; 00615 00616 create_init_vector_f(&delta_t_v, D, delta_t); 00617 00618 err = langevin_2_f(iterations, delta_t_v, params, get_pt_from_params, 00619 grad_energy_func, accept_sample); 00620 00621 free_vector_f(p); 00622 free_vector_f(delta_t_v); 00623 00624 return err; 00625 } 00626 00644 Error* langevin_2_f 00645 ( 00646 uint32_t iterations, 00647 const Vector_f* delta_t, 00648 void* params, 00649 void (*get_pt_from_params)(Vector_f** p_out, const void* params), 00650 Error* (*grad_energy_func)(Vector_f** grad_out, void* params), 00651 Error* (*accept_sample)(const Vector_f* sample, void* params) 00652 ) 00653 { 00654 uint32_t i; 00655 uint32_t n; 00656 float dx; 00657 float dt; 00658 float gauss; 00659 00660 Vector_f* g = NULL; 00661 Vector_f* s = NULL; 00662 Error* err; 00663 00664 for (i = 0; i < iterations; i++) 00665 { 00666 if ((err = grad_energy_func(&g, params))) 00667 { 00668 free_vector_f(g); 00669 free_vector_f(s); 00670 return err; 00671 } 00672 00673 get_pt_from_params(&s, params); 00674 00675 assert(s->num_elts == g->num_elts); 00676 assert(s->num_elts == delta_t->num_elts); 00677 00678 for (n = 0; n < s->num_elts; n++) 00679 { 00680 dx = g->elts[ n ]; 00681 dt = delta_t->elts[ n ]; 00682 gauss = sample_standard_gaussian_pdf_f(-6.0, 6.0); 00683 s->elts[ n ] -= dt*(0.5*dt*dx + gauss); 00684 } 00685 00686 if ((err = accept_sample(s, params))) 00687 { 00688 free_vector_f(g); 00689 free_vector_f(s); 00690 return err; 00691 } 00692 } 00693 00694 free_vector_f(g); 00695 free_vector_f(s); 00696 00697 return NULL; 00698 } 00699 00717 Error* langevin_1_d 00718 ( 00719 uint32_t iterations, 00720 double delta_t, 00721 void* params, 00722 void (*get_pt_from_params)(Vector_d** p_out, const void* params), 00723 Error* (*grad_energy_func)(Vector_d** grad_out, void* params), 00724 Error* (*accept_sample)(const Vector_d* sample, void* params) 00725 ) 00726 { 00727 uint32_t D; 00728 00729 Vector_d* p = NULL; 00730 Vector_d* delta_t_v = NULL; 00731 Error* err; 00732 00733 get_pt_from_params(&p, params); 00734 D = p->num_elts; 00735 00736 create_init_vector_d(&delta_t_v, D, delta_t); 00737 00738 err = langevin_2_d(iterations, delta_t_v, params, get_pt_from_params, 00739 grad_energy_func, accept_sample); 00740 00741 free_vector_d(p); 00742 free_vector_d(delta_t_v); 00743 00744 return err; 00745 } 00746 00764 Error* langevin_2_d 00765 ( 00766 uint32_t iterations, 00767 const Vector_d* delta_t, 00768 void* params, 00769 void (*get_pt_from_params)(Vector_d** p_out, const void* params), 00770 Error* (*grad_energy_func)(Vector_d** grad_out, void* params), 00771 Error* (*accept_sample)(const Vector_d* sample, void* params) 00772 ) 00773 { 00774 uint32_t i; 00775 uint32_t n; 00776 double dx; 00777 double dt; 00778 double gauss; 00779 00780 Vector_d* g = NULL; 00781 Vector_d* s = NULL; 00782 Error* err; 00783 00784 for (i = 0; i < iterations; i++) 00785 { 00786 if ((err = grad_energy_func(&g, params))) 00787 { 00788 free_vector_d(g); 00789 free_vector_d(s); 00790 return err; 00791 } 00792 00793 get_pt_from_params(&s, params); 00794 00795 assert(s->num_elts == g->num_elts); 00796 assert(s->num_elts == delta_t->num_elts); 00797 00798 for (n = 0; n < s->num_elts; n++) 00799 { 00800 dx = g->elts[ n ]; 00801 dt = delta_t->elts[ n ]; 00802 gauss = sample_standard_gaussian_pdf_d(-6.0, 6.0); 00803 s->elts[ n ] -= dt*(0.5*dt*dx + gauss); 00804 } 00805 00806 if ((err = accept_sample(s, params))) 00807 { 00808 free_vector_d(g); 00809 free_vector_d(s); 00810 return err; 00811 } 00812 } 00813 00814 free_vector_d(g); 00815 free_vector_d(s); 00816 00817 return NULL; 00818 } 00819 00832 static Error* hyperdynamics_hessian_eigenvalue_f 00833 ( 00834 float* e_out, 00835 const Vector_f* v, 00836 float eta, 00837 void* params, 00838 void (*get_pt_from_params)(Vector_f**, const void*), 00839 Error* (*set_params_from_pt)(const Vector_f*, void*), 00840 Error* (*energy_func)(float*, void*) 00841 ) 00842 { 00843 float a, b, c; 00844 00845 Vector_f* eta_v = NULL; 00846 Vector_f* p = NULL; 00847 Vector_f* q = NULL; 00848 Error* err; 00849 00850 get_pt_from_params(&p, params); 00851 00852 multiply_vector_by_scalar_f(&eta_v, v, eta); 00853 00854 assert(add_vectors_f(&q, p, eta_v) == NULL); 00855 00856 if ((err = set_params_from_pt(q, params)) || 00857 (err = energy_func(&a, params))) 00858 { 00859 assert(set_params_from_pt(p, params) == NULL); 00860 free_vector_f(eta_v); 00861 free_vector_f(p); free_vector_f(q); 00862 return err; 00863 } 00864 00865 assert(subtract_vectors_f(&q, p, eta_v) == NULL); 00866 00867 if ((err = set_params_from_pt(q, params)) || 00868 (err = energy_func(&b, params))) 00869 { 00870 assert(set_params_from_pt(p, params) == NULL); 00871 free_vector_f(eta_v); 00872 free_vector_f(p); free_vector_f(q); 00873 return err; 00874 } 00875 00876 assert(set_params_from_pt(p, params) == NULL); 00877 00878 if ((err = energy_func(&c, params))) 00879 { 00880 free_vector_f(eta_v); 00881 free_vector_f(p); free_vector_f(q); 00882 return err; 00883 } 00884 00885 *e_out = (a + b - 2.0*c) / (eta*eta); 00886 00887 free_vector_f(eta_v); 00888 free_vector_f(p); 00889 free_vector_f(q); 00890 00891 return NULL; 00892 } 00893 00894 static Error* hyperdynamics_hessian_eigenvalue_d 00895 ( 00896 double* e_out, 00897 const Vector_d* v, 00898 double eta, 00899 void* params, 00900 void (*get_pt_from_params)(Vector_d**, const void*), 00901 Error* (*set_params_from_pt)(const Vector_d*, void*), 00902 Error* (*energy_func)(double*, void*) 00903 ) 00904 { 00905 double a, b, c; 00906 00907 Vector_d* eta_v = NULL; 00908 Vector_d* p = NULL; 00909 Vector_d* q = NULL; 00910 Error* err; 00911 00912 get_pt_from_params(&p, params); 00913 00914 multiply_vector_by_scalar_d(&eta_v, v, eta); 00915 00916 assert(add_vectors_d(&q, p, eta_v) == NULL); 00917 00918 if ((err = set_params_from_pt(q, params)) || 00919 (err = energy_func(&a, params))) 00920 { 00921 assert(set_params_from_pt(p, params) == NULL); 00922 free_vector_d(eta_v); 00923 free_vector_d(p); free_vector_d(q); 00924 return err; 00925 } 00926 00927 assert(subtract_vectors_d(&q, p, eta_v) == NULL); 00928 00929 if ((err = set_params_from_pt(q, params)) || 00930 (err = energy_func(&b, params))) 00931 { 00932 assert(set_params_from_pt(p, params) == NULL); 00933 free_vector_d(eta_v); 00934 free_vector_d(p); free_vector_d(q); 00935 return err; 00936 } 00937 00938 assert(set_params_from_pt(p, params) == NULL); 00939 00940 if ((err = energy_func(&c, params))) 00941 { 00942 free_vector_d(eta_v); 00943 free_vector_d(p); free_vector_d(q); 00944 return err; 00945 } 00946 00947 *e_out = (a + b - 2.0*c) / (eta*eta); 00948 00949 free_vector_d(eta_v); 00950 free_vector_d(p); 00951 free_vector_d(q); 00952 00953 return NULL; 00954 } 00955 00968 static Error* hyperdynamics_hessian_eigenvector_f 00969 ( 00970 Vector_f** v_out, 00971 float eta, 00972 float gamma, 00973 void* params, 00974 void (*get_pt_from_params)(Vector_f**, const void*), 00975 Error* (*set_params_from_pt)(const Vector_f*, void*), 00976 Error* (*energy_func)(float*, void*), 00977 Error* (*grad_energy_func)(Vector_f**, void*) 00978 ) 00979 { 00980 uint32_t n; 00981 uint32_t N; 00982 uint8_t done; 00983 00984 float e; 00985 float delta_e; 00986 float g; 00987 float e_dv_dp; 00988 float e_dv_prev_dp; 00989 float beta; 00990 00991 Vector_f* v; 00992 Vector_f* v_cp = NULL; 00993 Vector_f* delta_v = NULL; 00994 Vector_f* eta_v = NULL; 00995 Vector_f* p = NULL; 00996 Vector_f* q = NULL; 00997 Vector_f* a = NULL; 00998 Vector_f* b = NULL; 00999 Error* err = NULL; 01000 Vector_f* e_dv = NULL; 01001 Vector_f* e_dv_prev = NULL; 01002 Vector_f* e_dv_diff = NULL; 01003 01004 get_pt_from_params(&p, params); 01005 N = p->num_elts; 01006 01007 create_vector_f(v_out, N); 01008 v = *v_out; 01009 01010 e = 1.0e+10; 01011 done = 0; 01012 01013 while (!done) 01014 { 01015 get_pt_from_params(&p, params); 01016 01017 multiply_vector_by_scalar_f(&eta_v, v, eta); 01018 01019 assert(add_vectors_f(&q, p, eta_v) == NULL); 01020 01021 if ((err = set_params_from_pt(q, params)) || 01022 (err = grad_energy_func(&a, params))) 01023 { 01024 assert(set_params_from_pt(p, params) == NULL); 01025 break; 01026 } 01027 01028 assert(subtract_vectors_f(&q, p, eta_v) == NULL); 01029 01030 if ((err = set_params_from_pt(q, params)) || 01031 (err = grad_energy_func(&b, params))) 01032 { 01033 assert(set_params_from_pt(p, params) == NULL); 01034 break; 01035 } 01036 01037 assert(set_params_from_pt(p, params) == NULL); 01038 01039 assert(copy_vector_f(&delta_v, v) == NULL); 01040 01041 assert(subtract_vectors_f(&e_dv, a, b) == NULL); 01042 multiply_vector_by_scalar_f(&e_dv, e_dv, 1 / eta); 01043 01044 if (!e_dv_prev) 01045 { 01046 copy_vector_f(&e_dv_prev, e_dv); 01047 calc_vector_dot_prod_f(&e_dv_prev_dp, e_dv_prev, e_dv_prev); 01048 } 01049 01050 subtract_vectors_f(&e_dv_diff, e_dv, e_dv_prev); 01051 calc_vector_dot_prod_f(&e_dv_dp, e_dv, e_dv_diff); 01052 01053 beta = (e_dv_prev_dp > 0) && (e_dv_dp / e_dv_prev_dp) > 0 01054 ? e_dv_dp / e_dv_prev_dp : 0; 01055 01056 multiply_vector_by_scalar_f(&e_dv_prev, e_dv_prev, beta); 01057 add_vectors_f(&e_dv, e_dv, e_dv_prev); 01058 01059 g = gamma; 01060 delta_e = e; 01061 done = 0; 01062 01063 while (!done) 01064 { 01065 copy_vector_f(&v_cp, v); 01066 01067 for (n = 0; n < N; n++) 01068 { 01069 v_cp->elts[ n ] -= g * e_dv->elts[ n ]; 01070 } 01071 normalize_vector_mag_f(&v_cp, v_cp); 01072 01073 if ((err = hyperdynamics_hessian_eigenvalue_f(&e, v_cp, eta, 01074 params, get_pt_from_params, set_params_from_pt, 01075 energy_func))) 01076 { 01077 break; 01078 } 01079 01080 // TEMP 01081 //fprintf(stdout, "e1 : %10.3e %10.3e %10.3e\n", 01082 // e, (delta_e - e), g); 01083 01084 g *= 0.5; 01085 01086 if (g < 1.0e-16 || (delta_e - e) >= 0) 01087 { 01088 done = 1; 01089 } 01090 } 01091 if (err) 01092 { 01093 break; 01094 } 01095 01096 copy_vector_f(&v, v_cp); 01097 01098 delta_e -= e; 01099 01100 done = 1; 01101 for (n = 0; n < N; n++) 01102 { 01103 delta_v->elts[ n ] 01104 = (fabs(fabs(delta_v->elts[ n ]) - fabs(v->elts[ n ])) < 1.0e-6) 01105 ? fabs(fabs(delta_v->elts[ n ]) - fabs(v->elts[ n ])) 01106 : fabs(delta_v->elts[ n ] - v->elts[ n ]); 01107 01108 done = (done && (delta_v->elts[ n ] <= 1.0e-6)); 01109 } 01110 01111 // TEMP 01112 //fprintf(stdout, "dv : "); 01113 //write_formatted_vector_fp_f(delta_v, "%10.3e", stdout); 01114 //fprintf(stdout, "v : "); 01115 //write_formatted_vector_fp_f(v, "%10.3e", stdout); 01116 01117 copy_vector_f(&e_dv_prev, e_dv); 01118 calc_vector_dot_prod_f(&e_dv_prev_dp, e_dv_prev, e_dv_prev); 01119 } 01120 01121 free_vector_f(v_cp); 01122 free_vector_f(delta_v); 01123 free_vector_f(eta_v); 01124 free_vector_f(p); 01125 free_vector_f(q); 01126 free_vector_f(a); 01127 free_vector_f(b); 01128 free_vector_f(e_dv); 01129 free_vector_f(e_dv_prev); 01130 free_vector_f(e_dv_diff); 01131 01132 if (err) 01133 { 01134 free_vector_f(*v_out); *v_out = NULL; 01135 } 01136 01137 return err; 01138 } 01139 01140 static Error* hyperdynamics_hessian_eigenvector_d 01141 ( 01142 Vector_d** v_out, 01143 double eta, 01144 double gamma, 01145 void* params, 01146 void (*get_pt_from_params)(Vector_d**, const void*), 01147 Error* (*set_params_from_pt)(const Vector_d*, void*), 01148 Error* (*energy_func)(double*, void*), 01149 Error* (*grad_energy_func)(Vector_d**, void*) 01150 ) 01151 { 01152 uint32_t n; 01153 uint32_t N; 01154 uint8_t done; 01155 01156 double e; 01157 double delta_e; 01158 double g; 01159 double e_dv_dp; 01160 double e_dv_prev_dp; 01161 double beta; 01162 01163 Vector_d* v; 01164 Vector_d* v_cp = NULL; 01165 Vector_d* delta_v = NULL; 01166 Vector_d* eta_v = NULL; 01167 Vector_d* p = NULL; 01168 Vector_d* q = NULL; 01169 Vector_d* a = NULL; 01170 Vector_d* b = NULL; 01171 Error* err = NULL; 01172 Vector_d* e_dv = NULL; 01173 Vector_d* e_dv_prev = NULL; 01174 Vector_d* e_dv_diff = NULL; 01175 01176 get_pt_from_params(&p, params); 01177 N = p->num_elts; 01178 01179 create_vector_d(v_out, N); 01180 v = *v_out; 01181 01182 e = 1.0e+10; 01183 done = 0; 01184 01185 while (!done) 01186 { 01187 get_pt_from_params(&p, params); 01188 01189 multiply_vector_by_scalar_d(&eta_v, v, eta); 01190 01191 assert(add_vectors_d(&q, p, eta_v) == NULL); 01192 01193 if ((err = set_params_from_pt(q, params)) || 01194 (err = grad_energy_func(&a, params))) 01195 { 01196 assert(set_params_from_pt(p, params) == NULL); 01197 break; 01198 } 01199 01200 assert(subtract_vectors_d(&q, p, eta_v) == NULL); 01201 01202 if ((err = set_params_from_pt(q, params)) || 01203 (err = grad_energy_func(&b, params))) 01204 { 01205 assert(set_params_from_pt(p, params) == NULL); 01206 break; 01207 } 01208 01209 assert(set_params_from_pt(p, params) == NULL); 01210 01211 assert(copy_vector_d(&delta_v, v) == NULL); 01212 01213 assert(subtract_vectors_d(&e_dv, a, b) == NULL); 01214 multiply_vector_by_scalar_d(&e_dv, e_dv, 1 / eta); 01215 01216 if (!e_dv_prev) 01217 { 01218 copy_vector_d(&e_dv_prev, e_dv); 01219 calc_vector_dot_prod_d(&e_dv_prev_dp, e_dv_prev, e_dv_prev); 01220 } 01221 01222 subtract_vectors_d(&e_dv_diff, e_dv, e_dv_prev); 01223 calc_vector_dot_prod_d(&e_dv_dp, e_dv, e_dv_diff); 01224 01225 beta = (e_dv_prev_dp > 0) && (e_dv_dp / e_dv_prev_dp) > 0 01226 ? e_dv_dp / e_dv_prev_dp : 0; 01227 01228 multiply_vector_by_scalar_d(&e_dv_prev, e_dv_prev, beta); 01229 add_vectors_d(&e_dv, e_dv, e_dv_prev); 01230 01231 g = gamma; 01232 delta_e = e; 01233 done = 0; 01234 01235 while (!done) 01236 { 01237 copy_vector_d(&v_cp, v); 01238 01239 for (n = 0; n < N; n++) 01240 { 01241 v_cp->elts[ n ] -= g * e_dv->elts[ n ]; 01242 } 01243 normalize_vector_mag_d(&v_cp, v_cp); 01244 01245 if ((err = hyperdynamics_hessian_eigenvalue_d(&e, v_cp, eta, 01246 params, get_pt_from_params, set_params_from_pt, 01247 energy_func))) 01248 { 01249 break; 01250 } 01251 01252 // TEMP 01253 //fprintf(stdout, "e1 : %10.3e %10.3e %10.3e\n", 01254 // e, (delta_e - e), g); 01255 01256 g *= 0.5; 01257 01258 if (g < 1.0e-128 || (delta_e - e) >= 0) 01259 { 01260 done = 1; 01261 } 01262 } 01263 if (err) 01264 { 01265 break; 01266 } 01267 01268 copy_vector_d(&v, v_cp); 01269 01270 delta_e -= e; 01271 01272 done = 1; 01273 for (n = 0; n < N; n++) 01274 { 01275 delta_v->elts[ n ] 01276 = (fabs(fabs(delta_v->elts[ n ]) - fabs(v->elts[ n ])) < 1.0e-8) 01277 ? fabs(fabs(delta_v->elts[ n ]) - fabs(v->elts[ n ])) 01278 : fabs(delta_v->elts[ n ] - v->elts[ n ]); 01279 01280 done = (done && (delta_v->elts[ n ] <= 1.0e-8)); 01281 } 01282 01283 // TEMP 01284 //fprintf(stdout, "dv : "); 01285 //write_formatted_vector_fp_d(delta_v, "%10.3e", stdout); 01286 //fprintf(stdout, "v : "); 01287 //write_formatted_vector_fp_d(v, "%10.3e", stdout); 01288 01289 copy_vector_d(&e_dv_prev, e_dv); 01290 calc_vector_dot_prod_d(&e_dv_prev_dp, e_dv_prev, e_dv_prev); 01291 } 01292 01293 free_vector_d(v_cp); 01294 free_vector_d(delta_v); 01295 free_vector_d(eta_v); 01296 free_vector_d(p); 01297 free_vector_d(q); 01298 free_vector_d(a); 01299 free_vector_d(b); 01300 free_vector_d(e_dv); 01301 free_vector_d(e_dv_prev); 01302 free_vector_d(e_dv_diff); 01303 01304 if (err) 01305 { 01306 free_vector_d(*v_out); *v_out = NULL; 01307 } 01308 01309 return err; 01310 } 01311 01325 static Error* hyperdynamics_dx_hessian_eigenvalue_f 01326 ( 01327 Vector_f** e_dx_out, 01328 const Vector_f* v, 01329 float eta, 01330 void* params, 01331 void (*get_pt_from_params)(Vector_f**, const void*), 01332 Error* (*set_params_from_pt)(const Vector_f*, void*), 01333 Error* (*grad_energy_func)(Vector_f**, void*) 01334 ) 01335 { 01336 uint32_t n; 01337 uint32_t N; 01338 01339 Vector_f* eta_v = NULL; 01340 Vector_f* a = NULL; 01341 Vector_f* b = NULL; 01342 Vector_f* c = NULL; 01343 Vector_f* p = NULL; 01344 Vector_f* q = NULL; 01345 Error* err; 01346 01347 get_pt_from_params(&p, params); 01348 N = p->num_elts; 01349 01350 multiply_vector_by_scalar_f(&eta_v, v, eta); 01351 01352 assert(add_vectors_f(&q, p, eta_v) == NULL); 01353 01354 if ((err = set_params_from_pt(q, params)) || 01355 (err = grad_energy_func(&a, params))) 01356 { 01357 assert(set_params_from_pt(p, params) == NULL); 01358 free_vector_f(eta_v); 01359 free_vector_f(p); free_vector_f(q); 01360 free_vector_f(a); free_vector_f(b); free_vector_f(c); 01361 free_vector_f(*e_dx_out); *e_dx_out = NULL; 01362 return err; 01363 } 01364 01365 assert(subtract_vectors_f(&q, p, eta_v) == NULL); 01366 01367 if ((err = set_params_from_pt(q, params)) || 01368 (err = grad_energy_func(&b, params))) 01369 { 01370 assert(set_params_from_pt(p, params) == NULL); 01371 free_vector_f(eta_v); 01372 free_vector_f(p); free_vector_f(q); 01373 free_vector_f(a); free_vector_f(b); free_vector_f(c); 01374 free_vector_f(*e_dx_out); *e_dx_out = NULL; 01375 return err; 01376 } 01377 01378 assert(set_params_from_pt(p, params) == NULL); 01379 01380 if ((err = grad_energy_func(&c, params))) 01381 { 01382 free_vector_f(eta_v); 01383 free_vector_f(p); free_vector_f(q); 01384 free_vector_f(a); free_vector_f(b); free_vector_f(c); 01385 free_vector_f(*e_dx_out); *e_dx_out = NULL; 01386 return err; 01387 } 01388 01389 create_vector_f(e_dx_out, N); 01390 for (n = 0; n < N; n++) 01391 { 01392 (*e_dx_out)->elts[ n ] = (a->elts[n] + b->elts[n] - 2.0*c->elts[n]) / 01393 (eta*eta); 01394 } 01395 01396 free_vector_f(eta_v); 01397 free_vector_f(p); 01398 free_vector_f(q); 01399 free_vector_f(a); 01400 free_vector_f(b); 01401 free_vector_f(c); 01402 01403 return NULL; 01404 } 01405 01406 static Error* hyperdynamics_dx_hessian_eigenvalue_d 01407 ( 01408 Vector_d** e_dx_out, 01409 const Vector_d* v, 01410 double eta, 01411 void* params, 01412 void (*get_pt_from_params)(Vector_d**, const void*), 01413 Error* (*set_params_from_pt)(const Vector_d*, void*), 01414 Error* (*grad_energy_func)(Vector_d**, void*) 01415 ) 01416 { 01417 uint32_t n; 01418 uint32_t N; 01419 01420 Vector_d* eta_v = NULL; 01421 Vector_d* a = NULL; 01422 Vector_d* b = NULL; 01423 Vector_d* c = NULL; 01424 Vector_d* p = NULL; 01425 Vector_d* q = NULL; 01426 Error* err; 01427 01428 get_pt_from_params(&p, params); 01429 N = p->num_elts; 01430 01431 multiply_vector_by_scalar_d(&eta_v, v, eta); 01432 01433 assert(add_vectors_d(&q, p, eta_v) == NULL); 01434 01435 if ((err = set_params_from_pt(q, params)) || 01436 (err = grad_energy_func(&a, params))) 01437 { 01438 assert(set_params_from_pt(p, params) == NULL); 01439 free_vector_d(eta_v); 01440 free_vector_d(p); free_vector_d(q); 01441 free_vector_d(a); free_vector_d(b); free_vector_d(c); 01442 free_vector_d(*e_dx_out); *e_dx_out = NULL; 01443 return err; 01444 } 01445 01446 assert(subtract_vectors_d(&q, p, eta_v) == NULL); 01447 01448 if ((err = set_params_from_pt(q, params)) || 01449 (err = grad_energy_func(&b, params))) 01450 { 01451 assert(set_params_from_pt(p, params) == NULL); 01452 free_vector_d(eta_v); 01453 free_vector_d(p); free_vector_d(q); 01454 free_vector_d(a); free_vector_d(b); free_vector_d(c); 01455 free_vector_d(*e_dx_out); *e_dx_out = NULL; 01456 return err; 01457 } 01458 01459 if ((err = set_params_from_pt(p, params)) || 01460 (err = grad_energy_func(&c, params))) 01461 { 01462 assert(set_params_from_pt(p, params) == NULL); 01463 free_vector_d(eta_v); 01464 free_vector_d(p); free_vector_d(q); 01465 free_vector_d(a); free_vector_d(b); free_vector_d(c); 01466 free_vector_d(*e_dx_out); *e_dx_out = NULL; 01467 return err; 01468 } 01469 01470 create_vector_d(e_dx_out, N); 01471 for (n = 0; n < N; n++) 01472 { 01473 (*e_dx_out)->elts[ n ] = (a->elts[n] + b->elts[n] - 2.0*c->elts[n]) / 01474 (eta*eta); 01475 } 01476 01477 free_vector_d(eta_v); 01478 free_vector_d(p); 01479 free_vector_d(q); 01480 free_vector_d(a); 01481 free_vector_d(b); 01482 free_vector_d(c); 01483 01484 return NULL; 01485 } 01486 01500 static Error* hyperdynamics_hessgrad_eigenvalue_f 01501 ( 01502 float* e_out, 01503 float lambda, 01504 const Vector_f* v, 01505 float eta, 01506 void* params, 01507 void (*get_pt_from_params)(Vector_f**, const void*), 01508 Error* (*set_params_from_pt)(const Vector_f*, void*), 01509 Error* (*energy_func)(float*, void*), 01510 uint8_t positive 01511 ) 01512 { 01513 float e; 01514 float a, b; 01515 01516 Vector_f* eta_v = NULL; 01517 Vector_f* p = NULL; 01518 Vector_f* q = NULL; 01519 Error* err; 01520 01521 if ((err = hyperdynamics_hessian_eigenvalue_f(&e, v, eta, params, 01522 get_pt_from_params, set_params_from_pt, energy_func))) 01523 { 01524 free_vector_f(eta_v); 01525 free_vector_f(p); 01526 free_vector_f(q); 01527 return err; 01528 } 01529 01530 get_pt_from_params(&p, params); 01531 01532 multiply_vector_by_scalar_f(&eta_v, v, eta); 01533 01534 assert(add_vectors_f(&q, p, eta_v) == NULL); 01535 01536 if ((err = set_params_from_pt(q, params)) || 01537 (err = energy_func(&a, params))) 01538 { 01539 assert(set_params_from_pt(p, params) == NULL); 01540 free_vector_f(eta_v); 01541 free_vector_f(p); 01542 free_vector_f(q); 01543 return err; 01544 } 01545 01546 assert(subtract_vectors_f(&q, p, eta_v) == NULL); 01547 01548 if ((err = set_params_from_pt(q, params)) || 01549 (err = energy_func(&b, params))) 01550 { 01551 assert(set_params_from_pt(p, params) == NULL); 01552 free_vector_f(eta_v); 01553 free_vector_f(p); 01554 free_vector_f(q); 01555 return err; 01556 } 01557 01558 assert(set_params_from_pt(p, params) == NULL); 01559 01560 if (positive) 01561 { 01562 e += (0.25*lambda / (eta*eta)) * (a - b) * (a - b); 01563 } 01564 else 01565 { 01566 e -= (0.25*lambda / (eta*eta)) * (a - b) * (a - b); 01567 } 01568 01569 *e_out = e; 01570 01571 free_vector_f(eta_v); 01572 free_vector_f(p); 01573 free_vector_f(q); 01574 01575 return NULL; 01576 } 01577 01578 static Error* hyperdynamics_hessgrad_eigenvalue_d 01579 ( 01580 double* e_out, 01581 double lambda, 01582 const Vector_d* v, 01583 double eta, 01584 void* params, 01585 void (*get_pt_from_params)(Vector_d**, const void*), 01586 Error* (*set_params_from_pt)(const Vector_d*, void*), 01587 Error* (*energy_func)(double*, void*), 01588 uint8_t positive 01589 ) 01590 { 01591 double e; 01592 double a, b; 01593 01594 Vector_d* eta_v = NULL; 01595 Vector_d* p = NULL; 01596 Vector_d* q = NULL; 01597 Error* err; 01598 01599 if ((err = hyperdynamics_hessian_eigenvalue_d(&e, v, eta, params, 01600 get_pt_from_params, set_params_from_pt, energy_func))) 01601 { 01602 free_vector_d(eta_v); 01603 free_vector_d(p); 01604 free_vector_d(q); 01605 return err; 01606 } 01607 01608 get_pt_from_params(&p, params); 01609 01610 multiply_vector_by_scalar_d(&eta_v, v, eta); 01611 01612 assert(add_vectors_d(&q, p, eta_v) == NULL); 01613 01614 if ((err = set_params_from_pt(q, params)) || 01615 (err = energy_func(&a, params))) 01616 { 01617 assert(set_params_from_pt(p, params) == NULL); 01618 free_vector_d(eta_v); 01619 free_vector_d(p); 01620 free_vector_d(q); 01621 return err; 01622 } 01623 01624 assert(subtract_vectors_d(&q, p, eta_v) == NULL); 01625 01626 if ((err = set_params_from_pt(q, params)) || 01627 (err = energy_func(&b, params))) 01628 { 01629 assert(set_params_from_pt(p, params) == NULL); 01630 free_vector_d(eta_v); 01631 free_vector_d(p); 01632 free_vector_d(q); 01633 return err; 01634 } 01635 01636 assert(set_params_from_pt(p, params) == NULL); 01637 01638 if (positive) 01639 { 01640 e += (0.25*lambda / (eta*eta)) * (a - b) * (a - b); 01641 } 01642 else 01643 { 01644 e -= (0.25*lambda / (eta*eta)) * (a - b) * (a - b); 01645 } 01646 01647 *e_out = e; 01648 01649 free_vector_d(eta_v); 01650 free_vector_d(p); 01651 free_vector_d(q); 01652 01653 return NULL; 01654 } 01655 01669 static Error* hyperdynamics_proj_hessian_eigenvector_f 01670 ( 01671 float* g1p_out, 01672 float e_pos, 01673 float e_neg, 01674 float lambda 01675 ) 01676 { 01677 double d; 01678 01679 assert(fabs(lambda) > 1.0e-8); 01680 01681 d = (e_pos - e_neg) / lambda; 01682 //assert(d > 0); 01683 if (d < 1.0e-8) 01684 { 01685 d = 1.0e-8; 01686 } 01687 01688 *g1p_out = sqrt(0.5 * d); 01689 01690 return NULL; 01691 } 01692 01693 static Error* hyperdynamics_proj_hessian_eigenvector_d 01694 ( 01695 double* g1p_out, 01696 double e_pos, 01697 double e_neg, 01698 double lambda 01699 ) 01700 { 01701 double d; 01702 01703 assert(fabs(lambda) > 1.0e-8); 01704 01705 d = (e_pos - e_neg) / lambda; 01706 //assert(d > 0); 01707 if (d < 1.0e-8) 01708 { 01709 d = 1.0e-8; 01710 } 01711 01712 *g1p_out = sqrt(0.5 * d); 01713 01714 return NULL; 01715 } 01716 01730 static Error* hyperdynamics_hessgrad_eigenvector_f 01731 ( 01732 float* lambda_out, 01733 Vector_f** v_pos_out, 01734 Vector_f** v_neg_out, 01735 float eta, 01736 float gamma, 01737 void* params, 01738 void (*get_pt_from_params)(Vector_f**, const void*), 01739 Error* (*set_params_from_pt)(const Vector_f*, void*), 01740 Error* (*energy_func)(float*, void*), 01741 Error* (*grad_energy_func)(Vector_f**, void*) 01742 ) 01743 { 01744 uint32_t n; 01745 uint32_t N; 01746 uint8_t done; 01747 float g1p; 01748 float lambda; 01749 float lambda_cp; 01750 float e_pos; 01751 float e_neg; 01752 float e_pos_dlambda; 01753 float e_neg_dlambda; 01754 float e_pos_dlambda_diff; 01755 float e_neg_dlambda_diff; 01756 float e_pos_dlambda_prev; 01757 float e_neg_dlambda_prev; 01758 float c, d; 01759 float delta_g1p; 01760 float delta_e; 01761 float delta_lambda; 01762 float g; 01763 float e_pos_dv_dp; 01764 float e_neg_dv_dp; 01765 float e_pos_dv_prev_dp; 01766 float e_neg_dv_prev_dp; 01767 float e_pos_dlambda_dp; 01768 float e_neg_dlambda_dp; 01769 float e_pos_dlambda_prev_dp; 01770 float e_neg_dlambda_prev_dp; 01771 float e_pos_dv_beta; 01772 float e_neg_dv_beta; 01773 float e_pos_dlambda_beta; 01774 float e_neg_dlambda_beta; 01775 01776 Vector_f* v_pos; 01777 Vector_f* v_neg; 01778 Vector_f* v_pos_cp = NULL; 01779 Vector_f* v_neg_cp = NULL; 01780 Vector_f* delta_v_pos = NULL; 01781 Vector_f* delta_v_neg = NULL; 01782 Vector_f* eta_v = NULL; 01783 Vector_f* e_pos_dv = NULL; 01784 Vector_f* e_neg_dv = NULL; 01785 Vector_f* e_pos_dv_diff = NULL; 01786 Vector_f* e_neg_dv_diff = NULL; 01787 Vector_f* e_pos_dv_prev = NULL; 01788 Vector_f* e_neg_dv_prev = NULL; 01789 Vector_f* p = NULL; 01790 Vector_f* q = NULL; 01791 Vector_f* a = NULL; 01792 Vector_f* b = NULL; 01793 Error* err = NULL; 01794 01795 get_pt_from_params(&p, params); 01796 N = p->num_elts; 01797 01798 create_vector_f(v_pos_out, N); 01799 v_pos = *v_pos_out; 01800 01801 create_vector_f(v_neg_out, N); 01802 v_neg = *v_neg_out; 01803 01804 create_vector_f(&e_pos_dv, N); 01805 create_vector_f(&e_neg_dv, N); 01806 01807 lambda = *lambda_out; 01808 01809 /* May not be the best initialization for these. */ 01810 g1p = 0; 01811 e_pos = 0; 01812 e_neg = 0; 01813 01814 done = 0; 01815 01816 while (!done) 01817 { 01818 get_pt_from_params(&p, params); 01819 01820 /* Positive lambda */ 01821 multiply_vector_by_scalar_f(&eta_v, v_pos, eta); 01822 01823 assert(add_vectors_f(&q, p, eta_v) == NULL); 01824 01825 if ((err = set_params_from_pt(q, params)) || 01826 (err = grad_energy_func(&a, params)) || 01827 (err = energy_func(&c, params))) 01828 { 01829 assert(set_params_from_pt(p, params) == NULL); 01830 break; 01831 } 01832 01833 assert(subtract_vectors_f(&q, p, eta_v) == NULL); 01834 01835 if ((err = set_params_from_pt(q, params)) || 01836 (err = grad_energy_func(&b, params)) || 01837 (err = energy_func(&d, params))) 01838 { 01839 assert(set_params_from_pt(p, params) == NULL); 01840 break; 01841 } 01842 01843 for (n = 0; n < N; n++) 01844 { 01845 e_pos_dv->elts[n] = (a->elts[n] - b->elts[n]) / eta + 01846 (0.5*lambda / eta) * 01847 (c - d) * (a->elts[n] + b->elts[n]); 01848 } 01849 e_pos_dlambda = (0.5*(c - d) / eta) * (0.5*(c - d) / eta); 01850 01851 if (!e_pos_dv_prev) 01852 { 01853 copy_vector_f(&e_pos_dv_prev, e_pos_dv); 01854 calc_vector_dot_prod_f(&e_pos_dv_prev_dp, e_pos_dv_prev, 01855 e_pos_dv_prev); 01856 e_pos_dlambda_prev = e_pos_dlambda; 01857 e_pos_dlambda_prev_dp = e_pos_dlambda_prev * e_pos_dlambda_prev; 01858 } 01859 01860 subtract_vectors_f(&e_pos_dv_diff, e_pos_dv, e_pos_dv_prev); 01861 calc_vector_dot_prod_f(&e_pos_dv_dp, e_pos_dv, e_pos_dv_diff); 01862 01863 e_pos_dlambda_diff = e_pos_dlambda - e_pos_dlambda_prev; 01864 e_pos_dlambda_dp = e_pos_dlambda * e_pos_dlambda_diff; 01865 01866 e_pos_dv_beta = 01867 (e_pos_dv_prev_dp > 0) && (e_pos_dv_dp / e_pos_dv_prev_dp) > 0 01868 ? e_pos_dv_dp / e_pos_dv_prev_dp : 0; 01869 01870 e_pos_dlambda_beta = (e_pos_dlambda_prev_dp > 0) && 01871 (e_pos_dlambda_dp / e_pos_dlambda_prev_dp) > 0 01872 ? e_pos_dlambda_dp / e_pos_dlambda_prev_dp : 0; 01873 01874 multiply_vector_by_scalar_f(&e_pos_dv_prev, e_pos_dv_prev, 01875 e_pos_dv_beta); 01876 add_vectors_f(&e_pos_dv, e_pos_dv, e_pos_dv_prev); 01877 01878 e_pos_dlambda += e_pos_dlambda_beta * e_pos_dlambda_prev; 01879 01880 01881 /* Negative lambda */ 01882 multiply_vector_by_scalar_f(&eta_v, v_neg, eta); 01883 01884 assert(add_vectors_f(&q, p, eta_v) == NULL); 01885 01886 if ((err = set_params_from_pt(q, params)) || 01887 (err = grad_energy_func(&a, params)) || 01888 (err = energy_func(&c, params))) 01889 { 01890 assert(set_params_from_pt(p, params) == NULL); 01891 break; 01892 } 01893 01894 assert(subtract_vectors_f(&q, p, eta_v) == NULL); 01895 01896 if ((err = set_params_from_pt(q, params)) || 01897 (err = grad_energy_func(&b, params)) || 01898 (err = energy_func(&d, params))) 01899 { 01900 assert(set_params_from_pt(p, params) == NULL); 01901 break; 01902 } 01903 01904 for (n = 0; n < N; n++) 01905 { 01906 e_neg_dv->elts[n] = (a->elts[n] - b->elts[n]) / eta - 01907 (0.5*lambda / eta) * 01908 (c - d) * (a->elts[n] + b->elts[n]); 01909 } 01910 e_neg_dlambda = -1.0 * (0.5*(c - d) / eta) * (0.5*(c - d) / eta); 01911 01912 if (!e_neg_dv_prev) 01913 { 01914 copy_vector_f(&e_neg_dv_prev, e_neg_dv); 01915 calc_vector_dot_prod_f(&e_neg_dv_prev_dp, e_neg_dv_prev, 01916 e_neg_dv_prev); 01917 e_neg_dlambda_prev = e_neg_dlambda; 01918 e_neg_dlambda_prev_dp = e_neg_dlambda_prev * e_neg_dlambda_prev; 01919 } 01920 01921 subtract_vectors_f(&e_neg_dv_diff, e_neg_dv, e_neg_dv_prev); 01922 calc_vector_dot_prod_f(&e_neg_dv_dp, e_neg_dv, e_neg_dv_diff); 01923 01924 e_neg_dlambda_diff = e_neg_dlambda - e_neg_dlambda_prev; 01925 e_neg_dlambda_dp = e_neg_dlambda * e_neg_dlambda_diff; 01926 01927 e_neg_dv_beta = 01928 (e_neg_dv_prev_dp > 0) && (e_neg_dv_dp / e_neg_dv_prev_dp) > 0 01929 ? e_neg_dv_dp / e_neg_dv_prev_dp : 0; 01930 01931 e_neg_dlambda_beta = (e_neg_dlambda_prev_dp > 0) && 01932 (e_neg_dlambda_dp / e_neg_dlambda_prev_dp) > 0 01933 ? e_neg_dlambda_dp / e_neg_dlambda_prev_dp : 0; 01934 01935 multiply_vector_by_scalar_f(&e_neg_dv_prev, e_neg_dv_prev, 01936 e_neg_dv_beta); 01937 add_vectors_f(&e_neg_dv, e_neg_dv, e_neg_dv_prev); 01938 01939 e_neg_dlambda += e_neg_dlambda_beta * e_neg_dlambda_prev; 01940 01941 01942 assert(set_params_from_pt(p, params) == NULL); 01943 01944 01945 assert(copy_vector_f(&delta_v_pos, v_pos) == NULL); 01946 assert(copy_vector_f(&delta_v_neg, v_neg) == NULL); 01947 delta_g1p = g1p; 01948 delta_lambda = lambda; 01949 delta_e = e_pos + e_neg; 01950 done = 0; 01951 g = gamma; 01952 01953 while (!done) 01954 { 01955 lambda_cp = lambda; 01956 01957 lambda_cp -= g * e_pos_dlambda; 01958 lambda_cp -= g * e_neg_dlambda; 01959 01960 copy_vector_f(&v_pos_cp, v_pos); 01961 copy_vector_f(&v_neg_cp, v_neg); 01962 01963 for (n = 0; n < N; n++) 01964 { 01965 v_pos_cp->elts[ n ] -= g * e_pos_dv->elts[ n ]; 01966 v_neg_cp->elts[ n ] -= g * e_neg_dv->elts[ n ]; 01967 } 01968 normalize_vector_mag_f(&v_pos_cp, v_pos_cp); 01969 normalize_vector_mag_f(&v_neg_cp, v_neg_cp); 01970 01971 if ((err = hyperdynamics_hessgrad_eigenvalue_f(&e_pos, lambda_cp, 01972 v_pos_cp, eta, params, get_pt_from_params, 01973 set_params_from_pt, energy_func, 1)) || 01974 (err = hyperdynamics_hessgrad_eigenvalue_f(&e_neg, lambda_cp, 01975 v_neg_cp, eta, params, get_pt_from_params, 01976 set_params_from_pt, energy_func, 0))) 01977 { 01978 break; 01979 } 01980 01981 // TEMP 01982 //fprintf(stdout, "g1p: %10.3e %10.3e %10.3e %10.3e\n", 01983 // e_pos, e_neg, (delta_e - (e_pos+e_neg)), g); 01984 01985 g *= 0.5; 01986 01987 if (g < 1.0e-16 || (delta_e - (e_pos+e_neg)) >= 0) 01988 { 01989 done = 1; 01990 } 01991 } 01992 if (err) 01993 { 01994 break; 01995 } 01996 lambda = lambda_cp; 01997 01998 copy_vector_f(&v_pos, v_pos_cp); 01999 copy_vector_f(&v_neg, v_neg_cp); 02000 02001 delta_lambda = fabs(delta_lambda - lambda); 02002 delta_e = fabs(delta_e - (e_pos + e_neg)); 02003 02004 hyperdynamics_proj_hessian_eigenvector_f(&g1p, e_pos, e_neg, lambda); 02005 delta_g1p = fabs(delta_g1p - g1p); 02006 02007 done = 1; 02008 for (n = 0; n < N; n++) 02009 { 02010 delta_v_pos->elts[ n ] 02011 = (fabs(fabs(delta_v_pos->elts[ n ]) - 02012 fabs(v_pos->elts[ n ])) < 1.0e-6) 02013 ? fabs(fabs(delta_v_pos->elts[ n ]) - fabs(v_pos->elts[ n ])) 02014 : fabs(delta_v_pos->elts[ n ] - v_pos->elts[ n ]); 02015 02016 delta_v_neg->elts[ n ] 02017 = (fabs(fabs(delta_v_neg->elts[ n ]) - 02018 fabs(v_neg->elts[ n ])) < 1.0e-6) 02019 ? fabs(fabs(delta_v_neg->elts[ n ]) - fabs(v_neg->elts[ n ])) 02020 : fabs(delta_v_neg->elts[ n ] - v_neg->elts[ n ]); 02021 02022 done = (done && (delta_v_pos->elts[ n ] <= 1.0e-6) 02023 && (delta_v_neg->elts[ n ] <= 1.0e-6)); 02024 } 02025 done = (done && (delta_lambda <= 1.0e-6)); 02026 done = (done || (delta_g1p <= 1.0e-4)); 02027 02028 copy_vector_f(&e_pos_dv_prev, e_pos_dv); 02029 calc_vector_dot_prod_f(&e_pos_dv_prev_dp, e_pos_dv_prev, e_pos_dv_prev); 02030 02031 e_pos_dlambda_prev = e_pos_dlambda; 02032 e_pos_dlambda_prev_dp = e_pos_dlambda_prev * e_pos_dlambda_prev; 02033 02034 copy_vector_f(&e_neg_dv_prev, e_neg_dv); 02035 calc_vector_dot_prod_f(&e_neg_dv_prev_dp, e_neg_dv_prev, e_neg_dv_prev); 02036 02037 e_neg_dlambda_prev = e_neg_dlambda; 02038 e_neg_dlambda_prev_dp = e_neg_dlambda_prev * e_neg_dlambda_prev; 02039 } 02040 02041 *lambda_out = lambda; 02042 02043 free_vector_f(v_pos_cp); 02044 free_vector_f(v_neg_cp); 02045 free_vector_f(delta_v_pos); 02046 free_vector_f(delta_v_neg); 02047 free_vector_f(eta_v); 02048 free_vector_f(e_pos_dv); 02049 free_vector_f(e_neg_dv); 02050 free_vector_f(e_pos_dv_diff); 02051 free_vector_f(e_neg_dv_diff); 02052 free_vector_f(e_pos_dv_prev); 02053 free_vector_f(e_neg_dv_prev); 02054 free_vector_f(p); 02055 free_vector_f(q); 02056 free_vector_f(a); 02057 free_vector_f(b); 02058 02059 if (err) 02060 { 02061 free_vector_f(*v_pos_out); *v_pos_out = NULL; 02062 free_vector_f(*v_neg_out); *v_neg_out = NULL; 02063 } 02064 02065 return err; 02066 } 02067 02068 static Error* hyperdynamics_hessgrad_eigenvector_d 02069 ( 02070 double* lambda_out, 02071 Vector_d** v_pos_out, 02072 Vector_d** v_neg_out, 02073 double eta, 02074 double gamma, 02075 void* params, 02076 void (*get_pt_from_params)(Vector_d**, const void*), 02077 Error* (*set_params_from_pt)(const Vector_d*, void*), 02078 Error* (*energy_func)(double*, void*), 02079 Error* (*grad_energy_func)(Vector_d**, void*) 02080 ) 02081 { 02082 uint32_t n; 02083 uint32_t N; 02084 uint8_t done; 02085 double g1p; 02086 double lambda; 02087 double lambda_cp; 02088 double e_pos; 02089 double e_neg; 02090 double e_pos_dlambda; 02091 double e_neg_dlambda; 02092 double e_pos_dlambda_diff; 02093 double e_neg_dlambda_diff; 02094 double e_pos_dlambda_prev; 02095 double e_neg_dlambda_prev; 02096 double c, d; 02097 double delta_g1p; 02098 double delta_e; 02099 double delta_lambda; 02100 double g; 02101 double e_pos_dv_dp; 02102 double e_neg_dv_dp; 02103 double e_pos_dv_prev_dp; 02104 double e_neg_dv_prev_dp; 02105 double e_pos_dlambda_dp; 02106 double e_neg_dlambda_dp; 02107 double e_pos_dlambda_prev_dp; 02108 double e_neg_dlambda_prev_dp; 02109 double e_pos_dv_beta; 02110 double e_neg_dv_beta; 02111 double e_pos_dlambda_beta; 02112 double e_neg_dlambda_beta; 02113 02114 Vector_d* v_pos; 02115 Vector_d* v_neg; 02116 Vector_d* v_pos_cp = NULL; 02117 Vector_d* v_neg_cp = NULL; 02118 Vector_d* delta_v_pos = NULL; 02119 Vector_d* delta_v_neg = NULL; 02120 Vector_d* eta_v = NULL; 02121 Vector_d* e_pos_dv = NULL; 02122 Vector_d* e_neg_dv = NULL; 02123 Vector_d* e_pos_dv_diff = NULL; 02124 Vector_d* e_neg_dv_diff = NULL; 02125 Vector_d* e_pos_dv_prev = NULL; 02126 Vector_d* e_neg_dv_prev = NULL; 02127 Vector_d* p = NULL; 02128 Vector_d* q = NULL; 02129 Vector_d* a = NULL; 02130 Vector_d* b = NULL; 02131 Error* err = NULL; 02132 02133 get_pt_from_params(&p, params); 02134 N = p->num_elts; 02135 02136 create_vector_d(v_pos_out, N); 02137 v_pos = *v_pos_out; 02138 02139 create_vector_d(v_neg_out, N); 02140 v_neg = *v_neg_out; 02141 02142 create_vector_d(&e_pos_dv, N); 02143 create_vector_d(&e_neg_dv, N); 02144 02145 lambda = *lambda_out; 02146 02147 /* May not be the best initialization for these. */ 02148 e_pos = 0; 02149 e_neg = 0; 02150 g1p = 0; 02151 02152 done = 0; 02153 02154 while (!done) 02155 { 02156 get_pt_from_params(&p, params); 02157 02158 /* Positive lambda */ 02159 multiply_vector_by_scalar_d(&eta_v, v_pos, eta); 02160 02161 assert(add_vectors_d(&q, p, eta_v) == NULL); 02162 02163 if ((err = set_params_from_pt(q, params)) || 02164 (err = grad_energy_func(&a, params)) || 02165 (err = energy_func(&c, params))) 02166 { 02167 assert(set_params_from_pt(p, params) == NULL); 02168 break; 02169 } 02170 02171 assert(subtract_vectors_d(&q, p, eta_v) == NULL); 02172 02173 if ((err = set_params_from_pt(q, params)) || 02174 (err = grad_energy_func(&b, params)) || 02175 (err = energy_func(&d, params))) 02176 { 02177 assert(set_params_from_pt(p, params) == NULL); 02178 break; 02179 } 02180 02181 for (n = 0; n < N; n++) 02182 { 02183 e_pos_dv->elts[n] = (a->elts[n] - b->elts[n]) / eta + 02184 (0.5*lambda / eta) * 02185 (c - d) * (a->elts[n] + b->elts[n]); 02186 } 02187 e_pos_dlambda = (0.5*(c - d) / eta) * (0.5*(c - d) / eta); 02188 02189 if (!e_pos_dv_prev) 02190 { 02191 copy_vector_d(&e_pos_dv_prev, e_pos_dv); 02192 calc_vector_dot_prod_d(&e_pos_dv_prev_dp, e_pos_dv_prev, 02193 e_pos_dv_prev); 02194 e_pos_dlambda_prev = e_pos_dlambda; 02195 e_pos_dlambda_prev_dp = e_pos_dlambda_prev * e_pos_dlambda_prev; 02196 } 02197 02198 subtract_vectors_d(&e_pos_dv_diff, e_pos_dv, e_pos_dv_prev); 02199 calc_vector_dot_prod_d(&e_pos_dv_dp, e_pos_dv, e_pos_dv_diff); 02200 02201 e_pos_dlambda_diff = e_pos_dlambda - e_pos_dlambda_prev; 02202 e_pos_dlambda_dp = e_pos_dlambda * e_pos_dlambda_diff; 02203 02204 e_pos_dv_beta = 02205 (e_pos_dv_prev_dp > 0) && (e_pos_dv_dp / e_pos_dv_prev_dp) > 0 02206 ? e_pos_dv_dp / e_pos_dv_prev_dp : 0; 02207 02208 e_pos_dlambda_beta = (e_pos_dlambda_prev_dp > 0) && 02209 (e_pos_dlambda_dp / e_pos_dlambda_prev_dp) > 0 02210 ? e_pos_dlambda_dp / e_pos_dlambda_prev_dp : 0; 02211 02212 multiply_vector_by_scalar_d(&e_pos_dv_prev, e_pos_dv_prev, 02213 e_pos_dv_beta); 02214 add_vectors_d(&e_pos_dv, e_pos_dv, e_pos_dv_prev); 02215 02216 e_pos_dlambda += e_pos_dlambda_beta * e_pos_dlambda_prev; 02217 02218 02219 /* Negative lambda */ 02220 multiply_vector_by_scalar_d(&eta_v, v_neg, eta); 02221 02222 assert(add_vectors_d(&q, p, eta_v) == NULL); 02223 02224 if ((err = set_params_from_pt(q, params)) || 02225 (err = grad_energy_func(&a, params)) || 02226 (err = energy_func(&c, params))) 02227 { 02228 assert(set_params_from_pt(p, params) == NULL); 02229 break; 02230 } 02231 02232 assert(subtract_vectors_d(&q, p, eta_v) == NULL); 02233 02234 if ((err = set_params_from_pt(q, params)) || 02235 (err = grad_energy_func(&b, params)) || 02236 (err = energy_func(&d, params))) 02237 { 02238 assert(set_params_from_pt(p, params) == NULL); 02239 break; 02240 } 02241 02242 for (n = 0; n < N; n++) 02243 { 02244 e_neg_dv->elts[n] = (a->elts[n] - b->elts[n]) / eta - 02245 (0.5*lambda / eta) * 02246 (c - d) * (a->elts[n] + b->elts[n]); 02247 } 02248 e_neg_dlambda = -1.0 * (0.5*(c - d) / eta) * (0.5*(c - d) / eta); 02249 02250 if (!e_neg_dv_prev) 02251 { 02252 copy_vector_d(&e_neg_dv_prev, e_neg_dv); 02253 calc_vector_dot_prod_d(&e_neg_dv_prev_dp, e_neg_dv_prev, 02254 e_neg_dv_prev); 02255 e_neg_dlambda_prev = e_neg_dlambda; 02256 e_neg_dlambda_prev_dp = e_neg_dlambda_prev * e_neg_dlambda_prev; 02257 } 02258 02259 subtract_vectors_d(&e_neg_dv_diff, e_neg_dv, e_neg_dv_prev); 02260 calc_vector_dot_prod_d(&e_neg_dv_dp, e_neg_dv, e_neg_dv_diff); 02261 02262 e_neg_dlambda_diff = e_neg_dlambda - e_neg_dlambda_prev; 02263 e_neg_dlambda_dp = e_neg_dlambda * e_neg_dlambda_diff; 02264 02265 e_neg_dv_beta = 02266 (e_neg_dv_prev_dp > 0) && (e_neg_dv_dp / e_neg_dv_prev_dp) > 0 02267 ? e_neg_dv_dp / e_neg_dv_prev_dp : 0; 02268 02269 e_neg_dlambda_beta = (e_neg_dlambda_prev_dp > 0) && 02270 (e_neg_dlambda_dp / e_neg_dlambda_prev_dp) > 0 02271 ? e_neg_dlambda_dp / e_neg_dlambda_prev_dp : 0; 02272 02273 multiply_vector_by_scalar_d(&e_neg_dv_prev, e_neg_dv_prev, 02274 e_neg_dv_beta); 02275 add_vectors_d(&e_neg_dv, e_neg_dv, e_neg_dv_prev); 02276 02277 e_neg_dlambda += e_neg_dlambda_beta * e_neg_dlambda_prev; 02278 02279 02280 assert(set_params_from_pt(p, params) == NULL); 02281 02282 02283 assert(copy_vector_d(&delta_v_pos, v_pos) == NULL); 02284 assert(copy_vector_d(&delta_v_neg, v_neg) == NULL); 02285 delta_g1p = g1p; 02286 delta_lambda = lambda; 02287 delta_e = e_pos + e_neg; 02288 done = 0; 02289 g = gamma; 02290 02291 while (!done) 02292 { 02293 lambda_cp = lambda; 02294 02295 lambda_cp -= g * e_pos_dlambda; 02296 lambda_cp -= g * e_neg_dlambda; 02297 02298 copy_vector_d(&v_pos_cp, v_pos); 02299 copy_vector_d(&v_neg_cp, v_neg); 02300 02301 for (n = 0; n < N; n++) 02302 { 02303 v_pos_cp->elts[ n ] -= g * e_pos_dv->elts[ n ]; 02304 v_neg_cp->elts[ n ] -= g * e_neg_dv->elts[ n ]; 02305 } 02306 normalize_vector_mag_d(&v_pos_cp, v_pos_cp); 02307 normalize_vector_mag_d(&v_neg_cp, v_neg_cp); 02308 02309 if ((err = hyperdynamics_hessgrad_eigenvalue_d(&e_pos, lambda_cp, 02310 v_pos_cp, eta, params, get_pt_from_params, 02311 set_params_from_pt, energy_func, 1)) || 02312 (err = hyperdynamics_hessgrad_eigenvalue_d(&e_neg, lambda_cp, 02313 v_neg_cp, eta, params, get_pt_from_params, 02314 set_params_from_pt, energy_func, 0))) 02315 { 02316 break; 02317 } 02318 02319 g *= 0.5; 02320 02321 if (g < 1.0e-128 || (delta_e - (e_pos+e_neg)) >= 0) 02322 { 02323 done = 1; 02324 } 02325 } 02326 if (err) 02327 { 02328 break; 02329 } 02330 lambda = lambda_cp; 02331 02332 copy_vector_d(&v_pos, v_pos_cp); 02333 copy_vector_d(&v_neg, v_neg_cp); 02334 02335 delta_lambda = fabs(delta_lambda - lambda); 02336 delta_e = fabs(delta_e - (e_pos + e_neg)); 02337 02338 hyperdynamics_proj_hessian_eigenvector_d(&g1p, e_pos, e_neg, lambda); 02339 delta_g1p = fabs(delta_g1p - g1p); 02340 02341 done = 1; 02342 for (n = 0; n < N; n++) 02343 { 02344 delta_v_pos->elts[ n ] 02345 = (fabs(fabs(delta_v_pos->elts[ n ]) - 02346 fabs(v_pos->elts[ n ])) < 1.0e-8) 02347 ? fabs(fabs(delta_v_pos->elts[ n ]) - fabs(v_pos->elts[ n ])) 02348 : fabs(delta_v_pos->elts[ n ] - v_pos->elts[ n ]); 02349 02350 delta_v_neg->elts[ n ] 02351 = (fabs(fabs(delta_v_neg->elts[ n ]) - 02352 fabs(v_neg->elts[ n ])) < 1.0e-8) 02353 ? fabs(fabs(delta_v_neg->elts[ n ]) - fabs(v_neg->elts[ n ])) 02354 : fabs(delta_v_neg->elts[ n ] - v_neg->elts[ n ]); 02355 02356 done = (done && (delta_v_pos->elts[ n ] <= 1.0e-8) 02357 && (delta_v_neg->elts[ n ] <= 1.0e-8)); 02358 } 02359 done = (done && (delta_lambda <= 1.0e-8)); 02360 done = (done || (delta_g1p <= 1.0e-4)); 02361 02362 copy_vector_d(&e_pos_dv_prev, e_pos_dv); 02363 calc_vector_dot_prod_d(&e_pos_dv_prev_dp, e_pos_dv_prev, e_pos_dv_prev); 02364 02365 e_pos_dlambda_prev = e_pos_dlambda; 02366 e_pos_dlambda_prev_dp = e_pos_dlambda_prev * e_pos_dlambda_prev; 02367 02368 copy_vector_d(&e_neg_dv_prev, e_neg_dv); 02369 calc_vector_dot_prod_d(&e_neg_dv_prev_dp, e_neg_dv_prev, e_neg_dv_prev); 02370 02371 e_neg_dlambda_prev = e_neg_dlambda; 02372 e_neg_dlambda_prev_dp = e_neg_dlambda_prev * e_neg_dlambda_prev; 02373 } 02374 02375 *lambda_out = lambda; 02376 02377 free_vector_d(v_pos_cp); 02378 free_vector_d(v_neg_cp); 02379 free_vector_d(delta_v_pos); 02380 free_vector_d(delta_v_neg); 02381 free_vector_d(eta_v); 02382 free_vector_d(e_pos_dv); 02383 free_vector_d(e_neg_dv); 02384 free_vector_d(e_pos_dv_diff); 02385 free_vector_d(e_neg_dv_diff); 02386 free_vector_d(e_pos_dv_prev); 02387 free_vector_d(e_neg_dv_prev); 02388 free_vector_d(p); 02389 free_vector_d(q); 02390 free_vector_d(a); 02391 free_vector_d(b); 02392 02393 if (err) 02394 { 02395 free_vector_d(*v_pos_out); *v_pos_out = NULL; 02396 free_vector_d(*v_neg_out); *v_neg_out = NULL; 02397 } 02398 02399 return err; 02400 } 02401 02415 static Error* hyperdynamics_dx_hessgrad_eigenvalue_f 02416 ( 02417 Vector_f** e_lambda_dx_out, 02418 float lambda, 02419 const Vector_f* v, 02420 float eta, 02421 void* params, 02422 void (*get_pt_from_params)(Vector_f**, const void*), 02423 Error* (*set_params_from_pt)(const Vector_f*, void*), 02424 Error* (*energy_func)(float*, void*), 02425 Error* (*grad_energy_func)(Vector_f**, void*), 02426 uint8_t positive 02427 ) 02428 { 02429 uint32_t n; 02430 uint32_t N; 02431 float a, b; 02432 02433 Vector_f* e_lambda_dx; 02434 Vector_f* e_dx = NULL; 02435 Vector_f* eta_v = NULL; 02436 Vector_f* p = NULL; 02437 Vector_f* q = NULL; 02438 Vector_f* c = NULL; 02439 Vector_f* d = NULL; 02440 Error* err; 02441 02442 if ((err = hyperdynamics_dx_hessian_eigenvalue_f(&e_dx, v, eta, params, 02443 get_pt_from_params, set_params_from_pt, grad_energy_func))) 02444 { 02445 return err; 02446 } 02447 02448 get_pt_from_params(&p, params); 02449 N = p->num_elts; 02450 02451 multiply_vector_by_scalar_f(&eta_v, v, eta); 02452 02453 assert(add_vectors_f(&q, p, eta_v) == NULL); 02454 02455 if ((err = set_params_from_pt(q, params)) || 02456 (err = energy_func(&a, params)) || 02457 (err = grad_energy_func(&c, params))) 02458 { 02459 assert(set_params_from_pt(p, params) == NULL); 02460 free_vector_f(e_dx); 02461 free_vector_f(eta_v); 02462 free_vector_f(p); free_vector_f(q); 02463 free_vector_f(c); free_vector_f(d); 02464 return err; 02465 } 02466 02467 assert(subtract_vectors_f(&q, p, eta_v) == NULL); 02468 02469 if ((err = set_params_from_pt(q, params)) || 02470 (err = energy_func(&b, params)) || 02471 (err = grad_energy_func(&d, params))) 02472 { 02473 assert(set_params_from_pt(p, params) == NULL); 02474 free_vector_f(e_dx); 02475 free_vector_f(eta_v); 02476 free_vector_f(p); free_vector_f(q); 02477 free_vector_f(c); free_vector_f(d); 02478 return err; 02479 } 02480 02481 assert(set_params_from_pt(p, params) == NULL); 02482 02483 create_vector_f(e_lambda_dx_out, N); 02484 e_lambda_dx = *e_lambda_dx_out; 02485 for (n = 0; n < N; n++) 02486 { 02487 e_lambda_dx->elts[ n ] = e_dx->elts[ n ]; 02488 02489 if (positive) 02490 { 02491 e_lambda_dx->elts[ n ] += 0.5*lambda * (a - b) * 02492 (c->elts[n] - d->elts[n]) / (eta*eta); 02493 } 02494 else 02495 { 02496 e_lambda_dx->elts[ n ] -= 0.5*lambda * (a - b) * 02497 (c->elts[n] - d->elts[n]) / (eta*eta); 02498 } 02499 } 02500 02501 free_vector_f(e_dx); 02502 free_vector_f(eta_v); 02503 free_vector_f(p); 02504 free_vector_f(q); 02505 free_vector_f(c); 02506 free_vector_f(d); 02507 02508 return NULL; 02509 } 02510 02511 static Error* hyperdynamics_dx_hessgrad_eigenvalue_d 02512 ( 02513 Vector_d** e_lambda_dx_out, 02514 double lambda, 02515 const Vector_d* v, 02516 double eta, 02517 void* params, 02518 void (*get_pt_from_params)(Vector_d**, const void*), 02519 Error* (*set_params_from_pt)(const Vector_d*, void*), 02520 Error* (*energy_func)(double*, void*), 02521 Error* (*grad_energy_func)(Vector_d**, void*), 02522 uint8_t positive 02523 ) 02524 { 02525 uint32_t n; 02526 uint32_t N; 02527 double a, b; 02528 02529 Vector_d* e_lambda_dx; 02530 Vector_d* e_dx = NULL; 02531 Vector_d* eta_v = NULL; 02532 Vector_d* p = NULL; 02533 Vector_d* q = NULL; 02534 Vector_d* c = NULL; 02535 Vector_d* d = NULL; 02536 Error* err; 02537 02538 if ((err = hyperdynamics_dx_hessian_eigenvalue_d(&e_dx, v, eta, params, 02539 get_pt_from_params, set_params_from_pt, grad_energy_func))) 02540 { 02541 return err; 02542 } 02543 02544 get_pt_from_params(&p, params); 02545 N = p->num_elts; 02546 02547 multiply_vector_by_scalar_d(&eta_v, v, eta); 02548 02549 assert(add_vectors_d(&q, p, eta_v) == NULL); 02550 02551 if ((err = set_params_from_pt(q, params)) || 02552 (err = energy_func(&a, params)) || 02553 (err = grad_energy_func(&c, params))) 02554 { 02555 assert(set_params_from_pt(p, params) == NULL); 02556 free_vector_d(e_dx); 02557 free_vector_d(eta_v); 02558 free_vector_d(p); free_vector_d(q); 02559 free_vector_d(c); free_vector_d(d); 02560 return err; 02561 } 02562 02563 assert(subtract_vectors_d(&q, p, eta_v) == NULL); 02564 02565 if ((err = set_params_from_pt(q, params)) || 02566 (err = energy_func(&b, params)) || 02567 (err = grad_energy_func(&d, params))) 02568 { 02569 assert(set_params_from_pt(p, params) == NULL); 02570 free_vector_d(e_dx); 02571 free_vector_d(eta_v); 02572 free_vector_d(p); free_vector_d(q); 02573 free_vector_d(c); free_vector_d(d); 02574 return err; 02575 } 02576 02577 assert(set_params_from_pt(p, params) == NULL); 02578 02579 create_vector_d(e_lambda_dx_out, N); 02580 e_lambda_dx = *e_lambda_dx_out; 02581 for (n = 0; n < N; n++) 02582 { 02583 e_lambda_dx->elts[ n ] = e_dx->elts[ n ]; 02584 02585 if (positive) 02586 { 02587 e_lambda_dx->elts[ n ] += 0.5*lambda * (a - b) * 02588 (c->elts[n] - d->elts[n]) / (eta*eta); 02589 } 02590 else 02591 { 02592 e_lambda_dx->elts[ n ] -= 0.5*lambda * (a - b) * 02593 (c->elts[n] - d->elts[n]) / (eta*eta); 02594 } 02595 } 02596 02597 free_vector_d(e_dx); 02598 free_vector_d(eta_v); 02599 free_vector_d(p); 02600 free_vector_d(q); 02601 free_vector_d(c); 02602 free_vector_d(d); 02603 02604 return NULL; 02605 } 02606 02620 static Error* hyperdynamics_dx_proj_hessian_eigenvector_f 02621 ( 02622 Vector_f** g1p_dx_out, 02623 const Vector_f* e_pos_dx, 02624 const Vector_f* e_neg_dx, 02625 float g1p, 02626 float lambda 02627 ) 02628 { 02629 uint32_t n; 02630 uint32_t N; 02631 02632 N = e_pos_dx->num_elts; 02633 create_vector_f(g1p_dx_out, N); 02634 02635 for (n = 0; n < N; n++) 02636 { 02637 (*g1p_dx_out)->elts[ n ] = (e_pos_dx->elts[n] - e_neg_dx->elts[n]) / 02638 (g1p*4.0*lambda); 02639 } 02640 02641 return NULL; 02642 } 02643 02644 static Error* hyperdynamics_dx_proj_hessian_eigenvector_d 02645 ( 02646 Vector_d** g1p_dx_out, 02647 const Vector_d* e_pos_dx, 02648 const Vector_d* e_neg_dx, 02649 double g1p, 02650 double lambda 02651 ) 02652 { 02653 uint32_t n; 02654 uint32_t N; 02655 02656 N = e_pos_dx->num_elts; 02657 create_vector_d(g1p_dx_out, N); 02658 02659 for (n = 0; n < N; n++) 02660 { 02661 (*g1p_dx_out)->elts[ n ] = (e_pos_dx->elts[n] - e_neg_dx->elts[n]) / 02662 (g1p*4.0*lambda); 02663 } 02664 02665 return NULL; 02666 } 02667 02710 Error* langevin_hyperdynamics_1_f 02711 ( 02712 uint32_t iterations, 02713 float delta_t, 02714 float gamma, 02715 float eta, 02716 float h, 02717 float d, 02718 void* params, 02719 void (*get_pt_from_params)(Vector_f** p_out, const void* params), 02720 Error* (*set_params_from_pt)(const Vector_f* p, void* params), 02721 Error* (*energy_func)(float* energy_out, void* params), 02722 Error* (*grad_energy_func)(Vector_f** grad_out, void* params), 02723 Error* (*accept_sample)(const Vector_f* sample, void* params, float energy_bias) 02724 ) 02725 { 02726 uint32_t D; 02727 02728 Vector_f* p = NULL; 02729 Vector_f* delta_t_v = NULL; 02730 Error* err; 02731 02732 get_pt_from_params(&p, params); 02733 D = p->num_elts; 02734 02735 create_init_vector_f(&delta_t_v, D, delta_t); 02736 02737 err = langevin_hyperdynamics_2_f(iterations, delta_t_v, gamma, eta, h, d, 02738 params, get_pt_from_params, set_params_from_pt, energy_func, 02739 grad_energy_func, accept_sample); 02740 02741 free_vector_f(p); 02742 free_vector_f(delta_t_v); 02743 02744 return err; 02745 } 02746 02776 Error* langevin_hyperdynamics_2_f 02777 ( 02778 uint32_t iterations, 02779 const Vector_f* delta_t, 02780 float gamma, 02781 float eta, 02782 float h, 02783 float d, 02784 void* params, 02785 void (*get_pt_from_params)(Vector_f** p_out, const void* params), 02786 Error* (*set_params_from_pt)(const Vector_f* p, void* params), 02787 Error* (*energy_func)(float* energy_out, void* params), 02788 Error* (*grad_energy_func)(Vector_f** grad_out, void* params), 02789 Error* (*accept_sample)(const Vector_f* sample, void* params, float energy_bias) 02790 ) 02791 { 02792 uint32_t i; 02793 uint32_t n; 02794 uint32_t N; 02795 float gauss; 02796 float lambda; 02797 float e; 02798 float e_pos; 02799 float e_neg; 02800 float g1p; 02801 float Vb; 02802 float Vb_dx; 02803 float dt; 02804 02805 Vector_f* p = NULL; 02806 Vector_f* v = NULL; 02807 Vector_f* v_pos = NULL; 02808 Vector_f* v_neg = NULL; 02809 Vector_f* e_dx = NULL; 02810 Vector_f* e_pos_dx = NULL; 02811 Vector_f* e_neg_dx = NULL; 02812 Vector_f* g1p_dx = NULL; 02813 Vector_f* V_dx = NULL; 02814 Error* err = NULL; 02815 02816 get_pt_from_params(&p, params); 02817 N = p->num_elts; 02818 02819 /* Randomly initialize lambda and the eigenvectors. */ 02820 create_random_vector_f(&v, N, -1, 1); 02821 normalize_vector_mag_f(&v, v); 02822 02823 create_random_vector_f(&v_pos, N, -1, 1); 02824 normalize_vector_mag_f(&v_pos, v_pos); 02825 02826 create_random_vector_f(&v_neg, N, -1, 1); 02827 normalize_vector_mag_f(&v_neg, v_neg); 02828 02829 lambda = sample_uniform_pdf_f(-1.0e3, 1.0e3); 02830 02831 for (i = 0; i < iterations; i++) 02832 { 02833 if ((err = hyperdynamics_hessian_eigenvector_f(&v, eta, gamma, 02834 params, get_pt_from_params, set_params_from_pt, 02835 energy_func, grad_energy_func))) 02836 { 02837 break; 02838 } 02839 02840 if ((err = hyperdynamics_hessian_eigenvalue_f(&e, v, eta, params, 02841 get_pt_from_params, set_params_from_pt, energy_func))) 02842 { 02843 break; 02844 } 02845 02846 if ((err = hyperdynamics_dx_hessian_eigenvalue_f(&e_dx, v, eta, params, 02847 get_pt_from_params, set_params_from_pt, 02848 grad_energy_func))) 02849 { 02850 break; 02851 } 02852 02853 if ((err = hyperdynamics_hessgrad_eigenvector_f(&lambda, &v_pos, &v_neg, 02854 eta, gamma, params, get_pt_from_params, 02855 set_params_from_pt, energy_func, grad_energy_func))) 02856 { 02857 break; 02858 } 02859 02860 if ((err = hyperdynamics_hessgrad_eigenvalue_f(&e_pos, lambda, v_pos, 02861 eta, params, get_pt_from_params, set_params_from_pt, 02862 energy_func, 1))) 02863 { 02864 break; 02865 } 02866 02867 if ((err = hyperdynamics_hessgrad_eigenvalue_f(&e_neg, lambda, v_neg, 02868 eta, params, get_pt_from_params, set_params_from_pt, 02869 energy_func, 0))) 02870 { 02871 break; 02872 } 02873 02874 if ((err = hyperdynamics_dx_hessgrad_eigenvalue_f(&e_pos_dx, lambda, 02875 v_pos, eta, params, get_pt_from_params, 02876 set_params_from_pt, energy_func, grad_energy_func, 1))) 02877 { 02878 break; 02879 } 02880 02881 if ((err = hyperdynamics_dx_hessgrad_eigenvalue_f(&e_neg_dx, lambda, 02882 v_neg, eta, params, get_pt_from_params, 02883 set_params_from_pt, energy_func, grad_energy_func, 0))) 02884 { 02885 break; 02886 } 02887 02888 if ((err = hyperdynamics_proj_hessian_eigenvector_f(&g1p, e_pos, e_neg, 02889 lambda))) 02890 { 02891 break; 02892 } 02893 02894 if ((err = hyperdynamics_dx_proj_hessian_eigenvector_f(&g1p_dx, 02895 e_pos_dx, e_neg_dx, g1p, lambda))) 02896 { 02897 break; 02898 } 02899 02900 if ((err = grad_energy_func(&V_dx, params))) 02901 { 02902 break; 02903 } 02904 02905 get_pt_from_params(&p, params); 02906 02907 Vb = 0.5*h * (1 + e / sqrt(e*e + g1p*g1p/(d*d))); 02908 02909 for (n = 0; n < N; n++) 02910 { 02911 Vb_dx = (h / (2*sqrt((e*e) + ((g1p*g1p)/(d*d))))) * 02912 (e_dx->elts[n] - e*(e*e_dx->elts[n] + 02913 (g1p/(d*d))*g1p_dx->elts[n]) / 02914 (e*e + (g1p*g1p)/(d*d))); 02915 02916 dt = delta_t->elts[ n ]; 02917 gauss = sample_standard_gaussian_pdf_f(-6.0, 6.0); 02918 02919 p->elts[ n ] -= dt*(0.5*dt*(V_dx->elts[n]+Vb_dx) + gauss); 02920 } 02921 02922 if ((err = accept_sample(p, params, Vb))) 02923 { 02924 break; 02925 } 02926 } 02927 02928 free_vector_f(p); 02929 free_vector_f(v); 02930 free_vector_f(v_pos); 02931 free_vector_f(v_neg); 02932 free_vector_f(e_dx); 02933 free_vector_f(e_pos_dx); 02934 free_vector_f(e_neg_dx); 02935 free_vector_f(g1p_dx); 02936 free_vector_f(V_dx); 02937 02938 return err; 02939 } 02940 02969 Error* langevin_hyperdynamics_1_d 02970 ( 02971 uint32_t iterations, 02972 double delta_t, 02973 double gamma, 02974 double eta, 02975 double h, 02976 double d, 02977 void* params, 02978 void (*get_pt_from_params)(Vector_d** p_out, const void* params), 02979 Error* (*set_params_from_pt)(const Vector_d* p, void* params), 02980 Error* (*energy_func)(double* energy_out, void* params), 02981 Error* (*grad_energy_func)(Vector_d** grad_out, void* params), 02982 Error* (*accept_sample)(const Vector_d* sample, void* params, double energy_bias) 02983 ) 02984 { 02985 uint32_t D; 02986 02987 Vector_d* p = NULL; 02988 Vector_d* delta_t_v = NULL; 02989 Error* err; 02990 02991 get_pt_from_params(&p, params); 02992 D = p->num_elts; 02993 02994 create_init_vector_d(&delta_t_v, D, delta_t); 02995 02996 err = langevin_hyperdynamics_2_d(iterations, delta_t_v, gamma, eta, h, d, 02997 params, get_pt_from_params, set_params_from_pt, energy_func, 02998 grad_energy_func, accept_sample); 02999 03000 free_vector_d(p); 03001 free_vector_d(delta_t_v); 03002 03003 return err; 03004 } 03005 03034 Error* langevin_hyperdynamics_2_d 03035 ( 03036 uint32_t iterations, 03037 const Vector_d* delta_t, 03038 double gamma, 03039 double eta, 03040 double h, 03041 double d, 03042 void* params, 03043 void (*get_pt_from_params)(Vector_d** p_out, const void* params), 03044 Error* (*set_params_from_pt)(const Vector_d* p, void* params), 03045 Error* (*energy_func)(double* energy_out, void* params), 03046 Error* (*grad_energy_func)(Vector_d** grad_out, void* params), 03047 Error* (*accept_sample)(const Vector_d* sample, void* params, double energy_bias) 03048 ) 03049 { 03050 uint32_t i; 03051 uint32_t n; 03052 uint32_t N; 03053 double gauss; 03054 double lambda; 03055 double e; 03056 double e_pos; 03057 double e_neg; 03058 double g1p; 03059 double Vb; 03060 double Vb_dx; 03061 double dt; 03062 03063 Vector_d* p = NULL; 03064 Vector_d* v = NULL; 03065 Vector_d* v_pos = NULL; 03066 Vector_d* v_neg = NULL; 03067 Vector_d* e_dx = NULL; 03068 Vector_d* e_pos_dx = NULL; 03069 Vector_d* e_neg_dx = NULL; 03070 Vector_d* g1p_dx = NULL; 03071 Vector_d* V_dx = NULL; 03072 Error* err = NULL; 03073 03074 get_pt_from_params(&p, params); 03075 N = p->num_elts; 03076 03077 /* Randomly initialize lambda and the eigenvectors. */ 03078 create_random_vector_d(&v, N, -1, 1); 03079 normalize_vector_mag_d(&v, v); 03080 03081 create_random_vector_d(&v_pos, N, -1, 1); 03082 normalize_vector_mag_d(&v_pos, v_pos); 03083 03084 create_random_vector_d(&v_neg, N, -1, 1); 03085 normalize_vector_mag_d(&v_neg, v_neg); 03086 03087 lambda = sample_uniform_pdf_d(-1.0e3, 1.0e3); 03088 03089 for (i = 0; i < iterations; i++) 03090 { 03091 if ((err = hyperdynamics_hessian_eigenvector_d(&v, eta, gamma, 03092 params, get_pt_from_params, set_params_from_pt, 03093 energy_func, grad_energy_func))) 03094 { 03095 break; 03096 } 03097 03098 if ((err = hyperdynamics_hessian_eigenvalue_d(&e, v, eta, params, 03099 get_pt_from_params, set_params_from_pt, energy_func))) 03100 { 03101 break; 03102 } 03103 03104 if ((err = hyperdynamics_dx_hessian_eigenvalue_d(&e_dx, v, eta, params, 03105 get_pt_from_params, set_params_from_pt, 03106 grad_energy_func))) 03107 { 03108 break; 03109 } 03110 03111 if ((err = hyperdynamics_hessgrad_eigenvector_d(&lambda, &v_pos, &v_neg, 03112 eta, gamma, params, get_pt_from_params, 03113 set_params_from_pt, energy_func, grad_energy_func))) 03114 { 03115 break; 03116 } 03117 03118 if ((err = hyperdynamics_hessgrad_eigenvalue_d(&e_pos, lambda, v_pos, 03119 eta, params, get_pt_from_params, set_params_from_pt, 03120 energy_func, 1))) 03121 { 03122 break; 03123 } 03124 03125 if ((err = hyperdynamics_hessgrad_eigenvalue_d(&e_neg, lambda, v_neg, 03126 eta, params, get_pt_from_params, set_params_from_pt, 03127 energy_func, 0))) 03128 { 03129 break; 03130 } 03131 03132 if ((err = hyperdynamics_dx_hessgrad_eigenvalue_d(&e_pos_dx, lambda, 03133 v_pos, eta, params, get_pt_from_params, 03134 set_params_from_pt, energy_func, grad_energy_func, 1))) 03135 { 03136 break; 03137 } 03138 03139 if ((err = hyperdynamics_dx_hessgrad_eigenvalue_d(&e_neg_dx, lambda, 03140 v_neg, eta, params, get_pt_from_params, 03141 set_params_from_pt, energy_func, grad_energy_func, 0))) 03142 { 03143 break; 03144 } 03145 03146 if ((err = hyperdynamics_proj_hessian_eigenvector_d(&g1p, e_pos, e_neg, 03147 lambda))) 03148 { 03149 break; 03150 } 03151 03152 if ((err = hyperdynamics_dx_proj_hessian_eigenvector_d(&g1p_dx, 03153 e_pos_dx, e_neg_dx, g1p, lambda))) 03154 { 03155 break; 03156 } 03157 03158 if ((err = grad_energy_func(&V_dx, params))) 03159 { 03160 break; 03161 } 03162 03163 get_pt_from_params(&p, params); 03164 03165 Vb = 0.5*h * (1 + e / sqrt(e*e + g1p*g1p/(d*d))); 03166 03167 for (n = 0; n < N; n++) 03168 { 03169 Vb_dx = (h / (2*sqrt((e*e) + ((g1p*g1p)/(d*d))))) * 03170 (e_dx->elts[n] - e*(e*e_dx->elts[n] + 03171 (g1p/(d*d))*g1p_dx->elts[n]) / 03172 (e*e + (g1p*g1p)/(d*d))); 03173 03174 dt = delta_t->elts[ n ]; 03175 gauss = sample_standard_gaussian_pdf_d(-6.0, 6.0); 03176 03177 p->elts[ n ] -= dt*(0.5*dt*(V_dx->elts[n]+Vb_dx) + gauss); 03178 } 03179 03180 if ((err = accept_sample(p, params, Vb))) 03181 { 03182 break; 03183 } 03184 } 03185 03186 free_vector_d(p); 03187 free_vector_d(v); 03188 free_vector_d(v_pos); 03189 free_vector_d(v_neg); 03190 free_vector_d(e_dx); 03191 free_vector_d(e_pos_dx); 03192 free_vector_d(e_neg_dx); 03193 free_vector_d(g1p_dx); 03194 free_vector_d(V_dx); 03195 03196 return err; 03197 } 03198