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, &
75
76 interface lalg_cholesky
77 module procedure dcholesky, zcholesky
78 end interface lalg_cholesky
79
80 interface lalg_cholesky_pivoted
81 module procedure dcholesky_pivoted, zcholesky_pivoted
82 end interface lalg_cholesky_pivoted
83
84 interface lalg_geneigensolve
85 module procedure dgeneigensolve, zgeneigensolve
86 end interface lalg_geneigensolve
87
88 interface lalg_eigensolve_nonh
89 module procedure zeigensolve_nonh, deigensolve_nonh
90 end interface lalg_eigensolve_nonh
91
92 interface lalg_eigensolve
93 module procedure deigensolve, zeigensolve
94 end interface lalg_eigensolve
95
98 end interface lalg_eigensolve_tridiagonal
99
102 end interface lalg_eigensolve_parallel
103
106
107 interface lalg_determinant
108 module procedure ddeterminant, zdeterminant
109 end interface lalg_determinant
110
111 interface lalg_inverse
112 module procedure dinverse, zinverse
113 end interface lalg_inverse
114
115 interface lalg_linsyssolve
116 module procedure dlinsyssolve, zlinsyssolve
117 end interface lalg_linsyssolve
118
121 end interface lalg_singular_value_decomp
122
123 interface lalg_pseudo_inverse
125 end interface lalg_pseudo_inverse
126
127 interface lalg_svd_inverse
128 module procedure dsvd_inverse, zsvd_inverse
129 end interface lalg_svd_inverse
130
133 end interface lalg_lowest_geneigensolve
134
135 interface lalg_lowest_eigensolve
136 module procedure dlowest_eigensolve, zlowest_eigensolve
137 end interface lalg_lowest_eigensolve
138
139 interface lapack_geev
140 module procedure lalg_dgeev, lalg_zgeev
141 end interface lapack_geev
142
143 interface lalg_least_squares
144 module procedure dleast_squares_vec, zleast_squares_vec
145 end interface lalg_least_squares
146
147 interface lalg_matrix_function
149 end interface lalg_matrix_function
150
151 interface lalg_matrix_rank_svd
152 module procedure dmatrix_rank_svd, zmatrix_rank_svd
153 end interface lalg_matrix_rank_svd
154
155 interface lalg_qr_factorization
156 module procedure dqr_factorization, zqr_factorization
157 end interface lalg_qr_factorization
158
159contains
160
161 ! ---------------------------------------------------------
163 real(real64) function sfmin()
164 interface
165 real(real64) function dlamch(cmach)
166 import real64
167 implicit none
168 character(1), intent(in) :: cmach
169 end function dlamch
170 end interface
172 sfmin = dlamch('S')
173 end function sfmin
174
175 subroutine lalg_dgeev(jobvl, jobvr, n, a, lda, w, vl, ldvl, vr, ldvr, work, lwork, rwork, info)
176 character(1), intent(in) :: jobvl, jobvr
177 integer, intent(in) :: n, lda, ldvl, ldvr, lwork
178 real(real64), intent(inout) :: a(:, :)
179 complex(real64), intent(out) :: w(:)
180 real(real64), intent(out) :: vl(:, :), vr(:, :)
181 real(real64), intent(out) :: work(:)
182 real(real64), intent(out) :: rwork(:)
183 integer, intent(out) :: info
184
185 real(real64), allocatable :: wr(:), wi(:)
186#ifndef NDEBUG
187 logical :: halting_mode(size(ieee_all))
188#endif
189
190 push_sub(lalg_dgeev)
192 safe_allocate(wr(1:n))
193 safe_allocate(wi(1:n))
194
195#ifndef NDEBUG
196 ! Optimized LAPACK backends (e.g. MKL) may raise spurious floating-point
197 ! exceptions while still returning correct results, so suspend trapping
198 ! for builds that enable it
199 call ieee_get_halting_mode(ieee_all, halting_mode)
200 call ieee_set_halting_mode(ieee_all, .false.)
201#endif
202 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)
203#ifndef NDEBUG
204 call ieee_set_halting_mode(ieee_all, halting_mode)
205#endif
206 w(1:n) = cmplx(wr(1:n), wi(1:n), real64)
207
208 safe_deallocate_a(wr)
209 safe_deallocate_a(wi)
211 pop_sub(lalg_dgeev)
212 end subroutine lalg_dgeev
213
214 subroutine lalg_zgeev(jobvl, jobvr, n, a, lda, w, vl, ldvl, vr, ldvr, work, lwork, rwork, info)
215 character(1), intent(in) :: jobvl, jobvr
216 integer, intent(in) :: n, lda, ldvl, ldvr, lwork
217 complex(real64), intent(inout) :: a(:, :)
218 complex(real64), intent(out) :: w(:)
219 complex(real64), intent(out) :: vl(:, :), vr(:, :)
220 real(real64), intent(out) :: rwork(:)
221 complex(real64), intent(out) :: work(:)
222 integer, intent(out) :: info
223
224 push_sub(lalg_zgeev)
225
226 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)
227
228 pop_sub(lalg_zgeev)
229 end subroutine lalg_zgeev
248 subroutine zlalg_exp(nn, pp, aa, ex, hermitian)
249 integer, intent(in) :: nn
250 complex(real64), intent(in) :: pp
251 complex(real64), intent(in) :: aa(:, :)
252 complex(real64), intent(inout) :: ex(:, :)
253 logical, intent(in) :: hermitian
254
255 complex(real64), allocatable :: evectors(:, :), zevalues(:)
256 real(real64), allocatable :: evalues(:)
257
258 integer :: ii
259
260 push_sub(zlalg_exp)
261
262 safe_allocate(evectors(1:nn, 1:nn))
263
264 if (hermitian) then
265 safe_allocate(evalues(1:nn))
266 safe_allocate(zevalues(1:nn))
267
268 evectors(1:nn, 1:nn) = aa(1:nn, 1:nn)
269
270 call lalg_eigensolve(nn, evectors, evalues)
271
272 zevalues(1:nn) = exp(pp*evalues(1:nn))
273
274 do ii = 1, nn
275 ex(1:nn, ii) = zevalues(1:nn)*conjg(evectors(ii, 1:nn))
276 end do
277
278 ex(:, :) = matmul(evectors(:, :), ex(:, :))
279
280 safe_deallocate_a(evalues)
281 safe_deallocate_a(zevalues)
282 else
283 safe_allocate(zevalues(1:nn))
284
285 evectors(1:nn, 1:nn) = aa(1:nn, 1:nn)
286
287 call lalg_eigensolve_nonh(nn, evectors, zevalues)
288
289 zevalues(1:nn) = exp(pp*zevalues(1:nn))
290
291 ex(1:nn, 1:nn) = evectors(1:nn, 1:nn)
292
293 call lalg_inverse(nn, evectors, 'dir')
294
295 do ii = 1, nn
296 evectors(1:nn, ii) = zevalues(1:nn)*evectors(1:nn, ii)
297 end do
298
299 ex(:, :) = matmul(ex(:, :), evectors(:, :))
300
301 safe_deallocate_a(zevalues)
302 end if
303
304 safe_deallocate_a(evectors)
305
306 pop_sub(zlalg_exp)
307 end subroutine zlalg_exp
308
326 subroutine zlalg_phi(nn, pp, aa, ex, hermitian)
327 integer, intent(in) :: nn
328 complex(real64), intent(in) :: pp
329 complex(real64), intent(in) :: aa(:, :)
330 complex(real64), intent(inout) :: ex(:, :)
331 logical, intent(in) :: hermitian
332
333 complex(real64), allocatable :: evectors(:, :), zevalues(:)
334 real(real64), allocatable :: evalues(:)
335
336 integer :: ii
337
338 push_sub(zlalg_phi)
339
340 safe_allocate(evectors(1:nn, 1:nn))
341
342 if (hermitian) then
343 safe_allocate(evalues(1:nn))
344 safe_allocate(zevalues(1:nn))
345
346 evectors(:, :) = aa(:, :)
347
348 call lalg_eigensolve(nn, evectors, evalues)
349
350 do ii = 1, nn
351 zevalues(ii) = (exp(pp*evalues(ii)) - m_z1) / (pp*evalues(ii))
352 end do
353
354 do ii = 1, nn
355 ex(1:nn, ii) = zevalues(1:nn)*conjg(evectors(ii, 1:nn))
356 end do
357
358 ex(:, :) = matmul(evectors(:, :), ex(:, :))
359
360 safe_deallocate_a(evalues)
361 safe_deallocate_a(zevalues)
362 else
363 safe_allocate(zevalues(1:nn))
364
365 evectors(:, :) = aa(:, :)
366
367 call lalg_eigensolve_nonh(nn, evectors, zevalues)
368
369 do ii = 1, nn
370 zevalues(ii) = (exp(pp*zevalues(ii)) - m_z1) / (pp*zevalues(ii))
371 end do
372
373 ex(:, :) = evectors(:, :)
374
375 call lalg_inverse(nn, evectors, 'dir')
376
377 do ii = 1, nn
378 evectors(1:nn, ii) = zevalues(1:nn)*evectors(1:nn, ii)
379 end do
380
381 ex(:, :) = matmul(ex(:, :), evectors(:, :))
382
383 safe_deallocate_a(zevalues)
384 end if
385
386 pop_sub(zlalg_phi)
387 end subroutine zlalg_phi
388
389 complex(real64) function lalg_zdni(eigenvec, alpha, beta)
390 integer, intent(in) :: alpha, beta
391 complex(real64), intent(in) :: eigenvec(2)
392 lalg_zdni = conjg(eigenvec(alpha)) * eigenvec(beta)
393 end function lalg_zdni
394
395 complex(real64) function lalg_zduialpha(eigenvec, mmatrix, alpha, gamma, delta)
396 integer, intent(in) :: alpha, gamma, delta
397 complex(real64),intent(in) :: eigenvec(2), mmatrix(2, 2)
398 lalg_zduialpha = mmatrix(alpha, gamma) * eigenvec(delta)
399 end function lalg_zduialpha
400
401 complex(real64) function lalg_zd2ni(eigenvec, mmatrix, alpha, beta, gamma, delta)
402 integer, intent(in) :: alpha, beta, gamma, delta
403 complex(real64), intent(in) :: eigenvec(2), mmatrix(2, 2)
404 lalg_zd2ni = conjg(mmatrix(alpha, delta) * eigenvec(gamma)) * eigenvec(beta) + &
405 conjg(eigenvec(alpha)) * mmatrix(beta, gamma) * eigenvec(delta)
406 end function lalg_zd2ni
407
408 ! ---------------------------------------------------------
413 pure real(real64) function pseudoinverse_default_tolerance(m, n, sg_values) result(tol)
414 integer, intent(in) :: m, n
415 real(real64), intent(in) :: sg_values(:)
416 tol = m_epsilon * m * n * maxval(sg_values)
418
419
425 function lalg_remove_rotation(n, A) result(P)
426 integer, intent(in) :: n
427 real(real64), intent(in) :: a(1:n, 1:n)
428 real(real64) :: p(1:n, 1:n)
429
430 real(real64) :: ata(1:n, 1:n)
431
432 push_sub(lalg_remove_rotation)
433
434 ata = matmul(transpose(a), a)
435 call lalg_matrix_function(n, m_one, ata, p, square_root, .true.)
436
437 pop_sub(lalg_remove_rotation)
438 end function lalg_remove_rotation
439
440#include "undef.F90"
441#include "complex.F90"
442#include "lalg_adv_lapack_inc.F90"
443
444#include "undef.F90"
445#include "real.F90"
446#include "lalg_adv_lapack_inc.F90"
447
448end module lalg_adv_oct_m
449
450!! Local Variables:
451!! mode: f90
452!! coding: utf-8
453!! End:
Note that lalg_determinant and lalg_inverse are just wrappers over the same routine.
Definition: lalg_adv.F90:202
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:497
integer function zmatrix_rank_svd(a, preserve_mat, tol)
Compute the rank of the matrix A using SVD.
Definition: lalg_adv.F90:1878
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:1033
complex(real64) function zdeterminant(n, a, preserve_mat)
Invert a real symmetric or complex Hermitian square matrix a.
Definition: lalg_adv.F90:1397
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:912
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:1551
subroutine, public zlalg_exp(nn, pp, aa, ex, hermitian)
Definition: lalg_adv.F90:344
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:509
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:3717
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:2415
subroutine zlalg_pseudo_inverse(a, threshold)
Invert a matrix with the Moore-Penrose pseudo-inverse.
Definition: lalg_adv.F90:1812
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:1153
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:3335
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:2599
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:2912
subroutine zinverse(n, a, method, det, threshold, uplo)
An interface to different method to invert a matrix.
Definition: lalg_adv.F90:2067
subroutine dqr_factorization(A, jpvt, tau, info, bof)
Compute a QR factorization with column pivoting of matrix A: A*P = Q*R.
Definition: lalg_adv.F90:2521
real(real64) function sfmin()
Auxiliary function.
Definition: lalg_adv.F90:259
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:3235
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:1651
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:2297
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:3788
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:2841
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:2353
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:1226
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:1305
complex(real64) function, public lalg_zduialpha(eigenvec, mmatrix, alpha, gamma, delta)
Definition: lalg_adv.F90:491
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:724
subroutine dleast_squares_vec(nn, aa, bb, xx, preserve_mat)
Definition: lalg_adv.F90:3643
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:2720
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:606
complex(real64) function, public lalg_zdni(eigenvec, alpha, beta)
Definition: lalg_adv.F90:485
subroutine zleast_squares_vec(nn, aa, bb, xx, preserve_mat)
Definition: lalg_adv.F90:1967
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:521
subroutine lalg_zgeev(jobvl, jobvr, n, a, lda, w, vl, ldvl, vr, ldvr, work, lwork, rwork, info)
Definition: lalg_adv.F90:310
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:2115
subroutine zqr_factorization(A, jpvt, tau, info, bof)
Compute a QR factorization with column pivoting of matrix A: A*P = Q*R.
Definition: lalg_adv.F90:834
integer function dmatrix_rank_svd(a, preserve_mat, tol)
Compute the rank of the matrix A using SVD.
Definition: lalg_adv.F90:3554
subroutine dinverse(n, a, method, det, threshold, uplo)
An interface to different method to invert a matrix.
Definition: lalg_adv.F90:3740
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:2044
real(real64) function ddeterminant(n, a, preserve_mat)
Invert a real symmetric or complex Hermitian square matrix a.
Definition: lalg_adv.F90:3081
subroutine lalg_dgeev(jobvl, jobvr, n, a, lda, w, vl, ldvl, vr, ldvr, work, lwork, rwork, info)
Definition: lalg_adv.F90:271
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:2991
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:3425
subroutine, public zlalg_phi(nn, pp, aa, ex, hermitian)
Definition: lalg_adv.F90:422
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:662
subroutine dlalg_pseudo_inverse(a, threshold)
Invert a matrix with the Moore-Penrose pseudo-inverse.
Definition: lalg_adv.F90:3488
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:1749
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)