All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cc.redberry.core.indexmapping.Mapping Maven / Gradle / Ivy

Go to download

Redberry is an open source computer algebra system designed for tensor manipulation. It implements basic computer algebra system routines as well as complex tools for real computations in physics. This is Redberry core, which contains the implementation of the basic computer algebra routines and general-purpose transformations.

There is a newer version: 1.1.10
Show newest version
/*
 * Redberry: symbolic tensor computations.
 *
 * Copyright (c) 2010-2014:
 *   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.indexmapping;

import cc.redberry.core.indices.IndicesUtils;
import cc.redberry.core.tensor.ApplyIndexMapping;
import cc.redberry.core.tensor.Tensor;
import cc.redberry.core.transformations.Transformation;
import cc.redberry.core.utils.ArraysUtils;
import cc.redberry.core.utils.IntArray;
import gnu.trove.iterator.TIntObjectIterator;
import gnu.trove.map.hash.TIntObjectHashMap;

import java.util.Arrays;

/**
 * This is the main class which represents the mapping from one tensor to another.
 * 

* {@code Mapping} implements {@code Transformation} and perform transformation by simple invocation of * {@link ApplyIndexMapping#applyIndexMappingAutomatically(cc.redberry.core.tensor.Tensor, Mapping)} ))} with * {@code this} as a second argument. *

*

* The underlying data structure is a * simple pair of sorted arrays {@code fromNames} and {@code toData}, such that i-th mapping entry is * {@code fromNames[i] -> toData[i]}. The array {@code fromNames} contains from indices names. The array {@code toData} * contains names of to indices where the first bit indicates whether the state of from index should be inverted. *

* * @author Dmitry Bolotin * @author Stanislav Poslavsky * @since 1.1.5 */ public final class Mapping implements Transformation { final int[] fromNames, toData; final boolean sign; /** * Identity mapping */ public static final Mapping IDENTITY = new Mapping(new int[0], new int[0], false, false); /** * Creates mapping from given {@code from} and {@code to} arrays of indices. * * @param from indices from * @param to indices to */ public Mapping(int[] from, int[] to) { this(from, to, false); } /** * Creates mapping from given {@code from} and {@code to} arrays of indices. * * @param from indices from * @param to indices to * @param sign the sign of mapping */ public Mapping(final int[] from, final int[] to, final boolean sign) { if (from.length != to.length) throw new IllegalArgumentException("From length != to length."); fromNames = new int[from.length]; toData = new int[from.length]; for (int i = 0; i < from.length; ++i) { fromNames[i] = IndicesUtils.getNameWithType(from[i]); toData[i] = IndicesUtils.getRawStateInt(from[i]) ^ to[i]; } ArraysUtils.quickSort(fromNames, toData); this.sign = sign; } Mapping(IndexMappingBuffer buffer) { TIntObjectHashMap map = buffer.getMap(); fromNames = new int[map.size()]; toData = new int[map.size()]; TIntObjectIterator iterator = map.iterator(); int i = 0; IndexMappingBufferRecord record; while (iterator.hasNext()) { iterator.advance(); record = iterator.value(); fromNames[i] = iterator.key(); toData[i] = record.getRawDiffStateBit() | record.getIndexName(); ++i; } ArraysUtils.quickSort(fromNames, toData); sign = buffer.getSign(); } private Mapping(int[] fromNames, int[] toData, boolean sign, boolean o) { this.fromNames = fromNames; this.toData = toData; this.sign = sign; } @Override public Tensor transform(Tensor t) { return ApplyIndexMapping.applyIndexMappingAutomatically(t, this); } /** * Returns {@code true} if this mapping does not contain any entries (however, it can have negative sign). * * @return {@code true} if this mapping does not contain any entries (however, it can have negative sign) * @see #isIdentity() */ public boolean isEmpty() {return fromNames.length == 0;} /** * Returns {@code true} if this mapping does not contain any entries and have positive sign. * * @return {@code true} if this mapping does not contain any entries and have positive sign. */ public boolean isIdentity() {return fromNames.length == 0 && !sign;} /** * Returns the sign of this mapping * * @return sign of this mapping */ public boolean getSign() {return sign;} /** * Returns mapping, formed from this mapping by multiplying by specified sign. * * @param sign false - plus, true - minus one * @return a new mapping, formed from this mapping by multiplying by specified sign */ public Mapping addSign(boolean sign) { return new Mapping(fromNames, toData, sign ^ this.sign, true); } /** * Returns the number of entries in this mapping. * * @return the number of entries in this mapping */ public int size() {return fromNames.length;} /** * Returns the names of from indices. * * @return names of from indices */ public IntArray getFromNames() { return new IntArray(fromNames); } /** * Returns the data array that represents to indices. * * @return data array that represents to indices. */ public IntArray getToData() { return new IntArray(toData); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Mapping mapping = (Mapping) o; if (sign != mapping.sign) return false; if (!Arrays.equals(fromNames, mapping.fromNames)) return false; if (!Arrays.equals(toData, mapping.toData)) return false; return true; } @Override public int hashCode() { int result = Arrays.hashCode(fromNames); result = 31 * result + Arrays.hashCode(toData); result = 31 * result + (sign ? 1 : 0); return result; } @Override public String toString() { int imax = fromNames.length - 1; if (imax == -1) { if (sign) return "-{}"; else return "{}"; } StringBuilder sb = new StringBuilder(); if (sign) sb.append("-"); sb.append("{"); for (int i = 0; ; ++i) { sb.append(IndicesUtils.toString(fromNames[i])); sb.append("->"); sb.append(IndicesUtils.toString(toData[i])); if (i == imax) break; sb.append(", "); } sb.append("}"); return sb.toString(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy