https://www.cdslab.org/paramonte/fortran/2
Current view: top level - main - pm_matrixUpdate@routines.inc.F90 (source / functions) Hit Total Coverage
Test: ParaMonte 2.0.0 :: Serial Fortran - Code Coverage Report Lines: 97 130 74.6 %
Date: 2024-04-08 03:18:57 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       2             : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       3             : !!!!                                                                                                                            !!!!
       4             : !!!!    ParaMonte: Parallel Monte Carlo and Machine Learning Library.                                                           !!!!
       5             : !!!!                                                                                                                            !!!!
       6             : !!!!    Copyright (C) 2012-present, The Computational Data Science Lab                                                          !!!!
       7             : !!!!                                                                                                                            !!!!
       8             : !!!!    This file is part of the ParaMonte library.                                                                             !!!!
       9             : !!!!                                                                                                                            !!!!
      10             : !!!!    LICENSE                                                                                                                 !!!!
      11             : !!!!                                                                                                                            !!!!
      12             : !!!!       https://github.com/cdslaborg/paramonte/blob/main/LICENSE.md                                                          !!!!
      13             : !!!!                                                                                                                            !!!!
      14             : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      15             : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      16             : 
      17             : !>  \brief
      18             : !>  This include file contains procedure implementation of the generic interfaces of [pm_matrixUpdate](@ref pm_matrixUpdate).
      19             : !>
      20             : !>  \finmain
      21             : !>
      22             : !>  \author
      23             : !>  \AmirShahmoradi, Apr 21, 2017, 1:54 AM, Institute for Computational Engineering and Sciences (ICES), The University of Texas at Austin
      24             : 
      25             : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      26             : 
      27             :         ! Define the BLAS storage triangle.
      28             : #if     shrk_ENABLED && SLD_ENABLED
      29             : #define BLAS_UPLO "L"
      30             : #elif   shrk_ENABLED && SUD_ENABLED
      31             : #define BLAS_UPLO "U"
      32             : #elif   !(setMatUpdateR1_ENABLED || setMatUpdateTriang_ENABLED)
      33             : #error  "Unrecognized interface."
      34             : #endif
      35             :         ! Define the BLAS storage triangle.
      36             : #if     shrk_ENABLED && OTP_ENABLED && CHM_ENABLED && CK_ENABLED
      37             : #define blasXXRK blasHERK
      38             : #define BLAS_TRANS "C"
      39             : #elif   shrk_ENABLED && ONO_ENABLED && CHM_ENABLED && CK_ENABLED
      40             : #define blasXXRK blasHERK
      41             : #define BLAS_TRANS "N"
      42             : #elif   shrk_ENABLED && OTP_ENABLED && (CHM_ENABLED || CSM_ENABLED) && (CK_ENABLED || RK_ENABLED)
      43             : #define blasXXRK blasSYRK
      44             : #define BLAS_TRANS "T"
      45             : #elif   shrk_ENABLED && ONO_ENABLED && (CHM_ENABLED || CSM_ENABLED) && (CK_ENABLED || RK_ENABLED)
      46             : #define blasXXRK blasSYRK
      47             : #define BLAS_TRANS "N"
      48             : #elif   !(IK_ENABLED || setMatUpdateR1_ENABLED || setMatUpdateTriang_ENABLED)
      49             : #error  "Unrecognized interface."
      50             : #endif
      51             :         ! Define the constants.
      52             : #if     IK_ENABLED
      53             : #define TYPE_KIND integer(TKC)
      54             :         integer(TKC), parameter :: ZERO = 0_TKC, ONE = 1_TKC
      55             : #elif   CK_ENABLED
      56             : #define TYPE_KIND complex(TKC)
      57             :         complex(TKC), parameter :: ZERO = (0._TKC, 0._TKC), ONE = (1._TKC, 0._TKC)
      58             : #elif   RK_ENABLED
      59             : #define TYPE_KIND real(TKC)
      60             :         real(TKC)   , parameter :: ZERO = 0._TKC, ONE = 1._TKC
      61             : #else
      62             : #error  "Unrecognized interface."
      63             : #endif
      64             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      65             : #if     setMatUpdate_ENABLED && shrk_ENABLED
      66             :         !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      67             : 
      68             : #if     !(BLAS_ENABLED && DISPATCH_ENABLED)
      69             :         TYPE_KIND :: temp
      70             :         integer(IK) :: irow, icol, idum
      71             : #endif
      72             : #if     ASS_ENABLED
      73             : #define BETA beta_def
      74             : #define ALPHA alpha_def
      75             :         integer(IK) :: ndim, ndum
      76             :         TYPE_KIND :: alpha_def, beta_def
      77           6 :         if (present(beta)) then; beta_def = beta; else; beta_def = ONE; end if
      78           6 :         if (present(alpha)) then; alpha_def = alpha; else; alpha_def = ONE; end if
      79           6 :         ndim = size(mat, 1, IK)
      80           6 :         CHECK_ASSERTION(__LINE__, size(mat, 1, IK) == size(mat, 2, IK), SK_"@setMatUpdate(): The condition `size(mat, 1) == size(mat, 2)` must hold. shape(mat) = "//getStr(shape(mat, IK)))
      81             : #if     ONO_ENABLED
      82           4 :         ndum = size(matA, 2, IK)
      83          36 :         CHECK_ASSERTION(__LINE__, size(mat, 2, IK) == size(matA, 1, IK), SK_"@setMatUpdate(): The condition `size(mat, 2) == size(matA, 1)` must hold. shape(mat), shape(matA) = "//getStr([shape(mat, IK), shape(matA, IK)]))
      84             : #elif   OTP_ENABLED
      85           2 :         ndum = size(matA, 1, IK)
      86          18 :         CHECK_ASSERTION(__LINE__, size(mat, 2, IK) == size(matA, 2, IK), SK_"@setMatUpdate(): The condition `size(mat, 2) == size(matA, 2)` must hold. shape(mat), shape(matA) = "//getStr([shape(mat, IK), shape(matA, IK)]))
      87             : #else
      88             : #error  "Unrecognized interface."
      89             : #endif
      90             : #elif   EXP_ENABLED
      91             :         ! Ensure roffs and subset bounds are logical.
      92       74193 :         CHECK_ASSERTION(__LINE__, all(0_IK <= [ndim, ndum]), SK_"@setMatUpdate(): The condition `all(0_IK <= [ndim, ndum])` must hold. ndim, ndum = "//getStr([ndim, ndum]))
      93      173117 :         CHECK_ASSERTION(__LINE__, all(0_IK <= 1_IK - lbound(mat, kind = IK)), SK_"@setMatUpdate(): The condition `all(0 <= [roff, coff])` must hold. roff, coff = "//getStr([1_IK - lbound(mat)]))
      94      173117 :         CHECK_ASSERTION(__LINE__, all(0_IK <= 1_IK - lbound(matA, kind = IK)), SK_"@setMatUpdate(): The condition `all(0 <= [roffA, coffA])` must hold. roffA, coffA = "//getStr([1_IK - lbound(matA)]))
      95             : #if     ONO_ENABLED
      96      160758 :         CHECK_ASSERTION(__LINE__, all([ndim, ndum] <= shape(matA, IK)), SK_"@setMatUpdate(): The condition `all([roffA + ndim, coffA + ndum] <= shape(matA))` must hold. roffA, coffA, ndim, ndum, shape(matA) = "//getStr([1_IK - lbound(matA, kind = IK), ndim, ndum, shape(matA, IK)]))
      97             : #elif   OTP_ENABLED
      98      160745 :         CHECK_ASSERTION(__LINE__, all([ndum, ndim] <= shape(matA, IK)), SK_"@setMatUpdate(): The condition `all([roffA + ndum, coffA + ndim] <= shape(matA))` must hold. roffA, coffA, ndim, ndum, shape(matA) = "//getStr([1_IK - lbound(matA, kind = IK), ndim, ndum, shape(matA, IK)]))
      99             : #else
     100             : #error  "Unrecognized interface."
     101             : #endif
     102             : #else
     103             : #error  "Unrecognized interface."
     104             : #endif
     105             :         ! Set the updating components.
     106             : #if     CHM_ENABLED && CK_ENABLED
     107             : #define GET_CONJG(X) conjg(X)
     108             : #define GET_RE(X) X%re
     109             : #define GET_REAL(X)real(X, TKC)
     110             : #elif   CHM_ENABLED || (CSM_ENABLED && (ONO_ENABLED || OTP_ENABLED))
     111             : #define GET_CONJG(X) X
     112             : #define GET_REAL(X)X
     113             : #define GET_RE(X) X
     114             : #else
     115             : #error  "Unrecognized interface."
     116             : #endif
     117             :         ! Set loop bounds.
     118             : #if     SLD_ENABLED
     119             : #define POFFSET + 1
     120             : #define GET_SLICE(i,j,k) j, k
     121             : #define SLD_SET(X,Y) X = Y
     122             : #define SUD_SET(X,Y)
     123             : #elif   SUD_ENABLED
     124             : #define POFFSET - 1
     125             : #define SLD_SET(X,Y)
     126             : #define SUD_SET(X,Y) X = Y
     127             : #define GET_SLICE(i,j,k) i, j
     128             : #else
     129             : #error  "Unrecognized interface."
     130             : #endif
     131             : #if     BLAS_ENABLED && DISPATCH_ENABLED
     132             :         call blasXXRK(BLAS_UPLO, BLAS_TRANS, ndim, ndum, GET_RE(ALPHA), matA(1,1), size(matA, 1, IK), GET_RE(BETA), mat(1,1), size(mat, 1, IK))
     133             : #else
     134             :         ! Quick return if possible.
     135       24737 :         if (ndim == 0_IK .or. ((GET_RE(ALPHA) == GET_RE(ZERO) .or. ndum == 0_IK) .and. GET_RE(BETA) == GET_RE(ONE))) return
     136       24120 :         if (GET_RE(ALPHA) == GET_RE(ZERO)) then
     137           0 :             if (GET_RE(BETA) == GET_RE(ZERO)) then
     138           0 :                 do icol = 1, ndim
     139           0 :                     do irow = GET_SLICE(1, icol, ndim)
     140           0 :                         mat(irow, icol) = ZERO
     141             :                     end do
     142             :                 end do
     143             :             else
     144           0 :                 do icol = 1, ndim
     145           0 :                     SLD_SET(mat(icol, icol), GET_RE(BETA) * GET_RE(mat(icol, icol)))
     146           0 :                     do irow = GET_SLICE(1, icol POFFSET, ndim)
     147           0 :                         mat(irow, icol) = GET_RE(BETA) * mat(irow, icol)
     148             :                     end do
     149           0 :                     SUD_SET(mat(icol, icol), GET_RE(BETA) * GET_RE(mat(icol, icol)))
     150             :                 end do
     151             :             end if
     152           0 :             return
     153             :         end if
     154             :         ! Perform Update.
     155             : #if     ONO_ENABLED
     156             :         ! Form  mat := GET_RE(ALPHA) * matA * matA ** T + GET_RE(BETA) * mat.
     157             :         ! Form  mat := GET_RE(ALPHA) * matA * matA ** H + GET_RE(BETA) * mat.
     158       32287 :         do icol = 1, ndim
     159       20225 :             if (GET_RE(BETA) == GET_RE(ZERO)) then
     160           0 :                 do irow = GET_SLICE(1, icol, ndim)
     161           0 :                     mat(irow, icol) = ZERO
     162             :                 end do
     163       20225 :             else if (GET_RE(BETA) /= GET_RE(ONE)) then
     164           0 :                 SLD_SET(mat(icol, icol), GET_RE(BETA) * GET_RE(mat(icol, icol)))
     165          12 :                 do irow = GET_SLICE(1, icol POFFSET, ndim)
     166          12 :                     mat(irow, icol) = GET_RE(BETA) * mat(irow, icol)
     167             :                 end do
     168           6 :                 SUD_SET(mat(icol, icol), GET_RE(BETA) * GET_RE(mat(icol, icol)))
     169             : #if         CHM_ENABLED && CK_ENABLED
     170             :             else
     171        9728 :                 mat(icol, icol)%im = ZERO%im
     172             : #endif
     173             :             end if
     174       65064 :             do idum = 1, ndum
     175       53002 :                 if (matA(icol, idum) /= ZERO) then
     176          88 :                     temp = GET_RE(ALPHA) * GET_CONJG(matA(icol, idum))
     177       19467 :                     SLD_SET(mat(icol, icol), GET_RE(mat(icol, icol)) + GET_REAL(temp * matA(icol, idum)))
     178       33672 :                     do irow = GET_SLICE(1, icol POFFSET, ndim)
     179       33672 :                         mat(irow, icol) = mat(irow, icol) + temp * matA(irow, idum)
     180             :                     end do
     181          88 :                     SUD_SET(mat(icol, icol), GET_RE(mat(icol, icol)) + GET_REAL(temp * matA(icol, idum)))
     182             :                 end if
     183             :             end do
     184             :         end do
     185             : #elif   OTP_ENABLED && CSM_ENABLED
     186             :         ! Form mat := GET_RE(ALPHA) * matA ** T * matA + GET_RE(BETA) * mat.
     187             :         ! This block is indeed the same as the block for HA_ENABLED.
     188             :         ! However, it is kept separately for now for its cleaner implementation.
     189          18 :         do icol = 1, ndim
     190          90 :             do irow = GET_SLICE(1, icol, ndim)
     191           0 :                 temp = ZERO
     192         288 :                 do idum = 1, ndum
     193         288 :                     temp = temp + matA(idum, irow) * matA(idum, icol)
     194             :                 end do
     195          88 :                 if (GET_RE(BETA) == ZERO) then
     196           0 :                     mat(irow, icol) = GET_RE(ALPHA) * temp
     197             :                 else
     198          72 :                     mat(irow, icol) = GET_RE(ALPHA) * temp + GET_RE(BETA) * mat(irow, icol)
     199             :                 end if
     200             :             end do
     201             :         end do
     202             : #elif   OTP_ENABLED && CHM_ENABLED
     203             :         ! Form mat := GET_RE(ALPHA) * matA ** H * matA + GET_RE(BETA) * mat.
     204             : #define SET_DIAGONAL \
     205             : GET_RE(temp) = GET_RE(ZERO); \
     206             : do idum = 1, ndum; \
     207             :     GET_RE(temp) = GET_RE(temp) + GET_REAL(GET_CONJG(matA(idum, icol)) * matA(idum, icol)); \
     208             : end do; \
     209             : if (GET_RE(BETA) == GET_RE(ZERO)) then; \
     210             :     mat(icol, icol) = GET_RE(ALPHA) * GET_RE(temp); \
     211             : else; \
     212             :     mat(icol, icol) = GET_RE(ALPHA) * GET_RE(temp) + GET_RE(BETA) * GET_RE(mat(icol, icol)); \
     213             : end if;
     214             : #define SET_OFFDIAG \
     215             : do irow = GET_SLICE(1, icol POFFSET, ndim); \
     216             :     temp = ZERO; \
     217             :     do idum = 1, ndum; \
     218             :         temp = temp + GET_CONJG(matA(idum, irow)) * matA(idum, icol); \
     219             :     end do; \
     220             :     if (GET_RE(BETA) == GET_RE(ZERO)) then; \
     221             :         mat(irow, icol) = GET_RE(ALPHA) * temp; \
     222             :     else; \
     223             :         mat(irow, icol) = GET_RE(ALPHA) * temp + GET_RE(BETA) * mat(irow, icol); \
     224             :     end if; \
     225             : end do;
     226       32252 :         do icol = 1, ndim
     227             : #if         SLD_ENABLED
     228          36 :             SET_DIAGONAL
     229          44 :             SET_OFFDIAG
     230             : #elif       SUD_ENABLED
     231       55389 :             SET_OFFDIAG
     232       64899 :             SET_DIAGONAL
     233             : #endif
     234             :         end do
     235             : #else
     236             : #error  "Unrecognized interface."
     237             : #endif
     238             : #endif
     239             : 
     240             :         !%%%%%%%%%%%%%%%%%%%%%
     241             : #elif   setMatUpdateR1_ENABLED
     242             :         !%%%%%%%%%%%%%%%%%%%%%
     243             : 
     244             :         integer(IK) :: i, j, jy, ix, kx, effLenX, srow, erow
     245             :         TYPE_KIND :: temp
     246             :         ! Define transpose type for complex arguments.
     247             : #if     setMatUpdateR1H_CK_ENABLED || setMatUpdateR1AH_CK_ENABLED
     248             : #define GET_CONJG(X) conjg(X)
     249             : #else
     250             : #define GET_CONJG(X) X
     251             : #endif
     252             :         ! Define the `alpha` factor of the transformation.
     253             : #if     Fixed_ENABLED
     254             : #define ALPHA_TIMES
     255             : #elif   Alpha_ENABLED
     256             : #define ALPHA_TIMES alpha *
     257           1 :         if (alpha == ZERO) return ! Quick return if possible.
     258             : #else
     259             : #error  "Unrecognized interface."
     260             : #endif
     261             :         kx = 1_IK
     262           6 :         if (incA /= 1_IK) then
     263           1 :             CHECK_ASSERTION(__LINE__, incA /= 0_IK, SK_"@setMatUpdateR1(): The condition `incA /= 0_IK` must hold. incA = "//getStr(incA)) ! fpp
     264           1 :             effLenX = (size(vecA, 1, IK) - 1_IK) / abs(incA) + 1_IK ! the effective length of `vecA`.
     265           3 :             CHECK_ASSERTION(__LINE__, incA * effLenX /= size(vecA, 1, IK), \
     266             :             SK_"@setMatUpdateR1(): The condition `size(vecA) == incA * ((size(vecA, 1) - 1) / abs(incA) + 1)` must hold. incA, size(vecA) = "//\
     267             :             getStr([incA, size(vecA, 1, IK)])) ! fpp
     268           1 :             if (incA < 0_IK) kx = size(vecA, 1, IK)
     269             :         else
     270           5 :             effLenX = size(vecA, 1, IK)
     271             :         end if
     272             : 
     273             :         jy = 1_IK
     274           6 :         if (incB /= 1_IK) then
     275           3 :             CHECK_ASSERTION(__LINE__, incB /= 0_IK, SK_"@setMatUpdateR1(): The condition `incB /= 0_IK` must hold. incB = "//getStr(incB)) ! fpp
     276           3 :             if (incB < 0_IK) jy = size(vecB, 1, IK)
     277             :         end if
     278             : 
     279           6 :         CHECK_ASSERTION(__LINE__, 0_IK <= roff, SK_"@setMatUpdateR1(): The conditions `0_IK <= roff` must hold. roff = "//getStr(roff)) ! fpp
     280             : 
     281          18 :         CHECK_ASSERTION(__LINE__, size(mat, 2, IK) == (size(vecB, 1, IK) - 1_IK) / abs(incB) + 1_IK, \
     282             :         SK_"@setMatUpdateR1(): The condition `size(mat, 2) == (size(vecB) - 1) / abs(incB) + 1` must hold. size(mat, 2), (size(vecB) - 1) / abs(incB) + 1 = "//\
     283             :         getStr([size(mat, 2, IK), (size(vecB, 1, IK) - 1_IK) / abs(incB) + 1_IK])) ! fpp
     284          30 :         CHECK_ASSERTION(__LINE__, size(mat, 1, IK) >= effLenX + roff, \
     285             :         SK_"@setMatUpdateR1(): The conditions `size(mat, 1) >= (size(vecA, 1) - 1) / abs(incA) + 1 + roff` must hold. size(mat, 1), size(vecA), incA, roff = "//\
     286             :         getStr([size(mat, 1, IK), size(vecA, 1, IK), incA, roff])) ! fpp
     287             : 
     288             :         !   Start the operations. In this version the elements of `mat` are accessed sequentially with one pass through `mat`.
     289             : 
     290           6 :         srow = roff + 1_IK
     291             :         erow = roff + effLenX
     292           6 :         if (incA == 1_IK) then
     293          20 :             do j = 1_IK, size(mat, 2, IK)
     294          15 :                 if (vecB(jy) /= ZERO) then
     295           3 :                     temp = ALPHA_TIMES GET_CONJG(vecB(jy))
     296          81 :                     do i = srow, erow
     297          81 :                         mat(i,j) = mat(i,j) + vecA(i) * temp
     298             :                     end do
     299             :                 end if
     300          20 :                 jy = jy + incB
     301             :             end do
     302             :         else
     303           4 :             do j = 1, size(mat, 2, IK)
     304           3 :                 if (vecB(jy) /= ZERO) then
     305           0 :                     temp = ALPHA_TIMES GET_CONJG(vecB(jy))
     306             :                     ix = kx
     307          15 :                     do i = srow, erow
     308          12 :                         mat(i,j) = mat(i,j) + vecA(ix) * temp
     309          15 :                         ix = ix + incA
     310             :                     end do
     311             :                 end if
     312           4 :                 jy = jy + incB
     313             :             end do
     314             :         end if
     315             : #undef  ALPHA_TIMES
     316             : 
     317             :         !%%%%%%%%%%%%%%%%%%%%%%%%%
     318             : #elif   setMatUpdateTriang_ENABLED
     319             :         !%%%%%%%%%%%%%%%%%%%%%%%%%
     320             : 
     321             :         integer(IK) :: irow, icol, idum
     322             :         TYPE_KIND :: temp
     323             : 
     324             :         ! Ensure roffs and subset bounds are logical.
     325          18 :         CHECK_ASSERTION(__LINE__, all(0_IK <= [ndim, ndum]), \
     326             :         SK_"@setMatUpdateTriang(): The condition `all(0_IK <= [ndim, ndum])` must hold. ndim, ndum = "//getStr([ndim, ndum])) ! fpp
     327          42 :         CHECK_ASSERTION(__LINE__, all(0_IK <= 1_IK - lbound(matA, kind = IK)), \
     328             :         SK_"@setMatUpdateTriang(): The condition `all(0 <= [roffA, coffA])` must hold. roffA, coffA = "//getStr([1_IK - lbound(matA)])) ! fpp
     329          42 :         CHECK_ASSERTION(__LINE__, all(0_IK <= 1_IK - lbound(mat, kind = IK)), \
     330             :         SK_"@setMatUpdateTriang(): The condition `all(0 <= [roff, coff])` must hold. roff, coff = "//getStr([1_IK - lbound(mat)])) ! fpp
     331             :         ! Ensure subset of `matA` does not overflow the matrix bounds.
     332             : #if     AS_ENABLED || AH_ENABLED
     333          52 :         CHECK_ASSERTION(__LINE__, all([ndim, ndum] <= shape(matA, kind = IK)), \
     334             :         SK_"@setMatUpdateTriang(): The condition `all([roffA + ndim, coffA + ndum] <= shape(matA))` must hold. roffA, coffA, ndim, ndum, shape(matA) = "\
     335             :         //getStr([1_IK - lbound(matA, kind = IK), ndim, ndum, shape(matA, IK)])) ! fpp
     336             : #elif   SA_ENABLED || HA_ENABLED
     337          26 :         CHECK_ASSERTION(__LINE__, all([ndum, ndim] <= shape(matA,IK)), \
     338             :         SK_"@setMatUpdateTriang(): The condition `all([roffA + ndum, coffA + ndim] <= shape(matA))` must hold. roffA, coffA, ndim, ndum, shape(matA) = "\
     339             :         //getStr([1_IK - lbound(matA, kind = IK), ndim, ndum, shape(matA, IK)])) ! fpp
     340             : #else
     341             : #error  "Unrecognized interface."
     342             : #endif
     343             :         ! Set the updating components.
     344             : #if     AS_ENABLED || SA_ENABLED
     345             : #define GET_CONJG(X) X
     346             : #define GET_REAL(X)X
     347             : #define GET_RE(X) X
     348             : #elif   AH_ENABLED || HA_ENABLED
     349             : #define GET_CONJG(X) conjg(X)
     350             : #define GET_RE(X) X%re
     351             : #define GET_REAL(X)real(X, TKC)
     352             : #else
     353             : #error  "Unrecognized interface."
     354             : #endif
     355             :         ! Set loop bounds.
     356             : #if     lowDiaC_ENABLED
     357             : #define POFFSET + 1
     358             : #define GET_SLICE(i,j,k) j, k
     359             : #define lowDiaC_SET(X,Y) X = Y
     360             : #define uppDiaC_SET(X,Y)
     361             : #elif   uppDiaC_ENABLED
     362             : #define POFFSET - 1
     363             : #define lowDiaC_SET(X,Y)
     364             : #define uppDiaC_SET(X,Y) X = Y
     365             : #define GET_SLICE(i,j,k) i, j
     366             : #else
     367             : #error  "Unrecognized interface."
     368             : #endif
     369             :         ! Quick return if possible.
     370           6 :         if (ndim == 0_IK .or. ((alpha == ZERO .or. ndum == 0_IK) .and. beta == ONE)) return
     371           6 :         if (alpha == GET_RE(ZERO)) then
     372           0 :             if (beta == GET_RE(ZERO)) then
     373           0 :                 do icol = 1, ndim
     374           0 :                     do irow = GET_SLICE(1, icol, ndim)
     375           0 :                         mat(irow, icol) = ZERO
     376             :                     end do
     377             :                 end do
     378             :             else
     379           0 :                 do icol = 1, ndim
     380           0 :                     lowDiaC_SET(mat(icol, icol), beta * GET_RE(mat(icol, icol)))
     381           0 :                     do irow = GET_SLICE(1, icol POFFSET, ndim)
     382           0 :                         mat(irow, icol) = beta * mat(irow, icol)
     383             :                     end do
     384           0 :                     uppDiaC_SET(mat(icol, icol), beta * GET_RE(mat(icol, icol)))
     385             :                 end do
     386             :             end if
     387           0 :             return
     388             :         end if
     389             :         ! Perform Update.
     390             : #if     AS_ENABLED || AH_ENABLED
     391             :         ! Form  mat := alpha * matA * matA ** T + beta * mat.
     392             :         ! Form  mat := alpha * matA * matA ** H + beta * mat.
     393          21 :         do icol = 1, ndim
     394          17 :             if (beta == GET_RE(ZERO)) then
     395           0 :                 do irow = GET_SLICE(1, icol, ndim)
     396           0 :                     mat(irow, icol) = ZERO
     397             :                 end do
     398          17 :             else if (beta /= GET_RE(ONE)) then
     399           0 :                 lowDiaC_SET(mat(icol, icol), beta * GET_RE(mat(icol, icol)))
     400           6 :                 do irow = GET_SLICE(1, icol POFFSET, ndim)
     401           6 :                     mat(irow, icol) = beta * mat(irow, icol)
     402             :                 end do
     403           3 :                 uppDiaC_SET(mat(icol, icol), beta * GET_RE(mat(icol, icol)))
     404             : #if         AH_ENABLED
     405             :             else
     406           6 :                 mat(icol, icol)%im = ZERO%im
     407             : #endif
     408             :             end if
     409          82 :             do idum = 1, ndum
     410          78 :                 if (matA(icol, idum) /= ZERO) then
     411          44 :                     temp = alpha * GET_CONJG(matA(icol, idum))
     412          15 :                     lowDiaC_SET(mat(icol, icol), GET_RE(mat(icol, icol)) + GET_REAL(temp * matA(icol, idum)))
     413         160 :                     do irow = GET_SLICE(1, icol POFFSET, ndim)
     414         160 :                         mat(irow, icol) = mat(irow, icol) + temp * matA(irow, idum)
     415             :                     end do
     416          44 :                     uppDiaC_SET(mat(icol, icol), GET_RE(mat(icol, icol)) + GET_REAL(temp * matA(icol, idum)))
     417             :                 end if
     418             :             end do
     419             :         end do
     420             : #elif   SA_ENABLED
     421             :         ! Form mat := alpha * matA ** T * matA + beta * mat.
     422             :         ! This block is indeed the same as the block for HA_ENABLED.
     423             :         ! However, it is kept separately for now for its cleaner implementation.
     424           9 :         do icol = 1, ndim
     425          45 :             do irow = GET_SLICE(1, icol, ndim)
     426           0 :                 temp = ZERO
     427         144 :                 do idum = 1, ndum
     428         144 :                     temp = temp + matA(idum, irow) * matA(idum, icol)
     429             :                 end do
     430          44 :                 if (beta == ZERO) then
     431           0 :                     mat(irow, icol) = alpha * temp
     432             :                 else
     433          36 :                     mat(irow, icol) = alpha * temp + beta * mat(irow, icol)
     434             :                 end if
     435             :             end do
     436             :         end do
     437             : #elif   HA_ENABLED
     438             :         ! Form mat := alpha * matA ** H * matA + beta * mat.
     439             : #define SET_DIAGONAL \
     440             : GET_RE(temp) = GET_RE(ZERO); \
     441             : do idum = 1, ndum; \
     442             :     GET_RE(temp) = GET_RE(temp) + GET_REAL(GET_CONJG(matA(idum, icol)) * matA(idum, icol)); \
     443             : end do; \
     444             : if (beta == GET_RE(ZERO)) then; \
     445             :     mat(icol, icol) = alpha * GET_RE(temp); \
     446             : else; \
     447             :     mat(icol, icol) = alpha * GET_RE(temp) + beta * GET_RE(mat(icol, icol)); \
     448             : end if;
     449             : #define SET_OFFDIAG \
     450             : do irow = GET_SLICE(1, icol POFFSET, ndim); \
     451             :     temp = ZERO; \
     452             :     do idum = 1, ndum; \
     453             :         temp = temp + GET_CONJG(matA(idum, irow)) * matA(idum, icol); \
     454             :     end do; \
     455             :     if (beta == GET_RE(ZERO)) then; \
     456             :         mat(irow, icol) = alpha * temp; \
     457             :     else; \
     458             :         mat(irow, icol) = alpha * temp + beta * mat(irow, icol); \
     459             :     end if; \
     460             : end do;
     461           4 :         do icol = 1, ndim
     462             : #if         lowDiaC_ENABLED
     463          18 :             SET_DIAGONAL
     464          22 :             SET_OFFDIAG
     465             : #elif       uppDiaC_ENABLED
     466           0 :             SET_OFFDIAG
     467           0 :             SET_DIAGONAL
     468             : #endif
     469             :         end do
     470             : #else
     471             : #error  "Unrecognized interface."
     472             : #endif
     473             : 
     474             : #else
     475             :         !%%%%%%%%%%%%%%%%%%%%%%%%
     476             : #error  "Unrecognized interface."
     477             :         !%%%%%%%%%%%%%%%%%%%%%%%%
     478             : #endif
     479             : #undef  SET_DIAGONAL
     480             : #undef  SET_OFFDIAG
     481             : #undef  lowDiaC_SET
     482             : #undef  uppDiaC_SET
     483             : #undef  BLAS_TRANS
     484             : #undef  BLAS_UPLO
     485             : #undef  TYPE_KIND
     486             : #undef  GET_CONJG
     487             : #undef  GET_SLICE
     488             : #undef  blasXXRK
     489             : #undef  GET_REAL
     490             : #undef  SLD_SET
     491             : #undef  SUD_SET
     492             : #undef  POFFSET
     493             : #undef  GET_RE
     494             : #undef  ALPHA
     495             : #undef  BETA

ParaMonte: Parallel Monte Carlo and Machine Learning Library 
The Computational Data Science Lab
© Copyright 2012 - 2024