/*
* Redberry: symbolic tensor computations.
*
* Copyright (c) 2010-2012:
* Stanislav Poslavsky <stvlpos@mail.ru>
* Bolotin Dmitriy <bolotin.dmitriy@gmail.com>
*
* This file is part of Redberry.
*
* Redberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Redberry is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Redberry. If not, see <http://www.gnu.org/licenses/>.
*/
package cc.redberry.core.tensor.testing;
import cc.redberry.core.indices.Indices;
import cc.redberry.core.tensor.SimpleTensor;
import cc.redberry.core.tensor.Tensor;
import cc.redberry.core.tensor.TensorContent;
import cc.redberry.core.tensor.TensorSortedContent;
import cc.redberry.core.combinatorics.IntPermutationsGenerator;
/**
*
* @author Dmitry Bolotin
* @author Stanislav Poslavsky
*/
public class TestEqualsContent implements TensorTest {
public static final TestEqualsContent INSTANCE = new TestEqualsContent();
TestEqualsContent() {
}
@Override
public boolean test(Tensor... arr) {
if (arr.length < 2)
throw new IllegalArgumentException();
for (int i = 1; i < arr.length; ++i)
if (!compare(arr[0], arr[i]))
return false;
return true;
}
private boolean compare(Tensor t1, Tensor t2) {
//TODO compare hash codes (not as t1.hashCode() != t2.hashCode())
if (t1.getClass() != t2.getClass())
return false;
if (t1 instanceof SimpleTensor) {
if (((SimpleTensor) t1).getName() != ((SimpleTensor) t2).getName())
return false;
if (!compareIndices(t1.getIndices(), t2.getIndices()))
return false;
}
TensorContent c1 = t1.getContent();
TensorContent c2 = t2.getContent();
if (c1.size() == 0)
return true;
if (c1 instanceof TensorSortedContent)
return compareSortedArrays((TensorSortedContent) c1, (TensorSortedContent) c2);
else
return compareOrderedArrays(c1, c2);
}
protected boolean compareIndices(Indices i1, Indices i2) {
return i1.equals(i2);
}
private boolean compareOrderedArrays(TensorContent first, TensorContent second) {
int size;
if ((size = first.size()) != second.size())
return false;
for (int i = 0; i < size; ++i)
if (!compare(first.get(i), second.get(i)))
return false;
return true;
}
private boolean compareSortedArrays(TensorSortedContent arr1, TensorSortedContent arr2) {
int size;
if ((size = arr1.size()) != arr2.size())
return false;
int[] hashArray = new int[size];
for (int i = 0; i < size; ++i)
if ((hashArray[i] = arr1.get(i).hashCode()) != arr2.get(i).hashCode())
return false;
int begin = 0, i;
for (i = 1; i <= size; ++i)
if (i == size || hashArray[i] != hashArray[i - 1]) {
if (i - 1 != begin) {
if (!comparePermutationAlgorythm(arr1, arr2, begin, i - begin))
return false;
} else if (!compare(arr1.get(i - 1), arr2.get(i - 1)))
return false;
begin = i;
}
return true;
}
private boolean comparePermutationAlgorythm(TensorSortedContent arr1, TensorSortedContent arr2, int from, int size) {
IntPermutationsGenerator enumerator = new IntPermutationsGenerator(size);
int[] permutation;
OUTFOR:
while (enumerator.hasNext()) {
permutation = enumerator.next();
for (int i = 0; i < size; ++i)
if (!compare(arr1.get(i + from), arr2.get(permutation[i] + from)))
continue OUTFOR;
return true;
}
return false;
}
}