768 строки
27 KiB
C++
768 строки
27 KiB
C++
//
|
|
// <copyright file="MatrixUnitTests.cpp" company="Microsoft">
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// </copyright>
|
|
//
|
|
#include "stdafx.h"
|
|
#include "CppUnitTest.h"
|
|
#include "..\Math\Matrix.h"
|
|
|
|
#pragma warning (disable: 4244 4245 4305) // conversions and truncations; we don't care in this test project
|
|
|
|
#define epsilon 0.000001
|
|
#define IDX2C(i,j,ld) (((j)*(ld))+(i)) // 0 based indexing
|
|
|
|
using namespace Microsoft::MSR::CNTK;
|
|
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
|
|
|
|
|
namespace CNTKMathTest
|
|
{
|
|
TEST_CLASS(MatrixUnitTest)
|
|
{
|
|
|
|
public:
|
|
|
|
//This test should fail if you don't have CUDA GPU (or working under remote desktop)
|
|
TEST_METHOD(MatrixConsturctors)
|
|
{
|
|
SingleMatrix A0;
|
|
SingleMatrix A1(AUTOPLACEMATRIX);
|
|
SingleMatrix A2(-1);
|
|
SingleMatrix A3((size_t)13,(size_t)12,(DEVICEID_TYPE)0);
|
|
|
|
Assert::AreEqual<size_t>(0,A0.GetNumRows());
|
|
Assert::AreEqual<size_t>(0,A0.GetNumCols());
|
|
Assert::AreEqual<size_t>(0,A1.GetNumRows());
|
|
Assert::AreEqual<size_t>(0,A2.GetNumCols());
|
|
Assert::AreEqual<size_t>(13,A3.GetNumRows());
|
|
Assert::AreEqual<size_t>(12,A3.GetNumCols());
|
|
}
|
|
|
|
TEST_METHOD(MatrixMoveTest)
|
|
{
|
|
//no moves required
|
|
SingleMatrix a;
|
|
SingleMatrix b;
|
|
b.Resize(100,100);
|
|
std::swap(a,b);
|
|
|
|
//potentially a move is required
|
|
SingleMatrix A;
|
|
SingleMatrix B;
|
|
B.Resize(100,100);
|
|
B(12,13)=14; //this will move whole matrix B from GPU to CPU
|
|
std::swap(A,B); // this will not only swap A and B but will put them to their preferred device (GPU if present)
|
|
|
|
//This is deep copy, not move
|
|
SingleMatrix a1;
|
|
SingleMatrix b1;
|
|
b1.Resize(12,34);
|
|
b1=a1;
|
|
|
|
SingleMatrix a2;
|
|
SingleMatrix b2;
|
|
b2.Resize(12,34);
|
|
b2(2,3)=9;
|
|
b2=a2;
|
|
}
|
|
|
|
|
|
TEST_METHOD(MatrixAssignmentOperatorsAndInitializers)
|
|
{
|
|
//Zeros
|
|
SingleMatrix A0 = SingleMatrix::Zeros(12,32);
|
|
Assert::AreEqual<size_t>(12,A0.GetNumRows());
|
|
Assert::AreEqual<size_t>(32,A0.GetNumCols());
|
|
foreach_coord(i,j,A0)
|
|
{
|
|
Assert::AreEqual<float>(0,A0(i,j));
|
|
}
|
|
|
|
//Eye
|
|
SingleMatrix A1 = SingleMatrix::Eye(56);
|
|
Assert::AreEqual<size_t>(56,A1.GetNumRows());
|
|
Assert::AreEqual<size_t>(56,A1.GetNumCols());
|
|
foreach_coord(i,j,A1)
|
|
{
|
|
if (i!=j)
|
|
{
|
|
float x = A1(i,j);
|
|
Assert::AreEqual<float>(0,x);
|
|
}
|
|
else
|
|
{
|
|
float x = A1(i,j);
|
|
Assert::AreEqual<float>(1,x);
|
|
}
|
|
}
|
|
|
|
//Ones
|
|
SingleMatrix A2 = SingleMatrix::Ones(12,56);
|
|
Assert::AreEqual<size_t>(12,A2.GetNumRows());
|
|
Assert::AreEqual<size_t>(56,A2.GetNumCols());
|
|
foreach_coord(i,j,A2)
|
|
{
|
|
Assert::AreEqual<float>(1,A2(i,j));
|
|
}
|
|
|
|
//SetGaussianRandomValue
|
|
SingleMatrix A3= SingleMatrix::RandomGaussian(640,230,0,2,-1);
|
|
float avg = 0;
|
|
foreach_coord(i,j,A3)
|
|
{
|
|
avg+=A3(i,j);
|
|
}
|
|
avg/=(640*230);
|
|
float std=0;
|
|
foreach_coord(i,j,A3)
|
|
{
|
|
std+=((A3(i,j)-avg)*(A3(i,j)-avg)/(640*230));
|
|
}
|
|
std=sqrt(std);
|
|
//Assert::IsTrue(fabs(avg-0)<0.01);
|
|
//WARNING: The deviance seems to be off for both CPU and GPU implementations
|
|
//Assert::IsTrue(fabs(std-2)<0.01);
|
|
|
|
//RandomUniform
|
|
SingleMatrix A4 = SingleMatrix::RandomUniform(435, 100, -26.3, 30.2);
|
|
bool has_small=false;
|
|
bool has_big=false;
|
|
foreach_coord(i,j,A4)
|
|
{
|
|
Assert::IsTrue((A4(i,j)>=-26.3)&&(A4(i,j)<30.2));
|
|
if (A4(i,j)<-3)
|
|
has_small=true;
|
|
if (A4(i,j)>3)
|
|
has_big=true;
|
|
}
|
|
Assert::IsTrue(has_small);
|
|
Assert::IsTrue(has_big);
|
|
|
|
//RandomUniform
|
|
SingleMatrix A5((size_t)429,(size_t)1024);
|
|
A5.SetUniformRandomValue(-0.01,0.01);
|
|
foreach_coord(i,j,A5)
|
|
{
|
|
Assert::IsTrue(A5(i,j)<=0.01&&A5(i,j)>=-0.01);
|
|
}
|
|
|
|
//Check that seed allows results reproduce
|
|
//!!!WE NOW INITIALIZE SEED PER PROCESS!!!
|
|
/*
|
|
SingleMatrix A6 = SingleMatrix::RandomUniform(5,6,-1,3,1234);
|
|
SingleMatrix A7 = SingleMatrix::RandomUniform(5,6,-1,3,1234);
|
|
SingleMatrix A8 = SingleMatrix::RandomUniform(5,6,-1,3,12346);
|
|
SingleMatrix A9 = SingleMatrix::RandomUniform(5,6,-1,3);
|
|
|
|
Assert::IsTrue(A6.IsEqualTo(A7));
|
|
//Assert::IsTrue(!A8.IsEqualTo(A7)); */
|
|
|
|
}
|
|
|
|
TEST_METHOD(MatrixSetValueMethods)
|
|
{
|
|
//void SetValue(const ElemType v);
|
|
SingleMatrix A((size_t)32,(size_t)12);
|
|
Assert::AreEqual<size_t>(32,A.GetNumRows());
|
|
Assert::AreEqual<size_t>(12,A.GetNumCols());
|
|
Assert::AreEqual<size_t>(12*32,A.GetNumElements());
|
|
float v= -32.3451;
|
|
A.SetValue(v);
|
|
foreach_coord(i,j,A)
|
|
{
|
|
Assert::AreEqual<float>(v,A(i,j));
|
|
}
|
|
|
|
//void SetValue(const Matrix<ElemType>& deepCopyFrom);
|
|
SingleMatrix B;
|
|
B.SetValue(A);
|
|
foreach_coord(i,j,B)
|
|
{
|
|
Assert::AreEqual<float>(v,B(i,j));
|
|
}
|
|
|
|
//void SetValue(const size_t numRows, const size_t numCols, ElemType *pArray, const bool srcIsColMajor);
|
|
float *arr = new float[6];
|
|
arr[0]=123;arr[1]=0.23;arr[2]=-22;arr[3]=63;arr[4]=43.42;
|
|
arr[5]=324.3;arr[6]=99912;
|
|
B.SetValue(2,3,arr,matrixFlagNormal);
|
|
|
|
SingleMatrix B1;
|
|
B1.SetValue(2,3,arr);
|
|
foreach_coord(i,j,B)
|
|
{
|
|
Assert::AreEqual<float>(arr[IDX2C(i,j,2)],B(i,j));
|
|
Assert::AreEqual<float>(arr[IDX2C(i,j,2)],B1(i,j));
|
|
}
|
|
|
|
SingleMatrix BBBB = SingleMatrix::Zeros(6,8);
|
|
BBBB.SetColumn(arr,3);
|
|
for (int i=0;i<6;++i)
|
|
{
|
|
Assert::AreEqual<float>(arr[i],BBBB(i,3));
|
|
}
|
|
|
|
|
|
//void SetDiagonalValue(const ElemType v);
|
|
SingleMatrix C(4,4,AUTOPLACEMATRIX);
|
|
float val = -0.00332;
|
|
C.SetDiagonalValue(val);
|
|
foreach_coord(i,j,C)
|
|
{
|
|
if (i==j)
|
|
Assert::AreEqual<float>(val,C(i,j));
|
|
else
|
|
Assert::AreEqual<float>(0,C(i,j));
|
|
}
|
|
|
|
//void SetDiagonalValue(Matrix<ElemType>& vector);
|
|
SingleMatrix D(4,1,AUTOPLACEMATRIX);
|
|
float val1=43.324;
|
|
D.SetValue(val1);
|
|
C.SetDiagonalValue(D);
|
|
foreach_coord(i,j,C)
|
|
{
|
|
if (i==j)
|
|
Assert::AreEqual<float>(val1,C(i,j));
|
|
else
|
|
Assert::AreEqual<float>(0,C(i,j));
|
|
}
|
|
|
|
SingleMatrix C1(5,5,AUTOPLACEMATRIX);
|
|
SingleMatrix D1(1,5,AUTOPLACEMATRIX);
|
|
float val2=0.53;
|
|
D1=D1.Transpose();
|
|
D1.SetValue(val2);
|
|
C1.SetDiagonalValue(D1);
|
|
foreach_coord(i,j,C1)
|
|
{
|
|
if (i==j)
|
|
Assert::AreEqual<float>(val2,C1(i,j));
|
|
else
|
|
Assert::AreEqual<float>(0,C1(i,j));
|
|
}
|
|
}
|
|
|
|
TEST_METHOD(MatrixTransposeTest)
|
|
{
|
|
SingleMatrix A= SingleMatrix::RandomGaussian(64,23,0,2);
|
|
Assert::AreEqual<size_t>(64,A.GetNumRows());
|
|
Assert::AreEqual<size_t>(23,A.GetNumCols());
|
|
|
|
SingleMatrix B=A.Transpose();
|
|
|
|
Assert::AreEqual<size_t>(23,B.GetNumRows());
|
|
Assert::AreEqual<size_t>(64,B.GetNumCols());
|
|
|
|
foreach_coord(i,j,A)
|
|
{
|
|
Assert::AreEqual<size_t>(A(i,j),B(j,i));
|
|
}
|
|
}
|
|
|
|
TEST_METHOD(MatrixMultiAndDiv)
|
|
{
|
|
SingleMatrix M0((size_t)2,(size_t)3);
|
|
M0(0,0) = 1; M0(0,1) = 2; M0(0,2) = 3;
|
|
M0(1,0) = 4; M0(1,1) = 5; M0(1,2) = 6;
|
|
|
|
SingleMatrix M00((size_t)2, (size_t)3);
|
|
M00(0,0) = 10; M00(0,1) = 20; M00(0,2) = 30;
|
|
M00(1,0) = 40; M00(1,1) = 50; M00(1,2) = 60;
|
|
|
|
SingleMatrix M1((size_t)2,(size_t)3);
|
|
M1.Reshape(3,2);
|
|
M1(0,0) = 11; M1(0,1) = 15;
|
|
M1(1,0) = 14; M1(1,1) = 13;
|
|
M1(2,0) = 12; M1(2,1) = 16;
|
|
|
|
SingleMatrix M2((size_t)2,(size_t)2);
|
|
M2(0,0) = 75; M2(0,1) = 89;
|
|
M2(1,0) = 186; M2(1,1) = 221;
|
|
|
|
SingleMatrix M3 = M0 * M1;
|
|
Assert::IsTrue(M3.IsEqualTo(M2));
|
|
|
|
M3 = M0 * 10;
|
|
Assert::IsTrue(M3.IsEqualTo(M00));
|
|
|
|
M3 = M3 / 10;
|
|
Assert::IsTrue(M3.IsEqualTo(M0));
|
|
|
|
M3 *= 10;
|
|
Assert::IsTrue(M3.IsEqualTo(M00));
|
|
|
|
M3 /= 10;
|
|
Assert::IsTrue(M3.IsEqualTo(M0));
|
|
|
|
SingleMatrix::MultiplyAndWeightedAdd(1, M0, false, M1, false, 0, M3);
|
|
Assert::IsTrue(M3.IsEqualTo(M2));
|
|
|
|
M1.Reshape(2,3);
|
|
SingleMatrix::MultiplyAndWeightedAdd(1, M0, false, M1, true, 0, M3);
|
|
M2(0,0) = 74; M2(0,1) = 92;
|
|
M2(1,0) = 182; M2(1,1) = 227;
|
|
Assert::IsTrue(M3.IsEqualTo(M2));
|
|
|
|
SingleMatrix::MultiplyAndWeightedAdd(10, M0, false, M1, true, 2, M3);
|
|
M2(0,0) = 888; M2(0,1) = 1104;
|
|
M2(1,0) = 2184; M2(1,1) = 2724;
|
|
Assert::IsTrue(M3.IsEqualTo(M2));
|
|
|
|
SingleMatrix::MultiplyAndWeightedAdd(1, M0, true, M1, false, 0, M3);
|
|
M2.Resize(3,3);
|
|
M2(0,0) = 67; M2(0,1) = 72; M2(0,2) = 77;
|
|
M2(1,0) = 92; M2(1,1) = 99; M2(1,2) = 106;
|
|
M2(2,0) = 117; M2(2,1) = 126; M2(2,2) = 135;
|
|
Assert::IsTrue(M3.IsEqualTo(M2));
|
|
|
|
//Multiplications of arbitrary matrix with 1x1 matrix
|
|
|
|
SingleMatrix A((size_t)2,(size_t)3);
|
|
A(0,0) = 1; A(0,1) = 2; A(0,2) = 3;
|
|
A(1,0) = 4; A(1,1) = 5; A(1,2) = 6;
|
|
|
|
SingleMatrix B = SingleMatrix::Eye(1);
|
|
|
|
SingleMatrix C=A*B;
|
|
Assert::IsTrue(C.IsEqualTo(A));
|
|
C=B*A;
|
|
Assert::IsTrue(C.IsEqualTo(A));
|
|
B(0,0)=0.5;
|
|
B.InplaceAbs();
|
|
C=A*B;
|
|
|
|
SingleMatrix D((size_t)2,(size_t)3);
|
|
D(0,0) = 0.5; D(0,1) = 1; D(0,2) = 1.5;
|
|
D(1,0) = 2; D(1,1) = 2.5; D(1,2) = 3;
|
|
Assert::IsTrue(C.IsEqualTo(D));
|
|
}
|
|
|
|
TEST_METHOD(MatrixTranspose)
|
|
{
|
|
SingleMatrix M0((size_t)2,(size_t)3);
|
|
M0(0,0) = 1; M0(0,1) = 2; M0(0,2) = 3;
|
|
M0(1,0) = 4; M0(1,1) = 5; M0(1,2) = 6;
|
|
|
|
SingleMatrix M1((size_t)3,(size_t)2);
|
|
M1(0,0) = 1; M1(0,1) = 4;
|
|
M1(1,0) = 2; M1(1,1) = 5;
|
|
M1(2,0) = 3; M1(2,1) = 6;
|
|
|
|
SingleMatrix M2 = M0.Transpose();
|
|
Assert::IsTrue(M2.IsEqualTo(M1, 0.0001));
|
|
|
|
M2.AssignTransposeOf(M1);
|
|
Assert::IsTrue(M2.IsEqualTo(M0, 0.0001));
|
|
}
|
|
|
|
TEST_METHOD(MatrixAddAndSub)
|
|
{
|
|
SingleMatrix M0((size_t)2,(size_t)3);
|
|
M0(0,0) = 1; M0(0,1) = 2; M0(0,2) = 3;
|
|
M0(1,0) = 4; M0(1,1) = 5; M0(1,2) = 6;
|
|
|
|
SingleMatrix M1((size_t)2,(size_t)3);
|
|
M1(0,0) = 11; M1(0,1) = 12; M1(0,2) = 13;
|
|
M1(1,0) = 14; M1(1,1) = 15; M1(1,2) = 16;
|
|
|
|
SingleMatrix M2((size_t)2,(size_t)3);
|
|
M2(0,0) = 12; M2(0,1) = 14; M2(0,2) = 16;
|
|
M2(1,0) = 18; M2(1,1) = 20; M2(1,2) = 22;
|
|
|
|
SingleMatrix M3 = M2 - M0;
|
|
Assert::IsTrue(M3.IsEqualTo(M1));
|
|
|
|
M3 += M0;
|
|
Assert::IsTrue(M3.IsEqualTo(M2));
|
|
|
|
M3 = M0 + 10;
|
|
Assert::IsTrue(M3.IsEqualTo(M1));
|
|
|
|
M3 -= 10;
|
|
Assert::IsTrue(M3.IsEqualTo(M0));
|
|
|
|
M3 = M1 + M0;
|
|
Assert::IsTrue(M3.IsEqualTo(M2));
|
|
SingleMatrix M4=SingleMatrix::Eye(3);
|
|
SingleMatrix M5 = M0*M4 + M1;
|
|
|
|
M3 -= M0;
|
|
Assert::IsTrue(M3.IsEqualTo(M1));
|
|
|
|
M3 = M1 - 10;
|
|
Assert::IsTrue(M3.IsEqualTo(M0));
|
|
|
|
SingleMatrix M33(M3); //M4==M3
|
|
M3 += 10;
|
|
Assert::IsTrue(M3.IsEqualTo(M1));
|
|
|
|
SingleMatrix M55=SingleMatrix::Eye(1);
|
|
M55(0,0)=10;
|
|
M55.InplaceAbs();
|
|
M33 += M55;//M5 is 1x1 matrix
|
|
Assert::IsTrue(M33.IsEqualTo(M1));
|
|
M33 -= 10;
|
|
M33 = M33 + 10;
|
|
Assert::IsTrue(M33.IsEqualTo(M1));
|
|
}
|
|
|
|
TEST_METHOD(MatrixElementOps)
|
|
{
|
|
SingleMatrix M0((size_t)2,(size_t)3);
|
|
M0(0,0) = 1; M0(0,1) = 2; M0(0,2) = 3;
|
|
M0(1,0) = 4; M0(1,1) = 5; M0(1,2) = 6;
|
|
|
|
SingleMatrix M00((size_t)2,(size_t)3);
|
|
M00(0,0) = 1.0; M00(0,1) = 1/2.0; M00(0,2) = 1/3.0;
|
|
M00(1,0) = 1/4.0; M00(1,1) = 1/5.0; M00(1,2) = 1/6.0;
|
|
|
|
SingleMatrix M1((size_t)2, (size_t)3);
|
|
M1(0,0) = 1; M1(0,1) = 1; M1(0,2) = 1;
|
|
M1(1,0) = 1; M1(1,1) = 1; M1(1,2) = 1;
|
|
|
|
SingleMatrix M3;
|
|
M3.AssignElementProductOf(M0, M00);
|
|
Assert::IsTrue(M3.IsEqualTo(M1, 0.0001));
|
|
|
|
SingleMatrix M4=SingleMatrix::Zeros(2,3);
|
|
M4 = M4.AddElementProductOf(M0,M00);
|
|
Assert::IsTrue(M4.IsEqualTo(M1,0.0001));
|
|
|
|
M3 = M0 ^ 4;
|
|
SingleMatrix M2((size_t)2,(size_t)3);
|
|
M2(0,0) = 1; M2(0,1) = 16; M2(0,2) = 81;
|
|
M2(1,0) = 256; M2(1,1) = 625; M2(1,2) = 1296;
|
|
Assert::IsTrue(M3.IsEqualTo(M2,0.001));
|
|
|
|
M3.SetValue(M0);
|
|
M3 ^= 4;
|
|
Assert::IsTrue(M3.IsEqualTo(M2, 0.001));
|
|
|
|
M3.SetValue(M0);
|
|
M3.ElementMultiplyWith(M00);
|
|
Assert::IsTrue(M3.IsEqualTo(M1, 0.001));
|
|
|
|
M3.SetValue(M0);
|
|
M3.ElementInverse();
|
|
Assert::IsTrue(M3.IsEqualTo(M00, 0.001));
|
|
|
|
M2(0,0) = 0.7311; M2(0,1) = 0.8808; M2(0,2) = 0.9526;
|
|
M2(1,0) = 0.9820; M2(1,1) = 0.9933; M2(1,2) = 0.9975;
|
|
M3.AssignElementDivisionOf(M2, M0);
|
|
M2.ElementMultiplyWith(M00);
|
|
Assert::IsTrue(M3.IsEqualTo(M2, 0.0001));
|
|
|
|
M3.SetValue(M0);
|
|
M3.InplaceSigmoid();
|
|
M2(0,0) = 0.7311; M2(0,1) = 0.8808; M2(0,2) = 0.9526;
|
|
M2(1,0) = 0.9820; M2(1,1) = 0.9933; M2(1,2) = 0.9975;
|
|
Assert::IsTrue(M3.IsEqualTo(M2, 0.0001));
|
|
|
|
M3.SetValue(M0);
|
|
M3.InplaceTanh();
|
|
M2(0,0) = 0.7616; M2(0,1) = 0.9640; M2(0,2) = 0.9951;
|
|
M2(1,0) = 0.9993; M2(1,1) = 0.9999; M2(1,2) = 1.0000;
|
|
Assert::IsTrue(M3.IsEqualTo(M2, 0.0001));
|
|
|
|
M3.SetValue(M0);
|
|
M3.InplaceLogSoftmax(true);
|
|
M3.InplaceExp();
|
|
M2(0,0) = 0.0474; M2(0,1) = 0.0474; M2(0,2) = 0.0474;
|
|
M2(1,0) = 0.9526; M2(1,1) = 0.9526; M2(1,2) = 0.9526;
|
|
Assert::IsTrue(M3.IsEqualTo(M2, 0.0001));
|
|
|
|
M3.SetValue(M0);
|
|
M3.InplaceLogSoftmax(false);
|
|
M3.InplaceExp();
|
|
M2(0,0) = 0.0900; M2(0,1) = 0.2447; M2(0,2) = 0.6652;
|
|
M2(1,0) = 0.0900; M2(1,1) = 0.2447; M2(1,2) = 0.6652;
|
|
Assert::IsTrue(M3.IsEqualTo(M2, 0.0001));
|
|
|
|
M3.SetValue(M0);
|
|
M3.InplaceSqrt();
|
|
M2(0,0) = 1; M2(0,1) = 1.4142; M2(0,2) = 1.7321;
|
|
M2(1,0) = 2; M2(1,1) = 2.2361; M2(1,2) = 2.4495;
|
|
Assert::IsTrue(M3.IsEqualTo(M2, 0.0001));
|
|
|
|
M3.SetValue(M0);
|
|
M3.InplaceExp();
|
|
M2(0,0) = 2.7183; M2(0,1) = 7.3891; M2(0,2) = 20.0855;
|
|
M2(1,0) = 54.5982; M2(1,1) = 148.4132; M2(1,2) = 403.4288;
|
|
Assert::IsTrue(M3.IsEqualTo(M2, 0.0001));
|
|
|
|
M3.SetValue(M0);
|
|
M3.InplaceExp();
|
|
M2(0,0) = 2.7183; M2(0,1) = 7.3891; M2(0,2) = 20.0855;
|
|
M2(1,0) = 54.5982; M2(1,1) = 148.4132; M2(1,2) = 403.4288;
|
|
Assert::IsTrue(M3.IsEqualTo(M2, 0.0001));
|
|
|
|
M3.InplaceLog();
|
|
Assert::IsTrue(M3.IsEqualTo(M0, 0.0001));
|
|
|
|
M3.SetValue(M0);
|
|
M3.InplaceTruncateBottom(2);
|
|
M2(0,0) = 2; M2(0,1) = 2; M2(0,2) = 3;
|
|
M2(1,0) = 4; M2(1,1) = 5; M2(1,2) = 6;
|
|
Assert::IsTrue(M3.IsEqualTo(M2, 0.001));
|
|
|
|
M3.SetValue(M0);
|
|
M3.InplaceTruncateTop(4);
|
|
M2(0,0) = 1; M2(0,1) = 2; M2(0,2) = 3;
|
|
M2(1,0) = 4; M2(1,1) = 4; M2(1,2) = 4;
|
|
Assert::IsTrue(M3.IsEqualTo(M2, 0.001));
|
|
}
|
|
|
|
TEST_METHOD(MatrixColumnElementMultiplyWithVsCPUMatrix)
|
|
{
|
|
CPUMatrix<float> MCPU = CPUMatrix<float>::RandomUniform(429,1024,-3.4,1);
|
|
CPUMatrix<float> ACPU = CPUMatrix<float>::Ones(429,1);
|
|
CPUMatrix<float> MCPU_copy(MCPU);
|
|
MCPU.ColumnElementMultiplyWith(ACPU);
|
|
Assert::IsTrue(MCPU_copy.IsEqualTo(MCPU,0.0001));
|
|
|
|
//
|
|
Matrix<float> M = Matrix<float>::RandomUniform(429,1024,-3.4,1);
|
|
Matrix<float> A = Matrix<float>::Ones(429,1);
|
|
Matrix<float> M_copy(M);
|
|
M.ColumnElementMultiplyWith(A);
|
|
Assert::IsTrue(M_copy.IsEqualTo(M,0.0001));
|
|
|
|
CPUMatrix<float> MC1 = CPUMatrix<float>::RandomUniform(429,1024,-3.4,1);
|
|
CPUMatrix<float> MC2 = CPUMatrix<float>::RandomUniform(429,1,0,3);
|
|
MC1.ColumnElementMultiplyWith(MC2);
|
|
|
|
Matrix<float> M1(MC1.GetNumRows(),MC1.GetNumCols(),MC1.GetArray(),matrixFlagNormal);
|
|
Matrix<float> M2(MC2.GetNumRows(),MC2.GetNumCols(),MC2.GetArray(),matrixFlagNormal);
|
|
M1.ColumnElementMultiplyWith(M2);
|
|
|
|
foreach_coord(i,j,M2)
|
|
{
|
|
Assert::IsTrue(fabs(M2(i,j)-MC2(i,j))<0.00001);
|
|
}
|
|
}
|
|
|
|
TEST_METHOD(MatrixAssignXOf)
|
|
{
|
|
//AssignDifferenceOf
|
|
Matrix<float> A = Matrix<float>::RandomUniform(429,1024,5,32);
|
|
Matrix<float> B = Matrix<float>::RandomUniform(429,1024,5,32);
|
|
Matrix<float> C;
|
|
C.AssignDifferenceOf(A,B);
|
|
foreach_coord(i,j,C)
|
|
{
|
|
Assert::IsTrue(C(i,j)==A(i,j)-B(i,j));
|
|
}
|
|
float x=234.2;
|
|
C.AssignDifferenceOf(A,x);
|
|
foreach_coord(i,j,C)
|
|
{
|
|
Assert::IsTrue(C(i,j)==A(i,j)-x);
|
|
}
|
|
|
|
C.AssignDifferenceOf(x,A);
|
|
foreach_coord(i,j,C)
|
|
{
|
|
Assert::IsTrue(C(i,j)==x-A(i,j));
|
|
}
|
|
|
|
C.AssignDifferenceOf(1,A);
|
|
foreach_coord(i,j,C)
|
|
{
|
|
Assert::IsTrue(C(i,j)==1-A(i,j));
|
|
}
|
|
//
|
|
|
|
//AssignElementProductOf
|
|
C.AssignElementProductOf(A,B);
|
|
foreach_coord(i,j,C)
|
|
{
|
|
Assert::IsTrue(C(i,j)==A(i,j)*B(i,j));
|
|
}
|
|
|
|
//AddElementProductOf
|
|
Matrix<float> C_copy(C);
|
|
C.AddElementProductOf(A,B);
|
|
foreach_coord(i,j,C)
|
|
{
|
|
Assert::IsTrue(C(i,j)==C_copy(i,j)+A(i,j)*B(i,j));
|
|
}
|
|
|
|
//AssignSigmoidOf
|
|
CPUMatrix<float> AC = CPUMatrix<float>::RandomUniform(429,1024,5,32);
|
|
CPUMatrix<float> BC = CPUMatrix<float>::RandomUniform(429,1024,-5,12);
|
|
Matrix<float> D(AC.GetNumRows(),AC.GetNumCols(),AC.GetArray(),matrixFlagNormal);
|
|
Matrix<float> E(BC.GetNumRows(),BC.GetNumCols(),BC.GetArray(),matrixFlagNormal);
|
|
AC.AssignSigmoidOf(BC);
|
|
D.AssignSigmoidOf(E);
|
|
foreach_coord(i,j,AC)
|
|
{
|
|
Assert::IsTrue(fabs(AC(i,j)-D(i,j))<0.00001);
|
|
}
|
|
|
|
//AssignSignOf
|
|
Matrix<float> M1 = Matrix<float>::RandomUniform(42,12,-5,12);
|
|
Matrix<float> M2((size_t)4, (size_t)5);
|
|
M2.AssignSignOf(M1);
|
|
foreach_coord(i,j,M1)
|
|
{
|
|
float v = M1(i,j);
|
|
float expected = (v == (float)0? (float)0 : (v > 0? (float)1 : (float)(-1)));
|
|
float actual = M2(i,j);
|
|
Assert::AreEqual<float>(expected, actual);
|
|
}
|
|
|
|
Matrix<float> M3 = Matrix<float>::RandomUniform(42,12,-5,2);;
|
|
Matrix<float> M4(M3);
|
|
M3.AddSignOf(M1);
|
|
foreach_coord(i,j,M3)
|
|
{
|
|
float v = M1(i,j);
|
|
Assert::AreEqual<float>(M4(i,j)+(v == (float)0? (float)0 : (v > 0? (float)1 : (float)(-1))),M3(i,j));
|
|
}
|
|
|
|
|
|
//AssignTruncateBottom and Top
|
|
Matrix<float> M5((size_t)2, (size_t)2);
|
|
M5(0,0)=1; M5(0,1)=2;
|
|
M5(1,0)=3; M5(1,1)=4;
|
|
|
|
Matrix<float> M6;
|
|
M6.AssignTruncateBottomOf(M5,3);
|
|
Assert::AreEqual<float>(3,M6(0,0));
|
|
Assert::AreEqual<float>(3,M6(0,1));
|
|
Assert::AreEqual<float>(3,M6(1,0));
|
|
Assert::AreEqual<float>(4,M6(1,1));
|
|
|
|
|
|
Matrix<float> M7;
|
|
M7.AssignTruncateTopOf(M5,3);
|
|
Assert::AreEqual<float>(1,M7(0,0));
|
|
Assert::AreEqual<float>(2,M7(0,1));
|
|
Assert::AreEqual<float>(3,M7(1,0));
|
|
Assert::AreEqual<float>(3,M7(1,1));
|
|
}
|
|
|
|
TEST_METHOD(MatrixSum)
|
|
{
|
|
Matrix<float> M=Matrix<float>::Ones(429,1024,0);
|
|
float sum = M.SumOfElements();
|
|
Assert::AreEqual<float>(429*1024,sum);
|
|
|
|
CPUMatrix<float> MCPU=CPUMatrix<float>::Ones(429,1024);
|
|
float sumCPU = MCPU.SumOfElements();
|
|
Assert::AreEqual<float>(429*1024,sumCPU);
|
|
|
|
Matrix<float> M1=Matrix<float>::Ones(42,332);
|
|
M1*=-1;
|
|
float sum1 = M1.SumOfElements();
|
|
Assert::AreEqual<float>(-1*42*332,sum1);
|
|
|
|
Matrix<float> M2=Matrix<float>::Ones(3,2);
|
|
M2*=-1;
|
|
float sum2 = M2.SumOfElements();
|
|
Assert::AreEqual<float>(-1*3*2,sum2);
|
|
}
|
|
|
|
TEST_METHOD(MatrixColumnSlice)
|
|
{
|
|
float *fArray = new float[6];
|
|
fArray[0] = 1; fArray[1] = 4; fArray[2] = 2;
|
|
fArray[3] = 5; fArray[4] = 3; fArray[5] = 6;
|
|
Matrix<float> M0(2, 3, fArray, matrixFlagNormal);
|
|
|
|
Matrix<float> M1(2, 2, fArray, matrixFlagNormal);
|
|
|
|
Matrix<float> M2 = M0.ColumnSlice(0,2);
|
|
Assert::IsTrue(M2.IsEqualTo(M1, 0.0001));
|
|
|
|
Matrix<float> M3(2, 2, fArray+2, matrixFlagNormal);
|
|
|
|
M2 = M0.ColumnSlice(1,2);
|
|
Assert::IsTrue(M2.IsEqualTo(M3, 0.0001));
|
|
|
|
|
|
size_t k=100, n=20, m=50;
|
|
|
|
Matrix<float> AG((size_t)k,(size_t)n);
|
|
AG.SetUniformRandomValue(-1,1);
|
|
|
|
Matrix<float> BG((size_t)n,(size_t)m);
|
|
BG.SetUniformRandomValue(-1,1);
|
|
|
|
Matrix<float> CG((size_t)k,(size_t)m);
|
|
CG.SetUniformRandomValue(-1,1);
|
|
Matrix<float> DG((size_t)k,(size_t)m);
|
|
DG.SetValue(CG);
|
|
|
|
Matrix<float>::MultiplyAndAdd(AG, false, BG, false, DG);
|
|
|
|
for (int i=0; i<m; i++)
|
|
{
|
|
Matrix<float> col_BG = BG.ColumnSlice(i,1);
|
|
Matrix<float> col_CG = CG.ColumnSlice(i,1);
|
|
Matrix<float>::MultiplyAndAdd(AG, false, col_BG, false, col_CG);
|
|
}
|
|
Assert::IsTrue(CG.IsEqualTo(DG, 0.0001));
|
|
}
|
|
|
|
TEST_METHOD(MatrixKhatriRaoProduct)
|
|
{
|
|
float *fArray = new float[24];
|
|
fArray[0] = 0.8147f; fArray[3] = 0.9134f; fArray[6] = 0.2785f; fArray[9] = 0.9649f;
|
|
fArray[1] = 0.9058f; fArray[4] = 0.6324f; fArray[7] = 0.5469f; fArray[10] = 0.1576f;
|
|
fArray[2] = 0.1270f; fArray[5] = 0.0975f; fArray[8] = 0.9575f; fArray[11] = 0.9706f;
|
|
Matrix<float> A(3,4,fArray);
|
|
|
|
fArray[0] = 0.9572f; fArray[2] = 0.8003f; fArray[4] = 0.4218f; fArray[6] = 0.7922f;
|
|
fArray[1] = 0.4854f; fArray[3] = 0.1419f; fArray[5] = 0.9157f; fArray[7] = 0.9595f;
|
|
Matrix<float> B(2,4,fArray);
|
|
|
|
fArray[0] = 0.7798f; fArray[6] = 0.7310f; fArray[12] = 0.1175f; fArray[18] = 0.7644f;
|
|
fArray[1] = 0.8670f; fArray[7] = 0.5061f; fArray[13] = 0.2307f; fArray[19] = 0.1249f;
|
|
fArray[2] = 0.1215f; fArray[8] = 0.0781f; fArray[14] = 0.4038f; fArray[20] = 0.7689f;
|
|
fArray[3] = 0.3954f; fArray[9] = 0.1296f; fArray[15] = 0.2550f; fArray[21] = 0.9258f;
|
|
fArray[4] = 0.4396f; fArray[10] = 0.0897f; fArray[16] = 0.5008f; fArray[22] = 0.1512f;
|
|
fArray[5] = 0.0616f; fArray[11] = 0.0138f; fArray[17] = 0.8768f; fArray[23] = 0.9313f;
|
|
Matrix<float> D(6,4, fArray);
|
|
|
|
Matrix<float> C;
|
|
C.AssignKhatriRaoProductOf(A, B);
|
|
Assert::IsTrue(C.IsEqualTo(D, 0.0001f));
|
|
}
|
|
TEST_METHOD(MatrixAddColumnReshapeProductOf)
|
|
{
|
|
float *fArray = new float[12];
|
|
fArray[0] = 0.6557f; fArray[6] = 0.7431f;
|
|
fArray[1] = 0.0357f; fArray[7] = 0.3922f;
|
|
fArray[2] = 0.8491f; fArray[8] = 0.6555f;
|
|
fArray[3] = 0.9340f; fArray[9] = 0.1712f;
|
|
fArray[4] = 0.6787f; fArray[10] = 0.7060f;
|
|
fArray[5] = 0.7577f; fArray[11] = 0.0318f;
|
|
Matrix<float> A(6,2,fArray);
|
|
|
|
fArray[0] = 0.2769f; fArray[3] = 0.8235f;
|
|
fArray[1] = 0.0462f; fArray[4] = 0.6948f;
|
|
fArray[2] = 0.0971f; fArray[5] = 0.3171f;
|
|
Matrix<float> B(3,2,fArray);
|
|
|
|
fArray[0] = 0.2867f; fArray[2] = 1.2913f;
|
|
fArray[1] = 0.1266f; fArray[3] = 0.4520f;
|
|
Matrix<float> D0(2,2,fArray);
|
|
|
|
fArray[0] = 0.2657f; fArray[2] = 1.0923f;
|
|
fArray[1] = 0.3636f; fArray[3] = 0.6416f;
|
|
Matrix<float> D1(2,2,fArray);
|
|
|
|
Matrix<float> C((size_t)2, (size_t)2);
|
|
C.SetValue(0.0f);
|
|
C.AddColumnReshapeProductOf(A, B, false);
|
|
Assert::IsTrue(C.IsEqualTo(D0, 0.0001f));
|
|
|
|
C.SetValue(0.0f);
|
|
C.AddColumnReshapeProductOf(A, B, true);
|
|
Assert::IsTrue(C.IsEqualTo(D1, 0.0001f));
|
|
}
|
|
};
|
|
} |