charles-river-analytics / figaro

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

Problems with VariableElimination and Chain[Array[T], R] #635

Open dgarant opened 7 years ago

dgarant commented 7 years ago

I have a use case where I need to model non-deterministic functions where the number of inputs is unknown at compile time, but fixed at runtime. This requires that I implement something like the buildResult function. I'm finding that running VariableElimination in these cases results in target factors of dimension 0. Sampling strategies work fine. Here's a minimal example. Of course, there are other ways to model this particular three-variable system, but the signature of the buildResult function is what matters.

def buildResult[T:ClassTag, R](f:Array[T] => Element[R], elements:Element[T]*):Element[R] = {
  val arrElt = Container(elements:_*)
    .foldLeft(Array.empty[T])((run, c) => run ++ Array(c))
  Chain[Array[T], R](arrElt, f)
}

val in1 = discrete.Uniform(0.0, 1.0)
val in2 = discrete.Uniform(0.0, 1.0)
val sum = buildResult[Double, Double](vals => 
      discrete.Uniform(vals.sum-1, vals.sum, vals.sum+1), in1, in2)

val sampler = Importance(1000, sum)
sampler.run()
sampler.computeDistribution(sum).length should be > 0 // okay so far

val alg = VariableElimination(sum)
alg.run()
alg.computeDistribution(sum).length should be > 0 // failure occurs here

Is there something wrong with my approach, or is this unsupported?

apfeffer commented 7 years ago

Hi Dan,

I’m having trouble parsing your code. What is buildResult supposed to do?

Avi

From: Dan Garant notifications@github.com Reply-To: p2t2/figaro reply@reply.github.com Date: Friday, December 2, 2016 at 12:24 PM To: p2t2/figaro figaro@noreply.github.com Subject: [p2t2/figaro] Problems with VariableElimination and Chain[Array[T], R] (#635)

I have a use case where I need to model non-deterministic functions where the number of inputs is unknown at compile time, but fixed at runtime. This requires that I implement something like the buildResult function. I'm finding that running VariableElimination in these cases results in target factors of dimension 0. Sampling strategies work fine. Here's a minimal example. Of course, there are other ways to model this particular three-variable system, but the signature of the buildResult function is what matters.

def buildResult[T:ClassTag, R](f:Array[T] => Element[R], elements:Element[T]*):Element[R] = {

val arrElt = Container(elements:_*)

.foldLeft(Array.empty[T])((run, c) => run ++ Array(c))

Chain[Array[T], R](arrElt, f)

}

val in1 = discrete.Uniform(0.0, 1.0)

val in2 = discrete.Uniform(0.0, 1.0)

val sum = buildResult[Double, Double](vals =>

  discrete.Uniform(vals.sum-1, vals.sum, vals.sum+1), in1, in2)

val sampler = Importance(1000, sum)

sampler.run()

sampler.computeDistribution(sum).length should be > 0 // okay so far

val alg = VariableElimination(sum)

alg.run()

alg.computeDistribution(sum).length should be > 0 // failure occurs here

Is there something wrong with my approach, or is this unsupported?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHubhttps://github.com/p2t2/figaro/issues/635, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AFJkdyJgqzCRWOjMspAXM5FTdwI56ydaks5rEFRMgaJpZM4LCypG.

dgarant commented 7 years ago

Ultimately I'd like an Element[Array[T]] from a sequence of Element[T]s. In my current code, I construct Element[Array[T]]s by folding a container. Then, I'm given a function which can turn Array[T]s into Rs. I'd like chain my array-type element into that function to get an Element[R].

I'm not sure what inspired me to fold a container instead of using Inject here. I tried Inject and that gives the expected result, so perhaps this can be closed.