(git:98357aa)
Loading...
Searching...
No Matches
pao_ml_gaussprocess.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Gaussian Process implementation
10!> \author Ole Schuett
11! **************************************************************************************************
13 USE kinds, ONLY: dp
14 USE pao_types, ONLY: pao_env_type,&
16#include "./base/base_uses.f90"
17
18 IMPLICIT NONE
19
20 PRIVATE
21
22 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'pao_ml_gaussprocess'
23
25
26CONTAINS
27
28! **************************************************************************************************
29!> \brief Builds the covariance matrix
30!> \param pao ...
31! **************************************************************************************************
32 SUBROUTINE pao_ml_gp_train(pao)
33 TYPE(pao_env_type), POINTER :: pao
34
35 INTEGER :: i, ikind, info, j, npoints
36 REAL(dp), DIMENSION(:), POINTER :: idescr, jdescr
37 TYPE(training_matrix_type), POINTER :: training_matrix
38
39 ! TODO this could be parallelized over ranks
40 DO ikind = 1, SIZE(pao%ml_training_matrices)
41 training_matrix => pao%ml_training_matrices(ikind)
42 npoints = SIZE(training_matrix%inputs, 2) ! number of points
43 cpassert(SIZE(training_matrix%outputs, 2) == npoints)
44 IF (npoints == 0) cycle ! have no training data
45
46 IF (pao%iw > 0) WRITE (pao%iw, *) "PAO|ML| Building covariance matrix for kind: ", &
47 trim(training_matrix%kindname), " from ", npoints, "training points."
48
49 ! build covariance matrix
50 ALLOCATE (training_matrix%GP(npoints, npoints))
51 DO i = 1, npoints
52 DO j = i, npoints
53 idescr => training_matrix%inputs(:, i)
54 jdescr => training_matrix%inputs(:, j)
55 training_matrix%GP(i, j) = kernel(pao%gp_scale, idescr, jdescr)
56 training_matrix%GP(j, i) = training_matrix%GP(i, j)
57 END DO
58 END DO
59
60 ! add noise of training data
61 DO i = 1, npoints
62 training_matrix%GP(i, i) = training_matrix%GP(i, i) + pao%gp_noise_var**2
63 END DO
64
65 ! compute cholesky decomposition of covariance matrix
66 CALL dpotrf("U", npoints, training_matrix%GP, npoints, info)
67 cpassert(info == 0)
68 END DO
69
70 END SUBROUTINE pao_ml_gp_train
71
72! **************************************************************************************************
73!> \brief Uses covariance matrix to make prediction
74!> \param pao ...
75!> \param ikind ...
76!> \param descriptor ...
77!> \param output ...
78!> \param variance ...
79! **************************************************************************************************
80 SUBROUTINE pao_ml_gp_predict(pao, ikind, descriptor, output, variance)
81 TYPE(pao_env_type), POINTER :: pao
82 INTEGER, INTENT(IN) :: ikind
83 REAL(dp), DIMENSION(:), INTENT(IN) :: descriptor
84 REAL(dp), DIMENSION(:), INTENT(OUT) :: output
85 REAL(dp), INTENT(OUT) :: variance
86
87 INTEGER :: i, info, npoints
88 REAL(dp), ALLOCATABLE, DIMENSION(:) :: cov, weights
89 TYPE(training_matrix_type), POINTER :: training_matrix
90
91 training_matrix => pao%ml_training_matrices(ikind)
92 npoints = SIZE(training_matrix%outputs, 2)
93
94 ! calculate covariances between descriptor and training-points
95 ALLOCATE (cov(npoints))
96 DO i = 1, npoints
97 cov(i) = kernel(pao%gp_scale, descriptor, training_matrix%inputs(:, i))
98 END DO
99
100 ! calculate weights
101 ALLOCATE (weights(npoints))
102 weights(:) = cov(:)
103 CALL dpotrs("U", npoints, 1, training_matrix%GP, npoints, weights, npoints, info)
104 cpassert(info == 0)
105
106 ! calculate predicted output
107 output = 0.0_dp
108 DO i = 1, npoints
109 output(:) = output + weights(i)*training_matrix%outputs(:, i)
110 END DO
111
112 ! calculate prediction's variance
113 variance = kernel(pao%gp_scale, descriptor, descriptor) - dot_product(weights, cov)
114
115 IF (variance < 0.0_dp) THEN
116 cpabort("PAO gaussian process found negative variance")
117 END IF
118
119 DEALLOCATE (cov, weights)
120 END SUBROUTINE pao_ml_gp_predict
121
122! **************************************************************************************************
123!> \brief Calculate gradient of Gaussian process
124!> \param pao ...
125!> \param ikind ...
126!> \param descriptor ...
127!> \param outer_deriv ...
128!> \param gradient ...
129! **************************************************************************************************
130 SUBROUTINE pao_ml_gp_gradient(pao, ikind, descriptor, outer_deriv, gradient)
131 TYPE(pao_env_type), POINTER :: pao
132 INTEGER, INTENT(IN) :: ikind
133 REAL(dp), DIMENSION(:), INTENT(IN), TARGET :: descriptor
134 REAL(dp), DIMENSION(:), INTENT(IN) :: outer_deriv
135 REAL(dp), DIMENSION(:), INTENT(OUT) :: gradient
136
137 INTEGER :: i, info, npoints
138 REAL(dp), ALLOCATABLE, DIMENSION(:) :: cov_deriv, weights_deriv
139 REAL(dp), DIMENSION(SIZE(descriptor)) :: kg
140 TYPE(training_matrix_type), POINTER :: training_matrix
141
142 training_matrix => pao%ml_training_matrices(ikind)
143 npoints = SIZE(training_matrix%outputs, 2)
144
145 ! calculate derivative of weights
146 ALLOCATE (weights_deriv(npoints))
147 DO i = 1, npoints
148 weights_deriv(i) = sum(outer_deriv*training_matrix%outputs(:, i))
149 END DO
150
151 ! calculate derivative of covariances
152 ALLOCATE (cov_deriv(npoints))
153 cov_deriv(:) = weights_deriv(:)
154 CALL dpotrs("U", npoints, 1, training_matrix%GP, npoints, cov_deriv, npoints, info)
155 cpassert(info == 0)
156
157 ! calculate derivative of kernel
158 gradient(:) = 0.0_dp
159 DO i = 1, npoints
160 kg = kernel_grad(pao%gp_scale, descriptor, training_matrix%inputs(:, i))
161 gradient(:) = gradient(:) + kg(:)*cov_deriv(i)
162 END DO
163
164 DEALLOCATE (cov_deriv, weights_deriv)
165 END SUBROUTINE pao_ml_gp_gradient
166
167! **************************************************************************************************
168!> \brief Gaussian kernel used to measure covariance between two descriptors.
169!> \param scale ...
170!> \param descr1 ...
171!> \param descr2 ...
172!> \return ...
173! **************************************************************************************************
174 PURE FUNCTION kernel(scale, descr1, descr2) RESULT(cov)
175 REAL(dp), INTENT(IN) :: scale
176 REAL(dp), DIMENSION(:), INTENT(IN) :: descr1, descr2
177 REAL(dp) :: cov
178
179 REAL(dp) :: fdist2
180 REAL(dp), DIMENSION(SIZE(descr1)) :: diff
181
182 diff = descr1 - descr2
183 fdist2 = sum((diff/scale)**2)
184 cov = exp(-fdist2/2.0_dp)
185 END FUNCTION kernel
186
187! **************************************************************************************************
188!> \brief Gradient of Gaussian kernel wrt descr1
189!> \param scale ...
190!> \param descr1 ...
191!> \param descr2 ...
192!> \return ...
193! **************************************************************************************************
194 PURE FUNCTION kernel_grad(scale, descr1, descr2) RESULT(grad)
195 REAL(dp), INTENT(IN) :: scale
196 REAL(dp), DIMENSION(:), INTENT(IN) :: descr1, descr2
197 REAL(dp), DIMENSION(SIZE(descr1)) :: grad
198
199 REAL(dp) :: cov, fdist2
200 REAL(dp), DIMENSION(SIZE(descr1)) :: diff
201
202 diff = descr1 - descr2
203 fdist2 = sum((diff/scale)**2)
204 cov = exp(-fdist2/2.0_dp)
205 grad(:) = cov*(-diff/scale**2)
206
207 END FUNCTION kernel_grad
208
209END MODULE pao_ml_gaussprocess
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Gaussian Process implementation.
subroutine, public pao_ml_gp_gradient(pao, ikind, descriptor, outer_deriv, gradient)
Calculate gradient of Gaussian process.
subroutine, public pao_ml_gp_train(pao)
Builds the covariance matrix.
subroutine, public pao_ml_gp_predict(pao, ikind, descriptor, output, variance)
Uses covariance matrix to make prediction.
Types used by the PAO machinery.
Definition pao_types.F:12