Bevisuali.Model.Workbench.ThreadMainScenariosInference C# (CSharp) Method

ThreadMainScenariosInference() protected method

protected ThreadMainScenariosInference ( ) : void
return void
        protected void ThreadMainScenariosInference()
        {
            while (true)
            {
                if (_scenariosThreadCancel)
                {
                    break;
                }

                bool didWork = false;

                List<ScenarioRecord> scenarios;
                lock (_scenariosInternal)
                {
                    scenarios = _scenariosInternal.ToList();
                }

                // For each scenario, refine the results.
                foreach (var scenarioRecord in scenarios)
                {
                    InferenceQuery inferenceQuery = scenarioRecord.Query;

                    // If more refinement is needed.
                    if (inferenceQuery.RefinementCount < this.InferenceTargetRefinement)
                    {
                        int nvariables = inferenceQuery.Network.Variables.Count;
                        int batchSize = InferenceStepBatchSizeVariable / nvariables;
                        if (batchSize < InferenceStepBatchSizeMinimum)
                        {
                            batchSize = InferenceStepBatchSizeMinimum;
                        }
                        inferenceQuery.RefineResults(batchSize);
                        didWork = true;

                        var resultsCopy = inferenceQuery.Results.ToDictionary(
                            kvp => kvp.Key,
                            kvp => kvp.Value);
                        scenarioRecord.Scenario.PosteriorMarginals = resultsCopy;
                    }

                    // If no more refinement is needed.
                    if (inferenceQuery.RefinementCount >= this.InferenceTargetRefinement
                        && scenarioRecord.Scenario.InferenceState != ComputationState.Done)
                    {
                        scenarioRecord.Scenario.InferenceState = ComputationState.Done;
                    }
                }

                // Update comparison.
                if (scenarios.Count == 2)
                {
                    if (didWork || _comparisonOptionsDirty)
                    {
                        _comparisonOptionsDirty = false;

                        var comparisonMetric = this._comparisonMetric;

                        ScenarioComparison oldComparison = _scenariosComparison;

                        ScenarioComparison comparison = new ScenarioComparison();
                        comparison.Scenario1 = scenarios[0].Scenario;
                        comparison.Scenario2 = scenarios[1].Scenario;
                        comparison.ComparisonMetric = comparisonMetric;

                        var posteriors1 = comparison.Scenario1.PosteriorMarginals;
                        var posteriors2 = comparison.Scenario2.PosteriorMarginals;
                        List<Tuple<String, Double>> similarities = new List<Tuple<string, double>>();
                        foreach (string variableName in posteriors1.Keys)
                        {
                            var variableDist1 = posteriors1[variableName];
                            var variableDist2 = posteriors2[variableName];
                            double dissimilarity;
                            if (comparisonMetric == Model.ComparisonMetric.SymmetricKLDivergence)
                            {
                                dissimilarity = this.MeasureDissimilarityKL(variableDist1, variableDist2);
                            }
                            else if (comparisonMetric == Model.ComparisonMetric.ErrorSum)
                            {
                                dissimilarity = this.MeasureDissimilarityES(variableDist1, variableDist2);
                            }
                            else
                            {
                                Debug.Fail("Unexpected state.");
                                dissimilarity = 0;
                            }
                            similarities.Add(new Tuple<string, double>(variableName, dissimilarity));
                        }

                        // Put most different variables first in the list.
                        comparison.SignificantVariables
                            = similarities
                            .OrderByDescending(s => s.Item2)
                            .TakeFraction(this._comparisonResultsLevel)
                            .ToArray();

                        // Store in model.
                        this._scenariosComparison = comparison;
                        if (this.ComparisonResultsUpdated != null)
                        {
                            this.ComparisonResultsUpdated(comparison);
                        }

                        // Restart layout process.
                        IList<string> significantVariables
                            = comparison
                            .SignificantVariables
                            .Select(x => x.Item1)
                            .OrderBy(x => x)
                            .ToList();
                        if (oldComparison == null ||
                                oldComparison
                                .SignificantVariables
                                .Select(x => x.Item1)
                                .OrderBy(x => x)
                                .SequenceEqual(significantVariables) == false)
                        {
                            _networkLayoutInternal = new NetworkLayoutRecord(
                                _bayesianNetwork,
                                _networkLayout,
                                significantVariables,
                                NetworkLayoutOptions
                            );
                        }

                        // Done.
                        didWork = true;
                    }
                }
                else
                {
                    _scenariosComparison = null;
                }

                if (_scenariosThreadCancel)
                {
                    break;
                }

                if (!didWork)
                {
                    Thread.Sleep(200);
                }
                else
                {
                    // HACK: Gives UI some time to breath if we're updating inference results
                    //       too often.
                    Thread.Sleep(50);
                }
            }
        }