Free cookie consent management tool by TermsFeed Policy Generator

Changeset 8252


Ignore:
Timestamp:
07/07/12 20:38:53 (12 years ago)
Author:
swagner
Message:

Refactored DataReducer (#1745)

Location:
trunk/sources/HeuristicLab.Operators/3.3
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Operators/3.3/DataReducer.cs

    r7395 r8252  
    7070      var values = ParameterToReduce.ActualValue;
    7171      if (values.Count() > 0) {
    72         if (values.All(x => x.GetType() == typeof(IntValue))) {
    73           List<IntValue> intValues = new List<IntValue>();
    74           values.ForEach(x => intValues.Add((IntValue)x));
    75           CalculateResult(intValues);
    76         } else if (values.All(x => x.GetType() == typeof(DoubleValue))) {
    77           List<DoubleValue> doubleValues = new List<DoubleValue>();
    78           values.ForEach(x => doubleValues.Add((DoubleValue)x));
    79           CalculateResult(doubleValues);
    80         } else if (values.All(x => x.GetType() == typeof(TimeSpanValue))) {
    81           List<TimeSpanValue> timeSpanValues = new List<TimeSpanValue>();
    82           values.ForEach(x => timeSpanValues.Add((TimeSpanValue)x));
    83           CalculateResult(timeSpanValues);
     72        if (values.All(x => typeof(IntValue).IsAssignableFrom(x.GetType()))) {
     73          CalculateResult(values.OfType<IntValue>().Select(x => x.Value), values.First().GetType());
     74        } else if (values.All(x => typeof(DoubleValue).IsAssignableFrom(x.GetType()))) {
     75          CalculateResult(values.OfType<DoubleValue>().Select(x => x.Value), values.First().GetType());
     76        } else if (values.All(x => typeof(TimeSpanValue).IsAssignableFrom(x.GetType()))) {
     77          CalculateResult(values.OfType<TimeSpanValue>().Select(x => x.Value), values.First().GetType());
    8478        } else {
    8579          throw new ArgumentException(string.Format("Type {0} is not supported by the DataReducer.", values.First().GetType()));
     
    8983    }
    9084
    91     private void CalculateResult(List<IntValue> values) {
    92       int result = 1;
    93       if (TargetParameter.ActualValue == null) TargetParameter.ActualValue = new IntValue();
    94       IntValue target = (IntValue)TargetParameter.ActualValue;
    95 
     85    #region integer reduction
     86    private void CalculateResult(IEnumerable<int> values, Type targetType) {
     87      int result;
    9688      switch (ReductionOperation.Value.Value) {
    9789        case ReductionOperations.Sum:
    98           result = values.Sum(x => x.Value);
    99           break;
    100         case ReductionOperations.Prod:
    101           values.ForEach(x => result *= x.Value);
    102           break;
    103         case ReductionOperations.Avg:
    104           result = (int)Math.Round(values.Average(x => x.Value));
    105           break;
    106         case ReductionOperations.Min:
    107           result = values.Min(x => x.Value);
    108           break;
    109         case ReductionOperations.Max:
    110           result = values.Max(x => x.Value);
    111           break;
    112         default:
    113           throw new InvalidOperationException(string.Format("Operation {0} is not supported as ReductionOperation for type: {1}.", ReductionOperation.Value.Value, result.GetType()));
    114       }
    115 
     90          result = values.Sum();
     91          break;
     92        case ReductionOperations.Product:
     93          result = values.Aggregate(1, (x, y) => x * y);
     94          break;
     95        case ReductionOperations.Count:
     96          result = values.Count();
     97          break;
     98        case ReductionOperations.Min:
     99          result = values.Min();
     100          break;
     101        case ReductionOperations.Max:
     102          result = values.Max();
     103          break;
     104        case ReductionOperations.Avg:
     105          result = (int)Math.Round(values.Average());
     106          break;
     107        case ReductionOperations.Assign:
     108          result = values.Last();
     109          break;
     110        default:
     111          throw new InvalidOperationException(string.Format("Operation {0} is not supported as ReductionOperation for type: {1}.", ReductionOperation.Value.Value, typeof(IntValue)));
     112      }
     113
     114      IntValue target;
    116115      switch (TargetOperation.Value.Value) {
    117         case ReductionOperations.Assign:
     116        case ReductionOperations.Sum:
     117          target = InitializeTarget<IntValue, int>(targetType, 0);
     118          target.Value += result;
     119          break;
     120        case ReductionOperations.Product:
     121          target = InitializeTarget<IntValue, int>(targetType, 1);
     122          target.Value = target.Value * result;
     123          break;
     124        case ReductionOperations.Min:
     125          target = InitializeTarget<IntValue, int>(targetType, int.MaxValue);
     126          target.Value = Math.Min(target.Value, result);
     127          break;
     128        case ReductionOperations.Max:
     129          target = InitializeTarget<IntValue, int>(targetType, int.MinValue);
     130          target.Value = Math.Max(target.Value, result);
     131          break;
     132        case ReductionOperations.Avg:
     133          target = InitializeTarget<IntValue, int>(targetType, result);
     134          target.Value = (int)Math.Round((target.Value + result) / 2.0);
     135          break;
     136        case ReductionOperations.Assign:
     137          target = InitializeTarget<IntValue, int>(targetType, 0);
    118138          target.Value = result;
    119139          break;
    120         case ReductionOperations.Sum:
     140        default:
     141          throw new InvalidOperationException(string.Format("Operation {0} is not supported as TargetOperation for type: {1}.", TargetOperation.Value.Value, typeof(IntValue)));
     142      }
     143    }
     144    #endregion
     145
     146    #region double reduction
     147    private void CalculateResult(IEnumerable<double> values, Type targetType) {
     148      double result;
     149      switch (ReductionOperation.Value.Value) {
     150        case ReductionOperations.Sum:
     151          result = values.Sum();
     152          break;
     153        case ReductionOperations.Product:
     154          result = values.Aggregate(1.0, (x, y) => x * y);
     155          break;
     156        case ReductionOperations.Count:
     157          result = values.Count();
     158          break;
     159        case ReductionOperations.Min:
     160          result = values.Min();
     161          break;
     162        case ReductionOperations.Max:
     163          result = values.Max();
     164          break;
     165        case ReductionOperations.Avg:
     166          result = values.Average();
     167          break;
     168        case ReductionOperations.Assign:
     169          result = values.Last();
     170          break;
     171        default:
     172          throw new InvalidOperationException(string.Format("Operation {0} is not supported as ReductionOperation for type: {1}.", ReductionOperation.Value.Value, typeof(DoubleValue)));
     173      }
     174
     175      DoubleValue target;
     176      switch (TargetOperation.Value.Value) {
     177        case ReductionOperations.Sum:
     178          target = InitializeTarget<DoubleValue, double>(targetType, 0.0);
    121179          target.Value += result;
    122180          break;
    123         case ReductionOperations.Prod:
    124           if (target.Value == 0) target.Value = 1;
    125           target.Value *= result;
    126           break;
    127         default:
    128           throw new InvalidOperationException(string.Format("Operation {0} is not supported as TargetOperation for type: {1}.", TargetOperation.Value.Value, result.GetType()));
    129       }
    130     }
    131 
    132     private void CalculateResult(List<DoubleValue> values) {
    133       double result = 1.0;
    134       if (TargetParameter.ActualValue == null) TargetParameter.ActualValue = new DoubleValue();
    135       DoubleValue target = (DoubleValue)TargetParameter.ActualValue;
    136 
     181        case ReductionOperations.Product:
     182          target = InitializeTarget<DoubleValue, double>(targetType, 1.0);
     183          target.Value = target.Value * result;
     184          break;
     185        case ReductionOperations.Min:
     186          target = InitializeTarget<DoubleValue, double>(targetType, double.MaxValue);
     187          target.Value = Math.Min(target.Value, result);
     188          break;
     189        case ReductionOperations.Max:
     190          target = InitializeTarget<DoubleValue, double>(targetType, double.MinValue);
     191          target.Value = Math.Max(target.Value, result);
     192          break;
     193        case ReductionOperations.Avg:
     194          target = InitializeTarget<DoubleValue, double>(targetType, result);
     195          target.Value = (target.Value + result) / 2.0;
     196          break;
     197        case ReductionOperations.Assign:
     198          target = InitializeTarget<DoubleValue, double>(targetType, 0.0);
     199          target.Value = result;
     200          break;
     201        default:
     202          throw new InvalidOperationException(string.Format("Operation {0} is not supported as TargetOperation for type: {1}.", TargetOperation.Value.Value, typeof(DoubleValue)));
     203      }
     204    }
     205    #endregion
     206
     207    #region TimeSpan reduction
     208    private void CalculateResult(IEnumerable<TimeSpan> values, Type targetType) {
     209      TimeSpan result;
    137210      switch (ReductionOperation.Value.Value) {
    138211        case ReductionOperations.Sum:
    139           result = values.Sum(x => x.Value);
    140           break;
    141         case ReductionOperations.Prod:
    142           values.ForEach(x => result *= x.Value);
    143           break;
    144         case ReductionOperations.Avg:
    145           result = values.Average(x => x.Value);
    146           break;
    147         case ReductionOperations.Min:
    148           result = values.Min(x => x.Value);
    149           break;
    150         case ReductionOperations.Max:
    151           result = values.Max(x => x.Value);
    152           break;
    153         default:
    154           throw new InvalidOperationException(string.Format("Operation {0} is not supported as ReductionOperation for type: {1}.", ReductionOperation.Value.Value, result.GetType()));
    155       }
    156 
     212          result = values.Aggregate(new TimeSpan(), (x, y) => x + y);
     213          break;
     214        case ReductionOperations.Min:
     215          result = values.Min();
     216          break;
     217        case ReductionOperations.Max:
     218          result = values.Max();
     219          break;
     220        case ReductionOperations.Avg:
     221          result = TimeSpan.FromMilliseconds(values.Average(x => x.TotalMilliseconds));
     222          break;
     223        case ReductionOperations.Assign:
     224          result = values.Last();
     225          break;
     226        default:
     227          throw new InvalidOperationException(string.Format("Operation {0} is not supported as ReductionOperation for type: {1}.", ReductionOperation.Value.Value, typeof(TimeSpanValue)));
     228      }
     229
     230      TimeSpanValue target;
    157231      switch (TargetOperation.Value.Value) {
    158         case ReductionOperations.Assign:
     232        case ReductionOperations.Sum:
     233          target = InitializeTarget<TimeSpanValue, TimeSpan>(targetType, new TimeSpan());
     234          target.Value += result;
     235          break;
     236        case ReductionOperations.Min:
     237          target = InitializeTarget<TimeSpanValue, TimeSpan>(targetType, TimeSpan.MaxValue);
     238          target.Value = target.Value < result ? target.Value : result;
     239          break;
     240        case ReductionOperations.Max:
     241          target = InitializeTarget<TimeSpanValue, TimeSpan>(targetType, TimeSpan.MinValue);
     242          target.Value = target.Value > result ? target.Value : result;
     243          break;
     244        case ReductionOperations.Avg:
     245          target = InitializeTarget<TimeSpanValue, TimeSpan>(targetType, result);
     246          target.Value = TimeSpan.FromMilliseconds((target.Value.TotalMilliseconds + result.TotalMilliseconds) / 2);
     247          break;
     248        case ReductionOperations.Assign:
     249          target = InitializeTarget<TimeSpanValue, TimeSpan>(targetType, new TimeSpan());
    159250          target.Value = result;
    160251          break;
    161         case ReductionOperations.Sum:
    162           target.Value += result;
    163           break;
    164         case ReductionOperations.Prod:
    165           if (target.Value == 0.0) target.Value = 1.0;
    166           target.Value *= result;
    167           break;
    168         default:
    169           throw new InvalidOperationException(string.Format("Operation {0} is not supported as TargetOperation for type: {1}.", TargetOperation.Value.Value, result.GetType()));
    170       }
    171     }
    172 
    173     private void CalculateResult(List<TimeSpanValue> values) {
    174       TimeSpan result = TimeSpan.Zero;
    175       if (TargetParameter.ActualValue == null) TargetParameter.ActualValue = new TimeSpanValue();
    176       TimeSpanValue target = (TimeSpanValue)TargetParameter.ActualValue;
    177 
    178       switch (ReductionOperation.Value.Value) {
    179         case ReductionOperations.Sum:
    180           values.ForEach(x => result = result.Add(x.Value));
    181           break;
    182         case ReductionOperations.Avg:
    183           double avg = values.Average(x => x.Value.TotalMilliseconds);
    184           result = TimeSpan.FromMilliseconds(avg);
    185           break;
    186         case ReductionOperations.Min:
    187           result = values.Min(x => x.Value);
    188           break;
    189         case ReductionOperations.Max:
    190           result = values.Max(x => x.Value);
    191           break;
    192         default:
    193           throw new InvalidOperationException(string.Format("Operation {0} is not supported as ReductionOperation for type: {1}.", ReductionOperation.Value.Value, result.GetType()));
    194       }
    195 
    196       switch (TargetOperation.Value.Value) {
    197         case ReductionOperations.Assign:
    198           target.Value = result;
    199           break;
    200         case ReductionOperations.Sum:
    201           target.Value += result;
    202           break;
    203         default:
    204           throw new InvalidOperationException(string.Format("Operation {0} is not supported as TargetOperation for type: {1}.", TargetOperation.Value.Value, result.GetType()));
    205       }
    206     }
     252        default:
     253          throw new InvalidOperationException(string.Format("Operation {0} is not supported as TargetOperation for type: {1}.", TargetOperation.Value.Value, typeof(TimeSpanValue)));
     254      }
     255    }
     256    #endregion
     257
     258    #region helpers
     259    private T1 InitializeTarget<T1, T2>(Type targetType, T2 initialValue)
     260      where T1 : ValueTypeValue<T2>
     261      where T2 : struct {
     262      T1 target = (T1)TargetParameter.ActualValue;
     263      if (target == null) {
     264        target = (T1)Activator.CreateInstance(targetType);
     265        TargetParameter.ActualValue = target;
     266        target.Value = initialValue;
     267      }
     268      return target;
     269    }
     270    #endregion
    207271  }
    208272}
  • trunk/sources/HeuristicLab.Operators/3.3/ReductionOperations.cs

    r7395 r8252  
    2222namespace HeuristicLab.Operators {
    2323  public enum ReductionOperations {
    24     Assign,
    2524    Sum,
    26     Prod,
     25    Product,
     26    Count,
    2727    Min,
    2828    Max,
    29     Avg
     29    Avg,
     30    Assign
    3031  }
    3132}
Note: See TracChangeset for help on using the changeset viewer.