Пример #1
0
  /**
   * Collect all CalculationNodes on a path from any StateNode that is changed (as indicated by
   * m_changedStateNodeCode) to the posterior. Return the list in partial order as determined by the
   * BEASTObjects input relations.
   */
  private List<CalculationNode> calculateCalcNodePath() throws Exception {
    final List<CalculationNode> calcNodes = new ArrayList<>();
    //    	for (int i = 0; i < stateNode.length; i++) {
    //    		if (m_changedStateNodeCode.get(i)) {
    for (int k = 0; k < nrOfChangedStateNodes; k++) {
      int i = changeStateNodes[k];
      // go grab the path to the Runnable
      // first the outputs of the StateNodes that is changed
      boolean progress = false;
      for (CalculationNode node : stateNodeOutputs[i]) {
        if (!calcNodes.contains(node)) {
          calcNodes.add(node);
          progress = true;
        }
      }
      // next the path following the outputs
      while (progress) {
        progress = false;
        // loop over beastObjects till no more beastObjects can be added
        // efficiency is no issue here, assuming the graph remains
        // constant
        for (int calcNodeIndex = 0; calcNodeIndex < calcNodes.size(); calcNodeIndex++) {
          CalculationNode node = calcNodes.get(calcNodeIndex);
          for (BEASTInterface output : outputMap.get(node)) {
            if (output instanceof CalculationNode) {
              final CalculationNode calcNode = (CalculationNode) output;
              if (!calcNodes.contains(calcNode)) {
                calcNodes.add(calcNode);
                progress = true;
              }
            } else {
              throw new RuntimeException(
                  "DEVELOPER ERROR: found a"
                      + " non-CalculatioNode ("
                      + output.getClass().getName()
                      + ") on path between StateNode and Runnable");
            }
          }
        }
      }
      //    		}
    }

    // put calc nodes in partial order
    for (int i = 0; i < calcNodes.size(); i++) {
      CalculationNode node = calcNodes.get(i);
      List<BEASTInterface> inputList = node.listActiveBEASTObjects();
      for (int j = calcNodes.size() - 1; j > i; j--) {
        if (inputList.contains(calcNodes.get(j))) {
          // swap
          final CalculationNode node2 = calcNodes.get(j);
          calcNodes.set(j, node);
          calcNodes.set(i, node2);
          j = 0;
          i--;
        }
      }
    }

    return calcNodes;
  } // calculateCalcNodePath
Пример #2
0
 /**
  * Sets the posterior, needed to calculate paths of CalculationNode that need
  * store/restore/requireCalculation checks. As a side effect, outputs for every beastObject in the
  * model are calculated. NB the output map only contains outputs on a path to the posterior
  * BEASTObject!
  */
 @SuppressWarnings("unchecked")
 public void setPosterior(BEASTObject posterior) throws Exception {
   // first, calculate output map that maps BEASTObjects on a path
   // to the posterior to the list of output BEASTObjects. Strictly
   // speaking, this is a bit of overkill, since only
   // CalculationNodes need to be taken in account, but for
   // debugging purposes (developer forgot to derive from CalculationNode)
   // we keep track of the lot.
   outputMap = new HashMap<>();
   outputMap.put(posterior, new ArrayList<>());
   boolean progress = true;
   List<BEASTInterface> beastObjects = new ArrayList<>();
   beastObjects.add(posterior);
   while (progress) {
     progress = false;
     // loop over plug-ins, till no more plug-ins can be added
     // efficiency is no issue here
     for (int i = 0; i < beastObjects.size(); i++) {
       BEASTInterface beastObject = beastObjects.get(i);
       try {
         for (BEASTInterface inputBEASTObject : beastObject.listActiveBEASTObjects()) {
           if (!outputMap.containsKey(inputBEASTObject)) {
             outputMap.put(inputBEASTObject, new ArrayList<>());
             beastObjects.add(inputBEASTObject);
             progress = true;
           }
           if (!outputMap.get(inputBEASTObject).contains(beastObject)) {
             outputMap.get(inputBEASTObject).add(beastObject);
             progress = true;
           }
         }
       } catch (Exception e) {
         e.printStackTrace();
       }
     }
   }
   // Set of array of StateNode outputs. Since the StateNodes have a potential
   // to be changing objects (when store/restore is applied) it is necessary
   // to use another method to find the outputs, an array in this case.
   stateNodeOutputs = new List[stateNode.length];
   for (int i = 0; i < stateNode.length; i++) {
     stateNodeOutputs[i] = new ArrayList<>();
     if (outputMap.containsKey(stateNode[i])) {
       for (BEASTInterface beastObject : outputMap.get(stateNode[i])) {
         if (beastObject instanceof CalculationNode) {
           stateNodeOutputs[i].add((CalculationNode) beastObject);
         } else {
           throw new RuntimeException(
               "DEVELOPER ERROR: output of StateNode ("
                   + stateNode[i].getID()
                   + ") should be a CalculationNode, but "
                   + beastObject.getClass().getName()
                   + " is not.");
         }
       }
     } else {
       Log.warning.println(
           "\nWARNING: StateNode ("
               + stateNode[i].getID()
               + ") found that has no effect on posterior!\n");
     }
   }
 } // setPosterior