// Creates the features from the inputs. Features must be nSamples x nFeatures or nil func FeaturizeTrainable(t Trainable, inputs common.RowMatrix, featurizedInputs *mat64.Dense) *mat64.Dense { nSamples, nDim := inputs.Dims() if featurizedInputs == nil { nFeatures := t.NumFeatures() featurizedInputs = mat64.NewDense(nSamples, nFeatures, nil) } rowViewer, isRowViewer := inputs.(mat64.RowViewer) var f func(start, end int) if isRowViewer { f = func(start, end int) { featurizer := t.NewFeaturizer() for i := start; i < end; i++ { featurizer.Featurize(rowViewer.RowView(i), featurizedInputs.RowView(i)) } } } else { f = func(start, end int) { featurizer := t.NewFeaturizer() input := make([]float64, nDim) for i := start; i < end; i++ { inputs.Row(input, i) featurizer.Featurize(input, featurizedInputs.RowView(i)) } } } common.ParallelFor(nSamples, common.GetGrainSize(nSamples, minGrain, maxGrain), f) return featurizedInputs }
// UnscaleData is a wrapper for unscaling data in parallel. // TODO: Make this work better so that if there is an error somewhere data isn't changed func UnscaleData(scaler Scaler, data *mat64.Dense) error { m := &sync.Mutex{} var e ErrorList f := func(start, end int) { for r := start; r < end; r++ { errTmp := scaler.Unscale(data.RowView(r)) if errTmp != nil { m.Lock() e = append(e, &SliceError{Header: "scale", Idx: r, Err: errTmp}) m.Unlock() } } } nSamples, _ := data.Dims() grain := common.GetGrainSize(nSamples, 1, 500) common.ParallelFor(nSamples, grain, f) if len(e) != 0 { return e } return nil }