Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
09/27/16 16:30:54 (8 years ago)
Author:
gkronber
Message:

changed interpreter and grammar to smooth ch and ins uptake using a compartement model

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.Problems.GeneticProgramming.BloodGlucosePrediction/Interpreter.cs

    r13870 r14310  
    22using System.Collections;
    33using System.Collections.Generic;
     4using System.Collections.ObjectModel;
    45using System.Collections.Specialized;
    56using System.Drawing.Design;
    67using System.Linq;
     8using HeuristicLab.Common;
    79using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
    810using HeuristicLab.Problems.DataAnalysis;
     
    1517      public double[] realIns;
    1618      public double[] realCh;
    17       public double[] predGluc;
     19      public Dictionary<ISymbolicExpressionTreeNode, double[]> precalculatedValues;
    1820    }
    1921
     
    2527        realIns = dataset.GetDoubleValues("Insuline", rows).ToArray(),
    2628        realCh = dataset.GetDoubleValues("CH", rows).ToArray(),
     29        precalculatedValues = CreatePrecalculatedValues(model, dataset)
    2730      };
    28       data.predGluc = new double[data.realGluc.Length];
    29       Array.Copy(data.realGluc, data.predGluc, data.predGluc.Length);
    30       for (int k = 0; k < data.predGluc.Length; k++) {
     31      var predictions = new double[targetGluc.Length];
     32      var rowsEnumerator = rows.GetEnumerator();
     33      for (int k = 0; k < predictions.Length; k++, rowsEnumerator.MoveNext()) {
    3134        if (double.IsNaN(targetGluc[k])) {
    32           data.predGluc[k] = double.NaN;
     35          predictions[k] = double.NaN;
    3336        } else {
    34           var rawPred = InterpretRec(model, data, k);
    35           data.predGluc[k] = Math.Max(0, Math.Min(400, rawPred)); // limit output values of the model to 0 ... 400
    36         }
    37       }
    38       return data.predGluc;
     37          var rawPred = InterpretRec(model, data, rowsEnumerator.Current);
     38          predictions[k] = rawPred;
     39        }
     40      }
     41      return predictions;
     42    }
     43
     44    private static Dictionary<ISymbolicExpressionTreeNode, double[]> CreatePrecalculatedValues(ISymbolicExpressionTreeNode root, IDataset dataset) {
     45      var dict = new Dictionary<ISymbolicExpressionTreeNode, double[]>();
     46      // here we integrate ins or ch inputs over the whole day to generate smoothed ins/ch values with the same number of rows
     47      // the integrated values are reset to zero whenever a new evluation period starts
     48      foreach (var node in root.IterateNodesPrefix()) {
     49        var curvedInsNode = node as CurvedInsVariableTreeNode;
     50        var curvedChNode = node as CurvedChVariableTreeNode;
     51        if (curvedInsNode != null) {
     52          dict.Add(curvedInsNode, Integrate(curvedInsNode, dataset));
     53        } else if (curvedChNode != null) {
     54          dict.Add(curvedChNode, Integrate(curvedChNode, dataset));
     55        }
     56      }
     57      return dict;
     58    }
     59
     60    private static double[] Integrate(CurvedInsVariableTreeNode node, IDataset dataset) {
     61      // d Q1 / dt = ins(t) - alpha * Q1(t)
     62      // d Q2 / dt = alpha * (Q1(t) - Q2(t))
     63      // S = Q1(t) + Q2(t)
     64      var alpha = node.Alpha;
     65
     66      var ins = dataset.GetReadOnlyDoubleValues("Insuline");
     67      var time = dataset.GetReadOnlyDoubleValues("HourMin").ToArray();
     68
     69      // TODO reset for new time intervals
     70
     71      double q1, q2, q1_prev, q2_prev;
     72      // starting values: zeros
     73      q1 = q2 = q1_prev = q2_prev = 0;
     74      double[] s = new double[dataset.Rows];
     75
     76      for (int t = 1; t < dataset.Rows; t++) {
     77        if (IsStartOfNewPeriod(time, t)) {
     78          q1 = q2 = q1_prev = q2_prev = 0;
     79        }
     80        q1 = q1_prev + ins[t] - alpha * q1_prev;
     81        q2 = q2_prev + alpha * (q1_prev - q2_prev);
     82        s[t] = q1 + q2;
     83        q1_prev = q1;
     84        q2_prev = q2;
     85
     86      }
     87      return s;
     88    }
     89
     90    private static bool IsStartOfNewPeriod(double[] time, int t) {
     91      return t == 0 ||
     92             (time[t].IsAlmost(2005) && !time[t - 1].IsAlmost(2000));
     93    }
     94
     95
     96    private static double[] Integrate(CurvedChVariableTreeNode node, IDataset dataset) {
     97      // d Q1 / dt = ins(t) - alpha * Q1(t)
     98      // d Q2 / dt = alpha * (Q1(t) - Q2(t))
     99      // S = Q1(t) + Q2(t)
     100      var alpha = node.Alpha;
     101
     102      var ch = dataset.GetReadOnlyDoubleValues("CH");
     103      var time = dataset.GetReadOnlyDoubleValues("HourMin").ToArray();
     104
     105      // TODO reset for new time intervals
     106
     107      double q1, q2, q1_prev, q2_prev;
     108      // starting values: zeros
     109      q1 = q2 = q1_prev = q2_prev = 0;
     110      double[] s = new double[dataset.Rows];
     111
     112      for (int t = 1; t < dataset.Rows; t++) {
     113        if (IsStartOfNewPeriod(time, t)) {
     114          q1 = q2 = q1_prev = q2_prev = 0;
     115        }
     116        q1 = q1_prev + ch[t] - alpha * q1_prev;
     117        q2 = q2_prev + alpha * (q1_prev - q2_prev);
     118        s[t] = q1 + q2;
     119        q1_prev = q1;
     120        q2_prev = q2;
     121
     122      }
     123      return s;
    39124    }
    40125
     
    102187        }
    103188      } else if (node.Symbol is PredictedGlucoseVariableSymbol) {
    104         var n = (PredictedGlucoseVariableTreeNode)node;
    105         return n.Weight * data.predGluc[k + n.RowOffset];
     189        throw new NotSupportedException();
    106190      } else if (node.Symbol is RealGlucoseVariableSymbol) {
    107191        var n = (RealGlucoseVariableTreeNode)node;
    108         return n.Weight * data.realGluc[k + n.RowOffset];
     192        if (k + n.RowOffset < 0 || k + n.RowOffset >= data.realGluc.Length) return double.NaN;
     193        return data.realGluc[k + n.RowOffset];
    109194      } else if (node.Symbol is CurvedChVariableSymbol) {
    110         var n = (CurvedChVariableTreeNode)node;
    111         double prevVal;
    112         int prevValDistance;
    113         GetPrevDataAndDistance(data.realCh, k, out prevVal, out prevValDistance, maxDistance: 48);
    114         return n.Weight * prevVal * Beta(prevValDistance / 48.0, n.Alpha, n.Beta);
     195        return data.precalculatedValues[node][k];
    115196      } else if (node.Symbol is RealInsulineVariableSymbol) {
    116         var n = (RealInsulineVariableTreeNode)node;
    117         return n.Weight * data.realIns[k + n.RowOffset];
     197        throw new NotSupportedException();
    118198      } else if (node.Symbol is CurvedInsVariableSymbol) {
    119         var n = (CurvedInsVariableTreeNode)node;
    120         double maxVal;
    121         int maxValDistance;
    122         var sum = GetSumOfValues(48, k, data.realIns);
    123 
    124         GetMaxValueAndDistance(data.realIns, k, out maxVal, out maxValDistance, maxDistance: 48);
    125         return n.Weight * (sum - maxVal) * maxVal * Beta(maxValDistance / 48.0, n.Alpha, n.Beta);
     199        return data.precalculatedValues[node][k];
    126200      } else if (node.Symbol is Constant) {
    127201        var n = (ConstantTreeNode)node;
     
    135209      return 1.0 / alglib.beta(alpha, beta) * Math.Pow(x, alpha - 1) * Math.Pow(1 - x, beta - 1);
    136210    }
    137 
    138     private static void GetPrevDataAndDistance(double[] vals, int k, out double val, out int dist, int maxDistance = 48, double threshold = 0.0) {
    139       // look backward from the current idx k and find the first value above the threshold
    140       for (int i = k; i >= 0 && i >= (k - maxDistance); i--) {
    141         if (vals[i] > threshold) {
    142           val = vals[i];
    143           dist = k - i;
    144           return;
    145         }
    146       }
    147       val = 0;
    148       dist = maxDistance;
    149     }
    150 
    151     private static double GetSumOfValues(int windowSize, int k, double[] vals) {
    152       var sum = 0.0;
    153       for (int i = k; i >= 0 && i >= k - windowSize; i--)
    154         sum += vals[i];
    155       return sum;
    156     }
    157 
    158     private static void GetMaxValueAndDistance(double[] vals, int k, out double maxVal, out int dist, int maxDistance = 48) {
    159       // look backward from the current idx k and find the max value and it's distance
    160       maxVal = vals[k];
    161       dist = 0;
    162       for (int i = k; i >= 0 && i >= (k - maxDistance); i--) {
    163         if (vals[i] > maxVal) {
    164           maxVal = vals[i];
    165           dist = k - i;
    166         }
    167       }
    168     }
    169211  }
    170212}
Note: See TracChangeset for help on using the changeset viewer.