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  }