github.com/go-graphite/carbonapi@v0.17.0/expr/functions/kolmogorovSmirnovTest2/function.go (about) 1 package kolmogorovSmirnovTest2 2 3 import ( 4 "context" 5 "math" 6 7 "github.com/dgryski/go-onlinestats" 8 "github.com/go-graphite/carbonapi/expr/helper" 9 "github.com/go-graphite/carbonapi/expr/interfaces" 10 "github.com/go-graphite/carbonapi/expr/types" 11 "github.com/go-graphite/carbonapi/pkg/parser" 12 ) 13 14 type kolmogorovSmirnovTest2 struct{} 15 16 func GetOrder() interfaces.Order { 17 return interfaces.Any 18 } 19 20 func New(configFile string) []interfaces.FunctionMetadata { 21 res := make([]interfaces.FunctionMetadata, 0) 22 f := &kolmogorovSmirnovTest2{} 23 functions := []string{"kolmogorovSmirnovTest2", "ksTest2"} 24 for _, n := range functions { 25 res = append(res, interfaces.FunctionMetadata{Name: n, F: f}) 26 } 27 return res 28 } 29 30 // ksTest2(series, series, points|"interval") 31 // https://en.wikipedia.org/wiki/Kolmogorov%E2%80%93Smirnov_test 32 func (f *kolmogorovSmirnovTest2) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { 33 arg1, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) 34 if err != nil { 35 return nil, err 36 } 37 38 arg2, err := helper.GetSeriesArg(ctx, eval, e.Arg(1), from, until, values) 39 if err != nil { 40 return nil, err 41 } 42 43 if len(arg1) != 1 || len(arg2) != 1 { 44 return nil, types.ErrWildcardNotAllowed 45 } 46 47 a1 := arg1[0] 48 a2 := arg2[0] 49 50 windowSize, err := e.GetIntArg(2) 51 if err != nil { 52 return nil, err 53 } 54 windowSizeStr := e.Arg((2)).StringValue() 55 56 w1 := &types.Windowed{Data: make([]float64, windowSize)} 57 w2 := &types.Windowed{Data: make([]float64, windowSize)} 58 59 r := a1.CopyLinkTags() 60 r.Name = "kolmogorovSmirnovTest2(" + a1.Name + "," + a2.Name + "," + windowSizeStr + ")" 61 r.Values = make([]float64, len(a1.Values)) 62 r.StartTime = from 63 r.StopTime = until 64 65 d1 := make([]float64, windowSize) 66 d2 := make([]float64, windowSize) 67 68 for i, v1 := range a1.Values { 69 v2 := a2.Values[i] 70 w1.Push(v1) 71 w2.Push(v2) 72 73 if i >= windowSize { 74 // need a copy here because KS is destructive 75 copy(d1, w1.Data) 76 copy(d2, w2.Data) 77 r.Values[i] = onlinestats.KS(d1, d2) 78 } else { 79 r.Values[i] = math.NaN() 80 } 81 } 82 return []*types.MetricData{r}, nil 83 } 84 85 // TODO: Implement normal description 86 // Description is auto-generated description, based on output of https://github.com/graphite-project/graphite-web 87 func (f *kolmogorovSmirnovTest2) Description() map[string]types.FunctionDescription { 88 return map[string]types.FunctionDescription{ 89 "kolmogorovSmirnovTest2": { 90 Description: "Nonparametric test of the equality of continuous, one-dimensional probability distributions that can be used to compare a sample with a reference probability distribution (one-sample K–S test), or to compare two samples (two-sample K–S test). https://en.wikipedia.org/wiki/Kolmogorov%E2%80%93Smirnov_test", 91 Function: "kolmogorovSmirnovTest2(seriesList, seriesList, windowSize)", 92 Group: "Transform", 93 Module: "graphite.render.functions", 94 Name: "kolmogorovSmirnovTest2", 95 Params: []types.FunctionParam{ 96 { 97 Name: "seriesList", 98 Required: true, 99 Type: types.SeriesList, 100 }, 101 { 102 Name: "seriesList", 103 Required: true, 104 Type: types.SeriesList, 105 }, 106 { 107 Name: "window", 108 Required: true, 109 Type: types.Integer, 110 }, 111 }, 112 }, 113 "ksTest2": { 114 Description: "Nonparametric test of the equality of continuous, one-dimensional probability distributions that can be used to compare a sample with a reference probability distribution (one-sample K–S test), or to compare two samples (two-sample K–S test). https://en.wikipedia.org/wiki/Kolmogorov%E2%80%93Smirnov_test", 115 Function: "ksTest2(seriesList, seriesList, windowSize)", 116 Group: "Transform", 117 Module: "graphite.render.functions.custom", 118 Name: "ksTest2", 119 Params: []types.FunctionParam{ 120 { 121 Name: "seriesList", 122 Required: true, 123 Type: types.SeriesList, 124 }, 125 { 126 Name: "seriesList", 127 Required: true, 128 Type: types.SeriesList, 129 }, 130 { 131 Name: "window", 132 Required: true, 133 Type: types.Integer, 134 }, 135 }, 136 }, 137 } 138 }