use of edu.cmu.tetrad.calculator.parser.ExpressionParser in project tetrad by cmu-phil.
the class TemplateExpander method expandTemplate.
/**
* Returns the expanded template, which needs to be checked to make sure it can be used. Try setting it as the
* expression for the node or freeParameters you wish to use it for.
*
* @param template A template formula, which includes the functions TSUM and TPROD, which are not nestable,
* and NEW. TSUM(f($)) = f(X1) + f(X2) + .... TPROD(f($)) = f(X1) * f(X2) * .... NEW(a) = a new parameter with
* name beginning with a, such as a3, if a1 and a2 have already been used.
* @param semPm The generalized SEM PM for which this is intended. This is needed in order to figure out what
* the parents of <code>node</code> are, and in order to determine new freeParameters. May be null. If it is null,
* then the template may not contain any TSUM, TPROD, or NEW expressions.
* @param node The node this is intended for, if there is one. Like I said, the parents of a node need to
* be calculated. This may be null. If it is null, the template may not contain any TSUM or TPROD expressions
* --i.e. any TSUM or TPROD expressions--but it may contain NEW expressions. If semPm is null, then node must
* be null as well, since the node is relative to a generalized SEM PM.
* @return The expanded template.
* @throws ParseException for any of a variety of reasons. It may be that the original template cannot be parsed.
* It may be that the expanded formula without the error term added cannot be parsed. It may be that the
* expanded formula contains a "$", which means there was a "$" that was not properly embedded in a TSUM or
* TPROD. It may be that a TSUM or TPROD was embedded inside another TSUM or TPROD.
*/
public String expandTemplate(String template, GeneralizedSemPm semPm, Node node) throws ParseException {
ExpressionParser parser = new ExpressionParser();
List<String> usedNames;
if (semPm == null && template.contains("$")) {
throw new IllegalArgumentException("If semPm is null, the template may not contain any parameters or " + "$ expressions.");
}
if (semPm == null && node != null) {
throw new IllegalArgumentException("If semPm is not specified, then node may not be specified either. The" + " node must be for a specific generalized SEM PM.");
}
// Must make sure the original template is parseable.
parser.parseExpression(template);
usedNames = parser.getParameters();
template = replaceTemplateSums(semPm, template, node);
template = replaceTemplateProducts(semPm, template, node);
template = replaceNewParameters(semPm, template, usedNames);
template = replaceError(semPm, template, node);
Node error = null;
if (node != null) {
error = semPm.getErrorNode(node);
}
template = template.trim();
if (template.equals("")) {
template = "";
}
if (!"".equals(template)) {
// This will throw an exception if the expansion without the error term added is not parseable.
try {
parser.parseExpression(template);
} catch (ParseException e) {
template = "";
}
if (node == null && !parser.getParameters().isEmpty()) {
throw new IllegalArgumentException("If node is null, the template may not contain any $ expressions.");
}
}
if (node != null && node != error && !template.contains(error.getName())) {
if (template.trim().equals("")) {
template = error.getName();
} else {
template += " + " + error.getName();
}
}
if (template.contains("$")) {
throw new ParseException("Template contains a $ not inside TSUM or TPROD.", template.indexOf("$"));
}
return template;
}
use of edu.cmu.tetrad.calculator.parser.ExpressionParser in project tetrad by cmu-phil.
the class TestExpressionParser method test2.
public void test2() {
final Map<String, Double> values = new HashMap<>();
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<>();
//
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)");
// Log normal
formulas.add("exp(Normal(s2, s3))");
formulas.add("Normal(0, s3)");
// Gaussian Power
formulas.add("abs(Normal(s2, s3) ^ 3)");
formulas.add("Discrete(3, 1, 5)");
// Mixture of Gaussians
formulas.add("0.3 * Normal(-2.0e2, 0.5) + 0.7 * Normal(2.0, 0.5)");
formulas.add("StudentT(s3)");
// Single value.
formulas.add("s3");
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();
}
}
use of edu.cmu.tetrad.calculator.parser.ExpressionParser in project tetrad by cmu-phil.
the class TestExpressionParser method test1.
@Test
public void test1() {
final Map<String, Double> values = new HashMap<>();
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<>();
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();
}
}
use of edu.cmu.tetrad.calculator.parser.ExpressionParser in project tetrad by cmu-phil.
the class TestParser method testVariableRestriction.
/**
* Tests that undefined variables aren't allowed.
*/
@Test
public void testVariableRestriction() {
ExpressionParser parser = new ExpressionParser(Arrays.asList("x", "y", "z"), ExpressionParser.RestrictionType.MAY_ONLY_CONTAIN);
parseInvalid(parser, "x + x1");
}
use of edu.cmu.tetrad.calculator.parser.ExpressionParser in project tetrad by cmu-phil.
the class TestParser method testInvalidExpressions.
/**
* Tests misc invalid expressions.
*/
@Test
public void testInvalidExpressions() {
ExpressionParser parser = new ExpressionParser();
parseInvalid(parser, "(1 + 3))");
parseInvalid(parser, "(1 + (4 * 5) + sqrt(5)");
parseInvalid(parser, "1+");
parseInvalid(parser, "113#");
}
Aggregations