Skip to content

Commit

Permalink
bgate variable access fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Randall C. O'Reilly committed Jul 12, 2020
1 parent 892c7a6 commit a4a66d8
Show file tree
Hide file tree
Showing 12 changed files with 362 additions and 271 deletions.
40 changes: 40 additions & 0 deletions bgate/dareceptors_string.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 1 addition & 24 deletions bgate/gp.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ import (
// GPLayer represents the dorsal matrisome MSN's that are the main
// Go / NoGo gating units in BG. D1R = Go, D2R = NoGo.
type GPLayer struct {
leabra.Layer
DA float32 `inactive:"+" desc:"dopamine value for this layer"`
Layer
}

var KiT_GPLayer = kit.Types.AddType(&GPLayer{}, leabra.LayerProps)
Expand Down Expand Up @@ -107,28 +106,6 @@ func (ly *GPLayer) Defaults() {
ly.UpdateParams()
}

// DALayer interface:

func (ly *GPLayer) GetDA() float32 { return ly.DA }
func (ly *GPLayer) SetDA(da float32) { ly.DA = da }

/*
// UnitValByIdx returns value of given PBWM-specific variable by variable index
// and flat neuron index (from layer or neuron-specific one).
func (ly *GPLayer) UnitValByIdx(vidx NeuronVars, idx int) float32 {
switch vidx {
case DA:
return ly.DA
}
return 0
}
*/

func (ly *GPLayer) InitActs() {
ly.Layer.InitActs()
ly.DA = 0
}

//////////////////////////////////////////////////////////////////////
// GPeInPrjn

Expand Down
12 changes: 0 additions & 12 deletions bgate/gpi.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,18 +53,6 @@ func (ly *GPiLayer) Defaults() {
ly.UpdateParams()
}

/*
// UnitValByIdx returns value of given PBWM-specific variable by variable index
// and flat neuron index (from layer or neuron-specific one).
func (ly *GPiLayer) UnitValByIdx(vidx NeuronVars, idx int) float32 {
switch vidx {
case DA:
return ly.DA
}
return 0
}
*/

// Build constructs the layer state, including calling Build on the projections
// you MUST have properly configured the Inhib.Pool.On setting by this point
// to properly allocate Pools for the unit groups if necessary.
Expand Down
61 changes: 59 additions & 2 deletions bgate/layer.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,65 @@

package bgate

import (
"fmt"

"github.com/chewxy/math32"
"github.com/emer/leabra/leabra"
"github.com/goki/ki/kit"
)

// Layer is the base layer type for BGate framework.
// It has variables for the layer-level neuromodulatory variables: dopamine, ACh.
// Because the routines for accessing these variables are somewhat long
// Adds a dopamine variable to base Leabra layer type.
type Layer struct {
leabra.Layer
DA float32 `inactive:"+" desc:"dopamine value for this layer"`
}

var KiT_Layer = kit.Types.AddType(&Layer{}, leabra.LayerProps)

// DALayer interface:

func (ly *Layer) GetDA() float32 { return ly.DA }
func (ly *Layer) SetDA(da float32) { ly.DA = da }

// UnitVarIdx returns the index of given variable within the Neuron,
// according to UnitVarNames() list (using a map to lookup index),
// or -1 and error message if not found.
func (ly *Layer) UnitVarIdx(varNm string) (int, error) {
vidx, err := ly.Layer.UnitVarIdx(varNm)
if err == nil {
return vidx, err
}
if varNm != "DA" {
return -1, fmt.Errorf("bgate.NeuronVars: variable named: %s not found", varNm)
}
nn := len(leabra.NeuronVars)
return nn, nil
}

// UnitVal1D returns value of given variable index on given unit, using 1-dimensional index.
// returns NaN on invalid index.
// This is the core unit var access method used by other methods,
// so it is the only one that needs to be updated for derived layer types.
func (ly *Layer) UnitVal1D(varIdx int, idx int) float32 {
nn := len(leabra.NeuronVars)
if varIdx < 0 || varIdx > nn {
return math32.NaN()
}
if varIdx < nn {
return ly.Layer.UnitVal1D(varIdx, idx)
}
if idx < 0 || idx >= len(ly.Neurons) {
return math32.NaN()
}
if varIdx != nn {
return math32.NaN()
}
return ly.DA
}

func (ly *Layer) InitActs() {
ly.Layer.InitActs()
ly.DA = 0
}
65 changes: 46 additions & 19 deletions bgate/matrix.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
package bgate

import (
"fmt"
"strings"

"github.com/chewxy/math32"
"github.com/emer/leabra/leabra"
"github.com/goki/ki/kit"
)
Expand All @@ -26,10 +28,9 @@ func (mp *MatrixParams) Defaults() {
// MatrixLayer represents the dorsal matrisome MSN's that are the main
// Go / NoGo gating units in BG. D1R = Go, D2R = NoGo.
type MatrixLayer struct {
leabra.Layer
Layer
DaR DaReceptors `desc:"dominant type of dopamine receptor -- D1R for Go pathway, D2R for NoGo"`
Matrix MatrixParams `view:"inline" desc:"matrix parameters"`
DA float32 `inactive:"+" desc:"dopamine value for this layer"`
DALrn float32 `inactive:"+" desc:"effective learning dopamine value for this layer: reflects DaR and Gains"`
ACh float32 `inactive:"+" desc:"acetylcholine value from TAN tonically active neurons reflecting the absolute value of reward or CS predictions thereof -- used for resetting the trace of matrix learning"`
}
Expand Down Expand Up @@ -99,11 +100,6 @@ func (ly *MatrixLayer) Defaults() {
ly.UpdateParams()
}

// DALayer interface:

func (ly *MatrixLayer) GetDA() float32 { return ly.DA }
func (ly *MatrixLayer) SetDA(da float32) { ly.DA = da }

// AChLayer interface:

func (ly *MatrixLayer) GetACh() float32 { return ly.ACh }
Expand All @@ -123,18 +119,6 @@ func (ly *MatrixLayer) DALrnFmDA(da float32) float32 {
return da
}

/*
// UnitValByIdx returns value of given PBWM-specific variable by variable index
// and flat neuron index (from layer or neuron-specific one).
func (ly *MatrixLayer) UnitValByIdx(vidx NeuronVars, idx int) float32 {
switch vidx {
case DA:
return ly.DA
}
return 0
}
*/

func (ly *MatrixLayer) InitActs() {
ly.Layer.InitActs()
ly.DA = 0
Expand All @@ -149,3 +133,46 @@ func (ly *MatrixLayer) ActFmG(ltime *leabra.Time) {
ly.DALrn = ly.DALrnFmDA(ly.DA)
ly.Layer.ActFmG(ltime)
}

// UnitVarIdx returns the index of given variable within the Neuron,
// according to UnitVarNames() list (using a map to lookup index),
// or -1 and error message if not found.
func (ly *MatrixLayer) UnitVarIdx(varNm string) (int, error) {
vidx, err := ly.Layer.UnitVarIdx(varNm)
if err == nil {
return vidx, err
}
if !(varNm == "DALrn" || varNm == "ACh") {
return -1, fmt.Errorf("bgate.NeuronVars: variable named: %s not found", varNm)
}
nn := len(leabra.NeuronVars)
// nn = DA
if varNm == "DALrn" {
return nn + 1, nil
}
return nn + 2, nil
}

// UnitVal1D returns value of given variable index on given unit, using 1-dimensional index.
// returns NaN on invalid index.
// This is the core unit var access method used by other methods,
// so it is the only one that needs to be updated for derived layer types.
func (ly *MatrixLayer) UnitVal1D(varIdx int, idx int) float32 {
nn := len(leabra.NeuronVars)
if varIdx < 0 || varIdx > nn+2 { // nn = DA, nn+1 = DALrn, nn+2 = ACh
return math32.NaN()
}
if varIdx <= nn { //
return ly.Layer.UnitVal1D(varIdx, idx)
}
if idx < 0 || idx >= len(ly.Neurons) {
return math32.NaN()
}
if varIdx > nn+2 {
return math32.NaN()
}
if varIdx == nn+1 { // DALrn
return ly.DALrn
}
return ly.ACh
}
82 changes: 40 additions & 42 deletions bgate/matrix_trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
package bgate

import (
"fmt"

"github.com/chewxy/math32"
"github.com/emer/leabra/leabra"
"github.com/goki/mat32"
Expand All @@ -27,6 +29,17 @@ func (sy *TraceSyn) VarByName(varNm string) float32 {
return math32.NaN()
}

// VarByIndex returns synapse variable by index
func (sy *TraceSyn) VarByIndex(varIdx int) float32 {
switch varIdx {
case 0:
return sy.NTr
case 1:
return sy.Tr
}
return math32.NaN()
}

var TraceSynVars = []string{"NTr", "Tr"}

// Params for for trace-based learning in the MatrixTracePrjn.
Expand Down Expand Up @@ -178,55 +191,40 @@ func (pj *MatrixTracePrjn) DWt() {
///////////////////////////////////////////////////////////////////////////////
// SynVals

// SynVals sets values of given variable name for each synapse, using the natural ordering
// of the synapses (sender based for Leabra),
// into given float32 slice (only resized if not big enough).
// Returns error on invalid var name.
func (pj *MatrixTracePrjn) SynVals(vals *[]float32, varNm string) error {
_, err := leabra.SynapseVarByName(varNm)
// SynVarIdx returns the index of given variable within the synapse,
// according to *this prjn's* SynVarNames() list (using a map to lookup index),
// or -1 and error message if not found.
func (pj *MatrixTracePrjn) SynVarIdx(varNm string) (int, error) {
vidx, err := pj.Prjn.SynVarIdx(varNm)
if err == nil {
return pj.Prjn.SynVals(vals, varNm)
return vidx, err
}
ns := len(pj.TrSyns)
if *vals == nil || cap(*vals) < ns {
*vals = make([]float32, ns)
} else if len(*vals) < ns {
*vals = (*vals)[0:ns]
}
for i := range pj.TrSyns {
sy := &pj.TrSyns[i]
(*vals)[i] = sy.VarByName(varNm)
nn := len(leabra.SynapseVars)
switch varNm {
case "NTr":
return nn, nil
case "Tr":
return nn + 1, nil
}
return nil
return -1, fmt.Errorf("MatrixTracePrjn SynVarIdx: variable name: %v not valid", varNm)
}

// SynVal returns value of given variable name on the synapse
// between given send, recv unit indexes (1D, flat indexes).
// Returns math32.NaN() for access errors (see SynValTry for error message)
func (pj *MatrixTracePrjn) SynVal(varNm string, sidx, ridx int) float32 {
_, err := leabra.SynapseVarByName(varNm)
if err == nil {
return pj.Prjn.SynVal(varNm, sidx, ridx)
}
if !(varNm == "NTr" || varNm == "Tr") {
// SynVal1D returns value of given variable index (from SynVarIdx) on given SynIdx.
// Returns NaN on invalid index.
// This is the core synapse var access method used by other methods,
// so it is the only one that needs to be updated for derived layer types.
func (pj *MatrixTracePrjn) SynVal1D(varIdx int, synIdx int) float32 {
if varIdx < 0 || varIdx >= len(SynVarsAll) {
return math32.NaN()
}
rsi := pj.SynIdx(sidx, ridx)
if rsi < 0 {
return math32.NaN()
nn := len(leabra.SynapseVars)
if varIdx < nn {
return pj.Prjn.SynVal1D(varIdx, synIdx)
}
sy := &pj.TrSyns[rsi]
return sy.VarByName(varNm)
}

// SynValTry returns value of given variable name on the synapse
// between given send, recv unit indexes (1D, flat indexes).
// Returns error for access errors.
func (pj *MatrixTracePrjn) SynValTry(varNm string, sidx, ridx int) (float32, error) {
sv, err := pj.Prjn.SynValTry(varNm, sidx, ridx)
if err == nil {
return sv, err
if synIdx < 0 || synIdx >= len(pj.TrSyns) {
return math32.NaN()
}
sv = pj.SynVal(varNm, sidx, ridx)
return sv, nil
varIdx -= nn
sy := &pj.TrSyns[synIdx]
return sy.VarByIndex(varIdx)
}
Loading

0 comments on commit a4a66d8

Please sign in to comment.