/*
 * Redberry: symbolic tensor computations.
 *
 * Copyright (c) 2010-2015:
 *   Stanislav Poslavsky   
 *   Bolotin Dmitriy       
 *
 * 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 .
 */
package cc.redberry.core.tensor;

import cc.redberry.core.utils.HashFunctions;

import java.util.Arrays;

/**
 * @author Dmitry Bolotin
 * @author Stanislav Poslavsky
 * @since 1.0
 */
public final class TensorContraction implements Comparable {
    public final short tensorId; //aka stretch Id
    public final long[] indexContractions;
    private int hash = -1;

    public TensorContraction(final short tensorId, final long[] indexContractions) {
        this.tensorId = tensorId;
        this.indexContractions = indexContractions;
    }

    void sortContractions() {
        Arrays.sort(indexContractions);
    }

    public boolean containsFreeIndex() {
        for (long contraction : indexContractions)
            if (getToTensorId(contraction) == -1)
                return true;
        return false;
    }

    @Override
    public boolean equals(final Object obj) {
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        if (hashCode() != obj.hashCode())
            return false;
        final TensorContraction other = (TensorContraction) obj;
        if (tensorId != other.tensorId)
            return false;
        return Arrays.equals(indexContractions, other.indexContractions);
    }

    @Override//TODO improve hashCode(), may be precalculate with indices diff ids
    public int hashCode() {
        if (hash == -1) {
            long hash = 1L;
            for (long l : indexContractions)
                hash ^= HashFunctions.JenkinWang64shift(l);
            this.hash = HashFunctions.Wang64to32shift(hash);
        }
        return hash;

    }

    @Override
    public int compareTo(final TensorContraction o) {
        int val;
        if ((val = Integer.compare(tensorId, o.tensorId)) != 0)
            return val;
        if ((val = Integer.compare(indexContractions.length, o.indexContractions.length)) != 0)
            return val;
        for (int i = 0; i < indexContractions.length; ++i)
            if ((val = Long.compare(indexContractions[i], o.indexContractions[i])) != 0)
                return val;
        return 0;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        if (indexContractions.length == 0)
            return builder.append(tensorId).append("x").toString();
        builder.append(tensorId).append("x{");
        for (long l : indexContractions) {
            builder.append("^").append(getFromIndexId(l)).append("->").append(getToTensorId(l)).append("^").append(getToIndexId(l));
            builder.append(":");
        }
        builder.deleteCharAt(builder.length() - 1);
        builder.append("}");
        return builder.toString();
    }

    public static short getFromIndexId(final long contraction) {
        return (short) ((contraction >> 32) & 0xFFFF);
    }

    public static short getToIndexId(final long contraction) {
        return (short) (contraction & 0xFFFF);
    }

    public static short getToTensorId(final long contraction) {
        return (short) ((contraction >> 16) & 0xFFFF);
    }
}

 

Ads help maintain this website.