MCPcopy Create free account
hub / github.com/abbeycode/UnrarKit / InvertDecoderMatrix

Method InvertDecoderMatrix

Libraries/unrar/rs16.cpp:152–215  ·  view source on GitHub ↗

Apply Gauss�Jordan elimination to find inverse of decoder matrix. We have the square NDxND matrix, but we do not store its trivial diagonal "1" rows matching valid data, so we work with NExND matrix. Our original Cauchy matrix does not contain 0, so we skip search for non-zero pivot.

Source from the content-addressed store, hash-verified

150// Our original Cauchy matrix does not contain 0, so we skip search
151// for non-zero pivot.
152void RSCoder16::InvertDecoderMatrix()
153{
154 uint *MI=new uint[NE * ND]; // We'll create inverse matrix here.
155 memset(MI, 0, ND * NE * sizeof(*MI)); // Initialize to identity matrix.
156 for (uint Kr = 0, Kf = 0; Kr < NE; Kr++, Kf++)
157 {
158 while (ValidFlags[Kf]) // Skip trivial rows.
159 Kf++;
160 MI[Kr * ND + Kf] = 1; // Set diagonal 1.
161 }
162
163 // Kr is the number of row in our actual reduced NE x ND matrix,
164 // which does not contain trivial diagonal 1 rows.
165 // Kf is the number of row in full ND x ND matrix with all trivial rows
166 // included.
167 for (uint Kr = 0, Kf = 0; Kf < ND; Kr++, Kf++) // Select pivot row.
168 {
169 while (ValidFlags[Kf] && Kf < ND)
170 {
171 // Here we process trivial diagonal 1 rows matching valid data units.
172 // Their processing can be simplified comparing to usual rows.
173 // In full version of elimination we would set MX[I * ND + Kf] to zero
174 // after MI[..]^=, but we do not need it for matrix inversion.
175 for (uint I = 0; I < NE; I++)
176 MI[I * ND + Kf] ^= MX[I * ND + Kf];
177 Kf++;
178 }
179
180 if (Kf == ND)
181 break;
182
183 uint *MXk = MX + Kr * ND; // k-th row of main matrix.
184 uint *MIk = MI + Kr * ND; // k-th row of inversion matrix.
185
186 uint PInv = gfInv( MXk[Kf] ); // Pivot inverse.
187 // Divide the pivot row by pivot, so pivot cell contains 1.
188 for (uint I = 0; I < ND; I++)
189 {
190 MXk[I] = gfMul( MXk[I], PInv );
191 MIk[I] = gfMul( MIk[I], PInv );
192 }
193
194 for (uint I = 0; I < NE; I++)
195 if (I != Kr) // For all rows except containing the pivot cell.
196 {
197 // Apply Gaussian elimination Mij -= Mkj * Mik / pivot.
198 // Since pivot is already 1, it is reduced to Mij -= Mkj * Mik.
199 uint *MXi = MX + I * ND; // i-th row of main matrix.
200 uint *MIi = MI + I * ND; // i-th row of inversion matrix.
201 uint Mik = MXi[Kf]; // Cell in pivot position.
202 for (uint J = 0; J < ND; J++)
203 {
204 MXi[J] ^= gfMul(MXk[J] , Mik);
205 MIi[J] ^= gfMul(MIk[J] , Mik);
206 }
207 }
208 }
209

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected