Exemple #1
0
  /**
   * Sets the expression which should be evaluated when calculating new values for the given
   * parameter. These values are used to initialize the freeParameters.
   *
   * @param parameter The parameter whose initial value needs to be computed.
   * @param expressionString The formula for picking initial values.
   * @throws ParseException If the formula cannot be parsed or contains variable names.
   */
  public void setParameterEstimationInitializationExpression(
      String startsWith, String parameter, String expressionString) throws ParseException {
    if (parameter == null) {
      throw new NullPointerException("Parameter was null.");
    }

    if (startsWith == null) {
      throw new NullPointerException("StartsWith expression was null.");
    }

    if (startsWith.contains(" ")) {
      throw new IllegalArgumentException("StartsWith expression contains spaces.");
    }

    if (expressionString == null) {
      throw new NullPointerException("Expression string was null.");
    }

    // Parse the expression. This could throw an ParseException, but that exception needs to handed
    // up the
    // chain, because the interface will need it.
    ExpressionParser parser = new ExpressionParser();
    Expression expression = parser.parseExpression(expressionString);
    List<String> parameterNames = parser.getParameters();

    if (parameterNames.size() > 0) {
      throw new IllegalArgumentException(
          "Initial distribution may not " + "contain parameters: " + expressionString);
    }

    parameterEstimationInitializationExpressions.put(parameter, expression);
    parameterEstimationInitializationExpressionStrings.put(parameter, expressionString);
    startsWithParametersTemplates.put(startsWith, expressionString);
  }
  // Formulas that should and should not fail.
  @Test
  public void test4() {
    Map<String, Integer> formulasToOffsets = new LinkedHashMap<String, Integer>();

    // -1 means it should parse.
    formulasToOffsets.put("X X", 2);
    formulasToOffsets.put("b11 b11", 4);
    formulasToOffsets.put("X + Y ++", 7);
    formulasToOffsets.put("b1*X1 *+ b2 * X2 +", 17);
    formulasToOffsets.put("cos()", 0);
    formulasToOffsets.put("2..3 * X", 0);
    formulasToOffsets.put("+X1", -1);
    formulasToOffsets.put("-X1", -1);
    formulasToOffsets.put("A / B", -1);
    formulasToOffsets.put("b1*X1 +@**!! b2 * X2", 7);
    formulasToOffsets.put("X7", 0);

    List<String> otherNodes = new ArrayList<String>();
    otherNodes.add("X7");

    ExpressionParser parser =
        new ExpressionParser(otherNodes, ExpressionParser.RestrictionType.MAY_NOT_CONTAIN);

    for (String formula : formulasToOffsets.keySet()) {
      try {
        parser.parseExpression(formula);
        assertEquals(formulasToOffsets.get(formula).intValue(), -1);
      } catch (ParseException e) {
        int offset = e.getErrorOffset();
        assertEquals(formulasToOffsets.get(formula).intValue(), offset);
      }
    }
  }
  public void test2() {
    final Map<String, Double> values = new HashMap<String, Double>();

    values.put("b11", 1.0);
    values.put("X1", 2.0);
    values.put("X2", 3.0);
    values.put("B22", 4.0);
    values.put("B12", 5.0);
    values.put("X4", 6.0);
    values.put("b13", 7.0);
    values.put("X5", 8.0);
    values.put("b10", 9.0);
    values.put("X", 10.0);
    values.put("Y", 11.0);
    values.put("Z", 12.0);
    values.put("W", 13.0);
    values.put("T", 14.0);
    values.put("R", 15.0);
    values.put("s2", 0.0);
    values.put("s3", 1.0);

    Context context =
        new Context() {
          public Double getValue(String var) {
            return values.get(var);
          }
        };

    List<String> formulas = new ArrayList<String>();
    //
    formulas.add("ChiSquare(s3)");
    formulas.add("Gamma(1, 1)");
    formulas.add("Beta(3, 5)");
    formulas.add("Poisson(5)");
    formulas.add("Indicator(0.3)");
    formulas.add("ExponentialPower(3)");
    formulas.add("exp(Normal(s2, s3))"); // Log normal
    formulas.add("Normal(0, s3)");
    formulas.add("abs(Normal(s2, s3) ^ 3)"); // Gaussian Power
    formulas.add("Discrete(3, 1, 5)");
    formulas.add("0.3 * Normal(-2.0e2, 0.5) + 0.7 * Normal(2.0, 0.5)"); // Mixture of Gaussians
    formulas.add("StudentT(s3)");
    formulas.add("s3"); // Single value.
    formulas.add("Hyperbolic(5, 3)");
    formulas.add("Uniform(s2, s3)");
    formulas.add("VonMises(s3)");
    formulas.add("Split(0, 1, 5, 6)");
    formulas.add("Mixture(0.5, N(-2, 0.5), 0.5, N(2, 0.5))");
    //
    ExpressionParser parser = new ExpressionParser();

    try {
      for (String formula : formulas) {
        Expression expression = parser.parseExpression(formula);
        double value = expression.evaluate(context);
      }
    } catch (ParseException e) {
      e.printStackTrace();
    }
  }
Exemple #4
0
  public void setErrorsTemplate(String errorsTemplate) throws ParseException {
    if (errorsTemplate == null) {
      throw new NullPointerException();
    }

    // Test to make sure it's parsable.
    ExpressionParser parser = new ExpressionParser();
    parser.parseExpression(errorsTemplate);

    this.errorsTemplate = errorsTemplate;
  }
Exemple #5
0
  public void setParametersEstimationInitializationTemplate(String parametersTemplate)
      throws ParseException {
    if (parametersTemplate == null) {
      throw new NullPointerException();
    }

    // Test to make sure it's parsable.
    ExpressionParser parser = new ExpressionParser();
    parser.parseExpression(parametersTemplate);

    this.parametersEstimationInitializationTemplate = parametersTemplate;
  }
  // Test distribution means.
  @Test
  public void test5() {
    final Map<String, Double> values = new HashMap<String, Double>();

    Context context =
        new Context() {
          public Double getValue(String var) {
            return values.get(var);
          }
        };

    Map<String, Double> formulas = new LinkedHashMap<String, Double>();

    formulas.put("ChiSquare(1)", 1.0);
    formulas.put("Gamma(2, .5)", 1.0);
    formulas.put("Beta(1, 2)", 0.33);
    formulas.put("Normal(2, 3)", 2.0);
    formulas.put("N(2, 3)", 2.0);
    formulas.put("StudentT(5)", 0.0);
    formulas.put("U(0, 1)", 0.5);
    formulas.put("Uniform(0, 1)", 0.5);
    formulas.put("Split(0, 1, 5, 6)", 3.0);

    ExpressionParser parser = new ExpressionParser();

    try {
      for (String formula : formulas.keySet()) {
        Expression expression = parser.parseExpression(formula);

        double sum = 0.0;
        int sampleSize = 10000;

        for (int i = 0; i < sampleSize; i++) {
          double value = expression.evaluate(context);
          sum += value;
        }

        double mean = sum / sampleSize;

        assertEquals(formulas.get(formula), mean, 0.1);
      }
    } catch (ParseException e) {
      e.printStackTrace();
    }
  }
Exemple #7
0
  public void setParametersTemplate(String parametersTemplate) throws ParseException {
    if (parametersTemplate == null) {
      throw new NullPointerException();
    }

    // Test to make sure it's parsable.
    ExpressionParser parser = new ExpressionParser();
    Expression expression = parser.parseExpression(parametersTemplate);
    List<String> parameterNames = parser.getParameters();

    if (!parameterNames.isEmpty()) {
      throw new IllegalArgumentException(
          "Initial distribution for a parameter may not "
              + "contain parameters: "
              + expression.toString());
    }

    this.parametersTemplate = parametersTemplate;
  }
Exemple #8
0
  public void setStartsWithParametersTemplate(String startsWith, String parametersTemplate)
      throws ParseException {
    if (startsWith == null || startsWith.isEmpty()) {
      return;
    }

    if (parametersTemplate == null) {
      throw new NullPointerException();
    }

    // Test to make sure it's parsable.
    ExpressionParser parser = new ExpressionParser();
    parser.parseExpression(parametersTemplate);

    if (startsWith.contains(" ")) {
      throw new IllegalArgumentException("Starts with string contains spaces.");
    }

    //        this.parametersTemplate = parametersTemplate;

    this.startsWithParametersTemplates.put(startsWith, parametersTemplate);
  }
Exemple #9
0
  public void setNodeExpression(Node node, String expressionString) throws ParseException {
    if (node == null) {
      throw new NullPointerException("Node was null.");
    }

    if (expressionString == null) {
      //            return;
      throw new NullPointerException("Expression string was null.");
    }

    // Parse the expression. This could throw an ParseException, but that exception needs to handed
    // up the
    // chain, because the interface will need it.
    ExpressionParser parser = new ExpressionParser();
    Expression expression = parser.parseExpression(expressionString);
    List<String> parameterNames = parser.getParameters();

    // Make a list of parent names.
    List<Node> parents = this.graph.getParents(node);
    List<String> parentNames = new LinkedList<>();

    for (Node parent : parents) {
      parentNames.add(parent.getName());
    }

    //        List<String> _params = new ArrayList<String>(parameterNames);
    //        _params.retainAll(variableNames);
    //        _params.removeAll(parentNames);
    //
    //        if (!_params.isEmpty()) {
    //            throw new IllegalArgumentException("Conditioning on a variable other than the
    // parents: " + node);
    //        }

    // Make a list of parameter names, by removing from the parser's list of freeParameters any that
    // correspond
    // to parent variables. If there are any variable names (including error terms) that are not
    // among the list of
    // parents, that's a time to throw an exception. We must respect the graph! (We will not
    // complain if any parents
    // are missing.)
    parameterNames.removeAll(variableNames);

    for (Node variable : nodes) {
      if (parameterNames.contains(variable.getName())) {
        parameterNames.remove(variable.getName());
        //                throw new IllegalArgumentException("The list of parameter names may not
        // include variables: " + variable.getName());
      }
    }

    // Remove old parameter references.
    List<String> parametersToRemove = new LinkedList<>();

    for (String parameter : this.referencedParameters.keySet()) {
      Set<Node> nodes = this.referencedParameters.get(parameter);

      if (nodes.contains(node)) {
        nodes.remove(node);
      }

      if (nodes.isEmpty()) {
        parametersToRemove.add(parameter);
      }
    }

    for (String parameter : parametersToRemove) {
      this.referencedParameters.remove(parameter);
      this.parameterExpressions.remove(parameter);
      this.parameterExpressionStrings.remove(parameter);
      this.parameterEstimationInitializationExpressions.remove(parameter);
      this.parameterEstimationInitializationExpressionStrings.remove(parameter);
    }

    // Add new parameter references.
    for (String parameter : parameterNames) {
      if (this.referencedParameters.get(parameter) == null) {
        this.referencedParameters.put(parameter, new HashSet<Node>());
      }

      Set<Node> nodes = this.referencedParameters.get(parameter);
      nodes.add(node);

      setSuitableParameterDistribution(parameter);
    }

    // Remove old node references.
    List<Node> nodesToRemove = new LinkedList<>();

    for (Node _node : this.referencedNodes.keySet()) {
      Set<Node> nodes = this.referencedNodes.get(_node);

      if (nodes.contains(node)) {
        nodes.remove(node);
      }

      if (nodes.isEmpty()) {
        nodesToRemove.add(_node);
      }
    }

    for (Node _node : nodesToRemove) {
      this.referencedNodes.remove(_node);
    }

    // Add new freeParameters.
    for (String variableString : variableNames) {
      Node _node = getNode(variableString);

      if (this.referencedNodes.get(_node) == null) {
        this.referencedNodes.put(_node, new HashSet<Node>());
      }

      for (String s : parentNames) {
        if (s.equals(variableString)) {
          Set<Node> nodes = this.referencedNodes.get(_node);
          nodes.add(node);
        }
      }
    }

    // Finally, save the parsed expression and the original string that the user entered. No need to
    // annoy
    // the user by changing spacing.
    nodeExpressions.put(node, expression);
    nodeExpressionStrings.put(node, expressionString);
  }
  @Test
  public void test1() {
    final Map<String, Double> values = new HashMap<String, Double>();

    values.put("b11", 1.0);
    values.put("X1", 2.0);
    values.put("X2", 3.0);
    values.put("B22", 4.0);
    values.put("B12", 5.0);
    values.put("X4", 6.0);
    values.put("b13", 7.0);
    values.put("X5", 8.0);
    values.put("b10", 9.0);
    values.put("X", 10.0);
    values.put("Y", 11.0);
    values.put("Z", 12.0);
    values.put("W", 13.0);
    values.put("T", 14.0);
    values.put("R", 15.0);

    Context context =
        new Context() {
          public Double getValue(String var) {
            return values.get(var);
          }
        };

    Map<String, Double> formulasToEvaluations = new HashMap<String, Double>();

    formulasToEvaluations.put("0", 0.0);
    formulasToEvaluations.put("b11*X1 + sin(X2) + B22*X2 + B12*X4+b13*X5", 100.14);
    formulasToEvaluations.put("X5*X4*X4", 288.0);
    formulasToEvaluations.put("sin(b10*X1)", -0.75097);
    formulasToEvaluations.put("((X + ((Y * (Z ^ W)) * T)) + R)", 16476953628377113.0);
    formulasToEvaluations.put("X + Y * Z ^ W * T + R", 16476953628377113.0);
    formulasToEvaluations.put("pow(2, 5)", 32.0);
    formulasToEvaluations.put("2^5", 32.0);
    formulasToEvaluations.put("exp(1)", 2.718);
    formulasToEvaluations.put("sqrt(2)", 1.414);
    formulasToEvaluations.put("cos(0)", 1.0);
    formulasToEvaluations.put("cos(3.14/2)", 0.0);
    formulasToEvaluations.put("sin(0)", 0.0);
    formulasToEvaluations.put("sin(3.14/2)", 1.0);
    formulasToEvaluations.put("tan(1)", 1.56);
    formulasToEvaluations.put("cosh(1)", 1.54);
    formulasToEvaluations.put("sinh(1)", 1.18);
    formulasToEvaluations.put("tanh(1)", 0.76);
    formulasToEvaluations.put("acos(1)", 0.0);
    formulasToEvaluations.put("asin(1)", 1.57);
    formulasToEvaluations.put("atan(1)", 0.78);
    formulasToEvaluations.put("ln(1)", 0.0);
    formulasToEvaluations.put("log10(10)", 1.0);
    formulasToEvaluations.put("ceil(2.5)", 3.0);
    formulasToEvaluations.put("floor(2.5)", 2.0);
    formulasToEvaluations.put("abs(-5)", 5.0);
    formulasToEvaluations.put("max(2, 5, 3, 1, 10, -3)", 10.0);
    formulasToEvaluations.put("min(2, 5, 3, 1, 10, -3)", -3.0);

    // Logical.
    formulasToEvaluations.put("AND(1, 1)", 1.0);
    formulasToEvaluations.put("AND(1, 0)", 0.0);
    formulasToEvaluations.put("AND(0, 1)", 0.0);
    formulasToEvaluations.put("AND(0, 0)", 0.0);
    formulasToEvaluations.put("AND(0, 0.5)", 0.0);

    formulasToEvaluations.put("1 AND 1", 1.0);

    formulasToEvaluations.put("OR(1, 1)", 1.0);
    formulasToEvaluations.put("OR(1, 0)", 1.0);
    formulasToEvaluations.put("OR(0, 1)", 1.0);
    formulasToEvaluations.put("OR(0, 0)", 0.0);
    formulasToEvaluations.put("OR(0, 0.5)", 0.0);

    formulasToEvaluations.put("1 OR 1", 1.0);

    formulasToEvaluations.put("XOR(1, 1)", 0.0);
    formulasToEvaluations.put("XOR(1, 0)", 1.0);
    formulasToEvaluations.put("XOR(0, 1)", 1.0);
    formulasToEvaluations.put("XOR(0, 0)", 0.0);
    formulasToEvaluations.put("XOR(0, 0.5)", 0.0);

    formulasToEvaluations.put("1 XOR 1", 0.0);

    formulasToEvaluations.put("1 AND 0 OR 1 XOR 1 + 1", 1.0);

    formulasToEvaluations.put("1 < 2", 1.0);
    formulasToEvaluations.put("1 < 0", 0.0);
    formulasToEvaluations.put("1 < 1", 0.0);
    formulasToEvaluations.put("1 <= 2", 1.0);
    formulasToEvaluations.put("1 <= 1", 1.0);
    formulasToEvaluations.put("1 <= -1", 0.0);
    formulasToEvaluations.put("1 = 2", 0.0);
    formulasToEvaluations.put("1 = 1", 1.0);
    formulasToEvaluations.put("1 = -1", 0.0);
    formulasToEvaluations.put("1 > 2", 0.0);
    formulasToEvaluations.put("1 > 1", 0.0);
    formulasToEvaluations.put("1 > -1", 1.0);
    formulasToEvaluations.put("1 >= 2", 0.0);
    formulasToEvaluations.put("1 >= 1", 1.0);
    formulasToEvaluations.put("1 >= -1", 1.0);
    formulasToEvaluations.put("IF(1 > 2, 1, 2)", 2.0);
    formulasToEvaluations.put("IF(1 < 2, 1, 2)", 1.0);
    formulasToEvaluations.put("IF(1 < 2 AND 3 < 4, 1, 2)", 1.0);

    ExpressionParser parser = new ExpressionParser();

    try {
      for (String formula : formulasToEvaluations.keySet()) {
        Expression expression = parser.parseExpression(formula);

        double value = expression.evaluate(context);

        assertEquals(formulasToEvaluations.get(formula), value, 0.01);
      }
    } catch (ParseException e) {
      e.printStackTrace();
    }
  }