@Override protected ParseToken compile(List<ParseToken> nodes) { return new ParseToken(TokenType.Sum, nodes.toArray(new ParseToken[nodes.size()])); }
@Override protected ParseToken compile(List<ParseToken> nodes) { return new ParseToken(TokenType.Product, nodes.toArray(new ParseToken[nodes.size()])); }
@Override protected ParseToken inverseOperation(ParseToken node) { ParseToken[] content; if (node.tokenType == TokenType.Product) { content = new ParseToken[1 + node.content.length]; content[0] = new ParseTokenNumber(Complex.MINUS_ONE); System.arraycopy(node.content, 0, content, 1, node.content.length); } else content = new ParseToken[]{ new ParseTokenNumber(Complex.MINUS_ONE), node }; return new ParseToken(TokenType.Product, content); }
@Override protected ParseToken inverseOperation(ParseToken node) { return new ParseToken(TokenType.Power, node, new ParseTokenNumber(Complex.MINUS_ONE)); }
@Override public ParseToken parseToken(String expression, Parser parser) { if (expression.length() <= minLength) return null; if (!(power + '[').equals(expression.substring(0, power.length() + 1)) || expression.charAt(expression.length() - 1) != ']') return null; int level = 0, i, comma = -1; char c; for (i = power.length(); i < expression.length(); ++i) { c = expression.charAt(i); if (c == '[') ++level; if (level < 1) return null; if (c == ']') --level; if (c == ',' && level == 1) { if (comma != -1) throw new ParserException("Power takes only two arguments."); comma = i; } } ParseToken arg = parser.parse(expression.substring(power.length() + 1, comma)); ParseToken power = parser.parse(expression.substring(comma + 1, expression.length() - 1)); return new ParseToken(TokenType.Power, arg, power); } }
private ParseToken addDeltas(OuterIndices inserted, ParseToken node, OuterIndices expected, int[][] upper, int[][] lower) { List<ParseToken> multipliers = new ArrayList<>(); for (byte i = 0; i < TYPES_COUNT; ++i) { if (!inserted.initialized[i] && expected.initialized[i]) { if (expected.lower[i] == 0 && expected.upper[i] == 0) continue; if (expected.lower[i] != 1 || expected.upper[i] != 1) throw new IllegalArgumentException("Deltas insertion is only supported for one upper and " + "one lower omitted indices; node: " + node); multipliers.add(new ParseTokenSimpleTensor(IndicesFactory.createSimple(null, upper[i][0], lower[i][0]), CC.current().getKroneckerName())); } } if (multipliers.isEmpty()) return node; multipliers.add(node); return new ParseToken(TokenType.Product, multipliers.toArray(new ParseToken[multipliers.size()])); } }
if (power == null) return null; return new ParseToken(TokenType.Power, arg, power);
&& arguments.size() == 1 && arguments.get(0).getIndices().getFree().size() == 0) return new ParseToken(TokenType.Power, new ParseToken[]{arguments.get(0), new ParseTokenNumber(Complex.ONE_HALF)}); return new ParseToken(TokenType.Trace, arguments.toArray(new ParseToken[arguments.size()]));
public static ParseToken tensor2AST(Tensor tensor) { if (tensor instanceof TensorField) { TensorField tf = (TensorField) tensor; ParseToken[] content = new ParseToken[tf.size()]; int i = 0; for (Tensor t : tf) content[i++] = tensor2AST(t); return new ParseTokenTensorField(tf.getIndices(), tf.getStringName(), content, tf.getArgIndices()); } if (tensor instanceof SimpleTensor) { SimpleTensor st = (SimpleTensor) tensor; return new ParseTokenSimpleTensor(st.getIndices(), st.getStringName()); } if (tensor instanceof Complex) return new ParseTokenNumber((Complex) tensor); if (tensor instanceof Expression) return new ParseTokenExpression(false, tensor2AST(tensor.get(0)), tensor2AST(tensor.get(1))); ParseToken[] content = new ParseToken[tensor.size()]; int i = 0; for (Tensor t : tensor) content[i++] = tensor2AST(t); if (tensor instanceof ScalarFunction) return new ParseTokenScalarFunction(tensor.getClass().getSimpleName(), content); return new ParseToken(TokenType.valueOf(tensor.getClass().getSimpleName()), content); }
@Override public ParseToken transform(ParseToken node) { ensureMappedRulesInitialized(); int[] forbidden = ParseUtils.getAllIndicesT(node).toArray(); IndexGeneratorImpl generator = new IndexGeneratorImpl(forbidden); transformInsideFieldsAndScalarFunctions(node); ParseToken wrapped = new ParseToken(TokenType.Dummy, node); IITransformer transformer = createTransformer(wrapped); node = wrapped.content[0]; node.parent = null; if (transformer == null) return node; OuterIndices outerIndices = transformer.getOuterIndices(); int[][] upper = new int[TYPES_COUNT][], lower = new int[TYPES_COUNT][]; int j; for (byte i = 0; i < TYPES_COUNT; ++i) { upper[i] = new int[outerIndices.upper[i]]; for (j = 0; j < upper[i].length; ++j) upper[i][j] = 0x80000000 | generator.generate(i); lower[i] = new int[outerIndices.lower[i]]; for (j = 0; j < lower[i].length; ++j) lower[i][j] = generator.generate(i); } transformer.apply(generator, upper, lower); return node; }
@Override public ParseToken transform(ParseToken node) { TokenType type = node.tokenType; switch (type) { case SimpleTensor: ParseTokenSimpleTensor st = (ParseTokenSimpleTensor) node; NameAndStructureOfIndices ds = st.getIndicesTypeStructureAndName(); return new ParseTokenSimpleTensor(transformIndices(st.getIndices(), ds), transformer.newName(ds.getName(), ds)); case TensorField: ParseTokenTensorField tf = (ParseTokenTensorField) node; ParseToken[] newContent = transformContent(tf.content); SimpleIndices[] newArgsIndices = new SimpleIndices[tf.argumentsIndices.length]; for (int i = newArgsIndices.length - 1; i >= 0; --i) newArgsIndices[i] = IndicesFactory.createSimple(null, newContent[i].getIndices()); NameAndStructureOfIndices dsf = tf.getIndicesTypeStructureAndName(); return new ParseTokenTensorField(transformIndices(tf.getIndices(), dsf), transformer.newName(dsf.getName(), dsf), newContent, newArgsIndices); case Number: return node; case ScalarFunction: return new ParseTokenScalarFunction(((ParseTokenScalarFunction) node).function, transformContent(node.content)); case Expression: ParseToken[] nContent = transformContent(node.content); return new ParseTokenExpression(((ParseTokenExpression) node).preprocess, nContent[0], nContent[1]); default: return new ParseToken(node.tokenType, transformContent(node.content)); } }