public AggregatedDataRange GenerateReverseAverage(string name, TimeRange timeRange, int[] aggregationLevels, int aggregationLevel, double minValue, double maxValue) { if (minValue <= 0) { throw new Exception("Can only generate random data above zero."); } var descendingAggregationLevels = aggregationLevels.OrderByDescending(x => x).ToArray(); var highestAggregationLevel = descendingAggregationLevels[0]; var lowestAggregationLevel = descendingAggregationLevels[descendingAggregationLevels.Length - 1]; var aggregationLevelIndex = Array.IndexOf(descendingAggregationLevels, aggregationLevel); var quantisedLowTime = GetQuantisedTimeBeforeOrOn(highestAggregationLevel, timeRange.Min); var quantisedHighTime = GetQuantisedTimeAfterOrOn(highestAggregationLevel, timeRange.Max); var variance = (maxValue - minValue) / 10; var rangeValues = new LowestAggregationValues(quantisedLowTime, quantisedHighTime, lowestAggregationLevel); GenerateReverseAverageForRange(name, quantisedLowTime, quantisedHighTime, timeRange, descendingAggregationLevels, aggregationLevelIndex, minValue, maxValue, variance, rangeValues); List <double> data = new List <double>(); for (var time = quantisedLowTime; time <= quantisedHighTime; time += aggregationLevel) { if (time < timeRange.Min) { continue; } var value = rangeValues.GetValue(time); data.Add(time); data.Add(value); } return(new AggregatedDataRange(timeRange, data, aggregationLevel)); }
private void GenerateReverseAverageRecursive(string name, long lowTime, long highTime, double highValue, TimeRange timeRange, int[] aggregationLevels, int aggregationLevelIndex, int maxAggregationLevelIndex, double variance, LowestAggregationValues lowestAggregationValues) { if (aggregationLevelIndex > maxAggregationLevelIndex) { return; } if (lowTime > timeRange.Max || highTime < timeRange.Min) { return; } var aggregationLevel = aggregationLevels[aggregationLevelIndex]; var nextAggregationIndex = aggregationLevelIndex + 1; var nextAggregationLevel = aggregationLevels[nextAggregationIndex]; var aggregationMultiplier = nextAggregationLevel / aggregationLevel; var nextVariance = aggregationMultiplier * variance; var childTimes = GetQuantisedTimesBetweenOrAtEnd(aggregationLevel, lowTime, highTime); foreach (var childTime in childTimes) { var childBeforeTime = childTime - aggregationLevel; var childBeforeValue = lowestAggregationValues.GetValue(childBeforeTime); var childValue = lowestAggregationValues.GetOrAddValue(childTime, () => _valueGenerator.GenerateValueBetween(name, childTime, childBeforeTime, highTime, childBeforeValue, highValue, variance)); GenerateReverseAverageRecursive(name, childBeforeTime, childTime, childValue, timeRange, aggregationLevels, nextAggregationIndex, maxAggregationLevelIndex, nextVariance, lowestAggregationValues); } }
private void GenerateReverseAverageForRange(string name, long lowTime, long highTime, TimeRange timeRange, int[] aggregationLevels, int maxAggregationLevelIndex, double minValue, double maxValue, double variance, LowestAggregationValues lowestAggregationValues) { // Generate min and max value var lowValue = _valueGenerator.GenerateValue(name, lowTime, minValue, maxValue); var highValue = _valueGenerator.GenerateValue(name, highTime, minValue, maxValue); // Add to data array lowestAggregationValues.AddValue(lowTime, lowValue); lowestAggregationValues.AddValue(highTime, highValue); // Generate child points GenerateReverseAverageRecursive(name, lowTime, highTime, highValue, timeRange, aggregationLevels, 1, maxAggregationLevelIndex, variance, lowestAggregationValues); }