gitee.com/quant1x/num@v0.3.2/wave.go (about) 1 package num 2 3 import "cmp" 4 5 // QuantizationFactor 量化因子接口 6 type QuantizationFactor interface { 7 // Normalize 归一化, 标准化, 数据预处理 8 Normalize() 9 } 10 11 func PeeksAndValleys[E Number](x []E) (peeks, valleys []int) { 12 return 13 } 14 15 // 波浪 wave 波峰波谷 16 type wave struct { 17 data []float64 // 原始数据 18 diff []int // 一阶差分 19 peakIndex []int // 波峰位置存储 20 valleyIndex []int // 波谷位置存储 21 peakCount int // 所识别的波峰计数 22 valleyCount int // 所识别的波谷计数 23 } 24 25 // InitPV 创建并初始化波峰波谷 26 func initWave(data []float64) *wave { 27 n := len(data) 28 if n == 0 { 29 return nil 30 } 31 pv := wave{ 32 data: data, 33 diff: make([]int, n), 34 peakIndex: make([]int, n), 35 valleyIndex: make([]int, n), 36 } 37 for i := 0; i < n; i++ { 38 pv.diff[i] = 0 39 pv.peakIndex[i] = -1 40 pv.valleyIndex[i] = -1 41 } 42 pv.peakCount = 0 43 pv.valleyCount = 0 44 return &pv 45 } 46 47 // Normalize 归一化, 预处理 48 // 前向差分 49 func (this *wave) Normalize() { 50 n := len(this.data) 51 //step 1: 首先进行前向差分,并归一化 52 for i := 0; i < n-1; i++ { 53 c := this.data[i] 54 b := this.data[i+1] 55 if b-c > 0 { 56 this.diff[i] = 1 57 } else if b-c < 0 { 58 this.diff[i] = -1 59 } else { 60 this.diff[i] = 0 61 } 62 this.diff[i] = cmp.Compare(b, c) 63 } 64 } 65 66 // Find 找波峰波谷 67 func (this *wave) Find() { 68 n := len(this.data) 69 //step 1: 首先进行前向差分,并归一化 70 for i := 0; i < n-1; i++ { 71 c := this.data[i] 72 b := this.data[i+1] 73 sampleDiff := b - c 74 if sampleDiff > 0 { 75 this.diff[i] = 1 76 } else if sampleDiff < 0 { 77 this.diff[i] = -1 78 } else { 79 this.diff[i] = 0 80 } 81 } 82 83 // step 2: 对相邻相等的点进行领边坡度处理 84 for i := 0; i < n-1; i++ { 85 if this.diff[i] == 0 { 86 if i == (n - 2) { 87 if this.diff[i-1] >= 0 { 88 this.diff[i] = 1 89 } else { 90 this.diff[i] = -1 91 } 92 } else { 93 if this.diff[i+1] >= 0 { 94 this.diff[i] = 1 95 } else { 96 this.diff[i] = -1 97 } 98 } 99 } 100 } 101 // step 3: 对相邻相等的点进行领边坡度处理 102 for i := 0; i < n-1; i++ { 103 sampleDiff := this.diff[i+1] - this.diff[i] 104 if sampleDiff == -2 { 105 // 波峰识别 106 this.peakIndex[this.peakCount] = i + 1 107 this.peakCount++ 108 } else if sampleDiff == 2 { 109 // 波谷识别 110 this.valleyIndex[this.valleyCount] = i + 1 111 this.valleyCount++ 112 } 113 } 114 }