/** * Attaches symmetry to simple tensor. * * @param tensor string representation of simple tensor * @param permutation permutation * @throws java.lang.IllegalStateException if this tensor is already in use (it's permutation group calculated) * @throws java.lang.IllegalArgumentException if degree of specified permutation differs from the size of indices * of specified tensor */ public static void addSymmetry(String tensor, Permutation permutation) { addSymmetry(parseSimple(tensor), permutation); }
private static Tensor average(final int[] indices) { if (indices.length == 0) return Complex.ONE; if (indices.length == 2) return Tensors.createMetricOrKronecker(indices[0], indices[1]); SumBuilder sb = new SumBuilder(); for (int i = 1; i < indices.length; ++i) { int[] suffix = new int[indices.length - 2]; System.arraycopy(indices, 1, suffix, 0, i - 1); System.arraycopy(indices, i + 1, suffix, i - 1, indices.length - i - 1); sb.put(Tensors.multiply(Tensors.createMetricOrKronecker(indices[0], indices[i]), average(suffix))); } return sb.build(); }
/** * Returns {@code a} divided by {@code b}. * * @param a tensor * @param b scalar tensor * @return {@code a} divided by {@code b}. * @throws IllegalArgumentException if b is not scalar */ public static Tensor divide(Tensor a, Tensor b) { return multiply(a, reciprocal(b)); }
private Expression createBarSubs(SimpleTensor spinor, boolean negate) { if (spinor == null) return null; int dummy = spinor.getIndices().get(matrixType, 0), free = dummy + 1; SimpleTensor gamma = simpleTensor(gammaName, createSimple(null, setState(true, dummy), free, setType(metricType, 0))); SimpleTensor mom = setIndices(momentum, createSimple(null, setState(true, setType(metricType, 0)))); SimpleTensor rhs = setMatrixIndices0(spinor, free); return expression(multiply(spinor, gamma, mom), negate ? negate(multiply(mass, rhs)) : multiply(mass, rhs)); }
public static Expression[] setMandelstam(Tensor[][] momentums, Tensor s, Tensor t, Tensor u) { checkMandelstamInput(momentums, 4); if (s.getIndices().getFree().size() != 0 || t.getIndices().getFree().size() != 0 || u.getIndices().getFree().size() != 0) throw new IllegalArgumentException("Mandelstam variables should be scalar."); Expression[] result = new Expression[10]; int i; // (k1,k1) = m1^2, (k2,k2) = m2^2, (k3,k3) = m3^2, (k4,k4) = m4^2 for (i = 0; i < 4; ++i) result[i] = expression(square(momentums[i][0]), pow(momentums[i][1], 2)); //2(k1, k2) = s - k1^2 - k2^2 //2(k3, k4) = s - k3^2 - k4^2 result[i++] = expression(multiply(Complex.TWO, contract(momentums[0][0], momentums[1][0])), sum(s, negate(sum(pow(momentums[0][1], 2), pow(momentums[1][1], 2))))); result[i++] = expression(multiply(Complex.TWO, contract(momentums[2][0], momentums[3][0])), sum(s, negate(sum(pow(momentums[2][1], 2), pow(momentums[3][1], 2))))); //-2(k1, k3) = t - k1^2 - k3^2 //-2(k2, k4) = t - k2^2 - k4^2 result[i++] = expression(multiply(Complex.MINUS_TWO, contract(momentums[0][0], momentums[2][0])), sum(t, negate(sum(pow(momentums[0][1], 2), pow(momentums[2][1], 2))))); result[i++] = expression(multiply(Complex.MINUS_TWO, contract(momentums[1][0], momentums[3][0])), sum(t, negate(sum(pow(momentums[1][1], 2), pow(momentums[3][1], 2))))); //-2(k1, k4) = u - k1^2 - k4^2 //-2(k2, k3) = u - k2^2 - k3^2 result[i++] = expression(multiply(Complex.MINUS_TWO, contract(momentums[0][0], momentums[3][0])), sum(u, negate(sum(pow(momentums[0][1], 2), pow(momentums[3][1], 2))))); result[i++] = expression(multiply(Complex.MINUS_TWO, contract(momentums[1][0], momentums[2][0])), sum(u, negate(sum(pow(momentums[1][1], 2), pow(momentums[2][1], 2))))); return result; }
private Tensor traceOfArray(Tensor[] data) { //calculates trace using recursive algorithm if (data.length == 1) return Complex.ZERO; if (data.length == 2) return multiply(traceOfOne.get(1), createMetricOrKronecker(data[0].getIndices().get(metricType, 0), data[1].getIndices().get(metricType, 0))); if (data.length % 2 != 0) return Complex.ZERO; SumBuilder sb = new SumBuilder(); Tensor temp; for (int i = 0; i < data.length - 1; ++i) { temp = multiply(Complex.TWO, createMetricOrKronecker(data[i].getIndices().get(metricType, 0), data[i + 1].getIndices().get(metricType, 0)), traceOfArray(subArray(data, i, i + 1))); if (i % 2 != 0) temp = negate(temp); sb.put(temp); swap(data, i, i + 1); } return multiply(Complex.ONE_HALF, sb.build()); }
pb.put(differentiateSimpleTensor((SimpleTensor) tensor, rule, transformations)); for (int i = 0; i < varF.size(); i++) pb.put(createDiracDelta(field.get(i), varF.get(i))); return pb.build(); } else if (anyMappingExists(varF, field) || anyMappingExists(field, varF)) multiply(dArg, fieldDerivative(field, field.getArgIndices(i).getInverted(), i)) ); Tensor temp = multiply(((ScalarFunction) tensor).derivative(), differentiateWithRenaming(tensor.get(0), rule, transformations)); temp = applyTransformations(temp, transformations); } else if (tensor instanceof Power) { Tensor temp = sum( multiplyAndRenameConflictingDummies(tensor.get(1), pow(tensor.get(0), sum(tensor.get(1), Complex.MINUS_ONE)), differentiate1(tensor.get(0), rule, transformations)), multiplyAndRenameConflictingDummies(tensor, log(tensor.get(0)), differentiateWithRenaming(tensor.get(1), rule, transformations))); temp = applyTransformations(temp, transformations);
SimpleTensor eps1 = simpleTensor(defaultLeviCivitaName, IndicesFactory.createSimple(null, lower)); SimpleTensor eps2 = simpleTensor(defaultLeviCivitaName, IndicesFactory.createSimple(null, upper)); Tensor lhs = multiply(eps1, eps2); for (int i = 0; i < numberOfIndices; ++i) for (j = 0; j < numberOfIndices; ++j) matrix[i][j] = createKronecker(lower[i], upper[j]); Tensor rhs = TensorUtils.det(matrix); Expression substitution = expression(lhs, rhs); substitution = expression(substitution.get(0), negate(substitution.get(1))); return substitution;
loopProduct = multiply(loopProduct, Tensors.setIndices(loopMomentum, new int[]{indicesArray[i]})); ArraysUtils.addAll(externalMomentums, createMetric(setType(indexType, 0), setType(indexType, 1))), true, true, true); SimpleTensor[] params = genTensor.coefficients; Tensor inverted = ApplyIndexMapping.invertIndices(coeffs[j]); for (int i = 0; i < params.length; ++i) { matrix[i][j] = expandAndEliminate(multiplyAndRenameConflictingDummies(coeffs[i], inverted), simplifications); matrix[i][j] = simplifications.transform(matrix[i][j]); rhs[j] = expandAndEliminate(multiplyAndRenameConflictingDummies(loopProduct, inverted)); SumBuilder sol = new SumBuilder(); for (int i = 0; i < params.length; i++) sol.put(multiplyAndRenameConflictingDummies(inverse[i][j], rhs[i])); solution.put(multiplyAndRenameConflictingDummies(sol.build(), coeffs[j])); return expression(loopProduct, solution.build());
private Expression createP2Subs() { return expression(multiply(momentum, setIndices(momentum, momentum.getIndices().getInverted())), pow(mass, 2)); }
private Tensor order0(Tensor[] gammas) { if (gammas.length == 1) return gammas[0]; else if (gammas.length == 2) return metric(gammas); else { Tensor[] a = gammas.clone(); a[0] = Complex.TWO; a[1] = metric(gammas); Tensor[] b0 = gammas.clone(); swapAdj(b0, 0); Tensor b = order(Arrays.copyOfRange(b0, 1, b0.length)); if (b instanceof Sum) { Tensor[] pair = resolveDummy(b, b0[0]); b = FastTensors.multiplySumElementsOnFactor((Sum) pair[0], pair[1]); } else b = multiplyAndRenameConflictingDummies(b, b0[0]); return expandAndEliminate.transform(subtract(multiply(a), b)); } }
result[i] = expression(square(momentums[i][0]), pow(momentums[i][1], 2)); result[i++] = parseExpression("k1_{a}*k2^{a} = (1/2)*(-m1**2-m2**2+s)"); result[i++] = parseExpression("k3^{a}*k1_{a} = (1/2)*(m1**2+m3**2-t1)"); result[i++] = parseExpression("k4^{a}*k1_{a} = (1/2)*(m1**2-t2+m4**2)"); result[i++] = parseExpression("k5^{a}*k1_{a} = (1/2)*(-m1**2-m2**2-m3**2+s+t2-m4**2+t1)"); result[i++] = parseExpression("k3^{a}*k2_{a} = (1/2)*(-u1+m2**2+m3**2)"); result[i++] = parseExpression("k4^{a}*k2_{a} = (1/2)*(-u2+m2**2+m4**2)"); result[i++] = parseExpression("k5^{a}*k2_{a} = (1/2)*(u1-m1**2+u2-m2**2-m3**2+s-m4**2)"); result[i++] = parseExpression("k3_{a}*k4^{a} = (1/2)*(-u1-u2+2*m1**2+m3**2-s-t2+m4**2+2*m2**2-t1+m5**2)"); result[i++] = parseExpression("k3_{a}*k5^{a} = (1/2)*(-m1**2+u2-m2**2-m3**2+s+t2-m4**2-m5**2)"); result[i] = parseExpression("k5^{a}*k4_{a} = (1/2)*(u1-m1**2-m2**2-m3**2+s-m4**2+t1-m5**2)"); parseExpression("s = " + s.toString(Redberry)), parseExpression("t1 = " + t1.toString(Redberry)), parseExpression("t2 = " + t2.toString(Redberry)), parseExpression("u1 = " + u1.toString(Redberry)), parseExpression("u2 = " + u2.toString(Redberry)), expression(parse("m1"), momentums[0][1]), expression(parse("m2"), momentums[1][1]), expression(parse("m3"), momentums[2][1]), expression(parse("m4"), momentums[3][1]),
if (Tensors.parseSimple("R_lmab").getIndices().getSymmetries().availableForModification()) { Tensors.addSymmetry("R_lmab", IndexType.LatinLower, true, new int[]{0, 1, 3, 2}); Tensors.addSymmetry("R_lmab", IndexType.LatinLower, false, new int[]{2, 3, 0, 1}); if (Tensors.parseSimple("R_lm").getIndices().getSymmetries().availableForModification()) Tensors.addSymmetry("R_lm", IndexType.LatinLower, false, new int[]{1, 0}); this.L = Tensors.expression(Tensors.parse("L"), new Complex(operatorOrder)); this.hatQuantities = new Expression[HAT_QUANTITIES_GENERAL_COUNT][]; this.matrixIndicesCount = inputValues[1].get(0).getIndices().size() - operatorOrder; Tensor temp; String covariantIndicesString; Transformation n2 = new SqrSubs(Tensors.parseSimple("n_l")), n2Transformer = new Transformer(TraverseState.Leaving, new Transformation[]{n2}); Transformation[] transformations = ArraysUtils.addAll(new Transformation[]{EliminateMetricsTransformation.ELIMINATE_METRICS, n2Transformer}, riemannBackground); for (i = 0; i < actualHatQuantities; ++i) { temp = Tensors.parse(sb.toString(), insertion); temp = inputValues[0].transform(temp); temp = inputValues[i + 1].transform(temp); sb = new StringBuilder(); sb.append(getStringHatQuantitieName(i)).append("=0"); hatQuantities[i][0] = (Expression) Tensors.parse(sb.toString(), insertion); for (k = 0; k < i; ++k) sb.append("*n").append(IndicesUtils.toString(IndicesUtils.inverseIndexState(covariantIndices[k]), OutputFormat.Redberry)); temp = Tensors.parse(sb.toString()); temp = inputValues[0].transform(temp);
Flat = (Expression) Tensors.parse(Flat_, termIndicesInsertion); WR = (Expression) Tensors.parse(WR_, termIndicesInsertion); SR = (Expression) Tensors.parse(SR_, termIndicesInsertion); SSR = (Expression) Tensors.parse(SSR_, termIndicesInsertion); FF = (Expression) Tensors.parse(FF_, termIndicesInsertion); FR = (Expression) Tensors.parse(FR_, termIndicesInsertion); RR = (Expression) Tensors.parse(RR_, termIndicesInsertion); ACTION = (Expression) Tensors.parse(ACTION_, termIndicesInsertion); Expression[] terms = new Expression[]{Flat, WR, SR, SSR, FF, FR, RR}; DELTA_1 = (Expression) Tensors.parse(DELTA_1_, deltaIndicesInsertion); DELTA_2 = (Expression) Tensors.parse(DELTA_2_, deltaIndicesInsertion); DELTA_3 = (Expression) Tensors.parse(DELTA_3_, deltaIndicesInsertion); DELTA_4 = (Expression) Tensors.parse(DELTA_4_, deltaIndicesInsertion); Expression[] deltaExpressions = new Expression[]{DELTA_1, DELTA_2, DELTA_3, DELTA_4}; Tensors.parseExpression("R_{l m}^{l}_{a} = R_{ma}"), Tensors.parseExpression("R_{lm}^{a}_{a}=0"), Tensors.parseExpression("F_{l}^{l}^{a}_{b}=0"), Tensors.parseExpression("R_{lmab}*R^{lamb}=(1/2)*R_{lmab}*R^{lmab}"), Tensors.parseExpression("R_{lmab}*R^{lmab}=4*R_{lm}*R^{lm}-R*R"), Tensors.parseExpression("R_{l}^{l}= R") }; Expression kronecker = (Expression) Tensors.parse("d_{l}^{l}=4"); Transformation n2 = new SqrSubs(Tensors.parseSimple("n_l")), n2Transformer = new Transformer(TraverseState.Leaving, new Transformation[]{n2}); Transformation[] common = new Transformation[]{EliminateMetricsTransformation.ELIMINATE_METRICS, n2Transformer, kronecker}; Transformation[] all = ArraysUtils.addAll(common, riemansSubstitutions);
if (st.getIndices().size() == 0) continue; if (Tensors.isKroneckerOrMetric(st)) { usedTypes.add(getTypeEnum(st.getIndices().get(0))); continue; free[i] = createIndex(i, getType(si.get(i)), getState(si.get(i))); st = Tensors.setIndices(st, IndicesFactory.createSimple(null, si)); samples.addAll(Arrays.asList(TensorGeneratorUtils.allStatesCombinations(st))); byte btype = type.getType(); samples.add(Tensors.createKronecker(setType(btype, 0), 0x80000000 | setType(btype, 1))); if (CC.isMetric(btype)) { samples.add(Tensors.createMetric(setType(btype, 0), setType(btype, 1))); samples.add(Tensors.createMetric(0x80000000 | setType(btype, 0), 0x80000000 | setType(btype, 1)));
/** * Converts this AST to tensor. * * @return resulting tensor */ public Tensor toTensor() { switch (tokenType) { case Sum: return Tensors.sum(contentToTensors()); case Power: assert content.length == 2; return Tensors.pow(content[0].toTensor(), content[1].toTensor()); case Trace: case Product: return Tensors.multiplyAndRenameConflictingDummies(contentToTensors()); } throw new ParserException("Unknown tensor type: " + tokenType); }
private Expression getTraceSubstitution(int length) { Expression trace = cachedTraces.get(length); if (trace == null) { //product of gamma matrices as array Tensor[] data = new Tensor[length]; int matrixIndex = setType(matrixType, 0) - 1, metricIndex = -1; int firstUpper, u = firstUpper = ++matrixIndex, i; for (i = 0; i < length; ++i) { data[i] = Tensors.simpleTensor(gammaMatrixStringName, createSimple(null, u | 0x80000000, i == length - 1 ? firstUpper : (u = ++matrixIndex), setType(metricType, ++metricIndex))); } Tensor rhs = traceOfArray(data); rhs = expandAndEliminate.transform(rhs); cachedTraces.put(length, trace = expression(multiply(data), rhs)); } return trace; }