private double[] Boundaries(BoundariesType type) { var boundaries = new double[_levels + 1]; var reconstructionPoints = new double[_levels]; KeyValuePair <C, B> firstItem; _di41R.TryGetFirst(out firstItem); KeyValuePair <C, B> lastItem; _di41R.TryGetLast(out lastItem); var accDis = new SortedDictionary <int, int>(); var lockOnMe = new object(); _accStats = new AccumulationStats <C, I, M>(_di41R, firstItem.Key, lastItem.Key, accDis, lockOnMe); _accStats.AccDistribution(); // TODO: this could be empty: no last item double r = accDis.Last().Key; double delta = r / _levels; boundaries[0] = 0; boundaries[boundaries.Length - 1] = accDis.Last().Key; // in other words: calculates decision threshold for (int i = 1; i < boundaries.Length - 1; i++) { boundaries[i] = boundaries[i - 1] + delta; } if (type == BoundariesType.Uniform) { return(boundaries); } bool distortionReductionRequired = true; while (distortionReductionRequired) { // in other words: calculates new representitive levels double sum = 0; int count = 0; for (int i = 0; i < reconstructionPoints.Length; i++) { sum = 0; count = 0; foreach (var item in accDis) { if (boundaries[i] <= item.Key && item.Key < boundaries[i + 1]) { sum += item.Key * item.Value; count += item.Value; } } if (count == 0) { reconstructionPoints[i] = (boundaries[i + 1] + boundaries[i]) / 2; } else { reconstructionPoints[i] = sum / count; } } reconstructionPoints[reconstructionPoints.Length - 1] = (sum + accDis.Keys.Last()) / (count + 1); // this should be: (count + laskey.value) !! double t; distortionReductionRequired = false; for (int i = 1; i < boundaries.Length - 1; i++) { t = (reconstructionPoints[i - 1] + reconstructionPoints[i]) / 2; if (t != boundaries[i]) { distortionReductionRequired = true; } boundaries[i] = t; } } return(boundaries); }
private void Quantization(BoundariesType type) { var boundaries = Boundaries(type); var partitions = new Dictionary <int, int>(); for (int i = 0; i < boundaries.Length - 1; i++) { for (int j = (int)Math.Round(boundaries[i]); j < Math.Round(boundaries[i + 1]); j++) { partitions.Add(j, i); } } partitions.Add((int)boundaries[boundaries.Length - 1], boundaries.Length - 2); int currentPartition = 0; int previousPartition = 0; //int currentAccumulation = 0; int minAccumulation = int.MaxValue; int maxAccumulation = 0; int intervalsCount = 0; //bool startNewBlock = true; C currentBlockLeftEnd = _left; _tLambdas = new HashSet <uint>(); C currentBlockRightEnd = default(C); var enumerator = _di41R.EnumerateRange(_left, _right).GetEnumerator(); if (!enumerator.MoveNext()) { return; // i.e., no snapshot is available in given range to create second resolution. } currentBlockLeftEnd = enumerator.Current.Key; currentBlockRightEnd = enumerator.Current.Key; foreach (var lambda in enumerator.Current.Value.lambda) { if (!_tLambdas.Remove(lambda.atI)) { _tLambdas.Add(lambda.atI); } } intervalsCount = _tLambdas.Count; _atI = new uint[_tLambdas.Count]; _tLambdas.CopyTo(_atI); maxAccumulation = enumerator.Current.Value.accumulation; minAccumulation = enumerator.Current.Value.accumulation; previousPartition = partitions[enumerator.Current.Value.accumulation]; while (enumerator.MoveNext()) { foreach (var lambda in enumerator.Current.Value.lambda) { if (!_tLambdas.Remove(lambda.atI)) { _tLambdas.Add(lambda.atI); } } currentPartition = partitions[enumerator.Current.Value.accumulation]; if (currentPartition != previousPartition) { Update(leftEnd: currentBlockLeftEnd, rightEnd: currentBlockRightEnd /*snapshot.Key*/, minAccumulation: minAccumulation, maxAccumulation: maxAccumulation, count: intervalsCount); maxAccumulation = 0; minAccumulation = int.MaxValue; intervalsCount = _tLambdas.Count; currentBlockLeftEnd = enumerator.Current.Key; _atI = new uint[_tLambdas.Count]; _tLambdas.CopyTo(_atI); } else { intervalsCount += enumerator.Current.Value.lambda.Count - enumerator.Current.Value.omega; } maxAccumulation = Math.Max(maxAccumulation, enumerator.Current.Value.accumulation); minAccumulation = Math.Min(minAccumulation, enumerator.Current.Value.accumulation); previousPartition = currentPartition; currentBlockRightEnd = enumerator.Current.Key; } /*foreach (var snapshot in _di41R.EnumerateRange(_left, _right)) * { * foreach (var lambda in snapshot.Value.lambda) * if (!_tLambdas.Remove(lambda.atI)) * _tLambdas.Add(lambda.atI); * * currentAccumulation = snapshot.Value.accumulation; * currentPartition = partitions[currentAccumulation]; * * if (startNewBlock) * { * currentBlockLeftEnd = snapshot.Key; * startNewBlock = false; * intervalsCount = _tLambdas.Count; * _atI = new uint[_tLambdas.Count]; * _tLambdas.CopyTo(_atI); * } * else * { * if (currentPartition != previousPartition) * { * Update(leftEnd: currentBlockLeftEnd, rightEnd: currentBlockRightEnd snapshot.Key, minAccumulation: minAccumulation, maxAccumulation: maxAccumulation, count: intervalsCount); * maxAccumulation = 0; * minAccumulation = int.MaxValue; * startNewBlock = true; * } * * intervalsCount += snapshot.Value.lambda.Count - snapshot.Value.omega; * } * * maxAccumulation = Math.Max(maxAccumulation, currentAccumulation); * minAccumulation = Math.Min(minAccumulation, currentAccumulation); * previousPartition = currentPartition; * currentBlockRightEnd = snapshot.Key; * }*/ // make sure I need this: Update(leftEnd: currentBlockLeftEnd, rightEnd: _right, minAccumulation: minAccumulation, maxAccumulation: maxAccumulation, count: intervalsCount); _addedBlocks.TryAdd(_left, _bCounter.value); }