107 template <
typename Real>
124 unsigned int Solve(Real
const*
input,
int sortType);
160 void GetSinCos(Real u, Real
v, Real& cs, Real& sn);
227 template <
typename Real>
229 unsigned int maxIterations)
235 if (size > 1 && maxIterations > 0)
242 mGivens.reserve(maxIterations * (size - 1));
251 template <
typename Real>
263 int imin = -1, imax = -1;
264 for (
int i = mSize - 2; i >= 0; --i)
309 template <
typename Real>
312 if (eigenvalues &&
mSize > 0)
317 for (
int i = 0; i <
mSize; ++i)
326 size_t numBytes =
mSize*
sizeof(Real);
332 template <
typename Real>
335 if (eigenvectors &&
mSize > 0)
338 std::fill(eigenvectors, eigenvectors +
mSize*
mSize, (Real)0);
339 for (
int d = 0; d <
mSize; ++d)
341 eigenvectors[d + mSize*d] = (Real)1;
346 for (
int i = mSize - 3, rmin = i + 1; i >= 0; --i, --rmin)
350 Real twoinvvdv = column[mSize*(i + 1)];
351 for (r = 0; r < i + 1; ++
r)
362 for (r = 0; r <
mSize; ++
r)
365 for (c = rmin; c <
mSize; ++
c)
373 for (r = rmin; r <
mSize; ++
r)
375 for (c = 0; c <
mSize; ++
c)
383 for (
auto const& givens :
mGivens)
385 for (r = 0; r <
mSize; ++
r)
387 int j = givens.index + mSize*
r;
388 Real& q0 = eigenvectors[j];
389 Real& q1 = eigenvectors[j + 1];
390 Real prd0 = givens.cs * q0 - givens.sn * q1;
391 Real prd1 = givens.sn * q0 + givens.cs * q1;
400 mIsRotation = 1 - (((mSize - 2) * (mSize - 1) / 2) & 1);
406 for (
int i = 0; i <
mSize; ++i)
411 int start = i, current = i, j, next;
412 for (j = 0; j <
mSize; ++j)
414 mPVector[j] = eigenvectors[i + mSize*j];
420 for (j = 0; j <
mSize; ++j)
422 eigenvectors[current + mSize*j] =
423 eigenvectors[next + mSize*j];
428 for (j = 0; j <
mSize; ++j)
430 eigenvectors[current + mSize*j] =
mPVector[j];
438 template <
typename Real>
457 for (
int i = 0; i <
mSize; ++i)
462 int start = i, current = i, next;
482 template <
typename Real>
486 if (0 <= c && c <
mSize)
489 Real*
x = eigenvector;
493 memset(x, 0,
mSize*
sizeof(Real));
507 Real& xr = x[givens.index];
508 Real& xrp1 = x[givens.index + 1];
509 Real tmp0 = givens.cs * xr + givens.sn * xrp1;
510 Real tmp1 = -givens.sn * xr + givens.cs * xrp1;
516 for (
int i =
mSize - 3; i >= 0; --i)
520 Real twoinvvdv = column[
mSize*(i + 1)];
522 for (r = 0; r < i + 1; ++
r)
529 for (
int j = r + 1; j <
mSize; ++j)
531 s += x[j] * column[mSize*j];
540 y[
r] = x[
r] - s * column[mSize*
r];
547 if (x != eigenvector)
549 size_t numBytes =
mSize*
sizeof(Real);
550 Memcpy(eigenvector, x, numBytes);
555 template <
typename Real>
573 return std::numeric_limits<Real>::max();
577 template <
typename Real>
581 for (
int i = 0, ip1 = 1; i <
mSize - 2; ++i, ++ip1)
586 for (r = 0; r < ip1; ++
r)
590 for (r = ip1; r <
mSize; ++
r)
592 Real vr =
mMatrix[r + mSize*i];
597 length = sqrt(length);
601 Real sgn = (v1 >= (Real)0 ? (Real)1 : (Real)-1);
602 Real invDenom = ((Real)1) / (v1 + sgn *
length);
604 for (r = ip1 + 1; r <
mSize; ++
r)
613 Real invvdv = (Real)1 / vdv;
614 Real twoinvvdv = invvdv * (Real)2;
615 Real pdvtvdv = (Real)0;
616 for (r = i; r <
mSize; ++
r)
619 for (c = i; c <
r; ++
c)
632 for (r = i; r <
mSize; ++
r)
638 for (r = i; r <
mSize; ++
r)
642 Real
offset = vr * wr * (Real)2;
644 for (c = r + 1; c <
mSize; ++
c)
647 mMatrix[c + mSize*
r] -=
offset;
656 mMatrix[i + mSize*ip1] = twoinvvdv;
657 for (r = ip1 + 1; r <
mSize; ++
r)
665 int k, ksup = mSize - 1,
index = 0, delta = mSize + 1;
666 for (k = 0; k < ksup; ++k, index += delta)
674 template <
typename Real>
684 sn = ((Real)1) / sqrt(((Real)1) + tau*tau);
690 cs = ((Real)1) / sqrt(((Real)1) + tau*tau);
701 template <
typename Real>
709 Real dif = (a00 - a11) * (Real)0.5;
710 Real sgn = (dif >= (Real)0 ? (Real)1 : (Real)-1);
711 Real a01sqr = a01 * a01;
712 Real u = a11 - a01sqr / (dif + sgn*sqrt(dif*dif + a01sqr));
716 Real a12, a22, a23, tmp11, tmp12, tmp21, tmp22, cs, sn;
718 int i0 = imin - 1, i1 = imin, i2 = imin + 1;
719 for (; i1 <= imax; ++i0, ++i1, ++i2)
747 tmp11 = cs*a11 - sn*a12;
748 tmp12 = cs*a12 - sn*a22;
749 tmp21 = sn*a11 + cs*a12;
750 tmp22 = sn*a12 + cs*a22;
768 template <
typename Real>
789 std::vector<SortItem> items(
mSize);
791 for (i = 0; i <
mSize; ++i)
799 std::sort(items.begin(), items.end(),
800 [](SortItem
const& item0, SortItem
const& item1)
802 return item0.eigenvalue < item1.eigenvalue;
808 std::sort(items.begin(), items.end(),
809 [](SortItem
const& item0, SortItem
const& item1)
811 return item0.eigenvalue > item1.eigenvalue;
817 for (
auto const& item : items)
838 template <
typename Real>
845 template <
typename Real>
847 Real inCs, Real inSn)
SymmetricEigensolver(int size, unsigned int maxIterations)
void GetSinCos(Real u, Real v, Real &cs, Real &sn)
ReversalObject< ReverseIterator > reverse(Iterable &&range)
void ComputePermutation(int sortType)
gte::BSNumber< UIntegerType > abs(gte::BSNumber< UIntegerType > const &number)
std::vector< Real > mVVector
void GetEigenvector(int c, Real *eigenvector) const
std::vector< Real > mMatrix
void GetEigenvalues(Real *eigenvalues) const
std::vector< int > mVisited
std::vector< int > mPermutation
void DoQRImplicitShift(int imin, int imax)
std::vector< Real > mPVector
std::vector< Real > mWVector
GLenum GLenum GLsizei void GLsizei void * column
void GetEigenvectors(Real *eigenvectors) const
Real GetEigenvalue(int c) const
std::vector< GivensRotation > mGivens
unsigned int Solve(Real const *input, int sortType)
GLuint GLsizei GLsizei * length
GLenum GLenum GLenum input
void Memcpy(void *target, void const *source, size_t count)
std::vector< Real > mDiagonal
unsigned int mMaxIterations
std::vector< Real > mSuperdiagonal