Octopus
lalg_adv.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2006 M. Marques, A. Castro, A. Rubio, G. Bertsch
2!!
3!! This program is free software; you can redistribute it and/or modify
4!! it under the terms of the GNU General Public License as published by
5!! the Free Software Foundation; either version 2, or (at your option)
6!! any later version.
7!!
8!! This program is distributed in the hope that it will be useful,
9!! but WITHOUT ANY WARRANTY; without even the implied warranty of
10!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11!! GNU General Public License for more details.
12!!
13!! You should have received a copy of the GNU General Public License
14!! along with this program; if not, write to the Free Software
15!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16!! 02110-1301, USA.
17!!
18
19#include "global.h"
20
21module lalg_adv_oct_m
22 use blas_oct_m
24 use blacs_oct_m
25 use debug_oct_m
26 use global_oct_m
27#ifndef NDEBUG
28 use, intrinsic :: ieee_exceptions
29#endif
30 use, intrinsic :: iso_fortran_env
31 use lapack_oct_m
33 use math_oct_m
35 use mpi_oct_m
38 use sort_oct_m
39 use utils_oct_m
40#ifdef HAVE_ELPA
41 use elpa
42#endif
43
44 implicit none
45
46 private
47 public :: &
63 zlalg_exp, &
64 zlalg_phi, &
67 lalg_zdni, &
69 lalg_zd2ni, &
74
75
76
77 interface lalg_cholesky
78 module procedure dcholesky, zcholesky
79 end interface lalg_cholesky
80
81 interface lalg_cholesky_pivoted
82 module procedure dcholesky_pivoted, zcholesky_pivoted
83 end interface lalg_cholesky_pivoted
84
85 interface lalg_geneigensolve
86 module procedure dgeneigensolve, zgeneigensolve
87 end interface lalg_geneigensolve
88
89 interface lalg_eigensolve_nonh
90 module procedure zeigensolve_nonh, deigensolve_nonh
91 end interface lalg_eigensolve_nonh
92
93 interface lalg_eigensolve
94 module procedure deigensolve, zeigensolve
95 end interface lalg_eigensolve
96
99 end interface lalg_eigensolve_tridiagonal
100
103 end interface lalg_eigensolve_parallel
104
107
108 interface lalg_determinant
109 module procedure ddeterminant, zdeterminant
110 end interface lalg_determinant
111
112 interface lalg_inverse
113 module procedure dinverse, zinverse
114 end interface lalg_inverse
115
117 module procedure dlinsyssolve, zlinsyssolve
118 end interface lalg_linsyssolve
119
122 end interface lalg_singular_value_decomp
123
124 interface lalg_pseudo_inverse
126 end interface lalg_pseudo_inverse
127
128 interface lalg_svd_inverse
129 module procedure dsvd_inverse, zsvd_inverse
130 end interface lalg_svd_inverse
131
134 end interface lalg_lowest_geneigensolve
135
136 interface lalg_lowest_eigensolve
137 module procedure dlowest_eigensolve, zlowest_eigensolve
138 end interface lalg_lowest_eigensolve
139
140 interface lapack_geev
141 module procedure lalg_dgeev, lalg_zgeev
142 end interface lapack_geev
143
144 interface lalg_least_squares
145 module procedure dleast_squares_vec, zleast_squares_vec
146 end interface lalg_least_squares
147
148 interface lalg_matrix_function
150 end interface lalg_matrix_function
151
152 interface lalg_matrix_rank_svd
153 module procedure dmatrix_rank_svd, zmatrix_rank_svd
154 end interface lalg_matrix_rank_svd
155
156contains
157
158 ! ---------------------------------------------------------
160 real(real64) function sfmin()
161 interface
162 real(real64) function dlamch(cmach)
163 import real64
164 implicit none
165 character(1), intent(in) :: cmach
166 end function dlamch
167 end interface
168
169 sfmin = dlamch('S')
170 end function sfmin
171
172 subroutine lalg_dgeev(jobvl, jobvr, n, a, lda, w, vl, ldvl, vr, ldvr, work, lwork, rwork, info)
173 character(1), intent(in) :: jobvl, jobvr
174 integer, intent(in) :: n, lda, ldvl, ldvr, lwork
175 real(real64), intent(inout) :: a(:, :)
176 complex(real64), intent(out) :: w(:)
177 real(real64), intent(out) :: vl(:, :), vr(:, :)
178 real(real64), intent(out) :: work(:)
179 real(real64), intent(out) :: rwork(:)
180 integer, intent(out) :: info
181
182 real(real64), allocatable :: wr(:), wi(:)
183#ifndef NDEBUG
184 logical :: halting_mode(size(ieee_all))
185#endif
186
187 push_sub(lalg_dgeev)
189 safe_allocate(wr(1:n))
190 safe_allocate(wi(1:n))
191
192#ifndef NDEBUG
193 ! Optimized LAPACK backends (e.g. MKL) may raise spurious floating-point
194 ! exceptions while still returning correct results, so suspend trapping
195 ! for builds that enable it
196 call ieee_get_halting_mode(ieee_all, halting_mode)
197 call ieee_set_halting_mode(ieee_all, .false.)
198#endif
199 call dgeev(jobvl, jobvr, n, a(1, 1), lda, wr(1), wi(1), vl(1, 1), ldvl, vr(1, 1), ldvr, work(1), lwork, info)
200#ifndef NDEBUG
201 call ieee_set_halting_mode(ieee_all, halting_mode)
202#endif
203 w(1:n) = cmplx(wr(1:n), wi(1:n), real64)
204
205 safe_deallocate_a(wr)
206 safe_deallocate_a(wi)
208 pop_sub(lalg_dgeev)
209 end subroutine lalg_dgeev
210
211 subroutine lalg_zgeev(jobvl, jobvr, n, a, lda, w, vl, ldvl, vr, ldvr, work, lwork, rwork, info)
212 character(1), intent(in) :: jobvl, jobvr
213 integer, intent(in) :: n, lda, ldvl, ldvr, lwork
214 complex(real64), intent(inout) :: a(:, :)
215 complex(real64), intent(out) :: w(:)
216 complex(real64), intent(out) :: vl(:, :), vr(:, :)
217 real(real64), intent(out) :: rwork(:)
218 complex(real64), intent(out) :: work(:)
219 integer, intent(out) :: info
220
221 push_sub(lalg_zgeev)
222
223 call zgeev(jobvl, jobvr, n, a(1, 1), lda, w(1), vl(1, 1), ldvl, vr(1, 1), ldvr, work(1), lwork, rwork(1), info)
224
225 pop_sub(lalg_zgeev)
226 end subroutine lalg_zgeev
245 subroutine zlalg_exp(nn, pp, aa, ex, hermitian)
246 integer, intent(in) :: nn
247 complex(real64), intent(in) :: pp
248 complex(real64), intent(in) :: aa(:, :)
249 complex(real64), intent(inout) :: ex(:, :)
250 logical, intent(in) :: hermitian
251
252 complex(real64), allocatable :: evectors(:, :), zevalues(:)
253 real(real64), allocatable :: evalues(:)
254
255 integer :: ii
256
257 push_sub(zlalg_exp)
258
259 safe_allocate(evectors(1:nn, 1:nn))
260
261 if (hermitian) then
262 safe_allocate(evalues(1:nn))
263 safe_allocate(zevalues(1:nn))
264
265 evectors(1:nn, 1:nn) = aa(1:nn, 1:nn)
266
267 call lalg_eigensolve(nn, evectors, evalues)
268
269 zevalues(1:nn) = exp(pp*evalues(1:nn))
270
271 do ii = 1, nn
272 ex(1:nn, ii) = zevalues(1:nn)*conjg(evectors(ii, 1:nn))
273 end do
274
275 ex(:, :) = matmul(evectors(:, :), ex(:, :))
276
277 safe_deallocate_a(evalues)
278 safe_deallocate_a(zevalues)
279 else
280 safe_allocate(zevalues(1:nn))
281
282 evectors(1:nn, 1:nn) = aa(1:nn, 1:nn)
283
284 call lalg_eigensolve_nonh(nn, evectors, zevalues)
285
286 zevalues(1:nn) = exp(pp*zevalues(1:nn))
287
288 ex(1:nn, 1:nn) = evectors(1:nn, 1:nn)
289
290 call lalg_inverse(nn, evectors, 'dir')
291
292 do ii = 1, nn
293 evectors(1:nn, ii) = zevalues(1:nn)*evectors(1:nn, ii)
294 end do
295
296 ex(:, :) = matmul(ex(:, :), evectors(:, :))
297
298 safe_deallocate_a(zevalues)
299 end if
300
301 safe_deallocate_a(evectors)
302
303 pop_sub(zlalg_exp)
304 end subroutine zlalg_exp
305
323 subroutine zlalg_phi(nn, pp, aa, ex, hermitian)
324 integer, intent(in) :: nn
325 complex(real64), intent(in) :: pp
326 complex(real64), intent(in) :: aa(:, :)
327 complex(real64), intent(inout) :: ex(:, :)
328 logical, intent(in) :: hermitian
329
330 complex(real64), allocatable :: evectors(:, :), zevalues(:)
331 real(real64), allocatable :: evalues(:)
332
333 integer :: ii
334
335 push_sub(zlalg_phi)
336
337 safe_allocate(evectors(1:nn, 1:nn))
338
339 if (hermitian) then
340 safe_allocate(evalues(1:nn))
341 safe_allocate(zevalues(1:nn))
342
343 evectors(:, :) = aa(:, :)
344
345 call lalg_eigensolve(nn, evectors, evalues)
346
347 do ii = 1, nn
348 zevalues(ii) = (exp(pp*evalues(ii)) - m_z1) / (pp*evalues(ii))
349 end do
350
351 do ii = 1, nn
352 ex(1:nn, ii) = zevalues(1:nn)*conjg(evectors(ii, 1:nn))
353 end do
354
355 ex(:, :) = matmul(evectors(:, :), ex(:, :))
356
357 safe_deallocate_a(evalues)
358 safe_deallocate_a(zevalues)
359 else
360 safe_allocate(zevalues(1:nn))
361
362 evectors(:, :) = aa(:, :)
363
364 call lalg_eigensolve_nonh(nn, evectors, zevalues)
365
366 do ii = 1, nn
367 zevalues(ii) = (exp(pp*zevalues(ii)) - m_z1) / (pp*zevalues(ii))
368 end do
369
370 ex(:, :) = evectors(:, :)
371
372 call lalg_inverse(nn, evectors, 'dir')
373
374 do ii = 1, nn
375 evectors(1:nn, ii) = zevalues(1:nn)*evectors(1:nn, ii)
376 end do
377
378 ex(:, :) = matmul(ex(:, :), evectors(:, :))
379
380 safe_deallocate_a(zevalues)
381 end if
382
383 pop_sub(zlalg_phi)
384 end subroutine zlalg_phi
385
386 complex(real64) function lalg_zdni(eigenvec, alpha, beta)
387 integer, intent(in) :: alpha, beta
388 complex(real64), intent(in) :: eigenvec(2)
389 lalg_zdni = conjg(eigenvec(alpha)) * eigenvec(beta)
390 end function lalg_zdni
391
392 complex(real64) function lalg_zduialpha(eigenvec, mmatrix, alpha, gamma, delta)
393 integer, intent(in) :: alpha, gamma, delta
394 complex(real64),intent(in) :: eigenvec(2), mmatrix(2, 2)
395 lalg_zduialpha = mmatrix(alpha, gamma) * eigenvec(delta)
396 end function lalg_zduialpha
397
398 complex(real64) function lalg_zd2ni(eigenvec, mmatrix, alpha, beta, gamma, delta)
399 integer, intent(in) :: alpha, beta, gamma, delta
400 complex(real64), intent(in) :: eigenvec(2), mmatrix(2, 2)
401 lalg_zd2ni = conjg(mmatrix(alpha, delta) * eigenvec(gamma)) * eigenvec(beta) + &
402 conjg(eigenvec(alpha)) * mmatrix(beta, gamma) * eigenvec(delta)
403 end function lalg_zd2ni
404
405 ! ---------------------------------------------------------
410 pure real(real64) function pseudoinverse_default_tolerance(m, n, sg_values) result(tol)
411 integer, intent(in) :: m, n
412 real(real64), intent(in) :: sg_values(:)
413 tol = m_epsilon * m * n * maxval(sg_values)
415
416
422 function lalg_remove_rotation(n, A) result(P)
423 integer, intent(in) :: n
424 real(real64), intent(in) :: a(1:n, 1:n)
425 real(real64) :: p(1:n, 1:n)
426
427 real(real64) :: ata(1:n, 1:n)
428
429 push_sub(lalg_remove_rotation)
430
431 ata = matmul(transpose(a), a)
432 call lalg_matrix_function(n, m_one, ata, p, square_root, .true.)
433
434 pop_sub(lalg_remove_rotation)
435 end function lalg_remove_rotation
436
437#include "undef.F90"
438#include "complex.F90"
439#include "lalg_adv_lapack_inc.F90"
440
441#include "undef.F90"
442#include "real.F90"
443#include "lalg_adv_lapack_inc.F90"
444
445end module lalg_adv_oct_m
446
447!! Local Variables:
448!! mode: f90
449!! coding: utf-8
450!! End:
Note that lalg_determinant and lalg_inverse are just wrappers over the same routine.
Definition: lalg_adv.F90:203
double exp(double __x) __attribute__((__nothrow__
This module contains interfaces for BLACS routines Interfaces are from http:
Definition: blacs.F90:27
This module provides the BLACS processor grid.
This module contains interfaces for BLAS routines You should not use these routines directly....
Definition: blas.F90:120
complex(real64) function, public lalg_zd2ni(eigenvec, mmatrix, alpha, beta, gamma, delta)
Definition: lalg_adv.F90:494
integer function zmatrix_rank_svd(a, preserve_mat, tol)
Compute the rank of the matrix A using SVD.
Definition: lalg_adv.F90:1797
subroutine zlowest_geneigensolve(k, n, a, b, e, v, preserve_mat, bof, err_code)
Computes the k lowest eigenvalues and the eigenvectors of a real symmetric or complex Hermitian gener...
Definition: lalg_adv.F90:952
complex(real64) function zdeterminant(n, a, preserve_mat)
Invert a real symmetric or complex Hermitian square matrix a.
Definition: lalg_adv.F90:1316
subroutine zeigensolve_nonh(n, a, e, err_code, side, sort_eigenvectors)
Computes all the eigenvalues and the right (left) eigenvectors of a real or complex (non-Hermitian) e...
Definition: lalg_adv.F90:831
subroutine zlinsyssolve(n, nrhs, a, b, x)
compute the solution to a real system of linear equations A*X = B, where A is an N-by-N matrix and X ...
Definition: lalg_adv.F90:1470
subroutine, public zlalg_exp(nn, pp, aa, ex, hermitian)
Definition: lalg_adv.F90:341
pure real(real64) function, public pseudoinverse_default_tolerance(m, n, sg_values)
Computes the default Moore-Penrose pseudoinverse tolerance for zeroing.
Definition: lalg_adv.F90:506
subroutine deigensolve_parallel(n, a, e, bof, err_code)
Computes all the eigenvalues and the eigenvectors of a real symmetric or complex Hermitian eigenprobl...
Definition: lalg_adv.F90:3558
subroutine dgeneigensolve(n, a, b, e, preserve_mat, bof, err_code)
Computes all the eigenvalues and the eigenvectors of a real symmetric or complex Hermitian generalize...
Definition: lalg_adv.F90:2332
subroutine zlalg_pseudo_inverse(a, threshold)
Invert a matrix with the Moore-Penrose pseudo-inverse.
Definition: lalg_adv.F90:1731
subroutine zeigensolve(n, a, e, bof, err_code)
Computes all eigenvalues and eigenvectors of a real symmetric or hermitian square matrix A.
Definition: lalg_adv.F90:1072
subroutine dsingular_value_decomp(m, n, a, u, vt, sg_values, preserve_mat)
Computes the singular value decomposition of a real M x N matrix a.
Definition: lalg_adv.F90:3176
subroutine deigensolve_nonh(n, a, e, err_code, side, sort_eigenvectors)
Computes all the eigenvalues and the right (left) eigenvectors of a real or complex (non-Hermitian) e...
Definition: lalg_adv.F90:2440
subroutine deigensolve_tridiagonal(n, a, e, bof, err_code)
Computes all eigenvalues and eigenvectors of a real symmetric tridiagonal matrix. For the Hermitian c...
Definition: lalg_adv.F90:2753
subroutine zinverse(n, a, method, det, threshold, uplo)
An interface to different method to invert a matrix.
Definition: lalg_adv.F90:1986
real(real64) function sfmin()
Auxiliary function.
Definition: lalg_adv.F90:256
subroutine dlinsyssolve(n, nrhs, a, b, x)
compute the solution to a real system of linear equations A*X = B, where A is an N-by-N matrix and X ...
Definition: lalg_adv.F90:3076
subroutine zsingular_value_decomp(m, n, a, u, vt, sg_values, preserve_mat)
Computes the singular value decomposition of a real M x N matrix a.
Definition: lalg_adv.F90:1570
subroutine dcholesky(n, a, bof, err_code)
Compute the Cholesky decomposition of real symmetric or complex Hermitian positive definite matrix a,...
Definition: lalg_adv.F90:2216
subroutine dlalg_matrix_function(n, factor, a, fun_a, fun, hermitian, tridiagonal)
This routine calculates a function of a matrix by using an eigenvalue decomposition.
Definition: lalg_adv.F90:3629
subroutine deigensolve(n, a, e, bof, err_code)
Computes all eigenvalues and eigenvectors of a real symmetric or hermitian square matrix A.
Definition: lalg_adv.F90:2682
subroutine dcholesky_pivoted(A, piv, rank, tol, work, UL, bof, info)
Compute the Cholesky factorization with complete pivoting of a real symmetric or complex Hermitian po...
Definition: lalg_adv.F90:2272
subroutine zeigensolve_tridiagonal(n, a, e, bof, err_code)
Computes all eigenvalues and eigenvectors of a real symmetric tridiagonal matrix. For the Hermitian c...
Definition: lalg_adv.F90:1145
subroutine zlowest_eigensolve(k, n, a, e, v, preserve_mat)
Computes the k lowest eigenvalues and the eigenvectors of a standard symmetric-definite eigenproblem,...
Definition: lalg_adv.F90:1224
complex(real64) function, public lalg_zduialpha(eigenvec, mmatrix, alpha, gamma, delta)
Definition: lalg_adv.F90:488
subroutine zgeneigensolve(n, a, b, e, preserve_mat, bof, err_code)
Computes all the eigenvalues and the eigenvectors of a real symmetric or complex Hermitian generalize...
Definition: lalg_adv.F90:719
subroutine dleast_squares_vec(nn, aa, bb, xx, preserve_mat)
Definition: lalg_adv.F90:3484
subroutine dlowest_geneigensolve(k, n, a, b, e, v, preserve_mat, bof, err_code)
Computes the k lowest eigenvalues and the eigenvectors of a real symmetric or complex Hermitian gener...
Definition: lalg_adv.F90:2561
subroutine zcholesky(n, a, bof, err_code)
Compute the Cholesky decomposition of real symmetric or complex Hermitian positive definite matrix a,...
Definition: lalg_adv.F90:603
complex(real64) function, public lalg_zdni(eigenvec, alpha, beta)
Definition: lalg_adv.F90:482
subroutine zleast_squares_vec(nn, aa, bb, xx, preserve_mat)
Definition: lalg_adv.F90:1886
real(real64) function, dimension(1:n, 1:n), public lalg_remove_rotation(n, A)
Remove rotation from affine transformation A by computing the polar decomposition and discarding the ...
Definition: lalg_adv.F90:518
subroutine lalg_zgeev(jobvl, jobvr, n, a, lda, w, vl, ldvl, vr, ldvr, work, lwork, rwork, info)
Definition: lalg_adv.F90:307
subroutine, public zlalg_matrix_function(n, factor, a, fun_a, fun, hermitian, tridiagonal)
This routine calculates a function of a matrix by using an eigenvalue decomposition.
Definition: lalg_adv.F90:2034
integer function dmatrix_rank_svd(a, preserve_mat, tol)
Compute the rank of the matrix A using SVD.
Definition: lalg_adv.F90:3395
subroutine dinverse(n, a, method, det, threshold, uplo)
An interface to different method to invert a matrix.
Definition: lalg_adv.F90:3581
subroutine zeigensolve_parallel(n, a, e, bof, err_code)
Computes all the eigenvalues and the eigenvectors of a real symmetric or complex Hermitian eigenprobl...
Definition: lalg_adv.F90:1963
real(real64) function ddeterminant(n, a, preserve_mat)
Invert a real symmetric or complex Hermitian square matrix a.
Definition: lalg_adv.F90:2922
subroutine lalg_dgeev(jobvl, jobvr, n, a, lda, w, vl, ldvl, vr, ldvr, work, lwork, rwork, info)
Definition: lalg_adv.F90:268
subroutine dlowest_eigensolve(k, n, a, e, v, preserve_mat)
Computes the k lowest eigenvalues and the eigenvectors of a standard symmetric-definite eigenproblem,...
Definition: lalg_adv.F90:2832
subroutine dsvd_inverse(m, n, a, threshold)
Computes the inverse of a real M x N matrix, a, using the SVD decomposition.
Definition: lalg_adv.F90:3266
subroutine, public zlalg_phi(nn, pp, aa, ex, hermitian)
Definition: lalg_adv.F90:419
subroutine zcholesky_pivoted(A, piv, rank, tol, work, UL, bof, info)
Compute the Cholesky factorization with complete pivoting of a real symmetric or complex Hermitian po...
Definition: lalg_adv.F90:659
subroutine dlalg_pseudo_inverse(a, threshold)
Invert a matrix with the Moore-Penrose pseudo-inverse.
Definition: lalg_adv.F90:3329
subroutine zsvd_inverse(m, n, a, threshold)
Computes the inverse of a real M x N matrix, a, using the SVD decomposition.
Definition: lalg_adv.F90:1668
This module contains interfaces for LAPACK routines.
Definition: lapack.F90:120
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:117
This module contains interfaces for ScaLAPACK routines Interfaces are from http:
Definition: scalapack.F90:133
This module is intended to contain "only mathematical" functions and procedures.
Definition: sort.F90:119
This module is intended to contain simple general-purpose utility functions and procedures.
Definition: utils.F90:120
int true(void)