{-# LANGUAGE DeriveGeneric #-}
module Data.KdTree.Static
(
PointAsListFn
, SquaredDistanceFn
, KdTree
, empty
, emptyWithDist
, singleton
, singletonWithDist
, build
, buildWithDist
, insertUnbalanced
, batchInsertUnbalanced
, nearest
, inRadius
, kNearest
, inRange
, toList
, null
, size
, defaultSqrDist
) where
import Control.DeepSeq
import Control.DeepSeq.Generics (genericRnf)
import GHC.Generics
import qualified Data.Foldable as F
import Prelude hiding (null)
import qualified Data.KdMap.Static as KDM
import Data.KdMap.Static (PointAsListFn, SquaredDistanceFn, defaultSqrDist)
newtype KdTree a p = KdTree (KDM.KdMap a p ()) deriving (forall x. KdTree a p -> Rep (KdTree a p) x)
-> (forall x. Rep (KdTree a p) x -> KdTree a p)
-> Generic (KdTree a p)
forall x. Rep (KdTree a p) x -> KdTree a p
forall x. KdTree a p -> Rep (KdTree a p) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a p x. Rep (KdTree a p) x -> KdTree a p
forall a p x. KdTree a p -> Rep (KdTree a p) x
$cto :: forall a p x. Rep (KdTree a p) x -> KdTree a p
$cfrom :: forall a p x. KdTree a p -> Rep (KdTree a p) x
Generic
instance (NFData a, NFData p) => NFData (KdTree a p) where rnf :: KdTree a p -> ()
rnf = KdTree a p -> ()
forall a. (Generic a, GNFData (Rep a)) => a -> ()
genericRnf
instance (Show a, Show p) => Show (KdTree a p) where
show :: KdTree a p -> String
show (KdTree KdMap a p ()
kdm) = String
"KdTree " String -> ShowS
forall a. [a] -> [a] -> [a]
++ KdMap a p () -> String
forall a. Show a => a -> String
show KdMap a p ()
kdm
instance F.Foldable (KdTree a) where
foldr :: (a -> b -> b) -> b -> KdTree a a -> b
foldr a -> b -> b
f b
z (KdTree KdMap a a ()
kdMap) = ((a, ()) -> b -> b) -> b -> KdMap a a () -> b
forall p v b a. ((p, v) -> b -> b) -> b -> KdMap a p v -> b
KDM.foldrWithKey (a -> b -> b
f (a -> b -> b) -> ((a, ()) -> a) -> (a, ()) -> b -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a, ()) -> a
forall a b. (a, b) -> a
fst) b
z KdMap a a ()
kdMap
empty :: Real a => PointAsListFn a p -> KdTree a p
empty :: PointAsListFn a p -> KdTree a p
empty = KdMap a p () -> KdTree a p
forall a p. KdMap a p () -> KdTree a p
KdTree (KdMap a p () -> KdTree a p)
-> (PointAsListFn a p -> KdMap a p ())
-> PointAsListFn a p
-> KdTree a p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PointAsListFn a p -> KdMap a p ()
forall a p v. Real a => PointAsListFn a p -> KdMap a p v
KDM.empty
emptyWithDist :: Real a => PointAsListFn a p
-> SquaredDistanceFn a p
-> KdTree a p
emptyWithDist :: PointAsListFn a p -> SquaredDistanceFn a p -> KdTree a p
emptyWithDist PointAsListFn a p
p2l SquaredDistanceFn a p
d2 = KdMap a p () -> KdTree a p
forall a p. KdMap a p () -> KdTree a p
KdTree (KdMap a p () -> KdTree a p) -> KdMap a p () -> KdTree a p
forall a b. (a -> b) -> a -> b
$ PointAsListFn a p -> SquaredDistanceFn a p -> KdMap a p ()
forall a p v.
Real a =>
PointAsListFn a p -> SquaredDistanceFn a p -> KdMap a p v
KDM.emptyWithDist PointAsListFn a p
p2l SquaredDistanceFn a p
d2
singleton :: Real a => PointAsListFn a p -> p -> KdTree a p
singleton :: PointAsListFn a p -> p -> KdTree a p
singleton PointAsListFn a p
p2l p
p = KdMap a p () -> KdTree a p
forall a p. KdMap a p () -> KdTree a p
KdTree (KdMap a p () -> KdTree a p) -> KdMap a p () -> KdTree a p
forall a b. (a -> b) -> a -> b
$ PointAsListFn a p -> (p, ()) -> KdMap a p ()
forall a p v. Real a => PointAsListFn a p -> (p, v) -> KdMap a p v
KDM.singleton PointAsListFn a p
p2l (p
p, ())
singletonWithDist :: Real a => PointAsListFn a p
-> SquaredDistanceFn a p
-> p
-> KdTree a p
singletonWithDist :: PointAsListFn a p -> SquaredDistanceFn a p -> p -> KdTree a p
singletonWithDist PointAsListFn a p
p2l SquaredDistanceFn a p
d2 p
p = KdMap a p () -> KdTree a p
forall a p. KdMap a p () -> KdTree a p
KdTree (KdMap a p () -> KdTree a p) -> KdMap a p () -> KdTree a p
forall a b. (a -> b) -> a -> b
$ PointAsListFn a p
-> SquaredDistanceFn a p -> (p, ()) -> KdMap a p ()
forall a p v.
Real a =>
PointAsListFn a p -> SquaredDistanceFn a p -> (p, v) -> KdMap a p v
KDM.singletonWithDist PointAsListFn a p
p2l SquaredDistanceFn a p
d2 (p
p, ())
null :: KdTree a p -> Bool
null :: KdTree a p -> Bool
null (KdTree KdMap a p ()
kdm) = KdMap a p () -> Bool
forall a p v. KdMap a p v -> Bool
KDM.null KdMap a p ()
kdm
build :: Real a => PointAsListFn a p
-> [p]
-> KdTree a p
build :: PointAsListFn a p -> [p] -> KdTree a p
build PointAsListFn a p
pointAsList [p]
ps =
KdMap a p () -> KdTree a p
forall a p. KdMap a p () -> KdTree a p
KdTree (KdMap a p () -> KdTree a p) -> KdMap a p () -> KdTree a p
forall a b. (a -> b) -> a -> b
$ PointAsListFn a p -> [(p, ())] -> KdMap a p ()
forall a p v.
Real a =>
PointAsListFn a p -> [(p, v)] -> KdMap a p v
KDM.build PointAsListFn a p
pointAsList ([(p, ())] -> KdMap a p ()) -> [(p, ())] -> KdMap a p ()
forall a b. (a -> b) -> a -> b
$ [p] -> [()] -> [(p, ())]
forall a b. [a] -> [b] -> [(a, b)]
zip [p]
ps ([()] -> [(p, ())]) -> [()] -> [(p, ())]
forall a b. (a -> b) -> a -> b
$ () -> [()]
forall a. a -> [a]
repeat ()
buildWithDist :: Real a => PointAsListFn a p
-> SquaredDistanceFn a p
-> [p]
-> KdTree a p
buildWithDist :: PointAsListFn a p -> SquaredDistanceFn a p -> [p] -> KdTree a p
buildWithDist PointAsListFn a p
pointAsList SquaredDistanceFn a p
distSqr [p]
ps =
KdMap a p () -> KdTree a p
forall a p. KdMap a p () -> KdTree a p
KdTree (KdMap a p () -> KdTree a p) -> KdMap a p () -> KdTree a p
forall a b. (a -> b) -> a -> b
$ PointAsListFn a p
-> SquaredDistanceFn a p -> [(p, ())] -> KdMap a p ()
forall a p v.
Real a =>
PointAsListFn a p
-> SquaredDistanceFn a p -> [(p, v)] -> KdMap a p v
KDM.buildWithDist PointAsListFn a p
pointAsList SquaredDistanceFn a p
distSqr ([(p, ())] -> KdMap a p ()) -> [(p, ())] -> KdMap a p ()
forall a b. (a -> b) -> a -> b
$ [p] -> [()] -> [(p, ())]
forall a b. [a] -> [b] -> [(a, b)]
zip [p]
ps ([()] -> [(p, ())]) -> [()] -> [(p, ())]
forall a b. (a -> b) -> a -> b
$ () -> [()]
forall a. a -> [a]
repeat ()
insertUnbalanced :: Real a => KdTree a p -> p -> KdTree a p
insertUnbalanced :: KdTree a p -> p -> KdTree a p
insertUnbalanced (KdTree KdMap a p ()
kdm) p
p = KdMap a p () -> KdTree a p
forall a p. KdMap a p () -> KdTree a p
KdTree (KdMap a p () -> KdTree a p) -> KdMap a p () -> KdTree a p
forall a b. (a -> b) -> a -> b
$ KdMap a p () -> p -> () -> KdMap a p ()
forall a p v. Real a => KdMap a p v -> p -> v -> KdMap a p v
KDM.insertUnbalanced KdMap a p ()
kdm p
p ()
batchInsertUnbalanced :: Real a => KdTree a p -> [p] -> KdTree a p
batchInsertUnbalanced :: KdTree a p -> [p] -> KdTree a p
batchInsertUnbalanced (KdTree KdMap a p ()
kdm) [p]
ps =
KdMap a p () -> KdTree a p
forall a p. KdMap a p () -> KdTree a p
KdTree (KdMap a p () -> KdTree a p) -> KdMap a p () -> KdTree a p
forall a b. (a -> b) -> a -> b
$ KdMap a p () -> [(p, ())] -> KdMap a p ()
forall a p v. Real a => KdMap a p v -> [(p, v)] -> KdMap a p v
KDM.batchInsertUnbalanced KdMap a p ()
kdm ([(p, ())] -> KdMap a p ()) -> [(p, ())] -> KdMap a p ()
forall a b. (a -> b) -> a -> b
$ [p] -> [()] -> [(p, ())]
forall a b. [a] -> [b] -> [(a, b)]
zip [p]
ps ([()] -> [(p, ())]) -> [()] -> [(p, ())]
forall a b. (a -> b) -> a -> b
$ () -> [()]
forall a. a -> [a]
repeat ()
nearest :: Real a => KdTree a p -> p -> p
nearest :: KdTree a p -> p -> p
nearest (KdTree KdMap a p ()
t) p
query
| KdMap a p () -> Bool
forall a p v. KdMap a p v -> Bool
KDM.null KdMap a p ()
t = String -> p
forall a. HasCallStack => String -> a
error String
"Attempted to call nearest on an empty KdTree."
| Bool
otherwise = (p, ()) -> p
forall a b. (a, b) -> a
fst ((p, ()) -> p) -> (p, ()) -> p
forall a b. (a -> b) -> a -> b
$ KdMap a p () -> p -> (p, ())
forall a p v. Real a => KdMap a p v -> p -> (p, v)
KDM.nearest KdMap a p ()
t p
query
inRadius :: Real a => KdTree a p
-> a
-> p
-> [p]
inRadius :: KdTree a p -> a -> p -> [p]
inRadius (KdTree KdMap a p ()
t) a
radius p
query = ((p, ()) -> p) -> [(p, ())] -> [p]
forall a b. (a -> b) -> [a] -> [b]
map (p, ()) -> p
forall a b. (a, b) -> a
fst ([(p, ())] -> [p]) -> [(p, ())] -> [p]
forall a b. (a -> b) -> a -> b
$ KdMap a p () -> a -> p -> [(p, ())]
forall a p v. Real a => KdMap a p v -> a -> p -> [(p, v)]
KDM.inRadius KdMap a p ()
t a
radius p
query
kNearest :: Real a => KdTree a p -> Int -> p -> [p]
kNearest :: KdTree a p -> Int -> p -> [p]
kNearest (KdTree KdMap a p ()
t) Int
k p
query = ((p, ()) -> p) -> [(p, ())] -> [p]
forall a b. (a -> b) -> [a] -> [b]
map (p, ()) -> p
forall a b. (a, b) -> a
fst ([(p, ())] -> [p]) -> [(p, ())] -> [p]
forall a b. (a -> b) -> a -> b
$ KdMap a p () -> Int -> p -> [(p, ())]
forall a p v. Real a => KdMap a p v -> Int -> p -> [(p, v)]
KDM.kNearest KdMap a p ()
t Int
k p
query
inRange :: Real a => KdTree a p
-> p
-> p
-> [p]
inRange :: KdTree a p -> p -> p -> [p]
inRange (KdTree KdMap a p ()
t) p
lower p
upper = ((p, ()) -> p) -> [(p, ())] -> [p]
forall a b. (a -> b) -> [a] -> [b]
map (p, ()) -> p
forall a b. (a, b) -> a
fst ([(p, ())] -> [p]) -> [(p, ())] -> [p]
forall a b. (a -> b) -> a -> b
$ KdMap a p () -> p -> p -> [(p, ())]
forall a p v. Real a => KdMap a p v -> p -> p -> [(p, v)]
KDM.inRange KdMap a p ()
t p
lower p
upper
toList :: KdTree a p -> [p]
toList :: KdTree a p -> [p]
toList (KdTree KdMap a p ()
t) = KdMap a p () -> [p]
forall a p v. KdMap a p v -> [p]
KDM.keys KdMap a p ()
t
size :: KdTree a p -> Int
size :: KdTree a p -> Int
size (KdTree KdMap a p ()
t) = KdMap a p () -> Int
forall a p v. KdMap a p v -> Int
KDM.size KdMap a p ()
t