use of ucar.units_vcell.RationalNumber in project vcell by virtualcell.
the class VCUnitEvaluator method getUnitDefinition.
private VCUnitDefinition getUnitDefinition(SimpleNode node, UnitsHashMap unitsHashMap) throws ExpressionException, VCUnitException {
// temp variable
VCUnitDefinition unit = null;
if (node == null) {
return null;
}
if (node instanceof ASTAndNode || node instanceof ASTOrNode || node instanceof ASTNotNode) {
for (int i = 0; i < node.jjtGetNumChildren(); i++) {
SimpleNode child = (SimpleNode) node.jjtGetChild(i);
VCUnitDefinition childUnit = getUnitDefinition(child, unitsHashMap);
if (!childUnit.isEquivalent(unitSystem.getInstance_DIMENSIONLESS())) {
throw new VCUnitException("argument to boolean expression '" + child.infixString(SimpleNode.LANGUAGE_DEFAULT) + "' must be dimensionless");
}
}
return unitSystem.getInstance_DIMENSIONLESS();
} else if (node instanceof ASTRelationalNode) {
ArrayList<VCUnitDefinition> units = new ArrayList<VCUnitDefinition>();
for (int i = 0; i < node.jjtGetNumChildren(); i++) {
units.add(getUnitDefinition((SimpleNode) node.jjtGetChild(i), unitsHashMap));
}
// looking for imcompatabilities
computeUnit(node, (VCUnitDefinition[]) units.toArray(new VCUnitDefinition[units.size()]), true);
return unitSystem.getInstance_DIMENSIONLESS();
} else if (node instanceof ASTAddNode || node instanceof ASTMinusTermNode) {
ArrayList<VCUnitDefinition> units = new ArrayList<VCUnitDefinition>();
for (int i = 0; i < node.jjtGetNumChildren(); i++) {
units.add(getUnitDefinition((SimpleNode) node.jjtGetChild(i), unitsHashMap));
}
return computeUnit(node, (VCUnitDefinition[]) units.toArray(new VCUnitDefinition[units.size()]), true);
} else if (node instanceof ASTMultNode) {
if (node.jjtGetNumChildren() == 1) {
return getUnitDefinition((SimpleNode) node.jjtGetChild(0), unitsHashMap);
}
VCUnitDefinition accumUnit = null;
for (int i = 0; i < node.jjtGetNumChildren(); i++) {
SimpleNode child = (SimpleNode) node.jjtGetChild(i);
unit = getUnitDefinition(child, unitsHashMap);
if (unit.isTBD()) {
return unit;
}
if (accumUnit == null) {
accumUnit = unit;
} else {
accumUnit = accumUnit.multiplyBy(unit);
}
}
return accumUnit;
} else if (node instanceof ASTInvertTermNode) {
SimpleNode child = (SimpleNode) node.jjtGetChild(0);
unit = getUnitDefinition(child, unitsHashMap);
if (unit.isTBD()) {
return unit;
} else {
return unit.getInverse();
}
} else if (node instanceof DerivativeNode) {
unit = getUnitDefinition((SimpleNode) node.jjtGetChild(1), unitsHashMap);
return getUnitDefinition((SimpleNode) node.jjtGetChild(0), unitsHashMap).divideBy(unit);
} else if (node instanceof ASTLaplacianNode) {
return unitSystem.getInstance_TBD();
// unit = unitSystem.Instance(ModelUnitSystem.UNITSYMBOL_um);
// return getUnitDefinition((SimpleNode)node.jjtGetChild(0),unitsHashMap).divideBy(unit).divideBy(unit);
} else if (node instanceof ASTFloatNode) {
// return TBD instead of dimensionless.
return unitSystem.getInstance_TBD();
} else if (node instanceof ASTFuncNode) {
String functionName = ((ASTFuncNode) node).getName();
if (functionName.equalsIgnoreCase("pow")) {
SimpleNode child0 = (SimpleNode) node.jjtGetChild(0);
SimpleNode child1 = (SimpleNode) node.jjtGetChild(1);
VCUnitDefinition unit0 = getUnitDefinition(child0, unitsHashMap);
VCUnitDefinition unit1 = getUnitDefinition(child1, unitsHashMap);
if (!unit1.isEquivalent(unitSystem.getInstance_DIMENSIONLESS()) && !unit1.isTBD()) {
throw new VCUnitException("exponent of '" + node.infixString(SimpleNode.LANGUAGE_DEFAULT) + "' has units of " + unit0);
}
if (unit0.isEquivalent(unitSystem.getInstance_DIMENSIONLESS()) || unit0.isTBD()) {
return unit0;
}
try {
double d = ((SimpleNode) node.jjtGetChild(1)).evaluateConstant();
RationalNumber rn = RationalNumber.getApproximateFraction(d);
return unit0.raiseTo(rn);
} catch (ExpressionException e) {
// ????? don't know the unit now
return unitSystem.getInstance_TBD();
}
} else if (functionName.equalsIgnoreCase("exp")) {
SimpleNode child0 = (SimpleNode) node.jjtGetChild(0);
VCUnitDefinition unit0 = getUnitDefinition(child0, unitsHashMap);
if (!unit0.isEquivalent(unitSystem.getInstance_DIMENSIONLESS()) && !unit0.isTBD()) {
throw new VCUnitException("exponent of exp() '" + node.infixString(SimpleNode.LANGUAGE_DEFAULT) + "' has units of " + unit0);
}
return unitSystem.getInstance_DIMENSIONLESS();
} else if (functionName.equalsIgnoreCase("sqrt")) {
SimpleNode child0 = (SimpleNode) node.jjtGetChild(0);
VCUnitDefinition unit0 = getUnitDefinition(child0, unitsHashMap);
if (unit0.isEquivalent(unitSystem.getInstance_DIMENSIONLESS()) || unit0.isTBD()) {
return unit0;
}
RationalNumber rn = new RationalNumber(1, 2);
return unit0.raiseTo(rn);
} else if (functionName.equalsIgnoreCase("abs") || functionName.equalsIgnoreCase("min") || functionName.equalsIgnoreCase("max")) {
return getUnitDefinition((SimpleNode) node.jjtGetChild(0), unitsHashMap);
} else if (((ASTFuncNode) node).getFunction() == FunctionType.USERDEFINED) {
ASTFuncNode funcNode = (ASTFuncNode) node;
SymbolTableFunctionEntry stfe = funcNode.getSymbolTableFunctionEntry();
if (stfe != null) {
if (stfe.getUnitDefinition() != null) {
return stfe.getUnitDefinition();
}
}
return unitSystem.getInstance_TBD();
} else {
return unitSystem.getInstance_DIMENSIONLESS();
}
} else if (node instanceof ASTPowerNode) {
SimpleNode child0 = (SimpleNode) node.jjtGetChild(0);
SimpleNode child1 = (SimpleNode) node.jjtGetChild(1);
VCUnitDefinition unit0 = getUnitDefinition(child0, unitsHashMap);
VCUnitDefinition unit1 = getUnitDefinition(child1, unitsHashMap);
if (!unit1.isEquivalent(unitSystem.getInstance_DIMENSIONLESS()) && !unit1.isTBD()) {
throw new VCUnitException("exponent of '" + node.infixString(SimpleNode.LANGUAGE_DEFAULT) + "' has units of " + unit0);
}
if (unit0.isEquivalent(unitSystem.getInstance_DIMENSIONLESS())) {
return unitSystem.getInstance_DIMENSIONLESS();
}
boolean bConstantExponent = false;
double exponentValue = 1;
try {
exponentValue = child1.evaluateConstant();
bConstantExponent = true;
} catch (ExpressionException e) {
bConstantExponent = false;
}
if (bConstantExponent) {
//
if (unit0.isTBD()) {
return unitSystem.getInstance_TBD();
} else {
RationalNumber rn = RationalNumber.getApproximateFraction(exponentValue);
return unit0.raiseTo(rn);
}
} else {
return unitSystem.getInstance_TBD();
}
} else if (node instanceof ASTIdNode) {
SymbolTableEntry ste = ((ASTIdNode) node).symbolTableEntry;
unit = unitsHashMap.get(ste);
if (unit == null) {
unit = ste.getUnitDefinition();
if (unit == null) {
throw new ExpressionException("No unit found for expression node: " + node.toString());
} else {
unitsHashMap.put(ste, unit);
}
}
return unit;
} else {
throw new ExpressionException("node type " + node.getClass().toString() + " not supported yet");
}
}
Aggregations