///[W, F, errors, times, iters] = NMFSparseKL(V, W0, F0, maxIter, tolerence) void mexFunction(int nlhs, mxArray *outs[], int nrhs, const mxArray *inps[]) { srand (9999); int nz, m, n, k, d1, d2; unsigned long *x, *ind; double *values, **W, **F, **Wr, **Fr; get(inps[0], nz, n, m, x, ind, values); //mexPrintf(" m = %d, n = %d\n", m, n); vector<map<int, double>> V, VT; vector<vector<pair<int, double> > > VV, VVT; convert(nz, m, n, x, ind, values, V); transpose(nz, m, n, x, ind, values, VT); map_vector(V, VV); map_vector(VT, VVT); getArray(inps[1], m, k, W); getArray(inps[2], n, k, F); int maxIter = (int) getDouble(inps[3]); double tolerance = getDouble(inps[4]); int maxThread = (int) getDouble(inps[5]); double **params; getArray(inps[6], d1, d2, params); vector<double> errors, times, iters; printfFnc(" m = %d, n = %d, k = %d\n", m, n, k); printfFnc(" %f %f %f %f\n", (*params)[0], (*params)[1], (*params)[2], (*params)[3]); /// Output arguments outs[0] = mxCreateDoubleMatrix(m, k, mxREAL); outs[1] = mxCreateDoubleMatrix(n, k, mxREAL); outs[2] = mxCreateDoubleMatrix(1, maxIter, mxREAL); double* derrors = mxGetPr(outs[2]); outs[3] = mxCreateDoubleMatrix(1, maxIter, mxREAL); double* dtimes = mxGetPr(outs[3]); outs[4] = mxCreateDoubleMatrix(1, maxIter, mxREAL); double* diters = mxGetPr(outs[4]); getArray(outs[0], m, k, Wr); getArray(outs[1], n, k, Fr); MultipleIterativeAlgorithmPar(VV, VVT, W, F, Wr, Fr, m, n, k, maxIter, tolerance, errors, times, iters, maxThread, *params); For(i, maxIter) derrors[i] = errors[i], dtimes[i] = times[i], diters[i] = iters[i]; }
void CRationalApproximationCGMJob::compute() { SG_DEBUG("Entering\n"); REQUIRE(m_aggregator, "Job result aggregator is not set!\n"); REQUIRE(m_operator, "Operator is not set!\n"); REQUIRE(m_vector.vector, "Vector is not set!\n"); REQUIRE(m_shifts.vector, "Shifts are not set!\n"); REQUIRE(m_weights.vector, "Weights are not set!\n"); REQUIRE(m_operator->get_dimension()==m_vector.vlen, "Dimension mismatch! %d vs %d\n", m_operator->get_dimension(), m_vector.vlen); REQUIRE(m_shifts.vlen==m_weights.vlen, "Number of shifts and weights are not equal!\n"); // solve the linear system with the sample vector SGVector<complex128_t> vec=m_linear_solver->solve_shifted_weighted( m_operator, m_vector, m_shifts, m_weights); // Take negative (see CRationalApproximation for the formula) Map<VectorXcd> v(vec.vector, vec.vlen); v=-v; // take out the imaginary part of the result before // applying linear operator SGVector<float64_t> agg=m_operator->apply(vec.get_imag()); // perform dot product Map<VectorXd> map_agg(agg.vector, agg.vlen); Map<VectorXd> map_vector(m_vector.vector, m_vector.vlen); float64_t result=map_vector.dot(map_agg); result*=m_const_multiplier; // form the final result into a scalar result and submit to the aggregator CScalarResult<float64_t>* final_result=new CScalarResult<float64_t>(result); SG_REF(final_result); m_aggregator->submit_result(final_result); SG_UNREF(final_result); SG_DEBUG("Leaving\n"); }
void pclbo::LBOEstimation<PointT, NormalT>::compute() { typename pcl::KdTreeFLANN<PointT>::Ptr kdt(new pcl::KdTreeFLANN<PointT>()); kdt->setInputCloud(_cloud); const double avg_dist = pclbo::avg_distance<PointT>(10, _cloud, kdt); const double h = 5 * avg_dist; std::cout << "Average distance between points: " << avg_dist << std::endl; int points_with_mass = 0; double avg_mass = 0.0; B.resize(_cloud->size()); std::cout << "Computing the Mass matrix..." << std::flush; // Compute the mass matrix diagonal B for (int i = 0; i < _cloud->size(); i++) { const auto& point = _cloud->at(i); const auto& normal = _normals->at(i); const auto& normal_vector = normal.getNormalVector3fMap().template cast<double>(); if (!pcl::isFinite(point)) continue; std::vector<int> indices; std::vector<float> distances; kdt->radiusSearch(point, h, indices, distances); if (indices.size() < 4) { B[i] = 0.0; continue; } // Project the neighbor points in the tangent plane at p_i with normal n_i std::vector<Eigen::Vector3d> projected_points; for (const auto& neighbor_index : indices) { if (neighbor_index != i) { const auto& neighbor_point = _cloud->at(neighbor_index); projected_points.push_back(project(point, normal, neighbor_point)); } } assert(projected_points.size() >= 3); // Use the first vector to create a 2D basis Eigen::Vector3d u = projected_points[0]; u.normalize(); Eigen::Vector3d v = (u.cross(normal_vector)); v.normalize(); // Add the points to a 2D plane std::vector<Eigen::Vector2d> plane; // Add the point at the center plane.push_back(Eigen::Vector2d::Zero()); // Add the rest of the points for (const auto& projected : projected_points) { double x = projected.dot(u); double y = projected.dot(v); // Add the 2D point to the vector plane.push_back(Eigen::Vector2d(x, y)); } assert(plane.size() >= 4); // Compute the voronoi cell area of the point double area = VoronoiDiagram::area(plane); B[i] = area; avg_mass += area; points_with_mass++; } // Average mass if (points_with_mass > 0) { avg_mass /= static_cast<double>(points_with_mass); } // Set border points to have average mass for (auto& b : B) { if (b == 0.0) { b = avg_mass; } } std::cout << "done" << std::endl; std::cout << "Computing the stiffness matrix..." << std::flush; std::vector<double> diag(_cloud->size(), 0.0); // Compute the stiffness matrix Q for (int i = 0; i < _cloud->size(); i++) { const auto& point = _cloud->at(i); if (!pcl::isFinite(point)) continue; std::vector<int> indices; std::vector<float> distances; kdt->radiusSearch(point, h, indices, distances); for (const auto& j : indices) { if (j != i) { const auto& neighbor = _cloud->at(j); double d = (neighbor.getVector3fMap() - point.getVector3fMap()).norm(); double w = B[i] * B[j] * (1.0 / (4.0 * M_PI * h * h)) * exp(-(d * d) / (4.0 * h)); I.push_back(i); J.push_back(j); S.push_back(w); diag[i] += w; } } } // Fill the diagonal as the negative sum of the rows for (int i = 0; i < diag.size(); i++) { I.push_back(i); J.push_back(i); S.push_back(-diag[i]); } // Compute the B^{-1}Q matrix Eigen::MatrixXd Q = Eigen::MatrixXd::Zero(_cloud->size(), _cloud->size()); for (int i = 0; i < I.size(); i++) { const int row = I[i]; const int col = J[i]; Q(row, col) = S[i]; } std::cout << "done" << std::endl; std::cout << "Computing eigenvectors" << std::endl; Eigen::Map<Eigen::VectorXd> B_vec(B.data(), B.size()); Eigen::GeneralizedSelfAdjointEigenSolver<Eigen::MatrixXd> ges; ges.compute(Q, B_vec.asDiagonal()); eigenvalues = ges.eigenvalues(); eigenfunctions = ges.eigenvectors(); // Sort the eigenvalues by magnitude std::vector<std::pair<double, int> > map_vector(eigenvalues.size()); for (auto i = 0; i < eigenvalues.size(); i++) { map_vector[i].first = std::abs(eigenvalues(i)); map_vector[i].second = i; } std::sort(map_vector.begin(), map_vector.end()); // truncate the first 100 eigenfunctions Eigen::MatrixXd eigenvectors(eigenfunctions.rows(), eigenfunctions.cols()); Eigen::VectorXd eigenvals(eigenfunctions.cols()); eigenvalues.resize(map_vector.size()); for (auto i = 0; i < map_vector.size(); i++) { const auto& pair = map_vector[i]; eigenvectors.col(i) = eigenfunctions.col(pair.second); eigenvals(i) = pair.first; } eigenfunctions = eigenvectors; eigenvalues = eigenvals; }