static IndexMappingProvider createPort(IndexMappingProvider opu, Tensor from, Tensor to) { if (from.hashCode() != to.hashCode()) return IndexMappingProvider.Util.EMPTY_PROVIDER; if (from.getClass() != to.getClass()) { Tensor nonComplex; // Processing case -2*(1/2)*g_mn -> g_mn if (from instanceof Product && !(to instanceof Product)) { if (from.size() != 2) return IndexMappingProvider.Util.EMPTY_PROVIDER; if ((nonComplex = extractNonComplexFactor(from)) != null) return new MinusIndexMappingProviderWrapper(createPort(opu, nonComplex, to)); return IndexMappingProvider.Util.EMPTY_PROVIDER; } // Processing case g_mn -> -2*(1/2)*g_mn if (to instanceof Product && !(from instanceof Product)) { if (to.size() != 2) return IndexMappingProvider.Util.EMPTY_PROVIDER; if ((nonComplex = extractNonComplexFactor(to)) != null) return new MinusIndexMappingProviderWrapper(createPort(opu, from, nonComplex)); return IndexMappingProvider.Util.EMPTY_PROVIDER; } return IndexMappingProvider.Util.EMPTY_PROVIDER; } IndexMappingProviderFactory factory = map.get(from.getClass()); if (factory == null) throw new RuntimeException("Unsupported tensor type: " + from.getClass()); return factory.create(opu, from, to); }
public static Tensor symmetrize(SimpleTensor tensor, int[] freeIndices, Symmetries symmetries) { if (symmetries.isEmpty()) return tensor; int[] tempI = freeIndices.clone(); int[] allFreeIndices = tensor.getIndices().getFree().getAllIndices().copy(); Arrays.sort(tempI); Arrays.sort(allFreeIndices); int[] diff = MathUtils.intSetDifference(tempI, allFreeIndices); System.arraycopy(freeIndices, 0, allFreeIndices, 0, freeIndices.length); System.arraycopy(diff, 0, allFreeIndices, freeIndices.length, diff.length); SumBuilder builder = new SumBuilder(); Tensor temp; for (Symmetry symmetry : symmetries) { temp = applyIndexMapping(tensor, allFreeIndices, permute(allFreeIndices, symmetry), new int[0]); if (symmetry.isAntiSymmetry()) temp = negate(temp); builder.put(temp); } temp = builder.build(); if (temp instanceof Sum) { // retrieving factor Complex factor = null, tempF; for (int i = temp.size() - 1; i >= 0; --i) { if (temp.get(i) instanceof Product) { tempF = ((Product) temp.get(i)).getFactor(); assert tempF.isInteger(); tempF = tempF.abs(); } else tempF = Complex.ONE; if (factor == null) factor = tempF; assert factor.equals(tempF); } if (!factor.isOne()) temp = FastTensors.multiplySumElementsOnFactor((Sum) temp, factor.reciprocal()); return multiply(new Complex(new Rational(1, temp.size())), temp); } return temp; }
@Test public void run() { try (Graph g = new Graph(); Session s = new Session(g)) { TestUtil.transpose_A_times_X(g, new int[][] {{2}, {3}}); try (Tensor x = Tensor.create(new int[][] {{5}, {7}}); AutoCloseableList<Tensor> outputs = new AutoCloseableList<Tensor>(s.runner().feed("X", x).fetch("Y").run())) { assertEquals(1, outputs.size()); final int[][] expected = {{31}}; assertEquals(expected, outputs.get(0).copyTo(new int[1][1])); } } }