/** * Tests whether specified mapping is a mapping from <i>{@code from}</i> tensor onto <i>{@code to}</i> tensor. * * @param mapping mapping * @param from tensor <i>{@code from}</i> * @param to tensor <i>{@code to}</i> * @return {@code true} if specified mapping is a mapping from <i>{@code from}</i> tensor onto * <i>{@code to}</i> tensor and {@code false} in other case. */ public static boolean testMapping(Mapping mapping, Tensor from, Tensor to) { return IndexMappingBufferTester.test(new IndexMappingBufferTester(mapping), from, to); }
@Override public IndexMappingBufferTester clone() { return new IndexMappingBufferTester(innerBuffer.clone(), from, to, signum); }
@Override public boolean test(IndexMappingBufferTester tester) { for (int i = 1; i < from.length; ++i) if (!IndexMappingBufferTester.test(tester, from[i], to[currentPermutation[i]])) return false; return true; } }
@Override public FromToHolder export() { final TIntObjectHashMap<IndexMappingBufferRecord> map = innerBuffer.map; final int size = from.length + map.size(); int[] from1 = new int[size], to1 = new int[size]; System.arraycopy(from, 0, from1, 0, from.length); System.arraycopy(to, 0, to1, 0, from.length); int i = from.length; TIntObjectIterator<IndexMappingBufferRecord> iterator = map.iterator(); while (iterator.hasNext()) { iterator.advance(); from1[i] = iterator.key(); to1[i++] = iterator.value().getIndexName(); } return new FromToHolder(from1, to1, getSign()); }
/** * Tests whether specified {@link IndexMappingBufferTester} is a real mapping of tensor {@code from} * on tensor {@code to}. * * @param tester tester of mappings * @param from from tensor * @param to to tensor * @return {@code true} if there is mapping of tensor {@code from} on tensor {@code to} equal * to specified mapping */ public static boolean test(IndexMappingBufferTester tester, Tensor from, Tensor to) { tester.reset(); final IndexMappingProvider provider = IndexMappings.createPort(IndexMappingProvider.Util.singleton(tester), from, to); provider.tick(); IndexMappingBuffer buffer; while ((buffer = provider.take()) != null) if (!buffer.getSign()) return true; return false; }
@Override public IndexMappingBuffer take() { OUTER: while (true) { final IndexMappingBuffer buffer = mainProvider.take(); if (buffer == null) return null; buffer.removeContracted(); //buffer.addSignum(cache.lastReturned.sign); final IndexMappingBufferTester tester = new IndexMappingBufferTester(buffer.export().mergeWith(cache.lastReturned)); for (Tester t : testers) if (!t.test(tester)) continue OUTER; //buffer.addSignum(cache.lastReturned.sign); return buffer; } }
@Override public boolean test(final IndexMappingBufferTester tester) { return IndexMappingBufferTester.test(tester, from, to); } }
/** * Returns {@code true} if specified tensor is zero in consequence of its symmetries: is both symmetric and * asymmetric with respect to some permutation at the same time. * * @param t tensor * @return {@code true} if specified tensor is zero in consequence of its symmetries */ public static boolean isZeroDueToSymmetry(Tensor t) { int[] indices = IndicesUtils.getIndicesNames(t.getIndices().getFree()); IndexMappingBufferTester bufferTester = new IndexMappingBufferTester(indices, false); OutputPort<IndexMappingBuffer> mp = IndexMappings.createPortOfBuffers(bufferTester, t, t); IndexMappingBuffer buffer; while ((buffer = mp.take()) != null) if (buffer.getSign()) return true; return false; }
@Override public boolean test(final IndexMappingBufferTester tester) { //TODO discuss algorithm with Dima boolean[] bijection = new boolean[length]; int i, j; OUT: for (i = 0; i < length; ++i) { for (j = 0; j < length; ++j) if (!bijection[j] && IndexMappingBufferTester.test(tester, from[j], to[i])) { bijection[j] = true; continue OUT; } return false; } return true; // int[] permutation; // final PriorityPermutationGenerator generator = permutationGenerator; // generator.reset(); // int i; // OUTER: // while ((permutation = generator.next()) != null) // for (i = 0; i < from.length; ++i) { // if (!IndexMappingBufferTester.test(tester, from[i], to[permutation[i]])) // continue OUTER; // generator.nice(); // return true; // } // return false; } }
/** * Returns {@code true} if tensor u mathematically (not programming) equals to tensor v, * {@code false} if they they differ only in the sign and {@code null} otherwise. * * @param u tensor * @param v tensor * @return {@code true} {@code false} if tensor u mathematically (not programming) equals to tensor v, * {@code true} if they they differ only in the sign and {@code null} otherwise */ public static Boolean compare1(Tensor u, Tensor v) { Indices freeIndices = u.getIndices().getFree(); if (!freeIndices.equalsRegardlessOrder(v.getIndices().getFree())) return null; int[] free = freeIndices.getAllIndices().copy(); IndexMappingBuffer tester = new IndexMappingBufferTester(free, false); IndexMappingBuffer buffer = IndexMappings.createPortOfBuffers(tester, u, v).take(); if (buffer == null) return null; return buffer.getSign(); }
/** * Returns {@code true} if tensor u mathematically (not programming) equals to tensor v. * * @param u tensor * @param v tensor * @return {@code true} if specified tensors are mathematically (not programming) equal */ public static boolean equals(Tensor u, Tensor v) { if (u == v) return true; Indices freeIndices = u.getIndices().getFree(); if (!freeIndices.equalsRegardlessOrder(v.getIndices().getFree())) return false; int[] free = freeIndices.getAllIndices().copy(); IndexMappingBuffer tester = new IndexMappingBufferTester(free, false); OutputPort<IndexMappingBuffer> mp = IndexMappings.createPortOfBuffers(tester, u, v); IndexMappingBuffer buffer; while ((buffer = mp.take()) != null) if (!buffer.getSign()) return true; return false; }