putNonScalar(tensor);
}
private void putNonScalar(Tensor tensor) {
Indices freeIndices = tensor.getIndices().getFree();
TIntHashSet freeSet = new TIntHashSet(freeIndices.getAllIndices().copy());
// Firstly we should check whether adding
// specified tensor will merge some of the
// existing components,
// e.g. if component1 = F_mn*A^n
// component2 = H_ij
// tensor = X^im
// then two of the existing components must be
// merged into resulting
// component = F_mn*A^n*H_ij*X^im
//components that will be merged
Set<Component> toMerge = new HashSet<>();
Component component;
int index;
if (!indexToComponent.isEmpty())
// for each free index in tensor
for (TIntIterator iterator = freeSet.iterator(); iterator.hasNext(); ) {
index = iterator.next();
// this assertion case corresponds to the inconsistent
// indices exception
//todo discuss with Dima, may be we must to throw exception here?
assert !indexToComponent.containsKey(index);
index = IndicesUtils.inverseIndexState(index);
component = indexToComponent.remove(index);
if (component != null) {
// free index of tensor (e.g. ^i) is
// contracted with index (_i) in component
// as result, this index is not free now
//removing not free from the set of free indices of tensor
iterator.remove();
//removing not free from the set of free indices of component
component.freeIndices.remove(index);
//the component should be merged with this tensor
toMerge.add(component);
}
}
if (toMerge.isEmpty()) {
//no any intersections found
//so, tensor forms the new connected component
component = new Component(tensor, freeSet);
//for each free index of tensor
for (TIntIterator iterator = freeSet.iterator(); iterator.hasNext(); ) {
index = iterator.next();
//we should add the entry new free index <-> new component
//to the index <-> component mapping
indexToComponent.put(index, component);
}
//adding new unique component to the set of unique components
components.add(component);
return;
}
// At this point toMerge is not empty
// we shall merge all of the components from the toMerge
// set into the first component in the toMerge set
Iterator<Component> iterator = toMerge.iterator();
//taking the first component in the toMerge set
component = iterator.next();
//adding new tensor to this component
component.elements.add(tensor);
//adding all of the new free indices to the free indices of component
component.freeIndices.addAll(freeSet);
// We should add additional entries for the new free
// indices into the free index <-> component mapping
//for each new free index
for (TIntIterator tit = freeSet.iterator(); tit.hasNext(); ) {
index = tit.next();
//adding additional entries for new free
//indices in the free index <-> component mapping
indexToComponent.put(index, component);
}