Java tutorial
/* * * * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. * See the NOTICE file distributed with this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use * this file except in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License is * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and limitations under the License. * * */ package eu.amidst.dynamic.inference; import eu.amidst.core.distribution.*; import eu.amidst.core.inference.ImportanceSamplingRobust; import eu.amidst.core.inference.InferenceAlgorithm; import eu.amidst.core.inference.messagepassing.VMP; import eu.amidst.core.models.BayesianNetwork; import eu.amidst.core.models.DAG; import eu.amidst.core.utils.MultinomialIndex; import eu.amidst.core.utils.Serialization; import eu.amidst.core.variables.*; import eu.amidst.dynamic.models.DynamicBayesianNetwork; import eu.amidst.dynamic.models.DynamicDAG; import eu.amidst.dynamic.utils.DynamicBayesianNetworkGenerator; import eu.amidst.dynamic.utils.DynamicToStaticBNConverter; import eu.amidst.dynamic.variables.DynamicAssignment; import eu.amidst.dynamic.variables.DynamicVariables; import org.apache.commons.lang3.StringUtils; import java.io.IOException; import java.util.*; import java.util.stream.Collectors; import java.util.stream.IntStream; /** * This class implements the MAP Inference algorithm for {@link DynamicBayesianNetwork} models. */ public class DynamicMAPInference implements InferenceAlgorithmForDBN { /** * Represents the search algorithm to be used. */ public enum SearchAlgorithm { VMP, IS } /** Represents the {@link DynamicBayesianNetwork} model. */ private DynamicBayesianNetwork model; /** Represents a {@link BayesianNetwork} object. */ private BayesianNetwork unfoldedStaticModel; /** Represents a {@link BayesianNetwork} object. */ private List<BayesianNetwork> mergedClassVarModels; /** Represents the number of time steps. */ private int nTimeSteps = 2; /** Represents the number of consecutive class variables to merge */ private int nMergedClassVars = 2; /** Represents the sample size when using IS. */ private int sampleSize = 1000; /** Represents the MAP {@link Variable}. */ private Variable MAPvariable; /** Represents the name of the MAP {@link Variable}. */ private String MAPvarName; /** Represents a dynamic evidence defined as a list of {@link DynamicAssignment} objects. */ private List<DynamicAssignment> evidence; /** Represents a static evidence defined as an {@link Assignment} object. */ private Assignment staticEvidence; /** Represents the processing mode, either parallel (i.e., true) or not. */ private boolean parallelMode = true; /** Represents the initial seed. */ private int seed = 125123; /** Represents the MAP sequence defined as an {@link Assignment} object. */ private Assignment MAPestimate; /** Represents the MAP sequence defined as an array of integers. */ private int[] MAPsequence; /** Represents the Log Probability of the MAP estimate. */ private double MAPestimateLogProbability; String groupedClassName = "__GROUPED_CLASS__"; private List<int[]> bestSequenceEachModel; List<List<UnivariateDistribution>> allGroupedPosteriorDistributions; List<UnivariateDistribution> allUngroupedPosteriorDistributions; /** * {@inheritDoc} */ @Override public void addDynamicEvidence(DynamicAssignment assignment) { throw new UnsupportedOperationException("Operation not supported in Dynamic MAP Inference"); } /** * {@inheritDoc} */ @Override public void reset() { seed = 125123; parallelMode = true; sampleSize = 1000; nMergedClassVars = 2; nTimeSteps = 2; model = null; unfoldedStaticModel = null; mergedClassVarModels = null; evidence = null; MAPvarName = null; MAPvariable = null; MAPestimate = null; MAPsequence = null; MAPestimateLogProbability = Double.NaN; } /** * {@inheritDoc} */ @Override public <E extends UnivariateDistribution> E getFilteredPosterior(Variable var) { throw new UnsupportedOperationException("Operation not supported in Dynamic MAP Inference"); } /** * {@inheritDoc} */ @Override public <E extends UnivariateDistribution> E getPredictivePosterior(Variable var, int nTimesAhead) { throw new UnsupportedOperationException("Operation not supported in Dynamic MAP Inference"); } /** * {@inheritDoc} */ @Override public long getTimeIDOfLastEvidence() { return (long) this.evidence.stream().mapToDouble(DynamicAssignment::getTimeID).max().getAsDouble(); } /** * {@inheritDoc} */ @Override public long getTimeIDOfPosterior() { throw new UnsupportedOperationException("Operation not supported in Dynamic MAP Inference"); } /** * {@inheritDoc} */ @Override public DynamicBayesianNetwork getOriginalModel() { return this.model; } /** * Sets the evidence for this DynamicMAPInference. * @param evidence a list of {@link DynamicAssignment} objects. */ public void setEvidence(List<DynamicAssignment> evidence) { if (evidence == null) { this.evidence = null; this.staticEvidence = null; return; } long sequenceID = evidence.get(0).getSequenceID(); for (DynamicAssignment dynAssig : evidence) { if (dynAssig.getSequenceID() != sequenceID) { System.out.println("Error: Different sequence IDs in the evidence"); System.exit(-15); } if (dynAssig.getTimeID() >= nTimeSteps || dynAssig.getTimeID() < 0) { System.out.println("Error: Evidence time ID out of the range"); System.exit(-20); } if (!Double.isNaN(dynAssig.getValue(MAPvariable))) { System.out.println("Error: MAP variable should not be in the evidence"); System.exit(-30); } } this.evidence = evidence; if (unfoldedStaticModel != null) { staticEvidence = new HashMapAssignment(unfoldedStaticModel.getNumberOfVars()); evidence.stream().forEach(dynamicAssignment -> { int time = (int) dynamicAssignment.getTimeID(); Set<Variable> dynAssigVariables = dynamicAssignment.getVariables(); for (Variable dynVariable : dynAssigVariables) { Variable staticVariable = unfoldedStaticModel.getVariables() .getVariableByName(dynVariable.getName() + "_t" + Integer.toString(time)); double varValue = dynamicAssignment.getValue(dynVariable); staticEvidence.setValue(staticVariable, varValue); } }); } } // public void setEvidence(DataStream<DynamicDataInstance> evidence1) { // // DynamicDataInstance currentDataInstance = evidence1.stream().findFirst().get(); // long sequenceID = currentDataInstance.getSequenceID(); // // List<DynamicAssignment> evidence2 = new ArrayList<>(1); // for(DynamicDataInstance instance : evidence1) { // if(instance.getSequenceID()!=sequenceID) { // continue; // } // instance.setValue(this.MAPvariable, Utils.missingValue()); // // DynamicAssignment dynamicAssignment = new HashMapDynamicAssignment(this.model.getNumberOfVars()); // this.model.getDynamicVariables().getListOfDynamicVariables().stream().filter(var -> !(var.getName()==this.MAPvarName)).forEach(var -> { // dynamicAssignment.setValue(var,instance.getValue(var)); // }); // evidence2.add(dynamicAssignment); // } // // //evidence2.sort( (l1,l2) -> (l1.getTimeID()<l2.getTimeID() ? 1 : -1) ) ; // //// evidence2.forEach(evid -> { //// System.out.println(evid.outputString(this.model.getDynamicVariables().getListOfDynamicVariables())); ////// System.out.println(evid.getSequenceID()); ////// System.out.println(evid.getTimeID()); //// }); // // // this.evidence = evidence2; // //// if (staticEvenModel!=null) { //// staticEvidence = new HashMapAssignment(staticEvenModel.getNumberOfVars()); //// //// evidence.stream().forEach(dynamicAssignment -> { //// int time = (int) dynamicAssignment.getTimeID(); //// Set<Variable> dynAssigVariables = dynamicAssignment.getVariables(); //// for (Variable dynVariable : dynAssigVariables) { //// Variable staticVariable = staticEvenModel.getVariables().getVariableByName(dynVariable.getName() + "_t" + Integer.toString(time)); //// double varValue = dynamicAssignment.getValue(dynVariable); //// staticEvidence.setValue(staticVariable, varValue); //// } //// //// }); //// } // } public List<List<UnivariateDistribution>> getGroupedPosteriorDistributions() { return allGroupedPosteriorDistributions; } public List<UnivariateDistribution> getUngroupedPosteriorDistributions() { return allUngroupedPosteriorDistributions; } /** * Sets the model for this DynamicMAPInference. * @param model a {@link DynamicBayesianNetwork} object. */ public void setModel(DynamicBayesianNetwork model) { this.model = model; this.unfoldedStaticModel = DynamicToStaticBNConverter.convertDBNtoBN(model, nTimeSteps); } /** * Sets the parallel mode for this DynamicMAPInference. * @param parallelMode true if the parallel mode is activated, false otherwise. */ public void setParallelMode(boolean parallelMode) { this.parallelMode = parallelMode; } /** * Sets the MAP variable for this DynamicMAPInference. * @param MAPvariable a valid {@link Variable} object. */ public void setMAPvariable(Variable MAPvariable) { boolean parents0 = model.getDynamicDAG().getParentSetTime0(MAPvariable).getNumberOfParents() > 0; boolean parentsT = model.getDynamicDAG().getParentSetTimeT(MAPvariable).getParents().stream() .anyMatch(parent -> !parent.isInterfaceVariable()); if (parents0 || parentsT) { System.out.println("Error: The dynamic MAP variable must not have parents"); System.exit(-5); } if (!MAPvariable.isMultinomial()) { System.out.println("Error: The dynamic MAP variable must be multinomial"); System.exit(-10); } this.MAPvariable = MAPvariable; this.MAPvarName = MAPvariable.getName(); } /** * Sets the number of time steps. * @param ntimeSteps an {@code int} that represents the number of time steps. */ public void setNumberOfTimeSteps(int ntimeSteps) { if (ntimeSteps < 2) { System.out.println("Error: The number of time steps should be at least 2"); System.exit(-12); } nTimeSteps = ntimeSteps; this.setModel(this.model); } /** * Sets the number of consecutive copies of the class variable to merge. * Should be less than or equal to the number of time steps. * @param nMergedClassVars an {@code int} that represents the number of class variable copies to merge. */ public void setNumberOfMergedClassVars(int nMergedClassVars) { if (nMergedClassVars > nTimeSteps) { System.out.println( "Error: The number of merged class variables should be less or equal than the number of time steps"); System.exit(-13); } if (nMergedClassVars < 2 || nMergedClassVars > 10) { System.out.println("Error: The number of merged class variables should be between 2 and 10"); System.exit(-14); } this.nMergedClassVars = nMergedClassVars; } /** * Sets the size of the sample when using Importance Sampling for inference. * @param sampleSize an {@code int} that represents the size of the sample. */ public void setSampleSize(int sampleSize) { this.sampleSize = sampleSize; } /** * Sets the seed for repeatability in simulations. * @param seed an {@code int} that represents the seed. */ public void setSeed(int seed) { this.seed = seed; } /** * Returns the MAP sequence found as an {@link Assignment} of variables * @return an {@link Assignment} object with the MAP sequence */ public Assignment getMAPestimate() { return MAPestimate; } /** * Returns the MAP sequence found as array of integers * @return an array of integers representing the MAP sequence */ public int[] getMAPsequence() { return MAPsequence; } public double getMAPestimateLogProbability() { return MAPestimateLogProbability; } public double getMAPestimateProbability() { return Math.exp(MAPestimateLogProbability); } /** * Returns the list of models with merged class variable. * @return a List of {@link BayesianNetwork} objects. */ public List<BayesianNetwork> getMergedClassVarModels() { return mergedClassVarModels; } /** * Returns a single {@link BayesianNetwork} object, corresponding to the unfolded dynamic network * over the specified number of time steps. * @return a {@link BayesianNetwork} object. */ public BayesianNetwork getUnfoldedStaticModel() { return unfoldedStaticModel; } public Assignment getUnfoldedEvidence() { return staticEvidence; } /** * Returns replicated MAP variables. * @return a {@code List} of {@link Variable}. */ public List<Variable> getReplicatedMAPVariables() { if (MAPestimate == null) { return null; } return getMAPestimate().getVariables().stream() .sorted((var1, var2) -> (var1.getVarID() > var2.getVarID() ? 1 : -1)).collect(Collectors.toList()); } public List<int[]> getBestSequencesForEachSubmodel() { return bestSequenceEachModel; } /** * Computes Dynamic MAP for the even static model. */ public void computeMergedClassVarModels() { DynamicDAG dynamicDAG = model.getDynamicDAG(); DynamicVariables dynamicVariables = model.getDynamicVariables(); mergedClassVarModels = new ArrayList<>(nMergedClassVars); IntStream.range(0, nMergedClassVars).forEachOrdered(modelNumber -> { // System.out.println("Model number " + modelNumber); Variables variables = obtainReplicatedStaticVariables(dynamicVariables, modelNumber); DAG dag = obtainStaticDAG(dynamicDAG, variables, modelNumber); // System.out.println(dag.toString()); BayesianNetwork bn = obtainStaticMergedClassVarNetwork(dag, variables, modelNumber); // System.out.println(bn.toString()); // int replicationsMAPVariable = (modelNumber==0 ? 0 : 1) + (nTimeSteps-modelNumber)/nMergedClassVars + ((nTimeSteps-modelNumber)%nMergedClassVars==0 ? 0 : 1); // IntStream.range(0,replicationsMAPVariable).forEach(i-> { // System.out.println("Variable " + groupedClassName + "_t" + i); // System.out.println(bn.getConditionalDistribution(bn.getVariables().getVariableByName(groupedClassName + "_t" + i)).toString()); // System.out.println(); // }); // System.out.println(bn.getConditionalDistribution(bn.getVariables().getVariableByName(groupedClassName + "_t1")).toString()); // System.out.println(); // System.out.println(bn.getConditionalDistribution(bn.getVariables().getVariableByName(groupedClassName + "_t2")).toString()); // System.out.println(); // System.out.println(bn.getConditionalDistribution(bn.getVariables().getVariableByName(groupedClassName + "_t3")).toString()); // System.out.println(); mergedClassVarModels.add(bn); // System.out.println("MODEL " + modelNumber); // System.out.println(bn); }); } /** * Runs the inference algorithm. */ public void runInference() { if (MAPvariable == null || MAPvarName == null) { System.out.println("Error: The MAP variable has not been set"); System.exit(-30); } if (this.mergedClassVarModels == null) { this.computeMergedClassVarModels(); } // if (this.staticEvenModel == null) { // this.computeDynamicMAPEvenModel(); // } // // if (evidence!=null && staticEvidence==null) { // // staticEvidence = new HashMapAssignment(staticEvenModel.getNumberOfVars()); // // evidence.stream().forEach(dynamicAssignment -> { // int time = (int) dynamicAssignment.getTimeID(); // Set<Variable> dynAssigVariables = dynamicAssignment.getVariables(); // for (Variable dynVariable : dynAssigVariables) { // Variable staticVariable = staticEvenModel.getVariables().getVariableByName(dynVariable.getName() + "_t" + Integer.toString(time)); // double varValue = dynamicAssignment.getValue(dynVariable); // staticEvidence.setValue(staticVariable, varValue); // } // // }); // } this.runInference(SearchAlgorithm.VMP); } /** * Runs the inference given an input search algorithm. * @param searchAlgorithm a valid {@link SearchAlgorithm} value. */ public void runInference(SearchAlgorithm searchAlgorithm) { if (MAPvariable == null || MAPvarName == null) { System.out.println("Error: The MAP variable has not been set"); System.exit(-30); } if (this.mergedClassVarModels == null) { this.computeMergedClassVarModels(); } if (this.unfoldedStaticModel == null) { unfoldedStaticModel = DynamicToStaticBNConverter.convertDBNtoBN(model, nTimeSteps); } // // if (evidence!=null && staticEvidence==null) { // // staticEvidence = new HashMapAssignment(staticEvenModel.getNumberOfVars()); // // evidence.stream().forEach(dynamicAssignment -> { // int time = (int) dynamicAssignment.getTimeID(); // Set<Variable> dynAssigVariables = dynamicAssignment.getVariables(); // for (Variable dynVariable : dynAssigVariables) { // Variable staticVariable = staticEvenModel.getVariables().getVariableByName(dynVariable.getName() + "_t" + Integer.toString(time)); // double varValue = dynamicAssignment.getValue(dynVariable); // staticEvidence.setValue(staticVariable, varValue); // } // // }); // } // if (evidence != null && staticEvidence == null) { staticEvidence = new HashMapAssignment(unfoldedStaticModel.getNumberOfVars()); evidence.stream().forEach(dynamicAssignment -> { int time = (int) dynamicAssignment.getTimeID(); Set<Variable> dynAssigVariables = dynamicAssignment.getVariables(); for (Variable dynVariable : dynAssigVariables) { Variable staticVariable = unfoldedStaticModel.getVariables() .getVariableByName(dynVariable.getName() + "_t" + Integer.toString(time)); double varValue = dynamicAssignment.getValue(dynVariable); staticEvidence.setValue(staticVariable, varValue); } }); } List<InferenceAlgorithm> staticModelsInference = new ArrayList<>(nMergedClassVars); IntStream.range(0, nMergedClassVars).forEachOrdered(i -> { InferenceAlgorithm currentModelInference; switch (searchAlgorithm) { case VMP: currentModelInference = new VMP(); //((VMP)currentModelInference).setTestELBO(true); ((VMP) currentModelInference).setThreshold(0.0001); ((VMP) currentModelInference).setMaxIter(3000); break; case IS: default: currentModelInference = new ImportanceSamplingRobust(); Random random = new Random((this.seed)); currentModelInference.setSeed(random.nextInt()); this.seed = random.nextInt(); ((ImportanceSamplingRobust) currentModelInference).setSampleSize(sampleSize); break; } currentModelInference.setParallelMode(this.parallelMode); currentModelInference.setModel(mergedClassVarModels.get(i)); if (searchAlgorithm == SearchAlgorithm.IS) { ((ImportanceSamplingRobust) currentModelInference) .setVariablesAPosteriori(mergedClassVarModels.get(i).getVariables().getListOfVariables() .stream().filter(variable -> variable.getName().contains(groupedClassName)) .collect(Collectors.toList())); } BayesianNetwork thisModel = mergedClassVarModels.get(i); if (staticEvidence != null) { Assignment thisEvidence = new HashMapAssignment(); for (Variable varEvidence : staticEvidence.getVariables()) { thisEvidence.setValue(thisModel.getVariables().getVariableByName(varEvidence.getName()), staticEvidence.getValue(varEvidence)); } currentModelInference.setEvidence(thisEvidence); } currentModelInference.runInference(); //System.out.println(currentModelInference.getLogProbabilityOfEvidence()); staticModelsInference.add(currentModelInference); }); // // IntStream.range(0, 2).parallel().forEach(i -> { // if (i == 0) { // evenModelInference.setParallelMode(this.parallelMode); // evenModelInference.setModel(staticEvenModel); // if (evidence != null) { // evenModelInference.setEvidence(staticEvidence); // } // evenModelInference.runInference(); // } // else { // oddModelInference.setParallelMode(this.parallelMode); // oddModelInference.setModel(staticOddModel); // if (evidence != null) { // oddModelInference.setEvidence(staticEvidence); // } // oddModelInference.runInference(); // } // }); List<List<UnivariateDistribution>> posteriorMAPDistributions = new ArrayList<>(); IntStream.range(0, nMergedClassVars).forEachOrdered(modelNumber -> { List<UnivariateDistribution> currentModelPosteriorMAPDistributions = new ArrayList<>(); int nReplicationsMAPVariable = (modelNumber == 0 ? 0 : 1) + (nTimeSteps - modelNumber) / nMergedClassVars + ((nTimeSteps - modelNumber) % nMergedClassVars == 0 ? 0 : 1); IntStream.range(0, nReplicationsMAPVariable).forEachOrdered(i -> { currentModelPosteriorMAPDistributions.add(staticModelsInference.get(modelNumber).getPosterior(i)); //System.out.println(staticModelsInference.get(modelNumber).getPosterior(i).toString()); }); posteriorMAPDistributions.add(currentModelPosteriorMAPDistributions); }); // int replicationsMAPVariableEvenModel = nTimeSteps/2 + nTimeSteps%2; // IntStream.range(0,replicationsMAPVariableEvenModel).forEachOrdered(i -> posteriorMAPDistributionsEvenModel.add(evenModelInference.getPosterior(i))); // // int replicationsMAPVariableOddModel = 1 + (nTimeSteps-1)/2 + (nTimeSteps-1)%2; // IntStream.range(0,replicationsMAPVariableOddModel).forEachOrdered(i -> posteriorMAPDistributionsOddModel.add(oddModelInference.getPosterior(i))); posteriorMAPDistributions.forEach(list -> { StringBuilder stringBuilder = new StringBuilder(); list.forEach(uniDist -> { stringBuilder.append(Arrays.toString(uniDist.getParameters())); stringBuilder.append(" , "); }); //System.out.println("Model number " + posteriorMAPDistributions.indexOf(list) + ": " + stringBuilder.toString()); }); allGroupedPosteriorDistributions = posteriorMAPDistributions; bestSequenceEachModel = new ArrayList<>(); IntStream.range(0, nMergedClassVars).forEachOrdered(modelNumber -> { int[] thisModelBestSequence = new int[nTimeSteps]; int indexSequence = 0; List<UnivariateDistribution> thisModelPosteriors = posteriorMAPDistributions.get(modelNumber); for (int k = 0; k < thisModelPosteriors.size(); k++) { UnivariateDistribution thisDistribution = thisModelPosteriors.get(k); int indexMaxProbability = (int) argMax(thisDistribution.getParameters())[1]; int thisDistribNumberOfMergedVars = (int) Math .round(Math.log(thisDistribution.getVariable().getNumberOfStates()) / Math.log(MAPvariable.getNumberOfStates())); String m_base_nStates = Integer.toString( Integer.parseInt(Integer.toString(indexMaxProbability), 10), MAPvariable.getNumberOfStates()); m_base_nStates = StringUtils.leftPad(m_base_nStates, thisDistribNumberOfMergedVars, '0'); for (int j = 0; j < m_base_nStates.length(); j++) { thisModelBestSequence[indexSequence] = Integer.parseInt(m_base_nStates.substring(j, j + 1)); indexSequence++; } } //System.out.println("Best sequence model " + modelNumber + ": " + Arrays.toString(thisModelBestSequence)); bestSequenceEachModel.add(thisModelBestSequence); }); List<double[]> conditionalDistributionsMAPvariable = obtainMAPVariableConditionalDistributions( posteriorMAPDistributions); //System.out.println("Cond Distributions: " + Arrays.toString(conditionalDistributionsMAPvariable)); StringBuilder stringBuilder = new StringBuilder(); conditionalDistributionsMAPvariable.forEach(conDistr -> { stringBuilder.append(Arrays.toString(conDistr)); stringBuilder.append(" , "); }); //System.out.println("Combined Conditional Distributions: \n" + stringBuilder.toString()); computeMostProbableSequence(conditionalDistributionsMAPvariable); } /** * Runs the inference for Ungrouped MAP variable given an input search algorithm. * @param searchAlgorithm a valid {@link SearchAlgorithm} value. */ public void runInferenceUngroupedMAPVariable(SearchAlgorithm searchAlgorithm) { if (MAPvariable == null || MAPvarName == null) { System.out.println("Error: The MAP variable has not been set"); System.exit(-30); } if (this.unfoldedStaticModel == null) { unfoldedStaticModel = DynamicToStaticBNConverter.convertDBNtoBN(model, nTimeSteps); } if (evidence != null && staticEvidence == null) { staticEvidence = new HashMapAssignment(unfoldedStaticModel.getNumberOfVars()); evidence.stream().forEach(dynamicAssignment -> { int time = (int) dynamicAssignment.getTimeID(); Set<Variable> dynAssigVariables = dynamicAssignment.getVariables(); for (Variable dynVariable : dynAssigVariables) { Variable staticVariable = unfoldedStaticModel.getVariables() .getVariableByName(dynVariable.getName() + "_t" + Integer.toString(time)); double varValue = dynamicAssignment.getValue(dynVariable); staticEvidence.setValue(staticVariable, varValue); } }); } InferenceAlgorithm staticModelInference; switch (searchAlgorithm) { case VMP: staticModelInference = new VMP(); //((VMP)staticModelInference).setTestELBO(true); ((VMP) staticModelInference).setThreshold(0.0001); ((VMP) staticModelInference).setMaxIter(3000); break; case IS: default: ImportanceSamplingRobust importanceSampling = new ImportanceSamplingRobust(); importanceSampling.setSampleSize(this.sampleSize); Random random = new Random((this.seed)); importanceSampling.setSeed(random.nextInt()); staticModelInference = importanceSampling; break; } staticModelInference.setParallelMode(this.parallelMode); staticModelInference.setModel(unfoldedStaticModel); if (searchAlgorithm == SearchAlgorithm.IS) { ((ImportanceSamplingRobust) staticModelInference).setVariablesAPosteriori(unfoldedStaticModel .getVariables().getListOfVariables().stream() .filter(variable -> variable.getName().contains(MAPvarName)).collect(Collectors.toList())); } if (evidence != null) { staticModelInference.setEvidence(staticEvidence); } staticModelInference.runInference(); List<UnivariateDistribution> posteriorMAPDistributionsStaticModel = new ArrayList<>(); IntStream.range(0, nTimeSteps).forEachOrdered(i -> { posteriorMAPDistributionsStaticModel.add(staticModelInference.getPosterior(i)); //System.out.println("Ungrouped Posterior " + i + staticModelInference.getPosterior(i).toString()); }); allUngroupedPosteriorDistributions = posteriorMAPDistributionsStaticModel; double[] probabilities = posteriorMAPDistributionsStaticModel.stream() .map(dist -> argMax(dist.getParameters())).mapToDouble(array -> array[0]).toArray(); double MAPsequenceProbability = Math.exp(Arrays.stream(probabilities).map(prob -> Math.log(prob)).sum()); int[] MAPsequence = posteriorMAPDistributionsStaticModel.stream().map(dist -> argMax(dist.getParameters())) .mapToInt(array -> (int) array[1]).toArray(); MAPestimate = new HashMapAssignment(nTimeSteps); IntStream.range(0, nTimeSteps).forEach(t -> { Variables variables = Serialization.deepCopy(this.unfoldedStaticModel.getVariables()); Variable currentVar; if (variables.getVariableByName(MAPvarName + "_t" + Integer.toString(t)) != null) { currentVar = variables.getVariableByName(MAPvarName + "_t" + Integer.toString(t)); } else { currentVar = variables.newMultinomialVariable(MAPvarName + "_t" + Integer.toString(t), MAPvariable.getNumberOfStates()); } MAPestimate.setValue(currentVar, MAPsequence[t]); }); MAPestimateLogProbability = Math.log(MAPsequenceProbability); this.MAPsequence = MAPsequence; } private List<double[]> obtainMAPVariableConditionalDistributions( List<List<UnivariateDistribution>> posteriorMAPVariableDistributions) { List<double[]> listCondDistributions = new ArrayList<>(nTimeSteps); int nStates = MAPvariable.getNumberOfStates(); // Univariate distribution Y_0 // UnivariateDistribution dist0_1 = posteriorMAPDistributionsEvenModel.get(0); // This variable Z_0 groups Y_0 and Y_1 // UnivariateDistribution dist0 = posteriorMAPDistributionsOddModel.get(0); // This variable is just Y_0 (not a group) // double[] dist0_probs = new double[nStates]; // System.out.println("\n\n\n\n\n\n\n\n\n\n\n\n\n"); IntStream.range(0, nTimeSteps).forEachOrdered(timeStep -> { // System.out.println("\n\nTime step " + timeStep); double[] combinedConditionalDistributionProbabilities, baseDistributionProbabilities; int baseModelIndex = (timeStep + 1) % nMergedClassVars; int baseDistributionIndex = (timeStep >= baseModelIndex) ? (baseModelIndex == 0 ? 0 : 1) + (timeStep - baseModelIndex) / nMergedClassVars : (timeStep - baseModelIndex) / nMergedClassVars; baseDistributionProbabilities = posteriorMAPVariableDistributions.get(baseModelIndex) .get(baseDistributionIndex).getParameters(); int nStatesBaseDistribution = baseDistributionProbabilities.length; int baseDistrib_nMergedVars = (int) Math.round(Math.log(nStatesBaseDistribution) / Math.log(nStates)); combinedConditionalDistributionProbabilities = IntStream.range(0, nMergedClassVars).mapToObj(modelNumber -> { if (modelNumber == baseModelIndex) { // System.out.println("\nModel number " + modelNumber); //System.out.println(Arrays.toString(baseDistributionProbabilities)); return baseDistributionProbabilities; } // System.out.println("\nModel number " + modelNumber); int distributionIndex = (timeStep >= modelNumber) ? (modelNumber == 0 ? 0 : 1) + (timeStep - modelNumber) / nMergedClassVars : (timeStep - modelNumber) / nMergedClassVars; int currentVarIndex = (timeStep >= modelNumber) ? (timeStep - modelNumber) % nMergedClassVars : timeStep; // System.out.println("CurrentVarIndex " + currentVarIndex); UnivariateDistribution currentDistrib = posteriorMAPVariableDistributions.get(modelNumber) .get(distributionIndex); //System.out.println(currentDistrib.toString()); double[] probabilities = new double[nStatesBaseDistribution]; int currentDistrib_nMergedVars = (int) Math.round( Math.log(currentDistrib.getVariable().getNumberOfStates()) / Math.log(nStates)); int current_nMergedVarsBaseDist = (int) Math .round(Math.log(baseDistributionProbabilities.length) / Math.log(nStates)); if (distributionIndex == 0) { // System.out.println("Current nMergedVars " + currentDistrib_nMergedVars + ", current nMergedVarsBaseDist " + current_nMergedVarsBaseDist); for (int m = 0; m < Math.pow(nStates, currentDistrib_nMergedVars); m++) { String m_base_nStates = Integer.toString(Integer.parseInt(Integer.toString(m), 10), nStates); m_base_nStates = StringUtils.leftPad(m_base_nStates, currentDistrib_nMergedVars, '0'); // int index_init = currentVarIndex - ((timeStep >= nMergedClassVars) ? nMergedClassVars : timeStep); int index_init = currentVarIndex + 1 - baseDistrib_nMergedVars; int index_end = currentVarIndex + 1; // String statesSequence = m_base_nStates.substring(currentVarIndex, currentVarIndex + current_nMergedVarsBaseDist); String statesSequence = m_base_nStates.substring(index_init, index_end); int currentState = Integer.parseInt(statesSequence, nStates); // System.out.println("Current state " + currentState); probabilities[currentState] += currentDistrib.getParameters()[m]; } } else { UnivariateDistribution previousDistrib = posteriorMAPVariableDistributions .get(modelNumber).get(distributionIndex - 1); int previousDistrib_nMergedVars = (int) Math .round(Math.log(previousDistrib.getVariable().getNumberOfStates()) / Math.log(nStates)); // System.out.println("Current nMergedVars " + currentDistrib_nMergedVars + ", previous nMergedVars " + previousDistrib_nMergedVars + ", current nMergedVarsBaseDist " + current_nMergedVarsBaseDist); for (int n = 0; n < Math.pow(nStates, previousDistrib_nMergedVars); n++) { String n_base_nStates = Integer.toString(Integer.parseInt(Integer.toString(n), 10), nStates); n_base_nStates = StringUtils.leftPad(n_base_nStates, previousDistrib_nMergedVars, '0'); for (int m = 0; m < Math.pow(nStates, currentDistrib_nMergedVars); m++) { String m_base_nStates = Integer .toString(Integer.parseInt(Integer.toString(m), 10), nStates); m_base_nStates = StringUtils.leftPad(m_base_nStates, currentDistrib_nMergedVars, '0'); // String statesSequence = m_base_nStates.substring(currentVarIndex, currentVarIndex + current_nMergedVarsBaseDist); // int currentState = Integer.parseInt(statesSequence, nStates); String n_concat_m_base_nStates = n_base_nStates.concat(m_base_nStates); int index_init = previousDistrib_nMergedVars + currentVarIndex + 1 - baseDistrib_nMergedVars; int index_end = previousDistrib_nMergedVars + currentVarIndex + 1; String statesSequence = n_concat_m_base_nStates.substring(index_init, index_end); // System.out.println("Complete sequence: " + n_concat_m_base_nStates + ", statesSequence:" + statesSequence); // int subIndices_m = currentVarIndex; // int subIndices_n = 1 + ((timeStep >= nMergedClassVars) ? (previousDistrib_nMergedVars - nMergedClassVars + currentVarIndex) : (previousDistrib_nMergedVars - (nMergedClassVars-timeStep) + currentVarIndex)); // // System.out.println("n_base_nStates: " + n_base_nStates + "m_base_nStates: " + m_base_nStates ); // // System.out.println("subIndices_m: " + Integer.toString(subIndices_m)); // System.out.println("subIndices_n: " + Integer.toString(subIndices_n)); // // String statesSequence_m = m_base_nStates.substring(0, subIndices_m); // String statesSequence_n = n_base_nStates.substring(subIndices_n, previousDistrib_nMergedVars); // // // System.out.println("statesSequence n: " + statesSequence_n + ", statesSequence m: " + statesSequence_m ); // // String statesSequence = statesSequence_n.concat(statesSequence_m); // System.out.println("States sequence length: " + statesSequence.length() + ", sequence: " + statesSequence); int currentState = Integer.parseInt(statesSequence, nStates); // System.out.println("Current state " + currentState); probabilities[currentState] += previousDistrib.getParameters()[n] * currentDistrib.getParameters()[m]; } } } // System.out.println("Model distribution: " + Arrays.toString(probabilities)); return probabilities; }).reduce(new double[baseDistributionProbabilities.length], (doubleArray1, doubleArray2) -> { if (doubleArray1.length != doubleArray2.length) { // System.out.println("Problem with lengths"); System.exit(-40); } for (int i = 0; i < doubleArray1.length; i++) doubleArray1[i] += ((double) 1 / nMergedClassVars) * doubleArray2[i]; return doubleArray1; }); //System.out.println("Combined distribution " + Arrays.toString(combinedConditionalDistributionProbabilities)); listCondDistributions.add(combinedConditionalDistributionProbabilities); }); // System.out.println("\n\n\n\n\n\n\n\n\n\n\n\n\n"); return listCondDistributions; } /** * Computes the Most Probable Sequence given the posterior distributions of the MAP variable. * @param posteriorDistributionsMAPvariable a {@code List} of conditional distribution values. */ private void computeMostProbableSequence(List<double[]> posteriorDistributionsMAPvariable) { int[] MAPsequence = new int[nTimeSteps]; int nStates = MAPvariable.getNumberOfStates(); int[] argMaxValues = new int[nTimeSteps - 1]; double MAPsequenceProbability = -1; double[] current_probs; double[] current_max_probs = new double[(int) Math.pow(nStates, nMergedClassVars - 1)]; double[] previous_max_probs = new double[(int) Math.pow(nStates, nMergedClassVars - 1)]; for (int t = nTimeSteps - 1; t >= 1; t--) { // System.out.println("Time:" + t); double[] currentDistProbabilities = posteriorDistributionsMAPvariable.get(t); if (Arrays.stream(currentDistProbabilities).anyMatch(Double::isNaN)) { MAPsequence = new int[nTimeSteps]; for (int i = 0; i < MAPsequence.length; i++) { MAPsequence[i] = -1; return; } } int currentDistrib_nMergedVars = (int) Math .round(Math.log(currentDistProbabilities.length) / Math.log(nStates)); // System.out.println("Current Probabilities:" + Arrays.toString(currentDistProbabilities)); current_max_probs = new double[(int) Math.pow(nStates, currentDistrib_nMergedVars - 1)]; if (t == nTimeSteps - 1) { previous_max_probs = Arrays.stream(previous_max_probs).map(d -> 1).toArray(); } // System.out.println("Current Max Probs Length: " + current_max_probs.length); // System.out.println("Previous Max Probs: " + Arrays.toString(previous_max_probs)); for (int m = 0; m < Math.pow(nStates, currentDistrib_nMergedVars); m++) { // System.out.println("State: " + m ); String m_base_nStates = Integer.toString(Integer.parseInt(Integer.toString(m), 10), nStates); m_base_nStates = StringUtils.leftPad(m_base_nStates, currentDistrib_nMergedVars, '0'); int currentStateFirstVars; int currentStateLastVars; if (t > 0) { String stateFirstVars = m_base_nStates.substring(0, currentDistrib_nMergedVars - 1); currentStateFirstVars = Integer.parseInt(stateFirstVars, nStates); String stateLastVars = m_base_nStates.substring(1, currentDistrib_nMergedVars); currentStateLastVars = Integer.parseInt(stateLastVars, nStates); } else { currentStateFirstVars = 0; currentStateLastVars = Integer.parseInt(m_base_nStates, nStates); } // System.out.println("FirstVars:" + currentStateFirstVars + ", LastVars:" + currentStateLastVars); double currentProb = currentDistProbabilities[m] * previous_max_probs[currentStateLastVars]; double maxProb = current_max_probs[currentStateFirstVars]; if (currentProb > maxProb) { current_max_probs[currentStateFirstVars] = currentProb; } } // System.out.println("Current Max Probabilities:" + Arrays.toString(current_max_probs)); argMaxValues[t - 1] = (int) argMax(current_max_probs)[1]; previous_max_probs = current_max_probs; if (t == 1) { MAPsequenceProbability = argMax(current_max_probs)[0]; } // System.out.println("MAP Sequence Prob:" + MAPsequenceProbability); // System.out.println("Arg Max Value: " + argMaxValues[t-1]+ "\n\n\n"); } // for (int t = nTimeSteps-1; t >= 0; t--) { // // current_probs = posteriorDistributionsMAPvariable.get(t); // double maxProb=-1; // // current_max_probs = new double[MAPvarNStates]; // // if (t==(nTimeSteps-1)) { // There are no previous_max_probs // for (int j = 0; j < MAPvarNStates; j++) { // To go over all values of Y_{t-1} // maxProb=-1; // for (int k = 0; k < MAPvarNStates; k++) { // To go over all values of Y_t // if (current_probs[j * MAPvarNStates + k] > maxProb) { // maxProb = current_probs[j * MAPvarNStates + k]; // // } // } // current_max_probs[j]=maxProb; // } // argMaxValues[t] = (int)argMax(current_max_probs)[1]; // previous_max_probs = current_max_probs; // } // else if (t>0 && t<(nTimeSteps-1)) { // for (int j = 0; j < MAPvarNStates; j++) { // To go over all values of Y_{t-1} // maxProb=-1; // for (int k = 0; k < MAPvarNStates; k++) { // To go over all values of Y_t // if (current_probs[j * MAPvarNStates + k]*previous_max_probs[j] > maxProb) { // maxProb = current_probs[j * MAPvarNStates + k]*previous_max_probs[k]; // } // } // current_max_probs[j]=maxProb; // } // argMaxValues[t] = (int)argMax(current_max_probs)[1]; // previous_max_probs = current_max_probs; // } // else { // Here, t=0 // for (int j = 0; j < MAPvarNStates; j++) { // To go over all values of Y_0 // maxProb=-1; // for (int k = 0; k < MAPvarNStates; k++) { // To go over all values of Y_1 // if (current_probs[j]*previous_max_probs[j] > maxProb) { // maxProb = current_probs[j]*previous_max_probs[j]; // } // } // current_max_probs[j]=maxProb; // } // MAPsequenceProbability = argMax(current_max_probs)[0]; // argMaxValues[t] = (int)argMax(current_max_probs)[1]; // previous_max_probs = current_max_probs; // } // } //System.out.println(Arrays.toString(argMaxValues)); // System.out.println("\n\n TRACEBACK \n\n"); //int previousVarMAPState = argMaxValues[0]; MAPsequence[0] = argMaxValues[0]; int thisVarMAPState = 0; for (int t = 1; t < nTimeSteps; t++) { // System.out.println("Time Step: " + t); current_probs = posteriorDistributionsMAPvariable.get(t); StringBuilder prevVarsStateBuilder = new StringBuilder(); int j_max = Math.min(nMergedClassVars - 1, t); for (int j = 0; j < Math.min(nMergedClassVars - 1, t); j++) { // System.out.println("Append: " + Integer.toString(MAPsequence[t-j_max+j]) ); prevVarsStateBuilder.append(Integer.toString(MAPsequence[t - j_max + j])); } //previousVarMAPState = argMaxValues[t-1]; // System.out.println("PrevVarsState: " + prevVarsStateBuilder.toString()); // String prevVarsState = Integer.toString(Integer.parseInt(prevVarsStateBuilder.toString()), nStates); String prevVarsState = prevVarsStateBuilder.toString(); // System.out.println("Prev Vars State:" + prevVarsState); // String m_base_nStates = Integer.toString(Integer.parseInt(Integer.toString(previousVarMAPState), 10), nStates); // m_base_nStates = StringUtils.leftPad(m_base_nStates, currentDistrib_nMergedVars, '0'); // // String stateConditioningVars = m_base_nStates.substring(0, currentDistrib_nMergedVars-1); // int currentStateConditioningVars = Integer.parseInt(stateConditioningVars, nStates); // // String stateLastVar = m_base_nStates.substring(currentDistrib_nMergedVars-1, currentDistrib_nMergedVars); // int currentStateLastVar = Integer.parseInt(stateLastVar, nStates); // // double currentProb=currentDistProbabilities[m] * previous_max_probs[currentStateLastVar]; // double maxProb=current_max_probs[currentStateConditioningVars]; // // if (currentProb>maxProb) { // current_max_probs[currentStateConditioningVars] = currentProb ; // } double maxProb = -1; for (int j = 0; j < nStates; j++) { // To go over all values of Y_t int currentState = Integer.parseInt(prevVarsState.concat(Integer.toString(j)), nStates); // System.out.println("Current state:" + currentState); if (current_probs[currentState] > maxProb) { maxProb = current_probs[currentState]; thisVarMAPState = j; } } MAPsequence[t] = thisVarMAPState; // System.out.println("Currente Sequence Value: " + MAPsequence[t] + "\n\n"); } // int previousVarMAPState = argMaxValues[0]; // MAPsequence[0] = argMaxValues[0]; // // int thisVarMAPState = 0; // for (int t = 1; t < nTimeSteps; t++) { // current_probs = posteriorDistributionsMAPvariable.get(t); // previousVarMAPState = argMaxValues[t-1]; // // double maxProb = -1; // for (int j = 0; j < nStates; j++) { // To go over all values of Y_t // // if (current_probs[previousVarMAPState * nStates + j] >= maxProb) { // maxProb = current_probs[previousVarMAPState * nStates + j]; // thisVarMAPState = j; // } // } // MAPsequence[t]=thisVarMAPState; // } if (Arrays.stream(MAPsequence).anyMatch(value -> value < 0)) { MAPestimateLogProbability = Double.NaN; } else { MAPestimateLogProbability = Math.log(MAPsequenceProbability); } this.MAPsequence = MAPsequence; // System.out.println("FINAL SEQUENCE: " + Arrays.toString(MAPsequence)); } // /** // * Computes the Most Probable Sequence given the posterior distributions of the MAP variable. // * @param posteriorDistributionsMAPvariable a {@code List} of conditional distribution values. // */ // private void computeMostProbableSequence(List<double[]> posteriorDistributionsMAPvariable) { // // int[] MAPsequence = new int[nTimeSteps]; // int MAPvarNStates = MAPvariable.getNumberOfStates(); // // int[] argMaxValues = new int[nTimeSteps]; // // double MAPsequenceProbability=-1; // double [] current_probs; // double [] current_max_probs; // double [] previous_max_probs = new double[MAPvarNStates];; // // for (int t = nTimeSteps-1; t >= 0; t--) { // // current_probs = posteriorDistributionsMAPvariable.get(t); // double maxProb=-1; // // current_max_probs = new double[MAPvarNStates]; // // if (t==(nTimeSteps-1)) { // There are no previous_max_probs // for (int j = 0; j < MAPvarNStates; j++) { // To go over all values of Y_{t-1} // maxProb=-1; // for (int k = 0; k < MAPvarNStates; k++) { // To go over all values of Y_t // if (current_probs[j * MAPvarNStates + k] > maxProb) { // maxProb = current_probs[j * MAPvarNStates + k]; // // } // } // current_max_probs[j]=maxProb; // } // argMaxValues[t] = (int)argMax(current_max_probs)[1]; // previous_max_probs = current_max_probs; // } // else if (t>0 && t<(nTimeSteps-1)) { // for (int j = 0; j < MAPvarNStates; j++) { // To go over all values of Y_{t-1} // maxProb=-1; // for (int k = 0; k < MAPvarNStates; k++) { // To go over all values of Y_t // if (current_probs[j * MAPvarNStates + k]*previous_max_probs[j] > maxProb) { // maxProb = current_probs[j * MAPvarNStates + k]*previous_max_probs[k]; // } // } // current_max_probs[j]=maxProb; // } // argMaxValues[t] = (int)argMax(current_max_probs)[1]; // previous_max_probs = current_max_probs; // } // else { // Here, t=0 // for (int j = 0; j < MAPvarNStates; j++) { // To go over all values of Y_0 // maxProb=-1; // for (int k = 0; k < MAPvarNStates; k++) { // To go over all values of Y_1 // if (current_probs[j]*previous_max_probs[j] > maxProb) { // maxProb = current_probs[j]*previous_max_probs[j]; // } // } // current_max_probs[j]=maxProb; // } // MAPsequenceProbability = argMax(current_max_probs)[0]; // argMaxValues[t] = (int)argMax(current_max_probs)[1]; // previous_max_probs = current_max_probs; // } // } // // int previousVarMAPState = argMaxValues[0]; // MAPsequence[0] = argMaxValues[0]; // // int thisVarMAPState = 0; // for (int t = 1; t < nTimeSteps; t++) { // current_probs = posteriorDistributionsMAPvariable.get(t); // previousVarMAPState = argMaxValues[t-1]; // // double maxProb = -1; // for (int j = 0; j < MAPvarNStates; j++) { // To go over all values of Y_t // // if (current_probs[previousVarMAPState * MAPvarNStates + j] >= maxProb) { // maxProb = current_probs[previousVarMAPState * MAPvarNStates + j]; // thisVarMAPState = j; // } // } // MAPsequence[t]=thisVarMAPState; // } // // MAPestimate = new HashMapAssignment(nTimeSteps); // // if (Arrays.stream(MAPsequence).anyMatch(value -> value<0)) { // MAPestimateLogProbability=Double.NaN; // } // else { // IntStream.range(0, nTimeSteps).forEach(t -> { //// Variables varsAux = Serialization.deepCopy(this.staticEvenModel.getVariables()); //// Variable currentVar = varsAux.newMultinomialVariable(MAPvarName + "_t" + Integer.toString(t), MAPvariable.getNumberOfStates()); // Variable currentVar; // try { // currentVar = this.staticEvenModel.getVariables().getVariableByName(MAPvarName + "_t" + Integer.toString(t)); // } // catch (Exception e) { // Variables copy = Serialization.deepCopy(this.staticEvenModel.getVariables()); // currentVar = copy.newMultinomialVariable(MAPvarName + "_t" + Integer.toString(t), MAPvariable.getNumberOfStates()); // } // MAPestimate.setValue(currentVar, MAPsequence[t]); // }); // MAPestimateLogProbability = Math.log(MAPsequenceProbability); // } // // this.MAPsequence = MAPsequence; // } // /** // * Returns Combined Conditional Distributions for both even and odd models. // * @param posteriorMAPVariableDistributions a {@code List} of {@code List} of {@link UnivariateDistribution} for each model. // * @return a {@code List} of conditional distributions values. // */ // private List<double[]> combinePosteriorConditionalDistributions(List<List<UnivariateDistribution>> posteriorMAPVariableDistributions) { // // List<double[]> listCondDistributions = new ArrayList<>(nTimeSteps); // // int nStates = MAPvariable.getNumberOfStates(); // // // Univariate distribution Y_0 // // UnivariateDistribution dist0_1 = posteriorMAPDistributionsEvenModel.get(0); // This variable Z_0 groups Y_0 and Y_1 // // UnivariateDistribution dist0 = posteriorMAPDistributionsOddModel.get(0); // This variable is just Y_0 (not a group) //// double[] dist0_probs = new double[nStates]; // // IntStream.range(0, nTimeSteps).forEachOrdered(timeStep -> { // //// System.out.println("\n\nTime step " + timeStep); // double [] combinedConditionalDistributionProbabilities; // // combinedConditionalDistributionProbabilities = // // IntStream.range(0, nMergedClassVars).mapToObj(modelNumber -> { // //// System.out.println("\nModel number " + modelNumber); // // int distributionIndex = (timeStep>=modelNumber) ? (modelNumber==0 ? 0 : 1) + (timeStep-modelNumber)/nMergedClassVars : (timeStep-modelNumber)/nMergedClassVars; // // UnivariateDistribution dist0 = posteriorMAPVariableDistributions.get(modelNumber).get(distributionIndex); //// System.out.println(dist0.toString()); // // double[] probabilities = new double[nStates]; // // int current_nMergedVars = (int)Math.round(Math.log(dist0.getVariable().getNumberOfStates())/Math.log(nStates)); // // for (int m = 0; m < Math.pow(nStates,current_nMergedVars); m++) { // String m_base_nStates = Integer.toString(Integer.parseInt(Integer.toString(m), 10), nStates); // m_base_nStates = StringUtils.leftPad(m_base_nStates, current_nMergedVars, '0'); // int currentVarIndex = (timeStep>=modelNumber) ? (timeStep-modelNumber)%nMergedClassVars : timeStep; // int currentState = Integer.parseInt(m_base_nStates.substring(currentVarIndex,currentVarIndex+1)); // // probabilities[currentState] += dist0.getParameters()[m]; // } //// System.out.println(Arrays.toString(probabilities)); // return probabilities; // // }) // .reduce(new double[nStates], (doubleArray1, doubleArray2)-> { // for (int i=0; i<doubleArray1.length; i++) // doubleArray1[i] += ((double)1/nMergedClassVars) * doubleArray2[i]; // return doubleArray1; // }); // //// System.out.println("Combined distribution " + Arrays.toString(combinedConditionalDistributionProbabilities)); // listCondDistributions.add(combinedConditionalDistributionProbabilities); // }); // // // // //// //// double[] probs1 = new double[nMergedStates]; //// int probs_index1 = 0; //// //// for (int m = 0; m < Math.pow(nStates,repetitionsConDistT); m++) { //// String m_base_nStates = Integer.toString(Integer.parseInt(Integer.toString(m), 10), nStates); //// m_base_nStates = StringUtils.leftPad(m_base_nStates, repetitionsConDistT, '0'); //// //// double probT=1; //// for ( int n=0; n < m_base_nStates.length(); n++) { //// int currentState = Integer.parseInt(m_base_nStates.substring(n,n+1)); //// //// int previousState; //// if(n>=1) //// previousState = Integer.parseInt(m_base_nStates.substring(n-1,n)); //// else //// previousState = parentState; //// //// assignment1 = new HashMapAssignment(2); //// assignment1.setValue(dynVar.getInterfaceVariable(), previousState); //// assignment1.setValue(dynVar,currentState); //// //// //// probT = probT * conDistT.getConditionalProbability(assignment1); //// } //// probs1[probs_index1] = probT; //// probs_index1++; //// } //// //// //// //// //// //// dist0_probs = dist0.getParameters(); //// for (int i = 0; i < MAPvarNStates; i++) { //// dist0_probs[i] = (double) 1/2 * dist0_probs[i]; //// //// for (int j = 0; j < MAPvarNStates; j++) { //// dist0_probs[i] = dist0_probs[i] + (double) 1/2 * dist0_1.getProbability(i*MAPvarNStates + j); //// } //// } //// listCondDistributions.add(dist0_probs); //// //// // // // // // //// //// // Conditional distribution Y_1 | Y_0; //// UnivariateDistribution dist_paired1 = posteriorMAPDistributionsEvenModel.get(0); // This variable Z_0 groups Y_0 and Y_1 //// UnivariateDistribution dist_unpaired_1 = posteriorMAPDistributionsOddModel.get(1); // This variable groups Y_1 and Y_2 (if nTimeSteps>2) //// //// double[] dist_probs1 = dist_paired1.getParameters(); //// //// for (int i = 0; i < MAPvarNStates; i++) { // To go over all values of Y_0 //// for (int j = 0; j < MAPvarNStates; j++) { // To go over all values of Y_1 //// int index = i * MAPvarNStates + j; //// dist_probs1[index] = (double) 1/2 * dist_probs1[index]; //// //// if (nTimeSteps>2) { //// for (int k = 0; k < MAPvarNStates; k++) { // To go over all values of Y_2 in the distrib of (Y_1,Y_2) //// dist_probs1[index] = dist_probs1[index] + (double) 1 / 2 * dist_unpaired_1.getProbability(j * MAPvarNStates + k); //// } //// } //// else { //// for (int k = 0; k < MAPvarNStates; k++) { // To go over all values of Y_2 in the distrib of (Y_1,Y_2) //// dist_probs1[index] = dist_probs1[index] + (double) 1 / 2 * dist_unpaired_1.getProbability(j); //// } //// } //// } //// } //// listCondDistributions.add(dist_probs1); //// //// IntStream.range(2, nTimeSteps - 1).forEachOrdered(t -> { //// if (t % 2 == 0) { //// int idxOdd = 1 + (t - 2) / 2; //// UnivariateDistribution dist_paired = posteriorMAPDistributionsOddModel.get(idxOdd); // This variable groups Y_t and Y_{t-1} //// //// UnivariateDistribution dist_unpaired_pre = posteriorMAPDistributionsEvenModel.get(idxOdd - 1); // This variable groups Y_{t-2} and Y_{t-1} //// UnivariateDistribution dist_unpaired_post = posteriorMAPDistributionsEvenModel.get(idxOdd); // This variable groups Y_t and Y_{t+1} //// //// double[] dist_probs = dist_paired.getParameters(); //// //// for (int i = 0; i < MAPvarNStates; i++) { // To go over all values of Y_{t-1} //// for (int j = 0; j < MAPvarNStates; j++) { // To go over all values of Y_t //// //// int index = i * MAPvarNStates + j; //// dist_probs[index] = (double) 1 / 2 * dist_probs[index]; //// //// for (int k = 0; k < MAPvarNStates; k++) { // To go over all values of Y_{t-2} //// for (int m = 0; m < MAPvarNStates; m++) { // To go over all values of Y_{t+1} //// dist_probs[index] = dist_probs[index] + (double) 1 / 2 * dist_unpaired_pre.getProbability(k * MAPvarNStates + i) * dist_unpaired_post.getProbability(j * MAPvarNStates + m); //// } //// } //// } //// } //// listCondDistributions.add(dist_probs); //// } else { //// int idxEven = (t - 1) / 2; //// UnivariateDistribution dist_paired = posteriorMAPDistributionsEvenModel.get(idxEven); // This variable groups Y_t and Y_{t-1} //// //// UnivariateDistribution dist_unpaired_pre = posteriorMAPDistributionsOddModel.get(idxEven); // This variable groups Y_{t-2} and Y_{t-1} //// UnivariateDistribution dist_unpaired_post = posteriorMAPDistributionsOddModel.get(idxEven + 1); // This variable groups Y_t and Y_{t+1} //// //// double[] dist_probs = dist_paired.getParameters(); //// //// for (int i = 0; i < MAPvarNStates; i++) { // To go over all values of Y_{t-1} //// for (int j = 0; j < MAPvarNStates; j++) { // To go over all values of Y_t //// //// int index = i * MAPvarNStates + j; //// dist_probs[index] = (double) 1 / 2 * dist_probs[index]; //// //// for (int k = 0; k < MAPvarNStates; k++) { // To go over all values of Y_{t-2} //// for (int m = 0; m < MAPvarNStates; m++) { // To go over all values of Y_{t+1} //// dist_probs[index] = dist_probs[index] + (double) 1 / 2 * dist_unpaired_pre.getProbability(k * MAPvarNStates + i) * dist_unpaired_post.getProbability(j * MAPvarNStates + m); //// } //// } //// } //// } //// listCondDistributions.add(dist_probs); //// } //// }); //// //// if (nTimeSteps>2) { //// // Conditional distribution Y_t | Y_{t-1}, with t = nTimeSteps-1 //// int t = (nTimeSteps - 1); //// if (t % 2 == 0) { //// int idxOdd = 1 + (t - 2) / 2; //// UnivariateDistribution dist_paired = posteriorMAPDistributionsOddModel.get(idxOdd); // This variable groups Y_t and Y_{t-1} //// //// UnivariateDistribution dist_unpaired_pre = posteriorMAPDistributionsEvenModel.get(idxOdd - 1); // This variable groups Y_{t-2} and Y_{t-1} //// UnivariateDistribution dist_unpaired_post = posteriorMAPDistributionsEvenModel.get(idxOdd); // This variable is just Y_t (not a group) //// //// double[] dist_probs = dist_paired.getParameters(); //// //// for (int i = 0; i < MAPvarNStates; i++) { // To go over all values of Y_{t-1} //// for (int j = 0; j < MAPvarNStates; j++) { // To go over all values of Y_t //// //// int index = i * MAPvarNStates + j; //// dist_probs[index] = (double) 1 / 2 * dist_probs[index]; //// //// for (int k = 0; k < MAPvarNStates; k++) { // To go over all values of Y_{t-2} //// //// dist_probs[index] = dist_probs[index] + (double) 1 / 2 * dist_unpaired_pre.getProbability(k * MAPvarNStates + i) * dist_unpaired_post.getProbability(j); //// } //// } //// } //// listCondDistributions.add(dist_probs); //// } //// else { //// int idxEven = (t - 1) / 2; //// UnivariateDistribution dist_paired = posteriorMAPDistributionsEvenModel.get(idxEven); // This variable groups Y_t and Y_{t-1} //// //// UnivariateDistribution dist_unpaired_pre = posteriorMAPDistributionsOddModel.get(idxEven); // This variable groups Y_{t-2} and Y_{t-1} //// //// double[] dist_probs = dist_paired.getParameters(); //// //// for (int i = 0; i < MAPvarNStates; i++) { // To go over all values of Y_{t-1} //// for (int j = 0; j < MAPvarNStates; j++) { // To go over all values of Y_t //// //// int index = i * MAPvarNStates + j; //// dist_probs[index] = (double) 1 / 2 * dist_probs[index]; //// //// for (int k = 0; k < MAPvarNStates; k++) { // To go over all values of Y_{t-2} //// dist_probs[index] = dist_probs[index] + (double) 1 / 2 * dist_unpaired_pre.getProbability(k * MAPvarNStates + i); //// } //// } //// } //// listCondDistributions.add(dist_probs); //// } //// } // // return listCondDistributions; // } /** * Returns the max value and its corresponding index. * @param values an array of {@code double} values. * @return the max value and its corresponding index. */ private double[] argMax(double[] values) { double maxValue = Arrays.stream(values).max().getAsDouble(); double indexMaxValue = -1; for (int i = 0; i < values.length; i++) { if (values[i] == maxValue) { indexMaxValue = i; } } return new double[] { maxValue, indexMaxValue }; } /** * Returns the replicated static set of variables * @param dynamicVariables a {@link DynamicVariables} object. * @param modelNumber a {@code int} that indicates the number of the model being constructed. * @return a {@link Variables} object. */ private Variables obtainReplicatedStaticVariables(DynamicVariables dynamicVariables, int modelNumber) { Variables variables = new Variables(); // REPLICATIONS OF THE MAP VARIABLE (EACH 'nMergedClassVars' CONSECUTIVE ARE GROUPED) int replicationsMAPVariable = (modelNumber == 0 ? 0 : 1) + (nTimeSteps - modelNumber) / nMergedClassVars + ((nTimeSteps - modelNumber) % nMergedClassVars == 0 ? 0 : 1); IntStream.range(0, replicationsMAPVariable).forEach(mergedClassVarIndex -> { int nStatesMAPVariable = (int) Math.pow(MAPvariable.getNumberOfStates(), nMergedClassVars); // If it is the first merged variable and not the first model (not 'complete') if ((modelNumber != 0) && (mergedClassVarIndex == 0)) { nStatesMAPVariable = (int) Math.pow(MAPvariable.getNumberOfStates(), modelNumber); } // If it is the last merged variable and not 'complete' if (((nTimeSteps - modelNumber) % nMergedClassVars != 0) && (mergedClassVarIndex == replicationsMAPVariable - 1)) { nStatesMAPVariable = (int) Math.pow(MAPvariable.getNumberOfStates(), (nTimeSteps - modelNumber) % nMergedClassVars); } variables.newMultinomialVariable(groupedClassName + "_t" + Integer.toString(mergedClassVarIndex), nStatesMAPVariable); }); // REPLICATIONS OF THE REST OF VARIABLES (EACH ONE REPEATED 'nTimeSteps' TIMES) dynamicVariables.getListOfDynamicVariables().stream().filter(var -> !var.equals(MAPvariable)) .forEach(dynVar -> IntStream.range(0, nTimeSteps).forEach(i -> { VariableBuilder aux = dynVar.getVariableBuilder(); aux.setName(dynVar.getName() + "_t" + Integer.toString(i)); variables.newVariable(aux); })); return variables; } /** * Returns the static DAG structure. * @param dynamicDAG a {@link DynamicDAG} object. * @param variables a {@link Variables} object. * @param modelNumber an integer * @return a {@link DAG} object. */ private DAG obtainStaticDAG(DynamicDAG dynamicDAG, Variables variables, int modelNumber) { DAG dag = new DAG(variables); DynamicVariables dynamicVariables = dynamicDAG.getDynamicVariables(); /* * PARENTS OF THE MAP VARIABLE (ONLY THE PREVIOUS TEMPORAL COPY OF ITSELF) */ int replicationsMAPVariable = (modelNumber == 0 ? 0 : 1) + (nTimeSteps - modelNumber) / nMergedClassVars + ((nTimeSteps - modelNumber) % nMergedClassVars == 0 ? 0 : 1); IntStream.range(1, replicationsMAPVariable).forEach(mergedClassVarIndex -> { Variable staticVar = variables .getVariableByName(groupedClassName + "_t" + Integer.toString(mergedClassVarIndex)); dag.getParentSet(staticVar).addParent(variables .getVariableByName(groupedClassName + "_t" + Integer.toString(mergedClassVarIndex - 1))); }); /* * PARENTS OF THE REST OF VARIABLES */ dynamicVariables.getListOfDynamicVariables().stream().filter(var -> !var.equals(MAPvariable)) .forEach(dynVar -> { // ADD PARENTS AT TIME T=0 Variable staticVar0 = variables.getVariableByName(dynVar.getName() + "_t0"); List<Variable> parents0 = dynamicDAG.getParentSetTime0(dynVar).getParents(); parents0.stream().filter(parent -> parent.equals(MAPvariable)) .forEach(parentaux2 -> dag.getParentSet(staticVar0) .addParent(variables.getVariableByName(groupedClassName + "_t0"))); parents0.stream().filter(parent -> !parent.equals(MAPvariable)) .forEach(parentaux2 -> dag.getParentSet(staticVar0) .addParent(variables.getVariableByName(parentaux2.getName() + "_t0"))); // ADD PARENTS AT TIMES T>0 IntStream.range(1, nTimeSteps).forEach(timeStep -> { Variable staticVar = variables .getVariableByName(dynVar.getName() + "_t" + Integer.toString(timeStep)); List<Variable> parents = dynamicDAG.getParentSetTimeT(dynVar).getParents(); int indexMAPReplication = (timeStep >= modelNumber) ? (modelNumber == 0 ? 0 : 1) + (timeStep - modelNumber) / nMergedClassVars : (timeStep - modelNumber) / nMergedClassVars; if (indexMAPReplication >= replicationsMAPVariable) { System.out.println("Error in obtainStaticDAG: Bad MAP variable index"); System.exit(-50); } // PARENTS WHICH ARE INTERFACE VARIABLES List<Variable> parentsInterface = parents.stream() .filter(parentVar -> parentVar.isInterfaceVariable()).collect(Collectors.toList()); parentsInterface.stream().filter(parent -> parent.equals(MAPvariable)).forEach( parentVar -> dag.getParentSet(staticVar).addParent(variables.getVariableByName( groupedClassName + "_t" + Integer.toString(indexMAPReplication - 1)))); parentsInterface.stream().filter(parent -> !parent.equals(MAPvariable)) .forEach(parentVar -> dag.getParentSet(staticVar) .addParent(variables.getVariableByName(parentVar.getName() .replace("_Interface", "_t" + Integer.toString(timeStep - 1))))); // PARENTS WHICH ARE NOT INTERFACE VARIABLES List<Variable> parentsNotInterface = parents.stream() .filter(parentVar -> !parentVar.isInterfaceVariable()).collect(Collectors.toList()); parentsNotInterface.stream().filter(parent -> parent.equals(MAPvariable)).forEach( parentVar -> dag.getParentSet(staticVar).addParent(variables.getVariableByName( groupedClassName + "_t" + Integer.toString(indexMAPReplication)))); parentsNotInterface.stream().filter(parent -> !parent.equals(MAPvariable)).forEach( parentVar -> dag.getParentSet(staticVar).addParent(variables.getVariableByName( parentVar.getName() + "_t" + Integer.toString(timeStep)))); }); }); return dag; } /** * Returns the grouped Distribution of the MAP Variable at Time 0. * @param dynVar the dynamic {@link Variable} object. * @param staticVar the static {@link Variable} object. * @param conDist0 the {@link ConditionalDistribution} at time 0. * @param conDistT the {@link ConditionalDistribution} at time T. * @return a {@link Multinomial} distribution. */ private Multinomial groupedDistributionMAPVariableTime0(Variable dynVar, Variable staticVar, ConditionalDistribution conDist0, ConditionalDistribution conDistT, int modelNumber) { if (modelNumber == 1) { return (Multinomial) conDist0; } Assignment assignment0; assignment0 = new HashMapAssignment(1); int nStates = dynVar.getNumberOfStates(); int nMergedStates = staticVar.getNumberOfStates(); Multinomial multinomial = new Multinomial(staticVar); double[] probs = new double[nMergedStates]; int probs_index = 0; int repetitionsConDistT = (int) Math.round(Math.log(nMergedStates) / Math.log(nStates) - 1); Assignment assignment1; for (int k = 0; k < nStates; k++) { // Probabilities at t=0 assignment0.setValue(dynVar, k); double prob0 = conDist0.getConditionalProbability(assignment0); for (int m = 0; m < Math.pow(nStates, repetitionsConDistT); m++) { String m_base_nStates = Integer.toString(Integer.parseInt(Integer.toString(m), 10), nStates); m_base_nStates = StringUtils.leftPad(m_base_nStates, repetitionsConDistT, '0'); //System.out.println(m_base_nStates); double probT = 1; for (int n = 0; n < m_base_nStates.length(); n++) { int currentState = Integer.parseInt(m_base_nStates.substring(n, n + 1)); int previousState; if (n >= 1) previousState = Integer.parseInt(m_base_nStates.substring(n - 1, n)); else previousState = k; assignment1 = new HashMapAssignment(2); assignment1.setValue(dynVar.getInterfaceVariable(), previousState); assignment1.setValue(dynVar, currentState); probT = probT * conDistT.getConditionalProbability(assignment1); } probs[probs_index] = prob0 * probT; probs_index++; } } multinomial.setProbabilities(probs); return multinomial; } /** * Returns the grouped Distribution of the MAP Variable at Time 0. * @param dynVar the dynamic {@link Variable} object. * @param staticVar the static {@link Variable} object. * @param nStatesStaticVarParent the number of static variable parents. * @param parents the {@code List} of parent {@link Variable}s. * @param conDistT the {@link ConditionalDistribution} at time T. * @return a {@link Multinomial_MultinomialParents} distribution. */ private Multinomial_MultinomialParents groupedDistributionMAPVariableTimeT(Variable dynVar, Variable staticVar, int nStatesStaticVarParent, List<Variable> parents, ConditionalDistribution conDistT, int modelNumber) { Multinomial_MultinomialParents multinomial_multinomialParents = new Multinomial_MultinomialParents( staticVar, parents); Assignment assignment1; Multinomial multinomial; int nStates = dynVar.getNumberOfStates(); int nMergedStates = staticVar.getNumberOfStates(); int repetitionsConDistT = (int) Math.round(Math.log(nMergedStates) / Math.log(nStates)); for (int s = 0; s < nStatesStaticVarParent; s++) { int parentState = s % nStates; double[] probs1 = new double[nMergedStates]; int probs_index1 = 0; for (int m = 0; m < Math.pow(nStates, repetitionsConDistT); m++) { String m_base_nStates = Integer.toString(Integer.parseInt(Integer.toString(m), 10), nStates); m_base_nStates = StringUtils.leftPad(m_base_nStates, repetitionsConDistT, '0'); double probT = 1; for (int n = 0; n < m_base_nStates.length(); n++) { int currentState = Integer.parseInt(m_base_nStates.substring(n, n + 1)); int previousState; if (n >= 1) previousState = Integer.parseInt(m_base_nStates.substring(n - 1, n)); else previousState = parentState; assignment1 = new HashMapAssignment(2); assignment1.setValue(dynVar.getInterfaceVariable(), previousState); assignment1.setValue(dynVar, currentState); probT = probT * conDistT.getConditionalProbability(assignment1); } probs1[probs_index1] = probT; probs_index1++; } multinomial = new Multinomial(staticVar); multinomial.setProbabilities(probs1); multinomial_multinomialParents.setMultinomial(s, multinomial); } return multinomial_multinomialParents; } /** * Returns the {@link BayesianNetwork} related to the static grouped class. * @param dag a {@link DAG} object. * @param variables a {@link Variables} obejct. * @param modelNumber an integer * @return a {@link BayesianNetwork} object. */ private BayesianNetwork obtainStaticMergedClassVarNetwork(DAG dag, Variables variables, int modelNumber) { DynamicDAG dynamicDAG = model.getDynamicDAG(); BayesianNetwork bn = new BayesianNetwork(dag); Variable staticVar, dynVar; ConditionalDistribution conDist0, conDistT; int replicationsMAPVariable = (modelNumber == 0 ? 0 : 1) + (nTimeSteps - modelNumber) / nMergedClassVars + ((nTimeSteps - modelNumber) % nMergedClassVars == 0 ? 0 : 1); /* * OBTAIN AND SET THE CONDITIONAL (UNIVARIATE) DISTRIBUTION FOR THE GROUPED MAP/CLASS VARIABLE AT TIME T=0 */ staticVar = variables.getVariableByName(groupedClassName + "_t0"); dynVar = model.getDynamicVariables().getVariableByName(MAPvarName); conDist0 = Serialization.deepCopy(model.getConditionalDistributionsTime0().get(dynVar.getVarID())); conDistT = Serialization.deepCopy(model.getConditionalDistributionsTimeT().get(dynVar.getVarID())); Multinomial multinomial = groupedDistributionMAPVariableTime0(dynVar, staticVar, conDist0, conDistT, modelNumber); multinomial.setVar(staticVar); bn.setConditionalDistribution(staticVar, multinomial); /* * CREATE THE GENERAL (TIME T) CONDITIONAL DISTRIBUTION OF THE GROUPED MAP/CLASS VARIABLE, IF NEEDED */ Multinomial_MultinomialParents generalConditionalDistTimeT; // ToDo: Review Condition: nTimeSteps>= 4,5 if (modelNumber == 0 && (replicationsMAPVariable > 2 || (replicationsMAPVariable == 2 && nTimeSteps >= 4))) { Variable staticVar_current = variables.getVariableByName(groupedClassName + "_t1"); Variable staticVar_interface = variables.getVariableByName(groupedClassName + "_t0"); List<Variable> parents = bn.getDAG().getParentSet(staticVar_current).getParents(); ConditionalDistribution conDist_dynamic = Serialization.deepCopy(conDistT); generalConditionalDistTimeT = groupedDistributionMAPVariableTimeT(dynVar, staticVar_current, staticVar_interface.getNumberOfStates(), parents, conDist_dynamic, modelNumber); } else if (modelNumber > 0 && (replicationsMAPVariable > 3 || replicationsMAPVariable == 3 && nTimeSteps >= 5)) { Variable staticVar_current = variables.getVariableByName(groupedClassName + "_t2"); Variable staticVar_interface = variables.getVariableByName(groupedClassName + "_t1"); List<Variable> parents = bn.getDAG().getParentSet(staticVar_current).getParents(); ConditionalDistribution conDist_dynamic = Serialization.deepCopy(conDistT); generalConditionalDistTimeT = groupedDistributionMAPVariableTimeT(dynVar, staticVar_current, staticVar_interface.getNumberOfStates(), parents, conDist_dynamic, modelNumber); } else { // In this case, 'generalConditionalDistTimeT' will never be used. generalConditionalDistTimeT = new Multinomial_MultinomialParents(staticVar, bn.getDAG().getParentSet(staticVar).getParents()); } /* * ADD CONDITIONAL DISTRIBUTIONS FOR THE REPLICATIONS OF THE GROUPED MAP/CLASS VARIABLE */ // FIRST CONDITIONAL DISTRIBUTION, t_1 | t_0, IF IT'S NOT THE GENERAL ONE if (modelNumber != 0) { Variable staticVar0 = variables.getVariableByName(groupedClassName + "_t1"); Variable staticVar0_interface = variables.getVariableByName(groupedClassName + "_t0"); List<Variable> parents = bn.getDAG().getParentSet(staticVar0).getParents(); ConditionalDistribution conDist_dynamic = Serialization .deepCopy(model.getConditionalDistributionsTimeT().get(dynVar.getVarID())); ConditionalDistribution conditionalDistTime1 = groupedDistributionMAPVariableTimeT(dynVar, staticVar0, staticVar0_interface.getNumberOfStates(), parents, conDist_dynamic, modelNumber); conditionalDistTime1.setVar(staticVar0); bn.setConditionalDistribution(staticVar0, conditionalDistTime1); } // INTERMEDIATE COMPLETE CONDITIONAL DISTRIBUTIONS, t_i | t_{i-1}, FOLLOWING THE GENERAL CONDITIONAL DISTRIBUTION int initialTimeStep = 2; int finalTimeStep = replicationsMAPVariable - 1; if (modelNumber == 0) initialTimeStep = 1; if ((nTimeSteps - modelNumber) % nMergedClassVars == 0) finalTimeStep = replicationsMAPVariable; IntStream.range(initialTimeStep, finalTimeStep).forEach(timeStep -> { Variable staticVar1 = variables.getVariableByName(groupedClassName + "_t" + Integer.toString(timeStep)); ConditionalDistribution conditionalDistribution = Serialization.deepCopy(generalConditionalDistTimeT); conditionalDistribution.setConditioningVariables(dag.getParentSet(staticVar1).getParents()); conditionalDistribution.setVar(staticVar1); bn.setConditionalDistribution(staticVar1, conditionalDistribution); }); // LAST CONDITIONAL DISTRIBUTION, t_{nTimeSteps} | t_{nTimeSteps-1}, IF IT'S NOT THE GENERAL ONE if ((nTimeSteps - modelNumber) % nMergedClassVars != 0) { Variable staticVar1 = variables .getVariableByName(groupedClassName + "_t" + Integer.toString(replicationsMAPVariable - 1)); Variable staticVar1_interface = variables .getVariableByName(groupedClassName + "_t" + Integer.toString(replicationsMAPVariable - 2)); List<Variable> parents1 = bn.getDAG().getParentSet(staticVar1).getParents(); Multinomial_MultinomialParents lastConDist = groupedDistributionMAPVariableTimeT(dynVar, staticVar1, staticVar1_interface.getNumberOfStates(), parents1, conDistT, modelNumber); bn.setConditionalDistribution(staticVar1, lastConDist); } /* * ADD CONDITIONAL DISTRIBUTIONS FOR VARIABLES HAVING AS A PARENT THE GROUPED MAP/CLASS VARIABLE, AT TIME T=0 */ List<Variable> dynVariables = model.getDynamicVariables().getListOfDynamicVariables(); List<Variable> dynVariablesWithClassParent = dynVariables.stream().filter(var -> !var.equals(MAPvariable)) .filter(var -> dynamicDAG.getParentSetTime0(var).contains(MAPvariable)) .collect(Collectors.toList()); List<Variable> dynVariablesNoClassParent = dynVariables.stream().filter(var -> !var.equals(MAPvariable)) .filter(var -> !dynamicDAG.getParentSetTime0(var).contains(MAPvariable)) .collect(Collectors.toList()); // dynVariablesWithClassParent.stream().forEach(dynVariable -> { // ConditionalDistribution conditionalDistribution = Serialization.deepCopy(model.getConditionalDistributionTime0(dynVariable)); // // Variable staticMAPVar1 = variables.getVariableByName(groupedClassName + "_t0"); // Variable staticVar1 = variables.getVariableByName(dynVariable.getName() + "_t0"); // List<Variable> thisVarParents = conditionalDistribution.getConditioningVariables(); // List<Variable> parentList0 = bn.getDAG().getParentSet(staticVar1).getParents(); // int indexMAPvariable = thisVarParents.indexOf(MAPvariable); // // thisVarParents.set(indexMAPvariable, staticMAPVar1); // // // conditionalDistribution.setConditioningVariables(parentList0); // conditionalDistribution.setVar(staticVar1); // //// if(modelNumber==1) //// bn.setConditionalDistribution(staticVar1, conditionalDistribution); //// else { // BaseDistribution_MultinomialParents staticVar2Distribution = obtainDistributionOfMAPChildren(staticVar1, conditionalDistribution, parentList0, modelNumber, 0); // bn.setConditionalDistribution(staticVar1, staticVar2Distribution); //// } // // }); /* * ADD CONDITIONAL DISTRIBUTIONS FOR VARIABLES HAVING AS A PARENT THE GROUPED MAP/CLASS VARIABLE, AT ANY TIME T */ dynVariablesWithClassParent.stream().forEach(dynVariable -> { IntStream.range(0, nTimeSteps).forEachOrdered(timeStep -> { ConditionalDistribution dynamicConDist; dynamicConDist = Serialization .deepCopy(timeStep == 0 ? model.getConditionalDistributionTime0(dynVariable) : model.getConditionalDistributionTimeT(dynVariable)); // )if(timeStep==0) { // = Serialization.deepCopy(model.getConditionalDistributionTime0(dynVariable)); // } // else { // dynamicConDist = Serialization.deepCopy(model.getConditionalDistributionTimeT(dynVariable)); // } Variable staticVar2 = variables .getVariableByName(dynVariable.getName() + "_t" + Integer.toString(timeStep)); List<Variable> parentList = bn.getDAG().getParentSet(staticVar2).getParents(); ConditionalDistribution staticVar2Distribution = obtainDistributionOfMAPChildren(staticVar2, dynamicConDist, parentList, modelNumber, timeStep); bn.setConditionalDistribution(staticVar2, staticVar2Distribution); }); }); /* * ADD CONDITIONAL DISTRIBUTIONS FOR VARIABLES NOT HAVING AS A PARENT THE GROUPED MAP/CLASS VARIABLE, AT ANY TIME T */ dynVariablesNoClassParent.stream().forEach(dynVariable -> { // TIME T=0 ConditionalDistribution conditionalDistribution = Serialization .deepCopy(model.getConditionalDistributionTime0(dynVariable)); Variable staticVar1 = variables.getVariableByName(dynVariable.getName() + "_t0"); List<Variable> thisVarParents = conditionalDistribution.getConditioningVariables(); thisVarParents = thisVarParents.stream() .map(parent -> variables.getVariableByName(parent.getName() + "_t0")) .collect(Collectors.toList()); conditionalDistribution.setConditioningVariables(thisVarParents); conditionalDistribution.setVar(staticVar1); bn.setConditionalDistribution(staticVar1, conditionalDistribution); // TIMES T>0 IntStream.range(1, nTimeSteps).forEach(i -> { ConditionalDistribution conditionalDistribution1 = Serialization .deepCopy(model.getConditionalDistributionTimeT(dynVariable)); Variable staticVar2 = variables .getVariableByName(dynVariable.getName() + "_t" + Integer.toString(i)); List<Variable> thisVarParents1 = conditionalDistribution1.getConditioningVariables(); thisVarParents1 = thisVarParents1.stream().map(parent -> { if (parent.getName().contains("_Interface")) { return variables.getVariableByName( parent.getName().replace("_Interface", "_t" + Integer.toString(i - 1))); } else { return variables.getVariableByName(parent.getName() + "_t" + Integer.toString(i)); } }).collect(Collectors.toList()); conditionalDistribution1.setConditioningVariables(thisVarParents1); conditionalDistribution1.setVar(staticVar2); bn.setConditionalDistribution(staticVar2, conditionalDistribution1); }); }); return bn; } /** * Returns the distribution of MAP Children at time T. * @param staticVariable the static {@link Variable} object. * @param dynamicConditionalDistribution the dynamic {@link ConditionalDistribution} at time T. * @param parentList the {@code List} of parent {@link Variable}s. * @param modelNumber an integer * @param time_step an integer with the time step. * @return a {@link BaseDistribution_MultinomialParents} distribution. */ private ConditionalDistribution obtainDistributionOfMAPChildren(Variable staticVariable, ConditionalDistribution dynamicConditionalDistribution, List<Variable> parentList, int modelNumber, int time_step) { boolean allParentsMultinomial = parentList.stream().allMatch(parent -> parent.isMultinomial()); List<Variable> multinomialParents = parentList.stream().filter(parent -> parent.isMultinomial()) .collect(Collectors.toList()); List<Variable> continuousParents = parentList.stream().filter(parent -> !parent.isMultinomial()) .collect(Collectors.toList()); //BaseDistribution_MultinomialParents staticVarConDist = new BaseDistribution_MultinomialParents(staticVariable, parentList); ConditionalDistribution staticVarConDist; // In this method, all variables have at least one parent (either discrete or continuous) int distributionType = -1; if (staticVariable.isMultinomial()) { distributionType = 0; staticVarConDist = new Multinomial_MultinomialParents(staticVariable, parentList); } else if (staticVariable.isNormal()) { int nMultinomialParents = multinomialParents.size(); int nNormalParents = continuousParents.size(); if (nNormalParents > 0 && nMultinomialParents == 0) { distributionType = 1; staticVarConDist = new ConditionalLinearGaussian(staticVariable, parentList); } else if (nNormalParents == 0 && nMultinomialParents > 0) { distributionType = 2; staticVarConDist = new Normal_MultinomialParents(staticVariable, parentList); } else if (nNormalParents > 0 && nMultinomialParents > 0) { distributionType = 3; staticVarConDist = new Normal_MultinomialNormalParents(staticVariable, parentList); } else { throw new IllegalArgumentException("Unrecognized DistributionType. "); } } else { throw new IllegalArgumentException("Unrecognized DistributionType. "); } int nStatesMultinomialParents = (int) Math.round(Math.exp( multinomialParents.stream().mapToDouble(parent -> Math.log(parent.getNumberOfStates())).sum())); int nStatesMAPVariable = MAPvariable.getNumberOfStates(); for (int m = 0; m < nStatesMultinomialParents; m++) { Assignment staticParentsConfiguration = MultinomialIndex .getVariableAssignmentFromIndex(multinomialParents, m); Assignment dynamicParentsConfiguration = new HashMapAssignment(multinomialParents.size()); IntStream.range(0, multinomialParents.size()).forEach(k -> { Variable currentParent = multinomialParents.get(k); int parentValue = (int) staticParentsConfiguration.getValue(currentParent); String parentName; if (currentParent.getName().contains(groupedClassName)) { parentName = currentParent.getName().replace(groupedClassName, MAPvarName).replaceAll("_t\\d+", ""); Variable dynCurrentParent = model.getDynamicVariables().getVariableByName(parentName); int dynParentValue; int nMergedStates = currentParent.getNumberOfStates(); int repetitionsConDistT = (int) Math .round(Math.log(nMergedStates) / Math.log(nStatesMAPVariable)); int indexCurrentParentState; if (time_step >= modelNumber) indexCurrentParentState = (time_step - modelNumber) % nMergedClassVars; else indexCurrentParentState = time_step; String m_base_nStates = Integer.toString(Integer.parseInt(Integer.toString(parentValue), 10), nStatesMAPVariable); m_base_nStates = StringUtils.leftPad(m_base_nStates, repetitionsConDistT, '0'); int dynamicParentState = Integer.parseInt( m_base_nStates.substring(indexCurrentParentState, indexCurrentParentState + 1)); dynParentValue = dynamicParentState; dynamicParentsConfiguration.setValue(dynCurrentParent, dynParentValue); // System.out.println("Variable: " + staticVariable.getName() + " with " + staticVariable.getNumberOfStates() + " states and " + parentList.size() + " parents"); // System.out.println("Parent " + parentName + " with " + nMergedStates + " states"); // System.out.println("Time step " + time_step + " and model number " + modelNumber); // System.out.println("Parent state number " + parentValue + " which is " + m_base_nStates); // System.out.println("Index parent state " + indexCurrentParentState); // System.out.println("Dynamic parent state number " + dynamicParentState); // System.out.println(); // if (time_step==0) { // Variable at time t=0 // if(modelNumber!=1) { // //dynParentValue = parentValue / (int) Math.pow(nStatesMAPVariable, nMergedClassVars - 1); //// System.out.println(currentParent.getNumberOfStates()); //// System.out.println(nStatesMAPVariable); //// System.out.println(parentValue); //// System.out.println(parentValue / (currentParent.getNumberOfStates()/nStatesMAPVariable)); // dynParentValue = parentValue / (int) Math.pow(nStatesMAPVariable, nMergedClassVars - 1); // } // else { // dynParentValue = parentValue; // } // } // Variable at time t=nTimeSteps-1 (last copy) and not complete // else { // // // if ((time_step - modelNumber) % nMergedClassVars != 0 && (time_step == nTimeSteps - 1)) { // dynParentValue = parentValue % nStatesMAPVariable; // } else { // if ((time_step - modelNumber) % nMergedClassVars == 0) { // dynParentValue = parentValue / (currentParent.getNumberOfStates() / nStatesMAPVariable); // ; // } else { // dynParentValue = parentValue % nStatesMAPVariable; // } // } // } // if ((!even_partition && nTimeSteps % 2 == 0 && (time_step == nTimeSteps - 1)) || (even_partition && nTimeSteps % 2 == 1 && (time_step == nTimeSteps - 1))) { // dynParentValue = parentValue; // } else { // if ((!even_partition && (time_step % 2 == 1)) || (even_partition && (time_step % 2 == 0))) { // dynParentValue = parentValue / MAPvariable.getNumberOfStates(); // } else { // dynParentValue = parentValue % MAPvariable.getNumberOfStates(); // } // } } else { if (multinomialParents.get(k).getName().endsWith("_t" + Integer.toString(time_step - 1))) { parentName = multinomialParents.get(k).getName().replaceFirst("_t\\d+", ""); Variable dynParent = model.getDynamicVariables().getVariableByName(parentName); dynamicParentsConfiguration.setValue(dynParent.getInterfaceVariable(), parentValue); } else { parentName = multinomialParents.get(k).getName().replaceFirst("_t\\d+", ""); Variable dynParent = model.getDynamicVariables().getVariableByName(parentName); dynamicParentsConfiguration.setValue(dynParent, parentValue); } } }); // System.out.println(dynamicParentsConfiguration.outputString()); // if (allParentsMultinomial && staticVariable.isMultinomial()) { //// try { // // Multinomial_MultinomialParents multinomial_multinomialParents = (Multinomial_MultinomialParents) dynamicConditionalDistribution; // Multinomial multinomial1 = (Multinomial) multinomial_multinomialParents.getMultinomial(dynamicParentsConfiguration); // // multinomial1.setVar(staticVariable); // multinomial1.setConditioningVariables(multinomialParents); // //// System.out.println(multinomial1.toString()+"\n\n"); // staticVarConDist.setBaseDistribution(m, multinomial1); // staticVarConDist.set //// } //// catch(Exception e) { //// System.out.println("Exception"); //// System.out.println(e.getMessage()); //// System.out.println(staticVariable.getName()); //// System.out.println(dynamicParentsConfiguration.outputString()); //// } // } // else if (allParentsMultinomial && staticVariable.isNormal() ){ // Normal_MultinomialParents normal_multinomialParents = (Normal_MultinomialParents) dynamicConditionalDistribution; // Normal clg = normal_multinomialParents.getNormal(dynamicParentsConfiguration); // clg.setConditioningVariables(multinomialParents); // //clg.setConditioningVariables(continuousParents); // clg.setVar(staticVariable); // // staticVarConDist.setBaseDistribution(m, clg); // } // else { // Normal_MultinomialNormalParents normal_multinomialNormalParents = (Normal_MultinomialNormalParents) dynamicConditionalDistribution; // ConditionalLinearGaussian clg = normal_multinomialNormalParents.getNormal_NormalParentsDistribution(dynamicParentsConfiguration); // clg.setConditioningVariables(continuousParents); // clg.setVar(staticVariable); // // staticVarConDist.setBaseDistribution(m, clg); // } if (distributionType == 0) { // Multinomial_Multinomial Multinomial_MultinomialParents multinomial_multinomialParents = (Multinomial_MultinomialParents) dynamicConditionalDistribution; Multinomial multinomial1 = (Multinomial) multinomial_multinomialParents .getMultinomial(dynamicParentsConfiguration); multinomial1.setVar(staticVariable); multinomial1.setConditioningVariables(multinomialParents); ((Multinomial_MultinomialParents) staticVarConDist).setMultinomial(m, multinomial1); } else if (distributionType == 2) { // Normal_Multinomial Normal_MultinomialParents normal_multinomialParents = (Normal_MultinomialParents) dynamicConditionalDistribution; Normal normal1 = normal_multinomialParents.getNormal(dynamicParentsConfiguration); normal1.setConditioningVariables(multinomialParents); //clg.setConditioningVariables(continuousParents); normal1.setVar(staticVariable); ((Normal_MultinomialParents) staticVarConDist).setNormal(m, normal1); } else if (distributionType == 3) { // Normal_MultinomialNormal Normal_MultinomialNormalParents normal_multinomialNormalParents = (Normal_MultinomialNormalParents) dynamicConditionalDistribution; ConditionalLinearGaussian clg = normal_multinomialNormalParents .getNormal_NormalParentsDistribution(dynamicParentsConfiguration); clg.setConditioningVariables(continuousParents); clg.setVar(staticVariable); ((Normal_MultinomialNormalParents) staticVarConDist).setNormal_NormalParentsDistribution(m, clg); } else { // ConditionalLinearGaussian, distributionType==1 ConditionalLinearGaussian clg = (ConditionalLinearGaussian) dynamicConditionalDistribution; //((ConditionalLinearGaussian)staticVarConDist) staticVarConDist = clg; } } // if (allParentsMultinomial && staticVariable.isNormal()) // return (Normal_MultinomialParents)staticVarConDist; // else { // return staticVarConDist; // } return staticVarConDist; } // public static Iterator<List<DynamicAssignment>> generateEvidence(DynamicBayesianNetwork dynamicBayesianNetwork, String mapVariableName, int numberOfSequences, int sequenceLength, double percentageOfEvidence, int seed) { // // Random random = new Random(seed); // Variable mapVariable = dynamicBayesianNetwork.getDynamicVariables().getVariableByName(mapVariableName); // List<List<DynamicAssignment>> evidences = new ArrayList<>(numberOfSequences); // // int nVarsEvidence = (int)(percentageOfEvidence * dynamicBayesianNetwork.getNumberOfVars()); // // // //DynamicBayesianNetworkSampler sampler = new DynamicBayesianNetworkSampler(dynamicBayesianNetwork); // //DataStream<DynamicDataInstance> sample = sampler.sampleToDataBase(numberOfSequences,sequenceLength); // // for (int i = 0; i < numberOfSequences; i++) { // // // List<Variable> varsDynamicModel = dynamicBayesianNetwork.getDynamicVariables().getListOfDynamicVariables(); // // if (nVarsEvidence > varsDynamicModel.size()-1) { // System.out.println("Too many variables to be observe"); // return null; // } // // List<Variable> varsEvidence = new ArrayList<>(nVarsEvidence); // // int currentVarsEvidence=0; // while (currentVarsEvidence < nVarsEvidence) { // int indexVarEvidence = random.nextInt(dynamicBayesianNetwork.getNumberOfDynamicVars()); // Variable varEvidence = varsDynamicModel.get(indexVarEvidence); // // if (varEvidence.equals(mapVariable) || varsEvidence.contains(varEvidence)) { // continue; // } // varsEvidence.add(varEvidence); // currentVarsEvidence++; // } // // List<DynamicAssignment> fullEvidence, evidence; // evidence = new ArrayList<>(sequenceLength); // // DynamicBayesianNetworkSampler bayesianNetworkSampler0 = new DynamicBayesianNetworkSampler(dynamicBayesianNetwork); // bayesianNetworkSampler0.setSeed(random.nextInt()); // DataStream<DynamicDataInstance> sample = bayesianNetworkSampler0.sampleToDataBase(1,sequenceLength); // // //sample.getAttributes().getFullListOfAttributes().forEach(attribute -> System.out.println(attribute.getName())); // fullEvidence = sample.stream().collect(Collectors.toList()); // //// System.out.println("Full Sample:"); //// fullEvidence.stream().forEachOrdered(dynass -> System.out.println(dynass.outputString(dynamicBayesianNetwork.getDynamicVariables().getListOfDynamicVariables()))); //// System.out.println(); // // // // Evidence in t=0, 1, ..., nTimeSteps-2 for variables in 'varsEvidence' // IntStream.range(0,sequenceLength-1).forEachOrdered(t -> { // HashMapDynamicAssignment dynamicAssignment = new HashMapDynamicAssignment(varsEvidence.size()); // dynamicAssignment.setSequenceID(0); // dynamicAssignment.setTimeID(t); // varsDynamicModel.stream().filter(variable -> varsEvidence.contains(variable)).forEach( variable -> dynamicAssignment.setValue(variable,fullEvidence.get(t).getValue(variable))); // evidence.add(dynamicAssignment); // }); // // // Evidence in t=(nTimeSteps-1) for all variables that are leaves in the DAG. // for (Variable currentVar : varsDynamicModel) { // if (!varsDynamicModel.stream().anyMatch(var -> dynamicBayesianNetwork.getDynamicDAG().getParentSetTimeT(var).getParents().contains(currentVar))) { // varsEvidence.add(currentVar); // } // } // HashMapDynamicAssignment dynamicAssignment1 = new HashMapDynamicAssignment(varsEvidence.size()); // dynamicAssignment1.setSequenceID(0); // dynamicAssignment1.setTimeID(sequenceLength-1); // varsDynamicModel.stream().filter(variable -> varsEvidence.contains(variable)).forEach( variable -> dynamicAssignment1.setValue(variable,fullEvidence.get(sequenceLength-1).getValue(variable))); // evidence.add(dynamicAssignment1); // //// System.out.println("Evidence:"); //// evidence.stream().forEachOrdered(dynass -> System.out.println(dynass.outputString(dynamicBayesianNetwork.getDynamicVariables().getListOfDynamicVariables()))); //// System.out.println(); // // StringBuilder classVarSequenceBuilder = new StringBuilder(); // classVarSequenceBuilder.append("ClassVar: ("); // fullEvidence.stream().forEachOrdered(dynass -> classVarSequenceBuilder.append( Integer.toString((int)dynass.getValue(mapVariable)) + ",")); // classVarSequenceBuilder.replace(classVarSequenceBuilder.lastIndexOf(","),classVarSequenceBuilder.lastIndexOf(",")+1,""); // classVarSequenceBuilder.append(")"); // System.out.println("Original sequence:"); // System.out.println(classVarSequenceBuilder.toString()); // System.out.println(); // // // evidences.add(evidence); // } // // return evidences.iterator(); // } public static void main(String[] arguments) throws IOException, ClassNotFoundException { // String file = "./networks/CajamarDBN.dbn"; // DynamicBayesianNetwork cajamarDBN = DynamicBayesianNetworkLoader.loadFromFile(file); // // DynamicMAPInference dynMAP = new DynamicMAPInference(); // dynMAP.setModel(cajamarDBN); // dynMAP.setNumberOfTimeSteps(6); // // cajamarDBN.getDynamicVariables().getListOfDynamicVariables().forEach(var -> System.out.println(var.getName())); // // System.out.println(cajamarDBN.toString()); // System.out.println("CausalOrder: " + cajamarDBN.getDynamicDAG().toString()); // // System.out.println(cajamarDBN.getDynamicDAG().toString()); // // Variable mapVariable = cajamarDBN.getDynamicVariables().getVariableByName("DEFAULT"); // dynMAP.setMAPvariable(mapVariable); // // dynMAP.computeDynamicMAPEvenModel(); // BayesianNetwork test = dynMAP.getStaticEvenModel(); // // System.out.println(test.getDAG().toString()); // System.out.println(cajamarDBN.toString()); // // dynMAP.runInference(); DynamicMAPInference dynMAP; Variable mapVariable; DynamicBayesianNetworkGenerator.setNumberOfContinuousVars(2); DynamicBayesianNetworkGenerator.setNumberOfDiscreteVars(10); DynamicBayesianNetworkGenerator.setNumberOfStates(2); DynamicBayesianNetworkGenerator.setNumberOfLinks(5); int nStatesClassVar = 2; DynamicBayesianNetwork dynamicBayesianNetwork = DynamicBayesianNetworkGenerator .generateDynamicNaiveBayes(new Random(50), nStatesClassVar, true); // // System.out.println("ORIGINAL DYNAMIC NETWORK:"); // // System.out.println(dynamicBayesianNetwork.toString()); // System.out.println(); dynMAP = new DynamicMAPInference(); dynMAP.setModel(dynamicBayesianNetwork); // INITIALIZE THE MODEL int nTimeSteps = 5; dynMAP.setNumberOfTimeSteps(nTimeSteps); int nMergedClassVars = 3; dynMAP.setNumberOfMergedClassVars(nMergedClassVars); mapVariable = dynamicBayesianNetwork.getDynamicVariables().getVariableByName("ClassVar"); dynMAP.setMAPvariable(mapVariable); System.out.println(dynamicBayesianNetwork.toString()); // System.out.println("ORIGINAL COND DISTRIBUTIONS MAP VARIABLE:"); // System.out.println(dynamicBayesianNetwork.getConditionalDistributionTime0(mapVariable).toString()); // System.out.println(dynamicBayesianNetwork.getConditionalDistributionTimeT(mapVariable).toString()); // System.out.println(); dynMAP.computeMergedClassVarModels(); // // /* // * GENERATE AN EVIDENCE FOR T=0,...,nTimeSteps-1 // */ // List<Variable> varsDynamicModel = dynamicBayesianNetwork.getDynamicVariables().getListOfDynamicVariables(); // // varsDynamicModel.forEach(var -> System.out.println("Var ID " + var.getVarID() + ": " + var.getName())); // int indexVarEvidence1 = 2; // int indexVarEvidence2 = 3; // int indexVarEvidence3 = 8; // Variable varEvidence1 = varsDynamicModel.get(indexVarEvidence1); // Variable varEvidence2 = varsDynamicModel.get(indexVarEvidence2); // Variable varEvidence3 = varsDynamicModel.get(indexVarEvidence3); // // List<Variable> varsEvidence = new ArrayList<>(3); // varsEvidence.add(0,varEvidence1); // varsEvidence.add(1,varEvidence2); // varsEvidence.add(2,varEvidence3); // // double varEvidenceValue; // // Random random = new Random(931234662); // // List<DynamicAssignment> evidence = new ArrayList<>(nTimeSteps); // // for (int t = 0; t < nTimeSteps; t++) { // HashMapDynamicAssignment dynAssignment = new HashMapDynamicAssignment(varsEvidence.size()); // // for (int i = 0; i < varsEvidence.size(); i++) { // // dynAssignment.setSequenceID(2343253); // dynAssignment.setTimeID(t); // Variable varEvidence = varsEvidence.get(i); // // if (varEvidence.isMultinomial()) { // varEvidenceValue = random.nextInt(varEvidence1.getNumberOfStates()); // } else { // varEvidenceValue = -5 + 10 * random.nextDouble(); // } // dynAssignment.setValue(varEvidence, varEvidenceValue); // } // evidence.add(dynAssignment); // } // // dynMAP.setEvidence(evidence); dynMAP.runInference(); // // System.out.println("\nMAP sequence: " + Arrays.toString(dynMAP.getMAPsequence()) + " with probability " + dynMAP.getMAPestimateProbability()); // //// Iterator<List<DynamicAssignment>> iterator = DynamicMAPInference.generateEvidence(dynamicBayesianNetwork,mapVariable.getName(),5,nTimeSteps,0.50,3634); //// while(iterator.hasNext()) { //// List<DynamicAssignment> evidence1 = iterator.next(); //// evidence1.forEach(assign -> System.out.println(assign.outputString())); //// } // int nStates = 3; // int nRepets = 5; // // for (int m = 0; m < Math.pow(nStates,nRepets); m++) { // String m_base_nStates = Integer.toString(Integer.parseInt(Integer.toString(m), 10), nStates); // m_base_nStates = StringUtils.leftPad(m_base_nStates, nRepets, '0'); // System.out.println(m_base_nStates); // //System.out.println(String.format("%0" + nRepets + "d",m)); // } } }