/
data.go
110 lines (93 loc) · 2.89 KB
/
data.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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// Copyright (c) 2019, The Emergent Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package netview
import (
"github.com/emer/emergent/emer"
"github.com/goki/mat32"
)
// LayData maintains a record of all the data for a given layer
type LayData struct {
// the layer name
LayName string `desc:"the layer name"`
// cached number of units
NUnits int `desc:"cached number of units"`
// the full data, [Ring.Max][len(Vars)][MaxData][NUnits] in that order
Data []float32 `desc:"the full data, [Ring.Max][len(Vars)][MaxData][NUnits] in that order"`
// receiving projection data -- shared with SendPrjns
RecvPrjns []*PrjnData `desc:"receiving projection data -- shared with SendPrjns"`
// sending projection data -- shared with RecvPrjns
SendPrjns []*PrjnData `desc:"sending projection data -- shared with RecvPrjns"`
}
// AllocSendPrjns allocates Sending projections for given layer.
// does nothing if already allocated.
func (ld *LayData) AllocSendPrjns(ly emer.Layer) {
nsp := ly.NSendPrjns()
if len(ld.SendPrjns) == nsp {
for si := 0; si < ly.NSendPrjns(); si++ {
pj := ly.SendPrjn(si)
spd := ld.SendPrjns[si]
spd.Prjn = pj
}
return
}
ld.SendPrjns = make([]*PrjnData, nsp)
for si := 0; si < ly.NSendPrjns(); si++ {
pj := ly.SendPrjn(si)
pd := &PrjnData{Send: pj.SendLay().Name(), Recv: pj.RecvLay().Name(), Prjn: pj}
ld.SendPrjns[si] = pd
pd.Alloc()
}
}
// FreePrjns nils prjn data -- for NoSynDat
func (ld *LayData) FreePrjns() {
ld.RecvPrjns = nil
ld.SendPrjns = nil
}
// PrjnData holds display state for a projection
type PrjnData struct {
// name of sending layer
Send string `desc:"name of sending layer"`
// name of recv layer
Recv string `desc:"name of recv layer"`
// source projection
Prjn emer.Prjn `desc:"source projection"`
// synaptic data, by variable in SynVars and number of data points
SynData []float32 `desc:"synaptic data, by variable in SynVars and number of data points"`
}
// Alloc allocates SynData to hold number of variables * nsyn synapses.
// If already has capacity, nothing happens.
func (pd *PrjnData) Alloc() {
pj := pd.Prjn
nvar := pj.SynVarNum()
nsyn := pj.Syn1DNum()
nt := nvar * nsyn
if cap(pd.SynData) < nt {
pd.SynData = make([]float32, nt)
} else {
pd.SynData = pd.SynData[:nt]
}
}
// RecordData records synaptic data from given prjn.
// must use sender or recv based depending on natural ordering.
func (pd *PrjnData) RecordData(nd *NetData) {
pj := pd.Prjn
vnms := pj.SynVarNames()
nvar := pj.SynVarNum()
nsyn := pj.Syn1DNum()
for vi := 0; vi < nvar; vi++ {
vnm := vnms[vi]
si := vi * nsyn
sv := pd.SynData[si : si+nsyn]
pj.SynVals(&sv, vnm)
nvi := nd.SynVarIdxs[vnm]
mn := &nd.SynMinVar[nvi]
mx := &nd.SynMaxVar[nvi]
for _, vl := range sv {
if !mat32.IsNaN(vl) {
*mn = mat32.Min(*mn, vl)
*mx = mat32.Max(*mx, vl)
}
}
}
}