/*
 * $Id$
 */

package edu.jas.gbufd;


import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import edu.jas.gb.ReductionAbstract;
import edu.jas.poly.ExpVector;
import edu.jas.poly.GenPolynomial;
import edu.jas.structure.RingElem;


/**
 * Polynomial pseudo reduction sequential use algorithm. Coefficients of
 * polynomials must not be from a field, i.e. the fraction free reduction is
 * implemented. Implements normalform.
 * @param  coefficient type
 * @author Heinz Kredel
 */

public class PseudoReductionPar> extends ReductionAbstract implements
                PseudoReduction {


    private static final Logger logger = Logger.getLogger(PseudoReductionPar.class);


    /**
     * Constructor.
     */
    public PseudoReductionPar() {
    }


    /**
     * Normalform.
     * @param Ap polynomial.
     * @param Pp polynomial list.
     * @return nf(Ap) with respect to Pp.
     */
    @SuppressWarnings("unchecked")
    public GenPolynomial normalform(List> Pp, GenPolynomial Ap) {
        if (Pp == null || Pp.isEmpty()) {
            return Ap;
        }
        if (Ap == null || Ap.isZERO()) {
            return Ap;
        }
        GenPolynomial[] P = new GenPolynomial[0];
        List> Ppp;
        synchronized (Pp) {
            Ppp = new ArrayList>(Pp); // sic
        }
        P = Ppp.toArray(P);
        int ll = Ppp.size();
        GenPolynomial Rz = Ap.ring.getZERO();
        GenPolynomial R = Rz.copy();

        GenPolynomial S = Ap.copy();
        while (S.length() > 0) {
            if (Pp.size() != ll) {
                //System.out.println("Pp.size() = " + Pp.size() + ", ll = " + ll);
                //long t = System.currentTimeMillis();
                synchronized (Pp) {
                    Ppp = new ArrayList>(Pp); // sic
                }
                P = Ppp.toArray(P);
                ll = Ppp.size();
                //ll = P.length; // wrong
                //t = System.currentTimeMillis()-t;
                //logger.info("Pp.toArray(): size() = " + l + ", ll = " + ll);
                S = Ap.copy(); // S.add(R)? // restart reduction ?
                R = Rz.copy();
            }
            boolean mt = false;
            Map.Entry m = S.leadingMonomial();
            ExpVector e = m.getKey();
            C a = m.getValue();
            ExpVector f = null;
            int i;
            for (i = 0; i < ll; i++) {
                f = P[i].leadingExpVector();
                mt = e.multipleOf(f);
                if (mt)
                    break;
            }
            if (!mt) {
                //System.out.println("m = " + m);
                //logger.debug("irred");
                //R = R.sum(a, e);
                //S = S.subtract(a, e);
                R.doPutToMap(e, a);
                S.doRemoveFromMap(e, a);
                //System.out.println(" S = " + S);
            } else {
                e = e.subtract(f);
                //logger.info("red div = " + e);
                C c = P[i].leadingBaseCoefficient();
                if (a.remainder(c).isZERO()) { //c.isUnit() ) {
                    a = a.divide(c);
                    S = S.subtractMultiple(a, e, P[i]);
                } else {
                    R = R.multiply(c);
                    //S = S.multiply(c);
                    S = S.scaleSubtractMultiple(c, a, e, P[i]);
                }
                //Q = p[i].multiply(a, e);
                //S = S.subtract(Q);
            }
        }
        return R;
    }


    /**
     * Normalform.
     * @param Pp polynomial list.
     * @param Ap polynomial.
     * @return ( nf(Ap), mf ) with respect to Pp and mf as multiplication factor
     *         for Ap.
     */
    @SuppressWarnings("unchecked")
    public PseudoReductionEntry normalformFactor(List> Pp, GenPolynomial Ap) {
        if (Ap == null) {
            return null;
        }
        C mfac = Ap.ring.getONECoefficient();
        PseudoReductionEntry pf = new PseudoReductionEntry(Ap, mfac);
        if (Pp == null || Pp.isEmpty()) {
            return pf;
        }
        if (Ap.isZERO()) {
            return pf;
        }
        GenPolynomial[] P = new GenPolynomial[0];
        List> Ppp;
        synchronized (Pp) {
            Ppp = new ArrayList>(Pp); // sic
        }
        P = Ppp.toArray(P);
        int l = Ppp.size();
        boolean mt = false;
        GenPolynomial Rz = Ap.ring.getZERO();
        GenPolynomial R = Rz.copy();
        //GenPolynomial T = null;
        //GenPolynomial Q = null;
        GenPolynomial S = Ap.copy();
        while (S.length() > 0) {
            if (Pp.size() != l) {
                //long t = System.currentTimeMillis();
                synchronized (Pp) {
                    Ppp = new ArrayList>(Pp);
                }
                P = Ppp.toArray(P);
                l = Ppp.size();
                //t = System.currentTimeMillis()-t;
                //logger.info("Pp.toArray() = " + t + " ms, size() = " + l);
                S = Ap.copy(); // S.add(R)? // restart reduction ?
                R = Rz.copy();
            }
            Map.Entry m = S.leadingMonomial();
            ExpVector e = m.getKey();
            C a = m.getValue();
            ExpVector f = null;
            int i;
            for (i = 0; i < l; i++) {
                f = P[i].leadingExpVector();
                mt = e.multipleOf(f);
                if (mt)
                    break;
            }
            if (!mt) {
                //logger.debug("irred");
                //R = R.sum(a, e);
                //S = S.subtract(a, e);
                R.doPutToMap(e, a);
                S.doRemoveFromMap(e, a);
                //System.out.println(" S = " + S);
            } else {
                e = e.subtract(f);
                //logger.info("red div = " + e);
                C c = P[i].leadingBaseCoefficient();
                if (a.remainder(c).isZERO()) { //c.isUnit() ) {
                    a = a.divide(c);
                    S = S.subtractMultiple(a, e, P[i]);
                } else {
                    mfac = mfac.multiply(c);
                    R = R.multiply(c);
                    //S = S.multiply(c);
                    S = S.scaleSubtractMultiple(c, a, e, P[i]);
                }
                //Q = p[i].multiply(a, e);
                //S = S.subtract(Q);
            }
        }
        if (logger.isInfoEnabled()) {
            logger.info("multiplicative factor = " + mfac);
        }
        pf = new PseudoReductionEntry(R, mfac);
        return pf;
    }


    /**
     * Normalform with recording. Note: Only meaningful if all divisions
     * are exact. Compute first the multiplication factor m with
     * normalform(Pp,Ap,m), then call this method with
     * normalform(row,Pp,m*Ap).
     * @param row recording matrix, is modified.
     * @param Pp a polynomial list for reduction.
     * @param Ap a polynomial.
     * @return nf(Pp,Ap), the normal form of Ap wrt. Pp.
     */
    @SuppressWarnings("unchecked")
    public GenPolynomial normalform(List> row, List> Pp,
                    GenPolynomial Ap) {
        throw new RuntimeException("normalform with recording not implemented");
    }

}

 

Ads help maintain this website.