charles-river-analytics / figaro

Figaro Programming Language and Core Libraries
Other
757 stars 153 forks source link

No object orientation for dynamic models #570

Open loechner opened 8 years ago

loechner commented 8 years ago

Should ElementCollection be supported for particle filters? Currently, the following test fails for me:

package com.cra.figaro.test.language

import com.cra.figaro.algorithm.filtering.ParticleFilter
import com.cra.figaro.language._

class ReferenceTestPF extends ReferenceTest {
  "Running particle filter" should {
    val numParticles = 10000
    val tolerance = 0.01

    "produce the correct set of values for an indirect single-valued reference" in {
      def transition(universePrevious: Universe): Universe = {
        val universeCurrent = new Universe()
        val xPrevious = universePrevious.get[C1]("x")
        Apply(xPrevious, (x: C1) => x)("x", universeCurrent)
        universeCurrent
      }

      val universeInitial = Universe.createNew()
      class C1 extends ElementCollection {
        val s = Select(0.2 -> 1, 0.3 -> 2, 0.5 -> 3)("s", this)
      }
      class C2 extends C1 {
        override val s = Select(0.5 -> 4, 0.5 -> 2)("s", this)
      }
      Select(0.2 -> new C1, 0.8 -> new C2)("x", universeInitial)

      val alg = ParticleFilter(universeInitial, transition, numParticles)
      alg.start()
      alg.advanceTime()
      noException should be thrownBy alg.currentProbability("x.s", 2)
      val correctProb = 0.2 * 0.3 + 0.8 * 0.5
      alg.currentProbability("x.s", 2) should be(correctProb +- tolerance)
    }
  }
}
bruttenberg commented 8 years ago

Hi Julian,

Thanks for filing the issue. This should be supported and I'll have to check our tests to see if we test for this. Can you tell me what version and what error you get?

loechner commented 8 years ago

Hi bruttenberg,

thanks for looking into this. I'm on the current master branch. Here is the error I get:

java.util.NoSuchElementException: key not found: Name(x)
    at scala.collection.MapLike$class.default(MapLike.scala:228)
    at scala.collection.AbstractMap.default(Map.scala:59)
    at scala.collection.mutable.HashMap.apply(HashMap.scala:65)
    at com.cra.figaro.language.ElementCollection$class.getElementByReference(ElementCollection.scala:292)
    at com.cra.figaro.language.Universe.getElementByReference(Universe.scala:33)
    at com.cra.figaro.algorithm.filtering.Snapshot.get(Snapshot.scala:43)
    at com.cra.figaro.algorithm.filtering.State.get(State.scala:29)
    at com.cra.figaro.algorithm.filtering.ParticleFilter$$anonfun$4.apply(ParticleFilter.scala:54)
    at com.cra.figaro.algorithm.filtering.ParticleFilter$$anonfun$4.apply(ParticleFilter.scala:54)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:245)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:245)
    at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:33)
    at scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:186)
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:245)
    at scala.collection.mutable.ArrayOps$ofRef.map(ArrayOps.scala:186)
    at com.cra.figaro.algorithm.filtering.ParticleFilter$class.computeCurrentExpectation(ParticleFilter.scala:54)
    at com.cra.figaro.algorithm.filtering.OneTimeParticleFilter.computeCurrentExpectation(ParticleFilter.scala:179)
    at com.cra.figaro.algorithm.filtering.Filtering.computeCurrentProbability(Filtering.scala:61)
    at com.cra.figaro.algorithm.filtering.OneTimeFiltering$class.currentProbability(OneTimeFiltering.scala:42)
    at com.cra.figaro.algorithm.filtering.OneTimeParticleFilter.currentProbability(ParticleFilter.scala:179)
    at com.cra.figaro.algorithm.filtering.Filtering.currentProbability(Filtering.scala:87)
    at com.cra.figaro.test.language.ReferenceTestPF$$anonfun$1$$anonfun$apply$mcV$sp$1$$anonfun$apply$mcV$sp$2.apply$mcV$sp(ReferenceTestPF.scala:52)
    at com.cra.figaro.test.language.ReferenceTestPF$$anonfun$1$$anonfun$apply$mcV$sp$1$$anonfun$apply$mcV$sp$2.apply(ReferenceTestPF.scala:52)
    at com.cra.figaro.test.language.ReferenceTestPF$$anonfun$1$$anonfun$apply$mcV$sp$1$$anonfun$apply$mcV$sp$2.apply(ReferenceTestPF.scala:52)
    at org.scalatest.Assertions$.checkNoException(Assertions.scala:1588)
    ... 58 more

The problem is that the nested reference name "s" can not be found in the "values" Map of com.cra.figaro.algorithm.filtering.Snapshot (the thrown exception hints in another direction).

The code snippet above extends your com.cra.figaro.test.language.ReferenceTest class. There you already define similar tests for other algorithms.

bruttenberg commented 8 years ago

Thanks Julian. My guess is that this is a bug and has not been tested. We'll have to take a look. You may be able to get around this for now by lifting the x.s variable up to the top level. Meaning, in the transition function, call get("x.s") and store into a variable. I'm not sure it will work though.

Brian

AliOC commented 8 years ago

Look into this Brian.