template<typename MatrixType> void matrixRedux(const MatrixType& m) { typedef typename MatrixType::Index Index; typedef typename MatrixType::Scalar Scalar; typedef typename MatrixType::RealScalar RealScalar; Index rows = m.rows(); Index cols = m.cols(); MatrixType m1 = MatrixType::Random(rows, cols); // The entries of m1 are uniformly distributed in [0,1], so m1.prod() is very small. This may lead to test // failures if we underflow into denormals. Thus, we scale so that entires are close to 1. MatrixType m1_for_prod = MatrixType::Ones(rows, cols) + Scalar(0.2) * m1; VERIFY_IS_MUCH_SMALLER_THAN(MatrixType::Zero(rows, cols).sum(), Scalar(1)); VERIFY_IS_APPROX(MatrixType::Ones(rows, cols).sum(), Scalar(float(rows*cols))); // the float() here to shut up excessive MSVC warning about int->complex conversion being lossy Scalar s(0), p(1), minc(internal::real(m1.coeff(0))), maxc(internal::real(m1.coeff(0))); for(int j = 0; j < cols; j++) for(int i = 0; i < rows; i++) { s += m1(i,j); p *= m1_for_prod(i,j); minc = (std::min)(internal::real(minc), internal::real(m1(i,j))); maxc = (std::max)(internal::real(maxc), internal::real(m1(i,j))); } const Scalar mean = s/Scalar(RealScalar(rows*cols)); VERIFY_IS_APPROX(m1.sum(), s); VERIFY_IS_APPROX(m1.mean(), mean); VERIFY_IS_APPROX(m1_for_prod.prod(), p); VERIFY_IS_APPROX(m1.real().minCoeff(), internal::real(minc)); VERIFY_IS_APPROX(m1.real().maxCoeff(), internal::real(maxc)); // test slice vectorization assuming assign is ok Index r0 = internal::random<Index>(0,rows-1); Index c0 = internal::random<Index>(0,cols-1); Index r1 = internal::random<Index>(r0+1,rows)-r0; Index c1 = internal::random<Index>(c0+1,cols)-c0; VERIFY_IS_APPROX(m1.block(r0,c0,r1,c1).sum(), m1.block(r0,c0,r1,c1).eval().sum()); VERIFY_IS_APPROX(m1.block(r0,c0,r1,c1).mean(), m1.block(r0,c0,r1,c1).eval().mean()); VERIFY_IS_APPROX(m1_for_prod.block(r0,c0,r1,c1).prod(), m1_for_prod.block(r0,c0,r1,c1).eval().prod()); VERIFY_IS_APPROX(m1.block(r0,c0,r1,c1).real().minCoeff(), m1.block(r0,c0,r1,c1).real().eval().minCoeff()); VERIFY_IS_APPROX(m1.block(r0,c0,r1,c1).real().maxCoeff(), m1.block(r0,c0,r1,c1).real().eval().maxCoeff()); // test empty objects VERIFY_IS_APPROX(m1.block(r0,c0,0,0).sum(), Scalar(0)); VERIFY_IS_APPROX(m1.block(r0,c0,0,0).prod(), Scalar(1)); }
cv::Mat performSuperpixelSegmentation_VariableSandM(std::vector<std::vector<double> > &kseeds, std::vector<double> &kseedsx, std::vector<double> &kseedsy, const std::vector<cv::Mat> &vec, const cv::Size &size, const int &STEP, const int &NUMITR = 10) { int sz = size.width*size.height; const int numk = (int) kseedsx.size(); int numitr = 0; int offset = (STEP < 10) ? STEP*1.5 : STEP; cv::Mat klabels = cv::Mat(size, cv::DataType<int>::type); klabels = -1; std::vector<std::vector<double> > sigmac(0); for (int c = 0; c < vec.size(); c++) { sigmac.push_back(std::vector<double>(numk, 0)); } std::vector<double> sigmax(numk, 0); std::vector<double> sigmay(numk, 0); std::vector<int> clustersize(numk, 0); std::vector<double> inv(numk, 0);//to store 1/clustersize[k] values std::vector<double> distxy(sz, DBL_MAX); std::vector<double> distc(sz, DBL_MAX); std::vector<double> distvec(sz, DBL_MAX); std::vector<double> maxc(numk, 10*10);//THIS IS THE VARIABLE VALUE OF M, just start with 10 std::vector<double> maxxy(numk, STEP*STEP);//THIS IS THE VARIABLE VALUE OF M, just start with 10 double invxywt = 1.0/(STEP*STEP);//NOTE: this is different from how usual SLIC/LKM works while( numitr < NUMITR ) { //------ //cumerr = 0; numitr++; //------ distvec.assign(sz, DBL_MAX); for( int n = 0; n < numk; n++ ) { int y1 = std::max(double(0), kseedsy[n]-offset); int y2 = std::min(double(size.height), kseedsy[n]+offset); int x1 = std::max(double(0), kseedsx[n]-offset); int x2 = std::min(double(size.width), kseedsx[n]+offset); for( int y = y1; y < y2; y++ ) { for( int x = x1; x < x2; x++ ) { int i = y*size.width + x; if( !(y < size.height && x < size.width && y >= 0 && x >= 0) ) { throw cv::Exception(); } distc[i] = 0; for (int c = 0; c < vec.size(); c++) { distc[i] += (vec[c].ptr<double>()[i] - kseeds[c][n]) * (vec[c].ptr<double>()[i] - kseeds[c][n]); } distxy[i] = (x - kseedsx[n])*(x - kseedsx[n]) + (y - kseedsy[n])*(y - kseedsy[n]); double dist = distc[i]/maxc[n] + distxy[i]*invxywt;//only varying m, prettier superpixels if( dist < distvec[i] ) { distvec[i] = dist; klabels.ptr<int>()[i] = n; } } } } //----------------------------------------------------------------- // Assign the max color distance for a cluster //----------------------------------------------------------------- if(0 == numitr) { maxc.assign(numk,1); maxxy.assign(numk,1); } {for( int i = 0; i < sz; i++ ) { if(maxc[klabels.ptr<int>()[i]] < distc[i]) maxc[klabels.ptr<int>()[i]] = distc[i]; if(maxxy[klabels.ptr<int>()[i]] < distxy[i]) maxxy[klabels.ptr<int>()[i]] = distxy[i]; }} //----------------------------------------------------------------- // Recalculate the centroid and store in the seed values //----------------------------------------------------------------- for (int c = 0; c < sigmac.size(); c++) { sigmac[c].assign(numk, 0); } sigmax.assign(numk, 0); sigmay.assign(numk, 0); clustersize.assign(numk, 0); for( int j = 0; j < sz; j++ ) { if(!(klabels.ptr<int>()[j] >= 0)) throw cv::Exception(); for (int c = 0; c < sigmac.size(); c++) { sigmac[c][klabels.ptr<int>()[j]] += vec[c].ptr<double>()[j]; } sigmax[klabels.ptr<int>()[j]] += (j%size.width); sigmay[klabels.ptr<int>()[j]] += (j/size.width); clustersize[klabels.ptr<int>()[j]]++; } {for( int k = 0; k < numk; k++ ) { if( clustersize[k] <= 0 ) clustersize[k] = 1; inv[k] = 1.0/double(clustersize[k]);//computing inverse now to multiply, than divide later }} {for( int k = 0; k < numk; k++ ) { for (int c = 0; c < kseeds.size(); c++) { kseeds[c][k] = sigmac[c][k] * inv[k]; } kseedsx[k] = sigmax[k]*inv[k]; kseedsy[k] = sigmay[k]*inv[k]; }} } return klabels; }
TEST(AggregateTests, SortedSumMaxGroupByTest) { /* * SELECT a, SUM(b), MAX(c) from table GROUP BY a; */ const int tuple_count = TESTS_TUPLES_PER_TILEGROUP; // Create a table and wrap it in logical tiles auto &txn_manager = concurrency::TransactionManager::GetInstance(); auto txn = txn_manager.BeginTransaction(); auto txn_id = txn->GetTransactionId(); std::unique_ptr<storage::DataTable> data_table( ExecutorTestsUtil::CreateTable(tuple_count, false)); ExecutorTestsUtil::PopulateTable(txn, data_table.get(), 2 * tuple_count, false, false, true); txn_manager.CommitTransaction(); std::unique_ptr<executor::LogicalTile> source_logical_tile1( executor::LogicalTileFactory::WrapTileGroup(data_table->GetTileGroup(0), txn_id)); std::unique_ptr<executor::LogicalTile> source_logical_tile2( executor::LogicalTileFactory::WrapTileGroup(data_table->GetTileGroup(1), txn_id)); // (1-5) Setup plan node // 1) Set up group-by columns std::vector<oid_t> group_by_columns = {0}; // 2) Set up project info planner::ProjectInfo::DirectMapList direct_map_list = { {0, {0, 0}}, {1, {1, 0}}, {2, {1, 1}}}; auto proj_info = new planner::ProjectInfo(planner::ProjectInfo::TargetList(), std::move(direct_map_list)); // 3) Set up unique aggregates std::vector<planner::AggregatePlan::AggTerm> agg_terms; planner::AggregatePlan::AggTerm sumb(EXPRESSION_TYPE_AGGREGATE_SUM, expression::TupleValueFactory(0, 1)); planner::AggregatePlan::AggTerm maxc(EXPRESSION_TYPE_AGGREGATE_MAX, expression::TupleValueFactory(0, 2)); agg_terms.push_back(sumb); agg_terms.push_back(maxc); // 4) Set up predicate (empty) expression::AbstractExpression* predicate = nullptr; // 5) Create output table schema auto data_table_schema = data_table.get()->GetSchema(); std::vector<oid_t> set = {0, 1, 2}; std::vector<catalog::Column> columns; for (auto column_index : set) { columns.push_back(data_table_schema->GetColumn(column_index)); } auto output_table_schema = new catalog::Schema(columns); // OK) Create the plan node planner::AggregatePlan node(proj_info, predicate, std::move(agg_terms), std::move(group_by_columns), output_table_schema, AGGREGATE_TYPE_SORTED); // Create and set up executor auto txn2 = txn_manager.BeginTransaction(); std::unique_ptr<executor::ExecutorContext> context( new executor::ExecutorContext(txn2)); executor::AggregateExecutor executor(&node, context.get()); MockExecutor child_executor; executor.AddChild(&child_executor); EXPECT_CALL(child_executor, DInit()).WillOnce(Return(true)); EXPECT_CALL(child_executor, DExecute()) .WillOnce(Return(true)) .WillOnce(Return(true)) .WillOnce(Return(false)); EXPECT_CALL(child_executor, GetOutput()) .WillOnce(Return(source_logical_tile1.release())) .WillOnce(Return(source_logical_tile2.release())); EXPECT_TRUE(executor.Init()); EXPECT_TRUE(executor.Execute()); txn_manager.CommitTransaction(); /* Verify result */ std::unique_ptr<executor::LogicalTile> result_tile(executor.GetOutput()); EXPECT_TRUE(result_tile.get() != nullptr); EXPECT_TRUE(result_tile->GetValue(0, 0) .OpEquals(ValueFactory::GetIntegerValue(0)) .IsTrue()); EXPECT_TRUE(result_tile->GetValue(0, 1) .OpEquals(ValueFactory::GetIntegerValue(105)) .IsTrue()); EXPECT_TRUE(result_tile->GetValue(0, 2) .OpEquals(ValueFactory::GetDoubleValue(42)) .IsTrue()); EXPECT_TRUE(result_tile->GetValue(1, 0) .OpEquals(ValueFactory::GetIntegerValue(10)) .IsTrue()); }
template<typename VectorType> void vectorRedux(const VectorType& w) { typedef typename VectorType::Index Index; typedef typename VectorType::Scalar Scalar; typedef typename NumTraits<Scalar>::Real RealScalar; Index size = w.size(); VectorType v = VectorType::Random(size); VectorType v_for_prod = VectorType::Ones(size) + Scalar(0.2) * v; // see comment above declaration of m1_for_prod for(int i = 1; i < size; i++) { Scalar s(0), p(1); RealScalar minc(internal::real(v.coeff(0))), maxc(internal::real(v.coeff(0))); for(int j = 0; j < i; j++) { s += v[j]; p *= v_for_prod[j]; minc = (std::min)(minc, internal::real(v[j])); maxc = (std::max)(maxc, internal::real(v[j])); } VERIFY_IS_MUCH_SMALLER_THAN(internal::abs(s - v.head(i).sum()), Scalar(1)); VERIFY_IS_APPROX(p, v_for_prod.head(i).prod()); VERIFY_IS_APPROX(minc, v.real().head(i).minCoeff()); VERIFY_IS_APPROX(maxc, v.real().head(i).maxCoeff()); } for(int i = 0; i < size-1; i++) { Scalar s(0), p(1); RealScalar minc(internal::real(v.coeff(i))), maxc(internal::real(v.coeff(i))); for(int j = i; j < size; j++) { s += v[j]; p *= v_for_prod[j]; minc = (std::min)(minc, internal::real(v[j])); maxc = (std::max)(maxc, internal::real(v[j])); } VERIFY_IS_MUCH_SMALLER_THAN(internal::abs(s - v.tail(size-i).sum()), Scalar(1)); VERIFY_IS_APPROX(p, v_for_prod.tail(size-i).prod()); VERIFY_IS_APPROX(minc, v.real().tail(size-i).minCoeff()); VERIFY_IS_APPROX(maxc, v.real().tail(size-i).maxCoeff()); } for(int i = 0; i < size/2; i++) { Scalar s(0), p(1); RealScalar minc(internal::real(v.coeff(i))), maxc(internal::real(v.coeff(i))); for(int j = i; j < size-i; j++) { s += v[j]; p *= v_for_prod[j]; minc = (std::min)(minc, internal::real(v[j])); maxc = (std::max)(maxc, internal::real(v[j])); } VERIFY_IS_MUCH_SMALLER_THAN(internal::abs(s - v.segment(i, size-2*i).sum()), Scalar(1)); VERIFY_IS_APPROX(p, v_for_prod.segment(i, size-2*i).prod()); VERIFY_IS_APPROX(minc, v.real().segment(i, size-2*i).minCoeff()); VERIFY_IS_APPROX(maxc, v.real().segment(i, size-2*i).maxCoeff()); } // test empty objects VERIFY_IS_APPROX(v.head(0).sum(), Scalar(0)); VERIFY_IS_APPROX(v.tail(0).prod(), Scalar(1)); VERIFY_RAISES_ASSERT(v.head(0).mean()); VERIFY_RAISES_ASSERT(v.head(0).minCoeff()); VERIFY_RAISES_ASSERT(v.head(0).maxCoeff()); }