/** * 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 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; } };
/** * 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; }
/** * 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(); }
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(); }
/** * 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; }