params

package
v2.0.0-dev0.1.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 19, 2026 License: BSD-3-Clause Imports: 12 Imported by: 34

README

Docs: GoDoc

See Wiki Params page for detailed docs.

Package params applies parameters to struct fields using css selectors to select which objects a given set of parameters applies to. The struct type must implement the Styler interface, with StyleName() string and StyleClass() string methods, which provide the name and class values against which the selectors test.

Parameters are set using a closure function that runs on matching objects, so that any type value can be set using full editor completion for accessing the struct fields, and any additional logic can be applied within the closure function, including parameter search functions.

Three levels of organization are supported:

  • Sheets is a map of named Sheets, typically with a "Base" Sheet that is applied first, and contains all the base-level defaults, and then different optional parameter Sheets for different configurations or test cases being explored.

  • Sheet is an ordered list (slice) of Sel elements, applied in order. The ordering is critical for organizing parameters into broad defaults that apply more generally, which are put at the start, followed by progressively more specific parameters that override those defaults for specific cases as needed.

  • Sel is an individual selector with an expression that matches on Name, Class or Type (Type can be left blank as the entire stack applies only to a specific type of object), and the Set function that sets the parameter values on matching objects.

TODO: replace with actual example from axon:

var LayerParams = axon.LayerSheets{
	"Base": {
		{Sel: "Layer", Doc: "all defaults",
			Set: func(ly *axon.LayerParams) {
				ly.Inhib.Layer.Gi = 1.05                     // 1.05 > 1.1 for short-term; 1.1 better long-run stability
				ly.Inhib.Layer.FB = 0.5                      // 0.5 > 0.2 > 0.1 > 1.0 -- usu 1.0
				ly.Inhib.ActAvg.Nominal = 0.06               // 0.6 > 0.5
				ly.Acts.NMDA.MgC = 1.2                       // 1.2 > 1.4 here, still..
				ly.Learn.RLRate.SigmoidLinear.SetBool(false) // false > true here
			}},
	},
}

In summary, the overall logic is all about the order of application, going from broad defaults to more specific overrides, with the following overall ordering:

  • A Defaults() method defined on the struct type, which establishes hard-coded default parameters.
  • The "Base" Sheet applies default parameters for a specific simulation, relative to hard-coded defaults.
  • Other Sheet cases defined in the map of Sheets can then optionally be applied with various experiments, parameter searches, or other specific cases.
  • Order of Sels within within a given Sheet is also critical, with the most general Type params first, then .Class, then the most specific #Name cases. For example, an overall learning rate that applies across all pathways with a Type sel, but then a slower one is needed for a for a .Class or specific #Name'd pathway.

Selectors

The Sel field of the Sel specifies a CSS-style selector determining over what scope the parameters should be applied:

  • .Class = anything with a given class label (each object can have multiple Class labels and thus receive multiple parameter settings, but again, order matters!)

  • #Name = a specific named object.

  • Type (no prefix) = name of a type -- because parameters only apply to a specific type of object, this can typically just be left blank.

There is a params.Styler interface with methods that any Go type can implement to provide these different labels.

Parameter Searching

TODO

Documentation

Overview

Package params provides general-purpose parameter management functionality for organizing multiple sets of parameters efficiently, and basic IO for saving / loading from JSON files and generating Go code to embed into applications, and a basic GUI for viewing and editing.

The main overall unit that is generally operated upon at run-time is the params.Set, which is a collection of params.Sheet's (akin to CSS style sheets) that constitute a coherent set of parameters.

A good strategy is to have a "Base" Set that has all the best parameters so far, and then other sets can modify specific params relative to that one. Order of application is critical, as subsequent params applications overwrite earlier ones, and the typical order is:

  • Defaults() method called that establishes the hard-coded default parameters.
  • Then apply "Base" params.Set for any changes relative to those.
  • Then optionally apply one or more additional params.Set's with current experimental parameters.

Critically, all of this is entirely up to the particular model program(s) to determine and control -- this package just provides the basic data structures for holding all of the parameters, and the IO / and Apply infrastructure.

Within a params.Set, multiple different params.Sheet's can be organized, with each CSS-style sheet achieving a relatively complete parameter styling of a given element of the overal model, e.g., "Network", "Sim", "Env". Or Network could be further broken down into "Learn" vs. "Act" etc, or according to different brain areas ("Hippo", "PFC", "BG", etc). Again, this is entirely at the discretion of the modeler and must be performed under explict program control, especially because order is so critical.

Each params.Sheet consists of a collection of params.Sel elements which actually finally contain the parameters. The Sel field specifies a CSS-style selector determining over what scope the parameters should be applied:

* Type = name of a type -- anything having this type name will get these params.

* .Class = anything with a given class label (each object can have multiple Class labels and thus receive multiple parameter settings, but again, order matters!)

* #Name = a specific named object.

The order of application within a given Sheet is also critical -- typically put the most general Type params first, then .Class, then the most specific #Name cases, to achieve within a given Sheet the same logic of establishing Base params for all types and then more specific overrides for special cases (e.g., an overall learning rate that appplies across all pathways, but maybe a faster or slower one for a .Class or specific #Name'd pathway).

There is a params.Styler interface with methods that any Go type can implement to provide these different labels. The emer.Network, .Layer, and .Path interfaces each implement this interface.

Otherwise, the Apply method will just directly apply params to a given struct type if it does not implement the Styler interface.

Parameter values are limited to float64 values *only*. These can be specified using "enum" style const integer values, and can be applied to any numeric type (they will be automatically converted), but internally this is the only parameter value type, which greatly simplifies the overall interface, and handles the vast majority of use-cases (especially because named options are just integers and can be set as such).

Finally, there are methods to show where params.Set's set the same parameter differently, and to compare with the default settings on a given object type using go struct field tags of the form default:"val1[,val2...]".

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AddClass

func AddClass(cur string, class ...string) string

AddClass is a helper function that adds given class(es) to current class string, ensuring it is not a duplicate of existing, and properly adding spaces.

func ClassMatch

func ClassMatch(sel, cls string) bool

ClassMatch returns true if given class names match. Handles space-separated multiple class names.

func PrintStruct

func PrintStruct(v any, indent int,
	filter func(path string, ft reflect.StructField, fv any) bool,
	format func(path string, ft reflect.StructField, fv any) string) string

PrintStruct returns a string representation of a struct for printing out parameter values. It uses standard Cogent Core display tags to produce results that resemble the GUI interface, and only includes exported fields. The optional filter function determines whether a field is included, based on the full path to the field (using . separators) and the field value. Indent provides the starting indent level (2 spaces). The optional format function returns a string representation of the value, if you want to override the default, which just uses reflectx.ToString (returning an empty string means use the default).

func SelMatch

func SelMatch[T Styler](sel string, obj T) bool

SelMatch returns true if Sel selector matches the target object properties.

func Tweak

func Tweak(v float32, typ TweakTypes) []float32

Tweak returns parameter Search values to try, below and above the given value. Log: use the quasi-log scheme: 1, 2, 5, 10 etc. Only if val is one of these vals. Increment: use increments around current value: e.g., if .5, returns .4 and .6. These apply to the 2nd significant digit (remainder after most significant digit) if that is present in the original value.

func TweakPct

func TweakPct(v, pct float32) []float32

TweakPct returns parameter Search values to try, as given given percent below and above the given value.

Types

type Search[T Styler] struct {
	// Sel is the selector for what to apply the parameters to,
	// using standard css selector syntax:
	//	- .Example applies to anything with a Class tag of 'Example'
	//	- #Example applies to anything with a Name of 'Example'
	//	- Example with no prefix or blank selector always applies as the presumed Type.
	Sel string

	// Set function applies given parameter value to the given object
	// of the target type.
	Set func(v T, val float32)

	// Vals is a function that generates values to search over. This is
	// typically called once at the start of the entire search process to get
	// a list of values that are cached, to determine the total number of search
	// jobs required, and then it is called again when this parameter is at the
	// top of the list to be searched, so that new values can potentially be
	// generated.
	Vals func() []float32
	// contains filtered or unexported fields
}

Search represents one parameter search element, applying given selector to objects of given type, using float32 values generated by given function.

func (*Search[T]) Apply

func (ps *Search[T]) Apply(obj T, val float32) bool

Apply checks if Sel selector applies to this object according to (.Class, #Name, Type) using the Styler interface, and returns false if it does not. If it does apply, then the given value is passed to the Set function on the object, and true is returned.

func (*Search[T]) CacheValues

func (ps *Search[T]) CacheValues() []float32

CacheValues calls the Vals function and caches the resulting values for later use. This can be called for dynamic searches to update the current values relative to any initial cached values, if the search is dynamic and depends on other state. Returns the updated cached values.

func (*Search[T]) JobString

func (ps *Search[T]) JobString(paramIndex int, val float32) string

JobString returns a string that identifies a param search job for given parameter index and value, for this item.

func (*Search[T]) Value

func (ps *Search[T]) Value(valIndex int) (bool, float32)

Value returns the parameter value at given value index. Returns false if the value index is invalid.

func (*Search[T]) Values

func (ps *Search[T]) Values() []float32

Values returns the search values, using cached values if already set, and returning Search.CacheValues otherwise.

type Searches

type Searches[T Styler] []*Search[T]

Searches is a list of Search elements, representing an entire parameter search process, where multiple parameters with multiple values per parameter are searched, typically in parallel across independent sim run jobs. Thus, you first get the total number of params via the Searches.NumParams method, and then launch jobs for each of these param indexes, which applies that param.

func (Searches[T]) NumParams

func (sr Searches[T]) NumParams() int

NumParams returns the total number of parameter values to search. This calls the Vals function to generate initial search values.

func (Searches[T]) SearchAtIndex

func (sr Searches[T]) SearchAtIndex(paramIndex int) (*Search[T], int)

SearchAtIndex returns the Search element at given parameter index in range [0..NumParams), and the value index within that search.

func (Searches[T]) SearchValue

func (sr Searches[T]) SearchValue(paramIndex int) (*Search[T], float32, string, error)

SearchValue returns Search and value for parameter at given param index within searches, returning error for invalid index. Also returns string descriptor for parameter.

type Sel

type Sel[T Styler] struct {

	// Sel is the selector for what to apply the parameters to,
	// using standard css selector syntax:
	//	- .Example applies to anything with a Class tag of 'Example'
	//	- #Example applies to anything with a Name of 'Example'
	//	- Example with no prefix or blank selector always applies as the presumed Type.
	Sel string `width:"30"`

	// Doc is documentation of these parameter values: what effect
	// do they have? what range was explored? It is valuable to record
	// this information as you explore the params.
	Doc string `width:"60"`

	// Set function applies parameter values to the given object of the target type.
	Set func(v T) `display:"-"`

	// NMatch is the number of times this selector matched a target
	// during the last Apply process. A warning is issued for any
	// that remain at 0: See Sheet SelMatchReset and SelNoMatchWarn methods.
	NMatch int `table:"-" toml:"-" json:"-" xml:"-" edit:"-"`
}

Sel specifies a selector for the scope of application of a set of parameters, using standard css selector syntax (. prefix = class, # prefix = name, and no prefix = type). Type always matches, and generally should come first as an initial set of defaults.

func (*Sel[T]) Apply

func (ps *Sel[T]) Apply(obj T) bool

Apply checks if Sel selector applies to this object according to (.Class, #Name, Type) using the Styler interface, and returns false if it does not. If it does apply, then the Set function is called on the object.

type Sheet

type Sheet[T Styler] []*Sel[T]

Sheet is a CSS-like style-sheet of params.Sel values, each of which represents a different set of specific parameter values applied according to the Sel selector: .Class #Name or Type.

The order of elements in the Sheet list is critical, as they are applied in the order given by the list (slice), and thus later Sel's can override those applied earlier. Generally put more general Type-level parameters first, and then subsequently more specific ones (.Class and #Name).

func NewSheet

func NewSheet[T Styler]() *Sheet[T]

NewSheet returns a new Sheet for given type.

func (*Sheet[T]) Apply

func (ps *Sheet[T]) Apply(obj T) bool

Apply applies entire sheet to given object, using Sel's in order. returns true if any Sel's applied, and error if any errors.

func (*Sheet[T]) ElemLabel

func (sh *Sheet[T]) ElemLabel(idx int) string

ElemLabel satisfies the core.SliceLabeler interface to provide labels for slice elements.

func (*Sheet[T]) SelByName

func (sh *Sheet[T]) SelByName(sel string) (*Sel[T], error)

SelByName returns given selector within the Sheet, by Name. Returns and logs error if not found.

func (*Sheet[T]) SelMatchReset

func (ps *Sheet[T]) SelMatchReset()

SelMatchReset resets the Sel.NMatch counter used to find cases where no Sel matched any target objects. Call at start of application process, which may be at an outer-loop of Apply calls (e.g., for a Network, Apply is called for each Layer and Path), so this must be called separately. See SelNoMatchWarn for warning call at end.

func (*Sheet[T]) SelNoMatchWarn

func (ps *Sheet[T]) SelNoMatchWarn(sheetName, objName string) error

SelNoMatchWarn issues warning messages for any Sel selectors that had no matches during the last Apply process -- see SelMatchReset. The sheetName and objName provide info about the Sheet and obj being applied. Returns an error message with the non-matching sets if any, else nil.

type Sheets

type Sheets[T Styler] map[string]*Sheet[T]

Sheets are named collections of Sheet elements that can be chosen among depending on different desired configurations. Conventionally, there is always a Base configuration with basic-level defaults, and then any number of more specific sets to apply after that.

func (*Sheets[T]) SheetByName

func (ps *Sheets[T]) SheetByName(name string) (*Sheet[T], error)

SheetByName tries to find given set by name. Returns and logs error if not found.

type Styler

type Styler interface {
	// StyleClass returns the space-separated list of class selectors (tags).
	// Parameters with a . prefix target class tags.
	// Do NOT include the . in the Class tags on Styler objects;
	// The . is only used in the Sel selector on the [Sel].
	StyleClass() string

	// StyleName returns the name of this object.
	// Parameters with a # prefix target object names, which are typically
	// unique. Do NOT include the # prefix in the actual object name,
	// which is only present in the Sel selector on [Sel].
	StyleName() string
}

Styler must be implemented by any object that parameters are applied to, to provide the .Class and #Name selector functionality.

type TweakTypes

type TweakTypes int32 //enums:enum

TweakTypes are the types of param tweak logic supported.

const (
	// Increment increments around current value, e.g., if .5, generates .4 and .6
	Increment TweakTypes = iota

	// Log uses the quasi-log scheme: 1, 2, 5, 10 etc, which only applies if value
	// is one of those numbers.
	Log
)
const TweakTypesN TweakTypes = 2

TweakTypesN is the highest valid value for type TweakTypes, plus one.

func TweakTypesValues

func TweakTypesValues() []TweakTypes

TweakTypesValues returns all possible values for the type TweakTypes.

func (TweakTypes) Desc

func (i TweakTypes) Desc() string

Desc returns the description of the TweakTypes value.

func (TweakTypes) Int64

func (i TweakTypes) Int64() int64

Int64 returns the TweakTypes value as an int64.

func (TweakTypes) MarshalText

func (i TweakTypes) MarshalText() ([]byte, error)

MarshalText implements the encoding.TextMarshaler interface.

func (*TweakTypes) SetInt64

func (i *TweakTypes) SetInt64(in int64)

SetInt64 sets the TweakTypes value from an int64.

func (*TweakTypes) SetString

func (i *TweakTypes) SetString(s string) error

SetString sets the TweakTypes value from its string representation, and returns an error if the string is invalid.

func (TweakTypes) String

func (i TweakTypes) String() string

String returns the string representation of this TweakTypes value.

func (*TweakTypes) UnmarshalText

func (i *TweakTypes) UnmarshalText(text []byte) error

UnmarshalText implements the encoding.TextUnmarshaler interface.

func (TweakTypes) Values

func (i TweakTypes) Values() []enums.Enum

Values returns all possible values for the type TweakTypes.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL