/** * Applies specified mapping of indices to tensor. * * @param tensor tensor * @param mapping mapping of indices * @return tensor with renamed indices */ public static Tensor applyIndexMapping(Tensor tensor, Mapping mapping) { return applyIndexMapping(tensor, mapping, new int[0]); }
Tensor applyIndexMappingToTo(Tensor oldFrom, Tensor to, Mapping mapping, SubstitutionIterator iterator) { if (toIsSymbolic) return mapping.getSign() ? Tensors.negate(to) : to; if (possiblyAddsDummies) return ApplyIndexMapping.applyIndexMapping(to, mapping, iterator.getForbidden()); return ApplyIndexMapping.applyIndexMappingAndRenameAllDummies(to, mapping, TensorUtils.getAllDummyIndicesT(oldFrom).toArray()); }
private static Tensor applyIndexMapping(Tensor tensor, IndexMapper indexMapper) { if (tensor instanceof SimpleTensor) return applyIndexMapping(tensor, indexMapper, false); if (tensor instanceof Complex || tensor instanceof ScalarFunction) return tensor; return applyIndexMapping(tensor, indexMapper, indexMapper.contract(getIndicesNames(tensor.getIndices().getFree()))); }
private static Tensor permute(Tensor tensor, int[] indicesArray, int[] upperPermutation, int[] lowerPermutation, List<int[]> generatedPermutations, List<Permutation> symmetries) { //creating resulting permutation upper indices are first, //because initial indices are sorted int[] permutation = new int[upperPermutation.length + lowerPermutation.length]; System.arraycopy(upperPermutation, 0, permutation, 0, upperPermutation.length); System.arraycopy(lowerPermutation, 0, permutation, upperPermutation.length, lowerPermutation.length); //TODO discover better algorithm (possible using stretches of symmetries) //checking wheather the way beetween current permutation and already //generated combinatorics exists throw any possible combination of symmetries for (int[] p : generatedPermutations) for (Permutation symmetry : symmetries) if (Arrays.equals(permutation, symmetry.permute(p))) return null; generatedPermutations.add(permutation); //processing new indices from permutation final int[] newIndices = new int[indicesArray.length]; for (int i = 0; i < indicesArray.length; ++i) newIndices[i] = indicesArray[permutation[i]]; //processing new tensor return ApplyIndexMapping.applyIndexMapping(tensor, new Mapping(indicesArray, newIndices), new int[0]); }
@Override Tensor differentiateSimpleTensorWithoutCheck(SimpleTensor simpleTensor) { int[] to = simpleTensor.getIndices().getAllIndices().copy(); to = addAll(to, freeVarIndices); return applyIndexMapping(derivative, new Mapping(allFreeFrom, to), new int[0]); }
private static Tensor setIndices(Tensor t, Indices from, Indices to) { return ApplyIndexMapping.applyIndexMapping(t, new Mapping(from.getAllIndices().copy(), to.getAllIndices().copy()), new int[0]); }
private static Tensor invertIndices(Tensor t) { Indices free = t.getIndices().getFree(); Mapping mapping = new Mapping(free.toArray(), free.getInverted().toArray()); return ApplyIndexMapping.applyIndexMapping(t, mapping); }
private Tensor __newTo(DFromTo fromTo, TensorField currentField, Tensor currentNode, SubstitutionIterator iterator) { TensorField from = fromTo.from; Mapping mapping = IndexMappings.simpleTensorsPort(from, currentField).take(); if (mapping == null) return currentNode; Indices[] fromIndices = from.getArgIndices(), currentIndices = currentField.getArgIndices(); List<Tensor> argFrom = new ArrayList<>(), argTo = new ArrayList<>(); Tensor fArg; int[] cIndices, fIndices; int i; for (i = from.size() - 1; i >= 0; --i) { if (IndexMappings.positiveMappingExists(currentNode.get(i), from.get(i))) continue; fIndices = fromIndices[i].getAllIndices().copy(); cIndices = currentIndices[i].getAllIndices().copy(); assert cIndices.length == fIndices.length; fArg = ApplyIndexMapping.applyIndexMapping(from.get(i), new Mapping(fIndices, cIndices), new int[0]); argFrom.add(fArg); argTo.add(currentNode.get(i)); } Tensor newTo = fromTo.to; newTo = new SubstitutionTransformation( argFrom.toArray(new Tensor[argFrom.size()]), argTo.toArray(new Tensor[argTo.size()]), false).transform(newTo); return applyIndexMappingToTo(currentNode, newTo, mapping, iterator); }
/** * Inverts indices of tensor * * @param tensor tensor * @return tensor with inverted indices */ public static Tensor invertIndices(Tensor tensor) { Indices indices = tensor.getIndices().getFree(); if (indices.size() == 0) return tensor; return applyIndexMapping(tensor, new Mapping(indices.toArray(), indices.getInverted().toArray())); } }
@Override public Tensor transform(Tensor tensor) { TreeTraverseIterator iterator = new TreeTraverseIterator(tensor); TraverseState state; Tensor current; while ((state = iterator.next()) != null) { if (state != TraverseState.Leaving) continue; current = iterator.current(); Mapping mapping = IndexMappings.getFirst(from, current); if (mapping != null) { Tensor newFrom = ApplyIndexMapping.applyIndexMapping(to, mapping); iterator.set(newFrom); } } return iterator.result(); } }
private static Transformation createSubstitution(TensorField dd) { Tensor from = dd.get(0), to = dd.get(1); to = ApplyIndexMapping.applyIndexMapping(to, new Mapping(dd.getArgIndices(1).toArray(), dd.getArgIndices(0).toArray()), new int[0]); return new SubstitutionTransformation(from, to); }
private static Expression compileExpr0(Tensor lhs, Tensor rhs) { return expression(lhs, ApplyIndexMapping.applyIndexMapping(rhs, new Mapping(rhs.getIndices().getFree().toArray(), lhs.getIndices().getFree().toArray()))); } }
private static Tensor _applyIndexMapping(Tensor tensor, Mapping mapping, int[] forbidden) { final int mappingSize = mapping.size(); int[] allForbidden = new int[mappingSize + forbidden.length]; IntArray toData = mapping.getToData(), fromNames = mapping.getFromNames(); ArraysUtils.arraycopy(toData, 0, allForbidden, 0, mappingSize); System.arraycopy(forbidden, 0, allForbidden, mappingSize, forbidden.length); int i; for (i = allForbidden.length - 1; i >= 0; --i) allForbidden[i] = IndicesUtils.getNameWithType(allForbidden[i]); IntArrayList fromL = new IntArrayList(mappingSize), toL = new IntArrayList(mappingSize); fromL.addAll(fromNames); toL.addAll(toData); Arrays.sort(allForbidden); final int[] dummyIndices = TensorUtils.getAllDummyIndicesT(tensor).toArray(); final int[] forbiddenGeneratorIndices = new int[allForbidden.length + dummyIndices.length]; System.arraycopy(allForbidden, 0, forbiddenGeneratorIndices, 0, allForbidden.length); System.arraycopy(dummyIndices, 0, forbiddenGeneratorIndices, allForbidden.length, dummyIndices.length); IndexGeneratorImpl generator = new IndexGeneratorImpl(forbiddenGeneratorIndices); for (int index : dummyIndices) if (Arrays.binarySearch(allForbidden, index) >= 0) { //if index is dummy it cannot be free, so from (which is equal to free) //cannot contain it assert ArraysUtils.binarySearch(fromNames, index) < 0; fromL.add(index); toL.add(generator.generate(IndicesUtils.getType(index))); } int[] _from = fromL.toArray(), _to = toL.toArray(); ArraysUtils.quickSort(_from, _to); return applyIndexMapping(tensor, new IndexMapper(_from, _to)); }
private Tensor orderArray(Gamma[] gammas) { final int numberOfGammas = gammas.length; int[] permutation = Permutations.createIdentityArray(numberOfGammas); Tensor fGamma = gammas[0].gamma, lGamma = gammas[gammas.length - 1].gamma; int[] mIndices = new int[numberOfGammas]; for (int i = 0; i < numberOfGammas; ++i) mIndices[i] = gammas[i].index; //use stable sort! //!! gammas is lost now !! ArraysUtils.insertionSort(gammas, permutation); if (Permutations.isIdentity(permutation)) return null;//signals that array is sorted! Cached cached = cache.get(new IntArray(permutation)); if (cached == null) { Tensor[] arr = createArray(permutation); Tensor ordered = eliminate(orderArray0(arr.clone())); cache.put(new IntArray(permutation), cached = new Cached(arr, ordered)); } int[] iFrom = new int[numberOfGammas + 2], iTo = new int[numberOfGammas + 2]; System.arraycopy(cached.getOriginalIndices(metricType), 0, iFrom, 0, numberOfGammas); System.arraycopy(mIndices, 0, iTo, 0, numberOfGammas); iFrom[numberOfGammas] = cached.originalArray[0].getIndices().getUpper().get(matrixType, 0); iTo[numberOfGammas] = fGamma.getIndices().getUpper().get(matrixType, 0); iFrom[numberOfGammas + 1] = cached.originalArray[numberOfGammas - 1].getIndices().getLower().get(matrixType, 0); iTo[numberOfGammas + 1] = lGamma.getIndices().getLower().get(matrixType, 0); return eliminate(ApplyIndexMapping.applyIndexMapping(cached.ordered, new Mapping(iFrom, iTo))); }
public static Tensor applyIndexMappingAndRenameAllDummies(Tensor tensor, Mapping mapping, int[] allowedDummies) { if (TensorUtils.isZero(tensor)) return tensor; int[] freeIndicesNames = IndicesUtils.getIndicesNames(tensor.getIndices().getFree()); Arrays.sort(freeIndicesNames); if (!mapping.getFromNames().equalsToArray(freeIndicesNames)) throw new IllegalArgumentException("From indices names does not match free indices names of tensor. Tensor: " + tensor + " mapping: " + mapping); final int[] dummies = TensorUtils.getAllDummyIndicesT(tensor).toArray(); int[] from = new int[mapping.size() + dummies.length]; int[] to = new int[mapping.size() + dummies.length]; ArraysUtils.arraycopy(mapping.getFromNames(), 0, from, 0, mapping.size()); ArraysUtils.arraycopy(mapping.getToData(), 0, to, 0, mapping.size()); System.arraycopy(dummies, 0, from, mapping.size(), dummies.length); IndexGeneratorFromData generator = new IndexGeneratorFromData(allowedDummies); for (int i = mapping.size() + dummies.length - 1, mappingSize = mapping.size(); i >= mappingSize; --i) to[i] = generator.generate(IndicesUtils.getType(from[i])); ArraysUtils.quickSort(from, to); tensor = applyIndexMapping(tensor, new IndexMapper(from, to)); if (mapping.getSign()) tensor = Tensors.negate(tensor); return tensor; }
to[i] = generator.generate(IndicesUtils.getType(from[i])); return applyIndexMapping(tensor, new IndexMapper(from, to), false);
private Tensor order(Tensor[] gammas) { int numberOfGammas = gammas.length; Tensor tensor = cache.get(numberOfGammas); if (tensor == null) cache.put(numberOfGammas, tensor = order0(createLine(numberOfGammas))); int[] iFrom = new int[numberOfGammas + 2], iTo = new int[numberOfGammas + 2]; for (int i = 0; i < numberOfGammas; ++i) { iFrom[i] = setType(metricType, i); iTo[i] = gammas[i].getIndices().get(metricType, 0); } iFrom[numberOfGammas] = setType(matrixType, 0) | 0x80000000; iTo[numberOfGammas] = gammas[0].getIndices().getUpper().get(matrixType, 0); iFrom[numberOfGammas + 1] = setType(matrixType, numberOfGammas); iTo[numberOfGammas + 1] = gammas[numberOfGammas - 1].getIndices().getLower().get(matrixType, 0); return eliminate(ApplyIndexMapping.applyIndexMapping(tensor, new Mapping(iFrom, iTo))); }
return applyIndexMapping(tensor, new IndexMapper(from, to), false);
Tensor move0(Tensor[] gammas, int index, boolean left) { if (gammas.length == 1) return gammas[0]; if ((index == 0 && left) || (index == gammas.length - 1 && !left)) return multiply(gammas); int numberOfGammas = gammas.length; IntArrayList iFrom = new IntArrayList(numberOfGammas + 2), iTo = new IntArrayList(numberOfGammas + 2), g5s = new IntArrayList(); for (int i = 0; i < numberOfGammas; ++i) { if (isGamma5(gammas[i])) g5s.add(i); else { iFrom.add(setType(metricType, i)); iTo.add(gammas[i].getIndices().get(metricType, 0)); } } iFrom.add(setType(matrixType, 0) | 0x80000000); iTo.add(gammas[0].getIndices().getUpper().get(matrixType, 0)); iFrom.add(setType(matrixType, numberOfGammas)); iTo.add(gammas[numberOfGammas - 1].getIndices().getLower().get(matrixType, 0)); Holder key = new Holder(index, numberOfGammas, g5s, left); Tensor tensor = cache.get(key); if (tensor == null) cache.put(key, tensor = left ? toLeft0(createLine(numberOfGammas, g5s), index) : toRight0(createLine(numberOfGammas, g5s), index)); return eliminate(ApplyIndexMapping.applyIndexMapping(tensor, new Mapping(iFrom.toArray(), iTo.toArray()))); }
new SymmetrizeTransformation(allFreeVarIndicesI, true).transform(symmetric); derivative = applyIndexMapping( derivative, new Mapping(allIndices,