diff --git a/api_minmax.go b/api_minmax.go new file mode 100644 index 0000000..964df7d --- /dev/null +++ b/api_minmax.go @@ -0,0 +1,155 @@ +package tensor + +import "github.com/pkg/errors" + +func MinBetween(a, b interface{}, opts ...FuncOpt) (retVal Tensor, err error) { + var minbetweener MinBetweener + var oe standardEngine + var ok bool + switch at := a.(type) { + case Tensor: + oe = at.standardEngine() + switch bt := b.(type) { + case Tensor: + if !bt.Shape().IsScalar() && !at.Shape().IsScalar() { // non-scalar Tensor addition + if oe != nil { + return oe.MinBetween(at, bt, opts...) + } + if oe = bt.standardEngine(); oe != nil { + return oe.MinBetween(at, bt, opts...) + } + if minbetweener, ok = at.Engine().(MinBetweener); ok { + return minbetweener.MinBetween(at, bt, opts...) + } + if minbetweener, ok = bt.Engine().(MinBetweener); ok { + return minbetweener.MinBetween(at, bt, opts...) + } + return nil, errors.New("Neither engines of either operand support MinBetween") + + } else { // at least one of the operands is a scalar + var leftTensor bool + if !bt.Shape().IsScalar() { + leftTensor = false // a Scalar-Tensor * b Tensor + tmp := at + at = bt + bt = tmp + } else { + leftTensor = true // a Tensor * b Scalar-Tensor + } + + if oe != nil { + return oe.MinBetweenScalar(at, bt, leftTensor, opts...) + } + if oe = bt.standardEngine(); oe != nil { + return oe.MinBetweenScalar(at, bt, leftTensor, opts...) + } + if minbetweener, ok = at.Engine().(MinBetweener); ok { + return minbetweener.MinBetweenScalar(at, bt, leftTensor, opts...) + } + if minbetweener, ok = bt.Engine().(MinBetweener); ok { + return minbetweener.MinBetweenScalar(at, bt, leftTensor, opts...) + } + return nil, errors.New("Neither engines of either operand support MinBetween") + } + + default: + if oe != nil { + return oe.MinBetweenScalar(at, bt, true, opts...) + } + if minbetweener, ok = at.Engine().(MinBetweener); ok { + return minbetweener.MinBetweenScalar(at, bt, true, opts...) + } + return nil, errors.New("Operand A's engine does not support MinBetween") + } + default: + switch bt := b.(type) { + case Tensor: + if oe = bt.standardEngine(); oe != nil { + return oe.MinBetweenScalar(bt, at, false, opts...) + } + if minbetweener, ok = bt.Engine().(MinBetweener); ok { + return minbetweener.MinBetweenScalar(bt, at, false, opts...) + } + return nil, errors.New("Operand B's engine does not support MinBetween") + default: + return nil, errors.Errorf("Cannot perform MinBetween of %T and %T", a, b) + } + } + panic("Unreachable") +} + +func MaxBetween(a, b interface{}, opts ...FuncOpt) (retVal Tensor, err error) { + var maxbetweener MaxBetweener + var oe standardEngine + var ok bool + switch at := a.(type) { + case Tensor: + oe = at.standardEngine() + switch bt := b.(type) { + case Tensor: + if !bt.Shape().IsScalar() && !at.Shape().IsScalar() { // non-scalar Tensor addition + if oe != nil { + return oe.MaxBetween(at, bt, opts...) + } + if oe = bt.standardEngine(); oe != nil { + return oe.MaxBetween(at, bt, opts...) + } + if maxbetweener, ok = at.Engine().(MaxBetweener); ok { + return maxbetweener.MaxBetween(at, bt, opts...) + } + if maxbetweener, ok = bt.Engine().(MaxBetweener); ok { + return maxbetweener.MaxBetween(at, bt, opts...) + } + return nil, errors.New("Neither engines of either operand support MaxBetween") + + } else { // at least one of the operands is a scalar + var leftTensor bool + if !bt.Shape().IsScalar() { + leftTensor = false // a Scalar-Tensor * b Tensor + tmp := at + at = bt + bt = tmp + } else { + leftTensor = true // a Tensor * b Scalar-Tensor + } + + if oe != nil { + return oe.MaxBetweenScalar(at, bt, leftTensor, opts...) + } + if oe = bt.standardEngine(); oe != nil { + return oe.MaxBetweenScalar(at, bt, leftTensor, opts...) + } + if maxbetweener, ok = at.Engine().(MaxBetweener); ok { + return maxbetweener.MaxBetweenScalar(at, bt, leftTensor, opts...) + } + if maxbetweener, ok = bt.Engine().(MaxBetweener); ok { + return maxbetweener.MaxBetweenScalar(at, bt, leftTensor, opts...) + } + return nil, errors.New("Neither engines of either operand support MaxBetween") + } + + default: + if oe != nil { + return oe.MaxBetweenScalar(at, bt, true, opts...) + } + if maxbetweener, ok = at.Engine().(MaxBetweener); ok { + return maxbetweener.MaxBetweenScalar(at, bt, true, opts...) + } + return nil, errors.New("Operand A's engine does not support MaxBetween") + } + default: + switch bt := b.(type) { + case Tensor: + if oe = bt.standardEngine(); oe != nil { + return oe.MaxBetweenScalar(bt, at, false, opts...) + } + if maxbetweener, ok = bt.Engine().(MaxBetweener); ok { + return maxbetweener.MaxBetweenScalar(bt, at, false, opts...) + } + return nil, errors.New("Operand B's engine does not support MaxBetween") + default: + return nil, errors.Errorf("Cannot perform MaxBetween of %T and %T", a, b) + } + } + panic("Unreachable") +} diff --git a/defaultengine_minmax.go b/defaultengine_minmax.go new file mode 100644 index 0000000..56ac432 --- /dev/null +++ b/defaultengine_minmax.go @@ -0,0 +1,349 @@ +// Code generated by genlib2. DO NOT EDIT. + +package tensor + +import ( + "github.com/pkg/errors" + "gorgonia.org/tensor/internal/storage" +) + +var ( + _ MinBetweener = StdEng{} + _ MaxBetweener = StdEng{} +) + +func (e StdEng) MinBetween(a Tensor, b Tensor, opts ...FuncOpt) (retVal Tensor, err error) { + if err = binaryCheck(a, b, ordTypes); err != nil { + return nil, errors.Wrapf(err, "MinBetween failed") + } + + var reuse DenseTensor + var safe bool + if reuse, safe, _, _, _, err = handleFuncOpts(a.Shape(), a.Dtype(), a.DataOrder(), true, opts...); err != nil { + return nil, errors.Wrap(err, "Unable to handle funcOpts") + } + typ := a.Dtype().Type + var dataA, dataB, dataReuse *storage.Header + var ait, bit, iit Iterator + var useIter, swap bool + if dataA, dataB, dataReuse, ait, bit, iit, useIter, swap, err = prepDataVV(a, b, reuse); err != nil { + return nil, errors.Wrapf(err, "StdEng.MinBetween") + } + // check to see if anything needs to be created + if reuse == nil { + if swap { + reuse = NewDense(b.Dtype(), b.Shape().Clone(), WithEngine(e)) + } else { + reuse = NewDense(a.Dtype(), a.Shape().Clone(), WithEngine(e)) + } + dataReuse = reuse.hdr() + if useIter { + iit = IteratorFromDense(reuse) + } + } + + if useIter { + switch { + case !safe && reuse == nil: + err = e.E.MinBetweenIter(typ, dataA, dataB, ait, bit) + retVal = a + case safe && reuse != nil: + storage.CopyIter(typ, dataReuse, dataA, iit, ait) + ait.Reset() + iit.Reset() + err = e.E.MinBetweenIter(typ, dataReuse, dataB, iit, bit) + retVal = reuse + default: // safe && bool + panic("Unreachable") + } + return + } + + // standard + switch { + case !safe && reuse == nil: + err = e.E.MinBetween(typ, dataA, dataB) + retVal = a + case safe && reuse != nil: + storage.Copy(typ, dataReuse, dataA) + err = e.E.MinBetween(typ, dataReuse, dataB) + retVal = reuse + default: + panic("Unreachable") + } + return +} + +func (e StdEng) MaxBetween(a Tensor, b Tensor, opts ...FuncOpt) (retVal Tensor, err error) { + if err = binaryCheck(a, b, ordTypes); err != nil { + return nil, errors.Wrapf(err, "MaxBetween failed") + } + + var reuse DenseTensor + var safe bool + if reuse, safe, _, _, _, err = handleFuncOpts(a.Shape(), a.Dtype(), a.DataOrder(), true, opts...); err != nil { + return nil, errors.Wrap(err, "Unable to handle funcOpts") + } + typ := a.Dtype().Type + var dataA, dataB, dataReuse *storage.Header + var ait, bit, iit Iterator + var useIter, swap bool + if dataA, dataB, dataReuse, ait, bit, iit, useIter, swap, err = prepDataVV(a, b, reuse); err != nil { + return nil, errors.Wrapf(err, "StdEng.MaxBetween") + } + // check to see if anything needs to be created + if reuse == nil { + if swap { + reuse = NewDense(b.Dtype(), b.Shape().Clone(), WithEngine(e)) + } else { + reuse = NewDense(a.Dtype(), a.Shape().Clone(), WithEngine(e)) + } + dataReuse = reuse.hdr() + if useIter { + iit = IteratorFromDense(reuse) + } + } + + if useIter { + switch { + case !safe && reuse == nil: + err = e.E.MaxBetweenIter(typ, dataA, dataB, ait, bit) + retVal = a + case safe && reuse != nil: + storage.CopyIter(typ, dataReuse, dataA, iit, ait) + ait.Reset() + iit.Reset() + err = e.E.MaxBetweenIter(typ, dataReuse, dataB, iit, bit) + retVal = reuse + default: // safe && bool + panic("Unreachable") + } + return + } + + // standard + switch { + case !safe && reuse == nil: + err = e.E.MaxBetween(typ, dataA, dataB) + retVal = a + case safe && reuse != nil: + storage.Copy(typ, dataReuse, dataA) + err = e.E.MaxBetween(typ, dataReuse, dataB) + retVal = reuse + default: + panic("Unreachable") + } + return +} + +func (e StdEng) MinBetweenScalar(t Tensor, s interface{}, leftTensor bool, opts ...FuncOpt) (retVal Tensor, err error) { + if err = unaryCheck(t, ordTypes); err != nil { + return nil, errors.Wrapf(err, "MinBetween failed") + } + + if err = scalarDtypeCheck(t, s); err != nil { + return nil, errors.Wrap(err, "MinBetween failed") + } + + var reuse DenseTensor + var safe bool + if reuse, safe, _, _, _, err = handleFuncOpts(t.Shape(), t.Dtype(), t.DataOrder(), true, opts...); err != nil { + return nil, errors.Wrap(err, "Unable to handle funcOpts") + } + a := t + typ := t.Dtype().Type + var ait, bit, iit Iterator + var dataA, dataB, dataReuse, scalarHeader *storage.Header + var useIter, newAlloc bool + + if leftTensor { + if dataA, dataB, dataReuse, ait, iit, useIter, newAlloc, err = prepDataVS(t, s, reuse); err != nil { + return nil, errors.Wrapf(err, opFail, "StdEng.MinBetween") + } + scalarHeader = dataB + } else { + if dataA, dataB, dataReuse, bit, iit, useIter, newAlloc, err = prepDataSV(s, t, reuse); err != nil { + return nil, errors.Wrapf(err, opFail, "StdEng.MinBetween") + } + scalarHeader = dataA + } + + // check to see if anything needs to be created + if reuse == nil { + reuse = NewDense(a.Dtype(), a.Shape().Clone(), WithEngine(e)) + dataReuse = reuse.hdr() + if useIter { + iit = IteratorFromDense(reuse) + } + } + + if useIter { + switch { + case !safe && reuse == nil: + err = e.E.MinBetweenIter(typ, dataA, dataB, ait, bit) + retVal = a + case safe && reuse != nil && !leftTensor: + storage.CopyIter(typ, dataReuse, dataB, iit, bit) + bit.Reset() + iit.Reset() + err = e.E.MinBetweenIter(typ, dataA, dataReuse, ait, bit) + retVal = reuse + case safe && reuse != nil && leftTensor: + storage.CopyIter(typ, dataReuse, dataA, iit, ait) + ait.Reset() + iit.Reset() + err = e.E.MinBetweenIter(typ, dataReuse, dataB, iit, bit) + retVal = reuse + default: // safe && bool + panic("Unreachable") + } + if newAlloc { + freeScalar(scalarHeader.Raw) + } + returnHeader(scalarHeader) + return + } + + // handle special case where A and B have both len 1 + if len(dataA.Raw) == int(typ.Size()) && len(dataB.Raw) == int(typ.Size()) { + switch { + case safe && reuse != nil && leftTensor: + storage.Copy(typ, dataReuse, dataA) + err = e.E.MinBetween(typ, dataReuse, dataB) + retVal = reuse + return + case safe && reuse != nil && !leftTensor: + storage.Copy(typ, dataReuse, dataB) + err = e.E.MinBetween(typ, dataReuse, dataA) + retVal = reuse + return + } + } + // standard + switch { + case !safe && reuse == nil: + err = e.E.MinBetween(typ, dataA, dataB) + retVal = a + case safe && reuse != nil && leftTensor: + storage.Copy(typ, dataReuse, dataA) + err = e.E.MinBetween(typ, dataReuse, dataB) + retVal = reuse + case safe && reuse != nil && !leftTensor: + storage.Copy(typ, dataReuse, dataB) + err = e.E.MinBetween(typ, dataA, dataReuse) + retVal = reuse + default: + panic("Unreachable") + } + if newAlloc { + freeScalar(scalarHeader.Raw) + } + returnHeader(scalarHeader) + return +} + +func (e StdEng) MaxBetweenScalar(t Tensor, s interface{}, leftTensor bool, opts ...FuncOpt) (retVal Tensor, err error) { + if err = unaryCheck(t, ordTypes); err != nil { + return nil, errors.Wrapf(err, "MaxBetween failed") + } + + if err = scalarDtypeCheck(t, s); err != nil { + return nil, errors.Wrap(err, "MaxBetween failed") + } + + var reuse DenseTensor + var safe bool + if reuse, safe, _, _, _, err = handleFuncOpts(t.Shape(), t.Dtype(), t.DataOrder(), true, opts...); err != nil { + return nil, errors.Wrap(err, "Unable to handle funcOpts") + } + a := t + typ := t.Dtype().Type + var ait, bit, iit Iterator + var dataA, dataB, dataReuse, scalarHeader *storage.Header + var useIter, newAlloc bool + + if leftTensor { + if dataA, dataB, dataReuse, ait, iit, useIter, newAlloc, err = prepDataVS(t, s, reuse); err != nil { + return nil, errors.Wrapf(err, opFail, "StdEng.MaxBetween") + } + scalarHeader = dataB + } else { + if dataA, dataB, dataReuse, bit, iit, useIter, newAlloc, err = prepDataSV(s, t, reuse); err != nil { + return nil, errors.Wrapf(err, opFail, "StdEng.MaxBetween") + } + scalarHeader = dataA + } + + // check to see if anything needs to be created + if reuse == nil { + reuse = NewDense(a.Dtype(), a.Shape().Clone(), WithEngine(e)) + dataReuse = reuse.hdr() + if useIter { + iit = IteratorFromDense(reuse) + } + } + + if useIter { + switch { + case !safe && reuse == nil: + err = e.E.MaxBetweenIter(typ, dataA, dataB, ait, bit) + retVal = a + case safe && reuse != nil && !leftTensor: + storage.CopyIter(typ, dataReuse, dataB, iit, bit) + bit.Reset() + iit.Reset() + err = e.E.MaxBetweenIter(typ, dataA, dataReuse, ait, bit) + retVal = reuse + case safe && reuse != nil && leftTensor: + storage.CopyIter(typ, dataReuse, dataA, iit, ait) + ait.Reset() + iit.Reset() + err = e.E.MaxBetweenIter(typ, dataReuse, dataB, iit, bit) + retVal = reuse + default: // safe && bool + panic("Unreachable") + } + if newAlloc { + freeScalar(scalarHeader.Raw) + } + returnHeader(scalarHeader) + return + } + + // handle special case where A and B have both len 1 + if len(dataA.Raw) == int(typ.Size()) && len(dataB.Raw) == int(typ.Size()) { + switch { + case safe && reuse != nil && leftTensor: + storage.Copy(typ, dataReuse, dataA) + err = e.E.MaxBetween(typ, dataReuse, dataB) + retVal = reuse + return + case safe && reuse != nil && !leftTensor: + storage.Copy(typ, dataReuse, dataB) + err = e.E.MaxBetween(typ, dataReuse, dataA) + retVal = reuse + return + } + } + // standard + switch { + case !safe && reuse == nil: + err = e.E.MaxBetween(typ, dataA, dataB) + retVal = a + case safe && reuse != nil && leftTensor: + storage.Copy(typ, dataReuse, dataA) + err = e.E.MaxBetween(typ, dataReuse, dataB) + retVal = reuse + case safe && reuse != nil && !leftTensor: + storage.Copy(typ, dataReuse, dataB) + err = e.E.MaxBetween(typ, dataA, dataReuse) + retVal = reuse + default: + panic("Unreachable") + } + if newAlloc { + freeScalar(scalarHeader.Raw) + } + returnHeader(scalarHeader) + return +} diff --git a/dense_reduction_test.go b/dense_reduction_test.go index f83d0c6..b10e3ac 100644 --- a/dense_reduction_test.go +++ b/dense_reduction_test.go @@ -547,17 +547,3 @@ func TestDense_Min(t *testing.T) { _, err = T.Min(1000) assert.NotNil(err) } - -func TestSlicedSum(t *testing.T) { - T := New(WithShape(4, 4), WithBacking([]int{ - 1, 2, 3, 4, - 5, 6, 7, 8, - 1, 2, 3, 4, - 5, 6, 7, 8, - })) - s, _ := T.Slice(sli(1, 3), sli(1, 3)) - sum, _ := Sum(s) - if sum.Data().(int) != 18 { - t.Errorf("Expected the sum of %v to be 18. Got %v instead", s, sum) - } -} diff --git a/engine.go b/engine.go index 1ac8400..f4d7bd2 100644 --- a/engine.go +++ b/engine.go @@ -44,6 +44,8 @@ type standardEngine interface { Gter Gteer ElEqer + MinBetweener + MaxBetweener // Anything that returns interface{} cannot be added here because they will likely have additional // optimized versions of the functions for types. @@ -157,6 +159,20 @@ type Moder interface { ModScalar(a Tensor, b interface{}, leftTensor bool, opts ...FuncOpt) (Tensor, error) } +// MinBetweener is any engine that can perform an elementwise min=between. +type MinBetweener interface { + MinBetween(a, b Tensor, opts ...FuncOpt) (Tensor, error) + + MinBetweenScalar(a Tensor, b interface{}, leftTensor bool, opts ...FuncOpt) (Tensor, error) +} + +// MaxBetweener is any engine that can perform an elementwise ma b[i]{ + b[i] = a + } + } +} + +func MaxVS{{short . | title}}(a []{{asType .}}, b {{asType .}}){ + for i := range a { + if b > a[i]{ + a[i] = b + } + } +} +` + +// Iter Min/Max +const genericIterMinMaxRaw = `func MinIterSV{{short . | title}}(a {{asType .}}, b []{{asType .}}, bit Iterator) (err error){ + var i int + var validi bool + for { + if i, validi, err = bit.NextValidity(); err != nil{ + err = handleNoOp(err) + break + } + if validi { + if a < b[i] { + b[i] = a + } + } + } + return +} + +func MinIterVS{{short . | title}}(a []{{asType .}}, b {{asType .}}, ait Iterator) (err error){ + var i int + var validi bool + for { + if i, validi, err = ait.NextValidity(); err != nil{ + err = handleNoOp(err) + break + } + if validi { + if b < a[i] { + a[i] = b + } + } + } + return +} + +func VecMinIter{{short . | title}}(a , b []{{asType .}}, ait, bit Iterator) (err error){ + var i,j int + var validi ,validj bool + for { + if i, validi, err = ait.NextValidity(); err != nil{ + err = handleNoOp(err) + break + } + if j, validj, err = bit.NextValidity(); err != nil{ + err = handleNoOp(err) + break + } + if validi && validj { + if b[j] < a[i] { + a[i] = b[j] + } + } + } + return +} + + +func MaxIterSV{{short . | title}}(a {{asType .}}, b []{{asType .}}, bit Iterator) (err error){ + var i int + var validi bool + for { + if i, validi, err = bit.NextValidity(); err != nil{ + err = handleNoOp(err) + break + } + if validi { + if a > b[i] { + b[i] = a + } + } + } + return +} + +func MaxIterVS{{short . | title}}(a []{{asType .}}, b {{asType .}}, ait Iterator) (err error){ + var i int + var validi bool + for { + if i, validi, err = ait.NextValidity(); err != nil{ + err = handleNoOp(err) + break + } + if validi { + if b > a[i] { + a[i] = b + } + } + } + return +} + +func VecMaxIter{{short . | title}}(a , b []{{asType .}}, ait, bit Iterator) (err error){ + var i,j int + var validi, validj bool + for { + if i, validi, err = ait.NextValidity(); err != nil{ + err = handleNoOp(err) + break + } + if j, validj, err = bit.NextValidity(); err != nil{ + err = handleNoOp(err) + break + } + if validi && validj { + if b[j] > a[i] { + a[i] = b[j] + } + } + } + return +} + ` // scalar Min/Max @@ -413,6 +562,7 @@ const genericScalarMinMaxRaw = `func Min{{short .}}(a, b {{asType .}}) (c {{asTy return b } + func Max{{short .}}(a, b {{asType .}}) (c {{asType .}}) {if a > b { return a } @@ -421,13 +571,15 @@ func Max{{short .}}(a, b {{asType .}}) (c {{asType .}}) {if a > b { ` var ( - genericElMinMax *template.Template - genericMinMax *template.Template + genericElMinMax *template.Template + genericMinMax *template.Template + genericElMinMaxIter *template.Template ) func init() { genericElMinMax = template.Must(template.New("genericVecVecMinMax").Funcs(funcs).Parse(genericElMinMaxRaw)) genericMinMax = template.Must(template.New("genericMinMax").Funcs(funcs).Parse(genericScalarMinMaxRaw)) + genericElMinMaxIter = template.Must(template.New("genericIterMinMax").Funcs(funcs).Parse(genericIterMinMaxRaw)) } func generateMinMax(f io.Writer, ak Kinds) { @@ -438,4 +590,8 @@ func generateMinMax(f io.Writer, ak Kinds) { for _, k := range filter(ak.Kinds, isOrd) { genericMinMax.Execute(f, k) } + + for _, k := range filter(ak.Kinds, isOrd) { + genericElMinMaxIter.Execute(f, k) + } } diff --git a/genlib2/internaleng.go b/genlib2/internaleng.go index ee5f15c..6d07d32 100644 --- a/genlib2/internaleng.go +++ b/genlib2/internaleng.go @@ -308,6 +308,102 @@ func generateECmp(f io.Writer, kinds Kinds) { } } +/* MIN/MAX BETWEEN */ + +type InternalEngMinMaxBetween struct { + BinOp + Kinds []reflect.Kind + Iter bool +} + +func (fn *InternalEngMinMaxBetween) Name() string { + name := fn.BinOp.Name() + + switch { + case fn.Iter: + return fmt.Sprintf("%sBetweenIter", name) + default: + return name + "Between" + } +} + +func (fn *InternalEngMinMaxBetween) Signature() *Signature { + var paramNames []string + var paramTemplates []*template.Template + + switch { + case fn.Iter: + paramNames = []string{"t", "a", "b", "ait", "bit"} + paramTemplates = []*template.Template{reflectType, arrayType, arrayType, iteratorType, iteratorType} + default: + paramNames = []string{"t", "a", "b"} + paramTemplates = []*template.Template{reflectType, arrayType, arrayType} + } + return &Signature{ + Name: fn.Name(), + NameTemplate: plainName, + ParamNames: paramNames, + ParamTemplates: paramTemplates, + + Err: true, + } +} + +func (fn *InternalEngMinMaxBetween) WriteBody(w io.Writer) { + var T *template.Template + + switch { + case fn.Iter: + T = eMinMaxIter + default: + T = eMinMaxSame + } + + lb := eLoopBody{ + BinOp: fn.BinOp, + Kinds: fn.Kinds, + } + T.Execute(w, lb) +} + +func (fn *InternalEngMinMaxBetween) Write(w io.Writer) { + w.Write([]byte("func (e E) ")) + sig := fn.Signature() + sig.Write(w) + w.Write([]byte("{\n")) + fn.WriteBody(w) + w.Write([]byte("}\n\n")) +} + +func generateEMinMaxBetween(f io.Writer, kinds Kinds) { + minmaxOps := []cmpOp{cmpBinOps[0], cmpBinOps[2]} // Gt and Lt + minmaxOps[0].name = "Max" + minmaxOps[1].name = "Min" + var methods []*InternalEngMinMaxBetween + for _, bo := range minmaxOps { + var ks []reflect.Kind + for _, k := range kinds.Kinds { + if tc := bo.TypeClass(); tc != nil && tc(k) { + ks = append(ks, k) + } + } + meth := &InternalEngMinMaxBetween{ + BinOp: bo, + Kinds: ks, + } + methods = append(methods, meth) + } + + for _, meth := range methods { + meth.Write(f) + meth.Iter = true + } + for _, meth := range methods { + meth.Write(f) + } + +} + /* REDUCTION */ type InternalEngReduce struct { diff --git a/genlib2/main.go b/genlib2/main.go index 328cd19..46327c4 100644 --- a/genlib2/main.go +++ b/genlib2/main.go @@ -73,6 +73,7 @@ func main() { pipeline(execLoc, "eng_arith.go", Kinds{allKinds}, generateEArith) pipeline(execLoc, "eng_map.go", Kinds{allKinds}, generateEMap) pipeline(execLoc, "eng_cmp.go", Kinds{allKinds}, generateECmp) + pipeline(execLoc, "eng_minmaxbetween.go", Kinds{allKinds}, generateEMinMaxBetween) pipeline(execLoc, "eng_reduce.go", Kinds{allKinds}, generateEReduce) pipeline(execLoc, "eng_unary.go", Kinds{allKinds}, generateUncondEUnary, generateCondEUnary, generateSpecialEUnaries) pipeline(execLoc, "reduction_specialization.go", Kinds{allKinds}, generateReductionSpecialization) @@ -82,6 +83,7 @@ func main() { pipeline(tensorPkgLoc, "defaultengine_arith.go", Kinds{allKinds}, generateStdEngArith) pipeline(tensorPkgLoc, "defaultengine_cmp.go", Kinds{allKinds}, generateStdEngCmp) pipeline(tensorPkgLoc, "defaultengine_unary.go", Kinds{allKinds}, generateStdEngUncondUnary, generateStdEngCondUnary) + pipeline(tensorPkgLoc, "defaultengine_minmax.go", Kinds{allKinds}, generateStdEngMinMax) // level 3 aggregation pipeline(tensorPkgLoc, "dense_arith.go", Kinds{allKinds}, generateDenseArith) diff --git a/internal/execution/eng_minmaxbetween.go b/internal/execution/eng_minmaxbetween.go new file mode 100644 index 0000000..5d31706 --- /dev/null +++ b/internal/execution/eng_minmaxbetween.go @@ -0,0 +1,778 @@ +// Code generated by genlib2. DO NOT EDIT. + +package execution + +import ( + "reflect" + + "github.com/pkg/errors" + "gorgonia.org/tensor/internal/storage" +) + +func (e E) MaxBetween(t reflect.Type, a *storage.Header, b *storage.Header) (err error) { + as := isScalar(a, t) + bs := isScalar(b, t) + + switch t { + case Int: + at := a.Ints() + bt := b.Ints() + switch { + case as && bs: + VecMaxI(at, bt) + case as && !bs: + MaxSVI(at[0], bt) + case !as && bs: + MaxVSI(at, bt[0]) + default: + VecMaxI(at, bt) + } + return + case Int8: + at := a.Int8s() + bt := b.Int8s() + switch { + case as && bs: + VecMaxI8(at, bt) + case as && !bs: + MaxSVI8(at[0], bt) + case !as && bs: + MaxVSI8(at, bt[0]) + default: + VecMaxI8(at, bt) + } + return + case Int16: + at := a.Int16s() + bt := b.Int16s() + switch { + case as && bs: + VecMaxI16(at, bt) + case as && !bs: + MaxSVI16(at[0], bt) + case !as && bs: + MaxVSI16(at, bt[0]) + default: + VecMaxI16(at, bt) + } + return + case Int32: + at := a.Int32s() + bt := b.Int32s() + switch { + case as && bs: + VecMaxI32(at, bt) + case as && !bs: + MaxSVI32(at[0], bt) + case !as && bs: + MaxVSI32(at, bt[0]) + default: + VecMaxI32(at, bt) + } + return + case Int64: + at := a.Int64s() + bt := b.Int64s() + switch { + case as && bs: + VecMaxI64(at, bt) + case as && !bs: + MaxSVI64(at[0], bt) + case !as && bs: + MaxVSI64(at, bt[0]) + default: + VecMaxI64(at, bt) + } + return + case Uint: + at := a.Uints() + bt := b.Uints() + switch { + case as && bs: + VecMaxU(at, bt) + case as && !bs: + MaxSVU(at[0], bt) + case !as && bs: + MaxVSU(at, bt[0]) + default: + VecMaxU(at, bt) + } + return + case Uint8: + at := a.Uint8s() + bt := b.Uint8s() + switch { + case as && bs: + VecMaxU8(at, bt) + case as && !bs: + MaxSVU8(at[0], bt) + case !as && bs: + MaxVSU8(at, bt[0]) + default: + VecMaxU8(at, bt) + } + return + case Uint16: + at := a.Uint16s() + bt := b.Uint16s() + switch { + case as && bs: + VecMaxU16(at, bt) + case as && !bs: + MaxSVU16(at[0], bt) + case !as && bs: + MaxVSU16(at, bt[0]) + default: + VecMaxU16(at, bt) + } + return + case Uint32: + at := a.Uint32s() + bt := b.Uint32s() + switch { + case as && bs: + VecMaxU32(at, bt) + case as && !bs: + MaxSVU32(at[0], bt) + case !as && bs: + MaxVSU32(at, bt[0]) + default: + VecMaxU32(at, bt) + } + return + case Uint64: + at := a.Uint64s() + bt := b.Uint64s() + switch { + case as && bs: + VecMaxU64(at, bt) + case as && !bs: + MaxSVU64(at[0], bt) + case !as && bs: + MaxVSU64(at, bt[0]) + default: + VecMaxU64(at, bt) + } + return + case Float32: + at := a.Float32s() + bt := b.Float32s() + switch { + case as && bs: + VecMaxF32(at, bt) + case as && !bs: + MaxSVF32(at[0], bt) + case !as && bs: + MaxVSF32(at, bt[0]) + default: + VecMaxF32(at, bt) + } + return + case Float64: + at := a.Float64s() + bt := b.Float64s() + switch { + case as && bs: + VecMaxF64(at, bt) + case as && !bs: + MaxSVF64(at[0], bt) + case !as && bs: + MaxVSF64(at, bt[0]) + default: + VecMaxF64(at, bt) + } + return + case String: + at := a.Strings() + bt := b.Strings() + switch { + case as && bs: + VecMaxStr(at, bt) + case as && !bs: + MaxSVStr(at[0], bt) + case !as && bs: + MaxVSStr(at, bt[0]) + default: + VecMaxStr(at, bt) + } + return + default: + return errors.Errorf("Unsupported type %v for Max", t) + } +} + +func (e E) MinBetween(t reflect.Type, a *storage.Header, b *storage.Header) (err error) { + as := isScalar(a, t) + bs := isScalar(b, t) + + switch t { + case Int: + at := a.Ints() + bt := b.Ints() + switch { + case as && bs: + VecMinI(at, bt) + case as && !bs: + MinSVI(at[0], bt) + case !as && bs: + MinVSI(at, bt[0]) + default: + VecMinI(at, bt) + } + return + case Int8: + at := a.Int8s() + bt := b.Int8s() + switch { + case as && bs: + VecMinI8(at, bt) + case as && !bs: + MinSVI8(at[0], bt) + case !as && bs: + MinVSI8(at, bt[0]) + default: + VecMinI8(at, bt) + } + return + case Int16: + at := a.Int16s() + bt := b.Int16s() + switch { + case as && bs: + VecMinI16(at, bt) + case as && !bs: + MinSVI16(at[0], bt) + case !as && bs: + MinVSI16(at, bt[0]) + default: + VecMinI16(at, bt) + } + return + case Int32: + at := a.Int32s() + bt := b.Int32s() + switch { + case as && bs: + VecMinI32(at, bt) + case as && !bs: + MinSVI32(at[0], bt) + case !as && bs: + MinVSI32(at, bt[0]) + default: + VecMinI32(at, bt) + } + return + case Int64: + at := a.Int64s() + bt := b.Int64s() + switch { + case as && bs: + VecMinI64(at, bt) + case as && !bs: + MinSVI64(at[0], bt) + case !as && bs: + MinVSI64(at, bt[0]) + default: + VecMinI64(at, bt) + } + return + case Uint: + at := a.Uints() + bt := b.Uints() + switch { + case as && bs: + VecMinU(at, bt) + case as && !bs: + MinSVU(at[0], bt) + case !as && bs: + MinVSU(at, bt[0]) + default: + VecMinU(at, bt) + } + return + case Uint8: + at := a.Uint8s() + bt := b.Uint8s() + switch { + case as && bs: + VecMinU8(at, bt) + case as && !bs: + MinSVU8(at[0], bt) + case !as && bs: + MinVSU8(at, bt[0]) + default: + VecMinU8(at, bt) + } + return + case Uint16: + at := a.Uint16s() + bt := b.Uint16s() + switch { + case as && bs: + VecMinU16(at, bt) + case as && !bs: + MinSVU16(at[0], bt) + case !as && bs: + MinVSU16(at, bt[0]) + default: + VecMinU16(at, bt) + } + return + case Uint32: + at := a.Uint32s() + bt := b.Uint32s() + switch { + case as && bs: + VecMinU32(at, bt) + case as && !bs: + MinSVU32(at[0], bt) + case !as && bs: + MinVSU32(at, bt[0]) + default: + VecMinU32(at, bt) + } + return + case Uint64: + at := a.Uint64s() + bt := b.Uint64s() + switch { + case as && bs: + VecMinU64(at, bt) + case as && !bs: + MinSVU64(at[0], bt) + case !as && bs: + MinVSU64(at, bt[0]) + default: + VecMinU64(at, bt) + } + return + case Float32: + at := a.Float32s() + bt := b.Float32s() + switch { + case as && bs: + VecMinF32(at, bt) + case as && !bs: + MinSVF32(at[0], bt) + case !as && bs: + MinVSF32(at, bt[0]) + default: + VecMinF32(at, bt) + } + return + case Float64: + at := a.Float64s() + bt := b.Float64s() + switch { + case as && bs: + VecMinF64(at, bt) + case as && !bs: + MinSVF64(at[0], bt) + case !as && bs: + MinVSF64(at, bt[0]) + default: + VecMinF64(at, bt) + } + return + case String: + at := a.Strings() + bt := b.Strings() + switch { + case as && bs: + VecMinStr(at, bt) + case as && !bs: + MinSVStr(at[0], bt) + case !as && bs: + MinVSStr(at, bt[0]) + default: + VecMinStr(at, bt) + } + return + default: + return errors.Errorf("Unsupported type %v for Min", t) + } +} + +func (e E) MaxBetweenIter(t reflect.Type, a *storage.Header, b *storage.Header, ait Iterator, bit Iterator) (err error) { + as := isScalar(a, t) + bs := isScalar(b, t) + + switch t { + case Int: + at := a.Ints() + bt := b.Ints() + switch { + case as && bs: + VecMaxI(at, bt) + case as && !bs: + MaxIterSVI(at[0], bt, bit) + case !as && bs: + MaxIterVSI(at, bt[0], ait) + default: + VecMaxIterI(at, bt, ait, bit) + } + return + case Int8: + at := a.Int8s() + bt := b.Int8s() + switch { + case as && bs: + VecMaxI8(at, bt) + case as && !bs: + MaxIterSVI8(at[0], bt, bit) + case !as && bs: + MaxIterVSI8(at, bt[0], ait) + default: + VecMaxIterI8(at, bt, ait, bit) + } + return + case Int16: + at := a.Int16s() + bt := b.Int16s() + switch { + case as && bs: + VecMaxI16(at, bt) + case as && !bs: + MaxIterSVI16(at[0], bt, bit) + case !as && bs: + MaxIterVSI16(at, bt[0], ait) + default: + VecMaxIterI16(at, bt, ait, bit) + } + return + case Int32: + at := a.Int32s() + bt := b.Int32s() + switch { + case as && bs: + VecMaxI32(at, bt) + case as && !bs: + MaxIterSVI32(at[0], bt, bit) + case !as && bs: + MaxIterVSI32(at, bt[0], ait) + default: + VecMaxIterI32(at, bt, ait, bit) + } + return + case Int64: + at := a.Int64s() + bt := b.Int64s() + switch { + case as && bs: + VecMaxI64(at, bt) + case as && !bs: + MaxIterSVI64(at[0], bt, bit) + case !as && bs: + MaxIterVSI64(at, bt[0], ait) + default: + VecMaxIterI64(at, bt, ait, bit) + } + return + case Uint: + at := a.Uints() + bt := b.Uints() + switch { + case as && bs: + VecMaxU(at, bt) + case as && !bs: + MaxIterSVU(at[0], bt, bit) + case !as && bs: + MaxIterVSU(at, bt[0], ait) + default: + VecMaxIterU(at, bt, ait, bit) + } + return + case Uint8: + at := a.Uint8s() + bt := b.Uint8s() + switch { + case as && bs: + VecMaxU8(at, bt) + case as && !bs: + MaxIterSVU8(at[0], bt, bit) + case !as && bs: + MaxIterVSU8(at, bt[0], ait) + default: + VecMaxIterU8(at, bt, ait, bit) + } + return + case Uint16: + at := a.Uint16s() + bt := b.Uint16s() + switch { + case as && bs: + VecMaxU16(at, bt) + case as && !bs: + MaxIterSVU16(at[0], bt, bit) + case !as && bs: + MaxIterVSU16(at, bt[0], ait) + default: + VecMaxIterU16(at, bt, ait, bit) + } + return + case Uint32: + at := a.Uint32s() + bt := b.Uint32s() + switch { + case as && bs: + VecMaxU32(at, bt) + case as && !bs: + MaxIterSVU32(at[0], bt, bit) + case !as && bs: + MaxIterVSU32(at, bt[0], ait) + default: + VecMaxIterU32(at, bt, ait, bit) + } + return + case Uint64: + at := a.Uint64s() + bt := b.Uint64s() + switch { + case as && bs: + VecMaxU64(at, bt) + case as && !bs: + MaxIterSVU64(at[0], bt, bit) + case !as && bs: + MaxIterVSU64(at, bt[0], ait) + default: + VecMaxIterU64(at, bt, ait, bit) + } + return + case Float32: + at := a.Float32s() + bt := b.Float32s() + switch { + case as && bs: + VecMaxF32(at, bt) + case as && !bs: + MaxIterSVF32(at[0], bt, bit) + case !as && bs: + MaxIterVSF32(at, bt[0], ait) + default: + VecMaxIterF32(at, bt, ait, bit) + } + return + case Float64: + at := a.Float64s() + bt := b.Float64s() + switch { + case as && bs: + VecMaxF64(at, bt) + case as && !bs: + MaxIterSVF64(at[0], bt, bit) + case !as && bs: + MaxIterVSF64(at, bt[0], ait) + default: + VecMaxIterF64(at, bt, ait, bit) + } + return + case String: + at := a.Strings() + bt := b.Strings() + switch { + case as && bs: + VecMaxStr(at, bt) + case as && !bs: + MaxIterSVStr(at[0], bt, bit) + case !as && bs: + MaxIterVSStr(at, bt[0], ait) + default: + VecMaxIterStr(at, bt, ait, bit) + } + return + default: + return errors.Errorf("Unsupported type %v for Max", t) + } +} + +func (e E) MinBetweenIter(t reflect.Type, a *storage.Header, b *storage.Header, ait Iterator, bit Iterator) (err error) { + as := isScalar(a, t) + bs := isScalar(b, t) + + switch t { + case Int: + at := a.Ints() + bt := b.Ints() + switch { + case as && bs: + VecMinI(at, bt) + case as && !bs: + MinIterSVI(at[0], bt, bit) + case !as && bs: + MinIterVSI(at, bt[0], ait) + default: + VecMinIterI(at, bt, ait, bit) + } + return + case Int8: + at := a.Int8s() + bt := b.Int8s() + switch { + case as && bs: + VecMinI8(at, bt) + case as && !bs: + MinIterSVI8(at[0], bt, bit) + case !as && bs: + MinIterVSI8(at, bt[0], ait) + default: + VecMinIterI8(at, bt, ait, bit) + } + return + case Int16: + at := a.Int16s() + bt := b.Int16s() + switch { + case as && bs: + VecMinI16(at, bt) + case as && !bs: + MinIterSVI16(at[0], bt, bit) + case !as && bs: + MinIterVSI16(at, bt[0], ait) + default: + VecMinIterI16(at, bt, ait, bit) + } + return + case Int32: + at := a.Int32s() + bt := b.Int32s() + switch { + case as && bs: + VecMinI32(at, bt) + case as && !bs: + MinIterSVI32(at[0], bt, bit) + case !as && bs: + MinIterVSI32(at, bt[0], ait) + default: + VecMinIterI32(at, bt, ait, bit) + } + return + case Int64: + at := a.Int64s() + bt := b.Int64s() + switch { + case as && bs: + VecMinI64(at, bt) + case as && !bs: + MinIterSVI64(at[0], bt, bit) + case !as && bs: + MinIterVSI64(at, bt[0], ait) + default: + VecMinIterI64(at, bt, ait, bit) + } + return + case Uint: + at := a.Uints() + bt := b.Uints() + switch { + case as && bs: + VecMinU(at, bt) + case as && !bs: + MinIterSVU(at[0], bt, bit) + case !as && bs: + MinIterVSU(at, bt[0], ait) + default: + VecMinIterU(at, bt, ait, bit) + } + return + case Uint8: + at := a.Uint8s() + bt := b.Uint8s() + switch { + case as && bs: + VecMinU8(at, bt) + case as && !bs: + MinIterSVU8(at[0], bt, bit) + case !as && bs: + MinIterVSU8(at, bt[0], ait) + default: + VecMinIterU8(at, bt, ait, bit) + } + return + case Uint16: + at := a.Uint16s() + bt := b.Uint16s() + switch { + case as && bs: + VecMinU16(at, bt) + case as && !bs: + MinIterSVU16(at[0], bt, bit) + case !as && bs: + MinIterVSU16(at, bt[0], ait) + default: + VecMinIterU16(at, bt, ait, bit) + } + return + case Uint32: + at := a.Uint32s() + bt := b.Uint32s() + switch { + case as && bs: + VecMinU32(at, bt) + case as && !bs: + MinIterSVU32(at[0], bt, bit) + case !as && bs: + MinIterVSU32(at, bt[0], ait) + default: + VecMinIterU32(at, bt, ait, bit) + } + return + case Uint64: + at := a.Uint64s() + bt := b.Uint64s() + switch { + case as && bs: + VecMinU64(at, bt) + case as && !bs: + MinIterSVU64(at[0], bt, bit) + case !as && bs: + MinIterVSU64(at, bt[0], ait) + default: + VecMinIterU64(at, bt, ait, bit) + } + return + case Float32: + at := a.Float32s() + bt := b.Float32s() + switch { + case as && bs: + VecMinF32(at, bt) + case as && !bs: + MinIterSVF32(at[0], bt, bit) + case !as && bs: + MinIterVSF32(at, bt[0], ait) + default: + VecMinIterF32(at, bt, ait, bit) + } + return + case Float64: + at := a.Float64s() + bt := b.Float64s() + switch { + case as && bs: + VecMinF64(at, bt) + case as && !bs: + MinIterSVF64(at[0], bt, bit) + case !as && bs: + MinIterVSF64(at, bt[0], ait) + default: + VecMinIterF64(at, bt, ait, bit) + } + return + case String: + at := a.Strings() + bt := b.Strings() + switch { + case as && bs: + VecMinStr(at, bt) + case as && !bs: + MinIterSVStr(at[0], bt, bit) + case !as && bs: + MinIterVSStr(at, bt[0], ait) + default: + VecMinIterStr(at, bt, ait, bit) + } + return + default: + return errors.Errorf("Unsupported type %v for Min", t) + } +} diff --git a/internal/execution/generic_minmax.go b/internal/execution/generic_minmax.go index 170f01b..8398d5f 100644 --- a/internal/execution/generic_minmax.go +++ b/internal/execution/generic_minmax.go @@ -12,6 +12,23 @@ func VecMinI(a, b []int) { } } } + +func MinSVI(a int, b []int) { + for i := range b { + if a < b[i] { + b[i] = a + } + } +} + +func MinVSI(a []int, b int) { + for i := range a { + if b < a[i] { + a[i] = b + } + } +} + func VecMaxI(a, b []int) { a = a[:] b = b[:len(a)] @@ -22,6 +39,22 @@ func VecMaxI(a, b []int) { } } } + +func MaxSVI(a int, b []int) { + for i := range b { + if a > b[i] { + b[i] = a + } + } +} + +func MaxVSI(a []int, b int) { + for i := range a { + if b > a[i] { + a[i] = b + } + } +} func VecMinI8(a, b []int8) { a = a[:] b = b[:len(a)] @@ -32,6 +65,23 @@ func VecMinI8(a, b []int8) { } } } + +func MinSVI8(a int8, b []int8) { + for i := range b { + if a < b[i] { + b[i] = a + } + } +} + +func MinVSI8(a []int8, b int8) { + for i := range a { + if b < a[i] { + a[i] = b + } + } +} + func VecMaxI8(a, b []int8) { a = a[:] b = b[:len(a)] @@ -42,6 +92,22 @@ func VecMaxI8(a, b []int8) { } } } + +func MaxSVI8(a int8, b []int8) { + for i := range b { + if a > b[i] { + b[i] = a + } + } +} + +func MaxVSI8(a []int8, b int8) { + for i := range a { + if b > a[i] { + a[i] = b + } + } +} func VecMinI16(a, b []int16) { a = a[:] b = b[:len(a)] @@ -52,6 +118,23 @@ func VecMinI16(a, b []int16) { } } } + +func MinSVI16(a int16, b []int16) { + for i := range b { + if a < b[i] { + b[i] = a + } + } +} + +func MinVSI16(a []int16, b int16) { + for i := range a { + if b < a[i] { + a[i] = b + } + } +} + func VecMaxI16(a, b []int16) { a = a[:] b = b[:len(a)] @@ -62,6 +145,22 @@ func VecMaxI16(a, b []int16) { } } } + +func MaxSVI16(a int16, b []int16) { + for i := range b { + if a > b[i] { + b[i] = a + } + } +} + +func MaxVSI16(a []int16, b int16) { + for i := range a { + if b > a[i] { + a[i] = b + } + } +} func VecMinI32(a, b []int32) { a = a[:] b = b[:len(a)] @@ -72,6 +171,23 @@ func VecMinI32(a, b []int32) { } } } + +func MinSVI32(a int32, b []int32) { + for i := range b { + if a < b[i] { + b[i] = a + } + } +} + +func MinVSI32(a []int32, b int32) { + for i := range a { + if b < a[i] { + a[i] = b + } + } +} + func VecMaxI32(a, b []int32) { a = a[:] b = b[:len(a)] @@ -82,6 +198,22 @@ func VecMaxI32(a, b []int32) { } } } + +func MaxSVI32(a int32, b []int32) { + for i := range b { + if a > b[i] { + b[i] = a + } + } +} + +func MaxVSI32(a []int32, b int32) { + for i := range a { + if b > a[i] { + a[i] = b + } + } +} func VecMinI64(a, b []int64) { a = a[:] b = b[:len(a)] @@ -92,6 +224,23 @@ func VecMinI64(a, b []int64) { } } } + +func MinSVI64(a int64, b []int64) { + for i := range b { + if a < b[i] { + b[i] = a + } + } +} + +func MinVSI64(a []int64, b int64) { + for i := range a { + if b < a[i] { + a[i] = b + } + } +} + func VecMaxI64(a, b []int64) { a = a[:] b = b[:len(a)] @@ -102,6 +251,22 @@ func VecMaxI64(a, b []int64) { } } } + +func MaxSVI64(a int64, b []int64) { + for i := range b { + if a > b[i] { + b[i] = a + } + } +} + +func MaxVSI64(a []int64, b int64) { + for i := range a { + if b > a[i] { + a[i] = b + } + } +} func VecMinU(a, b []uint) { a = a[:] b = b[:len(a)] @@ -112,6 +277,23 @@ func VecMinU(a, b []uint) { } } } + +func MinSVU(a uint, b []uint) { + for i := range b { + if a < b[i] { + b[i] = a + } + } +} + +func MinVSU(a []uint, b uint) { + for i := range a { + if b < a[i] { + a[i] = b + } + } +} + func VecMaxU(a, b []uint) { a = a[:] b = b[:len(a)] @@ -122,6 +304,22 @@ func VecMaxU(a, b []uint) { } } } + +func MaxSVU(a uint, b []uint) { + for i := range b { + if a > b[i] { + b[i] = a + } + } +} + +func MaxVSU(a []uint, b uint) { + for i := range a { + if b > a[i] { + a[i] = b + } + } +} func VecMinU8(a, b []uint8) { a = a[:] b = b[:len(a)] @@ -132,6 +330,23 @@ func VecMinU8(a, b []uint8) { } } } + +func MinSVU8(a uint8, b []uint8) { + for i := range b { + if a < b[i] { + b[i] = a + } + } +} + +func MinVSU8(a []uint8, b uint8) { + for i := range a { + if b < a[i] { + a[i] = b + } + } +} + func VecMaxU8(a, b []uint8) { a = a[:] b = b[:len(a)] @@ -142,6 +357,22 @@ func VecMaxU8(a, b []uint8) { } } } + +func MaxSVU8(a uint8, b []uint8) { + for i := range b { + if a > b[i] { + b[i] = a + } + } +} + +func MaxVSU8(a []uint8, b uint8) { + for i := range a { + if b > a[i] { + a[i] = b + } + } +} func VecMinU16(a, b []uint16) { a = a[:] b = b[:len(a)] @@ -152,6 +383,23 @@ func VecMinU16(a, b []uint16) { } } } + +func MinSVU16(a uint16, b []uint16) { + for i := range b { + if a < b[i] { + b[i] = a + } + } +} + +func MinVSU16(a []uint16, b uint16) { + for i := range a { + if b < a[i] { + a[i] = b + } + } +} + func VecMaxU16(a, b []uint16) { a = a[:] b = b[:len(a)] @@ -162,6 +410,22 @@ func VecMaxU16(a, b []uint16) { } } } + +func MaxSVU16(a uint16, b []uint16) { + for i := range b { + if a > b[i] { + b[i] = a + } + } +} + +func MaxVSU16(a []uint16, b uint16) { + for i := range a { + if b > a[i] { + a[i] = b + } + } +} func VecMinU32(a, b []uint32) { a = a[:] b = b[:len(a)] @@ -172,6 +436,23 @@ func VecMinU32(a, b []uint32) { } } } + +func MinSVU32(a uint32, b []uint32) { + for i := range b { + if a < b[i] { + b[i] = a + } + } +} + +func MinVSU32(a []uint32, b uint32) { + for i := range a { + if b < a[i] { + a[i] = b + } + } +} + func VecMaxU32(a, b []uint32) { a = a[:] b = b[:len(a)] @@ -182,6 +463,22 @@ func VecMaxU32(a, b []uint32) { } } } + +func MaxSVU32(a uint32, b []uint32) { + for i := range b { + if a > b[i] { + b[i] = a + } + } +} + +func MaxVSU32(a []uint32, b uint32) { + for i := range a { + if b > a[i] { + a[i] = b + } + } +} func VecMinU64(a, b []uint64) { a = a[:] b = b[:len(a)] @@ -192,6 +489,23 @@ func VecMinU64(a, b []uint64) { } } } + +func MinSVU64(a uint64, b []uint64) { + for i := range b { + if a < b[i] { + b[i] = a + } + } +} + +func MinVSU64(a []uint64, b uint64) { + for i := range a { + if b < a[i] { + a[i] = b + } + } +} + func VecMaxU64(a, b []uint64) { a = a[:] b = b[:len(a)] @@ -202,6 +516,22 @@ func VecMaxU64(a, b []uint64) { } } } + +func MaxSVU64(a uint64, b []uint64) { + for i := range b { + if a > b[i] { + b[i] = a + } + } +} + +func MaxVSU64(a []uint64, b uint64) { + for i := range a { + if b > a[i] { + a[i] = b + } + } +} func VecMinF32(a, b []float32) { a = a[:] b = b[:len(a)] @@ -212,6 +542,23 @@ func VecMinF32(a, b []float32) { } } } + +func MinSVF32(a float32, b []float32) { + for i := range b { + if a < b[i] { + b[i] = a + } + } +} + +func MinVSF32(a []float32, b float32) { + for i := range a { + if b < a[i] { + a[i] = b + } + } +} + func VecMaxF32(a, b []float32) { a = a[:] b = b[:len(a)] @@ -222,6 +569,22 @@ func VecMaxF32(a, b []float32) { } } } + +func MaxSVF32(a float32, b []float32) { + for i := range b { + if a > b[i] { + b[i] = a + } + } +} + +func MaxVSF32(a []float32, b float32) { + for i := range a { + if b > a[i] { + a[i] = b + } + } +} func VecMinF64(a, b []float64) { a = a[:] b = b[:len(a)] @@ -232,6 +595,23 @@ func VecMinF64(a, b []float64) { } } } + +func MinSVF64(a float64, b []float64) { + for i := range b { + if a < b[i] { + b[i] = a + } + } +} + +func MinVSF64(a []float64, b float64) { + for i := range a { + if b < a[i] { + a[i] = b + } + } +} + func VecMaxF64(a, b []float64) { a = a[:] b = b[:len(a)] @@ -242,6 +622,22 @@ func VecMaxF64(a, b []float64) { } } } + +func MaxSVF64(a float64, b []float64) { + for i := range b { + if a > b[i] { + b[i] = a + } + } +} + +func MaxVSF64(a []float64, b float64) { + for i := range a { + if b > a[i] { + a[i] = b + } + } +} func VecMinStr(a, b []string) { a = a[:] b = b[:len(a)] @@ -252,6 +648,23 @@ func VecMinStr(a, b []string) { } } } + +func MinSVStr(a string, b []string) { + for i := range b { + if a < b[i] { + b[i] = a + } + } +} + +func MinVSStr(a []string, b string) { + for i := range a { + if b < a[i] { + a[i] = b + } + } +} + func VecMaxStr(a, b []string) { a = a[:] b = b[:len(a)] @@ -262,6 +675,22 @@ func VecMaxStr(a, b []string) { } } } + +func MaxSVStr(a string, b []string) { + for i := range b { + if a > b[i] { + b[i] = a + } + } +} + +func MaxVSStr(a []string, b string) { + for i := range a { + if b > a[i] { + a[i] = b + } + } +} func MinI(a, b int) (c int) { if a < b { return a @@ -431,3 +860,1432 @@ func MaxStr(a, b string) (c string) { } return b } +func MinIterSVI(a int, b []int, bit Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if a < b[i] { + b[i] = a + } + } + } + return +} + +func MinIterVSI(a []int, b int, ait Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if b < a[i] { + a[i] = b + } + } + } + return +} + +func VecMinIterI(a, b []int, ait, bit Iterator) (err error) { + var i, j int + var validi, validj bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if j, validj, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi && validj { + if b[j] < a[i] { + a[i] = b[j] + } + } + } + return +} + +func MaxIterSVI(a int, b []int, bit Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if a > b[i] { + b[i] = a + } + } + } + return +} + +func MaxIterVSI(a []int, b int, ait Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if b > a[i] { + a[i] = b + } + } + } + return +} + +func VecMaxIterI(a, b []int, ait, bit Iterator) (err error) { + var i, j int + var validi, validj bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if j, validj, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi && validj { + if b[j] > a[i] { + a[i] = b[j] + } + } + } + return +} + +func MinIterSVI8(a int8, b []int8, bit Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if a < b[i] { + b[i] = a + } + } + } + return +} + +func MinIterVSI8(a []int8, b int8, ait Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if b < a[i] { + a[i] = b + } + } + } + return +} + +func VecMinIterI8(a, b []int8, ait, bit Iterator) (err error) { + var i, j int + var validi, validj bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if j, validj, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi && validj { + if b[j] < a[i] { + a[i] = b[j] + } + } + } + return +} + +func MaxIterSVI8(a int8, b []int8, bit Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if a > b[i] { + b[i] = a + } + } + } + return +} + +func MaxIterVSI8(a []int8, b int8, ait Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if b > a[i] { + a[i] = b + } + } + } + return +} + +func VecMaxIterI8(a, b []int8, ait, bit Iterator) (err error) { + var i, j int + var validi, validj bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if j, validj, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi && validj { + if b[j] > a[i] { + a[i] = b[j] + } + } + } + return +} + +func MinIterSVI16(a int16, b []int16, bit Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if a < b[i] { + b[i] = a + } + } + } + return +} + +func MinIterVSI16(a []int16, b int16, ait Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if b < a[i] { + a[i] = b + } + } + } + return +} + +func VecMinIterI16(a, b []int16, ait, bit Iterator) (err error) { + var i, j int + var validi, validj bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if j, validj, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi && validj { + if b[j] < a[i] { + a[i] = b[j] + } + } + } + return +} + +func MaxIterSVI16(a int16, b []int16, bit Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if a > b[i] { + b[i] = a + } + } + } + return +} + +func MaxIterVSI16(a []int16, b int16, ait Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if b > a[i] { + a[i] = b + } + } + } + return +} + +func VecMaxIterI16(a, b []int16, ait, bit Iterator) (err error) { + var i, j int + var validi, validj bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if j, validj, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi && validj { + if b[j] > a[i] { + a[i] = b[j] + } + } + } + return +} + +func MinIterSVI32(a int32, b []int32, bit Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if a < b[i] { + b[i] = a + } + } + } + return +} + +func MinIterVSI32(a []int32, b int32, ait Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if b < a[i] { + a[i] = b + } + } + } + return +} + +func VecMinIterI32(a, b []int32, ait, bit Iterator) (err error) { + var i, j int + var validi, validj bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if j, validj, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi && validj { + if b[j] < a[i] { + a[i] = b[j] + } + } + } + return +} + +func MaxIterSVI32(a int32, b []int32, bit Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if a > b[i] { + b[i] = a + } + } + } + return +} + +func MaxIterVSI32(a []int32, b int32, ait Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if b > a[i] { + a[i] = b + } + } + } + return +} + +func VecMaxIterI32(a, b []int32, ait, bit Iterator) (err error) { + var i, j int + var validi, validj bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if j, validj, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi && validj { + if b[j] > a[i] { + a[i] = b[j] + } + } + } + return +} + +func MinIterSVI64(a int64, b []int64, bit Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if a < b[i] { + b[i] = a + } + } + } + return +} + +func MinIterVSI64(a []int64, b int64, ait Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if b < a[i] { + a[i] = b + } + } + } + return +} + +func VecMinIterI64(a, b []int64, ait, bit Iterator) (err error) { + var i, j int + var validi, validj bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if j, validj, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi && validj { + if b[j] < a[i] { + a[i] = b[j] + } + } + } + return +} + +func MaxIterSVI64(a int64, b []int64, bit Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if a > b[i] { + b[i] = a + } + } + } + return +} + +func MaxIterVSI64(a []int64, b int64, ait Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if b > a[i] { + a[i] = b + } + } + } + return +} + +func VecMaxIterI64(a, b []int64, ait, bit Iterator) (err error) { + var i, j int + var validi, validj bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if j, validj, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi && validj { + if b[j] > a[i] { + a[i] = b[j] + } + } + } + return +} + +func MinIterSVU(a uint, b []uint, bit Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if a < b[i] { + b[i] = a + } + } + } + return +} + +func MinIterVSU(a []uint, b uint, ait Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if b < a[i] { + a[i] = b + } + } + } + return +} + +func VecMinIterU(a, b []uint, ait, bit Iterator) (err error) { + var i, j int + var validi, validj bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if j, validj, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi && validj { + if b[j] < a[i] { + a[i] = b[j] + } + } + } + return +} + +func MaxIterSVU(a uint, b []uint, bit Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if a > b[i] { + b[i] = a + } + } + } + return +} + +func MaxIterVSU(a []uint, b uint, ait Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if b > a[i] { + a[i] = b + } + } + } + return +} + +func VecMaxIterU(a, b []uint, ait, bit Iterator) (err error) { + var i, j int + var validi, validj bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if j, validj, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi && validj { + if b[j] > a[i] { + a[i] = b[j] + } + } + } + return +} + +func MinIterSVU8(a uint8, b []uint8, bit Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if a < b[i] { + b[i] = a + } + } + } + return +} + +func MinIterVSU8(a []uint8, b uint8, ait Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if b < a[i] { + a[i] = b + } + } + } + return +} + +func VecMinIterU8(a, b []uint8, ait, bit Iterator) (err error) { + var i, j int + var validi, validj bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if j, validj, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi && validj { + if b[j] < a[i] { + a[i] = b[j] + } + } + } + return +} + +func MaxIterSVU8(a uint8, b []uint8, bit Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if a > b[i] { + b[i] = a + } + } + } + return +} + +func MaxIterVSU8(a []uint8, b uint8, ait Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if b > a[i] { + a[i] = b + } + } + } + return +} + +func VecMaxIterU8(a, b []uint8, ait, bit Iterator) (err error) { + var i, j int + var validi, validj bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if j, validj, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi && validj { + if b[j] > a[i] { + a[i] = b[j] + } + } + } + return +} + +func MinIterSVU16(a uint16, b []uint16, bit Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if a < b[i] { + b[i] = a + } + } + } + return +} + +func MinIterVSU16(a []uint16, b uint16, ait Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if b < a[i] { + a[i] = b + } + } + } + return +} + +func VecMinIterU16(a, b []uint16, ait, bit Iterator) (err error) { + var i, j int + var validi, validj bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if j, validj, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi && validj { + if b[j] < a[i] { + a[i] = b[j] + } + } + } + return +} + +func MaxIterSVU16(a uint16, b []uint16, bit Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if a > b[i] { + b[i] = a + } + } + } + return +} + +func MaxIterVSU16(a []uint16, b uint16, ait Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if b > a[i] { + a[i] = b + } + } + } + return +} + +func VecMaxIterU16(a, b []uint16, ait, bit Iterator) (err error) { + var i, j int + var validi, validj bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if j, validj, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi && validj { + if b[j] > a[i] { + a[i] = b[j] + } + } + } + return +} + +func MinIterSVU32(a uint32, b []uint32, bit Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if a < b[i] { + b[i] = a + } + } + } + return +} + +func MinIterVSU32(a []uint32, b uint32, ait Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if b < a[i] { + a[i] = b + } + } + } + return +} + +func VecMinIterU32(a, b []uint32, ait, bit Iterator) (err error) { + var i, j int + var validi, validj bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if j, validj, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi && validj { + if b[j] < a[i] { + a[i] = b[j] + } + } + } + return +} + +func MaxIterSVU32(a uint32, b []uint32, bit Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if a > b[i] { + b[i] = a + } + } + } + return +} + +func MaxIterVSU32(a []uint32, b uint32, ait Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if b > a[i] { + a[i] = b + } + } + } + return +} + +func VecMaxIterU32(a, b []uint32, ait, bit Iterator) (err error) { + var i, j int + var validi, validj bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if j, validj, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi && validj { + if b[j] > a[i] { + a[i] = b[j] + } + } + } + return +} + +func MinIterSVU64(a uint64, b []uint64, bit Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if a < b[i] { + b[i] = a + } + } + } + return +} + +func MinIterVSU64(a []uint64, b uint64, ait Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if b < a[i] { + a[i] = b + } + } + } + return +} + +func VecMinIterU64(a, b []uint64, ait, bit Iterator) (err error) { + var i, j int + var validi, validj bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if j, validj, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi && validj { + if b[j] < a[i] { + a[i] = b[j] + } + } + } + return +} + +func MaxIterSVU64(a uint64, b []uint64, bit Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if a > b[i] { + b[i] = a + } + } + } + return +} + +func MaxIterVSU64(a []uint64, b uint64, ait Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if b > a[i] { + a[i] = b + } + } + } + return +} + +func VecMaxIterU64(a, b []uint64, ait, bit Iterator) (err error) { + var i, j int + var validi, validj bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if j, validj, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi && validj { + if b[j] > a[i] { + a[i] = b[j] + } + } + } + return +} + +func MinIterSVF32(a float32, b []float32, bit Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if a < b[i] { + b[i] = a + } + } + } + return +} + +func MinIterVSF32(a []float32, b float32, ait Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if b < a[i] { + a[i] = b + } + } + } + return +} + +func VecMinIterF32(a, b []float32, ait, bit Iterator) (err error) { + var i, j int + var validi, validj bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if j, validj, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi && validj { + if b[j] < a[i] { + a[i] = b[j] + } + } + } + return +} + +func MaxIterSVF32(a float32, b []float32, bit Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if a > b[i] { + b[i] = a + } + } + } + return +} + +func MaxIterVSF32(a []float32, b float32, ait Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if b > a[i] { + a[i] = b + } + } + } + return +} + +func VecMaxIterF32(a, b []float32, ait, bit Iterator) (err error) { + var i, j int + var validi, validj bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if j, validj, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi && validj { + if b[j] > a[i] { + a[i] = b[j] + } + } + } + return +} + +func MinIterSVF64(a float64, b []float64, bit Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if a < b[i] { + b[i] = a + } + } + } + return +} + +func MinIterVSF64(a []float64, b float64, ait Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if b < a[i] { + a[i] = b + } + } + } + return +} + +func VecMinIterF64(a, b []float64, ait, bit Iterator) (err error) { + var i, j int + var validi, validj bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if j, validj, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi && validj { + if b[j] < a[i] { + a[i] = b[j] + } + } + } + return +} + +func MaxIterSVF64(a float64, b []float64, bit Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if a > b[i] { + b[i] = a + } + } + } + return +} + +func MaxIterVSF64(a []float64, b float64, ait Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if b > a[i] { + a[i] = b + } + } + } + return +} + +func VecMaxIterF64(a, b []float64, ait, bit Iterator) (err error) { + var i, j int + var validi, validj bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if j, validj, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi && validj { + if b[j] > a[i] { + a[i] = b[j] + } + } + } + return +} + +func MinIterSVStr(a string, b []string, bit Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if a < b[i] { + b[i] = a + } + } + } + return +} + +func MinIterVSStr(a []string, b string, ait Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if b < a[i] { + a[i] = b + } + } + } + return +} + +func VecMinIterStr(a, b []string, ait, bit Iterator) (err error) { + var i, j int + var validi, validj bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if j, validj, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi && validj { + if b[j] < a[i] { + a[i] = b[j] + } + } + } + return +} + +func MaxIterSVStr(a string, b []string, bit Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if a > b[i] { + b[i] = a + } + } + } + return +} + +func MaxIterVSStr(a []string, b string, ait Iterator) (err error) { + var i int + var validi bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi { + if b > a[i] { + a[i] = b + } + } + } + return +} + +func VecMaxIterStr(a, b []string, ait, bit Iterator) (err error) { + var i, j int + var validi, validj bool + for { + if i, validi, err = ait.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if j, validj, err = bit.NextValidity(); err != nil { + err = handleNoOp(err) + break + } + if validi && validj { + if b[j] > a[i] { + a[i] = b[j] + } + } + } + return +}