Package csb :: Package statistics :: Package samplers :: Package mc :: Module neqsteppropagator
[frames] | no frames]

Source Code for Module csb.statistics.samplers.mc.neqsteppropagator

   1  """ 
   2  Propagator class employing stepwise trajectories as used in the NCMC 
   3  algorithm (Nilmeier et al., "Nonequilibrium candidate Monte Carlo is  
   4  an efficient tool for equilibrium simulation", PNAS 2011) 
   5  """ 
   6   
   7  import csb 
   8   
   9  import numpy 
  10   
  11  from abc import ABCMeta, abstractmethod 
  12  from csb.statistics.samplers.mc import TrajectoryBuilder, Trajectory, augment_state, PropagationResult 
  13  from csb.statistics.samplers.mc.propagators import AbstractPropagator, MDPropagator, HMCPropagator 
  14  from csb.numeric import InvertibleMatrix 
  15  from csb.numeric.integrators import FastLeapFrog 
16 17 -class NonequilibriumTrajectory(Trajectory):
18 """ 19 Trajectory holding additional information about energy difference 20 the Jacobian. 21 22 @param items: sequence of trajectory states 23 @type items: list of L{State}s 24 25 @param heat: heat produced during the trajectory 26 @type heat: float 27 28 @param work: work expended during the trajectory 29 @type work: float 30 31 @param deltaH: energy difference between initial and final states 32 @type deltaH: float 33 34 @param jacobian: product of Jacobians of perturbations applied in the 35 calculation of the trajectory 36 @type jacobian: float 37 """ 38
39 - def __init__(self, items, heat=0.0, work=0.0, deltaH=0.0, jacobian=1.0):
40 41 super(NonequilibriumTrajectory, self).__init__(items, heat=heat, work=work) 42 43 self._deltaH = None 44 self.deltaH = deltaH 45 self._jacobian = None 46 self.jacobian = jacobian
47 48 @property
49 - def jacobian(self):
50 return self._jacobian
51 @jacobian.setter
52 - def jacobian(self, value):
53 self._jacobian = value
54 55 @property
56 - def deltaH(self):
57 return self._deltaH
58 @deltaH.setter
59 - def deltaH(self, value):
60 self._deltaH = value
61
62 63 -class AbstractSystemInfo(object):
64 """ 65 Subclasses hold all information describing a current system setup 66 (Hamiltonian, boundaries, ...) 67 """ 68 69 pass
70
71 -class PerturbationResult(Trajectory):
72 """ 73 Instances hold the result of a perturbation. 74 75 @param items: list of states defining a phase-space trajectory 76 @type items: list of L{AbstractState}s 77 78 @param work: work performed on the system during perturbation 79 @type work: float 80 81 @param jacobian: jacobian of the perturbation 82 @type jacobian: float 83 84 @param perturbed_sys: L{AbstractSystemInfo} instance 85 describing the perturbed system 86 @type perturbed_sys: L{AbstractSystemInfo} 87 """ 88
89 - def __init__(self, items, perturbed_sys, work, heat=0.0, jacobian=1.0):
90 91 super(PerturbationResult, self).__init__(items, heat, work) 92 93 self._jacobian = None 94 self.jacobian = jacobian 95 self._perturbed_sys = None 96 self.perturbed_sys = perturbed_sys
97 98 @property
99 - def jacobian(self):
100 return self._jacobian
101 @jacobian.setter
102 - def jacobian(self, value):
103 self._jacobian = value
104 105 @property
106 - def perturbed_sys(self):
107 return self._perturbed_sys
108 @perturbed_sys.setter
109 - def perturbed_sys(self, value):
110 self._perturbed_sys = value
111
112 113 -class Protocol(object):
114 """ 115 Describes a stepwise protocol as in Nilmeier et al. (2011). 116 117 @param steps: the steps making up the protocol 118 @type steps: list of L{Step}s 119 """ 120
121 - def __init__(self, steps):
122 123 self._steps = None 124 self.steps = steps
125 126 @property
127 - def steps(self):
128 """ 129 The steps making up the protocol 130 """ 131 return self._steps
132 @steps.setter
133 - def steps(self, value):
134 self._steps = value
135
136 -class Step(object):
137 """ 138 Defines a step in an NCMC-like stepwise protocol. 139 140 @param perturbation: The perturbation of the system 141 @type perturbation: L{AbstractPerturbation} 142 143 @param propagation: The propagation of the perturbed system 144 @type propagation: L{AbstractPropagation} 145 """ 146
147 - def __init__(self, perturbation, propagation):
148 149 self._perturbation = None 150 self.perturbation = perturbation 151 self._propagation = None 152 self.propagation = propagation 153 self._perform = None 154 self.perform = self._perform_pert_prop
155
156 - def _perform_pert_prop(self, state):
157 158 perturbation_result = self.perturbation(state) 159 propagation_result = self.propagation(perturbation_result.final) 160 161 result_state = propagation_result.final 162 163 return NonequilibriumTrajectory([state, result_state], 164 heat=propagation_result.heat, 165 work=perturbation_result.work, 166 jacobian=perturbation_result.jacobian)
167
168 - def _perform_prop_pert(self, state):
169 170 propagation_result = self.propagation(state) 171 perturbation_result = self.perturbation(propagation_result.final) 172 result_state = perturbation_result.final 173 174 return NonequilibriumTrajectory([state, result_state], 175 heat=propagation_result.heat, 176 work=perturbation_result.work, 177 jacobian=perturbation_result.jacobian)
178
179 - def set_perturbation_first(self):
180 """ 181 Perform first perturbation, then propagation 182 """ 183 184 self.perform = self._perform_pert_prop
185
186 - def set_propagation_first(self):
187 """ 188 Perform first propagation, then perturbation 189 """ 190 191 self.perform = self._perform_prop_pert
192 193 @property
194 - def perturbation(self):
195 return self._perturbation
196 @perturbation.setter
197 - def perturbation(self, value):
198 self._perturbation = value
199 200 @property
201 - def propagation(self):
202 return self._propagation
203 @propagation.setter
204 - def propagation(self, value):
205 self._propagation = value
206
207 208 -class ReducedHamiltonian(object):
209 """ 210 Describes a reduced Hamiltonian (Hamiltonian, its position gradient 211 and the system temperature) 212 213 @param log_prob: log probability of the PDF under consideration, that is, 214 the negative potential energy of the system 215 @type log_prob: callable 216 217 @param gradient: gradient of the negative log probability of the PDF under 218 consideration, that is, the gradient of the potential energy; 219 function of position array and time 220 @type gradient: callable 221 222 @param temperature: system temperature 223 @type temperature: float 224 225 @param mass_matrix: system mass matrix 226 @type mass_matrix: L{InvertibleMatrix} 227 """ 228
229 - def __init__(self, log_prob, gradient=None, temperature=1.0, mass_matrix=None):
230 self._log_prob = None 231 self.log_prob = log_prob 232 self._gradient = None 233 self.gradient = gradient 234 self._temperature = None 235 self.temperature = temperature 236 self._mass_matrix = None 237 self.mass_matrix = mass_matrix
238
239 - def E(self, x):
240 """ 241 Potential energy of the system, aka negative log probability 242 243 @param x: position vector 244 @type x: 1D numpy array 245 """ 246 247 return -self.log_prob(x)
248
249 - def kinetic_energy(self, p):
250 """ 251 Kinetic energy of the system 252 253 @param p: system momentum vector 254 @type p: 1D numpy array 255 """ 256 257 if p is not None: 258 if self.mass_matrix is None: 259 return 0.5 * sum(p ** 2) 260 else: 261 if self.mass_matrix.is_unity_multiple: 262 return 0.5 * sum(p ** 2) / self.mass_matrix[0][0] 263 else: 264 return 0.5 * numpy.dot(p, numpy.dot(self.mass_matrix.inverse, p)) 265 else: 266 return 0.0
267
268 - def rlog_prob(self, x):
269 """ 270 Reduced log probability 271 272 @param x: position vector 273 @type x: 1D numpy array 274 """ 275 276 return self.log_prob(x) / self.temperature
277
278 - def rkinetic_energy(self, p):
279 """ 280 Reduced kinetic energy 281 282 @param p: system momentum vector 283 @type p: 1D numpy array 284 """ 285 286 return self.kinetic_energy(p) / self.temperature
287
288 - def __call__(self, x):
289 """ 290 Evaluates the reduced Hamiltionian at the state x 291 292 @param x: system state 293 @type x: L{State} 294 """ 295 296 return -self.rlog_prob(x.position) + self.rkinetic_energy(x.momentum)
297 298 @property
299 - def log_prob(self):
300 return self._log_prob
301 @log_prob.setter
302 - def log_prob(self, value):
303 self._log_prob = value
304 305 @property
306 - def gradient(self):
307 return self._gradient
308 @gradient.setter
309 - def gradient(self, value):
310 self._gradient = value
311 312 @property
313 - def temperature(self):
314 return self._temperature
315 @temperature.setter
316 - def temperature(self, value):
317 self._temperature = value
318 319 @property
320 - def mass_matrix(self):
321 return self._mass_matrix
322 @mass_matrix.setter
323 - def mass_matrix(self, value):
324 self._mass_matrix = value
325
326 327 -class AbstractPerturbation(object):
328 """ 329 Describes an abstract system perturbation 330 331 @param sys_before: information about the system before the perturbation 332 @type sys_before: L{AbstractSystemInfo} 333 334 @param sys_after: information about the system after the perturbation 335 @type sys_after: L{AbstractSystemInfo} 336 337 @param param: parameters neccessary for system perturbation 338 @type param: L{AbstractPerturbationParam} 339 340 @param evaluate_work: Allows to switch off the work evaluation, 341 which might not always be needed, in order to 342 save computation time. 343 @type evaluate_work: boolean 344 """ 345 346 __metaclass__ = ABCMeta 347
348 - def __init__(self, sys_before, sys_after, param=None, evaluate_work=True):
349 self._sys_before = None 350 self.sys_before = sys_before 351 self._sys_after = None 352 self.sys_after = sys_after 353 self.param = param 354 self._evaluate_work = None 355 self.evaluate_work = evaluate_work
356 357 @abstractmethod
358 - def _run_perturbator(self, state):
359 """ 360 Calculates the trajectory of the system while it is being perturbed. 361 362 @param state: The initial system state 363 @type state: L{State} 364 365 @return: The trajectory of the system while it is being perturbed 366 @rtype: L{Trajectory} 367 """ 368 369 pass
370 371 @abstractmethod
372 - def _calculate_work(self, traj):
373 """ 374 Calculates the work expended during perturbation of the system. 375 376 @param traj: The trajectory of the system while being perturbed 377 @type traj: L{Trajectory} 378 379 @return: The work expended during perturbation 380 @rtype: float 381 """ 382 383 pass
384 385 @abstractmethod
386 - def _calculate_jacobian(self, traj):
387 """ 388 Calculates the Jacobian determinant which reflects phase 389 space compression during perturbation. 390 391 @param traj: The trajectory of the system while being perturbed 392 @type traj: L{Trajectory} 393 394 @return: The Jacobian determinant 395 @rtype: float 396 """ 397 398 pass
399
400 - def _evaluate(self, state):
401 """ 402 Performs the perturbation of the system and / or the state 403 404 @param state: system state 405 @type state: L{State} 406 """ 407 408 traj = self._run_perturbator(state) 409 work = self._calculate_work(traj) 410 jacobian = self._calculate_jacobian(traj) 411 412 return PerturbationResult([traj.initial, traj.final], self.sys_after, 413 work, jacobian=jacobian)
414
415 - def __call__(self, state):
416 """ 417 Performs the perturbation of the system and / or the state 418 419 @param state: system state 420 @type state: L{State} 421 """ 422 423 return self._evaluate(state)
424 425 @property
426 - def sys_before(self):
427 return self._sys_before
428 @sys_before.setter
429 - def sys_before(self, value):
430 self._sys_before = value
431 432 @property
433 - def sys_after(self):
434 return self._sys_after
435 @sys_after.setter
436 - def sys_after(self, value):
437 self._sys_after = value
438 439 @property
440 - def param(self):
441 return self._param
442 @param.setter
443 - def param(self, value):
444 self._param = value
445 446 @property
447 - def evaluate_work(self):
448 return self._evaluate_work
449 @evaluate_work.setter
450 - def evaluate_work(self, value):
451 self._evaluate_work = value
452
453 454 -class AbstractPropagation(object):
455 """ 456 Describes an abstract system propagation 457 458 @param sys: information about the current system setup 459 @type sys: L{AbstractSystemInfo} 460 461 @param param: parameters neccessary for propagating the system 462 @type param: L{AbstractPropagationParam} 463 464 @param evaluate_heat: Allows to switch off the heat evaluation, 465 which might not always be needed, in order to 466 save computation time. 467 @type evaluate_heat: boolean 468 """ 469 470 __metaclass__ = ABCMeta 471
472 - def __init__(self, sys, param, evaluate_heat=True):
473 474 self._sys = None 475 self.sys = sys 476 self._param = None 477 self.param = param 478 self._evaluate_heat = None 479 self.evaluate_heat = evaluate_heat
480 481 @abstractmethod
482 - def _propagator_factory(self):
483 """ 484 Factory method which returns the propagator to be used for 485 propagating the system. 486 487 @return: Some propagator object 488 @rtype: L{AbstractPropagator} 489 """
490 491 @abstractmethod
492 - def _run_propagator(self, state):
493 """ 494 Propagates the system using the propagator instance returned 495 by _propagator_factory(). 496 497 @param state: Initial state 498 @type state: L{State} 499 500 @return: The result of the propagation 501 @rtype: L{PropagationResult} 502 """ 503 504 pass
505 506 @abstractmethod
507 - def _calculate_heat(self, traj):
508 """ 509 Calculates the heat resulting from system propagation. 510 511 @param traj: The trajectory of the system during propagation 512 @type traj: L{Trajectory} 513 514 @return: The heat resulting from system propagation. 515 @rtype: float 516 """ 517 518 pass
519
520 - def _evaluate(self, state):
521 """ 522 Performs the propagation of a state in the specified system 523 524 @param state: system state 525 @type state: L{State} 526 """ 527 528 traj = self._run_propagator(state) 529 heat = self._calculate_heat(traj) 530 531 return PropagationResult(traj.initial, traj.final, heat=heat)
532
533 - def __call__(self, state):
534 """ 535 Performs the propagation of a state in the specified system 536 537 @param state: system state 538 @type state: L{State} 539 """ 540 541 return self._evaluate(state)
542 543 @property
544 - def sys(self):
545 return self._sys
546 @sys.setter
547 - def sys(self, value):
548 self._sys = value
549 550 @property
551 - def param(self):
552 return self._param
553 @param.setter
554 - def param(self, value):
555 self._param = value
556 557 @property
558 - def evaluate_heat(self):
559 return self._evaluate_heat
560 @evaluate_heat.setter
561 - def evaluate_heat(self, value):
562 self._evaluate_heat = value
563
564 565 -class ReducedHamiltonianPerturbation(AbstractPerturbation):
566 """ 567 System perturbation by changing the reduced Hamiltonian 568 569 @param sys_before: information about the system before the perturbation 570 @type sys_before: L{AbstractSystemInfo} 571 572 @param sys_after: information about the system after the perturbation 573 @type sys_after: L{AbstractSystemInfo} 574 575 @param evaluate_work: Allows to switch off the work evaluation, 576 which might not always be needed, in order to 577 save computation time. 578 @type evaluate_work: boolean 579 """ 580
581 - def __init__(self, sys_before, sys_after, evaluate_work=True):
585
586 - def _calculate_work(self, traj):
587 588 work = 0.0 589 if self.evaluate_work == True: 590 work = self.sys_after.hamiltonian(traj.final) - \ 591 self.sys_before.hamiltonian(traj.initial) 592 593 return work
594
595 - def _calculate_jacobian(self, traj):
596 597 return 1.0
598
599 - def _run_perturbator(self, state):
600 601 return Trajectory([state, state])
602
603 604 -class AbstractMCPropagation(AbstractPropagation):
605 """ 606 System propagation by some MC algorithm. 607 608 @param sys: information about the current system setup 609 @type sys: L{AbstractSystemInfo} 610 611 @param param: parameters neccessary for propagating the system 612 @type param: L{AbstractPropagationParam} 613 614 @param evaluate_heat: Allows to switch off the heat evaluation, 615 which might not always be needed, in order to 616 save computation time. 617 @type evaluate_heat: boolean 618 """ 619 620 ## Not neccessary, but otherwise epydoc complains
621 - def __init__(self, sys, param, evaluate_heat=True):
622 623 super(AbstractMCPropagation, self).__init__(sys, param, evaluate_heat=True)
624
625 - def _calculate_heat(self, traj):
626 627 heat = 0.0 628 if self.evaluate_heat == True: 629 heat = self.sys.hamiltonian.E(traj.final.position) - \ 630 self.sys.hamiltonian.E(traj.initial.position) 631 632 return heat
633
634 - def _run_propagator(self, state):
635 636 gen = self._propagator_factory() 637 638 return gen.generate(state, self.param.iterations, False)
639
640 641 -class HMCPropagation(AbstractMCPropagation):
642 """ 643 System propagation by HMC 644 645 @param sys: information about the current system setup 646 @type sys: L{AbstractSystemInfo} 647 648 @param param: parameters neccessary for propagating the system 649 @type param: L{HMCPropagationParam} 650 651 @param evaluate_heat: Allows to switch off the heat evaluation, 652 which might not always be needed, in order to 653 save computation time. 654 @type evaluate_heat: boolean 655 """ 656
657 - def __init__(self, sys, param, evaluate_heat=True):
658 659 super(HMCPropagation, self).__init__(sys, param, evaluate_heat) 660 661 if self.param.gradient is None: 662 self.param.gradient = self.sys.hamiltonian.gradient
663
664 - def _set_mass_matrix(self, state):
665 """ 666 Sets the mass matrix in the param object. 667 668 @param state: The initial state which is used to determine the dimension 669 of the mass matrix 670 @type state: L{State} 671 """ 672 673 if self.param.mass_matrix is None: 674 d = len(state.position) 675 self.param.mass_matrix = InvertibleMatrix(numpy.eye(d))
676
677 - def _propagator_factory(self):
683
684 - def _evaluate(self, state):
685 686 self._set_mass_matrix(state) 687 688 return super(HMCPropagation, self)._evaluate(state)
689 690 @property
691 - def param(self):
692 return self._param
693 @param.setter
694 - def param(self, value):
695 self._param = value
696
697 698 -class AbstractMDPropagation(AbstractPropagation):
699 """ 700 System propagation by some MD algorithm 701 702 @param sys: information about the current system setup 703 @type sys: L{AbstractSystemInfo} 704 705 @param param: parameters neccessary for propagating the system 706 @type param: L{MDPropagationParam} 707 708 @param evaluate_heat: Allows to switch off the heat evaluation, 709 which might not always be needed, in order to 710 save computation time. 711 @type evaluate_heat: boolean 712 """ 713 714 __metaclass__ = ABCMeta 715 716 ## Not neccessary, but otherwise epydoc complains
717 - def __init__(self, sys, param, evaluate_heat=True):
718 719 super(AbstractMDPropagation, self).__init__(sys, param, evaluate_heat=True)
720
721 - def _set_mass_matrix(self, state):
722 """ 723 Sets the mass matrix in the param object. 724 725 @param state: The initial state which is used to determine the dimension 726 of the mass matrix 727 @type state: L{State} 728 """ 729 730 if self.param.mass_matrix is None: 731 d = len(state.position) 732 self.param.mass_matrix = InvertibleMatrix(numpy.eye(d))
733
734 - def _augment_state(self, state):
735 """ 736 Augments the initial state by a momentum if none is defined. 737 738 @param state: Initial state 739 @type state: L{State} 740 """ 741 742 if state.momentum == None: 743 state = augment_state(state, self.sys.hamiltonian.temperature, 744 self.param.mass_matrix) 745 746 return state
747
748 - def _run_propagator(self, state):
749 750 gen = self._propagator_factory() 751 state = self._augment_state(state) 752 traj = gen.generate(state, self.param.traj_length) 753 754 return traj
755
756 757 -class PlainMDPropagation(AbstractMDPropagation):
758 """ 759 System propagation by plain, microcanonical MD 760 761 @param sys: information about the current system setup 762 @type sys: L{AbstractSystemInfo} 763 764 @param param: parameters neccessary for propagating the system 765 @type param: L{PlainMDPropagationParam} 766 767 @param evaluate_heat: Allows to switch off the heat evaluation, 768 which might not always be needed, in order to 769 save computation time. 770 @type evaluate_heat: boolean 771 """ 772 773 ## Not neccessary, but otherwise epydoc is complaining
774 - def __init__(self, sys, param, evaluate_heat=True):
777
778 - def _propagator_factory(self):
783
784 - def _calculate_heat(self, traj):
785 786 heat = 0.0 787 if self.evaluate_heat == True: 788 heat = self.sys.hamiltonian(traj.final) - self.sys.hamiltonian(traj.initial) 789 790 return heat
791
792 - def _evaluate(self, state):
793 794 self._set_mass_matrix(state) 795 796 return super(PlainMDPropagation, self)._evaluate(state)
797
798 799 -class AbstractPerturbationParam(object):
800 """ 801 Subclasses hold informations required for different kinds 802 of system perturbation 803 """ 804 805 pass
806
807 808 -class AbstractPropagationParam(object):
809 """ 810 Subclasses hold informations required for different kinds 811 of system propagation 812 """ 813 814 pass
815
816 817 -class MDParam(object):
818 """ 819 Holds all required information for calculating a MD trajectory. 820 821 @param timestep: integration timestep 822 @type timestep: float 823 824 @param traj_length: MD trajectory length 825 @type traj_length: int 826 827 @param gradient: gradient governing the equations of motion, function of 828 position array and time 829 @type gradient: callable 830 831 @param temperature: System temperature for drawing momenta from the 832 Maxwell distribution 833 @type temperature: float 834 835 @param integrator: Integration scheme to be utilized 836 @type integrator: L{AbstractIntegrator} 837 838 @param mass_matrix: mass matrix for kinetic energy definition 839 @type mass_matrix: L{InvertibleMatrix} 840 """ 841
842 - def __init__(self, timestep, traj_length, gradient, temperature=1.0, 843 integrator=FastLeapFrog, mass_matrix=None):
844 845 self._timestep = None 846 self.timestep = timestep 847 self._traj_length = None 848 self.traj_length = traj_length 849 self._gradient = None 850 self.gradient = gradient 851 self._temperature = None 852 self.temperature = temperature 853 self._integrator = None 854 self.integrator = integrator 855 self._mass_matrix = None 856 self.mass_matrix = mass_matrix
857 858 @property
859 - def timestep(self):
860 return self._timestep
861 @timestep.setter
862 - def timestep(self, value):
863 self._timestep = value
864 865 @property
866 - def traj_length(self):
867 return self._traj_length
868 @traj_length.setter
869 - def traj_length(self, value):
870 self._traj_length = value
871 872 @property
873 - def gradient(self):
874 return self._gradient
875 @gradient.setter
876 - def gradient(self, value):
877 self._gradient = value
878 879 @property
880 - def temperature(self):
881 return self._temperature
882 @temperature.setter
883 - def temperature(self, value):
884 self._temperature = value
885 886 @property
887 - def integrator(self):
888 return self._integrator
889 @integrator.setter
890 - def integrator(self, value):
891 self._integrator = value
892 893 @property
894 - def mass_matrix(self):
895 return self._mass_matrix
896 @mass_matrix.setter
897 - def mass_matrix(self, value):
898 self._mass_matrix = value
899
900 901 -class HMCPropagationParam(MDParam, AbstractPropagationParam):
902 """ 903 Holds all required information for propagating a system by HMC. 904 The system temperature is taken from the 905 HMCPropagation.sys.hamiltonian.temperature property. 906 907 @param timestep: integration timestep 908 @type timestep: float 909 910 @param traj_length: MD trajectory length 911 @type traj_length: int 912 913 @param gradient: gradient governing the equations of motion, function of 914 position array and time 915 @type gradient: callable 916 917 @param iterations: number of HMC iterations to be performed 918 @type iterations: int 919 920 @param integrator: Integration scheme to be utilized 921 @type integrator: l{AbstractIntegrator} 922 923 @param mass_matrix: mass matrix for kinetic energy definition 924 @type mass_matrix: L{InvertibleMatrix} 925 """ 926
927 - def __init__(self, timestep, traj_length, gradient, iterations=1, 928 integrator=FastLeapFrog, mass_matrix=None):
929 930 super(HMCPropagationParam, self).__init__(timestep, traj_length, gradient, 931 integrator=integrator, mass_matrix=mass_matrix) 932 933 self._iterations = None 934 self.iterations = iterations
935 936 @property
937 - def iterations(self):
938 return self._iterations
939 @iterations.setter
940 - def iterations(self, value):
941 self._iterations = value
942
943 944 -class MDPropagationParam(MDParam, AbstractPropagationParam):
945 946 pass
947
948 949 -class PlainMDPropagationParam(MDParam, AbstractPropagationParam):
950 """ 951 Holds all required information for propagating a system by MD. 952 The system temperature is taken from the 953 MDPropagation.sys.hamiltonian.temperature property. 954 955 @param timestep: integration timestep 956 @type timestep: float 957 958 @param traj_length: MD trajectory length 959 @type traj_length: int 960 961 @param gradient: gradient governing the equations of motion, function of 962 position array and time 963 @type gradient: callable 964 965 @param integrator: Integration scheme to be utilized 966 @type integrator: l{AbstractIntegrator} 967 968 @param mass_matrix: mass matrix for kinetic energy definition 969 @type mass_matrix: L{InvertibleMatrix} 970 """ 971
972 - def __init__(self, timestep, traj_length, gradient, 973 integrator=FastLeapFrog, mass_matrix=None):
977
978 979 -class HamiltonianSysInfo(AbstractSystemInfo):
980 """ 981 Holds information describing a system by its Hamiltonian only. 982 983 @param hamiltonian: the Hamiltonian of the system to be described 984 @type hamiltonian: L{ReducedHamiltonian} 985 """ 986
987 - def __init__(self, hamiltonian):
988 989 self._hamiltonian = None 990 self.hamiltonian = hamiltonian
991 992 @property
993 - def hamiltonian(self):
994 return self._hamiltonian
995 @hamiltonian.setter
996 - def hamiltonian(self, value):
997 self._hamiltonian = value
998
999 1000 -class NonequilibriumStepPropagator(AbstractPropagator):
1001 """ 1002 Propagator class which propagates a system using NCMC-like 1003 stepwise trajectories 1004 1005 @param protocol: stepwise protocol to be followed 1006 @type protocol: L{Protocol} 1007 """ 1008
1009 - def __init__(self, protocol):
1010 1011 self._protocol = None 1012 self.protocol = protocol
1013
1014 - def _calculate_deltaH(self, traj):
1015 """ 1016 Calculate the difference of the Hamiltonian between the initial and 1017 the final state of a NCMC trajectory. 1018 1019 @param traj: The NCMC trajectory between whose initial and final states 1020 the Hamiltonian difference should be calculated 1021 @type traj: L{NonequilibriumTrajectory} 1022 """ 1023 1024 return self.protocol.steps[-1].perturbation.sys_after.hamiltonian(traj.final) - \ 1025 self.protocol.steps[0].perturbation.sys_before.hamiltonian(traj.initial)
1026
1027 - def generate(self, init_state, return_trajectory=False):
1028 1029 estate = init_state.clone() 1030 1031 reduced_work = 0. 1032 reduced_heat = 0. 1033 1034 builder = TrajectoryBuilder.create(full=return_trajectory) 1035 1036 total_jacobian = 1. 1037 1038 for i in range(len(self.protocol.steps)): 1039 shorttraj = self.protocol.steps[i].perform(estate) 1040 if i == 0: 1041 builder.add_initial_state(shorttraj.initial) 1042 1043 reduced_heat += shorttraj.heat 1044 reduced_work += shorttraj.work 1045 total_jacobian *= shorttraj.jacobian 1046 1047 estate = shorttraj.final 1048 1049 if i != len(self.protocol.steps) - 1: 1050 builder.add_intermediate_state(estate) 1051 else: 1052 builder.add_final_state(estate) 1053 1054 traj = builder.product 1055 1056 reduced_deltaH = self._calculate_deltaH(traj) 1057 1058 if init_state.momentum is None: 1059 for s in traj: 1060 s.momentum = None 1061 1062 result = NonequilibriumTrajectory([x for x in traj], 1063 heat=reduced_heat, 1064 work=reduced_work, 1065 deltaH=reduced_deltaH, 1066 jacobian=total_jacobian) 1067 1068 return result
1069 1070 @property
1071 - def protocol(self):
1072 return self._protocol
1073 @protocol.setter
1074 - def protocol(self, value):
1075 self._protocol = value
1076