[add][mod] added function to return closest keys in map
- [mod] modified Time to extend Ordered
This commit is contained in:
@@ -10,10 +10,15 @@ import scala.collection.parallel.ForkJoinTaskSupport
|
|||||||
|
|
||||||
// Note: case classes implement equality and compare their values and not the memory address
|
// Note: case classes implement equality and compare their values and not the memory address
|
||||||
// It only compares vals from the constructor
|
// It only compares vals from the constructor
|
||||||
case class Time(time: Int, duration: Int){
|
case class Time(time: Int, duration: Int) extends Ordered[Time]{
|
||||||
def prev: Time = { Time(time - 1, duration) }
|
def prev: Time = { Time(time - 1, duration) }
|
||||||
def start: Boolean = { time == 0 }
|
def start: Boolean = { time == 0 }
|
||||||
def get: Int = { time }
|
def get: Int = { time }
|
||||||
|
|
||||||
|
override def compare(that: Time): Int = {
|
||||||
|
time.compare(that.time)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// while it would seem convinient to just throw the sensors/behaviours as value into these
|
// while it would seem convinient to just throw the sensors/behaviours as value into these
|
||||||
@@ -23,6 +28,10 @@ case class SharedMemory(sensor: Map[Time, Map[Cell, Map[Group, Vector[SensorResu
|
|||||||
groundTruth: Map[Time, Map[Cell, Map[Group, Truth]]],
|
groundTruth: Map[Time, Map[Cell, Map[Group, Truth]]],
|
||||||
config: SimulationConfig,
|
config: SimulationConfig,
|
||||||
output: Vector[BroadcastObject[Boolean]]) {
|
output: Vector[BroadcastObject[Boolean]]) {
|
||||||
|
// memory optimization: remove sensor and throw output into output
|
||||||
|
// only map Truths from config into groundtruth, do a if groundTruth.contains(time) groundTruth(time) else prevTruth in case of time.start Truth(None) (or better map it to time.start anyways in parser)
|
||||||
|
// can drop cell from ground truth
|
||||||
|
|
||||||
// This could be spatially optimized to have a function to invoke a new simulation tick
|
// This could be spatially optimized to have a function to invoke a new simulation tick
|
||||||
// a template of Map[Cell, Map[Group, Vector[SensorResult]]] would have to be kept and deep copied when
|
// a template of Map[Cell, Map[Group, Vector[SensorResult]]] would have to be kept and deep copied when
|
||||||
// another tick is simulated. this won't work for ground truth, as it may already be defined
|
// another tick is simulated. this won't work for ground truth, as it may already be defined
|
||||||
@@ -77,13 +86,28 @@ case class SimulationConfig(duration: Int, runs: Int, tickfactor: Int = 1,
|
|||||||
val sensorThreadPool: ForkJoinTaskSupport = new ForkJoinTaskSupport(new scala.concurrent.forkjoin.ForkJoinPool(parSensorThreads))
|
val sensorThreadPool: ForkJoinTaskSupport = new ForkJoinTaskSupport(new scala.concurrent.forkjoin.ForkJoinPool(parSensorThreads))
|
||||||
}
|
}
|
||||||
case class SensorResult(result: BroadcastObject[(Group, Cell, Option[Double])]) extends BroadcastHandler(result)
|
case class SensorResult(result: BroadcastObject[(Group, Cell, Option[Double])]) extends BroadcastHandler(result)
|
||||||
|
/* rough size estimation
|
||||||
|
Group(name: String, sensorParent: Option[String] = None)
|
||||||
|
String: 2*x, String: 2*x
|
||||||
|
case class Cell(x: Int, y: Int)
|
||||||
|
Int: 4, Int: 4
|
||||||
|
Double: 8
|
||||||
|
4*8+4+4+8 ~ 64
|
||||||
|
SensorResult(result: BroadcastObject[(Group, Cell, Option[Double])])
|
||||||
|
default: 64
|
||||||
|
value: 64
|
||||||
|
locks: 8*4 (at least) = 32 (probably 64)
|
||||||
|
frame: 4
|
||||||
|
bool: 1
|
||||||
|
~ 3*64 = 192 byte
|
||||||
|
*/
|
||||||
case class SensorID(group: Group, Id: Int)
|
case class SensorID(group: Group, Id: Int)
|
||||||
case class Duration(simDuration: Int)
|
case class Duration(simDuration: Int)
|
||||||
case class TickFactor(factor: Int) // processed when parsing configuration, artifically place timings
|
case class TickFactor(factor: Int) // processed when parsing configuration, artifically place timings
|
||||||
case class Cell(x: Int, y: Int)
|
case class Cell(x: Int, y: Int)
|
||||||
case class Group(name: String, sensorParent: Option[String] = None){
|
case class Group(name: String, sensorParent: Option[String] = None){
|
||||||
// the sensorParent serves as indicator for the parser that a ground truth is not required
|
// the sensorParent serves as indicator for the parser that a ground truth is not required
|
||||||
// FIXME: use parent as get function and parent.set as setter to make var private
|
// TODO: use parent as get function and parent.set as setter to make var private
|
||||||
var parent: Option[String] = sensorParent // have to make this mutable to reassign it during parsing
|
var parent: Option[String] = sensorParent // have to make this mutable to reassign it during parsing
|
||||||
def getParentOrGroup: Group = {
|
def getParentOrGroup: Group = {
|
||||||
if(parent.isEmpty) {
|
if(parent.isEmpty) {
|
||||||
|
|||||||
@@ -3,11 +3,14 @@ package scim.lib
|
|||||||
// java imports
|
// java imports
|
||||||
import java.io.{File, FileInputStream}
|
import java.io.{File, FileInputStream}
|
||||||
|
|
||||||
|
import scala.collection.immutable.ListMap
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// scala imports
|
// scala imports
|
||||||
|
import scala.collection.JavaConverters._
|
||||||
import scala.collection.convert.wrapAll._
|
import scala.collection.convert.wrapAll._
|
||||||
import scala.collection.mutable
|
import scala.collection.mutable
|
||||||
import scala.collection.JavaConverters._
|
|
||||||
|
|
||||||
// external imports
|
// external imports
|
||||||
import org.yaml.snakeyaml.Yaml
|
import org.yaml.snakeyaml.Yaml
|
||||||
@@ -45,6 +48,7 @@ package object printUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
package object evalUtil {
|
package object evalUtil {
|
||||||
|
|
||||||
def time[A](name: String, f: => A): A = {
|
def time[A](name: String, f: => A): A = {
|
||||||
val t0 = System.nanoTime()
|
val t0 = System.nanoTime()
|
||||||
val result = f
|
val result = f
|
||||||
@@ -52,6 +56,14 @@ package object evalUtil {
|
|||||||
println(name + " Elapsed time: " + (t1 - t0) + "ns")
|
println(name + " Elapsed time: " + (t1 - t0) + "ns")
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: obviously need to assign something and not null
|
||||||
|
def memSize(obj: Any): Long = {
|
||||||
|
// import java.lang.instrument.Instrumentation
|
||||||
|
// val instrumentation: Instrumentation = null
|
||||||
|
// instrumentation.getObjectSize(obj)
|
||||||
|
0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
package object debugUtil {
|
package object debugUtil {
|
||||||
@@ -144,6 +156,59 @@ package object mapUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def getFirstElement[A, B](map: Map[A, B])(implicit ordering:Ordering[A]): (A, B) = {
|
||||||
|
ListMap(map.toSeq.sortBy(_._1):_*).toVector(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
def getLastElement[A, B](map: Map[A, B])(implicit ordering:Ordering[A]): (A, B) = {
|
||||||
|
ListMap(map.toSeq.sortBy(_._1):_*).toVector(map.size - 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is just a binary search that returns the closest match
|
||||||
|
private def getClosestKeysHelper[A, B](key: A, start: Int, end: Int, vector: Vector[(A, B)])(implicit ordering:Ordering[A]): ((A, B), Option[(A, B)]) = {
|
||||||
|
val mid = start + (end - start) / 2
|
||||||
|
val foundKey = vector(mid)._1
|
||||||
|
// dont check for equality but order
|
||||||
|
if(ordering.compare(key, foundKey) == 0) return (vector(mid), Some(vector(mid + 1)))
|
||||||
|
// special case for 2 elements left
|
||||||
|
if((end - start) == 1) {
|
||||||
|
if(ordering.compare(key, vector(end)._1) >= 0) {
|
||||||
|
(vector(end), None)
|
||||||
|
} else {
|
||||||
|
// use getFirstElement to check if this is the beginning
|
||||||
|
(vector(start), Some(vector(end)))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (ordering.compare(key, foundKey) > 0) {
|
||||||
|
getClosestKeysHelper(key, mid, end, vector)
|
||||||
|
} else {
|
||||||
|
getClosestKeysHelper(key, start, mid, vector)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def getClosestKeys[A, B](key: A, map: Map[A, B])(implicit ordering:Ordering[A]): ((A, B), Option[(A, B)]) = {
|
||||||
|
val vectorMap = ListMap(map.toSeq.sortBy(_._1):_*).toVector
|
||||||
|
getClosestKeysHelper(key, 0, vectorMap.size - 1, vectorMap)
|
||||||
|
}
|
||||||
|
|
||||||
|
def getKeyOrNext[A, B](key: A, map: Map[A, B])(implicit ordering:Ordering[A]): (A, B) = {
|
||||||
|
if(map.contains(key)) return (key, map(key))
|
||||||
|
val vectorMap = ListMap(map.toSeq.sortBy(_._1):_*).toVector
|
||||||
|
val result = getClosestKeysHelper(key, 0, vectorMap.size - 1, vectorMap)
|
||||||
|
if(ordering.compare(key, result._1._1)<= 0) {
|
||||||
|
result._1
|
||||||
|
} else {
|
||||||
|
result._2.getOrElse(result._1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def getKeyOrPrev[A, B](key: A, map: Map[A, B])(implicit ordering:Ordering[A]): (A, B) = {
|
||||||
|
if(map.contains(key)) return (key, map(key))
|
||||||
|
val vectorMap = ListMap(map.toSeq.sortBy(_._1):_*).toVector
|
||||||
|
val result = getClosestKeysHelper(key, 0, vectorMap.size - 1, vectorMap)
|
||||||
|
result._1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
package object yml {
|
package object yml {
|
||||||
|
|||||||
Reference in New Issue
Block a user