Package cc.redberry.transformation.fraction

Source Code of cc.redberry.transformation.fraction.ToCommonDenominator

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

import java.util.ArrayList;
import java.util.List;
import cc.redberry.core.tensor.Fraction;
import cc.redberry.core.tensor.Product;
import cc.redberry.core.tensor.Sum;
import cc.redberry.core.tensor.Tensor;
import cc.redberry.core.tensor.TensorIterator;
import cc.redberry.core.tensor.testing.TTest;
import cc.redberry.transformation.Transformation;

/**
*
* @author Dmitry Bolotin
* @author Stanislav Poslavsky
* @author Konstantin Kiselev
*/
public class ToCommonDenominator implements Transformation {
    @Override
    public Tensor transform(Tensor tensor) {
        if (!(tensor instanceof Sum))
            return tensor;
        Fraction result = null;
        TensorIterator iterator = tensor.iterator();
        Tensor current;
        while (iterator.hasNext()) {
            current = iterator.next();
            if (current instanceof Fraction) {
                if (result == null)
                    result = (Fraction) current;
                else
                    result = sumPair(result, current);
                iterator.remove();
            }
        }
        if (result == null)
            return tensor;
        if (((Sum) tensor).isEmpty())
            return result;
        return sumPair(result, tensor.equivalent());
    }

    private Fraction sumPair(Fraction f1, Tensor f2) {
        if (f2 instanceof Fraction) {
            Fraction f2_ = (Fraction) f2;
            Struct s = calcStruct(f1.getDenominator(), f2_.getDenominator());
            return new Fraction(
                    new Sum(
                    s.firstMultiplicand == null ? f1.getNumerator() : new Product(f1.getNumerator(), s.firstMultiplicand),
                    s.secondMultiplicand == null ? f2_.getNumerator() : new Product(f2_.getNumerator(), s.secondMultiplicand)),
                    s.denominator);
        }
        Tensor f = new Product(f1.getDenominator().clone(), f2);
        return new Fraction(new Sum(f1.getNumerator(), f), f1.getDenominator());
    }

    private static Struct calcStruct(Tensor t1, Tensor t2) {
        if (t1 instanceof Product && !(t2 instanceof Product)) {
            TensorIterator iterator = t1.iterator();
            boolean commonDetected = false;
            Tensor current;
            while (iterator.hasNext()) {
                current = iterator.next();
                if (TTest.testParity(current, t2)) {
                    iterator.remove();
                    commonDetected = true;
                    break;
                }
            }
            if (commonDetected)
                return new Struct(null, t1.equivalent().clone(), new Product(t1, t2));
            else
                return new Struct(t2.clone(), t1.clone(), new Product(t1, t2));
        }
        if (!(t1 instanceof Product) && t2 instanceof Product)
            return calcStruct(t2, t1).inverse();
        if (t1 instanceof Product && t2 instanceof Product) {
            Product _t1 = (Product) t1;
            Product _t2 = (Product) t2;
            _t1.sort();
            _t2.sort();
            TensorIterator iterator1 = _t1.iterator(), iterator2 = _t2.iterator();
            Tensor current1 = iterator1.next(), current2 = iterator2.next();
            int hash1 = current1.hashCode(), hash2 = current2.hashCode(), oldSize = 0;
            boolean process = false;

            List<Tensor> common = new ArrayList<>();
            List<Tensor> equalsHash1 = new ArrayList<>();

            while (true) {
                if (hash1 < hash2) {
                    if (!iterator1.hasNext())
                        break;
                    current1 = iterator1.next();

                } else if (hash2 < hash1) {
                    if (!iterator2.hasNext())
                        break;
                    current2 = iterator2.next();
                    hash2 = current2.hashCode();
                    process = process && hash2 == equalsHash1.get(0).hashCode();
                    if (process) {
                        for (int i = equalsHash1.size() - 1; i >= oldSize; --i)
                            if (TTest.testParity(equalsHash1.get(i), current2)) {
                                iterator2.remove();
//                                current2 = iterator2.next();

                                common.add(equalsHash1.remove(i));
                                break;
                            }
                        oldSize = equalsHash1.size();
                    }
                } else if (TTest.testParity(current1, current2)) {
                    common.add(current1);
                    iterator1.remove();
                    iterator2.remove();
                    if (!iterator1.hasNext() || !iterator2.hasNext())
                        break;
                    current1 = iterator1.next();
                    current2 = iterator2.next();
                } else {
                    process = true;
                    equalsHash1.add(current1);
                    iterator1.remove();
                    if (!iterator1.hasNext())
                        continue;
                    current1 = iterator1.next();
                }
                hash1 = current1.hashCode();
                hash2 = current2.hashCode();
            }
            _t1.add(equalsHash1);
            Product denom = new Product();
            denom.add(_t1.clone());
            denom.add(_t2.clone());
            denom.add(common);
            return new Struct(
                    _t2.isEmpty() ? null : _t2.equivalent(),
                    _t1.isEmpty() ? null : _t1.equivalent(),
                    denom.equivalent());
        } else if (TTest.testParity(t1, t2))
            return new Struct(null, null, t1);
        else
            return new Struct(t2.clone(), t1.clone(), new Product(t1, t2));
    }

    private static class Struct {
        Tensor firstMultiplicand;
        Tensor secondMultiplicand;
        Tensor denominator;

        public Struct(Tensor firstMultiplicand, Tensor secondMultiplicand, Tensor denominator) {
            this.firstMultiplicand = firstMultiplicand;
            this.secondMultiplicand = secondMultiplicand;
            this.denominator = denominator;
        }

        Struct inverse() {
            Tensor temp;
            temp = firstMultiplicand;
            firstMultiplicand = secondMultiplicand;
            secondMultiplicand = temp;
            return this;
        }
    }
}
TOP

Related Classes of cc.redberry.transformation.fraction.ToCommonDenominator

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.