Пример #1
0
        // Construct the Vandermonde matrix and solve it if necessary
        public bool Compute()
        {
            uint outcount = datamissing + parmissing;
            uint incount  = datapresent + datamissing;

            if (datamissing > parpresent)
            {
                //cerr << "Not enough recovery blocks." << endl;
                return(false);
            }
            else if (outcount == 0)
            {
                //cerr << "No output blocks." << endl;
                return(false);
            }

            //if (noiselevel > CommandLine::nlQuiet)
            //  cout << "Computing Reed Solomon matrix." << endl;

            /*  Layout of RS Matrix:
             *
             *                                   parpresent
             *                 datapresent       datamissing         datamissing       parmissing
             *           /                     |             \ /                     |           \
             * parpresent  |           (ppi[row])|             | |           (ppi[row])|           |
             * datamissing |          ^          |      I      | |          ^          |     0     |
             |(dpi[col])           |             | |(dmi[col])           |           |
             +---------------------+-------------+ +---------------------+-----------+
             |           (pmi[row])|             | |           (pmi[row])|           |
             | parmissing  |          ^          |      0      | |          ^          |     I     |
             |(dpi[col])           |             | |(dmi[col])           |           |
             \                     |             / \                     |           /
             */

            // Allocate the left hand matrix

            //leftmatrix = new Galois16[outcount * incount];
            leftmatrix = new ushort[outcount * incount];
            for (int i = 0; i < outcount * incount; ++i)
            {
                //leftmatrix[i] = new Galois16(0);
                leftmatrix[i] = 0;
            }

            // Allocate the right hand matrix only if we are recovering

            //Galois16[] rightmatrix = null;
            ushort[] rightmatrix = null;
            if (datamissing > 0)
            {
                //rightmatrix = new Galois16[outcount * outcount];
                rightmatrix = new ushort[outcount * outcount];

                for (int i = 0; i < outcount * outcount; ++i)
                {
                    //rightmatrix[i] = new Galois16(0);
                    rightmatrix[i] = 0;
                }
            }

            // Fill in the two matrices:

            // One row for each present recovery block that will be used for a missing data block
            for (uint row = 0; row < datamissing; row++)
            {
                RSOutputRow outputrow = outputrows[(int)row];

                // Define MPDL to skip reporting and speed things up
                //#ifndef MPDL
                //    if (noiselevel > CommandLine::nlQuiet)
                //    {
                //      int progress = row * 1000 / (datamissing+parmissing);
                //      cout << "Constructing: " << progress/10 << '.' << progress%10 << "%\r" << flush;
                //    }
                //#endif

                // Get the exponent of the next present recovery block
                while (!outputrow.present)
                {
                    outputrow = outputrows[(int)++row];
                }

                ushort exponent = outputrow.exponent;

                // One column for each present data block
                for (uint col = 0; col < datapresent; col++)
                {
                    //leftmatrix[row * incount + col] = Galois16.Pow(new Galois16(database[datapresentindex[col]]), new Galois16(exponent));
                    leftmatrix[row * incount + col] = processor.Pow(database[datapresentindex[col]], exponent);
                }

                // One column for each each present recovery block that will be used for a missing data block
                for (uint col = 0; col < datamissing; col++)
                {
                    //leftmatrix[row * incount + col + datapresent] = (row == col) ? 1 : 0;
                    leftmatrix[row * incount + col + datapresent] = (ushort)(row == col ? 1 : 0);
                }

                if (datamissing > 0)
                {
                    // One column for each missing data block
                    for (uint col = 0; col < datamissing; col++)
                    {
                        //rightmatrix[row * outcount + col] = Galois16.Pow(new Galois16(database[datamissingindex[col]]), new Galois16(exponent));
                        rightmatrix[row * outcount + col] = processor.Pow(database[datamissingindex[col]], exponent);
                    }
                    // One column for each missing recovery block
                    for (uint col = 0; col < parmissing; col++)
                    {
                        rightmatrix[row * outcount + col + datamissing] = 0;
                    }
                }
            }

            // One row for each recovery block being computed
            for (uint row = 0; row < parmissing; row++)
            {
                RSOutputRow outputrow = outputrows[(int)row];

                // Define MPDL to skip reporting and speed things up
                //#ifndef MPDL
                //if (noiselevel > CommandLine::nlQuiet)
                //{
                //  int progress = (row+datamissing) * 1000 / (datamissing+parmissing);
                //  cout << "Constructing: " << progress/10 << '.' << progress%10 << "%\r" << flush;
                //}
                //#endif

                // Get the exponent of the next missing recovery block
                while (outputrow.present)
                {
                    outputrow = outputrows[(int)++row];
                }
                ushort exponent = outputrow.exponent;

                // One column for each present data block
                for (uint col = 0; col < datapresent; col++)
                {
                    //leftmatrix[(row + datamissing) * incount + col] = Galois16.Pow(new Galois16(database[datapresentindex[col]]), new Galois16(exponent));
                    leftmatrix[(row + datamissing) * incount + col] = processor.Pow(database[datapresentindex[col]], exponent);
                }
                // One column for each each present recovery block that will be used for a missing data block
                for (uint col = 0; col < datamissing; col++)
                {
                    leftmatrix[(row + datamissing) * incount + col + datapresent] = 0;
                }

                if (datamissing > 0)
                {
                    // One column for each missing data block
                    for (uint col = 0; col < datamissing; col++)
                    {
                        //rightmatrix[(row + datamissing) * outcount + col] = Galois16.Pow(new Galois16(database[datamissingindex[col]]), new Galois16(exponent));
                        rightmatrix[(row + datamissing) * outcount + col] = processor.Pow(database[datamissingindex[col]], exponent);
                    }
                    // One column for each missing recovery block
                    for (uint col = 0; col < parmissing; col++)
                    {
                        //rightmatrix[(row + datamissing) * outcount + col + datamissing] = (row == col) ? 1 : 0;
                        rightmatrix[(row + datamissing) * outcount + col + datamissing] = (ushort)(row == col ? 1 : 0);
                    }
                }

                //row++;
            }

//#if TRACE
//            LogArrayToFile<Galois16>(@"leftmatrix.before.gauss.log", leftmatrix);
//            LogArrayToFile<Galois16>(@"rightmatrix.before.gauss.log", rightmatrix);
//#endif

            //if (noiselevel > CommandLine::nlQuiet)
            //  cout << "Constructing: done." << endl;

            // Solve the matrices only if recovering data
            if (datamissing > 0)
            {
                // Perform Gaussian Elimination and then delete the right matrix (which
                // will no longer be required).
                //bool success = ReedSolomon.GaussElim(noiselevel, outcount, incount, leftmatrix, rightmatrix, datamissing);
                bool success = ReedSolomon.GaussElim(outcount, incount, leftmatrix, rightmatrix, datamissing);
                //return success;
            }

//#if TRACE
//            LogArrayToFile<Galois16>(@"leftmatrix.after.gauss.log", leftmatrix);
//            LogArrayToFile<Galois16>(@"rightmatrix.after.gauss.log", rightmatrix);
//#endif

            return(true);
        }