Guest User

mrootsort

a guest
Jun 24th, 2026
23
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.13 KB | None | 0 0
  1. Option Explicit
  2.  
  3. Public Function SortRootResult(ByVal RootA As Variant, _
  4. ByVal Degree As Long, _
  5. Optional ByVal Tol As Double = 0.0000000001) As Variant
  6. Dim i As Long, j As Long
  7. Dim tmpR As Variant, tmpI As Variant
  8. Dim nReal As Long
  9. Dim nRows As Long, nCols As Long
  10.  
  11. On Error GoTo ReturnResult
  12.  
  13. nRows = UBound(RootA, 1)
  14. nCols = UBound(RootA, 2)
  15.  
  16. If Degree < 1 Then GoTo ReturnResult
  17. If nRows < Degree Then GoTo ReturnResult
  18. If nCols < 2 Then GoTo ReturnResult
  19.  
  20. ' Treat very small imaginary parts as zero
  21. For i = 1 To Degree
  22. If Abs(DblOrZero(RootA(i, 2))) <= Tol Then
  23. RootA(i, 2) = 0#
  24. End If
  25. Next i
  26.  
  27. ' Sort roots
  28. For i = 1 To Degree - 1
  29. For j = i + 1 To Degree
  30. If RootComesAfter(RootA(i, 1), RootA(i, 2), _
  31. RootA(j, 1), RootA(j, 2), Tol) Then
  32.  
  33. tmpR = RootA(i, 1)
  34. tmpI = RootA(i, 2)
  35.  
  36. RootA(i, 1) = RootA(j, 1)
  37. RootA(i, 2) = RootA(j, 2)
  38.  
  39. RootA(j, 1) = tmpR
  40. RootA(j, 2) = tmpI
  41. End If
  42. Next j
  43. Next i
  44.  
  45. ' Recount real and complex roots
  46. nReal = 0
  47. For i = 1 To Degree
  48. If Abs(DblOrZero(RootA(i, 2))) <= Tol Then
  49. RootA(i, 2) = 0#
  50. nReal = nReal + 1
  51. End If
  52. Next i
  53.  
  54. ' Count row is normally Degree + 1
  55. If nRows >= Degree + 1 Then
  56. RootA(Degree + 1, 1) = nReal
  57. RootA(Degree + 1, 2) = Degree - nReal
  58. End If
  59.  
  60. ReturnResult:
  61. SortRootResult = RootA
  62. End Function
  63.  
  64. Private Function RootComesAfter(ByVal rA As Variant, ByVal iA As Variant, _
  65. ByVal rB As Variant, ByVal iB As Variant, _
  66. ByVal Tol As Double) As Boolean
  67. Dim ar As Double, ai As Double
  68. Dim br As Double, bi As Double
  69. Dim aIsReal As Boolean, bIsReal As Boolean
  70.  
  71. ar = DblOrZero(rA)
  72. ai = DblOrZero(iA)
  73. br = DblOrZero(rB)
  74. bi = DblOrZero(iB)
  75.  
  76. If Abs(ai) <= Tol Then ai = 0#
  77. If Abs(bi) <= Tol Then bi = 0#
  78.  
  79. aIsReal = (ai = 0#)
  80. bIsReal = (bi = 0#)
  81.  
  82. ' Real roots must come before complex roots
  83. If aIsReal <> bIsReal Then
  84. RootComesAfter = Not aIsReal
  85. Exit Function
  86. End If
  87.  
  88. ' Sort by real part ascending
  89. If Abs(ar - br) > Tol Then
  90. RootComesAfter = (ar > br)
  91. Exit Function
  92. End If
  93.  
  94. ' If complex roots have the same real part,
  95. ' positive imaginary part comes first
  96. If Not aIsReal Then
  97. If Abs(ai - bi) > Tol Then
  98. RootComesAfter = (ai < bi)
  99. Exit Function
  100. End If
  101. End If
  102.  
  103. RootComesAfter = False
  104. End Function
  105.  
  106. Private Function DblOrZero(ByVal v As Variant) As Double
  107. On Error GoTo NotNumeric
  108.  
  109. If IsEmpty(v) Then GoTo NotNumeric
  110. If IsNull(v) Then GoTo NotNumeric
  111.  
  112. If IsNumeric(v) Then
  113. DblOrZero = CDbl(v)
  114. Else
  115. DblOrZero = 0#
  116. End If
  117.  
  118. Exit Function
  119.  
  120. NotNumeric:
  121. DblOrZero = 0#
  122. End Function
Advertisement
Add Comment
Please, Sign In to add comment