func (ft *FreqTable) Row() int {
	return ft.Table.Idxs[ft.Order[ft.Trial.Cur]]
}
Row returns the current row number in table, based on Sequential / perumuted Order and
already de-referenced through the IdxView's indexes to get the actual row in the table.
package env
import (
	"fmt"
	"log"
	"math"
	"github.com/emer/emergent/erand"
	"github.com/emer/etable/etable"
	"github.com/emer/etable/etensor"
)
type FreqTable struct {
	Nm         string          `desc:"name of this environment"`
	Dsc        string          `desc:"description of this environment"`
	Table      *etable.IdxView `desc:"this is an indexed view of the table with the set of patterns to output -- the indexes are used for the *sequential* view so you can easily sort / split / filter the patterns to be presented using this view -- we then add the random permuted Order on top of those if !sequential"`
	NSamples   float64         `desc:"number of samples to use in constructing the list of items to present according to frequency -- number per epoch ~ NSamples * Freq -- see RndSamp option"`
	RndSamp    bool            `desc:"if true, use random sampling of items NSamples times according to given Freq probability value -- otherwise just directly add NSamples * Freq items to the list"`
	Sequential bool            `desc:"present items from the table in sequential order (i.e., according to the indexed view on the Table)?  otherwise permuted random order.  All repetitions of given item will be sequential if Sequential"`
	Order      []int           `desc:"list of items to present, with repetitions -- updated every time through the list"`
	Run        Ctr             `view:"inline" desc:"current run of model as provided during Init"`
	Epoch      Ctr             `view:"inline" desc:"number of times through entire set of patterns"`
	Trial      Ctr             `view:"inline" desc:"current ordinal item in Table -- if Sequential then = row number in table, otherwise is index in Order list that then gives row number in Table"`
	TrialName  CurPrvString    `desc:"if Table has a Name column, this is the contents of that"`
	GroupName  CurPrvString    `desc:"if Table has a Group column, this is contents of that"`
	NameCol    string          `desc:"name of the Name column -- defaults to 'Name'"`
	GroupCol   string          `desc:"name of the Group column -- defaults to 'Group'"`
	FreqCol    string          `desc:"name of the Freq column -- defaults to 'Freq'"`
}
func (ft *FreqTable) Name() string { return ft.Nm }
func (ft *FreqTable) Desc() string { return ft.Dsc }
func (ft *FreqTable) Validate() error {
	if ft.Table == nil || ft.Table.Table == nil {
		return fmt.Errorf("env.FreqTable: %v has no Table set", ft.Nm)
	}
	if ft.Table.Table.NumCols() == 0 {
		return fmt.Errorf("env.FreqTable: %v Table has no columns -- Outputs will be invalid", ft.Nm)
	}
	_, err := ft.Table.Table.ColByNameTry(ft.FreqCol)
	if err != nil {
		return err
	}
	return nil
}
func (ft *FreqTable) Init(run int) {
	if ft.NameCol == "" {
		ft.NameCol = "Name"
	}
	if ft.GroupCol == "" {
		ft.GroupCol = "Group"
	}
	if ft.FreqCol == "" {
		ft.FreqCol = "Freq"
	}
	ft.Run.Scale = Run
	ft.Epoch.Scale = Epoch
	ft.Trial.Scale = Trial
	ft.Run.Init()
	ft.Epoch.Init()
	ft.Trial.Init()
	ft.Run.Cur = run
	ft.Sample()
	ft.Trial.Max = len(ft.Order)
	ft.Trial.Cur = -1  
}
func (ft *FreqTable) Sample() {
	if ft.NSamples <= 0 {
		ft.NSamples = 1
	}
	np := ft.Table.Len()
	if ft.Order == nil {
		ft.Order = make([]int, 0, int(math.Round(float64(np)*ft.NSamples)))
	} else {
		ft.Order = ft.Order[:0]
	}
	frqs := ft.Table.Table.ColByName(ft.FreqCol)
	for ri := 0; ri < np; ri++ {
		ti := ft.Table.Idxs[ri]
		frq := frqs.FloatVal1D(ti)
		if ft.RndSamp {
			n := int(ft.NSamples)
			for i := 0; i < n; i++ {
				if erand.BoolProb(frq, -1) {
					ft.Order = append(ft.Order, ri)
				}
			}
		} else {
			n := int(math.Round(ft.NSamples * frq))
			for i := 0; i < n; i++ {
				ft.Order = append(ft.Order, ri)
			}
		}
	}
	if !ft.Sequential {
		erand.PermuteInts(ft.Order)
	}
}