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
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):
47
48 @property
51 @jacobian.setter
53 self._jacobian = value
54
55 @property
58 @deltaH.setter
61
64 """
65 Subclasses hold all information describing a current system setup
66 (Hamiltonian, boundaries, ...)
67 """
68
69 pass
70
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):
97
98 @property
100 return self._jacobian
101 @jacobian.setter
103 self._jacobian = value
104
105 @property
107 return self._perturbed_sys
108 @perturbed_sys.setter
110 self._perturbed_sys = value
111
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
125
126 @property
128 """
129 The steps making up the protocol
130 """
131 return self._steps
132 @steps.setter
135
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):
155
167
178
180 """
181 Perform first perturbation, then propagation
182 """
183
184 self.perform = self._perform_pert_prop
185
187 """
188 Perform first propagation, then perturbation
189 """
190
191 self.perform = self._perform_prop_pert
192
193 @property
195 return self._perturbation
196 @perturbation.setter
198 self._perturbation = value
199
200 @property
202 return self._propagation
203 @propagation.setter
205 self._propagation = value
206
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):
238
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
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
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
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
297
298 @property
300 return self._log_prob
301 @log_prob.setter
303 self._log_prob = value
304
305 @property
307 return self._gradient
308 @gradient.setter
310 self._gradient = value
311
312 @property
314 return self._temperature
315 @temperature.setter
317 self._temperature = value
318
319 @property
321 return self._mass_matrix
322 @mass_matrix.setter
324 self._mass_matrix = value
325
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):
356
357 @abstractmethod
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
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
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
414
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
427 return self._sys_before
428 @sys_before.setter
430 self._sys_before = value
431
432 @property
434 return self._sys_after
435 @sys_after.setter
437 self._sys_after = value
438
439 @property
442 @param.setter
445
446 @property
448 return self._evaluate_work
449 @evaluate_work.setter
451 self._evaluate_work = value
452
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):
480
481 @abstractmethod
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
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
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
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
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
546 @sys.setter
547 - def sys(self, value):
549
550 @property
553 @param.setter
556
557 @property
559 return self._evaluate_heat
560 @evaluate_heat.setter
562 self._evaluate_heat = value
563
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
594
598
602
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
621 - def __init__(self, sys, param, evaluate_heat=True):
624
633
639
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):
663
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
683
689
690 @property
693 @param.setter
696
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
717 - def __init__(self, sys, param, evaluate_heat=True):
720
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
747
755
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
774 - def __init__(self, sys, param, evaluate_heat=True):
777
783
791
797
800 """
801 Subclasses hold informations required for different kinds
802 of system perturbation
803 """
804
805 pass
806
809 """
810 Subclasses hold informations required for different kinds
811 of system propagation
812 """
813
814 pass
815
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):
857
858 @property
860 return self._timestep
861 @timestep.setter
863 self._timestep = value
864
865 @property
867 return self._traj_length
868 @traj_length.setter
870 self._traj_length = value
871
872 @property
874 return self._gradient
875 @gradient.setter
877 self._gradient = value
878
879 @property
881 return self._temperature
882 @temperature.setter
884 self._temperature = value
885
886 @property
888 return self._integrator
889 @integrator.setter
891 self._integrator = value
892
893 @property
895 return self._mass_matrix
896 @mass_matrix.setter
898 self._mass_matrix = value
899
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):
935
936 @property
938 return self._iterations
939 @iterations.setter
941 self._iterations = value
942
947
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
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
991
992 @property
994 return self._hamiltonian
995 @hamiltonian.setter
997 self._hamiltonian = value
998
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
1013
1026
1027 - def generate(self, init_state, return_trajectory=False):
1069
1070 @property
1072 return self._protocol
1073 @protocol.setter
1075 self._protocol = value
1076