calculate.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. package utils
  2. import (
  3. "fmt"
  4. "github.com/gonum/stat"
  5. "github.com/shopspring/decimal"
  6. "math"
  7. "strings"
  8. )
  9. type Series []Coordinate
  10. type Coordinate struct {
  11. X, Y float64
  12. }
  13. func GetLinearResult(s []Coordinate) (gradient, intercept float64) {
  14. if len(s) <= 1 {
  15. return
  16. }
  17. var sum [5]float64
  18. i := 0
  19. for ; i < len(s); i++ {
  20. sum[0] += s[i].X
  21. sum[1] += s[i].Y
  22. sum[2] += s[i].X * s[i].X
  23. sum[3] += s[i].X * s[i].Y
  24. sum[4] += s[i].Y * s[i].Y
  25. }
  26. f := float64(i)
  27. gradient = (f*sum[3] - sum[0]*sum[1]) / (f*sum[2] - sum[0]*sum[0])
  28. intercept = (sum[1] / f) - (gradient * sum[0] / f)
  29. return
  30. }
  31. func CalculateCorrelationByIntArr(xArr, yArr []float64) (ratio float64) {
  32. xLen := float64(len(xArr))
  33. yLen := float64(len(yArr))
  34. if xLen == 0 || xLen != yLen {
  35. return
  36. }
  37. var Xa, Ya float64
  38. for i := range xArr {
  39. Xa += xArr[i]
  40. }
  41. Mx := Xa / xLen
  42. for i := range yArr {
  43. Ya += yArr[i]
  44. }
  45. My := Ya / yLen
  46. var Xb, Yb, SDx, SDy float64
  47. for i := range xArr {
  48. Xb += (xArr[i] - Mx) * (xArr[i] - Mx)
  49. }
  50. SDx = math.Sqrt(1 / (xLen - 1) * Xb)
  51. for i := range yArr {
  52. Yb += (yArr[i] - My) * (yArr[i] - My)
  53. }
  54. SDy = math.Sqrt(1 / (yLen - 1) * Yb)
  55. var Nume, Deno float64
  56. for i := 0; i < int(xLen); i++ {
  57. Nume += (xArr[i] - Mx) * (yArr[i] - My)
  58. }
  59. Deno = (xLen - 1) * (SDx * SDy)
  60. ratio = Nume / Deno
  61. if math.IsNaN(ratio) {
  62. ratio = 0
  63. }
  64. return
  65. }
  66. func ComputeCorrelation(sList []Coordinate) (r float64) {
  67. var xBar, yBar float64
  68. lenSList := len(sList)
  69. if lenSList < 2 {
  70. return
  71. }
  72. decimalX := decimal.NewFromFloat(0)
  73. decimalY := decimal.NewFromFloat(0)
  74. for _, coordinate := range sList {
  75. decimalX = decimalX.Add(decimal.NewFromFloat(coordinate.X))
  76. decimalY = decimalY.Add(decimal.NewFromFloat(coordinate.Y))
  77. }
  78. xBar, _ = decimalX.Div(decimal.NewFromInt(int64(lenSList))).Round(4).Float64()
  79. yBar, _ = decimalY.Div(decimal.NewFromInt(int64(lenSList))).Round(4).Float64()
  80. varXDeci := decimal.NewFromFloat(0)
  81. varYDeci := decimal.NewFromFloat(0)
  82. ssrDeci := decimal.NewFromFloat(0)
  83. for _, coordinate := range sList {
  84. diffXXbarDeci := decimal.NewFromFloat(coordinate.X).Sub(decimal.NewFromFloat(xBar))
  85. diffYYbarDeci := decimal.NewFromFloat(coordinate.Y).Sub(decimal.NewFromFloat(yBar))
  86. ssrDeci = ssrDeci.Add(diffXXbarDeci.Mul(diffYYbarDeci))
  87. varXDeci = varXDeci.Add(diffXXbarDeci.Mul(diffXXbarDeci))
  88. varYDeci = varYDeci.Add(diffYYbarDeci.Mul(diffYYbarDeci))
  89. }
  90. if varXDeci.IsZero() && varYDeci.IsZero() {
  91. r = 1
  92. return
  93. }
  94. sqrtVal, _ := varXDeci.Mul(varYDeci).Round(4).Float64()
  95. sst := math.Sqrt(sqrtVal) // 平方根
  96. if sst == 0 {
  97. return
  98. }
  99. r, _ = ssrDeci.Div(decimal.NewFromFloat(sst)).Round(4).Float64()
  100. return
  101. }
  102. func CalculationDecisive(sList []Coordinate) (r2 float64) {
  103. r := ComputeCorrelation(sList)
  104. r2, _ = decimal.NewFromFloat(r).Mul(decimal.NewFromFloat(r)).Round(4).Float64()
  105. return
  106. }
  107. func CalculateStandardDeviation(data []float64) float64 {
  108. return stat.StdDev(data, nil)
  109. }
  110. func ReplaceFormula(valArr map[string]float64, formulaStr string) string {
  111. funMap := getFormulaMap()
  112. for k, v := range funMap {
  113. formulaStr = strings.Replace(formulaStr, k, v, -1)
  114. }
  115. replaceCount := 0
  116. for tag, val := range valArr {
  117. dvStr := fmt.Sprintf("%v", val)
  118. formulaStr = strings.Replace(formulaStr, tag, dvStr, -1)
  119. replaceCount++
  120. }
  121. for k, v := range funMap {
  122. formulaStr = strings.Replace(formulaStr, v, k, -1)
  123. }
  124. return formulaStr
  125. }
  126. type CellPosition struct {
  127. Tag string
  128. Row int
  129. Value float64
  130. }
  131. func ReplaceFormulaByCellList(cellList []CellPosition, formulaStr string) string {
  132. funMap := getFormulaMap()
  133. for k, v := range funMap {
  134. formulaStr = strings.Replace(formulaStr, k, v, -1)
  135. }
  136. replaceCount := 0
  137. for _, cell := range cellList {
  138. dvStr := fmt.Sprintf("%v", cell.Value)
  139. formulaStr = strings.Replace(formulaStr, fmt.Sprint(cell.Tag, cell.Row), dvStr, -1)
  140. replaceCount++
  141. }
  142. for k, v := range funMap {
  143. formulaStr = strings.Replace(formulaStr, v, k, -1)
  144. }
  145. return formulaStr
  146. }
  147. func getFormulaMap() map[string]string {
  148. funMap := make(map[string]string)
  149. funMap["MAX"] = "[@@]"
  150. funMap["MIN"] = "[@!]"
  151. funMap["ABS"] = "[@#]"
  152. funMap["CEIL"] = "[@$]"
  153. funMap["COS"] = "[@%]"
  154. funMap["FLOOR"] = "[@^]"
  155. funMap["MOD"] = "[@&]"
  156. funMap["POW"] = "[@*]"
  157. funMap["ROUND"] = "[@(]"
  158. return funMap
  159. }