24 template <
typename Real>
28 typedef std::array<std::array<Real, 3>, 3>
Matrix;
31 uint32_t
operator() (uint32_t maxIterations, Real c0, Real c1, Real c2,
32 uint32_t& numRoots, std::array<Real, 3>& roots);
37 uint32_t
operator() (uint32_t maxIterations, Matrix& A,
38 uint32_t& numRoots, std::array<Real, 3>& roots);
41 void DoIteration(std::array<Real, 3>
const& V, Matrix& A);
44 std::array<Real, N>
House(std::array<Real, N>
const& X);
47 void RowHouse(
int rmin,
int rmax,
int cmin,
int cmax,
48 std::array<Real, N>
const& V, std::array<Real, N>
const& MV, Matrix& A);
51 void ColHouse(
int rmin,
int rmax,
int cmin,
int cmax,
52 std::array<Real, N>
const& V, std::array<Real, N>
const& MV, Matrix& A);
55 uint32_t& numRoots, std::array<Real, 3>& roots);
59 template <
typename Real>
61 uint32_t& numRoots, std::array<Real, 3>& roots)
78 std::array<Real, 3> V{
80 (Real)0.36602540378443865,
81 (Real)0.36602540378443865 };
84 return operator()(maxIterations, A, numRoots, roots);
87 template <
typename Real>
89 uint32_t& numRoots, std::array<Real, 3>& roots)
92 std::fill(roots.begin(), roots.end(), (Real)0);
94 for (uint32_t numIterations = 0; numIterations < maxIterations; ++numIterations)
97 Real tr = A[1][1] + A[2][2];
98 Real det = A[1][1] * A[2][2] - A[1][2] * A[2][1];
99 std::array<Real, 3> X{
100 A[0][0] * A[0][0] + A[0][1] * A[1][0] - tr * A[0][0] + det,
101 A[1][0] * (A[0][0] + A[1][1] - tr),
103 std::array<Real, 3> V = House<3>(X);
107 Real tr01 = A[0][0] + A[1][1];
108 if (tr01 + A[1][0] == tr01)
113 return numIterations;
116 Real tr12 = A[1][1] + A[2][2];
117 if (tr12 + A[2][1] == tr12)
122 return numIterations;
125 return maxIterations;
128 template <
typename Real>
131 Real multV = ((Real)-2) / (V[0] * V[0] + V[1] * V[1] + V[2] * V[2]);
132 std::array<Real, 3> MV{ multV * V[0], multV * V[1], multV * V[2] };
133 RowHouse<3>(0, 2, 0, 2, V, MV, A);
134 ColHouse<3>(0, 2, 0, 2, V, MV, A);
136 std::array<Real, 2> Y{ A[1][0], A[2][0] };
137 std::array<Real, 2> W = House<2>(Y);
138 Real multW = ((Real)-2) / (W[0] * W[0] + W[1] * W[1]);
139 std::array<Real, 2> MW{ multW * W[0], multW * W[1] };
140 RowHouse<2>(1, 2, 0, 2, W, MW, A);
141 ColHouse<2>(0, 2, 1, 2, W, MW, A);
144 template <
typename Real>
148 std::array<Real, N> V;
150 for (
int i = 0; i < N; ++i)
152 length += X[i] * X[i];
154 length = sqrt(length);
155 if (length != (Real)0)
157 Real sign = (X[0] >= (Real)0 ? (Real)1 : (Real)-1);
158 Real denom = X[0] + sign *
length;
159 for (
int i = 1; i < N; ++i)
168 template <
typename Real>
171 std::array<Real, N>
const& V, std::array<Real, N>
const& MV,
Matrix& A)
173 std::array<Real, 3> W;
175 for (
int c = cmin;
c <= cmax; ++
c)
178 for (
int r = rmin, k = 0;
r <= rmax; ++
r, ++k)
180 W[
c] += V[k] * A[
r][
c];
184 for (
int r = rmin, k = 0;
r <= rmax; ++
r, ++k)
186 for (
int c = cmin;
c <= cmax; ++
c)
188 A[
r][
c] += MV[k] * W[
c];
193 template <
typename Real>
196 std::array<Real, N>
const& V, std::array<Real, N>
const& MV,
Matrix& A)
198 std::array<Real, 3> W;
200 for (
int r = rmin;
r <= rmax; ++
r)
203 for (
int c = cmin, k = 0;
c <= cmax; ++
c, ++k)
205 W[
r] += V[k] * A[
r][
c];
209 for (
int r = rmin;
r <= rmax; ++
r)
211 for (
int c = cmin, k = 0;
c <= cmax; ++
c, ++k)
213 A[
r][
c] += W[
r] * MV[k];
218 template <
typename Real>
220 uint32_t& numRoots, std::array<Real, 3>& roots)
228 Real trace = A[i0][i0] + A[i1][i1];
229 Real halfTrace = trace * (Real)0.5;
230 Real determinant = A[i0][i0] * A[i1][i1] - A[i0][i1] * A[i1][i0];
231 Real discriminant = halfTrace * halfTrace - determinant;
232 if (discriminant >= (Real)0)
234 Real sign = (trace >= (Real)0 ? (Real)1 : (Real)-1);
235 Real root = halfTrace + sign * sqrt(discriminant);
236 roots[numRoots++] = root;
237 roots[numRoots++] = trace - root;
void GetQuadraticRoots(int i0, int i1, Matrix const &A, uint32_t &numRoots, std::array< Real, 3 > &roots)
void ColHouse(int rmin, int rmax, int cmin, int cmax, std::array< Real, N > const &V, std::array< Real, N > const &MV, Matrix &A)
GLuint GLsizei GLsizei * length
std::array< Real, N > House(std::array< Real, N > const &X)
void DoIteration(std::array< Real, 3 > const &V, Matrix &A)
std::array< std::array< Real, 3 >, 3 > Matrix
void RowHouse(int rmin, int rmax, int cmin, int cmax, std::array< Real, N > const &V, std::array< Real, N > const &MV, Matrix &A)
uint32_t operator()(uint32_t maxIterations, Real c0, Real c1, Real c2, uint32_t &numRoots, std::array< Real, 3 > &roots)