github.com/go-graphite/carbonapi@v0.17.0/expr/functions/pearson/function.go (about) 1 package pearson 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 pearson 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 := &pearson{} 23 functions := []string{"pearson"} 24 for _, n := range functions { 25 res = append(res, interfaces.FunctionMetadata{Name: n, F: f}) 26 } 27 return res 28 } 29 30 // pearson(series, series, windowSize) 31 func (f *pearson) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Expr, from, until int64, values map[parser.MetricRequest][]*types.MetricData) ([]*types.MetricData, error) { 32 arg1, err := helper.GetSeriesArg(ctx, eval, e.Arg(0), from, until, values) 33 if err != nil { 34 return nil, err 35 } 36 37 arg2, err := helper.GetSeriesArg(ctx, eval, e.Arg(1), from, until, values) 38 if err != nil { 39 return nil, err 40 } 41 42 if len(arg1) != 1 || len(arg2) != 1 { 43 return nil, types.ErrWildcardNotAllowed 44 } 45 46 a1 := arg1[0] 47 a2 := arg2[0] 48 49 windowSize, err := e.GetIntArg(2) 50 if err != nil { 51 return nil, err 52 } 53 54 w1 := &types.Windowed{Data: make([]float64, windowSize)} 55 w2 := &types.Windowed{Data: make([]float64, windowSize)} 56 57 r := a1.CopyLinkTags() 58 r.Name = "pearson(" + a1.Name + "," + a2.Name + "," + e.Arg(2).StringValue() + ")" 59 r.Values = make([]float64, len(a1.Values)) 60 r.StartTime = from 61 r.StopTime = r.StartTime + int64(len(r.Values))*r.StepTime 62 63 for i, v1 := range a1.Values { 64 v2 := a2.Values[i] 65 66 w1.Push(v1) 67 w2.Push(v2) 68 if i >= windowSize-1 { 69 r.Values[i] = onlinestats.Pearson(w1.Data, w2.Data) 70 } else { 71 r.Values[i] = math.NaN() 72 } 73 } 74 75 return []*types.MetricData{r}, nil 76 } 77 78 func (f *pearson) Description() map[string]types.FunctionDescription { 79 return map[string]types.FunctionDescription{ 80 "pearson": { 81 Description: ` 82 Implementation of Pearson product-moment correlation coefficient (PMCC) function(s) 83 84 .. code-block:: none 85 86 pearson( seriesA, seriesB, windowSize ) 87 88 89 Calculate Pearson score between seriesA and seriesB over windowSize. 90 91 Note: 92 Pearson will discard epochs where either series has a missing value. 93 94 Additionally there is a special case where a series (or window) containing only zeros leads to a division-by-zero 95 and will manifest as if the entire window/series had missing values.`, 96 Function: "pearson(seriesList, seriesList, windowSize)", 97 Group: "Transform", 98 Module: "graphite.render.functions.custom", 99 Name: "pearsonClosest", 100 Params: []types.FunctionParam{ 101 { 102 Name: "seriesList", 103 Required: true, 104 Type: types.SeriesList, 105 }, 106 { 107 Name: "seriesList", 108 Required: true, 109 Type: types.SeriesList, 110 }, 111 { 112 Name: "windowSize", 113 Required: true, 114 Type: types.Integer, 115 }, 116 }, 117 NameChange: true, // name changed 118 ValuesChange: true, // values changed 119 }, 120 } 121 }