org.tensorics.core.tensor.lang.TensorStructurals Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tensorics-core Show documentation
Show all versions of tensorics-core Show documentation
Tensorics is a java framework which uses a tensor as a central object. A tensor represents a set of values placed in an N-dimensional space. Wherever you are tempted to use maps of maps, a tensor might be a good choice ;-) Tensorics provides methods to create, transform and performing calculations with those tensors.
// @formatter:off
/*******************************************************************************
*
* This file is part of tensorics.
*
* Copyright (c) 2008-2011, CERN. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
// @formatter:on
package org.tensorics.core.tensor.lang;
import java.util.HashSet;
import java.util.Map.Entry;
import java.util.Set;
import java.util.function.Function;
import org.tensorics.core.tensor.Context;
import org.tensorics.core.tensor.ImmutableTensor;
import org.tensorics.core.tensor.ImmutableTensor.Builder;
import org.tensorics.core.tensor.Position;
import org.tensorics.core.tensor.Tensor;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
/**
* Structural manipulations of tensors (which do not require any knowledge about the mathematical behaviour of the
* elements).
*
* @author kfuchsbe, mihostet
*/
public final class TensorStructurals {
/**
* Private constructor to avoid instantiation
*/
private TensorStructurals() {
/* only static methods */
}
public static OngoingTensorManipulation from(Tensor tensor) {
return new OngoingTensorManipulation<>(tensor);
}
/**
* Merges the given set of the Tensors based on information in their context and dimensions. This operation is only
* possible, if the following preconditions are fulfilled:
*
* - The contexts of all the tensors have THE SAME dimensions
AND
* - The dimensions of all the tensors are THE SAME (first found tensor dimension is taken as an reference)
*
Tensor merge(Iterable> tensors) {
if (Iterables.isEmpty(tensors) || Iterables.size(tensors) == 1) {
throw new IllegalArgumentException("Cannot merge empty or one element list of tensors!");
}
Tensor firstTensor = tensors.iterator().next();
Set> refDimensionSet = firstTensor.shape().dimensionSet();
Position refContextPosition = firstTensor.context().getPosition();
Set> outcomeDimensionSet = new HashSet<>(refDimensionSet);
Set> dimensionSet = refContextPosition.dimensionSet();
if (dimensionSet.isEmpty()) {
throw new IllegalArgumentException("Cannot merge tensors with empty context!");
}
outcomeDimensionSet.addAll(dimensionSet);
Builder tensorBuilder = ImmutableTensor.builder(outcomeDimensionSet);
for (Tensor oneTensor : tensors) {
if (TensorStructurals.isValidInTermsOfDimensions(oneTensor, refDimensionSet,
refContextPosition.dimensionSet())) {
tensorBuilder.putAllAt(oneTensor, oneTensor.context().getPosition());
} else {
throw new IllegalArgumentException(
"One of the tensors in the provided list does not fit the others on dimensions."
+ " Cannot continiue merging" + oneTensor);
}
}
return tensorBuilder.build();
}
/**
* Checks if the provided tensor has: the same dimension as the reference dimensions, equal number of them, as well
* as equal number of Context Position dimension and referenceContext Position and their dimensionality.
*
* @param tensor the tensor to check
* @param refDimensions the dimensions that the tensor should have
* @param refContextDimensions the context position the context dimensions, to which the tensor shall be compatible
* @return {@code true} if the conditions are fulfilled, {@code false} if not.
*/
private static boolean isValidInTermsOfDimensions(Tensor tensor, Set> refDimensions,
Set> refContextDimensions) {
Set> tensorDimensionSet = tensor.shape().dimensionSet();
Set> contextPositionDimensionSet = tensor.context().getPosition().dimensionSet();
return (tensorDimensionSet.equals(refDimensions) && contextPositionDimensionSet.equals(refContextDimensions));
}
public static OngoingFlattening flatten(Tensor tensor) {
return new OngoingFlattening(tensor);
}
public static final OngoingCompletion complete(Tensor tensor) {
return new OngoingCompletion(tensor);
}
public static Tensor transformEntries(Tensor tensor, Function, T> function) {
Builder builder = ImmutableTensor.builder(tensor.shape().dimensionSet());
for (Entry entry : tensor.asMap().entrySet()) {
builder.putAt(function.apply(entry), entry.getKey());
}
return builder.build();
}
public static Tensor transformScalars(Tensor tensor, Function function) {
Builder builder = ImmutableTensor.builder(tensor.shape().dimensionSet());
builder.setTensorContext(tensor.context());
for (Entry entry : tensor.asMap().entrySet()) {
builder.putAt(function.apply(entry.getValue()), entry.getKey());
}
return builder.build();
}
public static final Tensor stripContext(Tensor tensor) {
Builder builder = ImmutableTensor.builder(tensor.shape().dimensionSet());
builder.putAll(tensor);
return builder.build();
}
public static final Tensor mergeContextIntoShape(Tensor tensor) {
if (tensor.context().getPosition().coordinates().isEmpty()) {
throw new IllegalArgumentException("an empty context can't be merged into the positions");
}
Builder builder = ImmutableTensor
.builder(Sets.union(tensor.shape().dimensionSet(), tensor.context().getPosition().dimensionSet()));
builder.putAllAt(tensor, tensor.context().getPosition());
return builder.build();
}
public static final Tensor setContext(Tensor tensor, Context context) {
Builder builder = ImmutableTensor.builder(tensor.shape().dimensionSet());
builder.setTensorContext(context);
builder.putAll(tensor);
return builder.build();
}
public static final OngoingTensorFiltering filter(Tensor tensor) {
return new OngoingTensorFiltering<>(tensor);
}
}