for fac in var_to_factors[var]markov blanket vardist[val*fac get_value(samplesample[varsample_one(vardistif >burn_incounts[sample[qvar]+= tot sum(counts values()as well as the computed distributionwe also include raw counts dist { : /tot for ( ,vin counts items()dist["raw_counts"counts return dist #from probgraphicalmodels import bn_ cha, , , bn_ chg gibbssampling(bn_ ch#inferencemethod max_display_level detailed tracing for all inference methods bn_ chg query( ,{}#bn_ chg query( ,{}#bn_ chg query( ,{ :true}#bn_ chg query( ,{ :true, :false} from probgraphicalmodels import bn_report,alarm,fire,leaving,report,smoke,tamper bn_reportg gibbssampling(bn_report#bn_reportg query(tamper,{report:true},number_samples= if __name__ ="__main__"inferencemethod testim(gibbssamplingthreshold= exercise change the code so that it can have multiple query variables make the list of query variable be an input to the algorithmso that the default value is the list of all non-observed variables exercise in this algorithmexplain where it computes the probability of variable given its markov blanket instead of returning the average of the samples for the query variableit is possible to return the average estimate of the probability of the query variable given its markov blanket does this converge to the same answer as the given codedoes it converge fastersloweror the sameplotting behaviour of stochastic simulators the stochastic simulation runs can give different answers each time they are run for the algorithms that give the same answer in the limit as the number of samples approaches infinity (as do all of these algorithms)the algorithms can be compared by comparing the accuracy for multiple runs summary statistics like the variance may provide some informationbut the assumptions behind the variance being appropriate (namely that the distribution is approximately gaussianmay not hold for cases where the predictions are bounded and often skewed version june