Stuck with "Replace Expression: #i.#Qb" or "Can only index by loop variables" (Migrated from community.research.microsoft.com) RRS feed

  • Question

  • laura posted on 02-06-2009 8:30 AM


    Trying to follow Tom's hints in the thread on "Work around plates by manual variable synchronization", I got stuck in a "Not Implemented Exception: Unhandled expression type in ReplaceExpression ( ): #i.#Qb". If factor graph and transformbrowser is enabled, this error message occurs between the two, but I have no idea what it is trying to tell me...


    The model maintains one array of edgeLabel variables, indexed by eRange. Each edgeLabel is drawn from a Discrete distribution.

    Each user has an array over his friends.  From this I creates a Constant Array called edgeIndexData which points to the edgeIndex of that friendship. I.e. if the edge between user 0 and his second friend has index 5, then edgeIndexData.[0].[2]=5.

    For each user u do

    - draw a currentFriend  ~ some distribution

    -  currentEdge = edgeIndex.[ u].[f]   // deterministic, given f

    -  currentLabel = edgeLabel2.[currentEdge]

    - do something with the label


    I assume that the problem is related to using the right switches. The following code wraps currentFriend, currentEdge and currentLabel in a switch, and gets the exception.


                    f.[uRange].[sRange] <- Variable.Discrete(psi.[uRange]).Attrib(new ValueRange(fVaryRange))
                    let currentFriend = f.[uRange].[sRange]
                    using (Variable.Switch(currentFriend)) (fun _ ->
                        let currentEdge = (edgeIndexData.[uRange].[currentFriend]).Attrib(new ValueRange(eRange))
                        using (Variable.Switch(currentEdge)) (fun _ ->
                            let currentLabel = ((edgeLabel2.[currentEdge])).Attrib(new ValueRange(cRange))
                            using (Variable.Switch(currentLabel)) (fun _ ->
                                // do something with currentLabel


     Then I was thinking that the Switch around currentEdge is sort of unnecessary, since the relation between currentFriend and currentEdge is deterministic. Omitting this switch I get the following error.

    ChannelTransform failed with 2 error(s) and 0 warning(s):
      Can only index by loop variables, not 'uRange'. in
    vint____5[uRange] = Factor.GetItems<int>(edgeLabel2_rep0[uRange], edgeIndexData[uRange])
      Can only index by loop variables, not 'uRange'. in
    vint____5_cases = Gate.CasesInt(vint____5[uRange][fVaryRange])

    I checked that uRange and fVaryRange are outer loops of these statements.


    vint____5 could not be named, but it containes the edgelabels of a user's friends.

                for(int uRange = 0; uRange<vint0; uRange++)
                    vint____5[uRange] = Factor.GetItems<int>(edgeLabel2, edgeIndexData[uRange]);


    Any ideas?


    Friday, June 3, 2011 5:10 PM


  • minka replied on 08-07-2009 10:40 AM

    This is now fixed in Infer.NET 2.3.

    Friday, June 3, 2011 5:11 PM

All replies

  • minka replied on 02-09-2009 1:23 PM

    Thanks Laura, it seems you have found a bug.  Infer.NET incorrectly thinks that currentEdge is a constant value and this leads to the error.  Even though edgeIndexData is constant, when you index it by the random currentFriend the result should be random.  This is why Switch(currentEdge) is needed (to answer your second question).  

    Friday, June 3, 2011 5:10 PM
  • minka replied on 08-07-2009 10:40 AM

    This is now fixed in Infer.NET 2.3.

    Friday, June 3, 2011 5:11 PM