github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/colexec/agg/variance.go (about)

     1  // Copyright 2021 Matrix Origin
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package agg
    16  
    17  import (
    18  	"math"
    19  	"reflect"
    20  	"unsafe"
    21  
    22  	"github.com/matrixorigin/matrixone/pkg/container/types"
    23  )
    24  
    25  type Variance[T1 types.Floats | types.Ints | types.UInts] struct {
    26  	Sum    []float64
    27  	Counts []float64
    28  }
    29  
    30  type EncodeVariance struct {
    31  	Sum    []float64
    32  	Counts []float64
    33  }
    34  
    35  // VD64 Variance for decimal64
    36  type VD64 struct {
    37  	Sum    []types.Decimal128
    38  	Counts []int64
    39  }
    40  
    41  // VD128 Variance for decimal128
    42  type VD128 struct {
    43  	Sum    []types.Decimal128
    44  	Counts []int64
    45  }
    46  
    47  type EncodeDecimalV struct {
    48  	Sum    []types.Decimal128
    49  	Counts []int64
    50  }
    51  
    52  func VarianceReturnType(typs []types.Type) types.Type {
    53  	switch typs[0].Oid {
    54  	case types.T_decimal64, types.T_decimal128:
    55  		return types.New(types.T_decimal128, 0, typs[0].Scale, typs[0].Precision)
    56  	default:
    57  		return types.New(types.T_float64, 0, 0, 0)
    58  	}
    59  }
    60  
    61  func String(b []byte) (s string) {
    62  	pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b))
    63  	pstring := (*reflect.StringHeader)(unsafe.Pointer(&s))
    64  	pstring.Data = pbytes.Data
    65  	pstring.Len = pbytes.Len
    66  	return
    67  }
    68  
    69  // NewVariance is used to create a Variance which supports float,int,uint
    70  func NewVariance[T1 types.Floats | types.Ints | types.UInts]() *Variance[T1] {
    71  	return &Variance[T1]{}
    72  }
    73  
    74  func (variance *Variance[T1]) Grows(count int) {
    75  	if len(variance.Sum) == 0 {
    76  		variance.Sum = make([]float64, count)
    77  		variance.Counts = make([]float64, count)
    78  	} else {
    79  		for i := 0; i < count; i++ {
    80  			variance.Sum = append(variance.Sum, 0)
    81  			variance.Counts = append(variance.Counts, 0)
    82  		}
    83  	}
    84  }
    85  
    86  func (variance *Variance[T1]) Eval(vs []float64) []float64 {
    87  	for i, v := range vs {
    88  		avg := (variance.Sum[i]) / (variance.Counts[i])
    89  		vs[i] = (v)/(variance.Counts[i]) - math.Pow(avg, 2)
    90  	}
    91  	return vs
    92  }
    93  
    94  func (variance *Variance[T1]) Merge(groupIndex1, groupIndex2 int64, x, y float64, IsEmpty1 bool, IsEmpty2 bool, agg any) (float64, bool) {
    95  	variance2 := agg.(*Variance[T1])
    96  	if IsEmpty1 && !IsEmpty2 {
    97  		variance.Sum[groupIndex1] = variance2.Sum[groupIndex2]
    98  		variance.Counts[groupIndex1] = variance2.Counts[groupIndex2]
    99  		return y, false
   100  	} else if IsEmpty2 && !IsEmpty1 {
   101  		return x, false
   102  	} else if IsEmpty1 && IsEmpty2 {
   103  		return x, true
   104  	} else {
   105  		variance.Counts[groupIndex1] += variance2.Counts[groupIndex2]
   106  		variance.Sum[groupIndex1] += variance2.Sum[groupIndex2]
   107  		return x + y, false
   108  	}
   109  }
   110  
   111  func (variance *Variance[T1]) Fill(groupIndex int64, v1 T1, v2 float64, z int64, IsEmpty bool, hasNull bool) (float64, bool) {
   112  	if hasNull {
   113  		return v2, IsEmpty
   114  	} else if IsEmpty {
   115  		f1 := float64(v1)
   116  		variance.Sum[groupIndex] = f1 * float64(z)
   117  		variance.Counts[groupIndex] += float64(z)
   118  		return math.Pow(f1, 2) * float64(z), false
   119  	}
   120  	f1 := float64(v1)
   121  	f2 := v2
   122  	variance.Sum[groupIndex] += f1 * float64(z)
   123  	variance.Counts[groupIndex] += float64(z)
   124  	return f2 + math.Pow(f1, 2)*float64(z), false
   125  }
   126  
   127  func (variance *Variance[T1]) MarshalBinary() ([]byte, error) {
   128  	return types.Encode(&EncodeVariance{
   129  		Sum:    variance.Sum,
   130  		Counts: variance.Counts,
   131  	})
   132  }
   133  
   134  func (variance *Variance[T1]) UnmarshalBinary(data []byte) error {
   135  	// avoid resulting errors caused by morpc overusing memory
   136  	copyData := make([]byte, len(data))
   137  	copy(copyData, data)
   138  	decoded := new(EncodeVariance)
   139  	if err := types.Decode(copyData, decoded); err != nil {
   140  		return nil
   141  	}
   142  	variance.Sum = decoded.Sum
   143  	variance.Counts = decoded.Counts
   144  	return nil
   145  }
   146  
   147  func NewVD64() *VD64 {
   148  	return &VD64{}
   149  }
   150  
   151  func (v *VD64) Grows(cnt int) {
   152  	d, _ := types.Decimal128_FromInt64(0, 64, 0)
   153  	for i := 0; i < cnt; i++ {
   154  		v.Sum = append(v.Sum, d)
   155  		v.Counts = append(v.Counts, 0)
   156  	}
   157  }
   158  
   159  func (v *VD64) Eval(vs []types.Decimal128) []types.Decimal128 {
   160  	for i, k := range vs {
   161  		a := types.Decimal128Int64Div(v.Sum[i], v.Counts[i])
   162  		a2 := types.Decimal128Decimal128Mul(a, a)
   163  		d := types.Decimal128Int64Div(k, v.Counts[i])
   164  		vs[i] = d.Sub(a2)
   165  	}
   166  	return vs
   167  }
   168  
   169  func (v *VD64) Merge(xIndex, yIndex int64, x types.Decimal128, y types.Decimal128, xEmpty bool, yEmpty bool, agg any) (types.Decimal128, bool) {
   170  	if !yEmpty {
   171  		vd := agg.(*VD64)
   172  		v.Counts[xIndex] += vd.Counts[yIndex]
   173  		v.Sum[xIndex] = v.Sum[xIndex].Add(vd.Sum[yIndex])
   174  		if !xEmpty {
   175  			return x.Add(y), false
   176  		}
   177  		return y, false
   178  	}
   179  	return x, xEmpty
   180  }
   181  
   182  func (v *VD64) Fill(i int64, v1 types.Decimal64, v2 types.Decimal128, z int64, isEmpty bool, isNull bool) (types.Decimal128, bool) {
   183  	if isNull {
   184  		return v2, isEmpty
   185  	}
   186  	x := types.Decimal128_FromDecimal64(v1)
   187  	v.Counts[i] += z
   188  	if isEmpty {
   189  		v.Sum[i] = types.Decimal128Int64Mul(x, z)
   190  		return types.Decimal128Int64Mul(types.Decimal128Decimal128Mul(x, x), z), false
   191  	}
   192  	v.Sum[i] = v.Sum[i].Add(types.Decimal128Int64Mul(x, z))
   193  	return v2.Add(types.Decimal128Int64Mul(types.Decimal128Decimal128Mul(x, x), z)), false
   194  }
   195  
   196  func (v *VD64) MarshalBinary() ([]byte, error) {
   197  	return types.Encode(&EncodeDecimalV{
   198  		Sum:    v.Sum,
   199  		Counts: v.Counts,
   200  	})
   201  }
   202  
   203  func (v *VD64) UnmarshalBinary(data []byte) error {
   204  	// avoid resulting errors caused by morpc overusing memory
   205  	copyData := make([]byte, len(data))
   206  	copy(copyData, data)
   207  	decoded := new(EncodeDecimalV)
   208  	if err := types.Decode(copyData, decoded); err != nil {
   209  		return nil
   210  	}
   211  	v.Sum = decoded.Sum
   212  	v.Counts = decoded.Counts
   213  	return nil
   214  }
   215  
   216  func NewVD128() *VD128 {
   217  	return &VD128{}
   218  }
   219  
   220  func (v *VD128) Grows(cnt int) {
   221  	d, _ := types.Decimal128_FromInt64(0, 64, 0)
   222  	for i := 0; i < cnt; i++ {
   223  		v.Sum = append(v.Sum, d)
   224  		v.Counts = append(v.Counts, 0)
   225  	}
   226  }
   227  
   228  func (v *VD128) Eval(vs []types.Decimal128) []types.Decimal128 {
   229  	for i, k := range vs {
   230  		a := types.Decimal128Int64Div(v.Sum[i], v.Counts[i])
   231  		a2 := types.Decimal128Decimal128Mul(a, a)
   232  		d := types.Decimal128Int64Div(k, v.Counts[i])
   233  		vs[i] = d.Sub(a2)
   234  	}
   235  	return vs
   236  }
   237  
   238  func (v *VD128) Merge(xIndex, yIndex int64, x types.Decimal128, y types.Decimal128, xEmpty bool, yEmpty bool, agg any) (types.Decimal128, bool) {
   239  	if !yEmpty {
   240  		vd := agg.(*VD128)
   241  		v.Counts[xIndex] += vd.Counts[yIndex]
   242  		v.Sum[xIndex] = v.Sum[xIndex].Add(vd.Sum[yIndex])
   243  		if !xEmpty {
   244  			return x.Add(y), false
   245  		}
   246  		return y, false
   247  	}
   248  	return x, xEmpty
   249  }
   250  
   251  func (v *VD128) Fill(i int64, v1 types.Decimal128, v2 types.Decimal128, z int64, isEmpty bool, isNull bool) (types.Decimal128, bool) {
   252  	if isNull {
   253  		return v2, isEmpty
   254  	}
   255  	v.Counts[i] += z
   256  	if isEmpty {
   257  		v.Sum[i] = types.Decimal128Int64Mul(v1, z)
   258  		return types.Decimal128Int64Mul(types.Decimal128Decimal128Mul(v1, v1), z), false
   259  	}
   260  	v.Sum[i] = v.Sum[i].Add(types.Decimal128Int64Mul(v1, z))
   261  	return v2.Add(types.Decimal128Int64Mul(types.Decimal128Decimal128Mul(v1, v1), z)), false
   262  }
   263  
   264  func (v *VD128) MarshalBinary() ([]byte, error) {
   265  	return types.Encode(&EncodeDecimalV{
   266  		Sum:    v.Sum,
   267  		Counts: v.Counts,
   268  	})
   269  }
   270  
   271  func (v *VD128) UnmarshalBinary(data []byte) error {
   272  	// avoid resulting errors caused by morpc overusing memory
   273  	copyData := make([]byte, len(data))
   274  	copy(copyData, data)
   275  	decoded := new(EncodeDecimalV)
   276  	if err := types.Decode(copyData, decoded); err != nil {
   277  		return nil
   278  	}
   279  	v.Sum = decoded.Sum
   280  	v.Counts = decoded.Counts
   281  	return nil
   282  }