void AdaptiveManifoldFilterN::computeEigenVector(const vector<Mat>& X, const Mat1b& mask, Mat1f& vecDst, int num_pca_iterations, const Mat1f& vecRand) { int cnNum = (int)X.size(); int height = X[0].rows; int width = X[0].cols; vecDst.create(1, cnNum); CV_Assert(vecRand.size() == Size(cnNum, 1) && vecDst.size() == Size(cnNum, 1)); CV_Assert(mask.rows == height && mask.cols == width); const float *pVecRand = vecRand.ptr<float>(); Mat1d vecDstd(1, cnNum, 0.0); double *pVecDst = vecDstd.ptr<double>(); Mat1f Xw(height, width); for (int iter = 0; iter < num_pca_iterations; iter++) { for (int i = 0; i < height; i++) { const uchar *maskRow = mask.ptr<uchar>(i); float *mulRow = Xw.ptr<float>(i); //first multiplication for (int cn = 0; cn < cnNum; cn++) { const float *srcRow = X[cn].ptr<float>(i); const float cnVal = pVecRand[cn]; if (cn == 0) { for (int j = 0; j < width; j++) mulRow[j] = cnVal*srcRow[j]; } else { for (int j = 0; j < width; j++) mulRow[j] += cnVal*srcRow[j]; } } for (int j = 0; j < width; j++) if (!maskRow[j]) mulRow[j] = 0.0f; //second multiplication for (int cn = 0; cn < cnNum; cn++) { float curCnSum = 0.0f; const float *srcRow = X[cn].ptr<float>(i); for (int j = 0; j < width; j++) curCnSum += mulRow[j]*srcRow[j]; //TODO: parallel reduce pVecDst[cn] += curCnSum; } } } divide(vecDstd, norm(vecDstd), vecDst); }
void python_to_delaunay_2(const MatrixXd& X, const VectorXd& w, RT &dt) { size_t N = X.rows(); assert(X.cols() == 2); assert(w.cols() == 1); assert(w.rows() == N); // insert points with indices in the regular triangulation std::vector<std::pair<Weighted_point,size_t> > Xw(N); for (size_t i = 0; i < N; ++i) { Xw[i] = std::make_pair(Weighted_point(Point(X(i,0), X(i,1)), w(i)), i); } dt.clear(); dt.insert(Xw.begin(), Xw.end()); dt.infinite_vertex()->info() = -1; }
double kantorovich (const T &densityT, const Functions &densityF, const Matrix &X, const Vector &weights, Vector &g, SparseMatrix &h) { typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef CGAL::Polygon_2<K> Polygon; typedef K::FT FT; typedef CGAL::Regular_triangulation_filtered_traits_2<K> RT_Traits; typedef CGAL::Regular_triangulation_vertex_base_2<RT_Traits> Vbase; typedef CGAL::Triangulation_vertex_base_with_info_2 <size_t, RT_Traits, Vbase> Vb; typedef CGAL::Regular_triangulation_face_base_2<RT_Traits> Cb; typedef CGAL::Triangulation_data_structure_2<Vb,Cb> Tds; typedef CGAL::Regular_triangulation_2<RT_Traits, Tds> RT; typedef RT::Vertex_handle Vertex_handle_RT; typedef RT::Weighted_point Weighted_point; typedef typename CGAL::Point_2<K> Point; size_t N = X.rows(); assert(weights.rows() == N); assert(weights.cols() == 1); assert(X.cols() == 2); // insert points with indices in the regular triangulation std::vector<std::pair<Weighted_point,size_t> > Xw(N); for (size_t i = 0; i < N; ++i) { Xw[i] = std::make_pair(Weighted_point(Point(X(i,0), X(i,1)), weights(i)), i); } RT dt (Xw.begin(), Xw.end()); dt.infinite_vertex()->info() = -1; // compute the quadratic part typedef MA::Voronoi_intersection_traits<K> Traits; typedef typename MA::Tri_intersector<T,RT,Traits> Tri_isector; typedef typename Tri_isector::Pgon Pgon; typedef Eigen::Triplet<FT> Triplet; std::vector<Triplet> htri; FT total(0), fval(0), total_area(0); g = Vector::Zero(N); MA::voronoi_triangulation_intersection_raw (densityT,dt, [&] (const Pgon &pgon, typename T::Face_handle f, Vertex_handle_RT v) { Tri_isector isector; Polygon p; std::vector<Vertex_handle_RT> adj; for (size_t i = 0; i < pgon.size(); ++i) { size_t ii = (i==0)?(pgon.size()-1):(i-1); //size_t ii = (i+1)%pgon.size(); p.push_back(isector.vertex_to_point(pgon[i], pgon[ii])); adj.push_back((pgon[i].type == Tri_isector::EDGE_DT) ? pgon[i].edge_dt.second : 0); } size_t idv = v->info(); auto fit = densityF.find(f); assert(fit != densityF.end()); auto fv = fit->second; // function to integrate // compute hessian for (size_t i = 0; i < p.size(); ++i) { if (adj[i] == 0) continue; Vertex_handle_RT w = adj[i]; size_t idw = w->info(); FT r = MA::integrate_1<FT>(p.edge(i), fv); FT d = 2*sqrt(CGAL::squared_distance(v->point(), w->point())); htri.push_back(Triplet(idv, idw, -r/d)); htri.push_back(Triplet(idv, idv, +r/d)); } // compute value and gradient FT warea = MA::integrate_1<FT>(p, FT(0), fv); FT intg = MA::integrate_3<FT>(p, FT(0), [&](Point p) { return fv(p) * CGAL::squared_distance(p, v->point()); }); fval = fval + warea * weights[idv] - intg; g[idv] = g[idv] + warea; total += warea; total_area += p.area(); }); h = SparseMatrix(N,N); h.setFromTriplets(htri.begin(), htri.end()); h.makeCompressed(); return fval; }