35 template<
typename Real>
43 diag =
static_cast<double>(chol(
i,
i));
46 return static_cast<Real
>(2*det);
50 template<
typename Real>
56 template<
typename Real>
59 Real tolerance)
const {
61 Real max = s->
Max(), min = s->
Min();
66 template<
typename Real>
70 return std::max(s.
Max(), -s.
Min());
74 template<
typename Real>
82 if (C(r, r) == 0.0)
return false;
90 template<
typename Real>
92 if (power == 1)
return;
97 (*this).SymPosSemiDefEig(&l, &U);
104 KALDI_ERR <<
"Error taking power " << (power * 0.5) <<
" of vector " 108 (*this).AddMat2(1.0, U,
kNoTrans, 0.0);
111 template<
typename Real>
120 Real good_sum = 0.0, bad_sum = 0.0;
123 Real a = M(i,
j), b = M(
j, i), avg = 0.5*(a+b), diff = 0.5*(a-b);
125 good_sum += std::abs(avg);
126 bad_sum += std::abs(diff);
128 good_sum += std::abs(M(i, i));
129 (*this)(
i,
i) = M(i, i);
131 if (bad_sum > 0.01 * good_sum) {
132 KALDI_ERR <<
"SpMatrix::Copy(), source matrix is not symmetric: " 133 << bad_sum <<
">" << good_sum;
141 (*this)(
i,
j) = 0.5*(M(i,
j) + M(
j, i));
143 (*this)(
i,
i) = M(i, i);
149 const Real *src = M.
Data();
150 Real *dest = this->
data_;
163 (*
this)(
i,
j) = M(
j,
i);
166 KALDI_ASSERT(
"Invalid argument to SpMatrix::CopyFromMat");
170 template<
typename Real>
172 const Real *data = this->
data_;
175 for (
int32 i = 1;
i <= num_rows;
i++, data +=
i)
181 template<
typename Real>
182 template<
typename OtherReal>
184 int32 num_rows = this->num_rows_;
187 Real *dst = this->
data_;
189 for (
int32 i = 1;
i <= num_rows;
i++, src++, dst +=
i)
192 for (
int32 i = 1;
i <= num_rows;
i++, src++, dst +=
i)
193 *dst += alpha * *src;
218 template<
typename Real>
222 KaldiBlasInt rows =
static_cast<int>(this->num_rows_);
223 KaldiBlasInt* p_ipiv =
new KaldiBlasInt[rows];
226 if ((p_work = static_cast<Real*>(
229 throw std::bad_alloc();
232 memset(p_work, 0,
sizeof(Real) * rows);
242 KALDI_ASSERT(result >= 0 &&
"Call to CLAPACK ssptrf_ called with wrong arguments");
245 if (det_sign) *det_sign = 0;
246 if (logdet) *logdet = -std::numeric_limits<Real>::infinity();
247 if (need_inverse)
KALDI_ERR <<
"CLAPACK stptrf_ : factorization failed";
249 if (logdet != NULL || det_sign != NULL) {
250 Real prod = 1.0, log_prod = 0.0;
252 for (
int i = 0;
i < (int)this->num_rows_;
i++) {
255 Real
diag = (*this)(
i,
i);
260 Real diag1 = (*this)(
i,
i), diag2 = (*
this)(i-1, i-1),
261 offdiag = (*
this)(
i, i-1);
262 Real thisdet = diag1*diag2 - offdiag*offdiag;
268 if (
i == (
int)(this->num_rows_-1) || fabs(prod) < 1.0e-10 || fabs(prod) > 1.0e+10) {
269 if (prod < 0) { prod = -prod; sign *= -1; }
274 if (logdet != NULL) *logdet = log_prod;
275 if (det_sign != NULL) *det_sign = sign;
288 "Call to CLAPACK ssptri_ called with wrong arguments");
291 KALDI_ERR <<
"CLAPACK ssptrf_ : Matrix is singular";
299 template<
typename Real>
303 M.
Invert(logdet, det_sign, need_inverse);
307 (*
this)(
i,
j) = M(
i,
j);
311 template<
typename Real>
313 bool inverse_needed) {
315 double logdet_tmp, det_sign_tmp;
316 dmat.
Invert(logdet ? &logdet_tmp : NULL,
317 det_sign ? &det_sign_tmp : NULL,
319 if (logdet) *logdet = logdet_tmp;
320 if (det_sign) *det_sign = det_sign_tmp;
321 (*this).CopyFromSp(dmat);
328 const double *Aptr = A.
Data();
329 const double *Bptr = B.
Data();
332 double all_twice = 2.0 *
cblas_Xdot(RR, Aptr, 1, Bptr, 1);
336 double diag_once = 0.0;
337 for (
MatrixIndexT row_plus_two = 2; row_plus_two <= R + 1; row_plus_two++) {
338 diag_once += *Aptr * *Bptr;
339 Aptr += row_plus_two;
340 Bptr += row_plus_two;
342 return all_twice - diag_once;
348 const float *Aptr = A.
Data();
349 const float *Bptr = B.
Data();
352 float all_twice = 2.0 *
cblas_Xdot(RR, Aptr, 1, Bptr, 1);
356 float diag_once = 0.0;
357 for (
MatrixIndexT row_plus_two = 2; row_plus_two <= R + 1; row_plus_two++) {
358 diag_once += *Aptr * *Bptr;
359 Aptr += row_plus_two;
360 Bptr += row_plus_two;
362 return all_twice - diag_once;
366 template<
typename Real,
typename OtherReal>
370 const Real *Aptr = A.
Data();
373 for (row = 0; row < R; row++) {
374 for (col = 0; col < row; col++)
375 ans += 2.0 * *(Aptr++) * *(Bptr++);
376 ans += *(Aptr++) * *(Bptr++);
388 template<
typename Real>
391 "KALDI_ERR: TraceSpMat: arguments have mismatched dimension");
393 Real ans = (Real)0.0;
394 const Real *Aptr = A.
Data(), *Bptr = B.
Data();
399 ans += *(Aptr++) * (Bptr[r*bStride + c] + Bptr[c*bStride + r]);
402 ans += *(Aptr++) * Bptr[r*bStride + r];
414 template<
typename Real>
422 "TraceMatSpMat: arguments have wrong dimension.");
424 tmp.
AddMatMat(1.0, C, transC, A, transA, 0.0);
437 template<
typename Real>
445 "KALDI_ERR: TraceMatSpMatSp: arguments have mismatched dimension.");
448 tmpAB.
AddMatSp(1.0, A, transA, B, 0.0);
450 tmpCD.
AddMatSp(1.0, C, transC, D, 0.0);
464 template<
typename Real>
467 Real bad_sum = 0.0, good_sum = 0.0;
471 good_sum += std::abs((*
this)(
i,
j));
473 bad_sum += std::abs((*
this)(
i,
j));
476 return (!(bad_sum > good_sum * cutoff));
479 template<
typename Real>
485 max = std::max(max, static_cast<Real>(std::abs((*
this)(
i,
j) -
486 (
i ==
j ? 1.0 : 0.0))));
487 return (max <= cutoff);
490 template<
typename Real>
493 Real max_abs_2diag = 0.0, max_abs_offdiag = 0.0;
497 max_abs_offdiag = std::max(max_abs_offdiag,
498 std::abs((*
this)(
i,
j)));
500 max_abs_2diag = std::max(max_abs_2diag,
501 std::abs((*
this)(
i,
j)));
503 return (max_abs_offdiag <= cutoff * max_abs_2diag);
506 template<
typename Real>
508 if (this->num_rows_ == 0)
return true;
509 return (this->Max() <= cutoff && this->Min() >= -cutoff);
512 template<
typename Real>
518 sum += (*
this)(
i,
j) * (*
this)(
i,
j) * 2;
519 sum += (*this)(
i,
i) * (*
this)(
i,
i);
521 return std::sqrt(sum);
524 template<
typename Real>
526 if (this->NumRows() != other.
NumRows())
527 KALDI_ERR <<
"SpMatrix::AproxEqual, size mismatch, " 528 << this->NumRows() <<
" vs. " << other.
NumRows();
530 tmp.
AddSp(-1.0, other);
535 template<
typename Real>
544 L.
Scale(std::sqrt(alpha));
560 KALDI_LOG <<
"ApplyFloor: flooring following diagonal to 1: " << l;
573 (*this).AddMat2Sp(1.0, LFull,
kNoTrans, D, 0.0);
578 template<
typename Real>
583 tmp.
Invert(&log_det, det_sign,
false);
588 template<
typename Real>
601 (*this).AddMat2Vec(1.0, P,
kNoTrans, s, 0.0);
605 template<
typename Real>
610 (*this).SymPosSemiDefEig(&s, &P);
612 Real floor = s.
Max() / maxCond;
613 if (floor < 0) floor = 0;
614 if (floor < 1.0e-40) {
615 KALDI_WARN <<
"LimitCond: limiting " << floor <<
" to 1.0e-40";
620 if (s(
i) <= floor) nfloored++;
622 s(
i) = 1.0 / std::sqrt(std::max(s(
i), floor));
624 s(
i) = std::sqrt(std::max(s(
i), floor));
627 (*this).AddMat2(1.0, P,
kNoTrans, 0.0);
643 KALDI_WARN <<
"Zero quadratic term in quadratic vector problem for " 644 << opts.
name <<
": leaving it unchanged.";
652 H_diag.
ApplyFloor(std::numeric_limits<double>::min() * 1.0E+3);
662 H_scaled.
AddVec2Sp(1.0, H_diag_inv_sqrt, H, 0.0);
677 double f = std::max(static_cast<double>(opts.
eps), l.
Max() / opts.
K);
687 <<
": floored " << nfloored<<
" eigenvalues. ";
699 if (auxf_after < auxf_before) {
701 KALDI_WARN <<
"Optimizing vector auxiliary function for " 702 << opts.
name<<
": auxf decreased " << auxf_before
703 <<
" to " << auxf_after <<
", change is " 704 << (auxf_after-auxf_before);
708 return auxf_after - auxf_before;
727 template<
typename Real>
740 KALDI_WARN <<
"Zero quadratic term in quadratic matrix problem for " 741 << opts.
name <<
": leaving it unchanged.";
750 Q_diag.
ApplyFloor(std::numeric_limits<Real>::min() * 1.0E+3);
760 Q_scaled.
AddVec2Sp(1.0, Q_diag_inv_sqrt, Q, 0.0);
765 new_opts, &M_scaled);
780 Real f = std::max<Real>(
static_cast<Real
>(opts.
eps), l.
Max() / opts.
K);
783 if (l(
i) < f) { nfloored++; l(
i) = f; }
787 <<
": floored " << nfloored <<
" eigenvalues. ";
796 Real auxf_before, auxf_after;
813 if (auxf_after < auxf_before) {
814 if (auxf_after < auxf_before - 1.0e-10)
815 KALDI_WARN <<
"Optimizing matrix auxiliary function for " 816 << opts.
name <<
", auxf decreased " 817 << auxf_before <<
" to " << auxf_after <<
", change is " 818 << (auxf_after-auxf_before);
822 return auxf_after - auxf_before;
826 template<
typename Real>
853 #ifdef KALDI_PARANOID // checking mainly for errors in the code or math. 873 Real objf_impr = 0.0;
883 Real old_objf =
VecVec(mdash_n, gdash_n)
884 - 0.5 *
VecSpVec(mdash_n, Qsum, mdash_n);
886 Real new_objf =
VecVec(mdash_n, gdash_n)
887 - 0.5 *
VecSpVec(mdash_n, Qsum, mdash_n);
888 if (new_objf < old_objf) {
889 if (new_objf < old_objf - 1.0e-05) {
890 KALDI_WARN <<
"In double quadratic matrix problem: objective " 891 "function decreasing during optimization of " << opts.
name 892 <<
", " << old_objf <<
"->" << new_objf <<
", change is " 893 << (new_objf - old_objf);
894 KALDI_ERR <<
"Auxiliary function decreasing.";
896 MdashNew.
Row(
n).CopyFromVec(MdashOld.
Row(
n));
899 objf_impr += new_objf - old_objf;
902 KALDI_WARN <<
"Matrix inversion or optimization failed during double " 903 "quadratic problem, solving for" << opts.
name 904 <<
": trying more stable approach.";
925 const Real *Sdata = S.
Data();
926 const Real *vdata = v.
Data();
927 Real *data = this->
data_;
931 *data = beta * *data + alpha * vdata[r] * vdata[c] * *Sdata;
944 template<
typename Real>
945 template<
typename OtherReal>
948 Real *data = this->
data_;
953 *data += alpha * v_data[
i] * v_data[
j];
963 template<
typename Real>
970 return VecVec(tmp_vec, v2);
981 template<
typename Real>
991 Real *tmp_vec_data = tmp_vec.
Data();
993 const Real *p_A_data = A.
Data();
994 Real *p_row_data = this->Data();
997 M_stride = M.
Stride(), dim = this->NumRows();
1000 const Real *M_data = M.
Data();
1003 this->Data() + this->SizeInBytes() >= A.
Data()) {
1007 p_A_data = tmp_A.
Data();
1011 for (
MatrixIndexT r = 0; r < dim; r++, p_row_data += r) {
1013 cblas_Xgemv(transM, r+1, M_other_dim, alpha, M_data, M_stride,
1014 tmp_vec_data, 1, beta, p_row_data, 1);
1017 for (
MatrixIndexT r = 0; r < dim; r++, p_row_data += r) {
1019 cblas_Xgemv(transM, M_other_dim, r+1, alpha, M_data, M_stride,
1020 tmp_vec_data, 1, beta, p_row_data, 1);
1025 template<
typename Real>
1059 Real *data = this->
data_;
1060 const Real *Mdata = M.
Data(), *MAdata = temp_MA.
Data();
1068 temp_MA_stride, Mdata + (
i * Mstride), 1, beta, data, 1);
1075 temp_MA_stride, Mdata +
i, Mstride, beta, data, 1);
1080 template<
typename Real>
1093 const Real *Mdata = M.
Data(), *vdata = v.
Data();
1094 Real *data = this->
data_;
1097 for (
MatrixIndexT col = 0; col < mcols; col++, vdata++, Mdata += 1)
1098 cblas_Xspr(dim, *vdata*alpha, Mdata, mstride, data);
1100 const Real *Mdata = M.
Data(), *vdata = v.
Data();
1101 Real *data = this->
data_;
1104 for (
MatrixIndexT row = 0; row < mrows; row++, vdata++, Mdata += mstride)
1105 cblas_Xspr(dim, *vdata*alpha, Mdata, 1, data);
1109 template<
typename Real>
1122 if (this_dim == 0)
return;
1124 if (beta != 1.0) this->Scale(beta);
1138 template<
typename Real>
1143 AddMat2Sp(alpha, Tmat, transM, A, beta);
1146 template<
typename Real>
1149 int32 dim = this->NumRows();
1155 template<
typename Real>
1159 AddMat2(alpha, Tmat, transM, beta);
1170 template<
typename Real>
void AddMat2(const Real alpha, const MatrixBase< Real > &M, MatrixTransposeType transM, const Real beta)
rank-N update: if (transM == kNoTrans) (*this) = beta*(*this) + alpha * M * M^T, or (if transM == kTr...
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
void AddVec2Sp(const Real alpha, const VectorBase< Real > &v, const SpMatrix< Real > &S, const Real beta)
Does *this = beta * *thi + alpha * diag(v) * S * diag(v)
bool IsUnit(Real cutoff=1.0e-05) const
This class provides a way for switching between double and float types.
bool IsDiagonal(Real cutoff=1.0e-05) const
Packed symetric matrix class.
void cblas_Xsyrk(const MatrixTransposeType trans, const MatrixIndexT dim_c, const MatrixIndexT other_dim_a, const float alpha, const float *A, const MatrixIndexT a_stride, const float beta, float *C, const MatrixIndexT c_stride)
This class describes the options for maximizing various quadratic objective functions.
double SolveQuadraticProblem(const SpMatrix< double > &H, const VectorBase< double > &g, const SolverOptions &opts, VectorBase< double > *x)
void clapack_Xsptri(KaldiBlasInt *num_rows, float *Mdata, KaldiBlasInt *ipiv, float *work, KaldiBlasInt *result)
bool ApproxEqual(const SpMatrix< Real > &other, float tol=0.01) const
Returns true if ((*this)-other).FrobeniusNorm() <= tol*(*this).FrobeniusNorma()
void cblas_Xspr2(MatrixIndexT dim, float alpha, const float *Xdata, MatrixIndexT incX, const float *Ydata, MatrixIndexT incY, float *Adata)
void AddVecVec(const Real alpha, const VectorBase< Real > &v, const VectorBase< Real > &w)
rank-two update, this <– this + alpha (v w' + w v').
void AddMat2Vec(const Real alpha, const MatrixBase< Real > &M, MatrixTransposeType transM, const VectorBase< Real > &v, const Real beta=0.0)
Extension of rank-N update: this <– beta*this + alpha * M * diag(v) * M^T.
MatrixIndexT NumCols() const
Returns number of columns (or zero for empty matrix).
Real SolveQuadraticMatrixProblem(const SpMatrix< Real > &Q, const MatrixBase< Real > &Y, const SpMatrix< Real > &SigmaInv, const SolverOptions &opts, MatrixBase< Real > *M)
Maximizes the auxiliary function : Like a numerically stable version of .
Base class which provides matrix operations not involving resizing or allocation. ...
const Real * Data() const
Gives pointer to raw data (const).
void InvertDouble(Real *logdet=NULL, Real *det_sign=NULL, bool inverse_needed=true)
void Xgemv_sparsevec(MatrixTransposeType trans, MatrixIndexT num_rows, MatrixIndexT num_cols, Real alpha, const Real *Mdata, MatrixIndexT stride, const Real *xdata, MatrixIndexT incX, Real beta, Real *ydata, MatrixIndexT incY)
Real FrobeniusNorm() const
sqrt of sum of square elements.
Real TraceSpMat(const SpMatrix< Real > &A, const MatrixBase< Real > &B)
Returns tr(A B).
Real * RowData(MatrixIndexT i)
Returns pointer to data for one row (non-const)
void AddMat(const Real alpha, const MatrixBase< Real > &M, MatrixTransposeType transA=kNoTrans)
*this += alpha * M [or M^T]
void swap(basic_filebuf< CharT, Traits > &x, basic_filebuf< CharT, Traits > &y)
void ApplyPow(Real exponent)
Takes matrix to a fraction power via Svd.
void Eig(VectorBase< Real > *s, MatrixBase< Real > *P=NULL) const
Solves the symmetric eigenvalue problem: at end we should have (*this) = P * diag(s) * P^T...
A class for storing matrices.
bool diagonal_precondition
void AddSpVec(const Real alpha, const SpMatrix< Real > &M, const VectorBase< Real > &v, const Real beta)
Add symmetric positive definite matrix times vector: this <– beta*this + alpha*M*v.
void CopyFromMat(const MatrixBase< OtherReal > &M, MatrixTransposeType trans=kNoTrans)
Copy given matrix. (no resize is done).
Real Min() const
Returns the minimum value of any element, or +infinity for the empty vector.
bool IsTridiagonal(Real cutoff=1.0e-05) const
MatrixIndexT NumRows() const
Real SolveDoubleQuadraticMatrixProblem(const MatrixBase< Real > &G, const SpMatrix< Real > &P1, const SpMatrix< Real > &P2, const SpMatrix< Real > &Q1, const SpMatrix< Real > &Q2, const SolverOptions &opts, MatrixBase< Real > *M)
Maximizes the auxiliary function : Encountered in matrix update with a prior.
void CopyFromSp(const SpMatrix< Real > &other)
void AddTp2Sp(const Real alpha, const TpMatrix< Real > &T, MatrixTransposeType transM, const SpMatrix< Real > &A, const Real beta=0.0)
The following function does: this <– beta*this + alpha * T * A * T^T.
void CopyFromSp(const SpMatrix< OtherReal > &M)
Copy given spmatrix. (no resize is done).
int ApplyFloor(const SpMatrix< Real > &Floor, Real alpha=1.0, bool verbose=false)
Floors this symmetric matrix to the matrix alpha * Floor, where the matrix Floor is positive definite...
void ApplyFloor(Real floor_val, MatrixIndexT *floored_count=nullptr)
Applies floor to all elements.
float cblas_Xdot(const int N, const float *const X, const int incX, const float *const Y, const int incY)
void CopyFromVec(const VectorBase< Real > &v)
Copy data from another vector (must match own size).
void AddVec2(const Real alpha, const VectorBase< OtherReal > &v)
rank-one update, this <– this + alpha v v'
MatrixIndexT NumCols() const
void Cholesky(const SpMatrix< Real > &orig)
MatrixIndexT Stride() const
Stride (distance in memory between each row). Will be >= NumCols.
void AddSmat2Sp(const Real alpha, const MatrixBase< Real > &M, MatrixTransposeType transM, const SpMatrix< Real > &A, const Real beta=0.0)
This is a version of AddMat2Sp specialized for when M is fairly sparse.
Real LogPosDefDet() const
Computes log determinant but only for +ve-def matrices (it uses Cholesky).
Real TraceMatSpMat(const MatrixBase< Real > &A, MatrixTransposeType transA, const SpMatrix< Real > &B, const MatrixBase< Real > &C, MatrixTransposeType transC)
Returns tr(A B C) (A and C may be transposed as specified by transA and transC).
const SubVector< Real > Row(MatrixIndexT i) const
Return specific row of matrix [const].
MatrixIndexT LimitCond(Real maxCond=1.0e+5, bool invert=false)
void MulElements(const VectorBase< Real > &v)
Multiply element-by-element by another vector.
void AddSp(const Real alpha, const SpMatrix< Real > &Ma)
#define KALDI_MEMALIGN(align, size, pp_orig)
void AddTp2(const Real alpha, const TpMatrix< Real > &T, MatrixTransposeType transM, const Real beta=0.0)
The following function does: this <– beta*this + alpha * T * T^T.
void AddMatSp(const Real alpha, const MatrixBase< Real > &A, MatrixTransposeType transA, const SpMatrix< Real > &B, const Real beta)
this <– beta*this + alpha*A*B.
void AddMatMat(const Real alpha, const MatrixBase< Real > &A, MatrixTransposeType transA, const MatrixBase< Real > &B, MatrixTransposeType transB, const Real beta)
template float TraceSpSp< float, double >(const SpMatrix< float > &A, const SpMatrix< double > &B)
Real Max() const
Returns the maximum value of any element, or -infinity for the empty vector.
double TraceSpSp(const SpMatrix< double > &A, const SpMatrix< double > &B)
#define KALDI_MEMALIGN_FREE(x)
void cblas_Xspr(MatrixIndexT dim, float alpha, const float *Xdata, MatrixIndexT incX, float *Adata)
Real VecSpVec(const VectorBase< Real > &v1, const SpMatrix< Real > &M, const VectorBase< Real > &v2)
Computes v1^T * M * v2.
Real TraceSpSpLower(const SpMatrix< Real > &A, const SpMatrix< Real > &B)
Packed symetric matrix class.
Real TraceMatMat(const MatrixBase< Real > &A, const MatrixBase< Real > &B, MatrixTransposeType trans)
We need to declare this here as it will be a friend function.
Real * Data()
Returns a pointer to the start of the vector's data.
MatrixIndexT Dim() const
Returns the dimension of the vector.
void AddMatVec(const Real alpha, const MatrixBase< Real > &M, const MatrixTransposeType trans, const VectorBase< Real > &v, const Real beta)
Add matrix times vector : this <– beta*this + alpha*M*v.
Real TraceMatSpMatSp(const MatrixBase< Real > &A, MatrixTransposeType transA, const SpMatrix< Real > &B, const MatrixBase< Real > &C, MatrixTransposeType transC, const SpMatrix< Real > &D)
Returns tr (A B C D) (A and C may be transposed as specified by transA and transB).
void Swap(SpMatrix *other)
Shallow swap.
void MulColsVec(const VectorBase< Real > &scale)
Equivalent to (*this) = (*this) * diag(scale).
void AddSmatMat(Real alpha, const SparseMatrix< Real > &A, MatrixTransposeType transA, const MatrixBase< Real > &B, Real beta)
(*this) = alpha * op(A) * B + beta * (*this), where A is sparse.
void CopyFromMat(const MatrixBase< Real > &orig, SpCopyType copy_type=kTakeMean)
template double TraceSpSp< double, float >(const SpMatrix< double > &A, const SpMatrix< float > &B)
A class representing a vector.
void InvertElements()
Invert all elements.
size_t SizeInBytes() const
#define KALDI_ASSERT(cond)
MatrixIndexT NumRows() const
Returns number of rows (or zero for empty matrix).
void AddMat2Sp(const Real alpha, const MatrixBase< Real > &M, MatrixTransposeType transM, const SpMatrix< Real > &A, const Real beta=0.0)
Extension of rank-N update: this <– beta*this + alpha * M * A * M^T.
void ApplyPow(Real power)
Take all elements of vector to a power.
void cblas_Xgemv(MatrixTransposeType trans, MatrixIndexT num_rows, MatrixIndexT num_cols, float alpha, const float *Mdata, MatrixIndexT stride, const float *xdata, MatrixIndexT incX, float beta, float *ydata, MatrixIndexT incY)
void DivElements(const VectorBase< Real > &v)
Divide element-by-element by a vector.
void cblas_Xspmv(const float alpha, const int num_rows, const float *Mdata, const float *v, const int v_inc, const float beta, float *y, const int y_inc)
void Resize(MatrixIndexT nRows, MatrixResizeType resize_type=kSetZero)
void Invert(Real *log_det=NULL, Real *det_sign=NULL, bool inverse_needed=true)
matrix inverse.
void SymPosSemiDefEig(VectorBase< Real > *s, MatrixBase< Real > *P, Real tolerance=0.001) const
This is the version of SVD that we implement for symmetric positive definite matrices.
Provides a vector abstraction class.
void clapack_Xsptrf(KaldiBlasInt *num_rows, float *Mdata, KaldiBlasInt *ipiv, KaldiBlasInt *result)
void Invert(Real *logdet=NULL, Real *det_sign=NULL, bool inverse_needed=true)
matrix inverse.
Real VecVec(const VectorBase< Real > &a, const VectorBase< Real > &b)
Returns dot product between v1 and v2.
void AddVec(const Real alpha, const VectorBase< OtherReal > &v)
Add vector : *this = *this + alpha * rv (with casting between floats and doubles) ...
bool IsZero(Real cutoff=1.0e-05) const
Real MaxAbsEig() const
Returns the maximum of the absolute values of any of the eigenvalues.
void CopyDiagFromSp(const SpMatrix< Real > &M)
Extracts the diagonal of a symmetric matrix.
void AddDiagVec(const Real alpha, const VectorBase< OtherReal > &v)
diagonal update, this <– this + diag(v)
Represents a non-allocating general vector which can be defined as a sub-vector of higher-level vecto...
Real LogDet(Real *det_sign=NULL) const