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.
| 150 | // Our original Cauchy matrix does not contain 0, so we skip search |
| 151 | // for non-zero pivot. |
| 152 | void 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 |
nothing calls this directly
no outgoing calls
no test coverage detected