github.com/qiaogw/arrgo@v0.0.8/arithmetic.go (about) 1 package arrgo 2 3 import ( 4 "math" 5 6 asm "github.com/qiaogw/arrgo/internal" 7 //"github.com/ledao/arrgo/internal" 8 ) 9 10 //多维数组和标量相加,结果为新的多维数组,不修改原数组。 11 func (a *Arrf) AddC(b float64) *Arrf { 12 if a == nil || a.Size() == 0 { 13 panic(SHAPE_ERROR) 14 } 15 ta := a.Copy() 16 asm.AddC(b, ta.Data) 17 return ta 18 } 19 20 //两个多维数组相加,结果为新的多维数组,不修改原数组。 21 //加法过程中间会发生广播,对矩阵运算有极大帮助。 22 //fixme : by ledao 广播机制会进行额外的运算,对于简单的场景最好有判断,避免广播。 23 func (a *Arrf) Add(b *Arrf) *Arrf { 24 if a.SameShapeTo(b) { 25 var ta = a.Copy() 26 asm.Add(ta.Data, b.Data) 27 return ta 28 } 29 var ta, tb, err = Boardcast(a, b) 30 if err != nil { 31 panic(err) 32 } 33 return ta.Add(tb) 34 } 35 36 //多维数组和标量相减,结果为新的多维数组,不修改原数组。 37 func (a *Arrf) SubC(b float64) *Arrf { 38 ta := a.Copy() 39 asm.SubtrC(b, ta.Data) 40 return ta 41 } 42 43 //两个多维数组相减,结果为新的多维数组,不修改原数组。 44 //减法过程中间会发生广播,对矩阵运算有极大帮助。 45 //fixme : by ledao 广播机制会进行额外的运算,对于简单的场景最好有判断,避免广播。 46 func (a *Arrf) Sub(b *Arrf) *Arrf { 47 if a.SameShapeTo(b) { 48 var ta = a.Copy() 49 asm.Subtr(ta.Data, b.Data) 50 return ta 51 } 52 var ta, tb, err = Boardcast(a, b) 53 if err != nil { 54 panic(err) 55 } 56 return ta.Sub(tb) 57 } 58 59 func (a *Arrf) MulC(b float64) *Arrf { 60 ta := a.Copy() 61 asm.MultC(b, ta.Data) 62 return ta 63 } 64 65 func (a *Arrf) Mul(b *Arrf) *Arrf { 66 if a.SameShapeTo(b) { 67 var ta = a.Copy() 68 asm.Mult(ta.Data, b.Data) 69 return ta 70 } 71 var ta, tb, err = Boardcast(a, b) 72 if err != nil { 73 panic(err) 74 } 75 return ta.Mul(tb) 76 } 77 78 func (a *Arrf) DivC(b float64) *Arrf { 79 ta := a.Copy() 80 asm.DivC(b, ta.Data) 81 return ta 82 } 83 84 func (a *Arrf) Div(b *Arrf) *Arrf { 85 if a.SameShapeTo(b) { 86 var ta = a.Copy() 87 asm.Div(ta.Data, b.Data) 88 return ta 89 } 90 var ta, tb, err = Boardcast(a, b) 91 if err != nil { 92 panic(err) 93 } 94 return ta.Div(tb) 95 } 96 97 func (a *Arrf) DotProd(b *Arrf) float64 { 98 switch { 99 case a.Ndims() == 1 && b.Ndims() == 1 && a.Length() == b.Length(): 100 return asm.DotProd(a.Data, b.Data) 101 } 102 panic(SHAPE_ERROR) 103 } 104 105 func (a *Arrf) MatProd(b *Arrf) *Arrf { 106 switch { 107 case a.Ndims() == 2 && b.Ndims() == 2 && a.Shape[1] == b.Shape[0]: 108 ret := Zeros(a.Shape[0], b.Shape[1]) 109 for i := 0; i < a.Shape[0]; i++ { 110 for j := 0; j < a.Shape[1]; j++ { 111 ret.Set(a.Index(Range{i, i + 1}).DotProd(b.Index(Range{0, b.Shape[0]}, Range{j, j + 1})), i, j) 112 } 113 } 114 return ret 115 } 116 panic(SHAPE_ERROR) 117 } 118 119 func Abs(b *Arrf) *Arrf { 120 tb := b.Copy() 121 for i, v := range tb.Data { 122 tb.Data[i] = math.Abs(v) 123 } 124 return tb 125 } 126 127 func Sqrt(b *Arrf) *Arrf { 128 tb := b.Copy() 129 for i, v := range tb.Data { 130 tb.Data[i] = math.Sqrt(v) 131 } 132 return tb 133 } 134 135 func Square(b *Arrf) *Arrf { 136 var tb = b.Copy() 137 for i, v := range tb.Data { 138 tb.Data[i] = math.Pow(v, 2) 139 } 140 return tb 141 } 142 143 func Exp(b *Arrf) *Arrf { 144 var tb = b.Copy() 145 for i, v := range tb.Data { 146 tb.Data[i] = math.Exp(v) 147 } 148 return tb 149 } 150 151 func Log(b *Arrf) *Arrf { 152 var tb = b.Copy() 153 for i, v := range tb.Data { 154 tb.Data[i] = math.Log(v) 155 } 156 return tb 157 } 158 159 func Log10(b *Arrf) *Arrf { 160 var tb = b.Copy() 161 for i, v := range tb.Data { 162 tb.Data[i] = math.Log10(v) 163 } 164 return tb 165 } 166 167 func Log2(b *Arrf) *Arrf { 168 var tb = b.Copy() 169 for i, v := range tb.Data { 170 tb.Data[i] = math.Log2(v) 171 } 172 return tb 173 } 174 175 func Log1p(b *Arrf) *Arrf { 176 var tb = b.Copy() 177 for i, v := range tb.Data { 178 tb.Data[i] = math.Log1p(v) 179 } 180 return tb 181 } 182 183 func Sign(b *Arrf) *Arrf { 184 var tb = b.Copy() 185 var sign float64 = 0 186 for i, v := range tb.Data { 187 if v > 0 { 188 sign = 1 189 } else if v < 0 { 190 sign = -1 191 } 192 tb.Data[i] = sign 193 } 194 return tb 195 } 196 197 func Ceil(b *Arrf) *Arrf { 198 var tb = b.Copy() 199 for i, v := range tb.Data { 200 tb.Data[i] = math.Ceil(v) 201 } 202 return tb 203 } 204 205 func Floor(b *Arrf) *Arrf { 206 var tb = b.Copy() 207 for i, v := range tb.Data { 208 tb.Data[i] = math.Floor(v) 209 } 210 return tb 211 } 212 213 func Round(b *Arrf, places int) *Arrf { 214 var tb = b.Copy() 215 for i, v := range tb.Data { 216 tb.Data[i] = Roundf(v, places) 217 } 218 return tb 219 } 220 221 func Modf(b *Arrf) (*Arrf, *Arrf) { 222 var tb = b.Copy() 223 var tbFrac = b.Copy() 224 for i, v := range tb.Data { 225 r, f := math.Modf(v) 226 tb.Data[i] = r 227 tbFrac.Data[i] = f 228 } 229 return tb, tbFrac 230 } 231 232 func IsNaN(b *Arrf) *Arrb { 233 var tb = EmptyB(b.Shape...) 234 for i, v := range b.Data { 235 tb.Data[i] = math.IsNaN(v) 236 } 237 return tb 238 } 239 240 func IsInf(b *Arrf) *Arrb { 241 var tb = EmptyB(b.Shape...) 242 for i, v := range b.Data { 243 tb.Data[i] = math.IsInf(v, 0) 244 } 245 return tb 246 } 247 248 func IsFinit(b *Arrf) *Arrb { 249 var tb = EmptyB(b.Shape...) 250 for i, v := range b.Data { 251 tb.Data[i] = !math.IsInf(v, 0) 252 } 253 return tb 254 } 255 256 func Cos(b *Arrf) *Arrf { 257 var tb = b.Copy() 258 for i, v := range tb.Data { 259 tb.Data[i] = math.Cos(v) 260 } 261 return tb 262 } 263 264 func Cosh(b *Arrf) *Arrf { 265 var tb = b.Copy() 266 for i, v := range tb.Data { 267 tb.Data[i] = math.Cosh(v) 268 } 269 return tb 270 } 271 272 func Acos(b *Arrf) *Arrf { 273 var tb = b.Copy() 274 for i, v := range tb.Data { 275 tb.Data[i] = math.Acos(v) 276 } 277 return tb 278 } 279 280 func Acosh(b *Arrf) *Arrf { 281 var tb = b.Copy() 282 for i, v := range tb.Data { 283 tb.Data[i] = math.Acosh(v) 284 } 285 return tb 286 } 287 288 func Sin(b *Arrf) *Arrf { 289 var tb = b.Copy() 290 for i, v := range tb.Data { 291 tb.Data[i] = math.Sin(v) 292 } 293 return tb 294 } 295 296 func Sinh(b *Arrf) *Arrf { 297 var tb = b.Copy() 298 for i, v := range tb.Data { 299 tb.Data[i] = math.Sinh(v) 300 } 301 return tb 302 } 303 304 func Asin(b *Arrf) *Arrf { 305 var tb = b.Copy() 306 for i, v := range tb.Data { 307 tb.Data[i] = math.Asin(v) 308 } 309 return tb 310 } 311 312 func Asinh(b *Arrf) *Arrf { 313 var tb = b.Copy() 314 for i, v := range tb.Data { 315 tb.Data[i] = math.Asinh(v) 316 } 317 return tb 318 } 319 320 func Tan(b *Arrf) *Arrf { 321 var tb = b.Copy() 322 for i, v := range tb.Data { 323 tb.Data[i] = math.Tan(v) 324 } 325 return tb 326 } 327 328 func Tanh(b *Arrf) *Arrf { 329 var tb = b.Copy() 330 for i, v := range tb.Data { 331 tb.Data[i] = math.Tanh(v) 332 } 333 return tb 334 } 335 336 func Atan(b *Arrf) *Arrf { 337 var tb = b.Copy() 338 for i, v := range tb.Data { 339 tb.Data[i] = math.Atan(v) 340 } 341 return tb 342 } 343 344 func Atanh(b *Arrf) *Arrf { 345 var tb = b.Copy() 346 for i, v := range tb.Data { 347 tb.Data[i] = math.Atanh(v) 348 } 349 return tb 350 } 351 352 func Add(a, b *Arrf) *Arrf { 353 return a.Add(b) 354 } 355 356 func Sub(a, b *Arrf) *Arrf { 357 return a.Sub(b) 358 } 359 360 func Mul(a, b *Arrf) *Arrf { 361 return a.Mul(b) 362 } 363 364 func Div(a, b *Arrf) *Arrf { 365 return a.Div(b) 366 } 367 368 func Pow(a, b *Arrf) *Arrf { 369 var t = ZerosLike(a) 370 for i, v := range a.Data { 371 t.Data[i] = math.Pow(v, b.Data[i]) 372 } 373 return t 374 } 375 376 func Maximum(a, b *Arrf) *Arrf { 377 var t = a.Copy() 378 for i, v := range t.Data { 379 if v < b.Data[i] { 380 v = b.Data[i] 381 } 382 t.Data[i] = v 383 } 384 return t 385 } 386 387 func Minimum(a, b *Arrf) *Arrf { 388 var t = a.Copy() 389 for i, v := range t.Data { 390 if v > b.Data[i] { 391 v = b.Data[i] 392 } 393 t.Data[i] = v 394 } 395 return t 396 } 397 398 func Mod(a, b *Arrf) *Arrf { 399 var t = a.Copy() 400 for i, v := range t.Data { 401 t.Data[i] = math.Mod(v, b.Data[i]) 402 } 403 return t 404 } 405 406 func CopySign(a, b *Arrf) *Arrf { 407 ta := Abs(a) 408 sign := Sign(b) 409 return ta.Mul(sign) 410 } 411 412 func Boardcast(a, b *Arrf) (*Arrf, *Arrf, error) { 413 if a.Ndims() < b.Ndims() { 414 return nil, nil, SHAPE_ERROR 415 } 416 var bNewShape []int 417 if a.Ndims() == b.Ndims() { 418 bNewShape = b.Shape 419 } else { 420 bNewShape = make([]int, len(a.Shape)) 421 for i := range bNewShape { 422 bNewShape[i] = 1 423 } 424 copy(bNewShape[len(a.Shape)-len(b.Shape):], b.Shape) 425 } 426 427 var aChangeIndex = make([]int, 0) 428 var aChangeNum = make([]int, 0) 429 var bChangeIndex = make([]int, 0) 430 var bChangeNum = make([]int, 0) 431 for i := range bNewShape { 432 if a.Shape[i] == bNewShape[i] { 433 continue 434 } else if a.Shape[i] == 1 { 435 aChangeIndex = append(aChangeIndex, i) 436 aChangeNum = append(aChangeNum, bNewShape[i]) 437 } else if bNewShape[i] == 1 { 438 bChangeIndex = append(bChangeIndex, i) 439 bChangeNum = append(bChangeNum, a.Shape[i]) 440 } else { 441 return nil, nil, SHAPE_ERROR 442 } 443 } 444 445 var aNew, bNew *Arrf 446 if len(aChangeNum) == 0 { 447 aNew = a 448 } else { 449 var baseNum = a.Length() 450 var expandTimes = ProductIntSlice(aChangeNum) 451 var expandData = make([]float64, baseNum*expandTimes) 452 for i := 0; i < expandTimes; i++ { 453 copy(expandData[i*baseNum:(i+1)*baseNum], a.Data) 454 } 455 var newPos = make([]int, len(aChangeIndex), len(a.Shape)) 456 var expandShape = make([]int, len(aChangeNum), len(a.Shape)) 457 copy(newPos, aChangeIndex) 458 copy(expandShape, aChangeNum) 459 for i := range a.Shape { 460 if !ContainsInt(aChangeIndex, i) { 461 newPos = append(newPos, i) 462 expandShape = append(expandShape, a.Shape[i]) 463 } 464 } 465 aNew = Array(expandData, expandShape...).Transpose(newPos...) 466 } 467 468 if len(bChangeNum) == 0 { 469 bNew = b 470 } else { 471 var baseNum = b.Length() 472 var expandTimes = ProductIntSlice(bChangeNum) 473 var expandData = make([]float64, baseNum*expandTimes) 474 for i := 0; i < expandTimes; i++ { 475 copy(expandData[i*baseNum:(i+1)*baseNum], b.Data) 476 } 477 var newPos = make([]int, len(bChangeIndex), len(bNewShape)) 478 var expandShape = make([]int, len(bChangeNum), len(bNewShape)) 479 copy(newPos, bChangeIndex) 480 copy(expandShape, bChangeNum) 481 for i := range bNewShape { 482 if !ContainsInt(bChangeIndex, i) { 483 newPos = append(newPos, i) 484 expandShape = append(expandShape, bNewShape[i]) 485 } 486 } 487 bNew = Array(expandData, expandShape...).Transpose(newPos...) 488 } 489 490 return aNew, bNew, nil 491 }