public void ToHyperrectangle_test(int x, int y, int w, int h) { Hyperrectangle expected = new Hyperrectangle(x, y, w, h); Rectangle target = new Rectangle(x, y, w, h); Hyperrectangle actual = target.ToHyperrectangle(); Assert.AreEqual(expected.ToString("0.##"), actual.ToString("0.##")); }
public void ToHyperrectangleF_test(double x, double y, double w, double h) { Hyperrectangle expected = new Hyperrectangle(x, y, w, h); RectangleF target = new RectangleF((float)x, (float)y, (float)w, (float)h); Hyperrectangle actual = target.ToHyperrectangle(); Assert.AreEqual(expected.ToString("0.##"), actual.ToString("0.##")); }
public void ToRectangleF_test(double x, double y, double w, double h) { Hyperrectangle target = new Hyperrectangle(x, y, w, h); RectangleF expected = new RectangleF((float)x, (float)y, (float)w, (float)h); RectangleF actual = target.ToRectangleF(); Assert.AreEqual(expected, actual); }
public void ToRectangle_test(int x, int y, int w, int h) { Hyperrectangle target = new Hyperrectangle(x, y, w, h); Rectangle expected = new Rectangle(x, y, w, h); Rectangle actual = target.ToRectangle(); Assert.AreEqual(expected, actual); }
// helper: get the right rectangle of node inside parent's rect private static Hyperrectangle rightRect(Hyperrectangle hyperrect, TNode node) { //var rect = hyperrect.ToRectangle(); //return (node.Axis != 0 ? // Rectangle.FromLTRB(rect.Left, (int)node.Position[1], rect.Right, rect.Bottom) : // Rectangle.FromLTRB((int)node.Position[0], rect.Top, rect.Right, rect.Bottom)).ToHyperrectangle(); Hyperrectangle copy = new Hyperrectangle((double[])hyperrect.Min.Clone(), (double[])hyperrect.Max.Clone()); copy.Min[node.Axis] = node.Position[node.Axis]; return(copy); }
/// <summary> /// Constructs a CLTree from the provided data. /// </summary> /// <param name="data">The data to use in constructing the tree</param> /// <param name="factory">The factory used to create features</param> /// <param name="numFeatures">The number of features to use</param> /// <returns>A CLTree</returns> public static CLTree <T> Compute(List <T> data, IFeatureFactory <T, float[]> factory, int numFeatures) { Hyperrectangle <float> bounds = new Hyperrectangle <float>(numFeatures, float.MaxValue, float.MinValue); fillFeatureValues(factory, numFeatures, data); for (int i = 0; i < numFeatures; i++) { bounds.MinimumBound[i] = _featureValues[i].Min(); bounds.MaximumBound[i] = _featureValues[i].Max(); } return(new CLTree <T>(split(Enumerable.Range(0, data.Count).ToList(), data.Count, bounds), _buildFeatures)); }
/// <summary> /// Convert the given hyperrectangle in to a System.Drawing.RectangleF. /// </summary> /// public static RectangleF ToRectangleF(this Hyperrectangle rect) { if (rect.NumberOfDimensions != 2) { throw new ArgumentException("rect"); } return(RectangleF.FromLTRB( left: (float)rect.Min[0], top: (float)rect.Min[1], right: (float)rect.Max[0], bottom: (float)rect.Max[1])); }
public void Contains_test( int rx, int ry, int rw, int rh, int x, int y, bool contains) { Hyperrectangle hr = new Hyperrectangle(rx, ry, rw, rh); Rectangle rf = new Rectangle(rx, ry, rw, rh); bool expected = rf.Contains(x, y); bool actual = hr.Contains(x, y); Assert.AreEqual(expected, actual); Assert.AreEqual(expected, contains); }
public void Contains_test( double rx, double ry, double rw, double rh, double x, double y, bool contains) { Hyperrectangle hr = new Hyperrectangle(rx, ry, rw, rh); RectangleF rf = new RectangleF((float)rx, (float)ry, (float)rw, (float)rh); bool expected = rf.Contains((float)x, (float)y); bool actual = hr.Contains(x, y); Assert.AreEqual(expected, actual); Assert.AreEqual(expected, contains); }
private void minMaxFromChild(KDNode child) { if (child == null) { return; } if (_bounds == null) { _bounds = child._bounds.Clone() as Hyperrectangle <float>; } else { _bounds += child._bounds; } }
public void IntersectsWith_test( double x1, double y1, double w1, double h1, double x2, double y2, double w2, double h2, bool intersects) { Hyperrectangle r1 = new Hyperrectangle(x1, y1, w1, h1); Hyperrectangle r2 = new Hyperrectangle(x2, y2, w2, h2); RectangleF f1 = new RectangleF((float)x1, (float)y1, (float)w1, (float)h1); RectangleF f2 = new RectangleF((float)x2, (float)y2, (float)w2, (float)h2); bool expected = f1.IntersectsWith(f2); bool actual = r1.IntersectsWith(r2); Assert.AreEqual(expected, actual); Assert.AreEqual(expected, intersects); }
public void IntersectsWith_test( int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2, bool intersects) { Hyperrectangle r1 = new Hyperrectangle(x1, y1, w1, h1); Hyperrectangle r2 = new Hyperrectangle(x2, y2, w2, h2); RectangleF f1 = new RectangleF(x1, y1, w1, h1); RectangleF f2 = new RectangleF(x2, y2, w2, h2); bool expected = f1.IntersectsWith(f2); bool actual = r1.IntersectsWith(r2); Assert.AreEqual(expected, actual); Assert.AreEqual(expected, intersects); }
private IList <TNode> getNodesInsideRegion(TNode node, Hyperrectangle region, Hyperrectangle subRegion) { var result = new List <TNode>(); if (node != null && region.IntersectsWith(subRegion)) { if (region.Contains(node.Position)) { result.Add(node); } result.AddRange(getNodesInsideRegion(node.Left, region, leftRect(subRegion, node))); result.AddRange(getNodesInsideRegion(node.Right, region, rightRect(subRegion, node))); } return(result); }
/// <summary> /// Generates code from the tree which will classify a point as belonging to a particular cluster. /// </summary> /// <returns>Generated code</returns> public string GenerateCode() { FillFeaturesArray(); InferBounds(); StringBuilder sb = new StringBuilder(); sb.Append("short getLabel(float[] x)\n{\n"); for (int i = 0; i < _features.Length; i++) { sb.AppendFormat("\tfloat {0}\n", _features[i].GenerateCode("y" + i)); } sb.Append("\n\t"); Dictionary <Hyperrectangle <float>, short> regions = GetRegions(); Hyperrectangle <float> space = _root.Bounds; foreach (var region in regions.Keys) { var ranges = from dim in Enumerable.Range(0, _numDimensions) select new { Dim = dim, Min = region.MinimumBound[dim], Max = region.MaximumBound[dim] }; ranges = ranges.OrderBy(o => o.Max - o.Min); var first = ranges.First(); sb.AppendFormat("if(({0} < {1} && {0} > {2})", "y" + first.Dim, first.Max, first.Min); foreach (var range in ranges.Skip(1)) { if (range.Min == space.MinimumBound[range.Dim] && range.Max == space.MaximumBound[range.Dim]) { continue; } sb.AppendFormat(" && ({0} < {1} && {0} > {2})", "y" + range.Dim, range.Max, range.Min); } sb.AppendFormat("){{\n\t\treturn {0};\n\t}}else ", regions[region]); } sb.Append("return 0;\n}"); return(sb.ToString()); }
private static void inferBounds(Node node, Hyperrectangle <float> bounds) { if (node == null) { return; } node.Bounds = bounds; if (node.NodeType == NodeType.Leaf) { return; } Threshold test = node.Threshold; float min = bounds.MinimumBound[test.Dimension]; float max = bounds.MaximumBound[test.Dimension]; Hyperrectangle <float> leftBounds = (Hyperrectangle <float>)bounds.Clone(); Hyperrectangle <float> rightBounds = (Hyperrectangle <float>)bounds.Clone(); leftBounds.MaximumBound[test.Dimension] = test.Value; rightBounds.MinimumBound[test.Dimension] = test.Value; inferBounds(node.Left, leftBounds); inferBounds(node.Right, rightBounds); }
private void initializeMinMax(int length) { _bounds = new Hyperrectangle <float>(length, float.MaxValue, float.MinValue); }
/// <summary> /// Constructs a CLTree from the provided data. /// </summary> /// <param name="data">The data to use in construction</param> /// <param name="factory">A factory to create feature dimensions</param> /// <param name="numFeatures">The number of features to use</param> /// <param name="bounds">The bounds of the data</param> /// <returns>A CLTree</returns> public static CLTree <T> Compute(List <T> data, IFeatureFactory <T, float[]> factory, int numFeatures, Hyperrectangle <float> bounds) { fillFeatureValues(factory, numFeatures, data); return(new CLTree <T>(split(Enumerable.Range(0, data.Count).ToList(), data.Count, bounds), _buildFeatures)); }
private static Node split(List <int> indices, int NCount, Hyperrectangle <float> bounds) { _depth++; int YCount = indices.Count; if (YCount <= MinY) { _depth--; return(new Node { NodeType = NodeType.Leaf, Y = YCount, N = NCount, Bounds = bounds }); } if (NCount < YCount) { NCount = YCount; } int length = _numFeatures; float min, max; Dictionary <Threshold, float> thresholds = new Dictionary <Threshold, float>(); float[] values = new float[YCount]; for (int i = 0; i < length; i++) { float[] featureValues = _featureValues[i]; for (int j = 0; j < YCount; j++) { values[j] = featureValues[indices[j]]; } Array.Sort <float>(values); min = bounds.MinimumBound[i]; max = bounds.MaximumBound[i]; Threshold cut1 = findCut(new Region { Min = min, Max = max, YCount = YCount, NCount = NCount }, values); if (cut1 == null) { continue; } Region r0 = new Region { Min = min, Max = cut1.Value, IncludeLeft = true, IncludeRight = cut1.IsInclusive }; Region r1 = new Region { Min = cut1.Value, Max = max, IncludeLeft = !cut1.IsInclusive, IncludeRight = true }; r0.CalculateCounts(values, min, max, NCount); r1.CalculateCounts(values, min, max, NCount); Region L = r0.RelativeDensity < r1.RelativeDensity ? r0 : r1; float[] LValues = L.Limit(values); if (LValues.Length == 0) { cut1.Dimension = i; cut1.Feature = _buildFeatures[i]; thresholds[cut1] = L.RelativeDensity; continue; } Threshold cut2 = findCut(L, LValues); if (cut2 == null) { continue; } if (L == r0) { r0 = new Region { Min = r0.Min, Max = cut2.Value, IncludeLeft = true, IncludeRight = cut2.IsInclusive }; r1 = new Region { Min = cut2.Value, Max = cut1.Value, IncludeLeft = !cut2.IsInclusive, IncludeRight = cut1.IsInclusive }; r0.CalculateCounts(values, min, max, NCount); r1.CalculateCounts(values, min, max, NCount); if (r1.RelativeDensity > r0.RelativeDensity) { cut2.Dimension = i; cut2.Feature = _buildFeatures[i]; thresholds[cut2] = r0.RelativeDensity; continue; } } else { r0 = new Region { Min = cut1.Value, Max = cut2.Value, IncludeLeft = !cut1.IsInclusive, IncludeRight = cut2.IsInclusive }; r1 = new Region { Min = cut2.Value, Max = r1.Max, IncludeLeft = !cut2.IsInclusive, IncludeRight = true }; r0.CalculateCounts(values, min, max, NCount); r1.CalculateCounts(values, min, max, NCount); if (r0.RelativeDensity > r1.RelativeDensity) { cut2.Dimension = i; cut2.Feature = _buildFeatures[i]; thresholds[cut2] = r1.RelativeDensity; continue; } } L = r0.RelativeDensity < r1.RelativeDensity ? r0 : r1; LValues = L.Limit(LValues); if (LValues.Length == 0) { continue; } Threshold cut3 = findCut(L, LValues); if (cut3 == null) { continue; } if (cut1.Value < cut3.Value) { r0 = new Region { Min = cut1.Value, Max = cut3.Value, IncludeLeft = !cut1.IsInclusive, IncludeRight = cut3.IsInclusive } } ; else { r0 = new Region { Min = cut3.Value, Max = cut1.Value, IncludeLeft = !cut3.IsInclusive, IncludeRight = cut1.IsInclusive } }; if (cut2.Value < cut3.Value) { r1 = new Region { Min = cut2.Value, Max = cut3.Value, IncludeLeft = !cut2.IsInclusive, IncludeRight = cut3.IsInclusive } } ; else { r1 = new Region { Min = cut3.Value, Max = cut2.Value, IncludeLeft = !cut3.IsInclusive, IncludeRight = cut2.IsInclusive } }; r0.CalculateCounts(values, min, max, NCount); r1.CalculateCounts(values, min, max, NCount); cut3.Feature = _buildFeatures[i]; cut3.Dimension = i; thresholds[cut3] = Math.Min(r0.RelativeDensity, r1.RelativeDensity); } values = null; if (thresholds.Count() == 0) { _depth--; return(new Node { NodeType = NodeType.Leaf, Y = YCount, N = NCount, Bounds = bounds }); } Threshold best = thresholds.OrderBy(o => o.Value).First().Key; List <int> left = new List <int>(); List <int> right = new List <int>(); values = _featureValues[best.Dimension]; foreach (int index in indices) { float value = values[index]; if (best.IsLeft(value)) { left.Add(index); } else { right.Add(index); } } UpdateManager.WriteLine("Splitting at {0}: {1} {2}", best, left.Count, right.Count); min = bounds.MinimumBound[best.Dimension]; max = bounds.MaximumBound[best.Dimension]; Hyperrectangle <float> leftBounds = (Hyperrectangle <float>)bounds.Clone(); Hyperrectangle <float> rightBounds = (Hyperrectangle <float>)bounds.Clone(); leftBounds.MaximumBound[best.Dimension] = best.Value; rightBounds.MinimumBound[best.Dimension] = best.Value; int leftNCount = (int)(((best.Value - min) * NCount) / (max - min)); Node node = new Node { Threshold = best, NodeType = NodeType.Branch, Y = YCount, N = NCount, Bounds = bounds }; node.Left = split(left, leftNCount, leftBounds); node.Right = split(right, NCount - leftNCount, rightBounds); _depth--; return(node); } } }
/// <summary> /// Retrieves a list of all points inside a given region. /// </summary> /// /// <param name="region">The region.</param> /// /// <returns>A list of all nodes contained in the region.</returns> /// public IList <TNode> GetNodesInsideRegion(Hyperrectangle region) { return(getNodesInsideRegion(this.Root, region, region)); }