Package pl.mkaczara.bch.math

Examples of pl.mkaczara.bch.math.GF2ToM


    }

    @Override
    public BinPolynomial decode(BinPolynomial input) throws UncorrectableErrorsException {
        //Cialo z definicji kodu
        GF2ToM gf = getCode().getGF();

        //Syndromy
        HashMap<Integer, Integer> syndromesToAlphaPowers = new HashMap<>();
        boolean errors = false;

        //Poszukiwanie syndromow S(1) - S(2T)
        for (int i = 1; i <= 2 * getCode().getT(); i++) {
            BinPolynomial currSyndrom = new BinPolynomial(0);
            for (int j = 0; j < getCode().getN(); j++) {
                //S(i) = R(j) * (S(i) + alfa(i*j))
                if (input.getCoefficient(j)) {
                    currSyndrom = currSyndrom.add(gf.getAlpha((i * j) % getCode().getN()));
                }
            }
            //Czy sa bledy
            if (currSyndrom.getPolyVector().compareTo(BigInteger.ZERO) != 0) {
                errors = true;
            }
            //Zapis potegi alfy zgodnej z syndromem na pozycji i-tej
            syndromesToAlphaPowers.put(i, gf.getPower(currSyndrom));
        }

        //Nie ma bledow
        if (!errors) {
            return getData(input);
        }

        //Tablica na wielomian lokalizacji bledow + listy pomocnicze
        int[][] errLocPoly = new int[getCode().getT() * 4 + 4][getCode().getT() * 2];
        ArrayList<Integer> discrepancy = new ArrayList<>();
        ArrayList<Integer> errLocPolyDeg = new ArrayList<>();
        ArrayList<Integer> degStepDiff = new ArrayList<>();

        //D
        discrepancy.add(0, 0);
        discrepancy.add(1, syndromesToAlphaPowers.get(1));

        //Pierwszy wyraz wielomianu = 1 (wolny)
        errLocPoly[1][0] = 1;
        //Pierwszy indeks potegi = 0
        errLocPoly[0][0] = 0;


        for (int i = 1; i < 2 * getCode().getT(); i++) {
            //Pozostale wsp wielomianu = 0
            errLocPoly[1][i] = 0;
            //Pozostale potegi = -1 (dla zerowych wsp wielomianu
            errLocPoly[0][i] = -1;
        }

        //Stopien wielomianu dla 0 i 1-szego wyrazu = 0
        errLocPolyDeg.add(0, 0);
        errLocPolyDeg.add(1, 0);

        //Odleglosc stopnia wielomianu bledu od kroku
        degStepDiff.add(0, -1);
        degStepDiff.add(1, 0);

        //Start, dopoki nie 2t i stopien wielomianu lokalizacji bledow <= T
        int currStep = 0;
        do {
            currStep++;
            //Jezeli D dla current step == -1
            if (discrepancy.get(currStep) == -1) {
                //Przepisanie stopnia wielomianu do nastepnego kroku
                errLocPolyDeg.add(currStep + 1, errLocPolyDeg.get(currStep));
                //Przepisanie wrtosci
                for (int i = 0; i <= errLocPolyDeg.get(currStep); i++) {
                    errLocPoly[currStep + 1][i] = errLocPoly[currStep][i];
                    errLocPoly[currStep][i] = gf.getPower(errLocPoly[currStep][i]);
                }
            } else {
                //Szukamy poprzednich krokow z D > 0
                int prevStep = currStep - 1;
                while ((discrepancy.get(prevStep) == -1) && (prevStep > 0)) {
                    prevStep--;
                }

                //D > 0 - szukamy poprzedniego kroku z max rożnicą: stopien - krok
                if (prevStep > 0) {
                    int j = prevStep;
                    while (j > 0) {
                        j--;
                        if ((discrepancy.get(j) != -1) && (degStepDiff.get(prevStep) < degStepDiff.get(j))) {
                            prevStep = j;
                        }
                    }
                }

                //Przeliczenie stopnia wielomianu lokalizacji bledow
                if (errLocPolyDeg.get(currStep) > errLocPolyDeg.get(prevStep) + currStep - prevStep) {
                    errLocPolyDeg.add(currStep + 1, errLocPolyDeg.get(currStep));
                } else {
                    errLocPolyDeg.add(currStep + 1, errLocPolyDeg.get(prevStep) + currStep - prevStep);
                }

                //Wszystkie nowe wsp. wielomianu to 0
                for (int i = 0; i < 2 * getCode().getT(); i++) {
                    errLocPoly[currStep + 1][i] = 0;
                }

                //Obliczenie nowych wsp. wielomianu na podstawie wsp. wielomianu ze znalezionego poprzedniego kroku
                for (int i = 0; i <= errLocPolyDeg.get(prevStep); i++) {
                    //Jeżeli jakaś sensowna potęga alfy z poprzedniego kroku
                    if (errLocPoly[prevStep][i] != -1) {
                        errLocPoly[currStep + 1][i + currStep - prevStep] = gf.getAlpha((discrepancy.get(currStep) + getCode().getN() - discrepancy.get(prevStep) + errLocPoly[prevStep][i]) % getCode().getN()).toUInt();
                    }
                }

                //Przepisanie wrtosci
                for (int i = 0; i <= errLocPolyDeg.get(currStep); i++) {
                    errLocPoly[currStep + 1][i] ^= errLocPoly[currStep][i];
                    errLocPoly[currStep][i] = gf.getPower(errLocPoly[currStep][i]);
                }
            }
            //Roznica: stopien - krok dla nastepnego kroku
            degStepDiff.add(currStep + 1, currStep - errLocPolyDeg.get(currStep + 1));

            //Krok mniejszy od 2T - mamy jeszcze syndromy - liczymy D
            if (currStep < 2 * getCode().getT()) {
                //Jezeli potega alfy powiazanej z syndromem jest jakaś sensowna
                if (syndromesToAlphaPowers.get(currStep + 1) != -1) {
                    discrepancy.add(currStep + 1, gf.getAlpha(syndromesToAlphaPowers.get(currStep + 1)).toUInt());
                } else {
                    discrepancy.add(currStep + 1, 0);
                }
                //D - dodawanie alf
                for (int i = 1; i <= errLocPolyDeg.get(currStep + 1); i++) {
                    if ((syndromesToAlphaPowers.get(currStep + 1 - i) != -1) && (errLocPoly[currStep + 1][i] != 0)) {
                        discrepancy.add(currStep + 1, discrepancy.get(currStep + 1) ^ gf.getAlpha((syndromesToAlphaPowers.get(currStep + 1 - i) + gf.getPower(errLocPoly[currStep + 1][i])) % getCode().getN()).toUInt());
                    }
                }
                //Zapis potegi dla alfy wyniku, wartosc niepotrzebna
                discrepancy.add(currStep + 1, gf.getPower(discrepancy.get(currStep + 1)));
            }
        } while ((currStep < 2 * getCode().getT()) && (errLocPolyDeg.get(currStep + 1) <= getCode().getT()));

        currStep++;
        //Warunek mozliwosci poprawy bledow
        if (errLocPolyDeg.get(currStep) <= getCode().getT()) {
            //Wspolczynniki wielomianu lokalizacji bledu jako potegi alf
            for (int i = 0; i <= errLocPolyDeg.get(currStep); i++) {
                errLocPoly[currStep][i] = gf.getPower(errLocPoly[currStep][i]);
            }

            //Algorytm Chien, szukanie alfa, dla ktorego wielomian lokalizacji bledow da 0 + inwersja (N - i)
            ArrayList<Integer> errorLocations = new ArrayList<>();
            for (int i = 1; i <= getCode().getN(); i++) {
                int result = 1;
                for (int j = 1; j <= errLocPolyDeg.get(currStep); j++) {
                    //Jezeli potega skojarzona z alfa jest sensowna
                    if (errLocPoly[currStep][j] != -1) {
                        errLocPoly[currStep][j] = (errLocPoly[currStep][j] + j) % getCode().getN();
                        result ^= gf.getAlpha(errLocPoly[currStep][j]).toUInt();
                    }
                }
                //alfa rozwiazaniem, wiec N-i => lokalizacja bledu
                if (result == 0) {
                    errorLocations.add(getCode().getN() - i);
View Full Code Here

TOP

Related Classes of pl.mkaczara.bch.math.GF2ToM

Copyright © 2018 www.massapicom. 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.