spire.std.map.scala Maven / Gradle / Ivy
package spire.std
import spire.algebra._
import scala.{ specialized => spec }
import scala.annotation.tailrec
@SerialVersionUID(0L)
class MapMonoid[K, V](implicit val scalar: Semigroup[V]) extends Monoid[Map[K, V]]
with Serializable {
def id: Map[K, V] = Map.empty
def op(x: Map[K, V], y: Map[K, V]): Map[K, V] = {
var xx = x
var yy = y
var f = scalar.op _
if (x.size < y.size) { xx = y; yy = x; f = (x: V, y: V) => scalar.op(y, x) }
yy.foldLeft(xx) { (z, kv) =>
z.updated(kv._1, (xx get kv._1).map(u => f(u, kv._2)).getOrElse(kv._2))
}
}
}
@SerialVersionUID(0L)
class MapGroup[K, V](implicit override val scalar: Group[V]) extends MapMonoid[K, V]
with Group[Map[K, V]] with Serializable {
def inverse(x: Map[K, V]): Map[K, V] = x.mapValues(scalar.inverse)
}
@SerialVersionUID(0L)
class MapSemiring[K, V](implicit val scalar: Semiring[V]) extends Semiring[Map[K, V]] with Serializable {
def zero: Map[K, V] = Map.empty
def plus(x: Map[K, V], y: Map[K, V]): Map[K, V] = {
var xx = x
var yy = y
if (x.size < y.size) { xx = y; yy = x }
yy.foldLeft(xx) { (z, kv) =>
z.updated(kv._1, (xx get kv._1).map(u => scalar.plus(u, kv._2)).getOrElse(kv._2))
}
}
def times(x: Map[K, V], y: Map[K, V]): Map[K, V] = {
var xx = x
var yy = y
var f = scalar.times _
if (x.size < y.size) { xx = y; yy = x; f = (x: V, y: V) => scalar.times(y, x) }
yy.foldLeft(zero) { (z, kv) =>
(xx get kv._1).map(u => z.updated(kv._1, f(u, kv._2))).getOrElse(z)
}
}
}
@SerialVersionUID(0L)
class MapRng[K, V](override implicit val scalar: Rng[V]) extends MapSemiring[K, V] with RingAlgebra[Map[K, V], V] with Serializable { self =>
def negate(x: Map[K, V]): Map[K, V] = x mapValues (scalar.negate(_))
def timesl(r: V, v: Map[K, V]): Map[K, V] = v mapValues (scalar.times(r, _))
}
@SerialVersionUID(0L)
class MapVectorSpace[K, V](override implicit val scalar: Field[V]) extends MapRng[K, V] with VectorSpace[Map[K, V], V] with Serializable {
override def times(x: Map[K, V], y: Map[K, V]): Map[K, V] = {
var xx = x
var yy = y
var f = scalar.times _
if (x.size < y.size) { xx = y; yy = x }
yy.foldLeft(zero) { (z, kv) =>
(xx get kv._1).map(u => z.updated(kv._1, scalar.times(u, kv._2))).getOrElse(z)
}
}
}
@SerialVersionUID(0L)
class MapInnerProductSpace[K, V: Field] extends MapVectorSpace[K, V] with InnerProductSpace[Map[K, V], V] with Serializable {
def dot(x: Map[K, V], y: Map[K, V]): V =
times(x, y).foldLeft(scalar.zero) { (a, b) => scalar.plus(a, b._2) }
}
@SerialVersionUID(0L)
class MapEq[K, V](implicit V: Eq[V]) extends Eq[Map[K, V]] with Serializable {
def eqv(x: Map[K, V], y: Map[K, V]): Boolean = {
if (x.size != y.size) false else {
x forall { case (k, v) =>
(y get k) match {
case Some(e) if V.eqv(e, v) => true
case _ => false
}
}
}
}
}
@SerialVersionUID(0L)
class MapVectorEq[K, V](implicit V: Eq[V], scalar: AdditiveMonoid[V]) extends Eq[Map[K, V]] with Serializable {
def eqv(x: Map[K, V], y: Map[K, V]): Boolean = {
@tailrec
def loop(acc: Map[K, V], it: Iterator[(K, V)]): Boolean = {
if (it.hasNext) {
val (k, v0) = it.next()
(acc get k) match {
case Some(v1) if V.eqv(v0, v1) =>
loop(acc - k, it)
case None if V.eqv(v0, scalar.zero) =>
loop(acc - k, it)
case _ =>
false
}
} else {
acc forall { case (_, v) => V.eqv(v, scalar.zero) }
}
}
loop(x, y.toIterator)
}
}
trait MapInstances0 {
implicit def MapMonoid[K, V: Semigroup]: MapMonoid[K, V] = new MapMonoid[K, V]
implicit def MapSemiring[K, V: Semiring]: MapSemiring[K, V] = new MapSemiring[K, V]
}
trait MapInstances1 extends MapInstances0 {
implicit def MapRng[K, V: Rng]: MapRng[K, V] = new MapRng[K, V]
}
trait MapInstances2 extends MapInstances1 {
implicit def MapGroup[K, V: Group]: MapGroup[K, V] = new MapGroup[K, V]
implicit def MapVectorSpace[K, V: Field]: MapVectorSpace[K, V] = new MapVectorSpace[K, V]
}
trait MapInstances3 extends MapInstances2 {
implicit def MapInnerProductSpace[K, V: Field]: MapInnerProductSpace[K, V] = new MapInnerProductSpace[K, V]
implicit def MapEq[K, V](implicit V0: Eq[V]): MapEq[K, V] = new MapEq[K, V]
}
trait MapInstances extends MapInstances3
© 2015 - 2025 Weber Informatics LLC | Privacy Policy