30 template <
typename Real>
35 Real
const* M, Real* inverseM, Real& determinant,
36 Real
const* B, Real* X,
37 Real
const* C,
int numCols, Real* Y)
const;
49 template <
typename Real>
51 Real* inverseM, Real& determinant, Real
const* B, Real* X, Real
const* C,
52 int numCols, Real* Y)
const 54 if (numRows <= 0 || !M
55 || ((B !=
nullptr) != (X !=
nullptr))
56 || ((C !=
nullptr) != (Y !=
nullptr))
57 || (C !=
nullptr && numCols < 1))
63 int numElements = numRows * numRows;
64 bool wantInverse = (inverseM !=
nullptr);
65 std::vector<Real> localInverseM;
68 localInverseM.resize(numElements);
69 inverseM = localInverseM.data();
71 Set(numElements, M, inverseM);
80 Set(numRows * numCols, C, Y);
83 #if defined(GTE_USE_ROW_MAJOR) 91 std::vector<int> colIndex(numRows), rowIndex(numRows), pivoted(numRows);
92 std::fill(pivoted.begin(), pivoted.end(), 0);
94 Real
const zero = (Real)0;
95 Real
const one = (Real)1;
100 int i1, i2,
row = 0, col = 0;
101 for (
int i0 = 0; i0 < numRows; ++i0)
104 Real maxValue = zero;
105 for (i1 = 0; i1 < numRows; ++i1)
109 for (i2 = 0; i2 < numRows; ++i2)
113 Real absValue =
std::abs(matInvM(i1, i2));
114 if (absValue > maxValue)
125 if (maxValue == zero)
130 Set(numElements,
nullptr, inverseM);
136 Set(numRows,
nullptr, X);
141 Set(numRows * numCols,
nullptr, Y);
152 for (
int i = 0; i < numRows; ++i)
154 std::swap(matInvM(row, i), matInvM(col, i));
159 std::swap(X[row], X[col]);
164 for (
int i = 0; i < numCols; ++i)
166 std::swap(matY(row, i), matY(col, i));
176 Real diagonal = matInvM(col, col);
177 determinant *= diagonal;
178 Real inv = one / diagonal;
179 matInvM(col, col) = one;
180 for (i2 = 0; i2 < numRows; ++i2)
182 matInvM(col, i2) *= inv;
192 for (i2 = 0; i2 < numCols; ++i2)
194 matY(col, i2) *= inv;
199 for (i1 = 0; i1 < numRows; ++i1)
203 Real save = matInvM(i1, col);
204 matInvM(i1, col) = zero;
205 for (i2 = 0; i2 < numRows; ++i2)
207 matInvM(i1, i2) -= matInvM(col, i2) * save;
212 X[i1] -= X[col] * save;
217 for (i2 = 0; i2 < numCols; ++i2)
219 matY(i1, i2) -= matY(col, i2) * save;
229 for (i1 = numRows - 1; i1 >= 0; --i1)
231 if (rowIndex[i1] != colIndex[i1])
233 for (i2 = 0; i2 < numRows; ++i2)
235 std::swap(matInvM(i2, rowIndex[i1]),
236 matInvM(i2, colIndex[i1]));
244 determinant = -determinant;
250 template <
typename Real>
254 if (std::is_floating_point<Real>() == std::true_type())
257 size_t numBytes = numElements *
sizeof(Real);
260 Memcpy(target, source, numBytes);
264 memset(target, 0, numBytes);
273 for (
int i = 0; i < numElements; ++i)
275 target[i] = source[i];
280 Real
const zero = (Real)0;
281 for (
int i = 0; i < numElements; ++i)
gte::BSNumber< UIntegerType > abs(gte::BSNumber< UIntegerType > const &number)
void Set(int numElements, Real const *source, Real *target) const
GLsizei GLsizei GLchar * source
GLenum GLenum GLsizei void * row
#define LogError(message)
void Memcpy(void *target, void const *source, size_t count)
bool operator()(int numRows, Real const *M, Real *inverseM, Real &determinant, Real const *B, Real *X, Real const *C, int numCols, Real *Y) const