subroutine nsfc(N,R,Ic,Ia,Ja,Jlmax,Il,Jl,Ijl,Jumax,Iu,Ju,Iju,Q,Ira,Jra,Irac,Irl,Jrl,Iru,Jru,Flag)
!
integer,intent(in) :: N
integer,intent(inout) :: R(*)
integer,intent(in) :: Ic(*)
integer,intent(in) :: Ia(*)
integer,intent(in) :: Ja(*)
integer,intent(in) :: Jlmax
integer,intent(inout) :: Il(*)
integer,intent(inout) :: Jl(*)
integer,intent(inout) :: Ijl(*)
integer,intent(in) :: Jumax
integer,intent(inout) :: Iu(*)
integer,intent(inout) :: Ju(*)
integer,intent(inout) :: Iju(*)
integer,intent(inout) :: Q(*)
integer,intent(inout) :: Ira(*)
integer,intent(inout) :: Jra(*)
integer,intent(inout) :: Irac(*)
integer,intent(inout) :: Irl(*)
integer,intent(inout) :: Jrl(*)
integer,intent(inout) :: Iru(*)
integer,intent(inout) :: Jru(*)
integer,intent(out) :: Flag
!
integer :: cend, i, i1, iak, irai, irll, irul, j, jaiak, jairai, jlmin, jlptr, jmax, jmin, jtmp, jumin, juptr, k, &
& lasti, lastid, long, luk, m, np1, qm, rend, rk, vj
!
! ****** initialize pointers ****************************************
np1 = N + 1
jlmin = 1
jlptr = 0
Il(1) = 1
jumin = 1
juptr = 0
Iu(1) = 1
do k = 1, N
Irac(k) = 0
Jra(k) = 0
Jrl(k) = 0
Jru(k) = 0
enddo
! ****** initialize column pointers for a ***************************
do k = 1, N
rk = R(k)
iak = Ia(rk)
if ( iak>=Ia(rk+1) ) then
!
! ** error.. null row in a
Flag = N + rk
return
else
jaiak = Ic(Ja(iak))
if ( jaiak>k ) then
! ** error.. null pivot
Flag = 5*N + k
return
endif
Jra(k) = Irac(jaiak)
Irac(jaiak) = k
Ira(k) = iak
endif
enddo
!
! ****** for each column of l and row of u **************************
ALL: do k = 1, N
!
! ****** initialize q for computing kth column of l *****************
Q(np1) = np1
luk = -1
! ****** by filling in kth column of a ******************************
vj = Irac(k)
if ( vj/=0 ) then
qm = np1
do
m = qm
qm = Q(m)
if ( qm>=vj ) then
if ( qm==vj )then
! ** error.. duplicate entry in a
Flag = 2*N + rk
return
endif
luk = luk + 1
Q(m) = vj
Q(vj) = qm
vj = Jra(vj)
if ( vj==0 ) exit
qm = np1
endif
enddo
endif
! ****** link through jru *******************************************
lastid = 0
lasti = 0
Ijl(k) = jlptr
i = k
LOOP: do
i = Jru(i)
if ( i==0 ) then
! ****** lasti is the longest column merged into the kth ************
! ****** see if it equals the entire kth column *********************
qm = Q(np1)
if ( qm/=k ) then
! ** error.. null pivot
Flag = 5*N + k
return
endif
LUKZ: if ( luk/=0 ) then
if ( lastid/=luk ) then
! ****** if not, see if kth column can overlap the previous one *****
KTHCOL: if ( jlmin<=jlptr ) then
qm = Q(qm)
do j = jlmin, jlptr
if ( Jl(j)<qm ) cycle
if ( Jl(j)==qm ) then
Ijl(k) = j
do i = j, jlptr
if ( Jl(i)/=qm ) exit KTHCOL
qm = Q(qm)
if ( qm>N ) exit LUKZ
enddo
jlptr = j - 1
endif
exit
enddo
endif KTHCOL
! ****** move column indices from q to jl, update vectors ***********
jlmin = jlptr + 1
Ijl(k) = jlmin
if ( luk/=0 ) then
jlptr = jlptr + luk
if ( jlptr>Jlmax ) then
! ** error.. insufficient storage for jl
Flag = 3*N + k
return
else
qm = Q(np1)
do j = jlmin, jlptr
qm = Q(qm)
Jl(j) = qm
enddo
endif
endif
else
! ****** if so, jl can be compressed ********************************
irll = Irl(lasti)
Ijl(k) = irll + 1
if ( Jl(irll)/=k ) Ijl(k) = Ijl(k) - 1
endif
endif LUKZ
Irl(k) = Ijl(k)
Il(k+1) = Il(k) + luk
!
! ****** initialize q for computing kth row of u ********************
Q(np1) = np1
luk = -1
! ****** by filling in kth row of reordered a ***********************
rk = R(k)
jmin = Ira(k)
jmax = Ia(rk+1) - 1
if ( jmin<=jmax ) then
do j = jmin, jmax
vj = Ic(Ja(j))
qm = np1
do
m = qm
qm = Q(m)
if ( qm>=vj ) then
if ( qm==vj )then
! ** error.. duplicate entry in a
Flag = 2*N + rk
return
endif
luk = luk + 1
Q(m) = vj
Q(vj) = qm
exit
endif
enddo
enddo
endif
! ****** link through jrl, ******************************************
lastid = 0
lasti = 0
Iju(k) = juptr
i = k
i1 = Jrl(k)
do
i = i1
if ( i==0 ) then
! ****** update jrl(k) and irl(k) ***********************************
if ( Il(k+1)>Il(k) ) then
j = Jl(Irl(k))
Jrl(k) = Jrl(j)
Jrl(j) = k
endif
! ****** lasti is the longest row merged into the kth ***************
! ****** see if it equals the entire kth row ************************
qm = Q(np1)
if ( qm/=k )then
! ** error.. null pivot
Flag = 5*N + k
return
endif
LUKY: if ( luk/=0 ) then
if ( lastid/=luk ) then
! ****** if not, see if kth row can overlap the previous one ********
KTHROW: if ( jumin<=juptr ) then
qm = Q(qm)
do j = jumin, juptr
if ( Ju(j)<qm ) cycle
if ( Ju(j)==qm ) then
Iju(k) = j
do i = j, juptr
if ( Ju(i)/=qm ) exit KTHROW
qm = Q(qm)
if ( qm>N ) exit LUKY
enddo
juptr = j - 1
endif
exit
enddo
endif KTHROW
! ****** move row indices from q to ju, update vectors **************
jumin = juptr + 1
Iju(k) = jumin
if ( luk/=0 ) then
juptr = juptr + luk
if ( juptr>Jumax ) then
! ** error.. insufficient storage for ju
Flag = 6*N + k
return
else
qm = Q(np1)
do j = jumin, juptr
qm = Q(qm)
Ju(j) = qm
enddo
endif
endif
else
! ****** if so, ju can be compressed ********************************
irul = Iru(lasti)
Iju(k) = irul + 1
if ( Ju(irul)/=k ) Iju(k) = Iju(k) - 1
endif
endif LUKY
Iru(k) = Iju(k)
Iu(k+1) = Iu(k) + luk
!
! ****** update iru, jru ********************************************
i = k
exit LOOP
else
i1 = Jrl(i)
qm = np1
jmin = Iru(i)
jmax = Iju(i) + Iu(i+1) - Iu(i) - 1
long = jmax - jmin
if ( long>=0 ) then
jtmp = Ju(jmin)
if ( jtmp/=k ) then
! ****** update irl and jrl, *****************************************
long = long + 1
cend = Ijl(i) + Il(i+1) - Il(i)
Irl(i) = Irl(i) + 1
if ( Irl(i)<cend ) then
j = Jl(Irl(i))
Jrl(i) = Jrl(j)
Jrl(j) = i
endif
endif
if ( lastid<long ) then
lasti = i
lastid = long
endif
! ****** and merge the corresponding rows into the kth row **********
do j = jmin, jmax
vj = Ju(j)
do
m = qm
qm = Q(m)
if ( qm>=vj ) then
if ( qm/=vj ) then
luk = luk + 1
Q(m) = vj
Q(vj) = qm
qm = vj
endif
exit
endif
enddo
enddo
endif
endif
enddo
else
qm = np1
jmin = Irl(i)
jmax = Ijl(i) + Il(i+1) - Il(i) - 1
long = jmax - jmin
if ( long>=0 ) then
jtmp = Jl(jmin)
if ( jtmp/=k ) long = long + 1
if ( jtmp==k ) R(i) = -R(i)
if ( lastid<long ) then
lasti = i
lastid = long
endif
! ****** and merge the corresponding columns into the kth column ****
do j = jmin, jmax
vj = Jl(j)
do
m = qm
qm = Q(m)
if ( qm>=vj ) then
if ( qm/=vj ) then
luk = luk + 1
Q(m) = vj
Q(vj) = qm
qm = vj
endif
exit
endif
enddo
enddo
endif
endif
enddo LOOP
BACK: do
i1 = Jru(i)
if ( R(i)<0 ) then
R(i) = -R(i)
else
rend = Iju(i) + Iu(i+1) - Iu(i)
if ( Iru(i)<rend ) then
j = Ju(Iru(i))
Jru(i) = Jru(j)
Jru(j) = i
endif
endif
i = i1
if ( i==0 ) then
!
! ****** update ira, jra, irac **************************************
i = Irac(k)
if ( i==0 ) cycle ALL
else
Iru(i) = Iru(i) + 1
cycle BACK
endif
exit BACK
enddo BACK
INFINITE: do
i1 = Jra(i)
Ira(i) = Ira(i) + 1
if ( Ira(i)<Ia(R(i)+1) ) then
irai = Ira(i)
jairai = Ic(Ja(irai))
if ( jairai<=i ) then
Jra(i) = Irac(jairai)
Irac(jairai) = i
endif
endif
i = i1
if ( i==0 ) exit INFINITE
enddo INFINITE
enddo ALL
!
Ijl(N) = jlptr
Iju(N) = juptr
Flag = 0
end subroutine nsfc