NLSL
scmvm.f90
Go to the documentation of this file.
1 c NLSL Version 1.3.2
2 c**********************************************************************
3 c
4 c (S)parse (C)omplex (M)atrix (V)ector (M)ultiply
5 c ===============================================
6 c
7 c This subroutine will do a sparse matrix-vector multiplication
8 c of the form y=Z*x where Z is sparse and complex.
9 c
10 c NB: This routine utilizes the new matrix storage convention
11 c implemented by DJS in which only the upper half of the
12 c matrix is stored. It should be used only with versions
13 c of the MATRLL routine that store the matrix according to
14 c this convention (described below).
15 c
16 c The diagonal elements of Z are stored in the complex
17 c array zdiag in common /eprmat/. The upper diagonal of the
18 c real and imaginary parts of Z are stored separately by row
19 c in the zmat array (also in common /eprmat/), skipping
20 c zero elements. Imaginary elements are packed starting
21 c at the beginning of zmat, and real elements starting
22 c at the upper limit of zmat.
23 c The companion arrays jzmat and kzmat respectively
24 c give the the location of the first imaginary and real
25 c elements of each row of Z within zmat, and izmat gives
26 c the column index corresponding to each element in zmat.
27 c
28 c The matrix-vector multiply will not be performed if the
29 c user-halt flags defined in stdio.inc have been set
30 c
31 c Calling parameters:
32 c ------------------
33 c
34 c vectors :
35 c
36 c in /eprmat/
37 c
38 c zdiag : diagonal elements of Z
39 c zmat : real and imaginary elements of Z upper diagonal
40 c jzmat(i) : index of 1st imaginary element of row i in zmat
41 c kzmat(i) : index of 1st real element of row i in zmat
42 c izmat(i) : Z column index of ith element of zmat
43 c
44 c arguments:
45 c
46 c x : input vector for matrix-vector multiplication
47 c y : resultant vector
48 c
49 c scalars :
50 c
51 c ndim : number of rows in matrix
52 c
53 c Local Variables:
54 c ---------------
55 c
56 c accr : real part of dot product of a row of the
57 c matrix with the input vector
58 c acci : imaginary part of dot product of a row of the
59 c matrix with the input vector
60 c
61 c Notes:
62 c -----
63 c The routine does not use complex double precision
64 c arithmetic explicitly for two reasons. First is
65 c that, unfortunately, not all F77 compilers support
66 c complex double precision arithmetic. Second, most of
67 c floating point operations involve the multiplication
68 c of a purely real or purely imaginary number by a
69 c complex number. This is more efficiently done by
70 c treating the complex number an ordered pair or real
71 c numbers, since there is no unnecessary multiplications
72 c by zero performed.
73 c
74 c
75 c Includes:
76 c nlsdim.inc
77 c rndoff.inc
78 c eprmat.inc
79 c
80 c Uses:
81 c
82 c written by DJS 3-OCT-86
83 c
84 c**********************************************************************
85 c
86  subroutine scmvm(x,y,ndim)
87 c
88  use nlsdim
89  use rnddbl
90  use eprmat
91 c
92  integer ndim
93  double precision x,y
94  dimension x(2,mxdim),y(2,mxdim)
95 c
96  integer j,k,m,n,n1
97  double precision accr,acci
98 c
99 c######################################################################
100 c
101 c----------------------------------------------------------------------
102 c do diagonal elements first
103 c----------------------------------------------------------------------
104 c
105  do n=1,ndim
106  y(1,n)=zdiag(1,n)*x(1,n)-zdiag(2,n)*x(2,n)
107  y(2,n)=zdiag(1,n)*x(2,n)+zdiag(2,n)*x(1,n)
108  end do
109 c
110 c----------------------------------------------------------------------
111 c loop over rows (columns) of matrix for off-diagonal elements
112 c----------------------------------------------------------------------
113 c
114  do n=1,ndim
115  n1=n+1
116 c
117  accr=0.0d0
118  acci=0.0d0
119 c
120 c imaginary matrix elements
121 c
122  if (jzmat(n) .ne. jzmat(n1) ) then
123  do j=jzmat(n),jzmat(n1)-1
124  m=izmat(j)
125  acci=acci+zmat(j)*x(1,m)
126  y(2,m)=y(2,m)+zmat(j)*x(1,n)
127  accr=accr-zmat(j)*x(2,m)
128  y(1,m)=y(1,m)-zmat(j)*x(2,n)
129  end do
130  endif
131 c
132 c real matrix elements
133 c
134  if (kzmat(n) .ne. kzmat(n1)) then
135  do k=kzmat(n),kzmat(n1)-1
136  j = mxel-k+1
137  m=izmat(j)
138  accr=accr+zmat(j)*x(1,m)
139  y(1,m)=y(1,m)+zmat(j)*x(1,n)
140  acci=acci+zmat(j)*x(2,m)
141  y(2,m)=y(2,m)+zmat(j)*x(2,n)
142  end do
143  endif
144 c
145  y(1,n)=y(1,n)+accr
146 c*djs if (abs(y(1,n)).lt.rndoff) y(1,n)=0.0D0
147  y(2,n)=y(2,n)+acci
148 c*djs if (abs(y(2,n)).lt.rndoff) y(2,n)=0.0D0
149 c
150  end do
151 c
152  return
153  end
integer, dimension(mxdim+1), save jzmat
Definition: eprmat.f90:50
integer, dimension(mxdim+1), save kzmat
Definition: eprmat.f90:50
integer, dimension(mxel), save izmat
Definition: eprmat.f90:50
double precision, dimension(mxel), save zmat
Definition: eprmat.f90:49
integer, parameter mxel
Definition: nlsdim.f90:39
subroutine scmvm(x, y, ndim)
Definition: scmvm.f90:87
integer, parameter mxdim
Definition: nlsdim.f90:39
double precision, dimension(2, mxdim), save zdiag
Definition: eprmat.f90:49