double Cpoint3dCov::mahalanobisDistance(const Cpoint3d &qq) const { double dm2; Vector3f vDiff, vAux; vDiff << ( this->xx - qq.getX() ), ( this->yy - qq.getY() ), ( this->zz - qq.getZ() );//difference vector vAux = covMat.inverse()*vDiff; dm2 = vDiff(0)*vAux(0) + vDiff(1)*vAux(1) + vDiff(2)*vAux(2); return sqrt(dm2); }
double Cpoint3dCov::mahalanobisDistance2D(const Cpoint3d &qq) const { double dm2; Vector2f vDiff, vAux; vDiff << ( this->xx - qq.getX() ), ( this->yy - qq.getY() );//difference vector vAux = (covMat.block<2,2>(0,0).inverse())*vDiff; dm2 = vDiff(0)*vAux(0) + vDiff(1)*vAux(1); return sqrt(dm2); }
// estimate the feature transform for the given data (typically speaker adaptation data) Transform *FMLLREstimator::estimateTransform(Transform *transformInitial) { Matrix<double> matrixW(m_iDim,m_iDim+1); Matrix<float> matrixWF(m_iDim,m_iDim+1); Matrix<double> matrixA(m_iDim,m_iDim); Vector<double> vAux(m_iDim+1); // starting from scratch: bias = 0.0 and A = identity if (transformInitial == NULL) { matrixA.setIdentity(); } // starting from another transform else { assert(0); } // compute the matrix of cofactors of A Matrix<double> matrixP(matrixA); matrixP.matrixCofactor(); // initialize the transform // iterative update for(int iIteration = 0 ; iIteration < m_iIterations ; ++iIteration) { // compute the transform row by row for(int i=0 ; i < m_iDim ; ++i) { // invert G(i) (this is suboptimal, the inversion needs to be // done just once then it can be reused across iterations) Matrix<double> matrixGInverted(*m_matrixG[i]); matrixGInverted.invert(); // compute alpha (it implies solving a quadratic equation and selecting the solution // that produces a higher increase of the objective function) // get the zero extended vector of cofactors for the ith row Vector<double> vCofactor(matrixP.getRow(i)); vCofactor.appendFront(0.0); // compute constants double dBeta = m_fOccupancyTotal; Vector<double> vAux(m_iDim+1); vAux.mul(vCofactor,matrixGInverted); double dA = vAux.mul(vCofactor); double dB = vAux.mul(m_matrixK->getRow(i)); double dC = -1.0*dBeta; // there are two possible solutions double dAlpha1 = (-1.0*dB + sqrt(dB*dB - 4.0*dA*dC))/(2.0*dA); double dAlpha2 = (-1.0*dB - sqrt(dB*dB - 4.0*dA*dC))/(2.0*dA); // we let the objective function decide which solution is better (higher likelihood increase) double dAuxiliarFunction1 = dBeta*log(fabs(dAlpha1*dA+dB)) - 0.5*dAlpha1*dAlpha1*dA; double dAuxiliarFunction2 = dBeta*log(fabs(dAlpha2*dA+dB)) - 0.5*dAlpha2*dAlpha2*dA; double dAlpha = (dAuxiliarFunction1 > dAuxiliarFunction2) ? dAlpha1 : dAlpha2; // compute the w(i) Vector<double> vAux2(m_matrixK->getRow(i)); Vector<double> vCofactorRowEx(matrixP.getRow(i)); vCofactorRowEx.appendFront(0.0); vAux2.add(dAlpha,vCofactorRowEx); matrixW.getRow(i).mul(vAux2,matrixGInverted); // update A matrixA.getRow(i).copy(matrixW.getRowData(i)+1,m_iDim); // compute the matrix of cofactors after updating the row of the transform matrixP.copy(matrixA); matrixP.matrixCofactor(); } // compute the log(|A|) Matrix<double> matrixAInverted(matrixA); float fDet = (float)matrixAInverted.invert(); if (fDet == 0) { BVC_ERROR << "the A matrix is singular!, can't compute inverse"; } printf("log(|A|) = %8.4f\n",log(fDet)); } // create the transform Matrix<float> matrixWFloat(matrixW); return new Transform(TRANSFORM_TYPE_AFFINE,matrixWFloat); }