All Downloads are FREE. Search and download functionalities are using the official Maven repository.

breeze.linalg.Counter.scala Maven / Gradle / Ivy

The newest version!
package breeze.linalg
/*
 Copyright 2012 David Hall

 Licensed under the Apache License, Version 2.0 (the "License")
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
*/

import breeze.storage.DefaultArrayValue
import breeze.math.{TensorSpace, Ring, Semiring, Field}
import breeze.generic.{CanTransformValues, URFunc, UReduceable, CanMapValues}
import collection.Set
import operators._
import support.{CanCreateZerosLike, CanZipMapValues, CanNorm, CanCopy}

/**
 * A map-like tensor that acts like a collection of key-value pairs where
 * the set of values may grow arbitrarily.
 *
 * @author dramage, dlwh
 */
@SerialVersionUID(1)
trait CounterLike[K, V, +M<:scala.collection.mutable.Map[K,V], +This<:Counter[K,V]] extends TensorLike[K,V,This] with Serializable {
  def data : M
  def default: V


  def keySet: Set[K] = data.keySet

  def repr = this.asInstanceOf[This]

  override def size = data.size
  def activeSize = data.size

  def isEmpty = data.isEmpty

  def contains(k: K) = data.contains(k)

  override def apply(k : K) = {
    data.get(k) getOrElse default
  }

  def update(k : K, v : V) { data(k) = v }

  def get(k: K) = data.get(k)


  override def keysIterator = data.keysIterator

  override def valuesIterator = data.valuesIterator

  override def iterator = data.iterator


  def activeIterator = iterator

  def activeValuesIterator = valuesIterator

  def activeKeysIterator = keysIterator

  override def toString: String = data.mkString("Counter(",", ", ")")

  override def equals(p1: Any): Boolean = p1 match {
    case x:Counter[K, V] => x.data == this.data
    case _ => false
  }

  override def hashCode(): Int = data.hashCode()

  def toMap = data.toMap
}

trait Counter[K, V] extends Tensor[K,V] with CounterLike[K, V, collection.mutable.Map[K, V], Counter[K,V]] {

}

object Counter extends CounterOps {
  /** Returns an empty counter. */
  def apply[K,V:DefaultArrayValue:Semiring]() : Counter[K,V] =
    new Impl(scala.collection.mutable.HashMap[K,V]())

  /** Returns a counter by summing all the given values. */
  def apply[K,V:DefaultArrayValue:Semiring](values : (K,V)*) : Counter[K,V] =
    apply(values)

  /** Returns a counter by summing all the given values. */
  def apply[K,V:DefaultArrayValue:Semiring](values : TraversableOnce[(K,V)]) : Counter[K,V] = {
    val rv = apply[K,V]()
    val field = implicitly[Semiring[V]]
    values.foreach({ case (k,v) => rv(k) = field.+(v,rv(k)) })
    rv
  }

  /** Counts each of the given items. */
  def countTraversable[K](items : TraversableOnce[K]) : Counter[K,Int] = {
    val rv = apply[K,Int]()
    items.foreach(rv(_) += 1)
    rv
  }

  def count[K](items: K*): Counter[K,Int] = countTraversable(items)

  class Impl[K, V]
  (override val data : scala.collection.mutable.Map[K,V])
  (implicit defaultArrayValue : DefaultArrayValue[V])
  extends Counter[K,V] {
    def default = defaultArrayValue.value
  }

  implicit def canMapValues[K, V, RV:Semiring:DefaultArrayValue]: CanMapValues[Counter[K, V], V, RV, Counter[K, RV]]
  = new CanMapValues[Counter[K,V],V,RV,Counter[K,RV]] {
    override def map(from : Counter[K,V], fn : (V=>RV)) = {
      val rv = Counter[K,RV]()
      for( (k,v) <- from.iterator) {
        rv(k) = fn(from.data(k))
      }
      rv
    }

    override def mapActive(from : Counter[K,V], fn : (V=>RV)) = {
      val rv = Counter[K,RV]()
      for( (k,v) <- from.activeIterator) {
        rv(k) = fn(from.data(k))
      }
      rv
    }
  }

  implicit def ured[K, V]: UReduceable[Counter[K, V], V] = {
    new UReduceable[Counter[K, V], V] {
      def apply[Final](c: Counter[K, V], f: URFunc[V, Final]): Final = f(c.data.values)
    }

  }

  implicit def tensorspace[K, V:Field:DefaultArrayValue] = {
    implicit def zipMap = Counter.zipMap[K, V, V]
    // sigh...
    TensorSpace.make[Counter[K, V], K, V](canNorm,
      canMapValues[K, V, V],
      ured[K, V],
      zipMap,
      addVS,
      subVS,
      canMulVV,
      canDivVV,
      canCopy,
      canMulIntoVS,
      canDivIntoVS,
      addIntoVV[K, V],
      subIntoVV[K, V],
      addIntoVS[K, V],
      subIntoVS[K, V],
      canMulIntoVV,
      canDivIntoVV,
      canSetIntoVV,
      canSetIntoVS,
      canAxpy,
      implicitly[Field[V]],
      implicitly[CanCreateZerosLike[Counter[K, V], Counter[K, V]]],
      canMulVS,
      canDivVS,
      addVV,
      subVV,
      canNegate,
      implicitly[<:<[breeze.linalg.Counter[K,V],breeze.linalg.NumericOps[breeze.linalg.Counter[K,V]] with breeze.linalg.QuasiTensor[K,V]]],
      canMulInner[K, K, V]
    )
  }
}

trait CounterOps {
  implicit def canCopy[K1, V:DefaultArrayValue:Semiring]:CanCopy[Counter[K1, V]] = new CanCopy[Counter[K1, V]] {
    def apply(t: Counter[K1, V]): Counter[K1, V] = {
      Counter(t.iterator)
    }
  }


  def binaryOpFromBinaryUpdateOp[K, V, Other, Op<:OpType](implicit copy: CanCopy[Counter[K, V]], op: BinaryUpdateOp[Counter[K, V], Other, Op]) = {
    new BinaryOp[Counter[K, V], Other, Op, Counter[K, V]] {
      override def apply(a : Counter[K, V], b : Other) = {
        val c = copy(a)
        op(c, b)
        c
      }
    }
  }


  implicit def addIntoVV[K1, V:Semiring]:BinaryUpdateOp[Counter[K1, V], Counter[K1, V], OpAdd] = new BinaryUpdateOp[Counter[K1, V], Counter[K1, V], OpAdd] {
    val field = implicitly[Semiring[V]]
    def apply(a: Counter[K1, V], b: Counter[K1, V]) {
      for( (k,v) <- b.activeIterator) {
        a(k) = field.+(a(k), v)
      }
    }
  }

  implicit def canAxpy[K1, V:Semiring]:CanAxpy[V, Counter[K1, V], Counter[K1, V]] = new CanAxpy[V, Counter[K1, V], Counter[K1, V]] {
    val field = implicitly[Semiring[V]]
    def apply(s: V, b: Counter[K1, V], a: Counter[K1, V]) {
      for( (k,v) <- b.activeIterator) {
        a(k) = field.+(a(k), field.*(s, v))
      }
    }
  }

  implicit def addVV[K1, V:Semiring:DefaultArrayValue]:BinaryOp[Counter[K1, V], Counter[K1, V], OpAdd, Counter[K1,V]] = {
    binaryOpFromBinaryUpdateOp(canCopy, addIntoVV)
  }

  implicit def addIntoVS[K1, V:Semiring]:BinaryUpdateOp[Counter[K1, V], V, OpAdd] = new BinaryUpdateOp[Counter[K1, V], V, OpAdd] {
    val field = implicitly[Semiring[V]]
    def apply(a: Counter[K1, V], b: V) {
      for( (k,v) <- a.activeIterator) {
        a(k) = field.+(v, b)
      }
    }
  }


  implicit def addVS[K1, V:Semiring:DefaultArrayValue]:BinaryOp[Counter[K1, V], V, OpAdd, Counter[K1,V]] = {
    binaryOpFromBinaryUpdateOp(canCopy, addIntoVS)
  }

  implicit def subIntoVV[K1, V:Ring]:BinaryUpdateOp[Counter[K1, V], Counter[K1, V], OpSub] = new BinaryUpdateOp[Counter[K1, V], Counter[K1, V], OpSub] {
    val field = implicitly[Ring[V]]
    def apply(a: Counter[K1, V], b: Counter[K1, V]) {
      for( (k,v) <- b.activeIterator) {
        a(k) = field.-(a(k), v)
      }
    }
  }


  implicit def subVV[K1, V:Ring:DefaultArrayValue]:BinaryOp[Counter[K1, V], Counter[K1, V], OpSub, Counter[K1,V]] = {
    binaryOpFromBinaryUpdateOp(canCopy, subIntoVV)
  }

  implicit def subIntoVS[K1, V:Ring]:BinaryUpdateOp[Counter[K1, V], V, OpSub] = new BinaryUpdateOp[Counter[K1, V], V, OpSub] {
    val field = implicitly[Ring[V]]
    def apply(a: Counter[K1, V], b: V) {
      for( (k,v) <- a.activeIterator) {
        a(k) = field.-(v, b)
      }
    }
  }


  implicit def subVS[K1, K2<:K1, V:Ring:DefaultArrayValue]:BinaryOp[Counter[K1, V], V, OpSub, Counter[K1,V]] = {
    binaryOpFromBinaryUpdateOp(canCopy, subIntoVS)
  }

  implicit def canMulIntoVV[K2, K1 <: K2, V:Semiring]:BinaryUpdateOp[Counter[K1, V], Counter[K2, V], OpMulScalar] = new BinaryUpdateOp[Counter[K1, V], Counter[K2, V], OpMulScalar] {
    val field = implicitly[Semiring[V]]
    def apply(a: Counter[K1, V], b: Counter[K2, V]) {
      for( (k,v) <- a.activeIterator) {
        a(k) = field.*(v, b(k))
      }
    }
  }

  implicit def canMulVV[K2, K1<:K2, V](implicit semiring: Semiring[V],
                                       d: DefaultArrayValue[V]):BinaryOp[Counter[K1, V], Counter[K2, V], OpMulScalar, Counter[K1, V]] = {
    new BinaryOp[Counter[K1, V], Counter[K2, V], OpMulScalar, Counter[K1, V]] {
      override def apply(a : Counter[K1, V], b : Counter[K2, V]) = {
        val r = Counter[K1, V]()
        for( (k, v) <- a.activeIterator) {
          val vr = semiring.*(v, b(k))
          if(vr != semiring.zero)
            r(k) = vr
        }
        r
      }
    }
  }


  implicit def canMulIntoVS[K2, K1 <: K2, V:Semiring]:BinaryUpdateOp[Counter[K1, V], V, OpMulScalar] = new BinaryUpdateOp[Counter[K1, V], V, OpMulScalar] {
    val field = implicitly[Semiring[V]]
    def apply(a: Counter[K1, V], b: V) {
      for( (k,v) <- a.activeIterator) {
        a(k) = field.*(v, b)
      }
    }
  }

  implicit def canMulIntoVS_M[K2, K1 <: K2, V:Semiring]:BinaryUpdateOp[Counter[K1, V], V, OpMulMatrix] = new BinaryUpdateOp[Counter[K1, V], V, OpMulMatrix] {
    val field = implicitly[Semiring[V]]
    def apply(a: Counter[K1, V], b: V) {
      for( (k,v) <- a.activeIterator) {
        a(k) = field.*(v, b)
      }
    }
  }

  implicit def canMulVS[K2, K1<:K2, V](implicit semiring: Semiring[V],
                                       d: DefaultArrayValue[V]):BinaryOp[Counter[K1, V], V, OpMulScalar, Counter[K1, V]] = {
    new BinaryOp[Counter[K1, V], V, OpMulScalar, Counter[K1, V]] {
      override def apply(a : Counter[K1, V], b : V) = {
        val r = Counter[K1, V]()
        for( (k, v) <- a.activeIterator) {
          val vr = semiring.*(v, b)
            r(k) = vr
        }
        r
      }
    }
  }

  implicit def canMulVS_M[K2, K1<:K2, V](implicit semiring: Semiring[V],
                                       d: DefaultArrayValue[V]):BinaryOp[Counter[K1, V], V, OpMulMatrix, Counter[K1, V]] = {
    new BinaryOp[Counter[K1, V], V, OpMulMatrix, Counter[K1, V]] {
      override def apply(a : Counter[K1, V], b : V) = {
        val r = Counter[K1, V]()
        for( (k, v) <- a.activeIterator) {
          val vr = semiring.*(v, b)
            r(k) = vr
        }
        r
      }
    }
  }


  implicit def canDivIntoVV[K2, K1 <: K2, V:Field]:BinaryUpdateOp[Counter[K1, V], Counter[K2, V], OpDiv] = new BinaryUpdateOp[Counter[K1, V], Counter[K2, V], OpDiv] {
    val field = implicitly[Field[V]]
    def apply(a: Counter[K1, V], b: Counter[K2, V]) {
      for( (k,v) <- a.activeIterator) {
        a(k) = field./(v, b(k))
      }
    }
  }

  implicit def canDivVV[K2, K1<:K2, V](implicit copy: CanCopy[Counter[K1, V]],
                                       semiring: Field[V],
                                       d: DefaultArrayValue[V]):BinaryOp[Counter[K1, V], Counter[K2, V], OpDiv, Counter[K1, V]] = {
    new BinaryOp[Counter[K1, V], Counter[K2, V], OpDiv, Counter[K1, V]] {
      override def apply(a : Counter[K1, V], b : Counter[K2, V]) = {
        val r = Counter[K1, V]()
        for( (k, v) <- a.activeIterator) {
          val vr = semiring./(v, b(k))
            r(k) = vr
        }
        r
      }
    }
  }


  implicit def canDivVS[K1, V](implicit copy: CanCopy[Counter[K1, V]],
                               semiring: Field[V],
                               d: DefaultArrayValue[V]):BinaryOp[Counter[K1, V], V, OpDiv, Counter[K1, V]] = {
    new BinaryOp[Counter[K1, V], V, OpDiv, Counter[K1, V]] {
      override def apply(a : Counter[K1, V], b : V) = {
        val r = Counter[K1, V]()
        for( (k, v) <- a.activeIterator) {
          val vr = semiring./(v, b)
            r(k) = vr
        }
        r
      }
    }
  }

  implicit def canDivIntoVS[K1, V:Field]:BinaryUpdateOp[Counter[K1, V], V, OpDiv] = new BinaryUpdateOp[Counter[K1, V], V, OpDiv] {
    val field = implicitly[Field[V]]
    def apply(a: Counter[K1, V], b: V) {
      for( (k,v) <- a.activeIterator) {
        a(k) = field./(v, b)
      }
    }
  }


  implicit def canSetIntoVV[K1, K2 <: K1, V]:BinaryUpdateOp[Counter[K1, V], Counter[K2, V], OpSet] = new BinaryUpdateOp[Counter[K1, V], Counter[K2, V], OpSet] {
    def apply(a: Counter[K1, V], b: Counter[K2, V]) {
      a.data.clear()
      for( (k,v) <- b.activeIterator) {
        a(k) = v
      }
    }
  }


  implicit def canSetIntoVS[K1, V]:BinaryUpdateOp[Counter[K1, V], V, OpSet] = new BinaryUpdateOp[Counter[K1, V], V, OpSet] {
    def apply(a: Counter[K1, V], b: V) {
      for( k <- a.keysIterator) {
        a(k) = b
      }
    }
  }

  implicit def canNegate[K1, V](implicit  ring: Ring[V], d: DefaultArrayValue[V]):UnaryOp[Counter[K1, V], OpNeg, Counter[K1, V]] = {
    new UnaryOp[Counter[K1, V], OpNeg, Counter[K1, V]] {
      override def apply(a : Counter[K1, V]) = {
        val result = Counter[K1, V]()
        for( (k, v) <- a.activeIterator) {
          val vr = ring.negate(v)
          result(k) = vr
        }
        result
      }
    }
  }


  implicit def canMulInner[K2, K1<:K2, V](implicit copy: CanCopy[Counter[K1, V]],
                                          semiring: Semiring[V],
                                          d: DefaultArrayValue[V]):BinaryOp[Counter[K1, V], Counter[K2, V], OpMulInner, V] = {
    new BinaryOp[Counter[K1, V], Counter[K2, V], OpMulInner, V] {
      val zero = semiring.zero
      override def apply(a : Counter[K1, V], b : Counter[K2, V]) = {
        var result = zero
        for( (k, v) <- a.activeIterator) {
          val vr = semiring.*(v, b(k))
            result  = semiring.+(result, vr)
        }
        result
      }
    }
  }
  /** Returns the k-norm of this Vector. */
  implicit def canNorm[K, V:Ring]:CanNorm[Counter[K, V]] = new CanNorm[Counter[K, V]] {
    val field = implicitly[Ring[V]]
    def apply(c: Counter[K, V], n: Double): Double = {
      import c._

      if (n == 1) {
        var sum = 0.0
        activeValuesIterator foreach (v => sum += field.norm(v))
        sum
      } else if (n == 2) {
        var sum = 0.0
        activeValuesIterator foreach (v => { val nn = field.norm(v); sum += nn * nn })
        math.sqrt(sum)
      } else if (n == Double.PositiveInfinity) {
        var max = Double.NegativeInfinity
        activeValuesIterator foreach (v => { val nn = field.norm(v); if (nn > max) max = nn })
        max
      } else {
        var sum = 0.0
        activeValuesIterator foreach (v => { val nn = field.norm(v); sum += math.pow(nn,n) })
        math.pow(sum, 1.0 / n)
      }
    }
  }

  class CanZipMapValuesCounter[K, V, RV:DefaultArrayValue:Semiring] extends CanZipMapValues[Counter[K, V],V,RV,Counter[K, RV]] {

    /**Maps all corresponding values from the two collection. */
    def map(from: Counter[K, V], from2: Counter[K, V], fn: (V, V) => RV) = {
      val result = Counter[K, RV]
      for ( k <- (from.keySet ++ from2.keySet)) {
        result(k) = fn(from(k), from2(k))
      }
      result
    }
  }


  implicit def zipMap[K, V, R:DefaultArrayValue:Semiring] = new CanZipMapValuesCounter[K, V, R]


  implicit def canTransformValues[L, V]:CanTransformValues[Counter[L, V], V, V] = {
    new CanTransformValues[Counter[L, V], V, V] {
      def transform(from: Counter[L, V], fn: (V) => V) {
        for( (k,v) <- from.activeIterator) {
          from(k) = fn(v)
        }
      }

      def transformActive(from: Counter[L, V], fn: (V) => V) {
        transform(from, fn)
      }
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy