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

bitstream.simulator.Units.scala Maven / Gradle / Ivy

The newest version!
package bitstream.simulator.units

import reflect._
import Array._
import bitstream.types._
import math._
import scala.util.Random

// trait BitstreamSpecificType[A] {

//   type Bit

// }

// object BitstreamSpecificType {

//   implicit object SBitstreamType extends BitstreamSpecificType[SBitstream] {
//     type Bit = Tuple2[Int, Int]
//   }

//   implicit object DBitstreamType extends BitstreamSpecificType[DBitstream] {
//     type Bit = Int
//   }

// }

case class Decorrelator(val _numRows: Int, val _numCols: Int,
                        val _stepVal: Int = 16, val _rngRange: Int = 255) {

  private var rng = Random
  private var countersP = Matrix.zeros[Int](_numRows, _numCols)
  private var countersN = Matrix.zeros[Int](_numRows, _numCols)
  private var bufferP = new Array[Matrix[Int]](2)
  private var bufferN = new Array[Matrix[Int]](2)

  bufferP(0) = Matrix.zeros[Int](_numRows, _numCols)
  bufferP(1) = Matrix.zeros[Int](_numRows, _numCols)
  bufferN(0) = Matrix.zeros[Int](_numRows, _numCols)
  bufferN(1) = Matrix.zeros[Int](_numRows, _numCols)

  def rows: Int = _numRows
  def cols: Int = _numCols

  def evaluate(x: Tuple2[Int, Int])(implicit i: DummyImplicit): (Int, Int) = {
    require(_numRows == 1 && _numCols == 1,
      "Decorrelator of size > (1, 1) expects Matrix input")

    var resultP = Matrix.zeros[Int](_numRows, _numCols)
    var resultN = Matrix.zeros[Int](_numRows, _numCols)

    // Increment counters
    countersP = countersP + _stepVal * x._1
    countersN = countersN + _stepVal * x._2

    // Output spike
    resultP = bufferP(0)
    resultN = bufferN(0)
    bufferP(0) = bufferP(1)
    bufferN(0) = bufferN(1)
    val rP = rng.nextInt(_rngRange + 1)
    val rN = rng.nextInt(_rngRange + 1)
    bufferP(1)(0, 0) = if (rP <= countersP(0, 0)) 1 else 0
    bufferN(1)(0, 0) = if (rN <= countersN(0, 0)) 1 else 0

    // Decrement counters
    countersP = countersP - _stepVal * resultP
    countersN = countersN - _stepVal * resultN

    (resultP(0, 0), resultN(0, 0))
  }

  def evaluate(x: Tuple2[Matrix[Int], Matrix[Int]]): (Matrix[Int], Matrix[Int]) = {
    var resultP = Matrix.zeros[Int](_numRows, _numCols)
    var resultN = Matrix.zeros[Int](_numRows, _numCols)

    // Increment counters
    countersP = countersP + _stepVal * x._1
    countersN = countersN + _stepVal * x._2

    // Output spike
    resultP = bufferP(0)
    resultN = bufferN(0)
    bufferP(0) = bufferP(1)
    bufferN(0) = bufferN(1)
    for (i <- 0 until _numRows; j <- 0 until _numCols) {
      val rP = rng.nextInt(_rngRange + 1)
      val rN = rng.nextInt(_rngRange + 1)
      bufferP(1)(i, j) = if (rP <= countersP(i, j)) 1 else 0
      bufferN(1)(i, j) = if (rN <= countersN(i, j)) 1 else 0
    }

    // Decrement counters
    countersP = countersP - _stepVal * resultP
    countersN = countersN - _stepVal * resultN

    (resultP, resultN)
  }

}

case class DelayBuffer(private val _delay:Int) {

  // private val _delay = _delayDouble.toInt

  private var buffer = new Array[Bit](_delay)
  private var produceIndex = 0
  private var consumeIndex = 0

  // Fill delay buffer with empty values
  for (i <- 0 until _delay) this.push(0)

  def delay: Bit = _delay

  def pop: Bit = {
    if (produceIndex == consumeIndex)
      throw new Exception("Tried to pop from an empty DelayBuffer")
    else {
      consumeIndex += 1
      buffer((consumeIndex - 1) % _delay)
    }
  }
  def push(x: Bit): Unit = {
    buffer(produceIndex % _delay) = x
    produceIndex += 1
  }

  def evaluate(x: Bit): Bit = {
    this.push(x)
    this.pop
  }

}

case class SDM() {

  private var _error: Double = 0.0

  def error: Double = _error

  def evaluate(input: Double): Bit = {
    val output = if (input >= _error) 1 else -1
    _error = output - input + _error
    output
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy