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 use, intrinsic :: iso_fortran_env
28 use lapack_oct_m
30 use math_oct_m
32 use mpi_oct_m
35 use sort_oct_m
36 use utils_oct_m
37#ifdef HAVE_ELPA
38 use elpa
39#endif
40
41 implicit none
42
43 private
44 public :: &
59 zlalg_exp, &
60 zlalg_phi, &
63 lalg_zdni, &
65 lalg_zd2ni, &
70
71
72
73 interface lalg_cholesky
74 module procedure dcholesky, zcholesky
75 end interface lalg_cholesky
76
77 interface lalg_geneigensolve
78 module procedure dgeneigensolve, zgeneigensolve
79 end interface lalg_geneigensolve
80
81 interface lalg_eigensolve_nonh
82 module procedure zeigensolve_nonh, deigensolve_nonh
83 end interface lalg_eigensolve_nonh
84
85 interface lalg_eigensolve
86 module procedure deigensolve, zeigensolve
87 end interface lalg_eigensolve
88
91 end interface lalg_eigensolve_tridiagonal
92
95 end interface lalg_eigensolve_parallel
96
99
100 interface lalg_determinant
101 module procedure ddeterminant, zdeterminant
102 end interface lalg_determinant
103
104 interface lalg_inverse
105 module procedure dinverse, zinverse
106 end interface lalg_inverse
107
108 interface lalg_linsyssolve
109 module procedure dlinsyssolve, zlinsyssolve
110 end interface lalg_linsyssolve
111
114 end interface lalg_singular_value_decomp
115
118 end interface lalg_pseudo_inverse
119
120 interface lalg_svd_inverse
121 module procedure dsvd_inverse, zsvd_inverse
122 end interface lalg_svd_inverse
123
126 end interface lalg_lowest_geneigensolve
127
128 interface lalg_lowest_eigensolve
129 module procedure dlowest_eigensolve, zlowest_eigensolve
130 end interface lalg_lowest_eigensolve
131
132 interface lapack_geev
133 module procedure lalg_dgeev, lalg_zgeev
134 end interface lapack_geev
135
136 interface lalg_least_squares
137 module procedure dleast_squares_vec, zleast_squares_vec
138 end interface lalg_least_squares
139
140 interface lalg_matrix_function
142 end interface lalg_matrix_function
143
144 interface lalg_matrix_rank_svd
145 module procedure dmatrix_rank_svd, zmatrix_rank_svd
146 end interface lalg_matrix_rank_svd
147
148contains
149
150 ! ---------------------------------------------------------
152 real(real64) function sfmin()
153 interface
154 real(real64) function dlamch(cmach)
155 import real64
156 implicit none
157 character(1), intent(in) :: cmach
158 end function dlamch
159 end interface
160
161 sfmin = dlamch('S')
162 end function sfmin
163
164 subroutine lalg_dgeev(jobvl, jobvr, n, a, lda, w, vl, ldvl, vr, ldvr, work, lwork, rwork, info)
165 character(1), intent(in) :: jobvl, jobvr
166 integer, intent(in) :: n, lda, ldvl, ldvr, lwork
167 real(real64), intent(inout) :: a(:, :)
168 complex(real64), intent(out) :: w(:)
169 real(real64), intent(out) :: vl(:, :), vr(:, :)
170 real(real64), intent(out) :: work(:)
171 real(real64), intent(out) :: rwork(:)
172 integer, intent(out) :: info
173
174 real(real64), allocatable :: wr(:), wi(:)
175
176 push_sub(lalg_dgeev)
177
178 safe_allocate(wr(1:n))
179 safe_allocate(wi(1:n))
181 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)
182
183 w(1:n) = cmplx(wr(1:n), wi(1:n), real64)
185 safe_deallocate_a(wr)
186 safe_deallocate_a(wi)
187
188 pop_sub(lalg_dgeev)
189 end subroutine lalg_dgeev
190
191 subroutine lalg_zgeev(jobvl, jobvr, n, a, lda, w, vl, ldvl, vr, ldvr, work, lwork, rwork, info)
192 character(1), intent(in) :: jobvl, jobvr
193 integer, intent(in) :: n, lda, ldvl, ldvr, lwork
194 complex(real64), intent(inout) :: a(:, :)
195 complex(real64), intent(out) :: w(:)
196 complex(real64), intent(out) :: vl(:, :), vr(:, :)
197 real(real64), intent(out) :: rwork(:)
198 complex(real64), intent(out) :: work(:)
199 integer, intent(out) :: info
200
201 push_sub(lalg_zgeev)
202
203 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)
204
205 pop_sub(lalg_zgeev)
206 end subroutine lalg_zgeev
225 subroutine zlalg_exp(nn, pp, aa, ex, hermitian)
226 integer, intent(in) :: nn
227 complex(real64), intent(in) :: pp
228 complex(real64), intent(in) :: aa(:, :)
229 complex(real64), intent(inout) :: ex(:, :)
230 logical, intent(in) :: hermitian
232 complex(real64), allocatable :: evectors(:, :), zevalues(:)
233 real(real64), allocatable :: evalues(:)
234
235 integer :: ii
236
237 push_sub(zlalg_exp)
238
239 safe_allocate(evectors(1:nn, 1:nn))
240
241 if (hermitian) then
242 safe_allocate(evalues(1:nn))
243 safe_allocate(zevalues(1:nn))
244
245 evectors(1:nn, 1:nn) = aa(1:nn, 1:nn)
246
247 call lalg_eigensolve(nn, evectors, evalues)
248
249 zevalues(1:nn) = exp(pp*evalues(1:nn))
250
251 do ii = 1, nn
252 ex(1:nn, ii) = zevalues(1:nn)*conjg(evectors(ii, 1:nn))
253 end do
254
255 ex(:, :) = matmul(evectors(:, :), ex(:, :))
256
257 safe_deallocate_a(evalues)
258 safe_deallocate_a(zevalues)
259 else
260 safe_allocate(zevalues(1:nn))
261
262 evectors(1:nn, 1:nn) = aa(1:nn, 1:nn)
263
264 call lalg_eigensolve_nonh(nn, evectors, zevalues)
265
266 zevalues(1:nn) = exp(pp*zevalues(1:nn))
267
268 ex(1:nn, 1:nn) = evectors(1:nn, 1:nn)
269
270 call lalg_inverse(nn, evectors, 'dir')
271
272 do ii = 1, nn
273 evectors(1:nn, ii) = zevalues(1:nn)*evectors(1:nn, ii)
274 end do
275
276 ex(:, :) = matmul(ex(:, :), evectors(:, :))
277
278 safe_deallocate_a(zevalues)
279 end if
280
281 safe_deallocate_a(evectors)
282
283 pop_sub(zlalg_exp)
284 end subroutine zlalg_exp
285
303 subroutine zlalg_phi(nn, pp, aa, ex, hermitian)
304 integer, intent(in) :: nn
305 complex(real64), intent(in) :: pp
306 complex(real64), intent(in) :: aa(:, :)
307 complex(real64), intent(inout) :: ex(:, :)
308 logical, intent(in) :: hermitian
309
310 complex(real64), allocatable :: evectors(:, :), zevalues(:)
311 real(real64), allocatable :: evalues(:)
312
313 integer :: ii
314
315 push_sub(zlalg_phi)
316
317 safe_allocate(evectors(1:nn, 1:nn))
318
319 if (hermitian) then
320 safe_allocate(evalues(1:nn))
321 safe_allocate(zevalues(1:nn))
322
323 evectors(:, :) = aa(:, :)
324
325 call lalg_eigensolve(nn, evectors, evalues)
326
327 do ii = 1, nn
328 zevalues(ii) = (exp(pp*evalues(ii)) - m_z1) / (pp*evalues(ii))
329 end do
330
331 do ii = 1, nn
332 ex(1:nn, ii) = zevalues(1:nn)*conjg(evectors(ii, 1:nn))
333 end do
334
335 ex(:, :) = matmul(evectors(:, :), ex(:, :))
336
337 safe_deallocate_a(evalues)
338 safe_deallocate_a(zevalues)
339 else
340 safe_allocate(zevalues(1:nn))
341
342 evectors(:, :) = aa(:, :)
343
344 call lalg_eigensolve_nonh(nn, evectors, zevalues)
345
346 do ii = 1, nn
347 zevalues(ii) = (exp(pp*zevalues(ii)) - m_z1) / (pp*zevalues(ii))
348 end do
349
350 ex(:, :) = evectors(:, :)
351
352 call lalg_inverse(nn, evectors, 'dir')
353
354 do ii = 1, nn
355 evectors(1:nn, ii) = zevalues(1:nn)*evectors(1:nn, ii)
356 end do
357
358 ex(:, :) = matmul(ex(:, :), evectors(:, :))
359
360 safe_deallocate_a(zevalues)
361 end if
362
363 pop_sub(zlalg_phi)
364 end subroutine zlalg_phi
365
366 complex(real64) function lalg_zdni(eigenvec, alpha, beta)
367 integer, intent(in) :: alpha, beta
368 complex(real64) :: eigenvec(2)
369 lalg_zdni = conjg(eigenvec(alpha)) * eigenvec(beta)
370 end function lalg_zdni
371
372 complex(real64) function lalg_zduialpha(eigenvec, mmatrix, alpha, gamma, delta)
373 integer, intent(in) :: alpha, gamma, delta
374 complex(real64) :: eigenvec(2), mmatrix(2, 2)
375 lalg_zduialpha = mmatrix(alpha, gamma) * eigenvec(delta)
376 end function lalg_zduialpha
377
378 complex(real64) function lalg_zd2ni(eigenvec, mmatrix, alpha, beta, gamma, delta)
379 integer, intent(in) :: alpha, beta, gamma, delta
380 complex(real64) :: eigenvec(2), mmatrix(2, 2)
381 lalg_zd2ni = conjg(mmatrix(alpha, delta) * eigenvec(gamma)) * eigenvec(beta) + &
382 conjg(eigenvec(alpha)) * mmatrix(beta, gamma) * eigenvec(delta)
383 end function lalg_zd2ni
384
385 ! ---------------------------------------------------------
390 pure real(real64) function pseudoinverse_default_tolerance(m, n, sg_values) result(tol)
391 integer, intent(in) :: m, n
392 real(real64), intent(in) :: sg_values(:)
393 tol = m_epsilon * m * n * maxval(sg_values)
395
396
402 function lalg_remove_rotation(n, A) result(P)
403 integer, intent(in) :: n
404 real(real64), intent(in) :: a(1:n, 1:n)
405 real(real64) :: p(1:n, 1:n)
406
407 real(real64) :: ata(1:n, 1:n)
408
409 push_sub(lalg_remove_rotation)
410
411 ata = matmul(transpose(a), a)
412 call lalg_matrix_function(n, m_one, ata, p, square_root, .true.)
413
414 pop_sub(lalg_remove_rotation)
415 end function lalg_remove_rotation
416
417#include "undef.F90"
418#include "complex.F90"
419#include "lalg_adv_lapack_inc.F90"
420
421#include "undef.F90"
422#include "real.F90"
423#include "lalg_adv_lapack_inc.F90"
424
425end module lalg_adv_oct_m
426
427!! Local Variables:
428!! mode: f90
429!! coding: utf-8
430!! End:
Note that lalg_determinant and lalg_inverse are just wrappers over the same routine.
Definition: lalg_adv.F90:195
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:474
integer function zmatrix_rank_svd(a, preserve_mat, tol)
Compute the rank of the matrix A using SVD.
Definition: lalg_adv.F90:1682
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:871
complex(real64) function zdeterminant(n, a, preserve_mat)
Invert a real symmetric or complex Hermitian square matrix a.
Definition: lalg_adv.F90:1232
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:750
subroutine zlinsyssolve(n, nrhs, a, b, x)
compute the solution to a complex system of linear equations A*X = B, where A is an N-by-N matrix and...
Definition: lalg_adv.F90:1389
subroutine, public zlalg_exp(nn, pp, aa, ex, hermitian)
Definition: lalg_adv.F90:321
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:486
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:3351
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:2155
subroutine zlalg_pseudo_inverse(a, threshold)
Invert a matrix with the Moore-Penrose pseudo-inverse.
Definition: lalg_adv.F90:1616
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:991
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:2978
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:2262
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:2574
subroutine zinverse(n, a, method, det, threshold, uplo)
An interface to different method to invert a matrix.
Definition: lalg_adv.F90:1870
real(real64) function sfmin()
Auxiliary function.
Definition: lalg_adv.F90:248
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:2900
subroutine zsingular_value_decomp(m, n, a, u, vt, sg_values, preserve_mat)
Computes the singular value decomposition of a complex MxN matrix a.
Definition: lalg_adv.F90:1467
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:2100
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:3422
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:2504
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:1061
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:1140
complex(real64) function, public lalg_zduialpha(eigenvec, mmatrix, alpha, gamma, delta)
Definition: lalg_adv.F90:468
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:638
subroutine dleast_squares_vec(nn, aa, bb, xx, preserve_mat)
Definition: lalg_adv.F90:3278
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:2383
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:583
complex(real64) function, public lalg_zdni(eigenvec, alpha, beta)
Definition: lalg_adv.F90:462
subroutine zleast_squares_vec(nn, aa, bb, xx, preserve_mat)
Definition: lalg_adv.F90:1771
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:498
subroutine lalg_zgeev(jobvl, jobvr, n, a, lda, w, vl, ldvl, vr, ldvr, work, lwork, rwork, info)
Definition: lalg_adv.F90:287
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:1918
integer function dmatrix_rank_svd(a, preserve_mat, tol)
Compute the rank of the matrix A using SVD.
Definition: lalg_adv.F90:3189
subroutine dinverse(n, a, method, det, threshold, uplo)
An interface to different method to invert a matrix.
Definition: lalg_adv.F90:3374
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:1847
real(real64) function ddeterminant(n, a, preserve_mat)
Invert a real symmetric or complex Hermitian square matrix a.
Definition: lalg_adv.F90:2743
subroutine lalg_dgeev(jobvl, jobvr, n, a, lda, w, vl, ldvl, vr, ldvr, work, lwork, rwork, info)
Definition: lalg_adv.F90:260
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:2653
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:3057
subroutine, public zlalg_phi(nn, pp, aa, ex, hermitian)
Definition: lalg_adv.F90:399
subroutine dlalg_pseudo_inverse(a, threshold)
Invert a matrix with the Moore-Penrose pseudo-inverse.
Definition: lalg_adv.F90:3123
subroutine zsvd_inverse(m, n, a, threshold)
Computes inverse of a complex MxN matrix, a, using the SVD decomposition.
Definition: lalg_adv.F90:1550
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)