Commit a5cd62f7 authored by Alexander Alekhin's avatar Alexander Alekhin

core(perf): refactor kmeans test

- don't use RNG for "task size" parameters (N, K, dims)
- add "good" kmeans test data (without singularities: K > unique points)
parent 12ea8477
...@@ -3,13 +3,10 @@ ...@@ -3,13 +3,10 @@
using namespace std; using namespace std;
using namespace cv; using namespace cv;
using namespace perf; using namespace perf;
using std::tr1::make_tuple;
using std::tr1::get;
typedef perf::TestBaseWithParam<size_t> VectorLength; namespace {
typedef std::tr1::tuple<int, int> MaxDim_MaxPoints_t; typedef perf::TestBaseWithParam<size_t> VectorLength;
typedef perf::TestBaseWithParam<MaxDim_MaxPoints_t> MaxDim_MaxPoints;
PERF_TEST_P(VectorLength, phase32f, testing::Values(128, 1000, 128*1024, 512*1024, 1024*1024)) PERF_TEST_P(VectorLength, phase32f, testing::Values(128, 1000, 128*1024, 512*1024, 1024*1024))
{ {
...@@ -39,47 +36,125 @@ PERF_TEST_P(VectorLength, phase64f, testing::Values(128, 1000, 128*1024, 512*102 ...@@ -39,47 +36,125 @@ PERF_TEST_P(VectorLength, phase64f, testing::Values(128, 1000, 128*1024, 512*102
SANITY_CHECK(angle, 5e-5); SANITY_CHECK(angle, 5e-5);
} }
PERF_TEST_P( MaxDim_MaxPoints, kmeans, typedef perf::TestBaseWithParam< testing::tuple<int, int, int> > KMeans;
testing::Combine( testing::Values( 16, 32, 64 ),
testing::Values( 300, 400, 500) ) ) PERF_TEST_P_(KMeans, single_iter)
{ {
RNG& rng = theRNG(); RNG& rng = theRNG();
const int MAX_DIM = get<0>(GetParam()); const int K = testing::get<0>(GetParam());
const int MAX_POINTS = get<1>(GetParam()); const int dims = testing::get<1>(GetParam());
const int N = testing::get<2>(GetParam());
const int attempts = 5; const int attempts = 5;
Mat labels, centers; Mat data(N, dims, CV_32F);
int i, N = 0, N0 = 0, K = 0, dims = 0; rng.fill(data, RNG::UNIFORM, -0.1, 0.1);
dims = rng.uniform(1, MAX_DIM+1);
N = rng.uniform(1, MAX_POINTS+1);
N0 = rng.uniform(1, MAX(N/10, 2));
K = rng.uniform(1, N+1);
const int N0 = K;
Mat data0(N0, dims, CV_32F); Mat data0(N0, dims, CV_32F);
rng.fill(data0, RNG::UNIFORM, -1, 1); rng.fill(data0, RNG::UNIFORM, -1, 1);
for (int i = 0; i < N; i++)
{
int base = rng.uniform(0, N0);
cv::add(data0.row(base), data.row(i), data.row(i));
}
declare.in(data);
Mat labels, centers;
TEST_CYCLE()
{
kmeans(data, K, labels, TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS, 1, 0),
attempts, KMEANS_PP_CENTERS, centers);
}
SANITY_CHECK_NOTHING();
}
PERF_TEST_P_(KMeans, good)
{
RNG& rng = theRNG();
const int K = testing::get<0>(GetParam());
const int dims = testing::get<1>(GetParam());
const int N = testing::get<2>(GetParam());
const int attempts = 5;
Mat data(N, dims, CV_32F); Mat data(N, dims, CV_32F);
for( i = 0; i < N; i++ ) rng.fill(data, RNG::UNIFORM, -0.1, 0.1);
data0.row(rng.uniform(0, N0)).copyTo(data.row(i));
const int N0 = K;
Mat data0(N0, dims, CV_32F);
rng.fill(data0, RNG::UNIFORM, -1, 1);
for (int i = 0; i < N; i++)
{
int base = rng.uniform(0, N0);
cv::add(data0.row(base), data.row(i), data.row(i));
}
declare.in(data); declare.in(data);
Mat labels, centers;
TEST_CYCLE() TEST_CYCLE()
{ {
kmeans(data, K, labels, TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS, 30, 0), kmeans(data, K, labels, TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS, 30, 0),
attempts, KMEANS_PP_CENTERS, centers); attempts, KMEANS_PP_CENTERS, centers);
} }
Mat clusterPointsNumber = Mat::zeros(1, K, CV_32S); SANITY_CHECK_NOTHING();
}
PERF_TEST_P_(KMeans, with_duplicates)
{
RNG& rng = theRNG();
const int K = testing::get<0>(GetParam());
const int dims = testing::get<1>(GetParam());
const int N = testing::get<2>(GetParam());
const int attempts = 5;
Mat data(N, dims, CV_32F, Scalar::all(0));
const int N0 = std::max(2, K * 2 / 3);
Mat data0(N0, dims, CV_32F);
rng.fill(data0, RNG::UNIFORM, -1, 1);
for (int i = 0; i < N; i++)
{
int base = rng.uniform(0, N0);
data0.row(base).copyTo(data.row(i));
}
declare.in(data);
for( i = 0; i < labels.rows; i++ ) Mat labels, centers;
TEST_CYCLE()
{ {
int clusterIdx = labels.at<int>(i); kmeans(data, K, labels, TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS, 30, 0),
clusterPointsNumber.at<int>(clusterIdx)++; attempts, KMEANS_PP_CENTERS, centers);
} }
Mat sortedClusterPointsNumber; SANITY_CHECK_NOTHING();
cv::sort(clusterPointsNumber, sortedClusterPointsNumber, cv::SORT_EVERY_ROW + cv::SORT_ASCENDING); }
INSTANTIATE_TEST_CASE_P(/*nothing*/ , KMeans,
testing::Values(
// K clusters, dims, N points
testing::make_tuple(2, 3, 100000),
testing::make_tuple(4, 3, 500),
testing::make_tuple(4, 3, 1000),
testing::make_tuple(4, 3, 10000),
testing::make_tuple(8, 3, 1000),
testing::make_tuple(8, 16, 1000),
testing::make_tuple(8, 64, 1000),
testing::make_tuple(16, 16, 1000),
testing::make_tuple(16, 32, 1000),
testing::make_tuple(32, 16, 1000),
testing::make_tuple(32, 32, 1000),
testing::make_tuple(100, 2, 1000)
)
);
SANITY_CHECK(sortedClusterPointsNumber);
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment