gitee.com/quant1x/num@v0.3.2/diff.go (about) 1 package num 2 3 // Diff 元素的第一个离散差 4 // 5 // n默认是1 6 func Diff[E Number](S []E, n int) []E { 7 return v4Diff[E](S, n) 8 } 9 10 // v1Diff 元素的第一个离散差 11 // 12 // First discrete difference of element. 13 // Calculates the difference of a {klass} element compared with another 14 // element in the {klass} (default is element in previous row). 15 func v1Diff[T Number](s []T, param any) []T { 16 blocks := Rolling[T](s, param) 17 var d []T 18 var front = TypeDefault[T]() 19 for _, block := range blocks { 20 vs := block 21 vl := len(block) 22 if vl == 0 { 23 d = append(d, TypeDefault[T]()) 24 continue 25 } 26 vf := vs[0] 27 vc := vs[vl-1] 28 if DTypeIsNaN(Any2DType(vc)) || DTypeIsNaN(Any2DType(front)) { 29 front = vf 30 d = append(d, TypeDefault[T]()) 31 continue 32 } 33 diff := vc - front 34 d = append(d, diff) 35 front = vf 36 } 37 38 return d 39 } 40 41 // Deprecated: 推荐使用Diff [wangfeng on 2024/2/22 17:51] 42 func V2Diff[T BaseType](s []T, param any) []T { 43 return v2Diff[T](s, param) 44 } 45 46 func v2Diff[T BaseType](s []T, param any) []T { 47 var d any 48 switch vs := any(s).(type) { 49 case []float32: 50 d = v1Diff(vs, param) 51 case []float64: 52 d = v1Diff(vs, param) 53 case []int: 54 d = v1Diff(vs, param) 55 case []int8: 56 d = v1Diff(vs, param) 57 case []int16: 58 d = v1Diff(vs, param) 59 case []int32: 60 d = v1Diff(vs, param) 61 case []int64: 62 d = v1Diff(vs, param) 63 //case []uint, []uint8, []uint16, []uint32, []uint64, []uintptr: 64 // d = xv 65 default: 66 // 其它类型原样返回 67 panic(TypeError(vs)) 68 } 69 70 return d.([]T) 71 } 72 73 // 最原始的算法, 只支持向右滑动 74 func v3Diff[E Number](S []E, n int) []E { 75 length := len(S) 76 d := make([]E, length) 77 offset := AbsInt(n) 78 defaultValue := TypeDefault[E]() 79 for i, _ := range S[:length-offset] { 80 d[i] = S[i+offset] - S[i] 81 } 82 for i := length - offset; i < length; i++ { 83 d[i] = defaultValue 84 } 85 return d 86 } 87 88 func v4Diff[E Number](S []E, n int) []E { 89 d := v3Shift(S, n) 90 SubInplace(d, S) 91 return d 92 } 93 94 // 支持向左向右两个方向滑动 95 func v5Diff[E Number](S []E, n int) []E { 96 d := v3Shift(S, n) 97 for i, _ := range S { 98 d[i] -= S[i] 99 } 100 return d 101 } 102 103 func v6Diff[E Number](S []E, n int) []E { 104 arr := ndarray[E](S) 105 d := arr.v1Rolling(n, func(index int, v E) E { 106 return v - S[index] 107 }) 108 return d 109 } 110 111 func v7Diff[E Number](S []E, n int) []E { 112 arr := ndarray[E](S) 113 d := arr.v2Rolling(n, func(index int, v E) E { 114 return v - S[index] 115 }) 116 return d 117 } 118 119 func v8Diff[E Number](S []E, n int) []E { 120 length := len(S) 121 d := make([]E, length) 122 window := Any2Window[DType](n) 123 defaultValue := TypeDefault[E]() 124 for i := 0; i < length; i++ { 125 val := S[i] 126 period := window.At(i) 127 if DTypeIsNaN(period) { 128 val = defaultValue 129 } else { 130 newIndex := i - int(period) 131 if newIndex < 0 || newIndex >= length { 132 val = defaultValue 133 } else { 134 val = S[newIndex] - val 135 } 136 } 137 d[i] = val 138 } 139 return d 140 }