/*
* 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.context.OutputFormat;
import cc.redberry.core.indices.Indices;
import cc.redberry.core.number.Complex;
import cc.redberry.core.utils.ArraysUtils;
import cc.redberry.core.utils.TensorHashCalculator;
import cc.redberry.core.utils.TensorUtils;
import java.util.Arrays;
/**
* Representation of sum.
*
* @author Dmitry Bolotin
* @author Stanislav Poslavsky
* @since 1.0
*/
public final class Sum extends MultiTensor {
final Tensor[] data;
final int hash;
Sum(final Tensor[] data, Indices indices) {
super(indices);
assert data.length > 1;
this.data = data;
TensorWrapper[] wrappers = new TensorWrapper[data.length];
int i;
for (i = 0; i < data.length; ++i)
wrappers[i] = new TensorWrapper(data[i]);
ArraysUtils.quickSort(wrappers, data);
this.hash = Arrays.hashCode(data);
}
Sum(Indices indices, Tensor[] data, int hash) {
super(indices);
assert data.length > 1;
this.data = data;
this.hash = hash;
}
private static final class TensorWrapper implements Comparable {
final Tensor tensor;
final int hashWithIndices;
public TensorWrapper(Tensor tensor) {
this.tensor = tensor;
hashWithIndices = TensorHashCalculator.hashWithIndices(tensor);
}
@Override
public int compareTo(TensorWrapper o) {
int i = tensor.compareTo(o.tensor);
if (i != 0)
return i;
return Integer.compare(hashWithIndices, o.hashWithIndices);
}
}
@Override
public Tensor[] toArray() {
return data.clone();
}
@Override
public Tensor get(int i) {
return data[i];
}
@Override
public int size() {
return data.length;
}
@Override
public Tensor[] getRange(int from, int to) {
return Arrays.copyOfRange(data, from, to);
}
@Override
public Tensor set(int i, Tensor tensor) {
// return super.set(i, tensor);
if (i >= data.length || i < 0)
throw new IndexOutOfBoundsException();
Tensor old = data[i];
if (old == tensor)
return this;
if (TensorUtils.equalsExactly(old, tensor))
return this;
if (TensorUtils.isIndeterminate(tensor))
return tensor;
if (TensorUtils.isZero(tensor))
return remove(i);
Tensor[] newData = data.clone();
newData[i] = tensor;
if (TensorUtils.equals(old, tensor))
return new Sum(newData, indices);
return Tensors.sum(newData);
}
@Override
public Tensor remove(int i) {
if (i >= data.length || i < 0)
throw new IndexOutOfBoundsException();
if (data.length == 2)
return data[1 - i];
Tensor[] newData = new Tensor[data.length - 1];
System.arraycopy(data, 0, newData, 0, i);
if (i < data.length - 1)
System.arraycopy(data, i + 1, newData, i, data.length - i - 1);
return new Sum(newData, indices);
}
@Override
protected Tensor remove1(final int[] positions) {
Tensor[] newData = new Tensor[data.length - positions.length];
int pointer = 0, counter = -1;
for (int i = 0; i < data.length; ++i)
if (pointer < positions.length && i == positions[pointer]) {
++pointer;
continue;
} else newData[++counter] = data[i];
if (newData.length == 1) return newData[0];
return new Sum(newData, indices);
}
@Override
protected Complex getNeutral() {
return Complex.ZERO;
}
@Override
protected Tensor select1(int[] positions) {
Tensor[] newData = new Tensor[positions.length];
int i = -1;
for (int position : positions)
newData[++i] = data[position];
return new Sum(newData, indices);
}
@Override
public int hash() {
return hash;
}
@Override
public TensorBuilder getBuilder() {
return new SumBuilder(data.length);
}
@Override
public TensorFactory getFactory() {
return SumFactory.FACTORY;
}
@Override
public String toString(OutputFormat mode) {
StringBuilder sb = new StringBuilder();
String temp;
for (int i = 0; ; ++i) {
temp = get(i).toString(mode, Sum.class);
if ((temp.charAt(0) == '-' || temp.charAt(0) == '+') && sb.length() != 0)
sb.deleteCharAt(sb.length() - 1);
String str = get(i).toString(mode, Sum.class);
if (str.contains("'") && !mode.printMatrixIndices)
return toString(mode.printMatrixIndices());
sb.append(str);
if (i == size() - 1)
return sb.toString();
sb.append('+');
}
}
@Override
protected String toString(OutputFormat mode, Class extends Tensor> clazz) {
if (clazz == Power.class || clazz == Product.class)
return "(" + toString(mode) + ")";
else
return toString(mode);
}
}
Ads help maintain this website.