Package cc.redberry.core.indices

Source Code of cc.redberry.core.indices.SimpleIndicesImpl

/*
* 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.indices;

import cc.redberry.core.tensor.SimpleTensor;
import cc.redberry.core.combinatorics.Symmetries;
import cc.redberry.core.combinatorics.Symmetry;
import cc.redberry.core.utils.ArraysUtils;
import cc.redberry.core.utils.IntArrayList;

import java.util.Arrays;

/**
* This class represents ordered indices and stores indices without sorting. It
* is the most fundamental {@code Indices} implementation. It is using to
* represent {@link SimpleTensor} indices, and in contract with, for example,
* production, witch indices array can be sorted, it stores indices array in
* order, in witch they were passed in constructor.
*
* @author Dmitry Bolotin
* @author Stanislav Poslavsky
* @see SimpleIndices
* @see EmptyIndices
* @see AbstractIndices
* @see SortedIndices
*/
public final class SimpleIndicesImpl extends AbstractIndices implements SimpleIndices {
    private IndicesSymmetries symmetries = null;

    /**
     * Construct {@code SimpleIndicesImpl} instance from specified indices array
     * and with {@link Symmetries#EMPTY_SYMMETRIES}.
     *
     * @param data array of indices
     */
    SimpleIndicesImpl(int... data) {
        super(data);
        int[] toSort = new int[data.length];
        for (int i = 0; i < data.length; ++i)
            toSort[i] = data[i] & 0x7F000000;
        if (toSort.length > 100)
            ArraysUtils.timSort(toSort, data);
        else
            ArraysUtils.insertionSort(toSort, data);
        testConsistentWithException();
    }

    /**
     * Construct {@code SimpleIndicesImpl} instance from specified indices and
     * with identity symmetry.
     *
     * @param indices specified indices
     */
    SimpleIndicesImpl(Indices indices) {
        this(indices.getAllIndices().copy());
    }

    /**
     * Construct {@code SimpleIndicesImpl} instance from specified indices array
     * and with specified symmetries.
     *
     * @param data array of indices
     * @param symmetries symmetries of this indices
     */
    private SimpleIndicesImpl(int[] data, IndicesSymmetries symmetries) {
        this(data);
        this.symmetries = symmetries;
    }

    /**
     * This method allows to set {@code Symmetries} of this {@code Indices}.
     *
     * @param symmetries {@code Symmetries} to be set as {@code Symmetries} of
     * this {@code Indices}
     */
    @Override
    public void setSymmetries(IndicesSymmetries symmetries) {
        if (this.symmetries != null)
            throw new IllegalStateException("Symmetries are already set.");
        this.symmetries = symmetries;
    }

    /**
     * {@inheritDoc}
     *
     * @return {@inheritDoc}
     */
    @Override
    public IndicesSymmetries getSymmetries() {
        if (symmetries == null)
            symmetries = IndicesSymmetries.createCloneable(new IndicesTypeStructure(this));
        return symmetries;
    }

    @Override
    protected void calculateUpperLower() {
        int upperCount = 0;
        for (int index : data)
            if (index >>> 31 == 1)
                upperCount++;
        lower = new int[size - upperCount];
        upper = new int[upperCount];
        int ui = 0, li = 0;
        for (int index : data)
            if (index >>> 31 == 1)
                upper[ui++] = index;
            else
                lower[li++] = index;
    }

    /**
     * {@inheritDoc }
     */
    @Override
    public SimpleIndicesImpl clone() {
        return new SimpleIndicesImpl(Arrays.copyOf(data, size), symmetries == null ? null : symmetries.clone());
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public SimpleIndicesImpl getInverseIndices() {
        int[] dataInv = new int[size];
        for (int i = 0; i < size; ++i)
            dataInv[i] = data[i] ^ 0x80000000;
        return new SimpleIndicesImpl(dataInv, symmetries);
    }

    /**
     * {@inheritDoc }
     */
    @Override
    public SimpleIndicesImpl getFreeIndices() {
        IntArrayList dataList = new IntArrayList();
        boolean y;
        for (int i = 0; i < size; i++) {
            y = true;
            for (int j = 0; j < size; j++)
                if (i != j && (data[i] ^ data[j]) == 0x80000000) {
                    y = false;
                    break;
                }
            if (y)
                dataList.add(data[i]);
        }
        return new SimpleIndicesImpl(dataList.toArray(), symmetries);
    }

    @Override
    protected void _update() {
        sorted = null;
    }
    private int[] sorted = null;

    @Override
    protected int[] getSortedData() {
        if (sorted == null) {
            sorted = Arrays.copyOf(data, size);
            Arrays.sort(sorted);
        }
        return sorted;
    }

    @Override
    public void testConsistentWithException() {
        for (int i = 0; i < size - 1; ++i)
            for (int j = i + 1; j < size; ++j)
                if (data[i] == data[j])
                    throw new InconsistentIndicesException(data[i]);
    }

    @Override
    public boolean equalsWithSymmetries(Indices indices) {
        return _equalsWithSymmetries(indices) == Boolean.FALSE;
    }

    /**
     * More informative method, comparing indices using their symmetries lists.
     * It returns
     * <code>Boolean.FALSE</code> if indices are equals this,
     * <code>Boolean.TRUE</code> if indices differs from this on -1 (i.e. on odd
     * transposition) and
     * <code>null</code> in other case.
     *
     * @param indices indices to compare with this
     * @return
     * <code>Boolean.FALSE</code> if indices are equals this,
     * <code>Boolean.TRUE</code> if indices differs from this on -1 (i.e. on odd
     * transposition) and
     * <code>null</code> in other case.
     */
    public Boolean _equalsWithSymmetries(Indices indices) {
        if (indices.getClass() != this.getClass())
            return null;
        if (size != indices.size())
            return null;
        SimpleIndicesImpl _indices = (SimpleIndicesImpl) indices;
        boolean sign1;
        out_level_0:
        for (Symmetry s1 : symmetries) {
            sign1 = s1.isAntiSymmetry();
            for (int i = 0; i < size; ++i)
                if (data[s1.newIndexOf(i)] != (_indices).data[i])
                    continue;
            return Boolean.valueOf(sign1);
        }
        return null;
    }

    @Override
    public short[] getDiffIds() {
        return symmetries.getDiffIds();
    }
}
TOP

Related Classes of cc.redberry.core.indices.SimpleIndicesImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.