Add sort, sortrows, median and their unit test.
This commit is contained in:
@@ -425,3 +425,94 @@ Matrix Aurora::mean(const Matrix &aMatrix, FunctionDirection direction, bool aIn
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Matrix Aurora::sort(const Matrix &aMatrix) {
|
||||||
|
if (aMatrix.getDimSize(2)>1 || aMatrix.isComplex()) {
|
||||||
|
std::cerr
|
||||||
|
<< (aMatrix.getDimSize(2) > 1 ? "sort() not support 3D data!" : "sort() not support complex value type!")
|
||||||
|
<< std::endl;
|
||||||
|
return Matrix();
|
||||||
|
}
|
||||||
|
return sort(std::forward<Matrix &&>(aMatrix.deepCopy()));
|
||||||
|
}
|
||||||
|
Matrix Aurora::sort(Matrix &&aMatrix) {
|
||||||
|
if (aMatrix.getDimSize(2)>1 || aMatrix.isComplex()) {
|
||||||
|
std::cerr
|
||||||
|
<< (aMatrix.getDimSize(2) > 1 ? "sort() not support 3D data!" : "sort() not support complex value type!")
|
||||||
|
<< std::endl;
|
||||||
|
return Matrix();
|
||||||
|
}
|
||||||
|
if (aMatrix.getDimSize(0)>=100000){
|
||||||
|
#pragma omp parallel for
|
||||||
|
for (int i = 0; i < aMatrix.getDimSize(1); ++i) {
|
||||||
|
Eigen::Map<Eigen::VectorXd> srcV(aMatrix.getData()+i*aMatrix.getDimSize(0),aMatrix.getDimSize(0));
|
||||||
|
std::sort(srcV.array().begin(),srcV.array().end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < aMatrix.getDimSize(1); ++i) {
|
||||||
|
Eigen::Map<Eigen::VectorXd> srcV(aMatrix.getData()+i*aMatrix.getDimSize(0),aMatrix.getDimSize(0));
|
||||||
|
std::sort(srcV.array().begin(),srcV.array().end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return aMatrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix Aurora::sortrows(const Matrix &aMatrix) {
|
||||||
|
if (aMatrix.getDimSize(2)>1 || aMatrix.isComplex()) {
|
||||||
|
std::cerr
|
||||||
|
<< (aMatrix.getDimSize(2) > 1 ? "sortrows() not support 3D data!" : "sortrows() not support complex value type!")
|
||||||
|
<< std::endl;
|
||||||
|
return Matrix();
|
||||||
|
}
|
||||||
|
return sortrows(std::forward<Matrix &&>(aMatrix.deepCopy()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix Aurora::sortrows(Matrix &&aMatrix) {
|
||||||
|
if (aMatrix.getDimSize(2)>1 || aMatrix.isComplex()) {
|
||||||
|
std::cerr
|
||||||
|
<< (aMatrix.getDimSize(2) > 1 ? "sortrows() not support 3D data!" : "sortrows() not support complex value type!")
|
||||||
|
<< std::endl;
|
||||||
|
return Matrix();
|
||||||
|
}
|
||||||
|
Eigen::Map<Eigen::MatrixXd> srcM(aMatrix.getData(),aMatrix.getDimSize(0),aMatrix.getDimSize(1));
|
||||||
|
if (aMatrix.getDimSize(1)>=100000){
|
||||||
|
#pragma omp parallel for
|
||||||
|
for (int i = 0; i < aMatrix.getDimSize(0); ++i) {
|
||||||
|
std::sort(srcM.row(i).array().begin(),srcM.row(i).array().end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < aMatrix.getDimSize(0); ++i) {
|
||||||
|
std::sort(srcM.row(i).array().begin(),srcM.row(i).array().end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return aMatrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix Aurora::median(const Matrix &aMatrix) {
|
||||||
|
if (aMatrix.getDimSize(2) > 1 || aMatrix.isComplex()) {
|
||||||
|
std::cerr
|
||||||
|
<< (aMatrix.getDimSize(2) > 1 ? "median() not support 3D data!"
|
||||||
|
: "median() not support complex value type!")
|
||||||
|
<< std::endl;
|
||||||
|
return Matrix();
|
||||||
|
}
|
||||||
|
Matrix sorted = sort(aMatrix);
|
||||||
|
Eigen::Map<Eigen::MatrixXd> srcM(sorted.getData(),sorted.getDimSize(0),sorted.getDimSize(1));
|
||||||
|
bool flag = aMatrix.getDimSize(0) % 2 == 1;
|
||||||
|
double* ret = malloc(aMatrix.getDimSize(1));
|
||||||
|
Eigen::Map<Eigen::VectorXd> retV(ret,aMatrix.getDimSize(1));
|
||||||
|
if (flag) {
|
||||||
|
retV = srcM.row(aMatrix.getDimSize(0)/2);
|
||||||
|
return Matrix::New(ret,1,aMatrix.getDimSize(1));
|
||||||
|
} else {
|
||||||
|
retV = (srcM.row(aMatrix.getDimSize(0)/2-1).array()+srcM.row(aMatrix.getDimSize(0)/2).array())/2;
|
||||||
|
return Matrix::New(ret,1,aMatrix.getDimSize(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,6 +64,13 @@ namespace Aurora {
|
|||||||
*/
|
*/
|
||||||
Matrix mean(const Matrix& aMatrix,FunctionDirection direction = Column, bool aIncludeNan = true);
|
Matrix mean(const Matrix& aMatrix,FunctionDirection direction = Column, bool aIncludeNan = true);
|
||||||
|
|
||||||
|
Matrix sort(const Matrix& aMatrix);
|
||||||
|
Matrix sort(Matrix&& aMatrix);
|
||||||
|
|
||||||
|
Matrix sortrows(const Matrix& aMatrix);
|
||||||
|
Matrix sortrows(Matrix&& aMatrix);
|
||||||
|
|
||||||
|
Matrix median(const Matrix& aMatrix);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -245,6 +245,71 @@ TEST_F(Function2D_Test, mean) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(Function2D_Test, sort) {
|
||||||
|
double *dataB = new double[16]{1.1, 2.6, 6.2, 3.8,
|
||||||
|
4.3, 10.6, 5.7, 6.9,
|
||||||
|
7.1, 8.3, 9.7, 11.2,
|
||||||
|
17.8, 13.3,7 , -7.7};
|
||||||
|
auto B = Aurora::Matrix::fromRawData(dataB, 4, 4);
|
||||||
|
auto ret = Aurora::sort(B);
|
||||||
|
EXPECT_EQ(4, ret.getDimSize(0));
|
||||||
|
EXPECT_EQ(4, ret.getDimSize(1));
|
||||||
|
EXPECT_DOUBLE_EQ(3.8, ret.getData()[2]);
|
||||||
|
EXPECT_DOUBLE_EQ(5.7, ret.getData()[5]);
|
||||||
|
EXPECT_DOUBLE_EQ(-7.7, ret.getData()[12]);
|
||||||
|
ret = Aurora::sort(B*5);
|
||||||
|
EXPECT_EQ(4, ret.getDimSize(0));
|
||||||
|
EXPECT_EQ(4, ret.getDimSize(1));
|
||||||
|
EXPECT_DOUBLE_EQ(19, ret.getData()[2]);
|
||||||
|
EXPECT_DOUBLE_EQ(28.5, ret.getData()[5]);
|
||||||
|
EXPECT_DOUBLE_EQ(-38.5, ret.getData()[12]);
|
||||||
|
//big sort 10w以上多线程快
|
||||||
|
double * dataA = Aurora::random(1000000*4);
|
||||||
|
auto A = Aurora::Matrix::New(dataA, 1000000, 4);
|
||||||
|
ret = Aurora::sort(A);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Function2D_Test, sortrows) {
|
||||||
|
double *dataB = new double[16]{1.1, 2.6, 6.2, 3.8,
|
||||||
|
4.3, 10.6, 5.7, 6.9,
|
||||||
|
7.1, 8.3, 9.7, 11.2,
|
||||||
|
17.8, 13.3,7 , -7.7};
|
||||||
|
auto B = Aurora::Matrix::fromRawData(dataB, 4, 4);
|
||||||
|
auto ret = Aurora::sortrows(B);
|
||||||
|
EXPECT_EQ(4, ret.getDimSize(0));
|
||||||
|
EXPECT_EQ(4, ret.getDimSize(1));
|
||||||
|
EXPECT_DOUBLE_EQ(5.7, ret.getData()[2]);
|
||||||
|
EXPECT_DOUBLE_EQ(8.3, ret.getData()[5]);
|
||||||
|
EXPECT_DOUBLE_EQ(17.8, ret.getData()[12]);
|
||||||
|
ret = Aurora::sortrows(B*5);
|
||||||
|
EXPECT_EQ(4, ret.getDimSize(0));
|
||||||
|
EXPECT_EQ(4, ret.getDimSize(1));
|
||||||
|
EXPECT_DOUBLE_EQ(28.5, ret.getData()[2]);
|
||||||
|
EXPECT_DOUBLE_EQ(41.5, ret.getData()[5]);
|
||||||
|
EXPECT_DOUBLE_EQ(89, ret.getData()[12]);
|
||||||
|
//big sort 10w以上多线程快
|
||||||
|
double * dataA = Aurora::random(1000000*4);
|
||||||
|
auto A = Aurora::Matrix::New(dataA, 4, 1000000);
|
||||||
|
ret = Aurora::sortrows(A);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Function2D_Test, median) {
|
||||||
|
double *dataB = new double[20]{1.1, 2.6, 3.8, 6.2,
|
||||||
|
4.3, 5.7, 6.9, 10.6,
|
||||||
|
7.1, 8.3, 9.7, 11.2,
|
||||||
|
17.8, 13.3,26.5 , -7.7,
|
||||||
|
9.9, 8.2, 6.3, 5.1};
|
||||||
|
auto B = Aurora::Matrix::fromRawData(dataB, 4, 5);
|
||||||
|
auto ret = Aurora::median(B);
|
||||||
|
EXPECT_EQ(1, ret.getDimSize(0));
|
||||||
|
EXPECT_EQ(5, ret.getDimSize(1));
|
||||||
|
EXPECT_DOUBLE_EQ(3.2, ret.getData()[0]);
|
||||||
|
EXPECT_DOUBLE_EQ(6.3, ret.getData()[1]);
|
||||||
|
EXPECT_DOUBLE_EQ(9, ret.getData()[2]);
|
||||||
|
EXPECT_DOUBLE_EQ(15.55, ret.getData()[3]);
|
||||||
|
EXPECT_DOUBLE_EQ(7.25, ret.getData()[4]);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(Function2D_Test, fftAndComplexAndIfft){
|
TEST_F(Function2D_Test, fftAndComplexAndIfft){
|
||||||
// double input[10]{1,1,0,2,2,0,1,1,0,2};
|
// double input[10]{1,1,0,2,2,0,1,1,0,2};
|
||||||
// std::complex<double>* complexInput = Aurora::complex(10,input);
|
// std::complex<double>* complexInput = Aurora::complex(10,input);
|
||||||
|
|||||||
Reference in New Issue
Block a user