Package cc.redberry.core.tensor

Source Code of cc.redberry.core.tensor.Sum

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

import java.util.Collection;
import cc.redberry.core.context.CC;
import cc.redberry.core.context.Context;
import cc.redberry.core.context.ToStringMode;
import cc.redberry.core.indices.EmptyIndices;
import cc.redberry.core.indices.Indices;
import cc.redberry.core.indices.IndicesFactory;
import cc.redberry.core.utils.HashFunctions;

/**
* This class is the representation of sum.
*
* @author Dmitry Bolotin
* @author Stanislav Poslavsky
* @see Tensor
* @see MultiTensor
*/
public final class Sum extends MultiTensor {
    private TensorSortedContent content;

    /**
     * Constructs empty sum with specified parent tensor.
     *
     * @param parent parent tensor
     */
    public Sum(Tensor parent) {
        this.parent = parent;
    }

    /**
     * Constructs empty sum with {@link CC#getRootParentTensor() } as parent
     * tensor.
     */
    public Sum() {
        this(Context.get().getRootParentTensor());
    }

    /**
     * Constructs sum from specified collection and with specified parent tensor
     *
     * @param tensors specified collection of tensors
     * @param parent parent tensor
     */
    public Sum(Collection<? extends Tensor> tensors, Tensor parent) {
        this.parent = parent;
        for (Tensor tensor : tensors)
            add(tensor);
    }

    /**
     * Constructs sum from specified collection and with
     * {@link CC#getRootParentTensor() } as parent tensor.
     *
     * @param tensors specified collection of tensors
     */
    public Sum(Collection<? extends Tensor> tensors) {
        this(tensors, Context.get().getRootParentTensor());
    }

    /**
     * Constructs sum of two specified tensors with
     * {@link CC#getRootParentTensor() } as parent tensor.
     *
     * @param tensor1 first summand
     * @param tensor2 second summand
     */
    public Sum(Tensor tensor1, Tensor tensor2) {
        this.parent = CC.getRootParentTensor();
        add(tensor1);
        add(tensor2);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected char getSymbol() {
        return '+';
    }

    @Override
    protected void calculateHash() {
        hash = 0;
        for (Tensor t : getElements())
            hash ^= t.hash();
        hash = HashFunctions.JenkinWang32shift(hash);
        hashUptodate = true;
    }

    @Override
    String toString(ToStringMode mode, Class<? extends Tensor> clazz) {
        if (clazz == Product.class || clazz == Fraction.class)
            return "(" + toString(mode) + ")";
        return toString(mode);
    }

    /**
     * Returns implementation of {@code TensorSortedContentWithDataImpl}.
     *
     * @return implementation of {@code TensorSortedContentWithDataImpl}
     * @see TensorSortedContentWithDataImpl
     */
    @Override
    public TensorSortedContent getContent() {
        if (content == null)
            content = new TensorSortedContentImpl(false, getElements().toArray(new Tensor[size()]));
        return content;
    }

    @Override
    public void update() {
        content = null;
        super.update();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Sum clone() {
        Sum s = new Sum();
        for (Tensor t : this)
            s.add(t.clone());
        if (this.indices != null)
            s.indices = this.indices.clone();
        s.hashUptodate = hashUptodate;
        if (hashUptodate)
            s.hash = this.hash;
        return s;
    }

    /**
     * Returns zero if size of this sum equals zero, {@code getElements().get(0)}
     * if size of this sum equals one, and returns this in other case.
     *
     * @return zero if size of this sum equals zero, {@code getElements().get(0)}
     * if size of this sum equals one, and returns this in other case
     */
    @Override
    public Tensor equivalent() {
        switch (getElements().size()) {
            case 0:
                return TensorNumber.createZERO(parent);
            case 1:
                return getElements().get(0);
        }
        return this;
    }

    @Override
    protected void updateIndices() {
        indices = IndicesFactory.createSorted(getElements().get(0).getIndices().getFreeIndices());
        testConsistent();
    }

    private void testConsistent() {
        boolean isSymbol = (indices instanceof EmptyIndices);
        boolean b = true;
        for (Tensor t : this) {
            Indices ind = t.getIndices().getFreeIndices();
            if (!indices.equalsIgnoreOrder(ind))
                b = false;
            // Take care if sum e.g. a+h^i_i that indices will not be EmptyIndices (sum is not symbol)
            if (isSymbol && !(ind instanceof EmptyIndices)) {
                isSymbol = false;
                indices = ind;
            }
        }
        if (!b)
            throw new TensorException("Different free indices of summands", this);
    }
}
TOP

Related Classes of cc.redberry.core.tensor.Sum

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.