Octopus
math.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
22module math_oct_m
23 use debug_oct_m
24 use global_oct_m
25 use, intrinsic :: iso_c_binding, only: c_double
26 use, intrinsic :: iso_fortran_env
31
32 implicit none
33
34 private
35 public :: &
36 is_close, &
38 ylmr_cmplx, &
39 ylmr_real, &
40 real_gaunt, &
41 weights, &
42 factorial, &
43 hermite, &
48 ddelta, &
51 even, &
52 odd, &
56 pad, &
57 pad_pow2, &
58 log2, &
59 expm1, &
61 phi1, &
62 phi2, &
64 is_prime, &
76
77 interface is_close
78 module procedure dis_close_scalar, zis_close_scalar
79 end interface
80
81 interface diagonal_matrix
83 end interface diagonal_matrix
84
88
92
95 interface interpolate
98 end interface interpolate
99
100 interface symmetrize_matrix
101 module procedure dsymmetrize_matrix, zsymmetrize_matrix
102 end interface symmetrize_matrix
103
104 interface log2
105 module procedure dlog2, ilog2, llog2
106 end interface log2
107
108 interface pad
109 module procedure pad4, pad8, pad48, pad88
110 end interface pad
111
112 interface
113 real(c_double) function expm1(x) bind(c, name='expm1')
114 import c_double
115 real(c_double), intent(in), value :: x
116 end function expm1
117 end interface
118
119contains
120
139 elemental logical function dis_close_scalar(x, y, rtol, atol)
140 real(real64), intent(in) :: x, y
141 real(real64), optional, intent(in) :: rtol
142 real(real64), optional, intent(in) :: atol
143 real(real64) :: atol_, rtol_
144
145 atol_ = optional_default(atol, 1.e-8_real64)
146 rtol_ = optional_default(rtol, 1.e-5_real64)
147
148 dis_close_scalar = abs(x - y) <= (atol_ + rtol_ * abs(y))
149 end function dis_close_scalar
150
152 elemental logical function zis_close_scalar(x, y, rtol, atol)
153 complex(real64), intent(in) :: x, y
154 real(real64), optional, intent(in) :: rtol
155 real(real64), optional, intent(in) :: atol
156 real(real64) :: atol_, rtol_
157
158 atol_ = optional_default(atol, 1.e-8_real64)
159 rtol_ = optional_default(rtol, 1.e-5_real64)
160
161 zis_close_scalar = abs(x - y) <= (atol_ + rtol_ * abs(y))
162 end function zis_close_scalar
163
164
165 ! ---------------------------------------------------------
168 pure function idiagonal_matrix(dim, diag) result(matrix)
169 integer, intent(in) :: dim
170 integer, intent(in) :: diag
171 integer :: matrix(dim, dim)
172
173 integer :: ii
175 matrix = 0
176 do ii = 1, dim
177 matrix(ii, ii) = diag
178 end do
179
180 end function idiagonal_matrix
181
182 ! ---------------------------------------------------------
183 recursive function hermite(n, x) result (h)
184 integer, intent(in) :: n
185 real(real64), intent(in) :: x
186
187 real(real64) :: h
189 ! no push_sub, called too frequently
190
191 if (n <= 0) then
192 h = m_one
193 elseif (n == 1) then
194 h = m_two*x
195 else
196 h = m_two*x*hermite(n-1,x) - m_two*(n-1)*hermite(n-2,x)
197 end if
198
199 end function hermite
200
202 ! ---------------------------------------------------------
203 recursive function factorial (n) RESULT (fac)
204 integer, intent(in) :: n
205
206 integer :: fac
207
208 ! no push_sub for recursive function
209
210 if (n <= 1) then
211 fac = 1
212 else
213 fac = n * factorial(n-1)
214 end if
215 end function factorial
216
217 ! ---------------------------------------------------------
219 subroutine ylmr_cmplx(xx, li, mi, ylm)
220 real(real64), intent(in) :: xx(3)
221 integer, intent(in) :: li, mi
222 complex(real64), intent(out) :: ylm
223
224 integer :: i
225 real(real64) :: dx, dy, dz, r, plm, cosm, sinm, cosmm1, sinmm1, cosphi, sinphi
226 real(real64), parameter :: tiny = 1.e-15_real64
227
228 ! no push_sub: this routine is called too many times
229
230 ! if l=0, no calculations are required
231 if (li == 0) then
232 ylm = cmplx(sqrt(m_one/(m_four*m_pi)), m_zero, real64)
233 return
234 end if
235
236 r = sqrt(xx(1)**2 + xx(2)**2 + xx(3)**2)
237
238 ! if r=0, direction is undefined => make ylm=0 except for l=0
239 if (r <= tiny) then
240 ylm = m_z0
241 return
242 end if
243 dx = xx(1)/r
244 dy = xx(2)/r
245 dz = xx(3)/r
246
247 ! get the associated Legendre polynomial (including the normalization factor)
248 ! We need to avoid getting outside [-1:1] due to rounding errors
249 if(abs(dz) > m_one) dz = sign(m_one, dz)
250 plm = loct_legendre_sphplm(li, abs(mi), dz)
251
252 ! compute sin(|m|*phi) and cos(|m|*phi)
253 r = sqrt(dx*dx + dy*dy)
254 if(r > tiny) then
255 cosphi = dx/r
256 sinphi = dy/r
257 else ! In this case the values are ill defined so we choose \phi=0
258 cosphi = m_zero
259 sinphi = m_zero
260 end if
262 cosm = m_one
263 sinm = m_zero
264 do i = 1, abs(mi)
265 cosmm1 = cosm
266 sinmm1 = sinm
267 cosm = cosmm1*cosphi - sinmm1*sinphi
268 sinm = cosmm1*sinphi + sinmm1*cosphi
269 end do
270
271 !And now ylm
272 ylm = plm*cmplx(cosm, sinm, real64)
273
274 if (mi < 0) then
275 ylm = conjg(ylm)
276 do i = 1, abs(mi)
277 ylm = -ylm
278 end do
279 end if
280
281 end subroutine ylmr_cmplx
282
283
284 ! ---------------------------------------------------------
290 subroutine ylmr_real(xx, li, mi, ylm)
291 real(real64), intent(in) :: xx(3)
292 integer, intent(in) :: li, mi
293 real(real64), intent(out) :: ylm
294
295 integer, parameter :: lmaxd = 20
296 real(real64), parameter :: tiny = 1.e-15_real64
297 integer :: i, ilm0, l, m, mabs
298 integer, save :: lmax = -1
299
300 real(real64) :: cmi, cosm, cosmm1, cosphi, dphase, dplg, fac, &
301 fourpi, plgndr, phase, pll, pmm, pmmp1, sinm, &
302 sinmm1, sinphi, rsize, rx, ry, rz, xysize
303 real(real64), save :: c(0:(lmaxd+1)*(lmaxd+1))
304
305 ! no push_sub: called too frequently
306
307 ! evaluate normalization constants once and for all
308 if (li > lmax) then
309 fourpi = m_four*m_pi
310 do l = 0, li
311 ilm0 = l*l + l
312 do m = 0, l
313 fac = (2*l+1)/fourpi
314 do i = l - m + 1, l + m
315 fac = fac/i
316 end do
317 c(ilm0 + m) = sqrt(fac)
318 ! next line because ylm are real combinations of m and -m
319 if (m /= 0) c(ilm0 + m) = c(ilm0 + m)*sqrt(m_two)
320 c(ilm0 - m) = c(ilm0 + m)
321 end do
322 end do
323 lmax = li
324 end if
325
326 ! if l=0, no calculations are required
327 if (li == 0) then
328 ylm = c(0)
329 return
330 end if
331
332 ! if r=0, direction is undefined => make ylm=0 except for l=0
333 rsize = sqrt(xx(1)**2 + xx(2)**2 + xx(3)**2)
334 if (rsize < tiny) then
335 ylm = m_zero
336 return
337 end if
338
339 rx = xx(1)/rsize
340 ry = xx(2)/rsize
341 rz = xx(3)/rsize
342
343 ! explicit formulas for l=1 and l=2
344 if (li == 1) then
345 select case (mi)
346 case (-1)
347 ylm = (-c(1))*ry
348 case (0)
349 ylm = c(2)*rz
350 case (1)
351 ylm = (-c(3))*rx
352 end select
353 return
354 end if
355
356 if (li == 2) then
357 select case (mi)
358 case (-2)
359 ylm = c(4)*6.0_real64*rx*ry
360 case (-1)
361 ylm = (-c(5))*m_three*ry*rz
362 case (0)
363 ylm = c(6)*m_half*(m_three*rz*rz - m_one)
364 case (1)
365 ylm = (-c(7))*m_three*rx*rz
366 case (2)
367 ylm = c(8)*m_three*(rx*rx - ry*ry)
368 end select
369 return
370 end if
371
372 ! general algorithm based on routine plgndr of numerical recipes
373 mabs = abs(mi)
374 xysize = sqrt(max(rx*rx + ry*ry, tiny))
375 cosphi = rx/xysize
376 sinphi = ry/xysize
377 cosm = m_one
378 sinm = m_zero
379 do m = 1, mabs
380 cosmm1 = cosm
381 sinmm1 = sinm
382 cosm = cosmm1*cosphi - sinmm1*sinphi
383 sinm = cosmm1*sinphi + sinmm1*cosphi
384 end do
385
386 if (mi < 0) then
387 phase = sinm
388 dphase = mabs*cosm
389 else
390 phase = cosm
391 dphase = (-mabs)*sinm
392 end if
393
394 pmm = m_one
395 fac = m_one
396
397 if (mabs > m_zero) then
398 do i = 1, mabs
399 pmm = (-pmm)*fac*xysize
400 fac = fac + m_two
401 end do
402 end if
403
404 if (li == mabs) then
405 plgndr = pmm
406 dplg = (-li)*rz*pmm/(xysize**2)
407 else
408 pmmp1 = rz*(2*mabs + 1)*pmm
409 if (li == mabs + 1) then
410 plgndr = pmmp1
411 dplg = -((li*rz*pmmp1 - (mabs + li)*pmm)/(xysize**2))
412 else
413 do l = mabs + 2, li
414 pll = (rz*(2*l - 1)*pmmp1 - (l + mabs - 1)*pmm)/(l - mabs)
415 pmm = pmmp1
416 pmmp1 = pll
417 end do
418 plgndr = pll
419 dplg = -((li*rz*pll - (l + mabs - 1)*pmm)/(xysize**2))
420 end if
421 end if
422
423 ilm0 = li*li + li
424 cmi = c(ilm0 + mi)
425 ylm = cmi*plgndr*phase
426
427 end subroutine ylmr_real
428
429
430 ! ---------------------------------------------------------
439 real(real64) function real_gaunt(l1, m1, l2, m2, l3, m3) result(coeff)
440 integer, intent(in) :: l1, m1, l2, m2, l3, m3
441
442 integer, parameter :: lmax_cache = 6
443 integer, parameter :: ngauss = 16 ! exact for polynomial degree <= 31 >= 3*lmax_cache
444 integer, parameter :: nphi = 72
445 real(real64), save :: cache(0:lmax_cache, -lmax_cache:lmax_cache, &
446 0:lmax_cache, -lmax_cache:lmax_cache, 0:lmax_cache, -lmax_cache:lmax_cache)
447 logical, save :: initialized(0:lmax_cache, -lmax_cache:lmax_cache, &
448 0:lmax_cache, -lmax_cache:lmax_cache, 0:lmax_cache, -lmax_cache:lmax_cache) = .false.
449 real(real64), save :: gl_x(1:ngauss), gl_w(1:ngauss)
450 logical, save :: gl_initialized = .false.
451
452 integer :: ix, iphi, ii, jj, iter
453 real(real64) :: phi, dphi, y1, y2, y3, xx(3), sintheta
454 real(real64) :: zz, p0, p1, p2, dp
455
456 ! no PUSH_SUB/POP_SUB: this is a low-level, frequently-called numerical helper
457
458 assert(l1 >= 0 .and. l1 <= lmax_cache)
459 assert(l2 >= 0 .and. l2 <= lmax_cache)
460 assert(l3 >= 0 .and. l3 <= lmax_cache)
461 assert(abs(m1) <= l1)
462 assert(abs(m2) <= l2)
463 assert(abs(m3) <= l3)
464
465 if (.not. gl_initialized) then
466 ! Gauss-Legendre nodes and weights on [-1, 1] by Newton iteration on the
467 ! Legendre recurrence (machine precision).
468 do ii = 1, ngauss/2
469 zz = cos(m_pi*(ii - 0.25_real64)/(ngauss + m_half))
470 do iter = 1, 100
471 p0 = m_one
472 p1 = m_zero
473 do jj = 1, ngauss
474 p2 = p1
475 p1 = p0
476 p0 = ((2*jj - 1)*zz*p1 - (jj - 1)*p2)/jj
477 end do
478 dp = ngauss*(zz*p0 - p1)/(zz**2 - m_one)
479 if (abs(p0/dp) < 1e-15_real64) exit
480 zz = zz - p0/dp
481 end do
482 gl_x(ii) = -zz
483 gl_x(ngauss + 1 - ii) = zz
484 gl_w(ii) = m_two/((m_one - zz**2)*dp**2)
485 gl_w(ngauss + 1 - ii) = gl_w(ii)
486 end do
487 gl_initialized = .true.
488 end if
489
490 if (.not. initialized(l1, m1, l2, m2, l3, m3)) then
491 dphi = m_two*m_pi/real(nphi, real64)
492
493 coeff = m_zero
494 do ix = 1, ngauss
495 sintheta = sqrt(max(m_one - gl_x(ix)**2, m_zero))
496 do iphi = 1, nphi
497 phi = (real(iphi, real64) - m_half)*dphi
498 xx(1) = sintheta*cos(phi)
499 xx(2) = sintheta*sin(phi)
500 xx(3) = gl_x(ix)
501
502 call ylmr_real(xx, l1, m1, y1)
503 call ylmr_real(xx, l2, m2, y2)
504 call ylmr_real(xx, l3, m3, y3)
505
506 coeff = coeff + y1*y2*y3*gl_w(ix)*dphi
507 end do
508 end do
509
510 cache(l1, m1, l2, m2, l3, m3) = coeff
511 initialized(l1, m1, l2, m2, l3, m3) = .true.
512 end if
513
514 coeff = cache(l1, m1, l2, m2, l3, m3)
515 end function real_gaunt
516
517
518 ! ---------------------------------------------------------
528 subroutine weights(N, M, cc, side)
529 integer, intent(in) :: n, m
530 real(real64), intent(out) :: cc(0:,0:,0:)
531 integer, optional, intent(in) :: side
533 integer :: i, j, k, mn, side_
534 real(real64) :: c1, c2, c3, c4, c5, xi
535 real(real64), allocatable :: x(:)
536
537 push_sub(weights)
538
539 safe_allocate(x(0:m))
540
541 if (present(side)) then
542 side_ = side
543 else
544 side_ = 0
545 end if
546
547 select case (side_)
548 case (-1)
549 ! grid-points for left-side finite-difference formulas on an equi-spaced grid
550 mn = m
551 x(:) = (/(-i,i=0,mn)/)
552 case (+1)
553 ! grid-points for right-side finite-difference formulas on an equi-spaced grid
554 mn = m
555 x(:) = (/(i,i=0,mn)/)
556 case default
557 ! grid-points for centered finite-difference formulas on an equi-spaced grid
558 mn = m/2
559 x(:) = (/0,(-i,i,i=1,mn)/)
560 end select
561
562
563
564 xi = m_zero ! point at which the approx. are to be accurate
565
566 cc = m_zero
567 cc(0,0,0) = m_one
568
569 c1 = m_one
570 c4 = x(0) - xi
571
572 do j = 1, m
573 mn = min(j,n)
574 c2 = m_one
575 c5 = c4
576 c4 = x(j) - xi
577
578 do k = 0, j - 1
579 c3 = x(j) - x(k)
580 c2 = c2*c3
581
582 if (j <= n) cc(k, j - 1, j) = m_zero
583 cc(k, j, 0) = c4*cc(k, j - 1, 0)/c3
584
585 do i = 1, mn
586 cc(k, j, i) = (c4*cc(k, j - 1, i) - i*cc(k, j - 1, i - 1))/c3
587 end do
588
589 cc(j, j, 0) = -c1*c5*cc(j - 1, j - 1, 0) / c2
590 end do
591
592 do i = 1, mn
593 cc(j, j, i) = c1*(i*cc(j - 1, j - 1, i - 1) - c5*cc(j - 1, j - 1, i))/c2
594 end do
595
596 c1 = c2
597 end do
598
599 safe_deallocate_a(x)
600 pop_sub(weights)
601 end subroutine weights
602
603 ! ---------------------------------------------------------
604 real(real64) pure function ddelta(i, j)
605 integer, intent(in) :: i
606 integer, intent(in) :: j
607
608 ! no push_sub in pure function
609
610 if (i == j) then
611 ddelta = m_one
612 else
613 ddelta = m_zero
614 end if
615
616 end function ddelta
617
618 ! ---------------------------------------------------------
619 subroutine interpolation_coefficients(nn, xa, xx, cc)
620 integer, intent(in) :: nn
621 real(real64), intent(in) :: xa(:)
622 real(real64), intent(in) :: xx
623 real(real64), contiguous, intent(out) :: cc(:)
624
625 integer :: ii, kk
626
627 ! no push_sub, called too frequently
628
629 do ii = 1, nn
630 cc(ii) = m_one
631 do kk = 1, nn
632 if (kk == ii) cycle
633 cc(ii) = cc(ii)*(xx - xa(kk))/(xa(ii) - xa(kk))
634 end do
635 end do
636
637 end subroutine interpolation_coefficients
638
639
640 ! ---------------------------------------------------------
642 logical pure function even(n)
643 integer, intent(in) :: n
644
645 even = (mod(n, 2) == 0)
646
647 end function even
648
649
650 ! ---------------------------------------------------------
652 logical pure function odd(n)
653 integer, intent(in) :: n
654
655 odd = .not. even(n)
656
657 end function odd
658
659 ! ---------------------------------------------------------
662 subroutine cartesian2hyperspherical(x, u)
663 real(real64), contiguous, intent(in) :: x(:)
664 real(real64), contiguous, intent(out) :: u(:)
665
666 integer :: n, k, j
667 real(real64) :: sumx2
668 real(real64), allocatable :: xx(:)
669
671
672 n = size(x)
673 assert(n>1)
674 assert(size(u) == n-1)
675
676 ! These lines make the code less machine-dependent.
677 safe_allocate(xx(1:n))
678 do j = 1, n
679 if (abs(x(j))<1.0e-8_real64) then
680 xx(j) = m_zero
681 else
682 xx(j) = x(j)
683 end if
684 end do
685
686 u = m_zero
687 do k = 1, n-1
688 sumx2 = m_zero
689 do j = k+1, n
690 sumx2 = sumx2 + xx(j)**2
691 end do
692 if (abs(sumx2) <= m_epsilon .and. abs(xx(k)) <= m_epsilon) exit
693 if (k < n - 1) then
694 u(k) = atan2(sqrt(sumx2), xx(k))
695 else
696 u(n-1) = atan2(xx(n), xx(n-1))
697 end if
698 end do
699
700
702 end subroutine cartesian2hyperspherical
703 ! ---------------------------------------------------------
704
705
706 ! ---------------------------------------------------------
709 subroutine hyperspherical2cartesian(u, x)
710 real(real64), contiguous, intent(in) :: u(:)
711 real(real64), contiguous, intent(out) :: x(:)
713 integer :: n, j, k
714
716
717 n = size(x)
718 assert(n>1)
719 assert(size(u) == n-1)
720
721 if (n == 2) then
722 x(1) = cos(u(1))
723 x(2) = sin(u(1))
724 elseif (n == 3) then
725 x(1) = cos(u(1))
726 x(2) = sin(u(1))*cos(u(2))
727 x(3) = sin(u(1))*sin(u(2))
728 else
729 x(1) = cos(u(1))
730 x(2) = sin(u(1))*cos(u(2))
731 x(3) = sin(u(1))*sin(u(2))*cos(u(3))
732 do j = 4, n - 1
733 x(j) = m_one
734 do k = 1, j - 1
735 x(j) = x(j) * sin(u(k))
736 end do
737 x(j) = x(j) * cos(u(j))
738 end do
739 x(n) = m_one
740 do k = 1, n - 2
741 x(n) = x(n) * sin(u(k))
742 end do
743 x(n) = x(n) * sin(u(n-1))
744 end if
747 end subroutine hyperspherical2cartesian
748 ! ---------------------------------------------------------
749
750
751 ! ---------------------------------------------------------
755 subroutine hypersphere_grad_matrix(grad_matrix, r, x)
756 real(real64), contiguous, intent(out) :: grad_matrix(:,:)
757 real(real64), intent(in) :: r
758 real(real64), contiguous, intent(in) :: x(:)
759
760 integer :: n, l, m
761
763
764 n = size(x)+1 ! the dimension of the matrix is (n-1)x(n)
765
766 ! --- l=1 ---
767 grad_matrix = m_one
768 grad_matrix(1,1) = -r*sin(x(1))
769 do m = 2, n-1
770 grad_matrix(m,1) = m_zero
771 end do
772
773 ! --- l=2..(n-1) ---
774 do l=2, n-1
775 do m=1, n-1
776 if (m == l) then
777 grad_matrix(m,l) = -r*grad_matrix(m,l)*product(sin(x(1:l)))
778 elseif (m < l) then
779 grad_matrix(m,l) = grad_matrix(m,l)*r*cos(x(m))*cos(x(l))*product(sin(x(1:m-1)))*product(sin(x(m+1:l-1)))
780 else
781 grad_matrix(m,l) = m_zero
782 end if
783 end do
784 end do
785
786 ! --- l=n ---
787 do m=1, n-1
788 grad_matrix(m,n) = r*cos(x(m))*grad_matrix(m,n)*product(sin(x(1:m-1)))*product(sin(x(m+1:n-1)))
789 end do
790
792 end subroutine hypersphere_grad_matrix
793
794 ! ---------------------------------------------------------
795 integer(int64) pure function pad88(size, blk)
796 integer(int64), intent(in) :: size
797 integer(int64), intent(in) :: blk
798
799 integer(int64) :: mm
800
801 mm = mod(size, blk)
802 if (mm == 0) then
803 pad88 = size
804 else
805 pad88 = size + blk - mm
806 end if
807 end function pad88
808
809 ! ---------------------------------------------------------
810 integer(int64) pure function pad48(size, blk)
811 integer, intent(in) :: size
812 integer(int64), intent(in) :: blk
813
814 pad48 = pad88(int(size, int64), blk)
815 end function pad48
816
817 ! ---------------------------------------------------------
818 integer(int64) pure function pad8(size, blk)
819 integer(int64), intent(in) :: size
820 integer, intent(in) :: blk
821
822 pad8 = pad88(size, int(blk, int64))
823 end function pad8
824
825 ! ---------------------------------------------------------
826 integer pure function pad4(size, blk)
827 integer, intent(in) :: size
828 integer, intent(in) :: blk
829
830 pad4 = int(pad88(int(size, int64), int(blk, int64)), int32)
831 end function pad4
832
833 ! ---------------------------------------------------------
834
839 integer pure function pad_pow2(size)
840 integer, intent(in) :: size
841
842 integer :: mm, mm2
843
844 mm = size
845 pad_pow2 = 1
846
847 ! loop below never terminates otherwise! just pick 1 as value.
848 if (size == 0) return
849
850 ! first we divide by two all the times we can, so we catch exactly
851 ! the case when size is already a power of two
852 do
853 mm2 = mm/2
854 if (mm - 2*mm2 /= 0) exit
856 mm = mm2
857 end do
858
859 ! the rest is handled by log2
860 if (mm /= 1) then
861 pad_pow2 = pad_pow2*2**(ceiling(log(real(mm, real64) )/log(2.0_8)))
862 end if
863
864 end function pad_pow2
865
866 ! -------------------------------------------------------
867
868 real(real64) pure function dlog2(xx)
869 real(real64), intent(in) :: xx
870
871 dlog2 = log(xx)/log(m_two)
872 end function dlog2
873
874 ! -------------------------------------------------------
875
876 integer pure function ilog2(xx)
877 integer, intent(in) :: xx
878
879 ilog2 = nint(log2(real(xx, real64) ))
880 end function ilog2
881
882 ! -------------------------------------------------------
883
884 integer(int64) pure function llog2(xx)
885 integer(int64), intent(in) :: xx
886
887 llog2 = nint(log2(real(xx, real64) ), kind=int64)
888 end function llog2
889
890 ! -------------------------------------------------------
892 complex(real64) pure function exponential(z)
893 complex(real64), intent(in) :: z
894
895 exponential = exp(z)
896 end function exponential
897
898 ! -------------------------------------------------------
904 complex(real64) pure function phi1(z)
905 complex(real64), intent(in) :: z
906
907 real(real64), parameter :: cut = 0.002_real64
908
909 if (abs(z) < cut) then
910 phi1 = m_one + m_half*z*(m_one + z/m_three*(m_one + m_fourth*z*(m_one + z/m_five)))
911 else
912 phi1 = (exp(z) - m_z1)/z
913 end if
914 end function phi1
915
916 ! -------------------------------------------------------
923 complex(real64) pure function phi2(z)
924 complex(real64), intent(in) :: z
925
926 real(real64), parameter :: cut = 0.002_real64
927
928 if (abs(z) < cut) then
929 phi2 = m_half + z/6.0_real64*(m_one + m_fourth*z*(m_one + z/m_five*(m_one + z/6.0_real64)))
930 else
931 phi2 = (exp(z) - z - m_z1)/z**2
932 end if
933 end function phi2
934
935 ! -------------------------------------------------------
937 real(real64) pure function square_root(x)
938 real(real64), intent(in) :: x
939
940 square_root = sqrt(x)
941 end function square_root
942
943 ! -------------------------------------------------------
944
945 logical function is_prime(n)
946 integer, intent(in) :: n
947
948 integer :: i, root
949
950 push_sub(is_prime)
951
952 if (n < 1) then
953 message(1) = "Internal error: is_prime does not take negative numbers."
954 call messages_fatal(1)
955 end if
956 if (n == 1) then
957 is_prime = .false.
958 pop_sub(is_prime)
959 return
960 end if
962 root = nint(sqrt(real(n, real64) ))
963 do i = 2, root
964 if (mod(n,i) == 0) then
965 is_prime = .false.
966 pop_sub(is_prime)
967 return
968 end if
969 end do
970
971 is_prime = .true.
972 pop_sub(is_prime)
973 end function is_prime
974
975 ! ---------------------------------------------------------
980 subroutine generate_rotation_matrix(R, ff, tt)
981 real(real64), contiguous, intent(out) :: r(:,:)
982 real(real64), intent(in) :: ff(:)
983 real(real64), contiguous, intent(in) :: tt(:)
984
985 integer :: dim, i, j
986 real(real64) :: th, uv, uu, vv, ft
987 real(real64), allocatable :: axis(:), u(:), v(:), f(:), t(:), p(:)
988
990
991 dim = size(ff,1)
992
993 assert((dim == 2) .or. (dim == 3))
994 assert(size(tt,1) == dim)
995 assert((size(r,1) == dim) .and. (size(r,2) == dim))
996
997 safe_allocate(u(1:dim))
998 safe_allocate(v(1:dim))
999 safe_allocate(f(1:dim))
1000 safe_allocate(t(1:dim))
1001
1002
1003 !normalize
1004 f = ff / norm2(ff)
1005 t = tt / norm2(tt)
1006
1007 ft = dot_product(f,t)
1008 ! Note : if ff and tt are antiparallel, we get ft = -1 and R = Identity.
1009 ! This is wrong.
1010
1011 if (abs(ft) < m_one) then
1012 select case (dim)
1013 case (2)
1014 th = acos(ft)
1015 r(1,1) = cos(th)
1016 r(1,2) = -sin(th)
1017
1018 r(2,1) = sin(th)
1019 r(2,2) = cos(th)
1020
1021 case (3)
1022 if (.false.) then
1023 !Old implementation
1024 safe_allocate(axis(1:dim))
1025 th = acos(ft)
1026
1027 u = f / dot_product(f,f)
1028 v = t /dot_product(t,t)
1029
1030 axis = dcross_product(u,v)
1031 axis = axis / norm2(axis)
1032
1033 r(1,1) = cos(th) + axis(1)**2 * (1 - cos(th))
1034 r(1,2) = axis(1)*axis(2)*(1-cos(th)) + axis(3)*sin(th)
1035 r(1,3) = axis(1)*axis(3)*(1-cos(th)) - axis(2)*sin(th)
1036
1037 r(2,1) = axis(2)*axis(1)*(1-cos(th)) - axis(3)*sin(th)
1038 r(2,2) = cos(th) + axis(2)**2 * (1 - cos(th))
1039 r(2,3) = axis(2)*axis(3)*(1-cos(th)) + axis(1)*sin(th)
1040
1041 r(3,1) = axis(3)*axis(1)*(1-cos(th)) + axis(2)*sin(th)
1042 r(3,2) = axis(3)*axis(2)*(1-cos(th)) - axis(1)*sin(th)
1043 r(3,3) = cos(th) + axis(3)**2 * (1 - cos(th))
1044
1045 safe_deallocate_a(axis)
1046 end if
1047
1048 if (.true.) then
1049 !Naive implementation
1050 th = acos(ft)
1051 u = dcross_product(f,t)
1052 u = u / norm2(u)
1053
1054 r(1,1) = u(1)**2 + (1-u(1)**2)*cos(th)
1055 r(1,2) = u(1)*u(2)*(1-cos(th)) - u(3)*sin(th)
1056 r(1,3) = u(1)*u(3) + u(2)*sin(th)
1057
1058 r(2,1) = u(1)*u(2)*(1-cos(th)) + u(3)*sin(th)
1059 r(2,2) = u(2)**2 + (1-u(2)**2)*cos(th)
1060 r(2,3) = u(2)*u(3)*(1-cos(th)) - u(1)*sin(th)
1061
1062 r(3,1) = u(1)*u(3)*(1-cos(th)) - u(2)*sin(th)
1063 r(3,2) = u(2)*u(3)*(1-cos(th)) + u(1)*sin(th)
1064 r(3,3) = u(3)**2 + (1-u(3)**2)*cos(th)
1065 end if
1066
1067 if (.false.) then
1068 !Fast
1069 safe_allocate(p(1:dim))
1070
1071 if (abs(f(1)) <= abs(f(2)) .and. abs(f(1)) < abs(f(3))) then
1072 p = (/m_one, m_zero, m_zero/)
1073 else if (abs(f(2)) < abs(f(1)) .and. abs(f(2)) <= abs(f(3))) then
1074 p = (/m_zero, m_one, m_zero/)
1075 else if (abs(f(3)) <= abs(f(1)) .and. abs(f(3)) < abs(f(2))) then
1076 p = (/m_zero, m_zero, m_one/)
1077 end if
1078
1079 u = p - f
1080 v = p - t
1081
1082 uu = dot_product(u,u)
1083 vv = dot_product(v,v)
1084 uv = dot_product(u,v)
1085
1086 do i = 1,3
1087 do j = 1,3
1088
1089 r(i,j) = ddelta(i,j) - m_two * u(i)*u(j)/uu - m_two * v(i)*v(j)/vv &
1090 + 4_real64*uv * v(i)*u(j) /(uu*vv)
1091
1092 end do
1093 end do
1094
1095 safe_deallocate_a(p)
1096 end if
1097
1098
1099 end select
1100
1101 else
1102
1103 r = m_zero
1104 do i = 1,dim
1105 r(i,i) = m_one
1106 end do
1107
1108 end if
1109
1110
1111 safe_deallocate_a(u)
1112 safe_deallocate_a(v)
1113
1115 end subroutine generate_rotation_matrix
1116
1117 ! ---------------------------------------------------------
1126 subroutine numder_ridders(x, h, res, err, f)
1127 implicit none
1128 real(real64), intent(in) :: x, h
1129 real(real64), intent(out) :: res, err
1130 interface
1131 subroutine f(x, fx)
1132 use, intrinsic :: iso_fortran_env
1133 implicit none
1134 real(real64), intent(in) :: x
1135 real(real64), intent(inout) :: fx
1136 end subroutine f
1137 end interface
1138
1139 real(real64), parameter :: con = 1.4_real64, big = 1.0e30_real64, safe = m_two
1140 integer, parameter :: ntab = 20
1141 integer :: i, j
1142 real(real64) :: errt, fac, hh, fx1, fx2
1143 real(real64), allocatable :: a(:, :)
1144
1145 push_sub(numder_ridders)
1146
1147 if (abs(h) <= m_epsilon) then
1148 message(1) = "h must be nonzero in numder_ridders"
1149 call messages_fatal(1)
1150 end if
1151
1152 safe_allocate(a(1:ntab, 1:ntab))
1153
1154 hh = h
1155 call f(x+hh, fx1)
1156 call f(x-hh, fx2)
1157 a(1,1) = (fx1-fx2) / (m_two*hh)
1158 err = big
1159 do i = 2, ntab
1160 hh = hh / con
1161 call f(x+hh, fx1)
1162 call f(x-hh, fx2)
1163 a(1,i) = (fx1-fx2) / (m_two*hh)
1164 fac = con**2
1165 do j = 2, i
1166 a(j,i) = (a(j-1,i)*fac-a(j-1,i-1)) / (fac-m_one)
1167 fac = con**2*fac
1168 errt = max(abs(a(j,i)-a(j-1,i)),abs(a(j,i)-a(j-1,i-1)))
1169 if (errt .le. err) then
1170 err = errt
1171 res = a(j,i)
1172 end if
1173 end do
1174 if (abs(a(i,i)-a(i-1,i-1)) .ge. safe*err) then
1175 safe_deallocate_a(a)
1176 pop_sub(numder_ridders)
1177 return
1178 end if
1179 end do
1180
1181 safe_deallocate_a(a)
1182 pop_sub(numder_ridders)
1183 end subroutine numder_ridders
1184
1185 ! ---------------------------------------------------------
1186 pure function dzcross_product(a, b) result(c)
1187 real(real64), contiguous, intent(in) :: a(:)
1188 complex(real64), contiguous, intent(in) :: b(:)
1189
1190 complex(real64) :: c(1:3)
1191
1192 c(1) = a(2)*b(3) - a(3)*b(2)
1193 c(2) = a(3)*b(1) - a(1)*b(3)
1194 c(3) = a(1)*b(2) - a(2)*b(1)
1195
1196 end function dzcross_product
1197
1198 ! ---------------------------------------------------------
1199 pure function zdcross_product(a, b) result(c)
1200 complex(real64), contiguous, intent(in) :: a(:)
1201 real(real64), contiguous, intent(in) :: b(:)
1202
1203 complex(real64) :: c(1:3)
1204
1205 c(1) = a(2)*b(3) - a(3)*b(2)
1206 c(2) = a(3)*b(1) - a(1)*b(3)
1207 c(3) = a(1)*b(2) - a(2)*b(1)
1208
1209 end function zdcross_product
1210
1211
1212!*****************************************************************************80
1213!
1214!! LM_POLYNOMIAL evaluates Laguerre polynomials Lm(n,m,x).
1215!
1216! First terms:
1217!
1218! M = 0
1220! Lm(0,0,X) = 1
1221! Lm(1,0,X) = -X + 1
1222! Lm(2,0,X) = X^2 - 4 X + 2
1223! Lm(3,0,X) = -X^3 + 9 X^2 - 18 X + 6
1224! Lm(4,0,X) = X^4 - 16 X^3 + 72 X^2 - 96 X + 24
1225! Lm(5,0,X) = -X^5 + 25 X^4 - 200 X^3 + 600 X^2 - 600 x + 120
1226! Lm(6,0,X) = X^6 - 36 X^5 + 450 X^4 - 2400 X^3 + 5400 X^2 - 4320 X + 720
1227!
1228! M = 1
1229!
1230! Lm(0,1,X) = 0
1231! Lm(1,1,X) = -1,
1232! Lm(2,1,X) = 2 X - 4,
1233! Lm(3,1,X) = -3 X^2 + 18 X - 18,
1234! Lm(4,1,X) = 4 X^3 - 48 X^2 + 144 X - 96
1235!
1236! M = 2
1237!
1238! Lm(0,2,X) = 0
1239! Lm(1,2,X) = 0,
1240! Lm(2,2,X) = 2,
1241! Lm(3,2,X) = -6 X + 18,
1242! Lm(4,2,X) = 12 X^2 - 96 X + 144
1243!
1244! M = 3
1245!
1246! Lm(0,3,X) = 0
1247! Lm(1,3,X) = 0,
1248! Lm(2,3,X) = 0,
1249! Lm(3,3,X) = -6,
1250! Lm(4,3,X) = 24 X - 96
1251!
1252! M = 4
1253!
1254! Lm(0,4,X) = 0
1255! Lm(1,4,X) = 0
1256! Lm(2,4,X) = 0
1257! Lm(3,4,X) = 0
1258! Lm(4,4,X) = 24
1259!
1260! Recursion:
1261!
1262! Lm(0,M,X) = 1
1263! Lm(1,M,X) = (M+1-X)
1264!
1265! if 2 <= N:
1266!
1267! Lm(N,M,X) = ( (M+2*N-1-X) * Lm(N-1,M,X)
1268! + (1-M-N) * Lm(N-2,M,X) ) / N
1269!
1270! Special values:
1271!
1272! For M = 0, the associated Laguerre polynomials Lm(N,M,X) are equal
1273! to the Laguerre polynomials L(N,X).
1274!
1275! Licensing:
1276!
1277! This code is distributed under the GNU LGPL license.
1278!
1279! Modified:
1280!
1281! 08 February 2003
1282!
1283! Author:
1284!
1285! John Burkardt
1286!
1287! Reference:
1288!
1289! Milton Abramowitz, Irene Stegun,
1290! Handbook of Mathematical Functions,
1291! National Bureau of Standards, 1964,
1292! ISBN: 0-486-61272-4,
1293! LC: QA47.A34.
1294!
1295! Parameters:
1296!
1297! Input, integer ( kind = 4 ) MM, the number of evaluation points.
1298!
1299! Input, integer ( kind = 4 ) N, the highest order polynomial to compute.
1300! Note that polynomials 0 through N will be computed.
1301!
1302! Input, integer ( kind = 4 ) M, the parameter. M must be nonnegative.
1303!
1304! Input, real ( kind = rk ) X(MM), the evaluation points.
1305!
1306! Output, real ( kind = rk ) CX(MM,0:N), the associated Laguerre polynomials
1307! of degrees 0 through N evaluated at the evaluation points.
1308!
1309! Taken from
1310! https://people.sc.fsu.edu/~jburkardt/f_src/laguerre_polynomial/laguerre_polynomial.html
1311! and adapted to Octopus by N. Tancogne-Dejean
1312 subroutine generalized_laguerre_polynomial ( np, nn, mm, xx, cx )
1313 integer, intent(in) :: np
1314 integer, intent(in) :: nn, mm
1315 real(real64), intent(in) :: xx(np)
1316 real(real64), intent(out) :: cx(np)
1317
1318 integer ii, ip
1319 real(real64), allocatable :: cx_tmp(:,:)
1320
1321 assert(mm >= 0)
1322
1323 safe_allocate(cx_tmp(1:np, 0:nn))
1324
1325 if (nn < 0) then
1326 cx = m_zero
1327 return
1328 end if
1329
1330 if (nn == 0) then
1331 cx(1:np) = m_one
1332 return
1333 end if
1334
1335 cx_tmp(1:np,0) = m_one
1336 !$omp parallel private(ii, ip)
1337 !$omp do
1338 do ip = 1, np
1339 cx_tmp(ip,1) = real(mm + 1, real64) - xx(ip)
1340 end do
1341 !$omp end do
1342 do ii = 2, nn
1343 !$omp do
1344 do ip = 1, np
1345 cx_tmp(ip, ii) = &
1346 (( real(mm + 2*ii - 1, real64) - xx(ip)) * cx_tmp(ip,ii-1) &
1347 + real(-mm -ii + 1, real64) * cx_tmp(ip,ii-2)) / real(ii, real64)
1348 end do
1349 end do
1350 !$omp end parallel
1351
1352 cx(1:np) = cx_tmp(1:np, nn)
1353
1354 safe_deallocate_a(cx_tmp)
1355
1356 end subroutine generalized_laguerre_polynomial
1357
1358 subroutine dupper_triangular_to_hermitian(nn, aa)
1359 integer, intent(in) :: nn
1360 real(real64), contiguous, intent(inout) :: aa(:, :)
1361
1362 integer :: ii, jj
1363
1364 do jj = 1, nn
1365 do ii = 1, jj-1
1366 aa(jj, ii) = aa(ii, jj)
1367 end do
1368 end do
1369 end subroutine dupper_triangular_to_hermitian
1370
1371 subroutine zupper_triangular_to_hermitian(nn, aa)
1372 integer, intent(in) :: nn
1373 complex(real64), contiguous, intent(inout) :: aa(:, :)
1374
1375 integer :: ii, jj
1376
1377 do jj = 1, nn
1378 do ii = 1, jj-1
1379 aa(jj, ii) = conjg(aa(ii, jj))
1380 end do
1381 aa(jj, jj) = real(aa(jj, jj), real64)
1382 end do
1383 end subroutine zupper_triangular_to_hermitian
1384
1385 subroutine dlower_triangular_to_hermitian(nn, aa)
1386 integer, intent(in) :: nn
1387 real(real64), contiguous, intent(inout) :: aa(:, :)
1388
1389 integer :: ii, jj
1390
1391 do jj = 1, nn
1392 do ii = 1, jj-1
1393 aa(ii, jj) = aa(jj, ii)
1394 end do
1395 end do
1396 end subroutine dlower_triangular_to_hermitian
1397
1398 subroutine zlower_triangular_to_hermitian(nn, aa)
1399 integer, intent(in) :: nn
1400 complex(real64), contiguous, intent(inout) :: aa(:, :)
1401
1402 integer :: ii, jj
1403
1404 do jj = 1, nn
1405 do ii = 1, jj-1
1406 aa(ii, jj) = conjg(aa(jj, ii))
1407 end do
1408 aa(jj, jj) = real(aa(jj, jj), real64)
1409 end do
1410 end subroutine zlower_triangular_to_hermitian
1411
1413 subroutine dsymmetrize_matrix(nn, aa)
1414 integer, intent(in) :: nn
1415 real(real64), contiguous, intent(inout) :: aa(:, :)
1416
1417 integer :: ii, jj
1418
1419 do ii = 1, nn
1420 do jj = ii+1, nn
1421 aa(ii, jj) = m_half * (aa(ii, jj) + aa(jj, ii))
1422 aa(jj, ii) = aa(ii, jj)
1423 end do
1424 end do
1425 end subroutine dsymmetrize_matrix
1426
1428 subroutine zsymmetrize_matrix(n, a)
1429 integer, intent(in) :: n
1430 complex(real64), contiguous, intent(inout) :: a(:, :)
1431
1432 integer :: i,j
1433
1434 do i = 1, n
1435 do j = i+1, n
1436 a(i, j) = m_half * (a(i, j) + conjg(a(j, i)))
1437 a(j, i) = conjg(a(i, j))
1438 end do
1439 end do
1440 end subroutine zsymmetrize_matrix
1441
1442
1443 subroutine dzero_small_elements_matrix(aa, tol)
1444 real(real64), contiguous, intent(inout) :: aa(:, :)
1445 real(real64), intent(in) :: tol
1446
1447 where(abs(aa)<tol)
1448 aa = m_zero
1449 end where
1450 end subroutine dzero_small_elements_matrix
1453 logical function is_symmetric(a, tol)
1454 real(real64), intent(in) :: a(:, :)
1455 real(real64), optional, intent(in) :: tol
1456
1457 real(real64) :: tolerance
1458
1459 push_sub(is_symmetric)
1460
1461 tolerance = optional_default(tol, 1.0e-8_real64)
1462 ! a must be square
1463 assert(size(a, 1) == size(a, 2))
1465 is_symmetric = all(abs(a - transpose(a)) < tolerance)
1466
1467 pop_sub(is_symmetric)
1468
1469 end function is_symmetric
1470
1472 logical pure function is_diagonal(dim, matrix, tol)
1473 integer, intent(in) :: dim
1474 real(real64), intent(in) :: matrix(:, :)
1475 real(real64), intent(in) :: tol
1476
1477 integer :: ii, jj
1478 real(real64) :: max_diag
1479
1480 max_diag = m_zero
1481 do ii = 1, dim
1482 max_diag = max(abs(matrix(ii, ii)), max_diag)
1483 end do
1484
1485 is_diagonal = .true.
1486 do ii = 1, dim
1487 do jj = 1, dim
1488 if (ii == jj) cycle
1489 if (abs(matrix(ii, jj)) > tol*max_diag) is_diagonal = .false.
1490 end do
1491 end do
1492
1493 end function is_diagonal
1494
1496 subroutine convert_to_base(num, base, converted)
1497 integer, intent(in) :: num
1498 integer, intent(in) :: base
1499 integer, contiguous, intent(out) :: converted(:)
1500
1501 integer :: i, num_, length
1502
1503 ! no PUSH_SUB, called too often
1504
1505 converted = 0
1506 if (num > 0) then
1507 ! length of converted number
1508 length = floor(log(real(num, real64)) / log(real(base, real64))) + 1
1509 assert(size(converted) >= length)
1510
1511 num_ = num
1512 ! do conversion by repeated division
1513 do i = 1, size(converted)
1514 converted(i) = mod(num_, base)
1515 num_ = num_ / base
1516 end do
1517 end if
1518
1519 end subroutine convert_to_base
1520
1522 subroutine convert_from_base(converted, base, num)
1523 integer, intent(in) :: converted(:)
1524 integer, intent(in) :: base
1525 integer, intent(out) :: num
1526
1527 integer :: i
1528
1529 ! no PUSH_SUB, called too often
1530
1531 num = m_zero
1532 do i = 1, size(converted)
1533 num = num + converted(i) * base**(i-1)
1534 end do
1535
1536 end subroutine convert_from_base
1537
1538#include "undef.F90"
1539#include "complex.F90"
1540#include "math_inc.F90"
1541
1542#include "undef.F90"
1543#include "real.F90"
1544#include "math_inc.F90"
1545
1546end module math_oct_m
1547
1548!! Local Variables:
1549!! mode: f90
1550!! coding: utf-8
1551!! End:
This is the common interface to a simple-minded polynomical interpolation procedure (simple use of th...
Definition: math.F90:188
double acos(double __x) __attribute__((__nothrow__
double log(double __x) __attribute__((__nothrow__
double exp(double __x) __attribute__((__nothrow__
double sin(double __x) __attribute__((__nothrow__
double sqrt(double __x) __attribute__((__nothrow__
double cos(double __x) __attribute__((__nothrow__
double atan2(double __y, double __x) __attribute__((__nothrow__
double floor(double __x) __attribute__((__nothrow__
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:115
subroutine zsymmetrize_matrix(n, a)
make a complex matrix Hermitian
Definition: math.F90:1522
complex(real64) pure function, public phi2(z)
Compute phi2(z) = (phi1(z)-1)/z = (exp(z) - z - 1)/z^2.
Definition: math.F90:1017
integer pure function ilog2(xx)
Definition: math.F90:970
logical pure function, public even(n)
Returns if n is even.
Definition: math.F90:736
pure real(real64) function, dimension(dim, dim) ddiagonal_matrix(dim, diag)
Currently only returns a matrix whose diagonal elements are all the same. Note that the integer versi...
Definition: math.F90:1893
subroutine, public generalized_laguerre_polynomial(np, nn, mm, xx, cx)
Definition: math.F90:1406
complex(real64) pure function, public exponential(z)
Wrapper for exponential.
Definition: math.F90:986
subroutine dinterpolate_0(xa, ya, x, y)
Definition: math.F90:1971
subroutine, public ylmr_cmplx(xx, li, mi, ylm)
Computes spherical harmonics ylm at position (x, y, z)
Definition: math.F90:313
subroutine zinterpolate_0(xa, ya, x, y)
Definition: math.F90:1780
subroutine, public convert_to_base(num, base, converted)
convert an integer in base 10 to a different base
Definition: math.F90:1590
subroutine dinterpolate_1(xa, ya, x, y)
Definition: math.F90:1943
real(real64) pure function dlog2(xx)
Definition: math.F90:962
integer(int64) pure function pad88(size, blk)
Definition: math.F90:889
real(real64) pure function, public square_root(x)
Wrapper for sqrt.
Definition: math.F90:1031
integer pure function pad4(size, blk)
Definition: math.F90:920
subroutine dlower_triangular_to_hermitian(nn, aa)
Definition: math.F90:1479
pure complex(real64) function, dimension(1:3), public dzcross_product(a, b)
Definition: math.F90:1280
subroutine, public cartesian2hyperspherical(x, u)
Performs a transformation of an n-dimensional vector from Cartesian coordinates to hyperspherical coo...
Definition: math.F90:756
integer pure function, public pad_pow2(size)
create array size, which is padded to powers of 2
Definition: math.F90:933
subroutine, public dzero_small_elements_matrix(aa, tol)
Definition: math.F90:1537
subroutine zinterpolate_1(xa, ya, x, y)
Definition: math.F90:1752
pure real(real64) function, dimension(1:3), public dcross_product(a, b)
Definition: math.F90:1996
integer(int64) pure function pad48(size, blk)
Definition: math.F90:904
subroutine dsymmetrize_matrix(nn, aa)
symmetrize a real matrix
Definition: math.F90:1507
subroutine, public ylmr_real(xx, li, mi, ylm)
This is a Numerical Recipes-based subroutine computes real spherical harmonics ylm at position (x,...
Definition: math.F90:384
subroutine dupper_triangular_to_hermitian(nn, aa)
Definition: math.F90:1452
subroutine, public interpolation_coefficients(nn, xa, xx, cc)
Definition: math.F90:713
logical function, public is_symmetric(a, tol)
Check if a 2D array is symmetric.
Definition: math.F90:1547
subroutine, public generate_rotation_matrix(R, ff, tt)
Generates a rotation matrix R to rotate a vector f to t.
Definition: math.F90:1074
elemental logical function zis_close_scalar(x, y, rtol, atol)
Same as dis_close_scalar for complex numbers.
Definition: math.F90:246
logical pure function, public odd(n)
Returns if n is odd.
Definition: math.F90:746
real(real64) pure function, public ddelta(i, j)
Definition: math.F90:698
logical function, public is_prime(n)
Definition: math.F90:1039
complex(real64) pure function, public phi1(z)
Compute phi1(z) = (exp(z)-1)/z.
Definition: math.F90:998
pure complex(real64) function, dimension(1:3), public zcross_product(a, b)
Definition: math.F90:1805
subroutine, public weights(N, M, cc, side)
Compute the weights for finite-difference calculations:
Definition: math.F90:622
subroutine zinterpolate_2(xa, ya, x, y)
Definition: math.F90:1717
pure complex(real64) function, dimension(dim, dim) zdiagonal_matrix(dim, diag)
Currently only returns a matrix whose diagonal elements are all the same. Note that the integer versi...
Definition: math.F90:1702
subroutine zlower_triangular_to_hermitian(nn, aa)
Definition: math.F90:1492
logical pure function, public is_diagonal(dim, matrix, tol)
Returns true is the matrix of size dim x dim is diagonal, given a relative tolerance.
Definition: math.F90:1566
subroutine zupper_triangular_to_hermitian(nn, aa)
Definition: math.F90:1465
pure integer function, dimension(dim, dim) idiagonal_matrix(dim, diag)
Currently only returns a matrix whose diagonal elements are all the same. Note that the real and comp...
Definition: math.F90:262
integer(int64) pure function pad8(size, blk)
Definition: math.F90:912
subroutine dinterpolate_2(xa, ya, x, y)
Definition: math.F90:1908
subroutine, public numder_ridders(x, h, res, err, f)
Numerical derivative (Ridder`s algorithm).
Definition: math.F90:1220
integer(int64) pure function llog2(xx)
Definition: math.F90:978
recursive real(real64) function, public hermite(n, x)
Definition: math.F90:277
elemental logical function dis_close_scalar(x, y, rtol, atol)
Are and equal within a tolerance.
Definition: math.F90:233
pure complex(real64) function, dimension(1:3), public zdcross_product(a, b)
Definition: math.F90:1293
subroutine, public convert_from_base(converted, base, num)
convert an integer to base 10 from a different base
Definition: math.F90:1616
real(real64) function, public real_gaunt(l1, m1, l2, m2, l3, m3)
Real Gaunt coefficient , by quadrature.
Definition: math.F90:533
subroutine, public hyperspherical2cartesian(u, x)
Performs the inverse transformation of cartesian2hyperspherical.
Definition: math.F90:803
subroutine, public hypersphere_grad_matrix(grad_matrix, r, x)
Gives the hyperspherical gradient matrix, which contains the derivatives of the Cartesian coordinates...
Definition: math.F90:849
recursive integer function, public factorial(n)
Definition: math.F90:297
/* To use the profiling module, call profiling_in and profiling_out with the label of the region as a...
Definition: profiling.F90:143
static double f(double w, void *p)
int true(void)