Permalink
Browse files

nuke deprecated MetricSpace and BKTree

  • Loading branch information...
1 parent 8078481 commit 5a1bd6181c3a734b430fbe89f77c5b9cf1bac82f @larsrh larsrh committed Feb 8, 2014
@@ -1,201 +0,0 @@
-package scalaz
-
-import collection.immutable.IntMap
-import annotation.tailrec
-
-
-/**
- * Burkhard-Keller trees provide an implementation of sets which apart
- * from the ordinary operations also has an approximate member search,
- * allowing you to search for elements that are of a distance `n` from
- * the element you are searching for. The distance is determined using
- * a metric on the type of elements. Therefore all elements must
- * implement the [[scalaz.MetricSpace]] type class, rather than the more usual
- * [[scalaz.Ordering]].
- *
- * The worst case complexity of many of these operations is quite bad,
- * but the expected behavior varies greatly with the metric. For
- * example, the discrete metric (`distance x y | y == x = 0 |
- * otherwise = 1`) makes BK-trees behave abysmally. The metrics
- * mentioned above should give good performance characteristics.
- *
- * This implementation is a port of Haskell's [[http://hackage.haskell.org/packages/archive/bktrees/0.2.1/doc/html/src/Data-Set-BKTree.html Data.Set.BKTree]]
- */
-@deprecated("This class depends on `MetricSpace` which is deprecated, too.", "7.0.1")
-sealed abstract class BKTree[A] extends Product with Serializable {
- def isEmpty: Boolean =
- this match {
- case BKTreeEmpty() => true
- case BKTreeNode(_, _, _) => false
- }
-
- def map[B](f: A => B): BKTree[B] =
- this match {
- case BKTreeEmpty() => BKTreeEmpty()
- case BKTreeNode(a, s, c) => BKTreeNode(f(a), s, c.transform((_: Int, z: BKTree[A]) => z map f))
- }
-
- def size: Int =
- this match {
- case BKTreeEmpty() => 0
- case BKTreeNode(_, s, _) => s
- }
-
- def +(a: A)(implicit A: MetricSpace[A]): BKTree[A] =
- this match {
- case BKTreeEmpty() => BKTreeNode(a, 1, IntMap.empty)
- case BKTreeNode(v, s, c) => {
- val d = A.distance(v, a)
- BKTreeNode(v, s + 1, c + ((d, c get d match {
- case None => BKTreeNode(a, 1, IntMap.empty)
- case Some(w) => w + a
- })))
- }
- }
-
- def ++(t: BKTree[A])(implicit m: MetricSpace[A]): BKTree[A] = {
- var k: BKTree[A] = this
- for (v <- t.values)
- k = k + v
- k
- }
-
- def -(a: A)(implicit A: MetricSpace[A]): BKTree[A] =
- this match {
- case BKTreeEmpty() => BKTreeEmpty()
- case BKTreeNode(v, _, c) => {
- val d = A.distance(v, a)
- if(d == 0) BKTree(c.values.seq.flatMap(_.values).toSeq: _*)
- else {
- val subTree = updateMap(c, d, (t: BKTree[A]) => Some(t - a))
- val size = subTree.values.map(_.size).sum + 1
- BKTreeNode(v, size, subTree)
- }
- }
- }
-
- def --(t: BKTree[A])(implicit m: MetricSpace[A]): BKTree[A] = {
- var k: BKTree[A] = this
- for (v <- t.values)
- k = k - v
- k
- }
-
- def values: List[A] =
- this match {
- case BKTreeEmpty() => Nil
- case BKTreeNode(v, _, c) => v :: c.valuesIterator.toList.flatMap(_.values)
- }
-
-
- /**
- * Returns true of this set contains `a`.
- */
- @tailrec
- final def contains(a: A)(implicit A: MetricSpace[A]): Boolean =
- this match {
- case BKTreeEmpty() => false
- case BKTreeNode(v, _, c) =>
- val d = A.distance(v, a)
- d == 0 || (c get d match {
- case None => false
- case Some(w) => w contains a
- })
- }
-
- /** An alias for `contains` */
- final def -?-(a: A)(implicit A: MetricSpace[A]): Boolean = contains(a)
-
- /** Returns true if this set contains an element which has a distance from `a` that is less than or equal to `n` */
- def containsApproximate(a: A, n: Int)(implicit A: MetricSpace[A]): Boolean =
- this match {
- case BKTreeEmpty() => false
- case BKTreeNode(v, _, c) =>
- val d = A.distance(v, a)
- d <= n || (subChildren(d, n) exists (_._2 containsApproximate(a, n)))
- }
-
- /** An alias for `containsApproximate` */
- def =?=(a: A, n: Int)(implicit A: MetricSpace[A]): Boolean = containsApproximate(a, n)
-
- /** Returns the elements which have an distance from `a` that is less than or equal to `n`. */
- def valuesApproximate(a: A, n: Int)(implicit A: MetricSpace[A]): List[A] =
- this match {
- case BKTreeEmpty() => Nil
- case BKTreeNode(v, _, c) =>
- val d = A.distance(v, a)
- val k = subChildren(d, n).valuesIterator.toList flatMap (_ valuesApproximate(a, n))
- if (d <= n)
- v :: k
- else
- k
- }
-
- /** An alias for `valuesApproximate` */
- def |=|(a: A, n: Int)(implicit A: MetricSpace[A]): List[A] = valuesApproximate(a, n)
-
- private type M[A] = IntMap[A]
-
- private def subChildren(d: Int, n: Int): M[BKTree[A]] =
- this match {
- case BKTreeEmpty() => IntMap.empty
- case BKTreeNode(_, _, c) => subMap(c, d, n)
- }
-
- private def subMap(m: M[BKTree[A]], d: Int, n: Int): M[BKTree[A]] =
- splitMap(splitMap(m, d - n - 1)._2, d + n + 1)._1
-
- private def splitChildren(k: Int): (M[BKTree[A]], M[BKTree[A]]) =
- this match {
- case BKTreeEmpty() => (IntMap.empty, IntMap.empty)
- case BKTreeNode(_, _, c) => splitMap(c, k)
- }
-
- private def splitMap(m: M[BKTree[A]], k: Int): (M[BKTree[A]], M[BKTree[A]]) = {
- var m1: M[BKTree[A]] = IntMap.empty
- var m2: M[BKTree[A]] = IntMap.empty
- for ((i, v) <- m.iterator) {
- if (i < k)
- m1 = m1 + ((i, v))
- else if (i > k)
- m2 = m2 + ((i, v))
- }
- (m1, m2)
- }
-
- private def updateMap(m: M[BKTree[A]], k: Int, f: BKTree[A] => Option[BKTree[A]]) =
- m get k match {
- case None => m
- case Some(v) => f(v) match {
- case None => m - k
- case Some(value) => m.updated(k, value)
- }
- }
-}
-
-private case class BKTreeNode[A](value: A, sz: Int, children: IntMap[BKTree[A]]) extends BKTree[A]
-
-private case class BKTreeEmpty[A]() extends BKTree[A]
-
-object BKTree extends BKTreeInstances with BKTreeFunctions {
- def apply[A: MetricSpace](as: A*): BKTree[A] = as.foldLeft(emptyBKTree[A])((b, a) => b + a)
-}
-
-trait BKTreeFunctions {
- def emptyBKTree[A]: BKTree[A] = BKTreeEmpty()
-}
-
-sealed abstract class BKTreeInstances {
- implicit def bKTreeInstance: Functor[BKTree] with Length[BKTree] = new Functor[BKTree] with Length[BKTree] {
- def map[A, B](fa: BKTree[A])(f: A => B): BKTree[B] = fa map f
- def length[A](fa: BKTree[A]): Int = fa.size
- }
- implicit def bKTreeMonoid[A: MetricSpace]: Monoid[BKTree[A]] = new Monoid[BKTree[A]] {
- def append(f1: BKTree[A], f2: => BKTree[A]): BKTree[A] = f1 ++ f2
- def zero: BKTree[A] = BKTree[A]()
- }
- implicit def bkTreeEqual[A](implicit A: Equal[A]) = {
- import std.list._
- Equal.equalBy((ba: BKTree[A]) => ba.values)
- }
-}
@@ -1,94 +0,0 @@
-package scalaz
-
-////
-/**
- * Useful metric spaces include the manhattan distance between two points,
- * the Levenshtein edit distance between two strings, the number of
- * edges in the shortest path between two nodes in an undirected graph
- * and the Hamming distance between two binary strings. Any euclidean
- * space also has a metric. However, in this module we use int-valued
- * metrics and that's not compatible with the metrics of euclidean
- * spaces which are real-values.
- *
- * @see [[scalaz.BKTree]]
- */
-////
-@deprecated("Redundant to spire's `MetricSpace`", "7.0.1")
-trait MetricSpace[F] { self =>
- ////
- def distance(a: F, b: F): Int
-
- def contramap[B](f: B => F): MetricSpace[B] = new MetricSpace[B] {
- def distance(a: B, b: B): Int = self.distance(f(a), f(b))
- }
-
- // derived functions
-
- trait MetricSpaceLaw {
-
- import std.boolean.conditional
-
- def nonNegativity(a1: F, a2: F): Boolean = distance(a1, a1) >= 0
- def identity(a1: F): Boolean = distance(a1, a1) == 0
- def equality(a1: F, a2: F)(implicit F: Equal[F]): Boolean = conditional(F.equal(a1, a2), distance(a1, a2) == 0)
- def symmetry(a1: F, a2: F): Boolean = distance(a1, a2) == distance(a2, a1)
- def triangleInequality(a1: F, a2: F, a3: F): Boolean = (distance(a1, a2) + distance(a2, a3)) >= distance(a1, a3)
- }
-
- def metricSpaceLaw = new MetricSpaceLaw {}
-
- ////
- val metricSpaceSyntax = new scalaz.syntax.MetricSpaceSyntax[F] { def F = MetricSpace.this }
-}
-
-object MetricSpace {
- @inline def apply[F](implicit F: MetricSpace[F]): MetricSpace[F] = F
-
- ////
- val metricSpaceInstance = new Contravariant[MetricSpace] {
- def contramap[A, B](r: MetricSpace[A])(f: B => A): MetricSpace[B] = r contramap f
- }
-
- def metricSpace[A](f: (A, A) => Int): MetricSpace[A] = new MetricSpace[A] {
- def distance(a1: A, a2: A): Int = f(a1, a2)
- }
-
- def levenshtein[F[_], A](implicit l: Length[F], i: Index[F], e: Equal[A]): MetricSpace[F[A]] = new MetricSpace[F[A]] {
- def distance(a1: F[A], a2: F[A]): Int = levenshteinDistance(a1, a2)
- }
-
- def levenshteinDistance[F[_], A](value: F[A], w: F[A])(implicit l: Length[F], ind: Index[F], equ: Equal[A]): Int = {
- import Memo._
- def levenshteinMatrix(w: F[A])(implicit l: Length[F], ind: Index[F], equ: Equal[A]): (Int, Int) => Int = {
- val m = mutableHashMapMemo[(Int, Int), Int]
-
- def get(i: Int, j: Int): Int = if (i == 0) j
- else if (j == 0) i
- else {
- lazy val t: A = ind.index(value, (i - 1)).get
- lazy val u: A = ind.index(w, (j - 1)).get
- lazy val e: Boolean = equ.equal(t, u)
-
-
- val g: ((Int, Int)) => Int = m {
- case (a, b) => get(a, b)
- }
- val a: Int = g((i - 1, j)) + 1
- val b: Int = g((i - 1, j - 1)) + (if (e) 0 else 1)
- def c: Int = g((i, j - 1)) + 1
- if (a < b) a else if (b <= c) b else c
- }
-
- get
- }
-
- val k = levenshteinMatrix(w)
- k(l.length(value), l.length(w))
- }
-
- implicit def LevenshteinString: MetricSpace[String] = {
- import std.list._, std.anyVal._
- levenshtein[List, Char].contramap((s: String) => s.toList)
- }
- ////
-}
@@ -22,7 +22,6 @@
* - [[scalaz.Order]] extends [[scalaz.Equal]]
* - [[scalaz.Enum]] extends [[scalaz.Order]]
*
- * - [[scalaz.MetricSpace]]
* - [[scalaz.Plus]]
* - [[scalaz.PlusEmpty]] extends [[scalaz.Plus]]
* - [[scalaz.IsEmpty]] extends [[scalaz.PlusEmpty]]
@@ -250,12 +250,6 @@ trait AnyValInstances {
override def equalIsNatural: Boolean = true
}
- /** Warning: the triangle inequality will not hold if `b - a` overflows. */
- @deprecated("MetricSpace is deprecated", "7.0.1")
- implicit val intMetricSpace: MetricSpace[Int] = new MetricSpace[Int] {
- def distance(a: Int, b: Int): Int = scala.math.abs(b - a)
- }
-
implicit val intMultiplicationNewType: Monoid[Int @@ Multiplication] with Enum[Int @@ Multiplication] = new Monoid[Int @@ Multiplication] with Enum[Int @@ Multiplication] {
def append(f1: Int @@ Multiplication, f2: => Int @@ Multiplication) = Multiplication(Tag.unwrap(f1) * Tag.unwrap(f2))
@@ -1,31 +0,0 @@
-package scalaz
-package syntax
-
-/** Wraps a value `self` and provides methods related to `MetricSpace` */
-@deprecated("MetricSpace is deprecated", "7.0.1")
-trait MetricSpaceOps[F] extends Ops[F] {
- implicit def F: MetricSpace[F]
- ////
- final def <===>(a: F): Int = F.distance(self, a)
- ////
-}
-
-@deprecated("MetricSpace is deprecated", "7.0.1")
-trait ToMetricSpaceOps {
- implicit def ToMetricSpaceOps[F](v: F)(implicit F0: MetricSpace[F]) =
- new MetricSpaceOps[F] { def self = v; implicit def F: MetricSpace[F] = F0 }
-
- ////
-
- ////
-}
-
-@deprecated("MetricSpace is deprecated", "7.0.1")
-trait MetricSpaceSyntax[F] {
- implicit def ToMetricSpaceOps(v: F): MetricSpaceOps[F] = new MetricSpaceOps[F] { def self = v; implicit def F: MetricSpace[F] = MetricSpaceSyntax.this.F }
-
- def F: MetricSpace[F]
- ////
-
- ////
-}
@@ -22,9 +22,6 @@ trait Syntaxes {
object enum extends ToEnumOps
- @deprecated("metricSpace is deprecated", "7.0.1")
- object metricSpace extends ToMetricSpaceOps
-
object isEmpty extends ToIsEmptyOps
object plusEmpty extends ToPlusEmptyOps
@@ -161,7 +158,7 @@ trait ToDataOps
trait ToTypeClassOps
extends ToSemigroupOps with ToMonoidOps with ToEqualOps with ToLengthOps with ToShowOps
- with ToOrderOps with ToEnumOps with ToMetricSpaceOps with ToPlusEmptyOps with ToEachOps with ToIndexOps
+ with ToOrderOps with ToEnumOps with ToPlusEmptyOps with ToEachOps with ToIndexOps
with ToFunctorOps with ToContravariantOps with ToApplyOps
with ToApplicativeOps with ToBindOps with ToMonadOps with ToComonadOps
with ToBifoldableOps with ToCozipOps
Oops, something went wrong.

0 comments on commit 5a1bd61

Please sign in to comment.