Inverse of an s16.16 3x3 matrix, in s16.16, computed without floats.
The float-free half of P9 item 2 (FastLED#4043). buildRgbSolveMatrixQ16 still reaches this through invert3x3; a bind path that never touches float calls it directly.
False on a singular matrix, on a coefficient too large for s16.16, and on any input whose exact cofactors or determinant do not fit an i64. That last case is detected rather than bounded away: a deep-blue emitter at xy = (0.14, 0.03) already has a Z column near 28, so a fixed input limit generous enough to be safe would reject real parts.
212 {
213 const i32 a = in[0][0], b = in[0][1], c = in[0][2];
214 const i32 d = in[1][0], e = in[1][1], f = in[1][2];
215 const i32
g = in[2][0], h = in[2][1], i_ = in[2][2];
216
217
219 if (!cofactorQ32(e, i_, f, h, &cof[0][0]) ||
220 !cofactorQ32(c, h, b, i_, &cof[0][1]) ||
221 !cofactorQ32(b, f, c, e, &cof[0][2]) ||
222 !cofactorQ32(f,
g, d, i_, &cof[1][0]) ||
223 !cofactorQ32(a, i_, c,
g, &cof[1][1]) ||
224 !cofactorQ32(c, d, a, f, &cof[1][2]) ||
225 !cofactorQ32(d, h, e,
g, &cof[2][0]) ||
226 !cofactorQ32(b,
g, a, h, &cof[2][1]) ||
227 !cofactorQ32(a, e, b, d, &cof[2][2])) {
228 return false;
229 }
230
231
232 const i32 first_row[3] = {a, b, c};
234 for (int col = 0; col < 3; ++col) {
235 const i64 term_lhs =
static_cast<i64>(first_row[col]);
237 return false;
238 }
239 const i64 term = term_lhs * cof[col][0];
241 return false;
242 }
243 determinant += term;
244 }
245 if (determinant == 0) {
246 return false;
247 }
248
249 for (int row = 0; row < 3; ++row) {
250 for (int col = 0; col < 3; ++col) {
252
253
254
257 return false;
258 }
259 out[row][col] =
static_cast<i32
>(
value);
260 }
261 }
262 return true;
263}
bool sumFitsI64(i64 a, i64 b) FL_NO_EXCEPT
Does a + b fit an i64, for operands already known to be in range?
bool productFitsI64(i64 a, i64 b) FL_NO_EXCEPT
Does a * b fit an i64?
i64 divideCoefficientQ16(i64 cofactor_q32, i64 determinant_q48) FL_NO_EXCEPT
round(cofactor_q32 * 2^32 / determinant_q48), in s16.16, without a 128-bit intermediate.
constexpr i32 kMaxCoefficient
Largest coefficient magnitude the build accepts, in whole units.
constexpr int type_rank< T >::value