locked
Nested switch blocks - newbie question RRS feed

  • Question

  • Can one use nested switch blocks that are conditioned on different Variable<int> variables in Infer.Net? When I am trying to do it I am getting the following exception:

    An unhandled exception of type 'System.InvalidOperationException' occurred in Infer.Compiler.dll

    Additional information: Range 'index0' is already open in a ForEach or Switch block

    Friday, February 10, 2012 2:16 PM

Answers

  • Yes, you can have nested switch blocks.  You are probably getting this error because both variables are using the same ValueRange.  If so, you will need to use range cloning as described here.
    Saturday, February 11, 2012 12:22 PM
    Owner

All replies

  • Yes, you can have nested switch blocks.  You are probably getting this error because both variables are using the same ValueRange.  If so, you will need to use range cloning as described here.
    Saturday, February 11, 2012 12:22 PM
    Owner
  • I have a very similar question.  I get the same error: "Range g2VertexRangeClone is already open in a ForEach or Switch block" on the line //*.  I've tried changing the ValueRange like in the example you linked, but that hasn't solved it.  What am I missing?

    //Constructed above: bool[][] g2AdjacencyMatrixObserved, int[] g1EdgesSourceVerticesObserved, int[] g1EdgesSinkVerticesObserved
    
    Range g1VertexRange = new Range(g1.VertexCount).Named("g1VertexRange");
    Range g1VertexRangeClone = g1VertexRange.Clone().Named("g1VertexRangeClone");
    Range g2VertexRange = new Range(g2.VertexCount).Named("g2VertexRange");
    Range g2VertexRangeClone = g2VertexRange.Clone().Named("g2VertexRangeClone");
    Range g1EdgeRange = new Range(g1.EdgeCount).Named("g1EdgeRange");
    Range g1EdgeRangeClone = g1EdgeRange.Clone().Named("g1EdgeRangeClone");
    
    var g2AdjacencyMatrix = Variable.Array(Variable.Array<bool>(g2VertexRangeClone), g2VertexRange);
    g2AdjacencyMatrix.ObservedValue = g2AdjacencyMatrixObserved;
    VariableArray<int> g1EdgesSourceVertices = Variable.Observed(g1EdgeSourceVerticesObserved, g1EdgeRange);
    g1EdgesSourceVertices.SetValueRange(g1VertexRange);
    VariableArray<int> g1EdgesSinkVertices = Variable.Observed(g1EdgeSinkVerticesObserved, g1EdgeRangeClone);
    g1EdgesSinkVertices.SetValueRange(g1VertexRangeClone);
    
    VariableArray<int> labels = Variable.Array<int>(g1VertexRange);
    labels[g1VertexRange] = Variable.DiscreteUniform(g2VertexRange).ForEach(g1VertexRange);
    VariableArray<bool> areG1EdgesInG2 = Variable.Array<bool>(g1EdgeRange);
    areG1EdgesInG2[g1EdgeRange] = Variable.Bernoulli(0.99).ForEach(g1EdgeRange);
    using (Variable.ForEach(g1EdgeRange))
    {
    	var l1 = labels[g1EdgesSourceVertices[g1EdgeRange]];
    	var l2 = labels[g1EdgesSinkVertices[g1EdgeRange]];
    	l2.SetValueRange(g2VertexRangeClone);
    	using (Variable.Switch(l1))
    		using (Variable.Switch(l2))
    			areG1EdgesInG2[g1EdgeRange] = g2AdjacencyMatrix[l1][l2]; //*
    }

    InferenceEngine.Infer(labels);

    Here is some background into my problem, if it helps.  I'm trying to do some graph matching.  I have two graphs  g1 and g2.  My model says each vertex in g1 can be labelled as any vertex in g2.  Each edge in g1 has a 99% chance of corresponding to an edge between the labelled vertices in g2.  It's not a very good model, but I'd like to get this one working before I enhance it.  Thanks for any advice you have.

    Tuesday, April 10, 2012 8:50 PM
  • When you set the ValueRange of l2, you are actually setting the ValueRange of the entire labels array, which means that l1's ValueRange changes as well.  Try changing the definition of l2 to:

    var l2 = Variable.Copy(labels[g1EdgesSinkVertices[g1EdgeRange]]);
    By the way, you also have two definitions of areG1EdgesInG2.  The first one should be deleted.
    Sunday, April 22, 2012 9:35 AM
    Owner