📄 tnmex4.f90
字号:
End If
End If
JLM2 = JLM1
JLM1 = JLOW
JHM2 = JHM1
JHM1 = JHIG
!
! We try to bring the number of values in the low values set
! closer to NORD. In order to make better pivot choices, we
! decrease NORD if we already know that we don't have that
! many distinct values as a whole.
!
IF (JLOW+JHIG < NORD) NORD = JLOW+JHIG
Select Case (NORD-JLOW)
! ______________________________
Case (2:)
!
! Not enough values in low part, at least 2 are missing
!
Select Case (JHIG)
!
! Not enough values in high part either (too many duplicates)
!
Case (0)
NORD = JLOW
!
Case (1)
JLOW = JLOW + 1
ILOWT (JLOW) = IHIGT (1)
NORD = JLOW
!
! We make a special case when we have so few values in
! the high values set that it is bad performance to choose a pivot
! and apply the general algorithm.
!
Case (2)
If (XDONT(IHIGT(1)) <= XDONT(IHIGT(2))) Then
JLOW = JLOW + 1
ILOWT (JLOW) = IHIGT (1)
JLOW = JLOW + 1
ILOWT (JLOW) = IHIGT (2)
ElseIf (XDONT(IHIGT(1)) == XDONT(IHIGT(2))) Then
JLOW = JLOW + 1
ILOWT (JLOW) = IHIGT (1)
NORD = JLOW
Else
JLOW = JLOW + 1
ILOWT (JLOW) = IHIGT (2)
JLOW = JLOW + 1
ILOWT (JLOW) = IHIGT (1)
End If
Exit
!
Case (3)
!
!
IWRK1 = IHIGT (1)
IWRK2 = IHIGT (2)
IWRK3 = IHIGT (3)
If (XDONT(IWRK2) < XDONT(IWRK1)) Then
IHIGT (1) = IWRK2
IHIGT (2) = IWRK1
IWRK2 = IWRK1
End If
If (XDONT(IWRK2) > XDONT(IWRK3)) Then
IHIGT (3) = IWRK2
IHIGT (2) = IWRK3
IWRK2 = IWRK3
If (XDONT(IWRK2) < XDONT(IHIGT(1))) Then
IHIGT (2) = IHIGT (1)
IHIGT (1) = IWRK2
End If
End If
JHIG = 1
JLOW = JLOW + 1
ILOWT (JLOW) = IHIGT (1)
JHIG = JHIG + 1
IF (XDONT(IHIGT(JHIG)) /= XDONT(ILOWT(JLOW))) Then
JLOW = JLOW + 1
ILOWT (JLOW) = IHIGT (JHIG)
End If
JHIG = JHIG + 1
IF (XDONT(IHIGT(JHIG)) /= XDONT(ILOWT(JLOW))) Then
JLOW = JLOW + 1
ILOWT (JLOW) = IHIGT (JHIG)
End If
NORD = Min (JLOW, NORD)
Exit
!
Case (4:)
!
!
XPIV0 = XPIV
IFIN = JHIG
!
! One chooses a pivot from the 2 first values and the last one.
! This should ensure sufficient renewal between iterations to
! avoid worst case behavior effects.
!
IWRK1 = IHIGT (1)
IWRK2 = IHIGT (2)
IWRK3 = IHIGT (IFIN)
If (XDONT(IWRK2) < XDONT(IWRK1)) Then
IHIGT (1) = IWRK2
IHIGT (2) = IWRK1
IWRK2 = IWRK1
End If
If (XDONT(IWRK2) > XDONT(IWRK3)) Then
IHIGT (IFIN) = IWRK2
IHIGT (2) = IWRK3
IWRK2 = IWRK3
If (XDONT(IWRK2) < XDONT(IHIGT(1))) Then
IHIGT (2) = IHIGT (1)
IHIGT (1) = IWRK2
End If
End If
!
JDEB = JLOW
NWRK = NORD - JLOW
IWRK1 = IHIGT (1)
XPIV = XDONT (IWRK1) + REAL (NWRK) / REAL (NORD+NWRK) * &
(XDONT(IHIGT(IFIN))-XDONT(IWRK1))
!
! One takes values <= pivot to ILOWT
! Again, 2 parts, one where we take care of the remaining
! high values because we might still need them, and the
! other when we know that we will have more than enough
! low values in the end.
!
JHIG = 0
lowloop3: Do ICRS = 1, IFIN
If (XDONT(IHIGT(ICRS)) <= XPIV) Then
Do ILOW = 1, JLOW
If (XDONT(IHIGT(ICRS)) == XDONT (ILOWT(ILOW))) &
Cycle lowloop3
End Do
JLOW = JLOW + 1
ILOWT (JLOW) = IHIGT (ICRS)
If (JLOW > NORD) Exit
Else
JHIG = JHIG + 1
IHIGT (JHIG) = IHIGT (ICRS)
End If
End Do lowloop3
!
Do ICRS = ICRS + 1, IFIN
If (XDONT(IHIGT(ICRS)) <= XPIV) Then
JLOW = JLOW + 1
ILOWT (JLOW) = IHIGT (ICRS)
End If
End Do
End Select
!
! ______________________________
!
Case (1)
!
! Only 1 value is missing in low part
!
XMIN = XDONT (IHIGT(1))
IHIG = 1
Do ICRS = 2, JHIG
If (XDONT(IHIGT(ICRS)) < XMIN) Then
XMIN = XDONT (IHIGT(ICRS))
IHIG = ICRS
End If
End Do
!
JLOW = JLOW + 1
ILOWT (JLOW) = IHIGT (IHIG)
Exit
!
! ______________________________
!
Case (0)
!
! Low part is exactly what we want
!
Exit
!
! ______________________________
!
Case (-5:-1)
!
! Only few values too many in low part
!
IRNGT (1) = ILOWT (1)
Do ICRS = 2, NORD
IWRK = ILOWT (ICRS)
XWRK = XDONT (IWRK)
Do IDCR = ICRS - 1, 1, - 1
If (XWRK < XDONT(IRNGT(IDCR))) Then
IRNGT (IDCR+1) = IRNGT (IDCR)
Else
Exit
End If
End Do
IRNGT (IDCR+1) = IWRK
End Do
!
XWRK1 = XDONT (IRNGT(NORD))
insert1: Do ICRS = NORD + 1, JLOW
If (XDONT(ILOWT (ICRS)) < XWRK1) Then
XWRK = XDONT (ILOWT (ICRS))
Do ILOW = 1, NORD - 1
If (XWRK <= XDONT(IRNGT(ILOW))) Then
If (XWRK == XDONT(IRNGT(ILOW))) Cycle insert1
Exit
End If
End Do
Do IDCR = NORD - 1, ILOW, - 1
IRNGT (IDCR+1) = IRNGT (IDCR)
End Do
IRNGT (IDCR+1) = ILOWT (ICRS)
XWRK1 = XDONT (IRNGT(NORD))
End If
End Do insert1
!
Return
!
! ______________________________
!
Case (:-6)
!
! last case: too many values in low part
!
IDEB = JDEB + 1
IMIL = MIN ((JLOW+IDEB) / 2, NORD)
IFIN = MIN (JLOW, NORD+1)
!
! One chooses a pivot from 1st, last, and middle values
!
If (XDONT(ILOWT(IMIL)) < XDONT(ILOWT(IDEB))) Then
IWRK = ILOWT (IDEB)
ILOWT (IDEB) = ILOWT (IMIL)
ILOWT (IMIL) = IWRK
End If
If (XDONT(ILOWT(IMIL)) > XDONT(ILOWT(IFIN))) Then
IWRK = ILOWT (IFIN)
ILOWT (IFIN) = ILOWT (IMIL)
ILOWT (IMIL) = IWRK
If (XDONT(ILOWT(IMIL)) < XDONT(ILOWT(IDEB))) Then
IWRK = ILOWT (IDEB)
ILOWT (IDEB) = ILOWT (IMIL)
ILOWT (IMIL) = IWRK
End If
End If
If (IFIN <= 3) Exit
!
XPIV = XDONT (ILOWT(IDEB)) + REAL(NORD)/REAL(JLOW+NORD) * &
(XDONT(ILOWT(IFIN))-XDONT(ILOWT(1)))
If (JDEB > 0) Then
If (XPIV <= XPIV0) &
XPIV = XPIV0 + REAL(2*NORD-JDEB)/REAL (JLOW+NORD) * &
(XDONT(ILOWT(IFIN))-XPIV0)
Else
IDEB = 1
End If
!
! One takes values > XPIV to IHIGT
! However, we do not process the first values if we have been
! through the case when we did not have enough low values
!
JHIG = 0
IFIN = JLOW
JLOW = JDEB
!
If (XDONT(ILOWT(IFIN)) > XPIV) Then
ICRS = JDEB
lowloop4: Do
ICRS = ICRS + 1
If (XDONT(ILOWT(ICRS)) > XPIV) Then
JHIG = JHIG + 1
IHIGT (JHIG) = ILOWT (ICRS)
If (ICRS >= IFIN) Exit
Else
XWRK1 = XDONT(ILOWT(ICRS))
Do ILOW = IDEB, JLOW
If (XWRK1 == XDONT(ILOWT(ILOW))) &
Cycle lowloop4
End Do
JLOW = JLOW + 1
ILOWT (JLOW) = ILOWT (ICRS)
If (JLOW >= NORD) Exit
End If
End Do lowloop4
!
If (ICRS < IFIN) Then
Do
ICRS = ICRS + 1
If (XDONT(ILOWT(ICRS)) <= XPIV) Then
JLOW = JLOW + 1
ILOWT (JLOW) = ILOWT (ICRS)
Else
If (ICRS >= IFIN) Exit
End If
End Do
End If
Else
lowloop5: Do ICRS = IDEB, IFIN
If (XDONT(ILOWT(ICRS)) > XPIV) Then
JHIG = JHIG + 1
IHIGT (JHIG) = ILOWT (ICRS)
Else
XWRK1 = XDONT(ILOWT(ICRS))
Do ILOW = IDEB, JLOW
If (XWRK1 == XDONT(ILOWT(ILOW))) &
Cycle lowloop5
End Do
JLOW = JLOW + 1
ILOWT (JLOW) = ILOWT (ICRS)
If (JLOW >= NORD) Exit
End If
End Do lowloop5
!
Do ICRS = ICRS + 1, IFIN
If (XDONT(ILOWT(ICRS)) <= XPIV) Then
JLOW = JLOW + 1
ILOWT (JLOW) = ILOWT (ICRS)
End If
End Do
End If
!
End Select
! ______________________________
!
End Do
!
! Now, we only need to complete ranking of the 1:NORD set
! Assuming NORD is small, we use a simple insertion sort
!
IRNGT (1) = ILOWT (1)
Do ICRS = 2, NORD
IWRK = ILOWT (ICRS)
XWRK = XDONT (IWRK)
Do IDCR = ICRS - 1, 1, - 1
If (XWRK < XDONT(IRNGT(IDCR))) Then
IRNGT (IDCR+1) = IRNGT (IDCR)
Else
Exit
End If
End Do
IRNGT (IDCR+1) = IWRK
End Do
Return
end subroutine unipar
end Subroutine tnmex4
! end program spatiotemporalnn
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -