changeset 727:c6d4ea05a2d0

adding ability to deal with multivariate indicators
author Nicolas Saunier <nicolas.saunier@polymtl.ca>
date Mon, 10 Aug 2015 01:06:59 -0400
parents 43ae3a1af290
children dad99b86a104 e7ff0f60fef8
files python/indicators.py python/moving.py
diffstat 2 files changed, 40 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/python/indicators.py	Fri Aug 07 13:07:53 2015 -0400
+++ b/python/indicators.py	Mon Aug 10 01:06:59 2015 -0400
@@ -8,6 +8,9 @@
 from numpy import array, arange, mean, floor, mean
 
 
+def multivariateName(indicatorNames):
+    return '_'.join(indicatorNames)
+
 # need for a class representing the indicators, their units, how to print them in graphs...
 class TemporalIndicator(object):
     '''Class for temporal indicators
@@ -83,7 +86,27 @@
         plot([(x+timeShift)/xfactor for x in time], [self.values[i]/yfactor for i in time], options+marker, **kwargs)
         if self.maxValue:
             ylim(ymax = self.maxValue)
-	
+
+    @classmethod
+    def createMultivariate(cls, indicators):
+        '''Creates a new temporal indicator where the value at each instant is a list 
+        of the indicator values at the instant, in the same order
+        the time interval will be the union of the time intervals of the indicators
+        name is concatenation of the indicator names'''
+        if len(indicators) < 2:
+            print('Error creating multivariate indicator with only {} indicator'.format(len(indicators)))
+            return None
+
+        timeInterval = moving.TimeInterval.unionIntervals([indic.getTimeInterval() for indic in indicators])
+        values = {}
+        for t in timeInterval:
+            tmpValues = [indic[t] for indic in indicators]
+            uniqueValues = set(tmpValues)
+            if len(uniqueValues) >= 2 or uniqueValues.pop() is not None:
+                values[t] = tmpValues
+        return cls(multivariateName([indic.name for indic in indicators]), values)
+
+# TODO static method avec class en parametre pour faire des indicateurs agrege, list par instant
 
 def l1Distance(x, y): # lambda x,y:abs(x-y)
     if x is None or y is None:
@@ -91,12 +114,20 @@
     else:
         return abs(x-y)
 
+def multiL1Matching(x, y, thresholds, proportionMatching=1.):
+    n = 0
+    nDimensions = len(x)
+    for i in range(nDimensions):
+        if l1Distance(x[i], y[i]) <= thresholds[i]:
+            n += 1
+    return n >= nDimensions*proportionMatching
+
 from utils import LCSS as utilsLCSS
 
 class LCSS(utilsLCSS):
     '''Adapted LCSS class for indicators, same pattern'''
     def __init__(self, similarityFunc, delta = float('inf'), minLength = 0, aligned = False, lengthFunc = min):
-        utilsLCSS.__init__(self, similarityFunc, delta, aligned, lengthFunc)
+        utilsLCSS.__init__(self, similarityFunc = similarityFunc, delta = delta, aligned = aligned, lengthFunc = lengthFunc)
         self.minLength = minLength
 
     def checkIndicator(self, indicator):
--- a/python/moving.py	Fri Aug 07 13:07:53 2015 -0400
+++ b/python/moving.py	Mon Aug 10 01:06:59 2015 -0400
@@ -78,12 +78,13 @@
         else:
             return None
 
-def unionIntervals(intervals):
-    'returns the smallest interval containing all intervals'
-    inter = intervals[0]
-    for i in intervals[1:]:
-        inter = Interval.union(inter, i)
-    return inter
+    @classmethod
+    def unionIntervals(cls, intervals):
+        'returns the smallest interval containing all intervals'
+        inter = cls(intervals[0].first, intervals[0].last)
+        for i in intervals[1:]:
+            inter = cls.union(inter, i)
+        return inter
 
 
 class TimeInterval(Interval):