-
Notifications
You must be signed in to change notification settings - Fork 5
/
accuracy.go
91 lines (74 loc) · 2.01 KB
/
accuracy.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package oppai
import (
"math"
)
/* ------------------------------------------------------------- */
/* acc calc */
// Accuracy ...
type Accuracy struct {
// if N300 = -1 it will be calculated from the object count
N300, N100, N50, NMisses int
}
// Acc rounds to the closest amount of 300s, 100s, 50s for a given
/* accuracy percentage.
* @param nobjects the total number of hits (n300 + n100 + n50 +
* nmisses)
*/
func Acc(accPercent float64, nobjects, nmisses int) Accuracy {
var acc Accuracy
nmisses = min(nobjects, nmisses)
max300 := nobjects - nmisses
maxacc := (&Accuracy{
N300: max300,
NMisses: nmisses,
}).Value() * 100.0
accPercent = math.Max(0.0, math.Min(maxacc, accPercent))
/* just some black magic maths from wolfram alpha */
acc.N100 =
roundOppai(
-3.0 *
((accPercent*0.01-1.0)*float64(nobjects) +
float64(nmisses)) *
0.5)
if acc.N100 > max300 {
/* acc lower than all 100s, use 50s */
acc.N100 = 0
acc.N50 =
roundOppai(
-6.0 *
((accPercent*0.01-1.0)*float64(nobjects) +
float64(nmisses)) * 0.5)
acc.N50 = min(max300, acc.N50)
}
acc.N300 = nobjects - acc.N100 - acc.N50 - nmisses
return acc
}
/**
* @param nobjects the total number of hits (n300 + n100 + n50 +
* nmiss). if -1, n300 must have been set and
* will be used to deduce this value.
* @return the accuracy value (0.0-1.0)
*/
func (acc *Accuracy) value(nobjects int) float64 {
if nobjects < 0 && acc.N300 < 0 {
//panic("either nobjects or n300 must be specified")
}
n300x := acc.N300
if acc.N300 < 0 {
n300x = nobjects - acc.N100 - acc.N50 - acc.NMisses
}
if nobjects < 0 {
nobjects = n300x + acc.N100 + acc.N50 + acc.NMisses
}
if nobjects == 0 {
return 0
}
res := (float64(acc.N50)*50.0 +
float64(acc.N100)*100.0 +
float64(n300x)*300.0) /
(float64(nobjects) * 300.0)
return math.Max(0.0, math.Min(res, 1.0))
}
func (acc *Accuracy) Value() float64 {
return acc.value(-1)
}