-
Notifications
You must be signed in to change notification settings - Fork 0
/
math.go
74 lines (65 loc) · 1.66 KB
/
math.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
package engine
import (
"fmt"
"github.com/mumax/3/cuda"
"github.com/mumax/3/data"
"github.com/mumax/3/util"
)
func init() {
DeclFunc("average", Average, "Average of space-dependent quantity")
DeclFunc("makeAvg", MakeAvg, "Make new quantity, average of argument")
DeclFunc("makeAvgRegion", MakeAvgRegion, "Make new quantity, average of argument in region")
}
type reduced struct {
doc
calc func() []float64
}
func newReduced(nComp int, name, unit string, calc func() []float64) *reduced {
return &reduced{Doc(nComp, name, unit), calc}
}
func (r *reduced) GetVec() []float64 {
return r.calc()
}
func MakeAvgRegion(s Getter, region int) *reduced {
name := fmt.Sprint("avg_", s.Name(), "_reg", region)
return newReduced(s.NComp(), name, s.Unit(), func() []float64 {
src, r := s.Get()
if r {
defer cuda.Recycle(src)
}
out := cuda.Buffer(s.NComp(), s.Mesh())
defer cuda.Recycle(out)
cuda.RegionSelect(out, src, regions.Gpu(), byte(region))
return avg(out)
})
}
func MakeAvg(s Getter) *reduced {
name := fmt.Sprint("avg_", s.Name())
return newReduced(s.NComp(), name, s.Unit(), func() []float64 {
full := Average(s)
for i := range full {
full[i] /= spaceFill
}
return full
})
}
// average in userspace XYZ order
// does not yet take into account volume.
// pass volume parameter, possibly nil?
func Average(s Getter) []float64 {
b, recycle := s.Get()
if recycle {
defer cuda.Recycle(b)
}
return avg(b)
}
// userspace average
func avg(b *data.Slice) []float64 {
nComp := b.NComp()
avg := make([]float64, nComp)
for i := range avg {
I := util.SwapIndex(i, nComp)
avg[i] = float64(cuda.Sum(b.Comp(I))) / float64(b.Mesh().NCell())
}
return avg
}