Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Nearest Neighbor] Code and basic test for nearest neighbor #28

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/rtree.ml
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,16 @@ module Make (E : Envelope) (V : Value with type envelope = E.t) = struct
| Empty -> depth

let depth t = depth' t.tree 0
(*
let nearest_neighbor elem = function
| Node ns ->
(* let sub_sizes = List.map (fun (_, n) -> size' n) ns in
List.fold_left ( + ) 0 sub_sizes *)
| Leaf es ->
let sub_sizes = List.fold_left () es in
List.fold_left ( + ) 0 sub_sizes
| Empty -> *)

end

module Rectangle = Rectangle
3 changes: 3 additions & 0 deletions src/rtree_intf.ml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ module type Value = sig

val envelope : t -> envelope
(** Given a value, calculates the envelope for it. *)

val mindist: t -> envelope -> float
val minmaxdist: t -> envelope -> float
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do these need to be exposed in the interface?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to test these functions as well. Is that not necessary?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that they're a part of the Value signature then we need them here and can be tested individually. Could we add some documentation strings to them ? minmaxdist is a little opaque I think ?

end

module type Envelope = sig
Expand Down
73 changes: 73 additions & 0 deletions test/basic.ml
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,61 @@ module V = struct
type envelope = Rtree.Rectangle.t

let envelope i = List.assoc i !pre_made_envelopes

let mindist _p _e = 0.
let minmaxdist _p _e = 0.
end

module R = Rtree.Make (Rtree.Rectangle) (V)

module Vp = struct
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is Vp short for?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is short for (Value for Point)

type t = floatarray

let t =
let to_array arr = Float.Array.to_list arr |> Array.of_list in
let of_array arr = Array.to_list arr |> Float.Array.of_list in
Repr.(map (array float) of_array to_array)


type envelope = Rtree.Rectangle.t

let envelope fa=
let x0 = Array.Floatarray.get fa 0 in
let x1 = Array.Floatarray.get fa 0 in
let y0 = Array.Floatarray.get fa 1 in
let y1 = Array.Floatarray.get fa 1 in
Rtree.Rectangle.v ~x0 ~y0 ~x1 ~y1

let get arr i = Array.Floatarray.get arr i

let mindist (p:floatarray) (e:envelope) =
let (x0,y0,x1,y1) = Rtree.Rectangle.coords e in
let gete ind = if ind==0 then x0
else if ind==1 then y0 else if ind==2 then x1 else y1 in

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

multiple if-else is not a good idea IMO
Maybe you can use a match statement here, something like this

let gete = match ind with 
...
| 1 -> ...
|2 -> ...
...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with @AryanGodara here, also note the difference between = and == in OCaml (both can be used to check for equality): https://cs3110.github.io/textbook/chapters/mut/refs.html?highlight=physical#physical-equality

let dist i = if (get p i)< (gete i) then ( gete i ) -. (get p i)*. (gete i) -. (get p i)
else if (get p i)>(gete (i+2)) then (get p i) -. (gete (i+2)) *. (get p i)-. (gete (i+2))
else 0. in
dist 0 +. dist 1

let minmaxdist p e =
let (x0,y0,x1,y1) = Rtree.Rectangle.coords e in
let gete ind = if ind==0 then x0

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

match here as well

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @AryanGodara. I also need some feedback on how the point shall be stored?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @AryanGodara, I will change this but I also need feedback on where the point is stored in the code. @patricoferris I am waiting for the feedback

else if ind==1 then y0 else if ind==2 then x1 else y1 in
let rm k = if (get p k) <= ((gete k +. gete (k+2))/.2.) then (get p k)
else gete (k+2) in

let rM k = if (get p k) >= ((gete k +. gete (k+2))/.2.) then (get p k)
else gete (k+2) in

let farthest_distance_axis i= ( get p i -. rm i) *. (get p (i) -. rm i) in
let farthest_distance = farthest_distance_axis 0 +. farthest_distance_axis 1 in
let max_dist_axis i = farthest_distance -. (get p i -. rM i)*.(get p i -. rM i) +. (get p i -. rM i)*.(get p i -. rM i) in
min (max_dist_axis 0) (max_dist_axis 1)

end

module Rp = Rtree.Make (Rtree.Rectangle) (Vp)

let make_random_envelope () =
let x0 = Random.float 100. -. 50.
and x1 = Random.float 100. -. 50.
Expand Down Expand Up @@ -64,6 +115,8 @@ let test_functor _ =
type envelope = Rtree.Rectangle.t

let envelope i = List.assoc i elems
let mindist _p _e = 0.
let minmaxdist _p _e = 0.
end)
in
let r =
Expand Down Expand Up @@ -102,6 +155,8 @@ let test_lines () =
let y0 = Float.min y1 y2 in
let y1 = Float.max y1 y2 in
Rtree.Rectangle.v ~x0 ~y0 ~x1 ~y1
let mindist _p _e = 0.
let minmaxdist _p _e = 0.
end)
in
let l1 = { p1 = (1., 2.); p2 = (2., 3.) } in
Expand Down Expand Up @@ -136,6 +191,8 @@ let omt_loader () =
let y0 = Float.min y1 y2 in
let y1 = Float.max y1 y2 in
Rtree.Rectangle.v ~x0 ~y0 ~x1 ~y1
let mindist _p _e = 0.
let minmaxdist _p _e = 0.
end)
in
let lines =
Expand All @@ -158,6 +215,19 @@ let rectangle () =
let r = Rtree.Rectangle.merge_many [ r1; r2 ] in
assert (r = r3)

let test_min_dist () =

let arr = Array.Floatarray.create 2 in
Array.Floatarray.unsafe_set arr 0 5.;
Array.Floatarray.unsafe_set arr 1 5.;
let point = Array.Floatarray.create 2 in
Array.Floatarray.unsafe_set arr 0 0.;
Array.Floatarray.unsafe_set arr 1 0.;
let env = Vp.envelope arr in
let dist = Vp.mindist point env in
assert(dist = 25.)


let test_depth () =
let module R =
Rtree.Make
Expand All @@ -175,6 +245,8 @@ let test_depth () =
let y0 = Float.min y1 y2 in
let y1 = Float.max y1 y2 in
Rtree.Rectangle.v ~x0 ~y0 ~x1 ~y1
let mindist _p _e = 0.
let minmaxdist _p _e = 0.
end)
in
let lines =
Expand All @@ -198,6 +270,7 @@ let suite =
"omt" >:: omt_loader;
"rect" >:: rectangle;
"depth" >:: test_depth;
"min_dist" >:: test_min_dist
]

let _ = run_test_tt_main suite
4 changes: 4 additions & 0 deletions test/image.ml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ module Line = struct
let y0 = min (Gg.P2.y p1) (Gg.P2.y p2) in
let y1 = max (Gg.P2.y p1) (Gg.P2.y p2) in
Rtree.Rectangle.v ~x0 ~x1 ~y0 ~y1
let mindist _p _e = 0.
let minmaxdist _p _e = 0.
end

module Point = struct
Expand All @@ -38,6 +40,8 @@ module Point = struct
let x0 = Gg.P2.x p1 in
let y0 = Gg.P2.y p1 in
Rtree.Rectangle.v ~x0 ~x1:x0 ~y0 ~y1:y0
let mindist _p _e = 0.
let minmaxdist _p _e = 0.
end

module R = Rtree.Make (Rtree.Rectangle) (Line)
Expand Down
3 changes: 3 additions & 0 deletions test/persist.ml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ module Line = struct
let y0 = Float.min arr.(1) arr.(3) in
let y1 = Float.max arr.(1) arr.(3) in
Rtree.Rectangle.v ~x0 ~y0 ~x1 ~y1

let mindist _p _e = 0.
let minmaxdist _p _e = 0.
end

module R = Rtree.Make (Rtree.Rectangle) (Line)
Expand Down