123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101 |
- #pragma once
- #include <Mathematics/Math.h>
- #include <Mathematics/RangeIteration.h>
- #include <algorithm>
- #include <cstring>
- #include <vector>
- namespace WwiseGTE
- {
- template <typename Real>
- class SingularValueDecomposition
- {
- public:
-
-
-
-
-
-
-
-
-
- SingularValueDecomposition(int numRows, int numCols, unsigned int maxIterations)
- :
- mNumRows(0),
- mNumCols(0),
- mMaxIterations(0)
- {
- if (numCols > 1 && numRows >= numCols && maxIterations > 0)
- {
- mNumRows = numRows;
- mNumCols = numCols;
- mMaxIterations = maxIterations;
- mMatrix.resize(numRows * numCols);
- mDiagonal.resize(numCols);
- mSuperdiagonal.resize(numCols - 1);
- mRGivens.reserve(maxIterations * (numCols - 1));
- mLGivens.reserve(maxIterations * (numCols - 1));
- mFixupDiagonal.resize(numCols);
- mPermutation.resize(numCols);
- mVisited.resize(numCols);
- mTwoInvUTU.resize(numCols);
- mTwoInvVTV.resize(numCols - 2);
- mUVector.resize(numRows);
- mVVector.resize(numCols);
- mWVector.resize(numRows);
- }
- }
-
-
-
-
-
-
-
- unsigned int Solve(Real const* input, int sortType)
- {
- if (mNumRows > 0)
- {
- int numElements = mNumRows * mNumCols;
- std::copy(input, input + numElements, mMatrix.begin());
- Bidiagonalize();
-
-
-
-
-
-
-
-
-
-
- Real maxAbsComp = std::fabs(input[0]);
- for (int i = 1; i < numElements; ++i)
- {
- Real absComp = std::fabs(input[i]);
- if (absComp > maxAbsComp)
- {
- maxAbsComp = absComp;
- }
- }
- Real norm = (Real)0;
- if (maxAbsComp > (Real)0)
- {
- Real invMaxAbsComp = ((Real)1) / maxAbsComp;
- for (int i = 0; i < numElements; ++i)
- {
- Real ratio = input[i] * invMaxAbsComp;
- norm += ratio * ratio;
- }
- norm = maxAbsComp * std::sqrt(norm);
- }
- Real const multiplier = (Real)8;
- Real const epsilon = std::numeric_limits<Real>::epsilon();
- Real const threshold = multiplier * epsilon * norm;
- mRGivens.clear();
- mLGivens.clear();
- for (unsigned int j = 0; j < mMaxIterations; ++j)
- {
- int imin = -1, imax = -1;
- for (int i = mNumCols - 2; i >= 0; --i)
- {
-
-
- Real a00 = mDiagonal[i];
- Real a01 = mSuperdiagonal[i];
- Real a11 = mDiagonal[i + 1];
- Real sum = std::fabs(a00) + std::fabs(a11);
- if (sum + std::fabs(a01) != sum)
- {
- if (imax == -1)
- {
- imax = i;
- }
- imin = i;
- }
- else
- {
-
-
- if (imin >= 0)
- {
- break;
- }
- }
- }
- if (imax == -1)
- {
-
- EnsureNonnegativeDiagonal();
- ComputePermutation(sortType);
- return j;
- }
-
-
- if (DiagonalEntriesNonzero(imin, imax, threshold))
- {
-
-
- DoGolubKahanStep(imin, imax);
- }
- }
- return 0xFFFFFFFF;
- }
- else
- {
- return 0;
- }
- }
-
-
- void GetSingularValues(Real* singularValues) const
- {
- if (singularValues && mNumCols > 0)
- {
- if (mPermutation[0] >= 0)
- {
-
- for (int i = 0; i < mNumCols; ++i)
- {
- int p = mPermutation[i];
- singularValues[i] = mDiagonal[p];
- }
- }
- else
- {
-
- size_t numBytes = mNumCols * sizeof(Real);
- std::memcpy(singularValues, &mDiagonal[0], numBytes);
- }
- }
- }
-
-
-
-
- void GetU(Real* uMatrix) const
- {
- if (!uMatrix || mNumCols == 0)
- {
-
- return;
- }
-
- std::fill(uMatrix, uMatrix + mNumRows * mNumRows, (Real)0);
- for (int d = 0; d < mNumRows; ++d)
- {
- uMatrix[d + mNumRows * d] = (Real)1;
- }
-
-
- int r, c;
- for (int i0 = mNumCols - 1, i1 = i0 + 1; i0 >= 0; --i0, --i1)
- {
-
- Real twoinvudu = mTwoInvUTU[i0];
- Real const* column = &mMatrix[i0];
- mUVector[i0] = (Real)1;
- for (r = i1; r < mNumRows; ++r)
- {
- mUVector[r] = column[mNumCols * r];
- }
-
- mWVector[i0] = twoinvudu;
- for (r = i1; r < mNumRows; ++r)
- {
- mWVector[r] = (Real)0;
- for (c = i1; c < mNumRows; ++c)
- {
- mWVector[r] += mUVector[c] * uMatrix[r + mNumRows * c];
- }
- mWVector[r] *= twoinvudu;
- }
-
- for (r = i0; r < mNumRows; ++r)
- {
- for (c = i0; c < mNumRows; ++c)
- {
- uMatrix[c + mNumRows * r] -= mUVector[r] * mWVector[c];
- }
- }
- }
-
- for (auto const& givens : mLGivens)
- {
- int j0 = givens.index0;
- int j1 = givens.index1;
- for (r = 0; r < mNumRows; ++r, j0 += mNumRows, j1 += mNumRows)
- {
- Real& q0 = uMatrix[j0];
- Real& q1 = uMatrix[j1];
- Real prd0 = givens.cs * q0 - givens.sn * q1;
- Real prd1 = givens.sn * q0 + givens.cs * q1;
- q0 = prd0;
- q1 = prd1;
- }
- }
- if (mPermutation[0] >= 0)
- {
-
- std::fill(mVisited.begin(), mVisited.end(), 0);
- for (c = 0; c < mNumCols; ++c)
- {
- if (mVisited[c] == 0 && mPermutation[c] != c)
- {
-
- int start = c, current = c, next;
- for (r = 0; r < mNumRows; ++r)
- {
- mWVector[r] = uMatrix[c + mNumRows * r];
- }
- while ((next = mPermutation[current]) != start)
- {
- mVisited[current] = 1;
- for (r = 0; r < mNumRows; ++r)
- {
- uMatrix[current + mNumRows * r] =
- uMatrix[next + mNumRows * r];
- }
- current = next;
- }
- mVisited[current] = 1;
- for (r = 0; r < mNumRows; ++r)
- {
- uMatrix[current + mNumRows * r] = mWVector[r];
- }
- }
- }
- }
- }
- void GetV(Real* vMatrix) const
- {
- if (!vMatrix || mNumCols == 0)
- {
-
- return;
- }
-
- std::fill(vMatrix, vMatrix + mNumCols * mNumCols, (Real)0);
- for (int d = 0; d < mNumCols; ++d)
- {
- vMatrix[d + mNumCols * d] = (Real)1;
- }
-
- int i0 = mNumCols - 3;
- int i1 = i0 + 1;
- int i2 = i0 + 2;
- int r, c;
- for (; i0 >= 0; --i0, --i1, --i2)
- {
-
- Real twoinvvdv = mTwoInvVTV[i0];
- Real const* row = &mMatrix[mNumCols * i0];
- mVVector[i1] = (Real)1;
- for (r = i2; r < mNumCols; ++r)
- {
- mVVector[r] = row[r];
- }
-
- mWVector[i1] = twoinvvdv;
- for (r = i2; r < mNumCols; ++r)
- {
- mWVector[r] = (Real)0;
- for (c = i2; c < mNumCols; ++c)
- {
- mWVector[r] += mVVector[c] * vMatrix[r + mNumCols * c];
- }
- mWVector[r] *= twoinvvdv;
- }
-
- for (r = i1; r < mNumCols; ++r)
- {
- for (c = i1; c < mNumCols; ++c)
- {
- vMatrix[c + mNumCols * r] -= mVVector[r] * mWVector[c];
- }
- }
- }
-
- for (auto const& givens : mRGivens)
- {
- int j0 = givens.index0;
- int j1 = givens.index1;
- for (c = 0; c < mNumCols; ++c, j0 += mNumCols, j1 += mNumCols)
- {
- Real& q0 = vMatrix[j0];
- Real& q1 = vMatrix[j1];
- Real prd0 = givens.cs * q0 - givens.sn * q1;
- Real prd1 = givens.sn * q0 + givens.cs * q1;
- q0 = prd0;
- q1 = prd1;
- }
- }
-
- for (r = 0; r < mNumCols; ++r)
- {
- for (c = 0; c < mNumCols; ++c)
- {
- vMatrix[c + mNumCols * r] *= mFixupDiagonal[c];
- }
- }
- if (mPermutation[0] >= 0)
- {
-
- std::fill(mVisited.begin(), mVisited.end(), 0);
- for (c = 0; c < mNumCols; ++c)
- {
- if (mVisited[c] == 0 && mPermutation[c] != c)
- {
-
- int start = c, current = c, next;
- for (r = 0; r < mNumCols; ++r)
- {
- mWVector[r] = vMatrix[c + mNumCols * r];
- }
- while ((next = mPermutation[current]) != start)
- {
- mVisited[current] = 1;
- for (r = 0; r < mNumCols; ++r)
- {
- vMatrix[current + mNumCols * r] =
- vMatrix[next + mNumCols * r];
- }
- current = next;
- }
- mVisited[current] = 1;
- for (r = 0; r < mNumCols; ++r)
- {
- vMatrix[current + mNumCols * r] = mWVector[r];
- }
- }
- }
- }
- }
-
-
-
- void GetUColumn(int index, Real* uColumn) const
- {
- if (0 <= index && index < mNumRows)
- {
-
- Real* x = uColumn;
- Real* y = &mWVector[0];
-
- std::memset(x, 0, mNumRows * sizeof(Real));
- if (index < mNumCols && mPermutation[0] >= 0)
- {
-
- x[mPermutation[index]] = (Real)1;
- }
- else
- {
- x[index] = (Real)1;
- }
-
- for (auto const& givens : WwiseGTE::reverse(mLGivens))
- {
- Real& xr0 = x[givens.index0];
- Real& xr1 = x[givens.index1];
- Real tmp0 = givens.cs * xr0 + givens.sn * xr1;
- Real tmp1 = -givens.sn * xr0 + givens.cs * xr1;
- xr0 = tmp0;
- xr1 = tmp1;
- }
-
- for (int c = mNumCols - 1; c >= 0; --c)
- {
-
- int r;
- for (r = 0; r < c; ++r)
- {
- y[r] = x[r];
- }
-
- Real s = x[r];
- for (int j = r + 1; j < mNumRows; ++j)
- {
- s += x[j] * mMatrix[c + mNumCols * j];
- }
- s *= mTwoInvUTU[c];
-
- y[r] = x[r] - s;
-
- for (++r; r < mNumRows; ++r)
- {
- y[r] = x[r] - s * mMatrix[c + mNumCols * r];
- }
- std::swap(x, y);
- }
-
- if (x != uColumn)
- {
- size_t numBytes = mNumRows * sizeof(Real);
- std::memcpy(uColumn, x, numBytes);
- }
- }
- }
- void GetVColumn(int index, Real* vColumn) const
- {
- if (0 <= index && index < mNumCols)
- {
-
- Real* x = vColumn;
- Real* y = &mWVector[0];
-
- std::memset(x, 0, mNumCols * sizeof(Real));
- if (mPermutation[0] >= 0)
- {
-
- int p = mPermutation[index];
- x[p] = mFixupDiagonal[p];
- }
- else
- {
- x[index] = mFixupDiagonal[index];
- }
-
- for (auto const& givens : WwiseGTE::reverse(mRGivens))
- {
- Real& xr0 = x[givens.index0];
- Real& xr1 = x[givens.index1];
- Real tmp0 = givens.cs * xr0 + givens.sn * xr1;
- Real tmp1 = -givens.sn * xr0 + givens.cs * xr1;
- xr0 = tmp0;
- xr1 = tmp1;
- }
-
- for (int r = mNumCols - 3; r >= 0; --r)
- {
-
- int c;
- for (c = 0; c < r + 1; ++c)
- {
- y[c] = x[c];
- }
-
- Real s = x[c];
- for (int j = c + 1; j < mNumCols; ++j)
- {
- s += x[j] * mMatrix[j + mNumCols * r];
- }
- s *= mTwoInvVTV[r];
-
-
- y[c] = x[c] - s;
-
- for (++c; c < mNumCols; ++c)
- {
- y[c] = x[c] - s * mMatrix[c + mNumCols * r];
- }
- std::swap(x, y);
- }
-
- if (x != vColumn)
- {
- size_t numBytes = mNumCols * sizeof(Real);
- std::memcpy(vColumn, x, numBytes);
- }
- }
- }
- Real GetSingularValue(int index) const
- {
- if (0 <= index && index < mNumCols)
- {
- if (mPermutation[0] >= 0)
- {
-
- return mDiagonal[mPermutation[index]];
- }
- else
- {
-
- return mDiagonal[index];
- }
- }
- else
- {
- return (Real)0;
- }
- }
- private:
-
-
-
-
-
-
-
-
-
- void Bidiagonalize()
- {
- int r, c;
- for (int i = 0, ip1 = 1; i < mNumCols; ++i, ++ip1)
- {
-
- Real length = (Real)0;
- for (r = i; r < mNumRows; ++r)
- {
- Real ur = mMatrix[i + mNumCols * r];
- mUVector[r] = ur;
- length += ur * ur;
- }
- Real udu = (Real)1;
- length = std::sqrt(length);
- if (length > (Real)0)
- {
- Real& u1 = mUVector[i];
- Real sgn = (u1 >= (Real)0 ? (Real)1 : (Real)-1);
- Real invDenom = (Real)1 / (u1 + sgn * length);
- u1 = (Real)1;
- for (r = ip1; r < mNumRows; ++r)
- {
- Real& ur = mUVector[r];
- ur *= invDenom;
- udu += ur * ur;
- }
- }
-
- Real invudu = (Real)1 / udu;
- Real twoinvudu = invudu * (Real)2;
- for (c = i; c < mNumCols; ++c)
- {
- mWVector[c] = (Real)0;
- for (r = i; r < mNumRows; ++r)
- {
- mWVector[c] += mMatrix[c + mNumCols * r] * mUVector[r];
- }
- mWVector[c] *= twoinvudu;
- }
-
- for (r = i; r < mNumRows; ++r)
- {
- for (c = i; c < mNumCols; ++c)
- {
- mMatrix[c + mNumCols * r] -= mUVector[r] * mWVector[c];
- }
- }
- if (i < mNumCols - 2)
- {
-
- length = (Real)0;
- for (c = ip1; c < mNumCols; ++c)
- {
- Real vc = mMatrix[c + mNumCols * i];
- mVVector[c] = vc;
- length += vc * vc;
- }
- Real vdv = (Real)1;
- length = std::sqrt(length);
- if (length > (Real)0)
- {
- Real& v1 = mVVector[ip1];
- Real sgn = (v1 >= (Real)0 ? (Real)1 : (Real)-1);
- Real invDenom = (Real)1 / (v1 + sgn * length);
- v1 = (Real)1;
- for (c = ip1 + 1; c < mNumCols; ++c)
- {
- Real& vc = mVVector[c];
- vc *= invDenom;
- vdv += vc * vc;
- }
- }
-
- Real invvdv = (Real)1 / vdv;
- Real twoinvvdv = invvdv * (Real)2;
- for (r = i; r < mNumRows; ++r)
- {
- mWVector[r] = (Real)0;
- for (c = ip1; c < mNumCols; ++c)
- {
- mWVector[r] += mMatrix[c + mNumCols * r] * mVVector[c];
- }
- mWVector[r] *= twoinvvdv;
- }
-
- for (r = i; r < mNumRows; ++r)
- {
- for (c = ip1; c < mNumCols; ++c)
- {
- mMatrix[c + mNumCols * r] -= mWVector[r] * mVVector[c];
- }
- }
- mTwoInvVTV[i] = twoinvvdv;
- for (c = i + 2; c < mNumCols; ++c)
- {
- mMatrix[c + mNumCols * i] = mVVector[c];
- }
- }
- mTwoInvUTU[i] = twoinvudu;
- for (r = ip1; r < mNumRows; ++r)
- {
- mMatrix[i + mNumCols * r] = mUVector[r];
- }
- }
-
-
- int k, ksup = mNumCols - 1, index = 0, delta = mNumCols + 1;
- for (k = 0; k < ksup; ++k, index += delta)
- {
- mDiagonal[k] = mMatrix[index];
- mSuperdiagonal[k] = mMatrix[index + 1];
- }
- mDiagonal[k] = mMatrix[index];
- }
-
- void GetSinCos(Real x, Real y, Real& cs, Real& sn)
- {
-
- Real tau;
- if (y != (Real)0)
- {
- if (std::fabs(y) > std::fabs(x))
- {
- tau = -x / y;
- sn = (Real)1 / std::sqrt((Real)1 + tau * tau);
- cs = sn * tau;
- }
- else
- {
- tau = -y / x;
- cs = (Real)1 / std::sqrt((Real)1 + tau * tau);
- sn = cs * tau;
- }
- }
- else
- {
- cs = (Real)1;
- sn = (Real)0;
- }
- }
-
-
-
-
- bool DiagonalEntriesNonzero(int imin, int imax, Real threshold)
- {
- for (int i = imin; i <= imax; ++i)
- {
- if (std::fabs(mDiagonal[i]) <= threshold)
- {
-
-
- Real x, z, cs, sn;
- Real y = mSuperdiagonal[i];
- mSuperdiagonal[i] = (Real)0;
- for (int j = i + 1; j <= imax + 1; ++j)
- {
- x = mDiagonal[j];
- GetSinCos(x, y, cs, sn);
- mLGivens.push_back(GivensRotation(i, j, cs, sn));
- mDiagonal[j] = cs * x - sn * y;
- if (j <= imax)
- {
- z = mSuperdiagonal[j];
- mSuperdiagonal[j] = cs * z;
- y = sn * z;
- }
- }
- return false;
- }
- }
- return true;
- }
-
-
- void DoGolubKahanStep(int imin, int imax)
- {
-
-
- Real f0 = (imax >= (Real)1 ? mSuperdiagonal[imax - 1] : (Real)0);
- Real d1 = mDiagonal[imax];
- Real f1 = mSuperdiagonal[imax];
- Real d2 = mDiagonal[imax + 1];
- Real a00 = d1 * d1 + f0 * f0;
- Real a01 = d1 * f1;
- Real a11 = d2 * d2 + f1 * f1;
- Real dif = (a00 - a11) * (Real)0.5;
- Real sgn = (dif >= (Real)0 ? (Real)1 : (Real)-1);
- Real a01sqr = a01 * a01;
- Real u = a11 - a01sqr / (dif + sgn * std::sqrt(dif * dif + a01sqr));
- Real x = mDiagonal[imin] * mDiagonal[imin] - u;
- Real y = mDiagonal[imin] * mSuperdiagonal[imin];
- Real a12, a21, a22, a23, cs, sn;
- Real a02 = (Real)0;
- int i0 = imin - 1, i1 = imin, i2 = imin + 1;
- for (; i1 <= imax; ++i0, ++i1, ++i2)
- {
-
-
- GetSinCos(x, y, cs, sn);
- mRGivens.push_back(GivensRotation(i1, i2, cs, sn));
-
- if (i1 > imin)
- {
- mSuperdiagonal[i0] = cs * mSuperdiagonal[i0] - sn * a02;
- }
- a11 = mDiagonal[i1];
- a12 = mSuperdiagonal[i1];
- a22 = mDiagonal[i2];
- mDiagonal[i1] = cs * a11 - sn * a12;
- mSuperdiagonal[i1] = sn * a11 + cs * a12;
- mDiagonal[i2] = cs * a22;
- a21 = -sn * a22;
-
- x = mDiagonal[i1];
- y = a21;
-
-
- GetSinCos(x, y, cs, sn);
- mLGivens.push_back(GivensRotation(i1, i2, cs, sn));
-
- a11 = mDiagonal[i1];
- a12 = mSuperdiagonal[i1];
- a22 = mDiagonal[i2];
- mDiagonal[i1] = cs * a11 - sn * a21;
- mSuperdiagonal[i1] = cs * a12 - sn * a22;
- mDiagonal[i2] = sn * a12 + cs * a22;
- if (i1 < imax)
- {
- a23 = mSuperdiagonal[i2];
- a02 = -sn * a23;
- mSuperdiagonal[i2] = cs * a23;
-
- x = mSuperdiagonal[i1];
- y = a02;
- }
- }
- }
-
-
-
-
- void EnsureNonnegativeDiagonal()
- {
- for (int i = 0; i < mNumCols; ++i)
- {
- if (mDiagonal[i] >= (Real)0)
- {
- mFixupDiagonal[i] = (Real)1;
- }
- else
- {
- mDiagonal[i] = -mDiagonal[i];
- mFixupDiagonal[i] = (Real)-1;
- }
- }
- }
-
-
-
-
-
- void ComputePermutation(int sortType)
- {
- if (sortType == 0)
- {
-
-
-
- mPermutation[0] = -1;
- return;
- }
-
-
- struct SortItem
- {
- Real singularValue;
- int index;
- };
- std::vector<SortItem> items(mNumCols);
- int i;
- for (i = 0; i < mNumCols; ++i)
- {
- items[i].singularValue = mDiagonal[i];
- items[i].index = i;
- }
- if (sortType > 0)
- {
- std::sort(items.begin(), items.end(),
- [](SortItem const& item0, SortItem const& item1)
- {
- return item0.singularValue < item1.singularValue;
- }
- );
- }
- else
- {
- std::sort(items.begin(), items.end(),
- [](SortItem const& item0, SortItem const& item1)
- {
- return item0.singularValue > item1.singularValue;
- }
- );
- }
- i = 0;
- for (auto const& item : items)
- {
- mPermutation[i++] = item.index;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- }
-
- int mNumRows, mNumCols;
-
-
- unsigned int mMaxIterations;
-
-
-
- std::vector<Real> mMatrix;
-
-
-
-
- std::vector<Real> mDiagonal;
- std::vector<Real> mSuperdiagonal;
-
-
-
-
-
-
-
-
-
-
-
- struct GivensRotation
- {
-
-
- GivensRotation() = default;
- GivensRotation(int inIndex0, int inIndex1, Real inCs, Real inSn)
- :
- index0(inIndex0),
- index1(inIndex1),
- cs(inCs),
- sn(inSn)
- {
- }
- int index0, index1;
- Real cs, sn;
- };
- std::vector<GivensRotation> mRGivens;
- std::vector<GivensRotation> mLGivens;
-
-
- std::vector<Real> mFixupDiagonal;
-
-
-
-
- std::vector<int> mPermutation;
- mutable std::vector<int> mVisited;
-
-
- std::vector<Real> mTwoInvUTU;
- std::vector<Real> mTwoInvVTV;
- mutable std::vector<Real> mUVector;
- mutable std::vector<Real> mVVector;
- mutable std::vector<Real> mWVector;
- };
- }
|