File: wgedi.f

package info (click to toggle)
scilab 4.0-12
  • links: PTS
  • area: non-free
  • in suites: etch, etch-m68k
  • size: 100,640 kB
  • ctags: 57,333
  • sloc: ansic: 377,889; fortran: 242,862; xml: 179,819; tcl: 42,062; sh: 10,593; ml: 9,441; makefile: 4,377; cpp: 1,354; java: 621; csh: 260; yacc: 247; perl: 130; lex: 126; asm: 72; lisp: 30
file content (156 lines) | stat: -rw-r--r-- 4,605 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
      subroutine wgedi(ar,ai,lda,n,ipvt,detr,deti,workr,worki,job)
c     Copyright INRIA
      integer lda,n,ipvt(*),job
      double precision ar(lda,*),ai(lda,*),detr(2),deti(2),workr(*),
     *                 worki(*)
c!purpose
c
c     wgedi computes the determinant and inverse of a matrix
c     using the factors computed by wgeco or wgefa.
c
c!calling sequence
c
c      subroutine wgedi(ar,ai,lda,n,ipvt,detr,deti,workr,worki,job)
c     on entry
c
c        a       double-complex(lda, n)
c                the output from wgeco or wgefa.
c
c        lda     integer
c                the leading dimension of the array  a .
c
c        n       integer
c                the order of the matrix  a .
c
c        ipvt    integer(n)
c                the pivot vector from wgeco or wgefa.
c
c        work    double-complex(n)
c                work vector.  contents destroyed.
c
c        job     integer
c                = 11   both determinant and inverse.
c                = 01   inverse only.
c                = 10   determinant only.
c
c     on return
c
c        a       inverse of original matrix if requested.
c                otherwise unchanged.
c
c        det     double-complex(2)
c                determinant of original matrix if requested.
c                otherwise not referenced.
c                determinant = det(1) * 10.0**det(2)
c                with  1.0 .le. cabs1(det(1) .lt. 10.0
c                or  det(1) .eq. 0.0 .
c
c     error condition
c
c        a division by zero will occur if the input factor contains
c        a zero on the diagonal and the inverse is requested.
c        it will not occur if the subroutines are called correctly
c        and if wgeco has set rcond .gt. 0.0 or wgefa has set
c        info .eq. 0 .
c
c!originator
c     linpack. this version dated 07/01/79 .
c     cleve moler, university of new mexico, argonne national lab.
c
c!auxiliary routines
c
c     blas waxpy,wscal,wswap
c     fortran abs,mod
c
c!
c     internal variables
c
      double precision tr,ti
      double precision ten
      integer i,j,k,kb,kp1,l,nm1
c
      double precision zdumr,zdumi
      double precision cabs1
      cabs1(zdumr,zdumi) = abs(zdumr) + abs(zdumi)
c
c     compute determinant
c
      if (job/10 .eq. 0) go to 80
         detr(1) = 1.0d+0
         deti(1) = 0.0d+0
         detr(2) = 0.0d+0
         deti(2) = 0.0d+0
         ten = 10.0d+0
         do 60 i = 1, n
            if (ipvt(i) .eq. i) go to 10
               detr(1) = -detr(1)
               deti(1) = -deti(1)
   10       continue
            call wmul(ar(i,i),ai(i,i),detr(1),deti(1),detr(1),deti(1))
c           ...exit
c        ...exit
            if (cabs1(detr(1),deti(1)) .eq. 0.0d+0) go to 70
   20       if (cabs1(detr(1),deti(1)) .ge. 1.0d+0) go to 30
               detr(1) = ten*detr(1)
               deti(1) = ten*deti(1)
               detr(2) = detr(2) - 1.0d+0
               deti(2) = deti(2) - 0.0d+0
            go to 20
   30       continue
   40       if (cabs1(detr(1),deti(1)) .lt. ten) go to 50
               detr(1) = detr(1)/ten
               deti(1) = deti(1)/ten
               detr(2) = detr(2) + 1.0d+0
               deti(2) = deti(2) + 0.0d+0
            go to 40
   50       continue
   60    continue
   70    continue
   80 continue
c
c     compute inverse(u)
c
      if (mod(job,10) .eq. 0) go to 160
         do 110 k = 1, n
            call wdiv(1.0d+0,0.0d+0,ar(k,k),ai(k,k),ar(k,k),ai(k,k))
            tr = -ar(k,k)
            ti = -ai(k,k)
            call wscal(k-1,tr,ti,ar(1,k),ai(1,k),1)
            kp1 = k + 1
            if (n .lt. kp1) go to 100
            do 90 j = kp1, n
               tr = ar(k,j)
               ti = ai(k,j)
               ar(k,j) = 0.0d+0
               ai(k,j) = 0.0d+0
               call waxpy(k,tr,ti,ar(1,k),ai(1,k),1,ar(1,j),ai(1,j),1)
   90       continue
  100       continue
  110    continue
c
c        form inverse(u)*inverse(l)
c
         nm1 = n - 1
         if (nm1 .lt. 1) go to 150
         do 140 kb = 1, nm1
            k = n - kb
            kp1 = k + 1
            do 120 i = kp1, n
               workr(i) = ar(i,k)
               worki(i) = ai(i,k)
               ar(i,k) = 0.0d+0
               ai(i,k) = 0.0d+0
  120       continue
            do 130 j = kp1, n
               tr = workr(j)
               ti = worki(j)
               call waxpy(n,tr,ti,ar(1,j),ai(1,j),1,ar(1,k),ai(1,k),1)
  130       continue
            l = ipvt(k)
            if (l .ne. k)
     *         call wswap(n,ar(1,k),ai(1,k),1,ar(1,l),ai(1,l),1)
  140    continue
  150    continue
  160 continue
      return
      end