25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

102 lines
1.8KB

  1. package cfar
  2. import "sort"
  3. type orderedStat struct {
  4. guard int
  5. train int
  6. rank int
  7. scaleDb float64
  8. wrapAround bool
  9. }
  10. func newOS(cfg Config) CFAR {
  11. rank := cfg.Rank - 1
  12. total := 2 * cfg.TrainCells
  13. if rank < 0 {
  14. rank = 0
  15. }
  16. if rank >= total {
  17. rank = total - 1
  18. }
  19. return &orderedStat{
  20. guard: cfg.GuardCells,
  21. train: cfg.TrainCells,
  22. rank: rank,
  23. scaleDb: cfg.ScaleDb,
  24. wrapAround: cfg.WrapAround,
  25. }
  26. }
  27. func (o *orderedStat) Thresholds(spectrum []float64) []float64 {
  28. n := len(spectrum)
  29. if n == 0 {
  30. return nil
  31. }
  32. out := make([]float64, n)
  33. train := o.train
  34. guard := o.guard
  35. at := func(i int) float64 {
  36. if o.wrapAround {
  37. return spectrum[((i%n)+n)%n]
  38. }
  39. if i < 0 || i >= n {
  40. return spectrum[clampInt(i, 0, n-1)]
  41. }
  42. return spectrum[i]
  43. }
  44. win := make([]float64, 0, 2*train)
  45. for k := 1; k <= train; k++ {
  46. win = append(win, at(0-guard-k))
  47. win = append(win, at(0+guard+k))
  48. }
  49. sort.Float64s(win)
  50. out[0] = win[o.rank] + o.scaleDb
  51. for i := 1; i < n; i++ {
  52. removeFromSorted(&win, at(i-1-guard-train))
  53. removeFromSorted(&win, at(i-1+guard+1))
  54. insertSorted(&win, at(i-guard-1))
  55. insertSorted(&win, at(i+guard+train))
  56. out[i] = win[o.rank] + o.scaleDb
  57. }
  58. return out
  59. }
  60. func insertSorted(s *[]float64, v float64) {
  61. idx := sort.SearchFloat64s(*s, v)
  62. *s = append(*s, 0)
  63. copy((*s)[idx+1:], (*s)[idx:])
  64. (*s)[idx] = v
  65. }
  66. func removeFromSorted(s *[]float64, v float64) {
  67. idx := sort.SearchFloat64s(*s, v)
  68. if idx < len(*s) && (*s)[idx] == v {
  69. *s = append((*s)[:idx], (*s)[idx+1:]...)
  70. return
  71. }
  72. for i := idx - 1; i >= 0; i-- {
  73. if (*s)[i] == v {
  74. *s = append((*s)[:i], (*s)[i+1:]...)
  75. return
  76. }
  77. if (*s)[i] < v {
  78. break
  79. }
  80. }
  81. for i := idx + 1; i < len(*s); i++ {
  82. if (*s)[i] == v {
  83. *s = append((*s)[:i], (*s)[i+1:]...)
  84. return
  85. }
  86. if (*s)[i] > v {
  87. break
  88. }
  89. }
  90. }