void MatrixTest::testMatrixMatrixOperations ()
{
  Matrix<2,3,int> lMatrix;
  Matrix<3,2,int> rMatrix;
  Matrix<2,2,int> result(0);
  assignList(lMatrix) = 1, 2, 3,
                        4, 5, 6;
  assignList(rMatrix) = 6, 5,
                        4, 3,
                        2, 1;

  // Matrix matrix multiplication
  multiply (lMatrix, rMatrix, result);
  validateEquals (result(0,0), 20);
  validateEquals (result(0,1), 14);
  validateEquals (result(1,0), 56);
  validateEquals (result(1,1), 41);

  // Bitwise comparison
  Matrix<2,3,int> matrixA(1);
  Matrix<2,3,int> matrixB(2);
  validate (matrixA == matrixA);
  validate (! (matrixA == matrixB));

  // Test equalsReturnIndex
  Matrix<2,3,double> matrix1(1);
  Matrix<2,3,double> matrix2(2);
  int i=equalsReturnIndex(matrix1,matrix2);
  validateEquals(i,0);
}
示例#2
0
TEST(Matrix, MatrixMultiplication)
{
	core::F32_t valuesA[4][4];
	core::F32_t valuesB[4][4];
	core::F32_t valueA = 0;
	core::F32_t valueB = 15;

	for(int i = 0; i < 4; i++)
	{
		for(int j = 0; j < 4; j++)
		{
			valuesA[i][j] = valueA;
			valuesB[i][j] = valueB;
			valueA++;
			valueB--;
		}
	}

	core::Matrix4x4 matrixA(valuesA);
	core::Matrix4x4 matrixB(valuesB);
	core::Matrix4x4 result;
	core::Matrix4x4::multiply(matrixA, matrixB, result);
	ASSERT_EQ(result.m[0][0], 34);
	ASSERT_EQ(result.m[0][1], 28);
	ASSERT_EQ(result.m[0][2], 22);
	ASSERT_EQ(result.m[0][3], 16);
	ASSERT_EQ(result.m[1][0], 178);
	ASSERT_EQ(result.m[1][1], 156);
	ASSERT_EQ(result.m[1][2], 134);
	ASSERT_EQ(result.m[1][3], 112);
	ASSERT_EQ(result.m[2][0], 322);
	ASSERT_EQ(result.m[2][1], 284);
	ASSERT_EQ(result.m[2][2], 246);
	ASSERT_EQ(result.m[2][3], 208);
	ASSERT_EQ(result.m[3][0], 466);
	ASSERT_EQ(result.m[3][1], 412);
	ASSERT_EQ(result.m[3][2], 358);
	ASSERT_EQ(result.m[3][3], 304);
}
示例#3
0
// 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);
}