int run(const log4cxx::LoggerPtr &logger, KernelEVD<Scalar> &builder) const { KQP_SCALAR_TYPEDEFS(Scalar); KQP_LOG_INFO_F(logger, "Kernel EVD with dense vectors and builder \"%s\" (pre-images = %d, linear combination = %d)", %KQP_DEMANGLE(builder) %max_preimages %max_lc); ScalarMatrix matrix(n,n); matrix.setConstant(0); // Construction for(int i = 0; i < nb_add; i++) { Scalar alpha = Eigen::internal::abs(Eigen::internal::random_impl<Scalar>::run()) + 1e-3; int k = (int)std::abs(Eigen::internal::random_impl<double>::run() * (double)(max_preimages-min_preimages)) + min_preimages; int p = (int)std::abs(Eigen::internal::random_impl<double>::run() * (double)(max_lc-min_lc)) + min_lc; KQP_LOG_INFO(logger, boost::format("Pre-images (%dx%d) and linear combination (%dx%d)") % n % k % k % p); // Generate a number of pre-images ScalarMatrix m = ScalarMatrix::Random(n, k); // Generate the linear combination matrix ScalarMatrix mA = ScalarMatrix::Random(k, p); matrix.template selfadjointView<Eigen::Lower>().rankUpdate(m * mA, alpha); builder.add(alpha, FMatrixPtr(new Dense<Scalar>(m)), mA); } // Computing via EVD KQP_LOG_INFO(logger, "Computing an LDLT decomposition"); typedef Eigen::LDLT<ScalarMatrix> LDLT; LDLT ldlt = matrix.template selfadjointView<Eigen::Lower>().ldlt(); ScalarMatrix mL = ldlt.matrixL(); mL = ldlt.transpositionsP().transpose() * mL; FMatrixPtr mU(Dense<Scalar>::create(mL)); Eigen::Matrix<Scalar,Dynamic,1> mU_d = ldlt.vectorD(); // Comparing the results KQP_LOG_INFO(logger, "Retrieving the decomposition"); auto kevd = builder.getDecomposition(); ScalarAltMatrix mUY = Eigen::Identity<Scalar>(mL.rows(), mL.rows()); KQP_LOG_DEBUG(logger, "=== Decomposition ==="); // KQP_LOG_DEBUG(logger, "X = " << kevd.mX); KQP_LOG_DEBUG(logger, "Y = " << kevd.mY); KQP_LOG_DEBUG(logger, "D = " << kevd.mD); // Computing the difference between operators || U1 - U2 ||^2 KQP_LOG_INFO(logger, "Comparing the decompositions"); double error = KernelOperators<Scalar>::difference(kevd.fs, kevd.mX, kevd.mY, kevd.mD, mU, mUY, mU_d); KQP_LOG_INFO_F(logger, "Squared error is %e", %error); return error < tolerance ? 0 : 1; }
IGL_INLINE ScalarMatrix igl::embree::line_mesh_intersection ( const ScalarMatrix & V_source, const ScalarMatrix & N_source, const ScalarMatrix & V_target, const IndexMatrix & F_target ) { double tol = 0.00001; Eigen::MatrixXd ray_pos = V_source; Eigen::MatrixXd ray_dir = N_source; // Allocate matrix for the result ScalarMatrix R; R.resize(V_source.rows(), 3); // Initialize embree EmbreeIntersector embree; embree.init(V_target.template cast<float>(),F_target.template cast<int>()); // Shoot rays from the source to the target for (unsigned i=0; i<ray_pos.rows(); ++i) { igl::Hit A,B; // Shoot ray A Eigen::RowVector3d A_pos = ray_pos.row(i) + tol * ray_dir.row(i); Eigen::RowVector3d A_dir = -ray_dir.row(i); bool A_hit = embree.intersectBeam(A_pos.cast<float>(), A_dir.cast<float>(),A); Eigen::RowVector3d B_pos = ray_pos.row(i) - tol * ray_dir.row(i); Eigen::RowVector3d B_dir = ray_dir.row(i); bool B_hit = embree.intersectBeam(B_pos.cast<float>(), B_dir.cast<float>(),B); int choice = -1; if (A_hit && ! B_hit) choice = 0; else if (!A_hit && B_hit) choice = 1; else if (A_hit && B_hit) choice = A.t > B.t; Eigen::RowVector3d temp; if (choice == -1) temp << -1, 0, 0; else if (choice == 0) temp << A.id, A.u, A.v; else if (choice == 1) temp << B.id, B.u, B.v; R.row(i) = temp; } return R; }