Skip to content

Instantly share code, notes, and snippets.

@yu-iskw
Last active August 29, 2015 14:05
Show Gist options
  • Save yu-iskw/37ae208c530f7018e048 to your computer and use it in GitHub Desktop.
Save yu-iskw/37ae208c530f7018e048 to your computer and use it in GitHub Desktop.
Distance Metric Implementation Example
import breeze.generic.UFunc
import breeze.linalg.{sum, DenseVector => DBV, Vector => BV}
import breeze.macros.expand
object distance extends UFunc {
val DEFAULT_METHOD = "euclidean"
@expand
@expand.valify
implicit def distanceImpl: Impl3[BV[Double], BV[Double], String, Double] = {
new Impl3[BV[Double], BV[Double], String, Double] {
def apply(v1: BV[Double], v2: BV[Double], method: String): Double = {
method match {
case "euclidean" => euclidean(v1, v2)
case "manhattan" => manhattan(v1, v2)
case _ => euclidean(v1, v2) // originally throws
}
}
}
}
@expand
@expand.valify
implicit def defaultDistanceImpl: Impl2[BV[Double], BV[Double], Double] = {
new Impl2[BV[Double], BV[Double], Double] {
def apply(v1: BV[Double], v2: BV[Double]): Double = {
distance(v1, v2, DEFAULT_METHOD)
}
}
}
}
object euclidean extends UFunc {
@expand
@expand.valify
implicit def distanceImpl: Impl2[BV[Double], BV[Double], Double] = {
new Impl2[BV[Double], BV[Double], Double] {
def apply(v1: BV[Double], v2: BV[Double]): Double = {
val d = v1 - v2
Math.sqrt(d dot d)
}
}
}
}
object manhattan extends UFunc {
@expand
@expand.valify
implicit def distanceImpl: Impl2[BV[Double], BV[Double], Double] = {
new Impl2[BV[Double], BV[Double], Double] {
def apply(v1: BV[Double], v2: BV[Double]): Double = {
sum((v1 - v2).map(Math.abs))
}
}
}
}
@dlwh
Copy link

dlwh commented Aug 29, 2014

Thanks!

  1. no reason to use @expand if you're not using type parameters (@expand code gens type parameters)
  2. manhattan can just be norm(v1 - v2, 1), euclidean norm(v1 - v2, 2)
  3. I'd rather use objects in a sealed (or even non-sealed) trait than strings

@yu-iskw
Copy link
Author

yu-iskw commented Sep 2, 2014

HI @dlwh,

Thank you for your comment.
I am working to contribute some distance functions to Breeze.
I will send a PR to Breeze, please wait a moment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment