/** * Creates tester of specified {@link IndexMappingBuffer}. */ public IndexMappingBufferTester(IndexMappingBuffer buffer) { this(buffer.export()); //Map<Integer, IndexMappingBufferRecord> map = buffer.map; //final int size = map.size(); //from = new int[size]; //to = new int[size]; //sign = buffer.getSignum(); //int i = 0; //for (Map.Entry<Integer, IndexMappingBufferRecord> entry : map.entrySet()) { // from[i] = entry.getKey(); // to[i++] = entry.getValue().getIndexName(); //} //ArraysUtils.quickSort(this.from, this.to); //innerBuffer = new IndexMappingBufferImpl(); }
@Override public IndexMappingBuffer take() { IndexMappingBuffer buf = provider.take(); if (buf != null) buf.removeContracted(); return buf; } }
while (searchForPermutations.hasNext()) { permutation = searchForPermutations.next(); IndexMappingBuffer tempBuffer = currentBuffer.clone(); for (int i = 0; i < size; ++i) if (!tempBuffer.tryMap(fromIndices.get(i), toIndices.get(permutation.newIndexOf(i)))) continue out; tempBuffer.addSign(permutation.antisymmetry()); return tempBuffer; IndexMappingBuffer tempBuffer = currentBuffer; for (int i = 0; i < size; ++i) if (!tempBuffer.tryMap(fromIndices.get(i), toIndices.get(i))) return currentBuffer = null; currentBuffer = null; for (int mapFrom = 0; mapFrom < size; ++mapFrom) { int fromIndex = fromIndices.get(mapFrom); IndexMappingBufferRecord bRec = currentBuffer.getMap().get(getNameWithType(fromIndex));
/** * Returns {@code true} if there is positive mapping of tensor {@code from} on tensor {@code to}. * * @param from from tensor * @param to to tensor * @return {@code true} if there is positivemapping of tensor {@code from} on tensor {@code to} */ public static boolean positiveMappingExists(Tensor from, Tensor to) { IndexMappingBuffer buffer; OutputPort<IndexMappingBuffer> port = createPortOfBuffers(from, to); while ((buffer = port.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; } }
Mapping(IndexMappingBuffer buffer) { TIntObjectHashMap<IndexMappingBufferRecord> map = buffer.getMap(); fromNames = new int[map.size()]; toData = new int[map.size()]; TIntObjectIterator<IndexMappingBufferRecord> iterator = map.iterator(); int i = 0; IndexMappingBufferRecord record; while (iterator.hasNext()) { iterator.advance(); record = iterator.value(); fromNames[i] = iterator.key(); toData[i] = record.getRawDiffStateBit() | record.getIndexName(); ++i; } ArraysUtils.quickSort(fromNames, toData); sign = buffer.getSign(); }
@Override public IndexMappingBuffer take() { if (currentBuffer == null) return null; IndexMappingBuffer buf = currentBuffer; currentBuffer = null; buf.addSign(true); return buf; } }
@Override public IndexMappingBuffer take() { if (currentBuffer == null) return null; IndexMappingBuffer buf; while (true) { if (currentSource != null && (buf = currentSource.take()) != null) return buf; if (!permutationGenerator.hasNext()) { currentBuffer = null; return null; } currentPermutation = permutationGenerator.next(); currentSource = IndexMappings.createPortOfBuffers(currentBuffer.clone(), from[0], to[currentPermutation[0]]); } }
@Override public IndexMappingProvider create(IndexMappingProvider opu, Tensor from, Tensor to) { IndexMappingBuffer buffer; if ((buffer = IndexMappings.createPortOfBuffers(from.get(0), to.get(0)).take()) != null && !buffer.getSign()) return new DummyIndexMappingProvider(opu); return IndexMappingProvider.Util.EMPTY_PROVIDER; } };
@Override public IndexMappingBuffer take() { IndexMappingBuffer currentBuffer = provider.take(); if (currentBuffer == null) return null; currentBuffer.addSign(true); return currentBuffer; }
@Override public IndexMappingBuffer take() { if (currentBuffer == null) return null; while (currentProvider == null) { if (!generator.hasNext()) return null; final int[] permutation = generator.next(); final Tensor[] newTo = new Tensor[to.length]; for (int i = 0; i < to.length; ++i) newTo[i] = to[permutation[i]]; currentProvider = new SimpleProductMappingsPort(IndexMappingProvider.Util.singleton(currentBuffer.clone()), from, newTo); final IndexMappingBuffer buffer = currentProvider.take(); if (buffer != null) return buffer; currentProvider = null; } final IndexMappingBuffer buffer = currentProvider.take(); if (buffer == null) { currentProvider = null; return take(); } return buffer; } }
/** * 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() { IndexMappingBuffer buffer = provider.take(); if (buffer == null) return null; lastReturned = buffer.export(); return buffer; } }
@Override public IndexMappingBuffer take() { IndexMappingBuffer buffer = op.take(); if (buffer == null) return null; buffer.removeContracted(); return buffer; }
/** * 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 IndexMappingProvider create(IndexMappingProvider opu, Tensor from, Tensor to) { OutputPort<IndexMappingBuffer> mp = IndexMappings.createPortOfBuffers(from.get(0), to.get(0)); IndexMappingBuffer buffer; byte state = 0; while ((buffer = mp.take()) != null) { state |= (byte) (buffer.getSign() ? 0x10 : 0x01); if (state == 0x11) break; } switch (state) { case 0x00: return IndexMappingProvider.Util.EMPTY_PROVIDER; case 0x01: return new DummyIndexMappingProvider(opu); case 0x10: return new MinusIndexMappingProvider(opu); case 0x11: return new PlusMinusIndexMappingProvider(opu); default: throw new RuntimeException("Ups"); } } };
@Override public IndexMappingProvider create(IndexMappingProvider opu, Tensor from, Tensor to) { IndexMappingBuffer exponentMapping = IndexMappings.getFirstBuffer(from.get(1), to.get(1)); //todo try get first positive mapping if (exponentMapping == null || exponentMapping.getSign()) return IndexMappingProvider.Util.EMPTY_PROVIDER; //todo two signs are possible IndexMappingBuffer baseMapping = IndexMappings.getFirstBuffer(from.get(0), to.get(0)); if (baseMapping == null) return IndexMappingProvider.Util.EMPTY_PROVIDER; if (baseMapping.getSign() == false) return new DummyIndexMappingProvider(opu); if (!(from.get(1) instanceof Complex)) return IndexMappingProvider.Util.EMPTY_PROVIDER; assert to.get(1) instanceof Complex; Complex exponent = (Complex) from.get(1); if (NumberUtils.isIntegerEven(exponent)) return new DummyIndexMappingProvider(opu); if (NumberUtils.isIntegerOdd(exponent)) return new MinusIndexMappingProvider(opu); return IndexMappingProvider.Util.EMPTY_PROVIDER; } }
/** * 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; }