From 611d473b3d6696185a49cf4b9eb4e1ebfbceed24 Mon Sep 17 00:00:00 2001 From: Logan Drescher Date: Mon, 9 Mar 2026 17:46:17 -0400 Subject: [PATCH 1/2] Added NumExprCapability --- .../java/cbit/vcell/parser/ASTAndNode.java | 8 ++ .../java/cbit/vcell/parser/ASTFloatNode.java | 6 +- .../java/cbit/vcell/parser/ASTFuncNode.java | 105 ++++++++++++++++-- .../java/cbit/vcell/parser/ASTMultNode.java | 26 +++-- .../java/cbit/vcell/parser/ASTNotNode.java | 6 +- .../java/cbit/vcell/parser/ASTOrNode.java | 8 ++ .../java/cbit/vcell/parser/ASTPowerNode.java | 2 +- .../java/cbit/vcell/parser/Expression.java | 4 + .../java/cbit/vcell/parser/SimpleNode.java | 1 + .../cbit/vcell/parser/ExpressionTest.java | 15 +++ 10 files changed, 162 insertions(+), 19 deletions(-) diff --git a/vcell-math/src/main/java/cbit/vcell/parser/ASTAndNode.java b/vcell-math/src/main/java/cbit/vcell/parser/ASTAndNode.java index 6d49116761..fe891b495b 100644 --- a/vcell-math/src/main/java/cbit/vcell/parser/ASTAndNode.java +++ b/vcell-math/src/main/java/cbit/vcell/parser/ASTAndNode.java @@ -178,6 +178,14 @@ public String infixString(int lang) buffer.append(jjtGetChild(i).infixString(lang)); } buffer.append("))"); + }else if (lang == LANGUAGE_NUM_EXPR) { + int numChildren = jjtGetNumChildren(); + for (int i=0;i0) buffer.append(" & "); + buffer.append("(0.0!="); + buffer.append(jjtGetChild(i).infixString(lang)); + buffer.append(")"); + } }else{ for (int i=0;i0) { diff --git a/vcell-math/src/main/java/cbit/vcell/parser/ASTFloatNode.java b/vcell-math/src/main/java/cbit/vcell/parser/ASTFloatNode.java index e9e81822d3..b05f57091a 100644 --- a/vcell-math/src/main/java/cbit/vcell/parser/ASTFloatNode.java +++ b/vcell-math/src/main/java/cbit/vcell/parser/ASTFloatNode.java @@ -146,7 +146,11 @@ public String infixString(int lang) if (value == Double.POSITIVE_INFINITY) return "float('inf')"; if (value == Double.NEGATIVE_INFINITY) return "float('-inf')"; return value.toString(); - } else { + } else if (lang == LANGUAGE_NUM_EXPR) { + if (value == Double.POSITIVE_INFINITY) return "inf"; + if (value == Double.NEGATIVE_INFINITY) return "-inf"; + return value.toString(); + } else { return value.toString(); } } diff --git a/vcell-math/src/main/java/cbit/vcell/parser/ASTFuncNode.java b/vcell-math/src/main/java/cbit/vcell/parser/ASTFuncNode.java index 85702ee55a..61c030129b 100644 --- a/vcell-math/src/main/java/cbit/vcell/parser/ASTFuncNode.java +++ b/vcell-math/src/main/java/cbit/vcell/parser/ASTFuncNode.java @@ -134,6 +134,29 @@ public final String getPythonTranslation() { default -> "math." + getName(); }; } + + public final String getNumExprTranslation() { + return switch (this){ + case USERDEFINED -> throw new IllegalArgumentException("User defined functions have nothing to do with standard python names."); + case ABS -> "abs"; + case MAX -> "maximum"; + case MIN -> "minimum"; + case CSC -> "1.0/" + SIN.getNumExprTranslation(); + case COT -> "1.0/" + TAN.getNumExprTranslation(); + case SEC -> "1.0/" + COS.getNumExprTranslation(); + case ASIN -> "arcsin"; + case ACOS -> "arccos"; + case ATAN -> "arctan"; + case ATAN2 -> "arctan2"; + case CSCH -> "1.0/" + SINH.getNumExprTranslation(); + case COTH -> "1.0/" + TANH.getNumExprTranslation(); + case SECH -> "1.0/" + COSH.getNumExprTranslation(); + case LOGBASE -> "1.0/" + LOG.getNumExprTranslation(); + case ACSC, ACOT, ASEC, ACSCH, ACOTH, ASECH, FACTORIAL -> throw new UnsupportedOperationException("Python has no equivalent name."); + default -> getName(); + }; + } + public final String getHtmlDescription() { return htmlDescription; } @@ -2389,12 +2412,28 @@ String getMathMLName() { } String getPythonName(){ - if (funcType == FunctionType.USERDEFINED){ + return getPythonName(funcType); +} + +// This function is used when we need to "override" `funcType` to get the correct answer +private String getPythonName(ASTFuncNode.FunctionType functionType){ + if (functionType == FunctionType.USERDEFINED){ return funcName; } - return funcType.getPythonTranslation(); + return functionType.getPythonTranslation(); } +String getNumExprName(){ + return getNumExprName(funcType); +} + +// This function is used when we need to "override" `funcType` to get the correct answer +private String getNumExprName(ASTFuncNode.FunctionType functionType){ + if (functionType == FunctionType.USERDEFINED){ + return funcName; + } + return functionType.getNumExprTranslation(); +} /** * Insert the method's description here. @@ -2455,7 +2494,7 @@ public String infixString(int lang) { buffer.append(","); buffer.append("((double)(" + jjtGetChild(1).infixString(lang) + "))"); buffer.append(")"); - } else if (lang == LANGUAGE_PYTHON) { + } else if (lang == LANGUAGE_PYTHON || lang == LANGUAGE_NUM_EXPR) { buffer.append("(("); buffer.append(jjtGetChild(0).infixString(lang)); buffer.append(")**("); @@ -2485,19 +2524,26 @@ public String infixString(int lang) { buffer.append(jjtGetChild(0).infixString(lang)); buffer.append("))"); break; + } else if (lang == LANGUAGE_NUM_EXPR){ + // Need parenthesis to encapsulate the "1.0/x" operation + buffer.append("("); + buffer.append(getNumExprName()); + buffer.append("("); + buffer.append(jjtGetChild(0).infixString(lang)); + buffer.append("))"); + break; } // DO NOT PUT A "BREAK" HERE! We want to "fall through" to default! } case ACSC: - case ACOT: case ASEC: case ACSCH: case ACOTH: case ASECH:{ - if (lang == LANGUAGE_PYTHON){ // Need parenthesis to encapsulate the "1.0/x" operation + if (lang == LANGUAGE_PYTHON){ + // Need parenthesis to encapsulate the "1.0/x" operation Map inversionMap = Map.of( FunctionType.ACSC, FunctionType.ASIN, - FunctionType.ACOT, FunctionType.ATAN, FunctionType.ASEC, FunctionType.ACOS, FunctionType.ACSCH, FunctionType.ASINH, FunctionType.ACOTH, FunctionType.ATANH, @@ -2505,7 +2551,23 @@ public String infixString(int lang) { ); FunctionType inversionType = inversionMap.get(funcType); buffer.append("("); - buffer.append(getPythonName()); + buffer.append(getPythonName(inversionType)); + buffer.append("(1.0/("); + buffer.append(jjtGetChild(0).infixString(lang)); + buffer.append(")))"); + break; + } else if (lang == LANGUAGE_NUM_EXPR){ + // Need parenthesis to encapsulate the "1.0/x" operation + Map inversionMap = Map.of( + FunctionType.ACSC, FunctionType.ASIN, + FunctionType.ASEC, FunctionType.ACOS, + FunctionType.ACSCH, FunctionType.ASINH, + FunctionType.ACOTH, FunctionType.ATANH, + FunctionType.ASECH, FunctionType.ACOSH + ); + FunctionType inversionType = inversionMap.get(funcType); + buffer.append("("); + buffer.append(getNumExprName(inversionType)); buffer.append("(1.0/("); buffer.append(jjtGetChild(0).infixString(lang)); buffer.append(")))"); @@ -2513,6 +2575,23 @@ public String infixString(int lang) { } // DO NOT PUT A "BREAK" HERE! We want to "fall through" to default! } + case ACOT:{ + if (lang == LANGUAGE_PYTHON){ + buffer.append(String.format("((%s/2.0) - ", Math.PI)); + buffer.append(getPythonName(FunctionType.ATAN)); + buffer.append("("); + buffer.append(jjtGetChild(0).infixString(lang)); + buffer.append("))"); + break; + } else if (lang == LANGUAGE_NUM_EXPR){ + buffer.append(String.format("((%s/2.0) - ", Math.PI)); + buffer.append(getNumExprName(FunctionType.ATAN)); + buffer.append("("); + buffer.append(jjtGetChild(0).infixString(lang)); + buffer.append("))"); + break; + } + } case FACTORIAL: if (lang == LANGUAGE_PYTHON){ String name = getPythonName(); @@ -2525,8 +2604,7 @@ public String infixString(int lang) { } // DO NOT PUT A "BREAK" HERE! We want to "fall through" to default! default:{ - boolean needPythonicVersionOfName = lang == LANGUAGE_PYTHON && !funcType.equals(FunctionType.USERDEFINED); - String name = needPythonicVersionOfName ? getPythonName(): getName(); + String name = getAppropriateName(lang); buffer.append(name + "("); for (int i=0;i0) buffer.append(", "); @@ -2545,6 +2623,15 @@ public String infixString(int lang) { } +private String getAppropriateName(int language){ + if (FunctionType.USERDEFINED.equals(funcType)) return getName(); + return switch (language){ + case LANGUAGE_PYTHON -> getPythonName(); + case LANGUAGE_NUM_EXPR -> getNumExprName(); + default -> getName(); + }; +} + /** * Insert the method's description here. * Creation date: (6/20/01 11:04:41 AM) diff --git a/vcell-math/src/main/java/cbit/vcell/parser/ASTMultNode.java b/vcell-math/src/main/java/cbit/vcell/parser/ASTMultNode.java index 1f17861e94..4caf264aa4 100644 --- a/vcell-math/src/main/java/cbit/vcell/parser/ASTMultNode.java +++ b/vcell-math/src/main/java/cbit/vcell/parser/ASTMultNode.java @@ -416,7 +416,7 @@ public String infixString(int lang){ buffer.append("("); - if (bAllBoolean || bNoBoolean || (lang != SimpleNode.LANGUAGE_C && lang != SimpleNode.LANGUAGE_VISIT && lang != SimpleNode.LANGUAGE_PYTHON)) { // old way + if (bAllBoolean || bNoBoolean || (lang != SimpleNode.LANGUAGE_C && lang != SimpleNode.LANGUAGE_VISIT && lang != SimpleNode.LANGUAGE_PYTHON) && lang != SimpleNode.LANGUAGE_NUM_EXPR) { // old way for (int i=0;i0){ - if (lang == SimpleNode.LANGUAGE_MATLAB){ - buffer.append(" .* "); - } else if(lang == SimpleNode.LANGUAGE_PYTHON && bAllBoolean){ - buffer.append(" and "); - } else { - buffer.append(" * "); + if (bAllBoolean){ + if (lang == SimpleNode.LANGUAGE_PYTHON){ + buffer.append(" and "); + } else if (lang == SimpleNode.LANGUAGE_NUM_EXPR) { + buffer.append(" & "); + } else { + buffer.append(" * "); + } + } else { // mixed or no-boolean + if (lang == SimpleNode.LANGUAGE_MATLAB){ + buffer.append(" .* "); + } else { + buffer.append(" * "); + } } } buffer.append(jjtGetChild(i).infixString(lang)); @@ -447,6 +455,8 @@ public String infixString(int lang){ if (conditionBuffer.length() > 0) { if (lang == SimpleNode.LANGUAGE_PYTHON){ conditionBuffer.append(" and "); + } else if (lang == SimpleNode.LANGUAGE_NUM_EXPR) { + conditionBuffer.append(" & "); } else { conditionBuffer.append(" && "); } @@ -476,6 +486,8 @@ public String infixString(int lang){ } }else if (lang == SimpleNode.LANGUAGE_PYTHON) { buffer.append("(").append(valueBuffer).append(") if (").append(conditionBuffer).append(") else 0.0"); + }else if (lang == SimpleNode.LANGUAGE_NUM_EXPR) { + buffer.append("where(").append(conditionBuffer).append(", ").append(valueBuffer).append(", 0.0)"); }else{ buffer.append("((" + conditionBuffer + ") ? (" + valueBuffer + ") : 0.0)"); } diff --git a/vcell-math/src/main/java/cbit/vcell/parser/ASTNotNode.java b/vcell-math/src/main/java/cbit/vcell/parser/ASTNotNode.java index ee0d5bc8df..8f76402252 100644 --- a/vcell-math/src/main/java/cbit/vcell/parser/ASTNotNode.java +++ b/vcell-math/src/main/java/cbit/vcell/parser/ASTNotNode.java @@ -136,11 +136,15 @@ public Node flatten(boolean substituteConstants) throws ExpressionException { public String infixString(int language) { StringBuffer buffer = new StringBuffer(); boolean parentIsLogical = parent != null && parent.isLogical(); + boolean childIsLogical = jjtGetChild(0).isLogical(); if (language == LANGUAGE_VISIT){ buffer.append("not("); }else if(language == LANGUAGE_PYTHON){ if (parentIsLogical) buffer.append("not("); else buffer.append("float(not("); + }else if(language == LANGUAGE_NUM_EXPR){ + if (childIsLogical) buffer.append("~("); + else buffer.append("(0.0==("); }else if (language == LANGUAGE_ECLiPSe){ buffer.append("neg("); }else{ @@ -148,7 +152,7 @@ public String infixString(int language) { } buffer.append(jjtGetChild(0).infixString(language)); buffer.append(")"); - if (language == LANGUAGE_PYTHON && !parentIsLogical) buffer.append(")"); + if ((language == LANGUAGE_PYTHON && !parentIsLogical) || (language == LANGUAGE_NUM_EXPR && !childIsLogical)) buffer.append(")"); return buffer.toString(); } diff --git a/vcell-math/src/main/java/cbit/vcell/parser/ASTOrNode.java b/vcell-math/src/main/java/cbit/vcell/parser/ASTOrNode.java index c819a00a09..34b5753393 100644 --- a/vcell-math/src/main/java/cbit/vcell/parser/ASTOrNode.java +++ b/vcell-math/src/main/java/cbit/vcell/parser/ASTOrNode.java @@ -180,6 +180,14 @@ public String infixString(int lang) buffer.append(jjtGetChild(i).infixString(lang)); } buffer.append("))"); + }else if (lang == LANGUAGE_NUM_EXPR) { + int numChildren = jjtGetNumChildren(); + for (int i=0;i0) buffer.append(" | "); + buffer.append("(0.0!="); + buffer.append(jjtGetChild(i).infixString(lang)); + buffer.append(")"); + } }else{ for (int i=0;i0) { diff --git a/vcell-math/src/main/java/cbit/vcell/parser/ASTPowerNode.java b/vcell-math/src/main/java/cbit/vcell/parser/ASTPowerNode.java index fedb0821c2..153b4b363d 100644 --- a/vcell-math/src/main/java/cbit/vcell/parser/ASTPowerNode.java +++ b/vcell-math/src/main/java/cbit/vcell/parser/ASTPowerNode.java @@ -260,7 +260,7 @@ public String infixString(int lang){ buffer.append(" ^ "); buffer.append(jjtGetChild(1).infixString(lang)); buffer.append(")"); - } else if (lang == LANGUAGE_PYTHON) { + } else if (lang == LANGUAGE_PYTHON || lang == LANGUAGE_NUM_EXPR) { buffer.append("(("); buffer.append(jjtGetChild(0).infixString(lang)); buffer.append(")**("); diff --git a/vcell-math/src/main/java/cbit/vcell/parser/Expression.java b/vcell-math/src/main/java/cbit/vcell/parser/Expression.java index 54d8b484b8..57b6a4e034 100644 --- a/vcell-math/src/main/java/cbit/vcell/parser/Expression.java +++ b/vcell-math/src/main/java/cbit/vcell/parser/Expression.java @@ -707,6 +707,10 @@ public String infix_Matlab() public String infix_Python() { return rootNode == null ? null : rootNode.infixString(SimpleNode.LANGUAGE_PYTHON); } + + public String infix_NumExpr() { + return rootNode == null ? null : rootNode.infixString(SimpleNode.LANGUAGE_NUM_EXPR); + } /** * This method was created by a SmartGuide. * @return cbit.vcell.model.Expression diff --git a/vcell-math/src/main/java/cbit/vcell/parser/SimpleNode.java b/vcell-math/src/main/java/cbit/vcell/parser/SimpleNode.java index 6a7349d350..12f93feed9 100644 --- a/vcell-math/src/main/java/cbit/vcell/parser/SimpleNode.java +++ b/vcell-math/src/main/java/cbit/vcell/parser/SimpleNode.java @@ -32,6 +32,7 @@ public abstract class SimpleNode implements Node, java.io.Serializable { final static int LANGUAGE_UNITS = 6; final static int LANGUAGE_BNGL = 7; final static int LANGUAGE_PYTHON = 8; + final static int LANGUAGE_NUM_EXPR = 9; public SimpleNode(int i) { id = i; diff --git a/vcell-math/src/test/java/cbit/vcell/parser/ExpressionTest.java b/vcell-math/src/test/java/cbit/vcell/parser/ExpressionTest.java index 95f3de5202..4b21f45266 100644 --- a/vcell-math/src/test/java/cbit/vcell/parser/ExpressionTest.java +++ b/vcell-math/src/test/java/cbit/vcell/parser/ExpressionTest.java @@ -413,6 +413,21 @@ public void testEval() { } } +@Test +public void testNumExprGeneration() throws ExpressionException { + Expression expr1 = new Expression("(2.0 && id_2) * 3.3 / acsc(1 + id_1) * pow(2, 3.2 ^ 2)"); + String numExpr1 = expr1.infix_NumExpr(); + Assertions.assertEquals("(where(((0.0!=2.0) & (0.0!=id_2)), 3.3 / (arcsin(1.0/((1.0 + id_1)))) * ((2.0)**(((3.2)**(2.0)))), 0.0))", numExpr1); + + Expression expr2 = new Expression("(1.2 * 2.2) * logbase(3.3) * 2.0"); + String numExpr2 = expr2.infix_NumExpr(); + Assertions.assertEquals("((1.2 * 2.2) * (1.0/log(3.3)) * 2.0)", numExpr2); + + Expression expr3 = new Expression("(1.2 || 2.2) * (3.3 && !(2.0 && 0.0))"); + String numExpr3 = expr3.infix_NumExpr(); + Assertions.assertEquals("(((0.0!=1.2) | (0.0!=2.2)) & ((0.0!=3.3) & (0.0!=~(((0.0!=2.0) & (0.0!=0.0))))))", numExpr3); +} + /** * Insert the method's description here. From 534a40c131a399843391bdc0ad6c4007d153d817 Mon Sep 17 00:00:00 2001 From: Logan Drescher Date: Thu, 12 Mar 2026 10:23:38 -0400 Subject: [PATCH 2/2] Fixed two bugs, and updated testing --- .../java/cbit/vcell/parser/ASTFuncNode.java | 8 +- .../java/cbit/vcell/parser/ASTMultNode.java | 14 ++- .../cbit/vcell/parser/ExpressionTest.java | 12 ++- ...t_seed_1772035787937__4977_outOf_5000.txt} | 102 +++++++++++------- 4 files changed, 82 insertions(+), 54 deletions(-) rename vcell-math/src/test/reports/{pythonInfixTest_seed_1772035787937__4980_outOf_5000.txt => pythonInfixTest_seed_1772035787937__4977_outOf_5000.txt} (66%) diff --git a/vcell-math/src/main/java/cbit/vcell/parser/ASTFuncNode.java b/vcell-math/src/main/java/cbit/vcell/parser/ASTFuncNode.java index 61c030129b..d4cad628e8 100644 --- a/vcell-math/src/main/java/cbit/vcell/parser/ASTFuncNode.java +++ b/vcell-math/src/main/java/cbit/vcell/parser/ASTFuncNode.java @@ -2577,7 +2577,7 @@ public String infixString(int lang) { } case ACOT:{ if (lang == LANGUAGE_PYTHON){ - buffer.append(String.format("((%s/2.0) - ", Math.PI)); + buffer.append("(math.pi/2.0 - "); buffer.append(getPythonName(FunctionType.ATAN)); buffer.append("("); buffer.append(jjtGetChild(0).infixString(lang)); @@ -2595,8 +2595,10 @@ public String infixString(int lang) { case FACTORIAL: if (lang == LANGUAGE_PYTHON){ String name = getPythonName(); - // Since VCell now only accepts integer-values for factorial, integer casting should be safe - buffer.append(name).append("(int("); + // Since VCell now only accepts integer-values for factorial, + // Before we used casting, but there's a chance after math python can generate a different round off error. + // Since we know VCell only accepts integer, we're safe using `round` instead of just `int` + buffer.append(name).append("(round("); if (1 < this.jjtGetNumChildren()) throw new UnsupportedOperationException("Cannot take factorial of multiple children"); buffer.append(jjtGetChild(0).infixString(lang)); buffer.append("))"); diff --git a/vcell-math/src/main/java/cbit/vcell/parser/ASTMultNode.java b/vcell-math/src/main/java/cbit/vcell/parser/ASTMultNode.java index 4caf264aa4..2742f62d90 100644 --- a/vcell-math/src/main/java/cbit/vcell/parser/ASTMultNode.java +++ b/vcell-math/src/main/java/cbit/vcell/parser/ASTMultNode.java @@ -416,7 +416,7 @@ public String infixString(int lang){ buffer.append("("); - if (bAllBoolean || bNoBoolean || (lang != SimpleNode.LANGUAGE_C && lang != SimpleNode.LANGUAGE_VISIT && lang != SimpleNode.LANGUAGE_PYTHON) && lang != SimpleNode.LANGUAGE_NUM_EXPR) { // old way + if (bAllBoolean || bNoBoolean || (lang != SimpleNode.LANGUAGE_C && lang != SimpleNode.LANGUAGE_VISIT && lang != SimpleNode.LANGUAGE_PYTHON&& lang != SimpleNode.LANGUAGE_NUM_EXPR)) { // old way for (int i=0;i0){ - if (bAllBoolean){ + if (lang == SimpleNode.LANGUAGE_MATLAB){ + buffer.append(" .* "); + } else if (bAllBoolean){ if (lang == SimpleNode.LANGUAGE_PYTHON){ buffer.append(" and "); } else if (lang == SimpleNode.LANGUAGE_NUM_EXPR) { @@ -436,12 +438,8 @@ public String infixString(int lang){ } else { buffer.append(" * "); } - } else { // mixed or no-boolean - if (lang == SimpleNode.LANGUAGE_MATLAB){ - buffer.append(" .* "); - } else { - buffer.append(" * "); - } + } else { // mixed or no-boolean, and not matlab + buffer.append(" * "); } } buffer.append(jjtGetChild(i).infixString(lang)); diff --git a/vcell-math/src/test/java/cbit/vcell/parser/ExpressionTest.java b/vcell-math/src/test/java/cbit/vcell/parser/ExpressionTest.java index 4b21f45266..d52b57da3f 100644 --- a/vcell-math/src/test/java/cbit/vcell/parser/ExpressionTest.java +++ b/vcell-math/src/test/java/cbit/vcell/parser/ExpressionTest.java @@ -4,6 +4,7 @@ import cbit.vcell.parser.SymbolTableFunctionEntry.FunctionArgType; import cbit.vcell.units.VCUnitSystem; import net.sourceforge.interval.ia_math.RealInterval; +import org.apache.commons.math4.core.jdkmath.AccurateMath; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeAll; @@ -29,7 +30,7 @@ @Tag("Fast") public class ExpressionTest { - private static final boolean FAIL_ON_FIRST = true; + private static final boolean FAIL_ON_FIRST = false; private static final boolean ENSURE_SAME_SEED = true; // change me private static final long SAME_SEED = 1772035787937L; private static File tempDir; @@ -47,26 +48,29 @@ public class ExpressionTest { // } private static Set skipInfixList = new HashSet<>(List.of( + "acoth(min(cot( - id_0), floor((0.8708964264563003 * 0.29826500971825554 * 0.6457243719944876))))", "floor((pow(asinh(0.10118387985713251),cos(id_0)) * !(cot(id_0)) * min(csch(0.9837650351250335), coth(id_6))))", " - (min(cot(id_0), csch(0.36737356253208997)) * atan2((0.7233117778683602 >= 0.9759958353333693), (0.1299551891086368 * id_7 * 0.7165699878023953)) / abs(id_1))", "sech( - (coth(0.028177547796530367) ^ cot(id_1)))", "coth(((sinh(0.6449666197606081) ^ (id_4 * id_8 * id_9)) + cot((id_3 < 0.2261011754280382)) + sech(abs(0.8120086721536708))))", "(((cosh(id_3) * log(0.5598410965557573) * asin(0.015550241603964676)) * sin(floor(id_0)) * cosh(max(id_1, 0.585221823072032))) >= cot(floor((id_9 * id_2 * 0.30343841532874716))))", + "(cot(!( - id_6)) || ((tan(id_8) * atan2(id_5, id_7) * atan2(id_5, id_2)) * (pow(0.9897201897706811,id_1) * acosh(id_0) * (id_1 * 0.01088401412622797 * 0.8882413207692971)) * acot((0.3322552640871813 + id_9 + id_2))))", "coth(floor(cot(abs(id_0))))", " - factorial(( - id_2 / id_1 * ceil(id_5)))", "csch(exp(csc((id_2 * id_2 * id_9))))", "atan((tan(ceil(0.0)) || (cot(id_0) + asinh(0.5597772404451554) + sec(id_4))))", "cot(factorial( - (0.20783348997951046 && id_5)))", + "(sqrt((atan2(0.7218065889622693, id_1) + asech(0.5381259927491784) + atanh(0.78855529690269))) >= asinh((atan2(id_0, id_9) <= cot(id_0))))", " - cos((cos(id_1) ^ cot(id_0)))", + "pow(sinh(exp(acot(id_5))),tan(min(cot(id_0), (id_3 ^ id_8))))", "atan(abs(cot(floor(id_5))))", "coth(floor(cot((id_0 * 0.10280284481700341 * 0.3190467590050531))))", " - (( - id_1 * acos(0.9408318720601397) * cot(id_0)) && asinh(min(id_6, 0.130136440506475)))", "coth(factorial(floor(log(id_4))))", "(cot(!(sech(id_3))) ^ min( - atan2(0.7870190039110462, id_2), ((id_7 * id_0 * 0.10143937822636417) * min(id_4, id_2) * sech(0.5569515469432404))))", "cot(exp(coth((0.01722292952879423 ^ 0.7576553654648215))))", - "cosh(min(cot((id_7 * id_0 * 0.9871116728260001)), - !(id_6)))", - " - acos(((0.01949787088472099 * id_1 * id_9) ^ cot(id_0)))", - "factorial(min(tanh((id_9 ^ id_1)), floor( - 0.5153523376029631)))" + "(sec((asinh(0.0) && min(id_5, 0.648784608185188))) * (cot(floor(id_7)) <= (exp(id_7) * - 0.012384014519015274 * sqrt(0.7079441990714145))) * ceil(acot((0.8546428622959772 + id_0 + id_6))))", + "acsch(max(cot((id_0 * id_3 * 0.59541956426409)), (atan2(0.681661337447432, id_6) ^ atan2(0.2719307064055214, id_8))))" )); diff --git a/vcell-math/src/test/reports/pythonInfixTest_seed_1772035787937__4980_outOf_5000.txt b/vcell-math/src/test/reports/pythonInfixTest_seed_1772035787937__4977_outOf_5000.txt similarity index 66% rename from vcell-math/src/test/reports/pythonInfixTest_seed_1772035787937__4980_outOf_5000.txt rename to vcell-math/src/test/reports/pythonInfixTest_seed_1772035787937__4977_outOf_5000.txt index 06c71cd59b..2f3f247201 100644 --- a/vcell-math/src/test/reports/pythonInfixTest_seed_1772035787937__4980_outOf_5000.txt +++ b/vcell-math/src/test/reports/pythonInfixTest_seed_1772035787937__4977_outOf_5000.txt @@ -1,6 +1,14 @@ -4980 / 5000 models pass! +4977 / 5000 models pass! java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: - Progress: 65 + Progress: 77 + VCell Original Infix: acoth(min(cot( - id_0), floor((0.8708964264563003 * 0.29826500971825554 * 0.6457243719944876)))) + VCell Flat Infix: acoth(min(cot( - id_0), 0.0)) + Expected: -0.0 + Python Infix: (math.atanh(1.0/(min((1.0/math.tan( - id_0)), 0.0)))) + Python Exception: ZeroDivisionError: float division + +java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: + Progress: 101 VCell Original Infix: floor((pow(asinh(0.10118387985713251),cos(id_0)) * !(cot(id_0)) * min(csch(0.9837650351250335), coth(id_6)))) VCell Flat Infix: floor(((0.1010120140811213 ^ cos(id_0)) * !(cot(id_0)) * min(0.8693360808777927, coth(id_6)))) Expected: 0.0 @@ -8,7 +16,7 @@ java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: Python Exception: ZeroDivisionError: float division java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: - Progress: 170 + Progress: 246 VCell Original Infix: - (min(cot(id_0), csch(0.36737356253208997)) * atan2((0.7233117778683602 >= 0.9759958353333693), (0.1299551891086368 * id_7 * 0.7165699878023953)) / abs(id_1)) VCell Flat Infix: - (min(cot(id_0), 2.66174657516448) * atan2(0.0, (0.09312198827443384 * id_7)) / abs(id_1)) Expected: -0.0 @@ -16,7 +24,7 @@ java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: Python Exception: ZeroDivisionError: float division java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: - Progress: 482 + Progress: 681 VCell Original Infix: sech( - (coth(0.028177547796530367) ^ cot(id_1))) VCell Flat Infix: sech( - (35.498640665319236 ^ cot(id_1))) Expected: 0.0 @@ -24,7 +32,7 @@ java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: Python Exception: OverflowError: math range error java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: - Progress: 824 + Progress: 1164 VCell Original Infix: coth(((sinh(0.6449666197606081) ^ (id_4 * id_8 * id_9)) + cot((id_3 < 0.2261011754280382)) + sech(abs(0.8120086721536708)))) VCell Flat Infix: coth((0.7417315776928526 + (0.690621676135154 ^ (id_4 * id_8 * id_9)) + cot((id_3 < 0.2261011754280382)))) Expected: 1.0 @@ -32,7 +40,7 @@ java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: Python Exception: ZeroDivisionError: float division java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: - Progress: 902 + Progress: 1266 VCell Original Infix: (((cosh(id_3) * log(0.5598410965557573) * asin(0.015550241603964676)) * sin(floor(id_0)) * cosh(max(id_1, 0.585221823072032))) >= cot(floor((id_9 * id_2 * 0.30343841532874716)))) VCell Flat Infix: ( - (0.00902109438055013 * sin(floor(id_0)) * cosh(max(id_1, 0.585221823072032)) * cosh(id_3)) >= cot(floor((0.30343841532874716 * id_9 * id_2)))) Expected: 0.0 @@ -40,7 +48,15 @@ java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: Python Exception: ZeroDivisionError: float division java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: - Progress: 1329 + Progress: 1666 + VCell Original Infix: (cot(!( - id_6)) || ((tan(id_8) * atan2(id_5, id_7) * atan2(id_5, id_2)) * (pow(0.9897201897706811,id_1) * acosh(id_0) * (id_1 * 0.01088401412622797 * 0.8882413207692971)) * acot((0.3322552640871813 + id_9 + id_2)))) + VCell Flat Infix: (cot(!( - id_6)) || (0.009667631082752419 * tan(id_8) * atan2(id_5, id_7) * atan2(id_5, id_2) * (0.9897201897706811 ^ id_1) * acosh(id_0) * id_1 * acot((0.3322552640871813 + id_9 + id_2)))) + Expected: 1.0 + Python Infix: (float(bool((1.0/math.tan(float(not( - id_6)))) or (0.009667631082752419 * math.tan(id_8) * math.atan2(id_5, id_7) * math.atan2(id_5, id_2) * ((0.9897201897706811)**(id_1)) * math.acosh(id_0) * id_1 * (math.pi/2.0 - math.atan((0.3322552640871813 + id_9 + id_2))))))) + Python Exception: ZeroDivisionError: float division + +java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: + Progress: 1848 VCell Original Infix: coth(floor(cot(abs(id_0)))) VCell Flat Infix: coth(floor(cot(abs(id_0)))) Expected: 1.0 @@ -48,15 +64,15 @@ java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: Python Exception: ZeroDivisionError: float division java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: - Progress: 1681 + Progress: 2329 VCell Original Infix: - factorial(( - id_2 / id_1 * ceil(id_5))) VCell Flat Infix: - factorial( - (ceil(id_5) * id_2 / id_1)) Expected: -1.0 - Python Infix: - math.factorial(int( - (math.ceil(id_5) * id_2 / id_1))) + Python Infix: - math.factorial(round( - (math.ceil(id_5) * id_2 / id_1))) Python Exception: ValueError: math domain error java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: - Progress: 1790 + Progress: 2482 VCell Original Infix: csch(exp(csc((id_2 * id_2 * id_9)))) VCell Flat Infix: csch(exp(csc((id_2 * id_2 * id_9)))) Expected: 0.0 @@ -64,7 +80,7 @@ java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: Python Exception: OverflowError: math range error java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: - Progress: 1933 + Progress: 2704 VCell Original Infix: atan((tan(ceil(0.0)) || (cot(id_0) + asinh(0.5597772404451554) + sec(id_4)))) VCell Flat Infix: atan((0.0 || (0.5340297056736936 + cot(id_0) + sec(id_4)))) Expected: 0.7853981633974483 @@ -72,15 +88,23 @@ java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: Python Exception: ZeroDivisionError: float division java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: - Progress: 2465 + Progress: 3439 VCell Original Infix: cot(factorial( - (0.20783348997951046 && id_5))) VCell Flat Infix: cot(factorial( - (0.20783348997951046 && id_5))) Expected: 0.6420926159343306 - Python Infix: (1.0/math.tan(math.factorial(int( - (float(bool(0.20783348997951046 and id_5))))))) + Python Infix: (1.0/math.tan(math.factorial(round( - (float(bool(0.20783348997951046 and id_5))))))) Python Exception: ValueError: math domain error java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: - Progress: 2587 + Progress: 3487 + VCell Original Infix: (sqrt((atan2(0.7218065889622693, id_1) + asech(0.5381259927491784) + atanh(0.78855529690269))) >= asinh((atan2(id_0, id_9) <= cot(id_0)))) + VCell Flat Infix: (sqrt((2.298583646936585 + atan2(0.7218065889622693, id_1))) >= asinh((atan2(id_0, id_9) <= cot(id_0)))) + Expected: 1.0 + Python Infix: (math.sqrt((2.298583646936585 + math.atan2(0.7218065889622693, id_1))) >= math.asinh((math.atan2(id_0, id_9) <= (1.0/math.tan(id_0))))) + Python Exception: ZeroDivisionError: float division + +java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: + Progress: 3613 VCell Original Infix: - cos((cos(id_1) ^ cot(id_0))) VCell Flat Infix: - cos((cos(id_1) ^ cot(id_0))) Expected: -1.0 @@ -88,7 +112,15 @@ java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: Python Exception: ZeroDivisionError: float division java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: - Progress: 2626 + Progress: 3627 + VCell Original Infix: pow(sinh(exp(acot(id_5))),tan(min(cot(id_0), (id_3 ^ id_8)))) + VCell Flat Infix: (sinh(exp(acot(id_5))) ^ tan(min(cot(id_0), (id_3 ^ id_8)))) + Expected: 2.547860365917774 + Python Infix: ((math.sinh(math.exp((math.pi/2.0 - math.atan(id_5)))))**(math.tan(min((1.0/math.tan(id_0)), ((id_3)**(id_8)))))) + Python Exception: ZeroDivisionError: float division + +java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: + Progress: 3663 VCell Original Infix: atan(abs(cot(floor(id_5)))) VCell Flat Infix: atan(abs(cot(floor(id_5)))) Expected: 1.5707963267948966 @@ -96,7 +128,7 @@ java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: Python Exception: ZeroDivisionError: float division java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: - Progress: 2743 + Progress: 3822 VCell Original Infix: coth(floor(cot((id_0 * 0.10280284481700341 * 0.3190467590050531)))) VCell Flat Infix: coth(floor(cot((0.032798914455364356 * id_0)))) Expected: 1.0 @@ -104,7 +136,7 @@ java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: Python Exception: ZeroDivisionError: float division java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: - Progress: 2797 + Progress: 3903 VCell Original Infix: - (( - id_1 * acos(0.9408318720601397) * cot(id_0)) && asinh(min(id_6, 0.130136440506475))) VCell Flat Infix: - ( - (0.3457195131907874 * cot(id_0) * id_1) && asinh(min(id_6, 0.130136440506475))) Expected: -1.0 @@ -112,15 +144,15 @@ java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: Python Exception: ZeroDivisionError: float division java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: - Progress: 2856 + Progress: 3983 VCell Original Infix: coth(factorial(floor(log(id_4)))) VCell Flat Infix: coth(factorial(floor(log(id_4)))) Expected: 1.3130352854993315 - Python Infix: (1.0/math.tanh(math.factorial(int(math.floor(math.log(id_4)))))) + Python Infix: (1.0/math.tanh(math.factorial(round(math.floor(math.log(id_4)))))) Python Exception: ValueError: math domain error java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: - Progress: 3363 + Progress: 4695 VCell Original Infix: (cot(!(sech(id_3))) ^ min( - atan2(0.7870190039110462, id_2), ((id_7 * id_0 * 0.10143937822636417) * min(id_4, id_2) * sech(0.5569515469432404)))) VCell Flat Infix: (cot(!(sech(id_3))) ^ min( - atan2(0.7870190039110462, id_2), (0.08751198540266505 * id_7 * id_0 * min(id_4, id_2)))) Expected: 0.0 @@ -128,7 +160,7 @@ java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: Python Exception: ZeroDivisionError: float division java.lang.RuntimeException: Mismatch between expressions and results: - Progress: 3431 + Progress: 4786 VCell Original Infix: cot(exp(coth((0.01722292952879423 ^ 0.7576553654648215)))) VCell Flat Infix: cot(exp(coth((0.01722292952879423 ^ 0.7576553654648215)))) Expected: 1.7380578667392967 @@ -138,25 +170,17 @@ java.lang.RuntimeException: Mismatch between expressions and results: Threshold: 1.7380962131423855E-6 java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: - Progress: 3989 - VCell Original Infix: cosh(min(cot((id_7 * id_0 * 0.9871116728260001)), - !(id_6))) - VCell Flat Infix: cosh(min(cot((0.9871116728260001 * id_7 * id_0)), - !(id_6))) - Expected: 1.0 - Python Infix: math.cosh(min((1.0/math.tan((0.9871116728260001 * id_7 * id_0))), - float(not(id_6)))) + Progress: 4872 + VCell Original Infix: (sec((asinh(0.0) && min(id_5, 0.648784608185188))) * (cot(floor(id_7)) <= (exp(id_7) * - 0.012384014519015274 * sqrt(0.7079441990714145))) * ceil(acot((0.8546428622959772 + id_0 + id_6)))) + VCell Flat Infix: ((cot(floor(id_7)) <= - (0.010419837983700223 * exp(id_7))) * ceil(acot((0.8546428622959772 + id_0 + id_6)))) + Expected: 0.0 + Python Infix: ((math.ceil((math.pi/2.0 - math.atan((0.8546428622959772 + id_0 + id_6))))) if (((1.0/math.tan(math.floor(id_7))) <= - (0.010419837983700223 * math.exp(id_7)))) else 0.0) Python Exception: ZeroDivisionError: float division java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: - Progress: 4501 - VCell Original Infix: - acos(((0.01949787088472099 * id_1 * id_9) ^ cot(id_0))) - VCell Flat Infix: - acos(((0.01949787088472099 * id_1 * id_9) ^ cot(id_0))) - Expected: -1.5707963267948966 - Python Infix: - math.acos((((0.01949787088472099 * id_1 * id_9))**((1.0/math.tan(id_0))))) + Progress: 4875 + VCell Original Infix: acsch(max(cot((id_0 * id_3 * 0.59541956426409)), (atan2(0.681661337447432, id_6) ^ atan2(0.2719307064055214, id_8)))) + VCell Flat Infix: acsch(max(cot((0.59541956426409 * id_0 * id_3)), (atan2(0.681661337447432, id_6) ^ atan2(0.2719307064055214, id_8)))) + Expected: 0.0 + Python Infix: (math.asinh(1.0/(max((1.0/math.tan((0.59541956426409 * id_0 * id_3))), ((math.atan2(0.681661337447432, id_6))**(math.atan2(0.2719307064055214, id_8))))))) Python Exception: ZeroDivisionError: float division - -java.lang.RuntimeException: Unable to parse valid VCell Expression in Python: - Progress: 4977 - VCell Original Infix: factorial(min(tanh((id_9 ^ id_1)), floor( - 0.5153523376029631))) - VCell Flat Infix: factorial(min(tanh((id_9 ^ id_1)), -1.0)) - Expected: 1.0 - Python Infix: math.factorial(int(min(math.tanh(((id_9)**(id_1))), -1.0))) - Python Exception: ValueError: math domain error