Package cc.redberry.core.indexmapping

Source Code of cc.redberry.core.indexmapping.Mapping

/*
* Redberry: symbolic tensor computations.
*
* Copyright (c) 2010-2013:
*   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.indexmapping;

import cc.redberry.core.indices.IndicesUtils;
import cc.redberry.core.tensor.ApplyIndexMapping;
import cc.redberry.core.tensor.Tensor;
import cc.redberry.core.transformations.Transformation;
import cc.redberry.core.utils.ArraysUtils;
import cc.redberry.core.utils.IntArray;
import gnu.trove.iterator.TIntObjectIterator;
import gnu.trove.map.hash.TIntObjectHashMap;

import java.util.Arrays;

/**
* This is the main class which represents the mapping from one tensor to another.
* <p>
* {@code Mapping} implements {@code Transformation} and perform transformation by simple invocation of
* {@link ApplyIndexMapping#applyIndexMappingAutomatically(cc.redberry.core.tensor.Tensor, Mapping)} ))} with
* {@code this} as a second argument.
* </p>
* <p>
* The underlying data structure is a
* simple pair of sorted arrays {@code fromNames} and {@code toData}, such that <i>i</i>-th mapping entry is
* {@code fromNames[i] -> toData[i]}. The array {@code fromNames} contains from indices names. The array {@code toData}
* contains names of to indices where the first bit indicates whether the state of from index should be inverted.
* </p>
*
* @author Dmitry Bolotin
* @author Stanislav Poslavsky
* @since 1.1.5
*/
public final class Mapping implements Transformation {
    final int[] fromNames, toData;
    final boolean sign;
    /**
     * Identity mapping
     */
    public static final Mapping IDENTITY = new Mapping(new int[0], new int[0], false, false);

    /**
     * Creates mapping from given {@code from} and {@code to} arrays of indices.
     *
     * @param from indices from
     * @param to   indices to
     */
    public Mapping(int[] from, int[] to) {
        this(from, to, false);
    }

    /**
     * Creates mapping from given {@code from} and {@code to} arrays of indices.
     *
     * @param from indices from
     * @param to   indices to
     * @param sign the sign of mapping
     */
    public Mapping(final int[] from, final int[] to, final boolean sign) {
        if (from.length != to.length)
            throw new IllegalArgumentException("From length != to length.");

        fromNames = new int[from.length];
        toData = new int[from.length];
        for (int i = 0; i < from.length; ++i) {
            fromNames[i] = IndicesUtils.getNameWithType(from[i]);
            toData[i] = IndicesUtils.getRawStateInt(from[i]) ^ to[i];
        }
        ArraysUtils.quickSort(fromNames, toData);
        this.sign = sign;
    }

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

    private Mapping(int[] fromNames, int[] toData, boolean sign, boolean o) {
        this.fromNames = fromNames;
        this.toData = toData;
        this.sign = sign;
    }

    @Override
    public Tensor transform(Tensor t) {
        return ApplyIndexMapping.applyIndexMappingAutomatically(t, this);
    }

    /**
     * Returns {@code true} if this mapping does not contain any entries (however, it can have negative sign).
     *
     * @return {@code true} if this mapping does not contain any entries (however, it can have negative sign)
     * @see #isIdentity()
     */
    public boolean isEmpty() {return fromNames.length == 0;}

    /**
     * Returns {@code true} if this mapping does not contain any entries and have positive sign.
     *
     * @return {@code true} if this mapping does not contain any entries and have positive sign.
     */
    public boolean isIdentity() {return fromNames.length == 0 && !sign;}

    /**
     * Returns the sign of this mapping
     *
     * @return sign of this mapping
     */
    public boolean getSign() {return sign;}

    /**
     * Returns mapping, formed from this mapping by multiplying by specified sign.
     *
     * @param sign false - plus, true - minus one
     * @return a new mapping, formed from this mapping by multiplying by specified sign
     */
    public Mapping addSign(boolean sign) {
        return new Mapping(fromNames, toData, sign ^ this.sign, true);
    }

    /**
     * Returns the number of entries in this mapping.
     *
     * @return the number of entries in this mapping
     */
    public int size() {return fromNames.length;}

    /**
     * Returns the names of from indices.
     *
     * @return names of from indices
     */
    public IntArray getFromNames() {
        return new IntArray(fromNames);
    }

    /**
     * Returns the data array that represents to indices.
     *
     * @return data array that represents to indices.
     */
    public IntArray getToData() {
        return new IntArray(toData);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Mapping mapping = (Mapping) o;

        if (sign != mapping.sign) return false;
        if (!Arrays.equals(fromNames, mapping.fromNames)) return false;
        if (!Arrays.equals(toData, mapping.toData)) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = Arrays.hashCode(fromNames);
        result = 31 * result + Arrays.hashCode(toData);
        result = 31 * result + (sign ? 1 : 0);
        return result;
    }

    @Override
    public String toString() {
        int imax = fromNames.length - 1;
        if (imax == -1) {
            if (sign)
                return "-{}";
            else return "{}";
        }

        StringBuilder sb = new StringBuilder();
        if (sign)
            sb.append("-");
        sb.append("{");
        for (int i = 0; ; ++i) {
            sb.append(IndicesUtils.toString(fromNames[i]));
            sb.append("->");
            sb.append(IndicesUtils.toString(toData[i]));
            if (i == imax)
                break;
            sb.append(",");
        }
        sb.append("}");
        return sb.toString();
    }
}
TOP

Related Classes of cc.redberry.core.indexmapping.Mapping

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.