gitee.com/quant1x/num@v0.3.2/arithmetics.go (about) 1 package num 2 3 // 四则运算 (arithmetics) 4 5 // UnaryOperations 一元运算 unary operations 6 func UnaryOperations[T Number](x []T, f32 func([]float32) []float32, f64 func([]float64) []float64, cany func([]T) []T) []T { 7 var t []T 8 if len(x) == 0 { 9 return t 10 } 11 var d any 12 var s any 13 s = x 14 switch fs := s.(type) { 15 case []float32: 16 d = f32(fs) 17 case []float64: 18 d = f64(fs) 19 default: 20 d = cany(x) 21 } 22 return d.([]T) 23 } 24 25 func UnaryOperations1[T Number](x []T, f32 func([]float32) float32, f64 func([]float64) float64, cany func([]T) T) T { 26 var t T 27 if len(x) == 0 { 28 return t 29 } 30 var d any 31 var s any 32 s = x 33 switch fs := s.(type) { 34 case []float32: 35 d = f32(fs) 36 case []float64: 37 d = f64(fs) 38 default: 39 d = cany(x) 40 } 41 return d.(T) 42 } 43 44 // UnaryOperations2 一元运算 unary operations 45 // 46 // 运算和返回值是两种类型 47 func UnaryOperations2[T Number, E Number](x []T, f32 func([]float32) E, f64 func([]float64) E, cany func([]T) E) E { 48 if len(x) == 0 { 49 return E(0) 50 } 51 var d any 52 var s any 53 s = x 54 switch fs := s.(type) { 55 case []float32: 56 d = f32(fs) 57 case []float64: 58 d = f64(fs) 59 default: 60 d = cany(x) 61 } 62 return d.(E) 63 } 64 65 // BinaryOperations 二元运算 binary operations 66 // 67 // Binary operation 68 // calculate 69 func BinaryOperations[T Number](x []T, y any, f32 func(x, y []float32) []float32, f64 func(x, y []float64) []float64, cany func(x, y []T) []T) []T { 70 var d any 71 length := len(x) 72 var s any = x 73 switch vs := s.(type) { 74 case []float32: 75 f32s := AnyToSlice[float32](y, length) 76 //vs = FillNa(vs, 0.00) 77 //f32s = FillNa(f32s, 0.00) 78 d = f32(vs, f32s) 79 case []float64: 80 f64s := AnyToSlice[float64](y, length) 81 //vs = FillNa(vs, 0.00) 82 //f64s = FillNa(f64s, 0.00) 83 d = f64(vs, f64s) 84 default: 85 ys := AnyToSlice[T](y, length) 86 d = cany(x, ys) 87 } 88 return d.([]T) 89 } 90 91 func BinaryOperations2[T BaseType, E BaseType](x, y []T, f32 func(x, y []float32) []E, f64 func(x, y []float64) []E, cany func(x, y []T) []E) []E { 92 var d any 93 length := len(x) 94 var s any = x 95 switch vs := s.(type) { 96 case []float32: 97 f32s := AnyToSlice[float32](y, length) 98 d = f32(vs, f32s) 99 case []float64: 100 f64s := AnyToSlice[float64](y, length) 101 d = f64(vs, f64s) 102 default: 103 ys := AnyToSlice[T](y, length) 104 d = cany(x, ys) 105 } 106 return d.([]E) 107 } 108 109 // 三元运算 triple operations 110 /* 111 const ( 112 __k_calc_add = 1 // 加 113 __k_calc_sub = 2 // 减 114 __k_calc_mul = 3 // 乘 115 __k_calc_div = 4 // 除 116 __k_calc_mod = 5 // 取模 117 ) 118 119 var ( 120 // 加 121 __calc_add = func(f1, f2 DType) DType { 122 return f1 + f2 123 } 124 // 减 125 __calc_sub = func(f1, f2 DType) DType { 126 return f1 - f2 127 } 128 // 乘 129 __calc_mul = func(f1, f2 DType) DType { 130 return f1 * f2 131 } 132 // 除 133 __calc_div = func(f1, f2 DType) DType { 134 return f1 / f2 135 } 136 // 取模 137 __calc_mod = func(f1, f2 DType) DType { 138 return math.Mod(f1, f2) 139 } 140 ) 141 142 // 重构 143 144 func __arithmetic[T ~[]E, E Number](x T, y any, c int, calculator func(f1, f2 DType) E) []E { 145 if __y, ok := y.(Series); ok { 146 y = __y.Values() 147 } 148 var d = []E{} 149 switch Y := y.(type) { 150 case nil, int8, uint8, int16, uint16, int32, uint32, int64, uint64, int, uint, float32, float64, bool, string: 151 f2 := Any2DType(Y) 152 d = __arithmetic_dtype(x, f2, c, calculator) 153 case []float32: 154 d = __arithmetic_slice(x, Y, c, calculator) 155 case []float64: 156 d = __arithmetic_slice(x, Y, c, calculator) 157 case []int: 158 d = __arithmetic_slice(x, Y, c, calculator) 159 case []int8: 160 d = __arithmetic_slice(x, Y, c, calculator) 161 case []int16: 162 d = __arithmetic_slice(x, Y, c, calculator) 163 case []int32: 164 d = __arithmetic_slice(x, Y, c, calculator) 165 case []int64: 166 d = __arithmetic_slice(x, Y, c, calculator) 167 case []uint: 168 d = __arithmetic_slice(x, Y, c, calculator) 169 case []uint8: 170 d = __arithmetic_slice(x, Y, c, calculator) 171 case []uint16: 172 d = __arithmetic_slice(x, Y, c, calculator) 173 case []uint32: 174 d = __arithmetic_slice(x, Y, c, calculator) 175 case []uint64: 176 d = __arithmetic_slice(x, Y, c, calculator) 177 case []uintptr: 178 d = __arithmetic_slice(x, Y, c, calculator) 179 //case []string: 180 // d = __arithmetic_slice(x, Y, c, calculator) 181 //case []bool: 182 // d = __arithmetic_slice(x, Y, c, calculator) 183 default: 184 // 其它未知类型抛异常 185 panic(TypeError(y)) 186 } 187 return d 188 } 189 190 // 切片和dtype对比, 不用考虑slice长度对齐的问题 191 func __arithmetic_dtype[T ~[]E, E Number](x T, y DType, c int, calculator func(f1, f2 DType) E) []E { 192 var d any 193 xLen := len(x) 194 kind := checkoutRawType(x) 195 switch { 196 case kind == reflect.Float64 && c == __k_calc_add: 197 fs := make([]float64, xLen) 198 d = num.AddNumber_Into(fs, any(x).([]float64), y) 199 case kind == reflect.Float64 && c == __k_calc_sub: 200 fs := make([]float64, xLen) 201 d = num.SubNumber_Into(fs, any(x).([]float64), y) 202 case kind == reflect.Float64 && c == __k_calc_mul: 203 fs := make([]float64, xLen) 204 d = num.MulNumber_Into(fs, any(x).([]float64), y) 205 case kind == reflect.Float64 && c == __k_calc_div: 206 fs := make([]float64, xLen) 207 d = num.DivNumber_Into(fs, any(x).([]float64), y) 208 case kind == reflect.Float32 && c == __k_calc_add: 209 fs := make([]float32, xLen) 210 d = num32.AddNumber_Into(fs, any(x).([]float32), float32(y)) 211 case kind == reflect.Float32 && c == __k_calc_sub: 212 fs := make([]float32, xLen) 213 d = num32.SubNumber_Into(fs, any(x).([]float32), float32(y)) 214 case kind == reflect.Float32 && c == __k_calc_mul: 215 fs := make([]float32, xLen) 216 d = num32.MulNumber_Into(fs, any(x).([]float32), float32(y)) 217 case kind == reflect.Float32 && c == __k_calc_div: 218 fs := make([]float32, xLen) 219 d = num32.DivNumber_Into(fs, any(x).([]float32), float32(y)) 220 default: 221 b := y 222 bs := make([]E, xLen) 223 for i := 0; i < xLen; i++ { 224 a := Any2DType(x[i]) 225 bs[i] = calculator(a, b) 226 } 227 } 228 return d.([]E) 229 } 230 231 // 切片和切片对比 232 func __arithmetic_slice[T ~[]E, E Number, T2 ~[]E2, E2 Number](x T, y T2, c int, calculator func(f1, f2 DType) E) []E { 233 var d any 234 xLen := len(x) 235 yLen := len(y) 236 237 if xLen >= yLen { 238 es := make([]E, xLen) 239 switch xs := any(x).(type) { 240 case []float64: 241 num.Add_Into(es[:yLen], xs[:yLen], any(y).([]float64)[:yLen]) 242 } 243 switch { 244 case xKind == reflect.Float64 && xKind == yKind && c == __k_calc_add: 245 num.Add_Into(es[:yLen], any(x).([]float64)[:yLen], any(y).([]float64)[:yLen]) 246 case xKind == reflect.Float64 && xKind == yKind && c == __k_calc_sub: 247 num.Sub_Into(es[:yLen], any(x).([]float64)[:yLen], any(y).([]float64)[:yLen]) 248 case xKind == reflect.Float64 && xKind == yKind && c == __k_calc_mul: 249 num.Mul_Into(es[:yLen], any(x).([]float64)[:yLen], any(y).([]float64)[:yLen]) 250 case xKind == reflect.Float64 && xKind == yKind && c == __k_calc_div: 251 num.Div_Into(es[:yLen], any(x).([]float64)[:yLen], any(y).([]float64)[:yLen]) 252 case xKind == reflect.Float32 && xKind == yKind && c == __k_calc_add: 253 num.Add_Into(es[:yLen], any(x).([]float64)[:yLen], any(y).([]float64)[:yLen]) 254 case xKind == reflect.Float32 && xKind == yKind && c == __k_calc_sub: 255 num.Sub_Into(es[:yLen], any(x).([]float64)[:yLen], any(y).([]float64)[:yLen]) 256 case xKind == reflect.Float32 && xKind == yKind && c == __k_calc_mul: 257 num.Mul_Into(es[:yLen], any(x).([]float64)[:yLen], any(y).([]float64)[:yLen]) 258 case xKind == reflect.Float32 && xKind == yKind && c == __k_calc_div: 259 num.Div_Into(es[:yLen], any(x).([]float64)[:yLen], any(y).([]float64)[:yLen]) 260 } 261 if xKind == reflect.Float64 && xKind == yKind && c == __k_calc_add { 262 num.Gt_Into(es[:yLen], any(x).([]float64)[:yLen], any(y).([]float64)[:yLen]) 263 } else if xKind == reflect.Float64 && xKind == yKind && c == __k_compare_gte { 264 es := make([]float64, xLen) 265 num.Gte_Into(es[:yLen], any(x).([]float64)[:yLen], any(y).([]float64)[:yLen]) 266 } else if xKind == reflect.Float64 && xKind == yKind && c == __k_compare_lt { 267 es := make([]float64, xLen) 268 num.Lt_Into(es[:yLen], any(x).([]float64)[:yLen], any(y).([]float64)[:yLen]) 269 } else if xKind == reflect.Float64 && xKind == yKind && c == __k_compare_lte { 270 es := make([]float64, xLen) 271 num.Lte_Into(es[:yLen], any(x).([]float64)[:yLen], any(y).([]float64)[:yLen]) 272 } else if xKind == reflect.Float32 && xKind == yKind && c == __k_compare_gt { 273 num32.Gt_Into(es[:yLen], any(x).([]float32)[:yLen], any(y).([]float32)[:yLen]) 274 } else if xKind == reflect.Float32 && xKind == yKind && c == __k_compare_gte { 275 num32.Gte_Into(es[:yLen], any(x).([]float32)[:yLen], any(y).([]float32)[:yLen]) 276 } else if xKind == reflect.Float32 && xKind == yKind && c == __k_compare_lt { 277 num32.Lt_Into(es[:yLen], any(x).([]float32)[:yLen], any(y).([]float32)[:yLen]) 278 } else if xKind == reflect.Float32 && xKind == yKind && c == __k_compare_lte { 279 num32.Lte_Into(es[:yLen], any(x).([]float32)[:yLen], any(y).([]float32)[:yLen]) 280 } else if xKind == reflect.Bool && xKind == yKind && c == __k_compare_and { 281 num.And_Into(es[:yLen], any(x).([]bool)[:yLen], any(y).([]bool)[:yLen]) 282 } else { 283 for i := 0; i < yLen; i++ { 284 f1 := Any2DType(x[i]) 285 f2 := Any2DType(y[i]) 286 es[i] = calculator(f1, f2) 287 } 288 } 289 for i := yLen; i < xLen; i++ { 290 f1 := Any2DType(x[i]) 291 f2 := DType(0) 292 es[i] = calculator(f1, f2) 293 } 294 } else { 295 es = make([]bool, yLen) 296 if xKind == reflect.Float64 && xKind == yKind && c == __k_compare_gt { 297 num.Gt_Into(es[:xLen], any(x).([]float64)[:xLen], any(y).([]float64)[:xLen]) 298 } else if xKind == reflect.Float64 && xKind == yKind && c == __k_compare_gte { 299 num.Gte_Into(es[:xLen], any(x).([]float64)[:xLen], any(y).([]float64)[:xLen]) 300 } else if xKind == reflect.Float64 && xKind == yKind && c == __k_compare_lt { 301 num.Lt_Into(es[:xLen], any(x).([]float64)[:xLen], any(y).([]float64)[:xLen]) 302 } else if xKind == reflect.Float64 && xKind == yKind && c == __k_compare_lte { 303 num.Lte_Into(es[:xLen], any(x).([]float64)[:xLen], any(y).([]float64)[:xLen]) 304 } else if xKind == reflect.Float32 && xKind == yKind && c == __k_compare_gt { 305 num32.Gt_Into(es[:xLen], any(x).([]float32)[:xLen], any(y).([]float32)[:xLen]) 306 } else if xKind == reflect.Float32 && xKind == yKind && c == __k_compare_gte { 307 num32.Gte_Into(es[:xLen], any(x).([]float32)[:xLen], any(y).([]float32)[:xLen]) 308 } else if xKind == reflect.Float32 && xKind == yKind && c == __k_compare_lt { 309 num32.Lt_Into(es[:xLen], any(x).([]float32)[:xLen], any(y).([]float32)[:xLen]) 310 } else if xKind == reflect.Float32 && xKind == yKind && c == __k_compare_lte { 311 num32.Lte_Into(es[:xLen], any(x).([]float32)[:xLen], any(y).([]float32)[:xLen]) 312 } else if xKind == reflect.Bool && xKind == yKind && c == __k_compare_and { 313 num.And_Into(es[:xLen], any(x).([]bool)[:xLen], any(y).([]bool)[:xLen]) 314 } else { 315 for i := 0; i < xLen; i++ { 316 f1 := Any2DType(x[i]) 317 f2 := Any2DType(y[i]) 318 es[i] = calculator(f1, f2) 319 } 320 } 321 for i := xLen; i < yLen; i++ { 322 f1 := DType(0) 323 f2 := Any2DType(y[i]) 324 es[i] = calculator(f1, f2) 325 } 326 } 327 return d.([]E) 328 } 329 */