Files
Aurora/test/FunctionTester.cpp
2023-04-21 17:04:09 +08:00

399 lines
14 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <gtest/gtest.h>
#include "Matrix.h"
#include "Function.h"
#include "Function1D.h"
#include "Function2D.h"
#define DISPLAY_MATRIX(Matrix)\
printf("=====================================\r\n");\
printf("%s:\r\n", #Matrix);\
Matrix.printf();\
printf("%s end================================\r\n", #Matrix);
#define DISPLAY_MATRIX
class FunctionTester:public ::testing::Test{
protected:
static void SetUpFunctionTester(){
}
static void TearDownTestCase(){
}
void SetUp(){
}
void TearDown(){
}
};
double fourDecimalRound(double src){
return round(src*10000.0)/10000.0;
}
TEST_F(FunctionTester, MatrixCreate) {
double * dataA =Aurora::malloc(9);
double * dataB = new double[9];
double * dataC = new double[9];
double * dataD = new double[9];
//mkl matrix
{
Aurora::Matrix A = Aurora::Matrix::New(dataA, 3, 3);
EXPECT_EQ(dataA, A.getData());
EXPECT_EQ(9, A.getDataSize());
EXPECT_EQ(2, A.getDims());
EXPECT_EQ(3, A.getDimSize(0));
EXPECT_EQ(3, A.getDimSize(1));
EXPECT_EQ(Aurora::Normal, A.getValueType());
DISPLAY_MATRIX(A);
}
// double [] matrix
{
Aurora::Matrix B = Aurora::Matrix::fromRawData(dataB, 3, 3);
EXPECT_EQ(dataB, B.getData());
EXPECT_EQ(9, B.getDataSize());
EXPECT_EQ(2, B.getDims());
EXPECT_EQ(3, B.getDimSize(0));
EXPECT_EQ(3, B.getDimSize(1));
EXPECT_EQ(Aurora::Normal, B.getValueType());
DISPLAY_MATRIX(B);
}
// copy from double [] to mkl matrix
{
Aurora::Matrix C = Aurora::Matrix::copyFromRawData(dataC, 3, 3);
EXPECT_NE(dataC, C.getData());
EXPECT_EQ(9, C.getDataSize());
EXPECT_EQ(2, C.getDims());
EXPECT_EQ(3, C.getDimSize(0));
EXPECT_EQ(3, C.getDimSize(1));
EXPECT_EQ(Aurora::Normal, C.getValueType());
DISPLAY_MATRIX(C);
}
// 2vector
{
Aurora::Matrix C = Aurora::Matrix::copyFromRawData(dataC, 9);
EXPECT_NE(dataC, C.getData());
EXPECT_EQ(9, C.getDataSize());
EXPECT_EQ(2, C.getDims());
EXPECT_EQ(9, C.getDimSize(0));
EXPECT_EQ(1, C.getDimSize(1));
EXPECT_EQ(Aurora::Normal, C.getValueType());
DISPLAY_MATRIX(C);
}
// 2d vector
{
Aurora::Matrix C = Aurora::Matrix::fromRawData(dataC, 9, 1);
EXPECT_EQ(dataC, C.getData());
EXPECT_EQ(9, C.getDataSize());
EXPECT_EQ(2, C.getDims());
EXPECT_EQ(9, C.getDimSize(0));
EXPECT_EQ(1, C.getDimSize(1));
EXPECT_EQ(Aurora::Normal, C.getValueType());
DISPLAY_MATRIX(C);
}
// 2d vector column major
{
Aurora::Matrix C = Aurora::Matrix::copyFromRawData(dataD, 1, 9);
EXPECT_NE(dataD, C.getData());
delete [] dataD;
EXPECT_EQ(9, C.getDataSize());
EXPECT_EQ(2, C.getDims());
EXPECT_EQ(1, C.getDimSize(0));
EXPECT_EQ(9, C.getDimSize(1));
EXPECT_EQ(Aurora::Normal, C.getValueType());
DISPLAY_MATRIX(C);
}
// 3d matrix
{
double * tempData = new double[9];
Aurora::Matrix C = Aurora::Matrix::fromRawData(tempData, 3, 3,1);
EXPECT_EQ(dataD, C.getData());
EXPECT_EQ(9, C.getDataSize());
EXPECT_EQ(2, C.getDims());
EXPECT_EQ(3, C.getDimSize(0));
EXPECT_EQ(3, C.getDimSize(1));
EXPECT_EQ(1, C.getDimSize(2));
EXPECT_EQ(Aurora::Normal, C.getValueType());
DISPLAY_MATRIX(C);
}
// 3d matrix 2
{
double * tempData = new double[9];
Aurora::Matrix C = Aurora::Matrix::fromRawData(tempData, 3, 1,3);
EXPECT_EQ(dataD, C.getData());
EXPECT_EQ(9, C.getDataSize());
EXPECT_EQ(3, C.getDims());
EXPECT_EQ(3, C.getDimSize(0));
EXPECT_EQ(1, C.getDimSize(1));
EXPECT_EQ(3, C.getDimSize(2));
EXPECT_EQ(Aurora::Normal, C.getValueType());
DISPLAY_MATRIX(C);
}
}
TEST_F(FunctionTester, matrixSlice) {
double * dataA =Aurora::malloc(8);
double * dataB =Aurora::malloc(8);
double * dataC =Aurora::malloc(8);
for (int i = 0; i < 8; ++i) {
dataA[i]=(double)(i);
dataB[i]=(double)(1);
dataC[i]=(double)(9-i);
}
Aurora::Matrix A = Aurora::Matrix::New(dataA,2,2,2);
Aurora::Matrix B = Aurora::Matrix::New(dataB,2,2,2);
Aurora::Matrix C = Aurora::Matrix::New(dataC,2,2,2);
//2D slice
EXPECT_EQ(4.0,dataA[4]);
A(Aurora::$,Aurora::$,1) = B(0,Aurora::$,Aurora::$);
EXPECT_EQ(1,dataA[4]);
EXPECT_EQ(3,dataA[3]);
A(Aurora::$,1,Aurora::$) = B(Aurora::$,Aurora::$,0);
EXPECT_EQ(1.0,dataA[3]);
EXPECT_EQ(0.0,dataA[0]);
A(0,Aurora::$,Aurora::$) = B(Aurora::$,0,Aurora::$);
EXPECT_EQ(1.0,dataA[0]);
//vector slice
A(0,Aurora::$,0) = C(0,0,Aurora::$);
EXPECT_EQ(9.0,dataA[0]);
A(Aurora::$,0,0) = C(0,Aurora::$,1);
EXPECT_EQ(5.0,dataA[0]);
//error slice
EXPECT_EQ(1,A(Aurora::$,Aurora::$,Aurora::$).toMatrix().getDataSize() );
auto D =C(0,0,0).toMatrix();
EXPECT_EQ(1,D.getDataSize() );
EXPECT_EQ(9,D.getData()[0] );
}
TEST_F(FunctionTester, matrixOpertaor) {
//3D
{
double * dataA =new double[8];
double * dataB =new double[8];
double * dataD =new double[8];
for (int i = 0; i < 8; ++i) {
dataA[i]=(double)(i);
dataB[i]=(double)(2);
}
Aurora::Matrix A = Aurora::Matrix::fromRawData(dataA,2,2,2);
DISPLAY_MATRIX(A);
Aurora::Matrix B = Aurora::Matrix::fromRawData(dataB,2,2,2);
DISPLAY_MATRIX(B);
Aurora::Matrix D = Aurora::Matrix::fromRawData(dataD,4,2);
DISPLAY_MATRIX(D);
auto C = (A*B)-B;
DISPLAY_MATRIX(C);
EXPECT_EQ(C.getData()[2],2);
C = A*B/2.0;
EXPECT_EQ(C.getData()[2],2);
C = (A*8.0/B) * (B+1.0)-2.0+8;
EXPECT_EQ(C.getData()[2],30);
//Error matrix
C = A*D;
EXPECT_EQ(C.getDataSize(),0);
}
//complex
{
double * dataA =Aurora::malloc(8,true);
double * dataB =Aurora::malloc(8,true);
double * dataD =new double[8];
for (int i = 0; i < 16; ++i) {
dataA[i]=(double)(i+1);
dataB[i]=(double)(2);
if(i<8) dataD[i]=(double)(2);
}
Aurora::Matrix A = Aurora::Matrix::New(dataA,2,2,2,Aurora::Complex);
DISPLAY_MATRIX(A);
Aurora::Matrix B = Aurora::Matrix::New(dataB,2,2,2,Aurora::Complex);
DISPLAY_MATRIX(B);
Aurora::Matrix D = Aurora::Matrix::fromRawData(dataD,2,2,2);
DISPLAY_MATRIX(D);
auto C = A + 5.0 -2.0;
DISPLAY_MATRIX(C);
EXPECT_EQ(C.getData()[2],6);
EXPECT_EQ(C.getData()[3],4);
EXPECT_TRUE(C.isComplex());
C = A*B-B;
DISPLAY_MATRIX(C);
EXPECT_EQ(C.getData()[2],-4);
EXPECT_EQ(C.getData()[3],12);
EXPECT_TRUE(C.isComplex());
C = A*B-2.0+5.0;
DISPLAY_MATRIX(C);
EXPECT_EQ(C.getData()[2],1);
EXPECT_EQ(C.getData()[3],14);
C = A*B/2.0*3.;
DISPLAY_MATRIX(C);
EXPECT_EQ(C.getData()[2],-3);
EXPECT_EQ(C.getData()[3],21);
C = A*B/B;
DISPLAY_MATRIX(C);
EXPECT_EQ(C.getData()[2],3);
EXPECT_EQ(C.getData()[3],4);
C = A*B/(B*A/A);
DISPLAY_MATRIX(C);
EXPECT_EQ(C.getData()[2],3);
EXPECT_EQ(C.getData()[3],4);
C = B*D;
DISPLAY_MATRIX(C);
EXPECT_EQ(C.getData()[2],4);
EXPECT_EQ(C.getData()[3],4);
C = B/D;
DISPLAY_MATRIX(C);
EXPECT_EQ(C.getData()[2],1);
EXPECT_EQ(C.getData()[3],1);
C = B+D;
DISPLAY_MATRIX(C);
EXPECT_EQ(C.getData()[2],4);
EXPECT_EQ(C.getData()[3],2);
C = B-D;
DISPLAY_MATRIX(C);
EXPECT_EQ(C.getData()[2],0);
EXPECT_EQ(C.getData()[3],2);
C = B*(D*1.0);
DISPLAY_MATRIX(C);
EXPECT_EQ(C.getData()[2],4);
EXPECT_EQ(C.getData()[3],4);
C = B/(D*1.0);
DISPLAY_MATRIX(C);
EXPECT_EQ(C.getData()[2],1);
EXPECT_EQ(C.getData()[3],1);
C = B+(D*1.0);
DISPLAY_MATRIX(C);
EXPECT_EQ(C.getData()[2],4);
EXPECT_EQ(C.getData()[3],2);
C = B-(D*1.0);
DISPLAY_MATRIX(C);
EXPECT_EQ(C.getData()[2],0);
EXPECT_EQ(C.getData()[3],2);
C = (B*1.0)*(D*1.0);
DISPLAY_MATRIX(C);
EXPECT_EQ(C.getData()[2],4);
EXPECT_EQ(C.getData()[3],4);
C = (B*1.0)/(D*1.0);
DISPLAY_MATRIX(C);
EXPECT_EQ(C.getData()[2],1);
EXPECT_EQ(C.getData()[3],1);
C = (B*1.0)+(D*1.0);
DISPLAY_MATRIX(C);
EXPECT_EQ(C.getData()[2],4);
EXPECT_EQ(C.getData()[3],2);
C = (B*1.0)-(D*1.0);
DISPLAY_MATRIX(C);
EXPECT_EQ(C.getData()[2],0);
EXPECT_EQ(C.getData()[3],2);
}
}
TEST_F(FunctionTester, sign) {
double * dataA =Aurora::malloc(9);
double * dataB =Aurora::malloc(9);
for (int i = 0; i < 9; ++i) {
dataA[i]=(double)(i-3);
dataB[i]=(double)(i+2);
}
Aurora::Matrix A = Aurora::Matrix::New(dataA,3,3);
Aurora::Matrix B = Aurora::Matrix::New(dataB,3,3);
auto C = sign(A*B);
double * result = C.getData();
EXPECT_EQ(-1, result[0]);
EXPECT_EQ(0, result[3]);
EXPECT_EQ(1, result[4]);
}
TEST_F(FunctionTester, immse){
double *dataA = new double[9]{1,2,3,4,5,6,7,8,9};
double *dataB = new double[9]{10,20,30,40,50,40,30,20,10};
Aurora::Matrix A = Aurora::Matrix::fromRawData(dataA,3,3);
Aurora::Matrix B = Aurora::Matrix::fromRawData(dataB,3,3);
double v = immse(A,B);
EXPECT_DOUBLE_EQ(fourDecimalRound(v),698.3333)<<" immse error;";
}
TEST_F(FunctionTester, inv){
//默认是column major排布数据
double *dataA=new double[9]{2, 0, 2, 2, 3, 0, 3, 3, 3};
double *dataB=new double[9]{1, 1, 1, 1, 1, 1, 1, 1, 1};
Aurora::Matrix A = Aurora::Matrix::fromRawData(dataA,3,3);
Aurora::Matrix B = Aurora::Matrix::fromRawData(dataB,3,3);
auto invA = Aurora::inv(A);
double* result = invA.getData();
EXPECT_DOUBLE_EQ(0.75, fourDecimalRound(result[0]));
EXPECT_DOUBLE_EQ(0.5, fourDecimalRound(result[1]));
EXPECT_DOUBLE_EQ(-0.5, fourDecimalRound(result[2]));
EXPECT_DOUBLE_EQ(-0.5, fourDecimalRound(result[3]));
EXPECT_DOUBLE_EQ(.0, fourDecimalRound(result[4]));
EXPECT_DOUBLE_EQ(0.3333, fourDecimalRound(result[5]));
EXPECT_DOUBLE_EQ(-0.25, fourDecimalRound(result[6]));
EXPECT_DOUBLE_EQ(-0.5, fourDecimalRound(result[7]));
EXPECT_DOUBLE_EQ(0.5, fourDecimalRound(result[8]));
invA = Aurora::inv(A*B);
result = invA.getData();
EXPECT_DOUBLE_EQ(0.75, fourDecimalRound(result[0]));
EXPECT_DOUBLE_EQ(0.5, fourDecimalRound(result[1]));
EXPECT_DOUBLE_EQ(-0.5, fourDecimalRound(result[2]));
EXPECT_DOUBLE_EQ(-0.5, fourDecimalRound(result[3]));
EXPECT_DOUBLE_EQ(.0, fourDecimalRound(result[4]));
EXPECT_DOUBLE_EQ(0.3333, fourDecimalRound(result[5]));
EXPECT_DOUBLE_EQ(-0.25, fourDecimalRound(result[6]));
EXPECT_DOUBLE_EQ(-0.5, fourDecimalRound(result[7]));
EXPECT_DOUBLE_EQ(0.5, fourDecimalRound(result[8]));
}
TEST_F(FunctionTester, polyval){
double dataP[3]={3,2,1};
double dataX[3]={5,7,9};
double*resultP = Aurora::polyval(dataX,dataP,3);
EXPECT_DOUBLE_EQ(86., resultP[0])<<" polyval error;";
EXPECT_DOUBLE_EQ(162., resultP[1])<<" polyval error;";
EXPECT_DOUBLE_EQ(262., resultP[2])<<" polyval error;";
delete [] resultP;
}
TEST_F(FunctionTester, std){
double dataMA[9]={1, 2, 3, 2, 2, 6, 3, 3, 6};
double* resultStd = Aurora::std(3, 3, dataMA);
EXPECT_DOUBLE_EQ(1.0, resultStd[0])<<" std error index 0";
EXPECT_DOUBLE_EQ(2.3094, fourDecimalRound(resultStd[1]))<<" std error index 1";
EXPECT_DOUBLE_EQ(1.7321, fourDecimalRound(resultStd[2]))<<" std error index 2";
delete [] resultStd;
}
TEST_F(FunctionTester, fftAndComplexAndIfft){
double input[10]{1,1,0,2,2,0,1,1,0,2};
std::complex<double>* complexInput = Aurora::complex(10,input);
//复数化后实部不变虚部全为0
EXPECT_DOUBLE_EQ(complexInput[1].real(),1.0)<<" complex error";
EXPECT_DOUBLE_EQ(complexInput[1].imag(),0)<<" complex error";
std::complex<double>* result = Aurora::fft(10,complexInput);
delete [] complexInput;
//检验fft结果与matlab是否对应
EXPECT_DOUBLE_EQ(0.0729, fourDecimalRound(result[1].real()))<<" fft result value error";
EXPECT_DOUBLE_EQ(2.4899, fourDecimalRound(result[2].imag()))<<" fft result value error";
//检验fft的结果是否共轭
EXPECT_DOUBLE_EQ(0, result[4].imag()+result[6].imag())<<" fft result conjugate error";
EXPECT_DOUBLE_EQ(0, result[4].real()-result[6].real())<<" fft result conjugate error";
std::complex<double>* ifftResult = Aurora::ifft(10,result);
EXPECT_DOUBLE_EQ(fourDecimalRound(ifftResult[1].real()),1.0)<<" ifft result real value error";
EXPECT_DOUBLE_EQ(fourDecimalRound(ifftResult[1].imag()),0)<<" ifft result imag value error";
delete [] result;
delete [] ifftResult;
}
TEST_F(FunctionTester, hilbert) {
double input[10]{1,1,0,2,2,0,1,1,0,2};
auto result = Aurora::hilbert(10,input);
EXPECT_DOUBLE_EQ(fourDecimalRound(result[1].real()),1.0)<<" hilbert result real value error";
EXPECT_DOUBLE_EQ(fourDecimalRound(result[1].imag()),0.3249)<<" hilbert result imag value error";
delete [] result;
result = Aurora::hilbert(9,input);
EXPECT_DOUBLE_EQ(fourDecimalRound(result[1].real()),1.0)<<" hilbert result real value error";
EXPECT_DOUBLE_EQ(fourDecimalRound(result[1].imag()),0.4253)<<" hilbert result imag value error";
}