Package cc.redberry.core.context

Source Code of cc.redberry.core.context.Context$emptyTensor

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

import cc.redberry.core.combinatorics.Symmetry;
import cc.redberry.core.indices.*;
import cc.redberry.core.parser.Parser;
import cc.redberry.core.tensor.*;

import java.util.Arrays;

public final class Context {
    private final Parser parser;
    private final IndexConverterManager symbolConverter;
    private final NameManager nameManager;

    public static enum Regim {
        TESTING,
        NORMAL
    }

    //Bindings defaults
    private final ToStringMode defaultPrintMode;
    private final String imageOne;
    private final String kroneckerName;
    //Optional defaults
    private final String metricName;
    private final byte[] metricTypes;
    private volatile int[] metricNames, kroneckerNames;
    private volatile Regim regim;
    private final String workingFolder;
    private final String mapleDirectory;

    public Context(ContextSettings contextSettings) {
        //Bindings
        imageOne = contextSettings.getImageOne();
        defaultPrintMode = contextSettings.getDefaultToStringMode();
        kroneckerName = contextSettings.getKronecker();
        //Optional
        regim = contextSettings.getRegim();
        metricName = contextSettings.getMetricName();
        //Creating parser
        parser = new Parser(contextSettings.getParsers());
        //Creating symbol converter
        symbolConverter = new IndexConverterManager(contextSettings.getConverters());
        metricTypes = contextSettings.getMetricTypes();
        nameManager = new NameManager(this, contextSettings.getNameManagerSeed());
        nameManager.registerNewNameDescriptorListener(new MetricKroneckerListener());
        workingFolder = contextSettings.getWorkingFolder();
        mapleDirectory = contextSettings.getMapleDirectory();
    }

    /**
     * This method resets all tensor names.
     * <p/>
     * <br/><b>Any tensor created before this method call becomes invalid, and
     * must not be used!</b> <br/><br/>Mainly this method used in unit tests, so
     * avoid using this method in your code.
     */
    public synchronized void resetTensorNames() {
        nameManager.reset();
        metricNames = null;
        kroneckerNames = null;
    }

    public Regim getRegim() {
        return regim;
    }

    public void setRegim(Regim regim) {
        this.regim = regim;
    }

    public String getImageOne() {
        return imageOne;
    }

    public IndexConverterManager getIndexConverterManager() {
        return symbolConverter;
    }

    public ToStringMode getDefaultPrintMode() {
        return defaultPrintMode;
    }

    public NameManager getNameManager() {
        return nameManager;
    }

    public NameDescriptor getNameDescriptor(int nameId) {
        return nameManager.getNameDescriptor(nameId);
    }

    public String getKroneckerName() {
        return kroneckerName;
    }

    public boolean withMetric() {
        return metricName != null;
    }

    public String getMetricName() {
        return metricName;
    }

    public boolean isKronecker(SimpleTensor t) {
        if (kroneckerNames == null)
            return false;
        // kroneckerNames naturally sorted
        return Arrays.binarySearch(kroneckerNames, t.getName()) >= 0;
    }

    public boolean isMetric(SimpleTensor t) {
        if (metricNames == null)
            return false;
        // metricNames naturally sorted
        synchronized (this) {
            return Arrays.binarySearch(metricNames, t.getName()) >= 0;
        }
    }

    public SimpleTensor createKronecker(int index1, int index2) {
        if (IndicesUtils.getType(index1) != IndicesUtils.getType(index2) || IndicesUtils.getRawStateInt(index1) == IndicesUtils.getRawStateInt(index2))
            throw new IllegalArgumentException("This is not kronecker indices!");
        SimpleIndices indices = IndicesFactory.createSimple(index1, index2);
        NameDescriptor nd = new NameDescriptor(kroneckerName, new IndicesTypeStructure(indices));
        int name = nameManager.mapNameDescriptor(nd);
        return new SimpleTensor(name, indices);
    }

    public SimpleTensor createMetric(int index1, int index2) {
        byte type;
        if ((type = IndicesUtils.getType(index1)) != IndicesUtils.getType(index2)
                || IndicesUtils.getRawStateInt(index1) != IndicesUtils.getRawStateInt(index2)
                || Arrays.binarySearch(metricTypes, type) < 0)
            throw new IllegalArgumentException("This is not metric indices!");
        SimpleIndices indices = IndicesFactory.createSimple(index1, index2);
        NameDescriptor nd = new NameDescriptor(metricName, new IndicesTypeStructure(indices));
        int name = nameManager.mapNameDescriptor(nd);
        return new SimpleTensor(name, indices);
    }

    public SimpleTensor createMetricOrKronecker(int index1, int index2) {
        if (IndicesUtils.getRawStateInt(index1) == IndicesUtils.getRawStateInt(index2))
            return createMetric(index1, index2);
        return createKronecker(index1, index2);
    }

    public Tensor parse(String expression) {
        return parser.parse(expression);
    }

    public SimpleTensor parseSimple(String expression) {
        Tensor t = parser.parse(expression);
        if (t instanceof SimpleTensor)
            return (SimpleTensor) t;
        throw new RuntimeException("Not simple tensor");
    }

    public void addSymmetry(String tensor, IndexType type, boolean sign, int... permutation) {
        SimpleTensor st = (SimpleTensor) parse(tensor);
        addSymmetry(st, type, sign, permutation);
    }

    public void addSymmetry(SimpleTensor st, IndexType type, boolean sign, int... permutation) {
        addSymmetry(st, type, new Symmetry(permutation, sign));
    }

    public void addSymmetry(String tensor, IndexType type, Symmetry symmetry) {
        addSymmetry((SimpleTensor) parse(tensor), type, symmetry);
    }

    public void addSymmetry(SimpleTensor st, IndexType type, Symmetry symmetry) {
        st.getIndices().getSymmetries().add(type.getType(), symmetry);
    }

    public SimpleTensor createSimpleTensor(String name, SimpleIndices indices) {
        NameDescriptor descriptor = new NameDescriptor(name, new IndicesTypeStructure(indices));
        int tensorName = nameManager.mapNameDescriptor(descriptor);
        //dumping symmetries
        SimpleIndices nIndices = IndicesFactory.createSimple(indices);
        //creating simple and binding nIndices and descriptor symmetries
        SimpleTensor t = new SimpleTensor(tensorName, nIndices);
        //adding additional symmetries
        nIndices.getSymmetries().addAllUnsafe(indices.getSymmetries());
        return t;
    }

    public TensorField createTensorField(int name, SimpleIndices indices, Tensor... args) {
        if (!nameManager.containtsNameId(name))
            throw new RuntimeException("int name does not matches any tensor in context namespace");
        NameDescriptor descriptor = nameManager.getNameDescriptor(name);
        int tensorName = nameManager.mapNameDescriptor(descriptor);
        return new TensorField(tensorName, indices, args);
    }

    public static Context get() {
        return ContextManager.getCurrentContext();
    }

    public String getMapleDirectory() {
        return mapleDirectory;
    }

    public String getWorkingFolder() {
        return workingFolder;
    }

    /**
     * Parent for all root tensors.
     *
     * @return parent for all root tensors
     */
    public Tensor getRootParentTensor() {
        return emptyTensor.INSTANCE;
    }

    private class MetricKroneckerListener implements NewNameDescriptorListener {
        @Override
        public void newNameDescriptor(NameDescriptor descriptor) {
            if (descriptor.getIndexTypeStructure().size() != 2)
                return;
            byte type;
            if (metricName != null && descriptor.getName().equals(metricName)) {
                if (Arrays.binarySearch(metricTypes, type = descriptor.getIndexTypeStructure().get(0)) < 0
                        || type != descriptor.getIndexTypeStructure().get(1)
                        || descriptor.getIndexTypeStructure().size() != 2)
                    return;
                if (descriptor.getIndexTypeStructure().get(0) != descriptor.getIndexTypeStructure().get(1))
                    throw new IllegalArgumentException("Wrong metric.");
                descriptor.addSymmetry(
                        type, new Symmetry(new int[]{1, 0}, false));
                if (metricNames == null)
                    metricNames = new int[]{descriptor.getId()};
                else {
                    metricNames = Arrays.copyOf(metricNames, metricNames.length + 1);
                    metricNames[metricNames.length - 1] = descriptor.getId();
                    Arrays.sort(metricNames);
                }
            } else if (descriptor.getName().equals(kroneckerName)) {
                if (descriptor.getIndexTypeStructure().size() != 2
                        || (type = descriptor.getIndexTypeStructure().get(0)) != descriptor.getIndexTypeStructure().get(1))
                    return;
                if (descriptor.getIndexTypeStructure().get(0) != descriptor.getIndexTypeStructure().get(1))
                    throw new IllegalArgumentException("Wrong kronecker.");
                descriptor.addSymmetry(type, new Symmetry(new int[]{1, 0}, false));
                if (kroneckerNames == null)
                    kroneckerNames = new int[]{descriptor.getId()};
                else {
                    kroneckerNames = Arrays.copyOf(kroneckerNames, kroneckerNames.length + 1);
                    kroneckerNames[kroneckerNames.length - 1] = descriptor.getId();
                    Arrays.sort(kroneckerNames);
                }

            }
        }
    }

    private static class emptyTensor extends Tensor {
        public static final Tensor INSTANCE = new emptyTensor();

        @Override
        public void update() {
        }

        @Override
        public Tensor clone() {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        @Override
        public Indices getIndices() {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        @Override
        protected int hash() {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        @Override
        public AbstractTensorIterator iterator() {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        @Override
        public String toString(ToStringMode mode) {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        @Override
        public String toString() {
            return "null parent expression";
        }

        @Override
        public TensorContentImpl getContent() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }

    ;
}
TOP

Related Classes of cc.redberry.core.context.Context$emptyTensor

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.