public KdTree(ModelLoadContext ctx)
        {
            bool hasSeed = ctx.Reader.ReadByte() == 1;

            if (hasSeed)
            {
                var seed = ctx.Reader.ReadInt32();
                _rnd  = new Random(seed);
                _seed = seed;
            }
            else
            {
                _rnd  = new Random();
                _seed = null;
            }
            dimension = ctx.Reader.ReadInt32();
            int i = ctx.Reader.ReadInt32();

            _distance = (NearestNeighborsDistance)i;
            root      = ReadNode(ctx);
            byte b = ctx.Reader.ReadByte();

            if (b != 168)
            {
                throw Contracts.Except("Detected inconsistency in deserializing.");
            }
            SetDistanceFunction();
        }
 public static void SaveNode(ModelSaveContext ctx, IKdTreeNode node)
 {
     ctx.Writer.Write((byte)(node != null ? (node as KdTreeLeaf == null ? 1 : 2) : 0));
     if (node != null)
     {
         node.Save(ctx);
     }
     ctx.Writer.Write((byte)169);
 }
 public KdTreeNode(IPointIdFloat point, IKdTreeNode left, IKdTreeNode right, int depth)
 {
     this.point = point;
     this.left  = left;
     this.right = right;
     this.depth = depth;
     size       = 1 + left.size + right.size;
     if (depth > MaxDepth)
     {
         throw Contracts.Except("The k-d tree depth is too high (> {0}). This probably means the datasets is too sparse to be effective. You should reduce the number of dimensions (PCA for example).", MaxDepth);
     }
 }
 public void Add(IPointIdFloat p)
 {
     if (root == null)
     {
         var points = new IPointIdFloat[] { p };
         ValidatePointsArray(points);
         root = CreateTree(points.ToList(), _rnd);
     }
     else
     {
         ValidatePoint(p);
         root.Add(p);
     }
 }
 public KdTree(IEnumerable <IPointIdFloat> points, int dimension = -1, int?seed = null,
               NearestNeighborsDistance distance = NearestNeighborsDistance.L2)
 {
     _seed          = seed;
     _rnd           = seed.HasValue ? new Random(seed.Value) : new Random();
     _distance      = distance;
     this.dimension = dimension;
     if (points.Any())
     {
         ValidatePointsArray(points);
         root = CreateTree(points.ToList(), _rnd);
     }
     else
     {
         root = null;
     }
     SetDistanceFunction();
 }
        internal static IKdTreeNode CreateTree(IList <IPointIdFloat> points, Random rnd, int depth = 0)
        {
            switch (points.Count())
            {
            case 0:
                return(new KdTreeLeaf(depth));

            case 1:
                return(new KdTreeNode(points.First(), new KdTreeLeaf(depth + 1), new KdTreeLeaf(depth + 1), depth));

            default:
                IList <IPointIdFloat> leftPoints  = null;
                IList <IPointIdFloat> rightPoints = null;
                IPointIdFloat         median      = MedianPoint(points, ref leftPoints, ref rightPoints, depth, rnd);
                IKdTreeNode           left        = CreateTree(leftPoints, rnd, depth + 1);
                IKdTreeNode           right       = CreateTree(rightPoints, rnd, depth + 1);
                return(new KdTreeNode(median, left, right, depth));
            }
        }