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  }