double MCLR_SM::logit_g(double alpha,vnl_matrix<double> data_with_bias) { double gVal = 0; vnl_matrix<double> w_temp; w_temp = m.w + direction * alpha; vnl_matrix<double> f; f = Get_F_Matrix(data_with_bias,w_temp); vnl_vector<double> denominator(f.cols(),0); vnl_vector<double> f_vec(f.cols(),0); // Get the denominator for(int i=0;i<f.cols();++i) { vnl_vector<double> temp_col = f.get_column(i); denominator(i) = temp_col.sum(); } for(int i=0;i<f.cols();++i) { vnl_vector<double> temp_col = f.get_column(i); f_vec(i) = temp_col(y(i)-1)/denominator(i); if(f_vec(i)==0) f_vec(i) = 1e-9; } // Objective function value for(int i=0;i<f_vec.size();++i) { gVal = gVal+log(f_vec(i)); } //std::cout<<m.w(0,0)<<" --- " << m.w(0,1)<<"---"<< m.w(0,2)<<std::endl; //std::cout<<m.w(38,0) <<" --- " << m.w(38,1) <<"---"<< m.w(38,2) <<std::endl; //g = g - C*sum(sum(sqrt(w.^2+delta))); % consider the sparseness penalty double diff_term =0; for(int i=0;i<no_of_features+1;++i) { for(int j=0;j<no_of_classes;++j) { diff_term += sqrt(w_temp(i,j)*w_temp(i,j)+delta); } } diff_term = diff_term * m.sparsity_control; gVal = diff_term-gVal; return gVal; }
var GroebnerBasis(Kernel& k,const Tuple& f_){ uint n=f_.size-1; std::vector<var> f_vec(f_.tuple+1,f_.tuple+f_.size); for(uint i=n-1;i+1>0;i--){ if(!isExact(f_vec[i])){ wcerr<<"all polynomials must be Exact\n"; return $.Fail; } if(isNumber(f_vec[i])){ if(!cmpD(f_vec[i].object(), 0.0))//is zero f_vec.erase(f_vec.begin()+i); else return list(new Integer(1L)); } }
template <typename PointInT, typename PointOutT> void pcl::MovingLeastSquares<PointInT, PointOutT>::computeMLSPointNormal (int index, const PointCloudIn &input, const std::vector<int> &nn_indices, std::vector<float> &nn_sqr_dists, PointCloudOut &projected_points, NormalCloud &projected_points_normals) { // Compute the plane coefficients //pcl::computePointNormal<PointInT> (*input_, nn_indices, model_coefficients, curvature); EIGEN_ALIGN16 Eigen::Matrix3f covariance_matrix; Eigen::Vector4f xyz_centroid; // Estimate the XYZ centroid pcl::compute3DCentroid (input, nn_indices, xyz_centroid); //pcl::compute3DCentroid (input, nn_indices, xyz_centroid); pcl::computeCovarianceMatrix (input, nn_indices, xyz_centroid, covariance_matrix); // Compute the 3x3 covariance matrix EIGEN_ALIGN16 Eigen::Vector3f::Scalar eigen_value; EIGEN_ALIGN16 Eigen::Vector3f eigen_vector; Eigen::Vector4f model_coefficients; pcl::eigen33 (covariance_matrix, eigen_value, eigen_vector); model_coefficients.head<3> () = eigen_vector; model_coefficients[3] = 0; model_coefficients[3] = -1 * model_coefficients.dot (xyz_centroid); // Projected query point Eigen::Vector3f point = input[(*indices_)[index]].getVector3fMap (); float distance = point.dot (model_coefficients.head<3> ()) + model_coefficients[3]; point -= distance * model_coefficients.head<3> (); float curvature = covariance_matrix.trace (); // Compute the curvature surface change if (curvature != 0) curvature = fabsf (eigen_value / curvature); // Get a copy of the plane normal easy access Eigen::Vector3d plane_normal = model_coefficients.head<3> ().cast<double> (); // Vector in which the polynomial coefficients will be put Eigen::VectorXd c_vec; // Local coordinate system (Darboux frame) Eigen::Vector3d v (0.0f, 0.0f, 0.0f), u (0.0f, 0.0f, 0.0f); // Perform polynomial fit to update point and normal //////////////////////////////////////////////////// if (polynomial_fit_ && static_cast<int> (nn_indices.size ()) >= nr_coeff_) { // Update neighborhood, since point was projected, and computing relative // positions. Note updating only distances for the weights for speed std::vector<Eigen::Vector3d> de_meaned (nn_indices.size ()); for (size_t ni = 0; ni < nn_indices.size (); ++ni) { de_meaned[ni][0] = input_->points[nn_indices[ni]].x - point[0]; de_meaned[ni][1] = input_->points[nn_indices[ni]].y - point[1]; de_meaned[ni][2] = input_->points[nn_indices[ni]].z - point[2]; nn_sqr_dists[ni] = static_cast<float> (de_meaned[ni].dot (de_meaned[ni])); } // Allocate matrices and vectors to hold the data used for the polynomial fit Eigen::VectorXd weight_vec (nn_indices.size ()); Eigen::MatrixXd P (nr_coeff_, nn_indices.size ()); Eigen::VectorXd f_vec (nn_indices.size ()); Eigen::MatrixXd P_weight; // size will be (nr_coeff_, nn_indices.size ()); Eigen::MatrixXd P_weight_Pt (nr_coeff_, nr_coeff_); // Get local coordinate system (Darboux frame) v = plane_normal.unitOrthogonal (); u = plane_normal.cross (v); // Go through neighbors, transform them in the local coordinate system, // save height and the evaluation of the polynome's terms double u_coord, v_coord, u_pow, v_pow; for (size_t ni = 0; ni < nn_indices.size (); ++ni) { // (re-)compute weights weight_vec (ni) = exp (-nn_sqr_dists[ni] / sqr_gauss_param_); // transforming coordinates u_coord = de_meaned[ni].dot (u); v_coord = de_meaned[ni].dot (v); f_vec (ni) = de_meaned[ni].dot (plane_normal); // compute the polynomial's terms at the current point int j = 0; u_pow = 1; for (int ui = 0; ui <= order_; ++ui) { v_pow = 1; for (int vi = 0; vi <= order_ - ui; ++vi) { P (j++, ni) = u_pow * v_pow; v_pow *= v_coord; } u_pow *= u_coord; } } // Computing coefficients P_weight = P * weight_vec.asDiagonal (); P_weight_Pt = P_weight * P.transpose (); c_vec = P_weight * f_vec; P_weight_Pt.llt ().solveInPlace (c_vec); } switch (upsample_method_) { case (NONE): { Eigen::Vector3d normal = plane_normal; if (polynomial_fit_ && static_cast<int> (nn_indices.size ()) >= nr_coeff_ && pcl_isfinite (c_vec[0])) { point += (c_vec[0] * plane_normal).cast<float> (); // Compute tangent vectors using the partial derivates evaluated at (0,0) which is c_vec[order_+1] and c_vec[1] if (compute_normals_) normal = plane_normal - c_vec[order_ + 1] * u - c_vec[1] * v; } PointOutT aux; aux.x = point[0]; aux.y = point[1]; aux.z = point[2]; projected_points.push_back (aux); if (compute_normals_) { pcl::Normal aux_normal; aux_normal.normal_x = static_cast<float> (normal[0]); aux_normal.normal_y = static_cast<float> (normal[1]); aux_normal.normal_z = static_cast<float> (normal[2]); aux_normal.curvature = curvature; projected_points_normals.push_back (aux_normal); } break; } case (SAMPLE_LOCAL_PLANE): { // Uniformly sample a circle around the query point using the radius and step parameters for (float u_disp = -static_cast<float> (upsampling_radius_); u_disp <= upsampling_radius_; u_disp += static_cast<float> (upsampling_step_)) for (float v_disp = -static_cast<float> (upsampling_radius_); v_disp <= upsampling_radius_; v_disp += static_cast<float> (upsampling_step_)) if (u_disp*u_disp + v_disp*v_disp < upsampling_radius_*upsampling_radius_) { PointOutT projected_point; pcl::Normal projected_normal; projectPointToMLSSurface (u_disp, v_disp, u, v, plane_normal, curvature, point, c_vec, static_cast<int> (nn_indices.size ()), projected_point, projected_normal); projected_points.push_back (projected_point); if (compute_normals_) projected_points_normals.push_back (projected_normal); } break; } case (RANDOM_UNIFORM_DENSITY): { // Compute the local point density and add more samples if necessary int num_points_to_add = static_cast<int> (floor (desired_num_points_in_radius_ / 2.0 / static_cast<double> (nn_indices.size ()))); // Just add the query point, because the density is good if (num_points_to_add <= 0) { // Just add the current point Eigen::Vector3d normal = plane_normal; if (polynomial_fit_ && static_cast<int> (nn_indices.size ()) >= nr_coeff_ && pcl_isfinite (c_vec[0])) { // Projection onto MLS surface along Darboux normal to the height at (0,0) point += (c_vec[0] * plane_normal).cast<float> (); // Compute tangent vectors using the partial derivates evaluated at (0,0) which is c_vec[order_+1] and c_vec[1] if (compute_normals_) normal = plane_normal - c_vec[order_ + 1] * u - c_vec[1] * v; } PointOutT aux; aux.x = point[0]; aux.y = point[1]; aux.z = point[2]; projected_points.push_back (aux); if (compute_normals_) { pcl::Normal aux_normal; aux_normal.normal_x = static_cast<float> (normal[0]); aux_normal.normal_y = static_cast<float> (normal[1]); aux_normal.normal_z = static_cast<float> (normal[2]); aux_normal.curvature = curvature; projected_points_normals.push_back (aux_normal); } } else { // Sample the local plane for (int num_added = 0; num_added < num_points_to_add;) { float u_disp = (*rng_uniform_distribution_) (), v_disp = (*rng_uniform_distribution_) (); // Check if inside circle; if not, try another coin flip if (u_disp * u_disp + v_disp * v_disp > search_radius_ * search_radius_/4) continue; PointOutT projected_point; pcl::Normal projected_normal; projectPointToMLSSurface (u_disp, v_disp, u, v, plane_normal, curvature, point, c_vec, static_cast<int> (nn_indices.size ()), projected_point, projected_normal); projected_points.push_back (projected_point); if (compute_normals_) projected_points_normals.push_back (projected_normal); num_added ++; } } break; } case (VOXEL_GRID_DILATION): { // Take all point pairs and sample space between them in a grid-fashion // \note consider only point pairs with increasing indices MLSResult result (plane_normal, u, v, c_vec, static_cast<int> (nn_indices.size ()), curvature); mls_results_[index] = result; break; } } }
/******************************************************************************* * For each run, the input filename must be given on the command line. In all * * cases, the command line is: * * * * executable <input file name> * * * *******************************************************************************/ int main(int argc, char* argv[]) { // Initialize PETSc, MPI, and SAMRAI. PetscInitialize(&argc, &argv, NULL, NULL); SAMRAI_MPI::setCommunicator(PETSC_COMM_WORLD); SAMRAI_MPI::setCallAbortInSerialInsteadOfExit(); SAMRAIManager::startup(); { // cleanup dynamically allocated objects prior to shutdown // Parse command line options, set some standard options from the input // file, and enable file logging. Pointer<AppInitializer> app_initializer = new AppInitializer(argc, argv, "sc_poisson.log"); Pointer<Database> input_db = app_initializer->getInputDatabase(); // Create major algorithm and data objects that comprise the // application. These objects are configured from the input database. Pointer<CartesianGridGeometry<NDIM> > grid_geometry = new CartesianGridGeometry<NDIM>( "CartesianGeometry", app_initializer->getComponentDatabase("CartesianGeometry")); Pointer<PatchHierarchy<NDIM> > patch_hierarchy = new PatchHierarchy<NDIM>("PatchHierarchy", grid_geometry); Pointer<StandardTagAndInitialize<NDIM> > error_detector = new StandardTagAndInitialize<NDIM>( "StandardTagAndInitialize", NULL, app_initializer->getComponentDatabase("StandardTagAndInitialize")); Pointer<BergerRigoutsos<NDIM> > box_generator = new BergerRigoutsos<NDIM>(); Pointer<LoadBalancer<NDIM> > load_balancer = new LoadBalancer<NDIM>("LoadBalancer", app_initializer->getComponentDatabase("LoadBalancer")); Pointer<GriddingAlgorithm<NDIM> > gridding_algorithm = new GriddingAlgorithm<NDIM>("GriddingAlgorithm", app_initializer->getComponentDatabase("GriddingAlgorithm"), error_detector, box_generator, load_balancer); // Create variables and register them with the variable database. VariableDatabase<NDIM>* var_db = VariableDatabase<NDIM>::getDatabase(); Pointer<VariableContext> ctx = var_db->getContext("context"); Pointer<SideVariable<NDIM, double> > u_sc_var = new SideVariable<NDIM, double>("u_sc"); Pointer<SideVariable<NDIM, double> > f_sc_var = new SideVariable<NDIM, double>("f_sc"); Pointer<SideVariable<NDIM, double> > e_sc_var = new SideVariable<NDIM, double>("e_sc"); Pointer<SideVariable<NDIM, double> > r_sc_var = new SideVariable<NDIM, double>("r_sc"); const int u_sc_idx = var_db->registerVariableAndContext(u_sc_var, ctx, IntVector<NDIM>(1)); const int f_sc_idx = var_db->registerVariableAndContext(f_sc_var, ctx, IntVector<NDIM>(1)); const int e_sc_idx = var_db->registerVariableAndContext(e_sc_var, ctx, IntVector<NDIM>(1)); const int r_sc_idx = var_db->registerVariableAndContext(r_sc_var, ctx, IntVector<NDIM>(1)); Pointer<CellVariable<NDIM, double> > u_cc_var = new CellVariable<NDIM, double>("u_cc", NDIM); Pointer<CellVariable<NDIM, double> > f_cc_var = new CellVariable<NDIM, double>("f_cc", NDIM); Pointer<CellVariable<NDIM, double> > e_cc_var = new CellVariable<NDIM, double>("e_cc", NDIM); Pointer<CellVariable<NDIM, double> > r_cc_var = new CellVariable<NDIM, double>("r_cc", NDIM); const int u_cc_idx = var_db->registerVariableAndContext(u_cc_var, ctx, IntVector<NDIM>(0)); const int f_cc_idx = var_db->registerVariableAndContext(f_cc_var, ctx, IntVector<NDIM>(0)); const int e_cc_idx = var_db->registerVariableAndContext(e_cc_var, ctx, IntVector<NDIM>(0)); const int r_cc_idx = var_db->registerVariableAndContext(r_cc_var, ctx, IntVector<NDIM>(0)); // Register variables for plotting. Pointer<VisItDataWriter<NDIM> > visit_data_writer = app_initializer->getVisItDataWriter(); TBOX_ASSERT(visit_data_writer); visit_data_writer->registerPlotQuantity(u_cc_var->getName(), "VECTOR", u_cc_idx); for (unsigned int d = 0; d < NDIM; ++d) { ostringstream stream; stream << d; visit_data_writer->registerPlotQuantity(u_cc_var->getName() + stream.str(), "SCALAR", u_cc_idx, d); } visit_data_writer->registerPlotQuantity(f_cc_var->getName(), "VECTOR", f_cc_idx); for (unsigned int d = 0; d < NDIM; ++d) { ostringstream stream; stream << d; visit_data_writer->registerPlotQuantity(f_cc_var->getName() + stream.str(), "SCALAR", f_cc_idx, d); } visit_data_writer->registerPlotQuantity(e_cc_var->getName(), "VECTOR", e_cc_idx); for (unsigned int d = 0; d < NDIM; ++d) { ostringstream stream; stream << d; visit_data_writer->registerPlotQuantity(e_cc_var->getName() + stream.str(), "SCALAR", e_cc_idx, d); } visit_data_writer->registerPlotQuantity(r_cc_var->getName(), "VECTOR", r_cc_idx); for (unsigned int d = 0; d < NDIM; ++d) { ostringstream stream; stream << d; visit_data_writer->registerPlotQuantity(r_cc_var->getName() + stream.str(), "SCALAR", r_cc_idx, d); } // Initialize the AMR patch hierarchy. gridding_algorithm->makeCoarsestLevel(patch_hierarchy, 0.0); int tag_buffer = 1; int level_number = 0; bool done = false; while (!done && (gridding_algorithm->levelCanBeRefined(level_number))) { gridding_algorithm->makeFinerLevel(patch_hierarchy, 0.0, 0.0, tag_buffer); done = !patch_hierarchy->finerLevelExists(level_number); ++level_number; } // Allocate data on each level of the patch hierarchy. for (int ln = 0; ln <= patch_hierarchy->getFinestLevelNumber(); ++ln) { Pointer<PatchLevel<NDIM> > level = patch_hierarchy->getPatchLevel(ln); level->allocatePatchData(u_sc_idx, 0.0); level->allocatePatchData(f_sc_idx, 0.0); level->allocatePatchData(e_sc_idx, 0.0); level->allocatePatchData(r_sc_idx, 0.0); level->allocatePatchData(u_cc_idx, 0.0); level->allocatePatchData(f_cc_idx, 0.0); level->allocatePatchData(e_cc_idx, 0.0); level->allocatePatchData(r_cc_idx, 0.0); } // Setup vector objects. HierarchyMathOps hier_math_ops("hier_math_ops", patch_hierarchy); const int h_sc_idx = hier_math_ops.getSideWeightPatchDescriptorIndex(); SAMRAIVectorReal<NDIM, double> u_vec("u", patch_hierarchy, 0, patch_hierarchy->getFinestLevelNumber()); SAMRAIVectorReal<NDIM, double> f_vec("f", patch_hierarchy, 0, patch_hierarchy->getFinestLevelNumber()); SAMRAIVectorReal<NDIM, double> e_vec("e", patch_hierarchy, 0, patch_hierarchy->getFinestLevelNumber()); SAMRAIVectorReal<NDIM, double> r_vec("r", patch_hierarchy, 0, patch_hierarchy->getFinestLevelNumber()); u_vec.addComponent(u_sc_var, u_sc_idx, h_sc_idx); f_vec.addComponent(f_sc_var, f_sc_idx, h_sc_idx); e_vec.addComponent(e_sc_var, e_sc_idx, h_sc_idx); r_vec.addComponent(r_sc_var, r_sc_idx, h_sc_idx); u_vec.setToScalar(0.0); f_vec.setToScalar(0.0); e_vec.setToScalar(0.0); r_vec.setToScalar(0.0); // Setup exact solutions. muParserCartGridFunction u_fcn("u", app_initializer->getComponentDatabase("u"), grid_geometry); muParserCartGridFunction f_fcn("f", app_initializer->getComponentDatabase("f"), grid_geometry); u_fcn.setDataOnPatchHierarchy(e_sc_idx, e_sc_var, patch_hierarchy, 0.0); f_fcn.setDataOnPatchHierarchy(f_sc_idx, f_sc_var, patch_hierarchy, 0.0); // Setup the Poisson solver. PoissonSpecifications poisson_spec("poisson_spec"); poisson_spec.setCConstant(0.0); poisson_spec.setDConstant(-1.0); vector<RobinBcCoefStrategy<NDIM>*> bc_coefs(NDIM, static_cast<RobinBcCoefStrategy<NDIM>*>(NULL)); SCLaplaceOperator laplace_op("laplace_op"); laplace_op.setPoissonSpecifications(poisson_spec); laplace_op.setPhysicalBcCoefs(bc_coefs); laplace_op.initializeOperatorState(u_vec, f_vec); string solver_type = input_db->getString("solver_type"); Pointer<Database> solver_db = input_db->getDatabase("solver_db"); string precond_type = input_db->getString("precond_type"); Pointer<Database> precond_db = input_db->getDatabase("precond_db"); Pointer<PoissonSolver> poisson_solver = SCPoissonSolverManager::getManager()->allocateSolver( solver_type, "poisson_solver", solver_db, "", precond_type, "poisson_precond", precond_db, ""); poisson_solver->setPoissonSpecifications(poisson_spec); poisson_solver->setPhysicalBcCoefs(bc_coefs); poisson_solver->initializeSolverState(u_vec, f_vec); // Solve -L*u = f. u_vec.setToScalar(0.0); poisson_solver->solveSystem(u_vec, f_vec); // Compute error and print error norms. e_vec.subtract(Pointer<SAMRAIVectorReal<NDIM, double> >(&e_vec, false), Pointer<SAMRAIVectorReal<NDIM, double> >(&u_vec, false)); pout << "|e|_oo = " << e_vec.maxNorm() << "\n"; pout << "|e|_2 = " << e_vec.L2Norm() << "\n"; pout << "|e|_1 = " << e_vec.L1Norm() << "\n"; // Compute the residual and print residual norms. laplace_op.apply(u_vec, r_vec); r_vec.subtract(Pointer<SAMRAIVectorReal<NDIM, double> >(&f_vec, false), Pointer<SAMRAIVectorReal<NDIM, double> >(&r_vec, false)); pout << "|r|_oo = " << r_vec.maxNorm() << "\n"; pout << "|r|_2 = " << r_vec.L2Norm() << "\n"; pout << "|r|_1 = " << r_vec.L1Norm() << "\n"; // Interpolate the side-centered data to cell centers for output. static const bool synch_cf_interface = true; hier_math_ops.interp(u_cc_idx, u_cc_var, u_sc_idx, u_sc_var, NULL, 0.0, synch_cf_interface); hier_math_ops.interp(f_cc_idx, f_cc_var, f_sc_idx, f_sc_var, NULL, 0.0, synch_cf_interface); hier_math_ops.interp(e_cc_idx, e_cc_var, e_sc_idx, e_sc_var, NULL, 0.0, synch_cf_interface); hier_math_ops.interp(r_cc_idx, r_cc_var, r_sc_idx, r_sc_var, NULL, 0.0, synch_cf_interface); // Set invalid values on coarse levels (i.e., coarse-grid values that // are covered by finer grid patches) to equal zero. for (int ln = 0; ln <= patch_hierarchy->getFinestLevelNumber() - 1; ++ln) { Pointer<PatchLevel<NDIM> > level = patch_hierarchy->getPatchLevel(ln); BoxArray<NDIM> refined_region_boxes; Pointer<PatchLevel<NDIM> > next_finer_level = patch_hierarchy->getPatchLevel(ln + 1); refined_region_boxes = next_finer_level->getBoxes(); refined_region_boxes.coarsen(next_finer_level->getRatioToCoarserLevel()); for (PatchLevel<NDIM>::Iterator p(level); p; p++) { Pointer<Patch<NDIM> > patch = level->getPatch(p()); const Box<NDIM>& patch_box = patch->getBox(); Pointer<CellData<NDIM, double> > e_cc_data = patch->getPatchData(e_cc_idx); Pointer<CellData<NDIM, double> > r_cc_data = patch->getPatchData(r_cc_idx); for (int i = 0; i < refined_region_boxes.getNumberOfBoxes(); ++i) { const Box<NDIM> refined_box = refined_region_boxes[i]; const Box<NDIM> intersection = Box<NDIM>::grow(patch_box, 1) * refined_box; if (!intersection.empty()) { e_cc_data->fillAll(0.0, intersection); r_cc_data->fillAll(0.0, intersection); } } } } // Output data for plotting. visit_data_writer->writePlotData(patch_hierarchy, 0, 0.0); } // cleanup dynamically allocated objects prior to shutdown SAMRAIManager::shutdown(); PetscFinalize(); return 0; } // main
/******************************************************************************* * For each run, the input filename must be given on the command line. In all * * cases, the command line is: * * * * executable <input file name> * * * *******************************************************************************/ bool run_example(int argc, char* argv[]) { // Initialize PETSc, MPI, and SAMRAI. PetscInitialize(&argc, &argv, NULL, NULL); SAMRAI_MPI::setCommunicator(PETSC_COMM_WORLD); SAMRAI_MPI::setCallAbortInSerialInsteadOfExit(); SAMRAIManager::startup(); // Since SAMRAI and PETSc both require finalization routines we have to // ensure that no SAMRAI or PETSc objects are active at the point where we // call SAMRAIManager::shutdown() or PetscFinalize. Hence, to guarantee // that all objects are cleaned up by that point, we put everything we use // in an inner scope. { // Parse command line options, set some standard options from the input // file, and enable file logging. Pointer<AppInitializer> app_initializer = new AppInitializer(argc, argv, "cc_laplace.log"); Pointer<Database> input_db = app_initializer->getInputDatabase(); // Create major algorithm and data objects that comprise the // application. These objects are configured from the input // database. Nearly all SAMRAI applications (at least those in IBAMR) // start by setting up the same half-dozen objects. Pointer<CartesianGridGeometry<NDIM> > grid_geometry = new CartesianGridGeometry<NDIM>( "CartesianGeometry", app_initializer->getComponentDatabase("CartesianGeometry")); Pointer<PatchHierarchy<NDIM> > patch_hierarchy = new PatchHierarchy<NDIM>("PatchHierarchy", grid_geometry); Pointer<StandardTagAndInitialize<NDIM> > error_detector = new StandardTagAndInitialize<NDIM>( "StandardTagAndInitialize", NULL, app_initializer->getComponentDatabase("StandardTagAndInitialize")); Pointer<BergerRigoutsos<NDIM> > box_generator = new BergerRigoutsos<NDIM>(); Pointer<LoadBalancer<NDIM> > load_balancer = new LoadBalancer<NDIM>("LoadBalancer", app_initializer->getComponentDatabase("LoadBalancer")); Pointer<GriddingAlgorithm<NDIM> > gridding_algorithm = new GriddingAlgorithm<NDIM>("GriddingAlgorithm", app_initializer->getComponentDatabase("GriddingAlgorithm"), error_detector, box_generator, load_balancer); // Create variables and register them with the variable database. VariableDatabase<NDIM>* var_db = VariableDatabase<NDIM>::getDatabase(); Pointer<VariableContext> ctx = var_db->getContext("context"); // We create a variable for every vector we ultimately declare, // instead of creating and then cloning vectors. The rationale for // this is given below. Pointer<CellVariable<NDIM, double> > u_cc_var = new CellVariable<NDIM, double>("u_cc"); Pointer<CellVariable<NDIM, double> > f_cc_var = new CellVariable<NDIM, double>("f_cc"); Pointer<CellVariable<NDIM, double> > e_cc_var = new CellVariable<NDIM, double>("e_cc"); Pointer<CellVariable<NDIM, double> > f_approx_cc_var = new CellVariable<NDIM, double>("f_approx_cc"); // Internally, SAMRAI keeps track of variables (and their // corresponding vectors, data, etc.) by converting them to // indices. Here we get the indices after notifying the variable // database about them. const int u_cc_idx = var_db->registerVariableAndContext(u_cc_var, ctx, IntVector<NDIM>(1)); const int f_cc_idx = var_db->registerVariableAndContext(f_cc_var, ctx, IntVector<NDIM>(1)); const int e_cc_idx = var_db->registerVariableAndContext(e_cc_var, ctx, IntVector<NDIM>(1)); const int f_approx_cc_idx = var_db->registerVariableAndContext(f_approx_cc_var, ctx, IntVector<NDIM>(1)); // Register variables for plotting. Pointer<VisItDataWriter<NDIM> > visit_data_writer = app_initializer->getVisItDataWriter(); TBOX_ASSERT(visit_data_writer); visit_data_writer->registerPlotQuantity(u_cc_var->getName(), "SCALAR", u_cc_idx); visit_data_writer->registerPlotQuantity(f_cc_var->getName(), "SCALAR", f_cc_idx); visit_data_writer->registerPlotQuantity(f_approx_cc_var->getName(), "SCALAR", f_approx_cc_idx); visit_data_writer->registerPlotQuantity(e_cc_var->getName(), "SCALAR", e_cc_idx); // Initialize the AMR patch hierarchy. This sets up the coarsest level // (level 0) as well as any other levels specified in the input // file. We normally use the value tag_buffer to specify the number of // cells between a patch on level N and a patch on level N - 2: // however, SAMRAI ignores this value when setting up a hierarchy from // an input file so we just set it to an invalid value. gridding_algorithm->makeCoarsestLevel(patch_hierarchy, 0.0); const int tag_buffer = std::numeric_limits<int>::max(); int level_number = 0; while ((gridding_algorithm->levelCanBeRefined(level_number))) { gridding_algorithm->makeFinerLevel(patch_hierarchy, 0.0, 0.0, tag_buffer); ++level_number; } const int finest_level = patch_hierarchy->getFinestLevelNumber(); // Allocate data for each variable on each level of the patch // hierarchy. for (int ln = 0; ln <= finest_level; ++ln) { Pointer<PatchLevel<NDIM> > level = patch_hierarchy->getPatchLevel(ln); level->allocatePatchData(u_cc_idx, 0.0); level->allocatePatchData(f_cc_idx, 0.0); level->allocatePatchData(e_cc_idx, 0.0); level->allocatePatchData(f_approx_cc_idx, 0.0); } // By default, the norms defined on SAMRAI vectors are vectors in R^n: // however, in IBAMR we almost always want to use a norm that // corresponds to a numerical quadrature. To do this we have to // associate each vector with a set of cell-centered volumes. Rather // than set this up manually, we rely on an IBTK utility class that // computes this (as well as many other things!). These values are // known as `cell weights' in this context, so we get the ID of the // associated data by asking for that. Behind the scenes // HierarchyMathOps sets up the necessary cell-centered variables and // registers them with the usual SAMRAI objects: all we need to do is // ask for the ID. Due to the way SAMRAI works these calls must occur HierarchyMathOps hier_math_ops("hier_math_ops", patch_hierarchy); const int cv_cc_idx = hier_math_ops.getCellWeightPatchDescriptorIndex(); // SAMRAI patches do not store data as a single contiguous arrays; // instead, each hierarchy contains several contiguous arrays. Hence, // to do linear algebra, we rely on SAMRAI's own vector class which // understands these relationships. We begin by initializing each // vector with the patch hierarchy: SAMRAIVectorReal<NDIM, double> u_vec("u", patch_hierarchy, 0, finest_level); SAMRAIVectorReal<NDIM, double> f_vec("f", patch_hierarchy, 0, finest_level); SAMRAIVectorReal<NDIM, double> f_approx_vec("f_approx", patch_hierarchy, 0, finest_level); SAMRAIVectorReal<NDIM, double> e_vec("e", patch_hierarchy, 0, finest_level); // and then associate them with, in each case, the relevant // component. Note that adding the components in this way will // register the vector with the visit data writer declared above and // we will compute cell integrals over the entire domain with respect // to the control volumes defined by cv_cc_idx. u_vec.addComponent(u_cc_var, u_cc_idx, cv_cc_idx); f_vec.addComponent(f_cc_var, f_cc_idx, cv_cc_idx); f_approx_vec.addComponent(f_approx_cc_var, f_approx_cc_idx, cv_cc_idx); e_vec.addComponent(e_cc_var, e_cc_idx, cv_cc_idx); // By default, in SAMRAI, if we create another vector as // // SAMRAIVectorReal<NDIM, double> f_approx_vec("f_approx", patch_hierarchy, 0, finest_level); // // we will simply get a shallow copy of the u vector: put another way, // the two vectors will have different names but refer to the same // numerical values. Unfortunately cloning the vector doesn't work // either: the following code // // tbox::Pointer<SAMRAIVectorReal<NDIM, double> > f_approx = u_vec.cloneVector("f_approx"); // SAMRAIVectorReal<NDIM, double> &f_approx_vec = *f_approx; // f_approx_vec.setToScalar(0.0, false); // // crashes in SAMRAI 2.4.4 with a failed assertion referring to an // unknown variable ID. While ambiguous, the error message is not // wrong: we have to explicitly allocate data for each variable, so // creating a new anonymous variable for a cloned vector does not make // much sense. // Zero the vectors, including possible ghost data: u_vec.setToScalar(0.0, false); f_vec.setToScalar(0.0, false); f_approx_vec.setToScalar(0.0, false); e_vec.setToScalar(0.0, false); // Next, we use functions defined with muParser to set up the right // hand side and solution. These functions are read from the input // database and can be changed without recompiling. { muParserCartGridFunction u_fcn("u", app_initializer->getComponentDatabase("u"), grid_geometry); muParserCartGridFunction f_fcn("f", app_initializer->getComponentDatabase("f"), grid_geometry); u_fcn.setDataOnPatchHierarchy(u_cc_idx, u_cc_var, patch_hierarchy, 0.0); f_fcn.setDataOnPatchHierarchy(f_cc_idx, f_cc_var, patch_hierarchy, 0.0); } // Compute -L*u = f. PoissonSpecifications poisson_spec("poisson_spec"); poisson_spec.setCConstant(0.0); poisson_spec.setDConstant(-1.0); RobinBcCoefStrategy<NDIM>* bc_coef = NULL; CCLaplaceOperator laplace_op("laplace op"); laplace_op.setPoissonSpecifications(poisson_spec); laplace_op.setPhysicalBcCoef(bc_coef); laplace_op.initializeOperatorState(u_vec, f_vec); laplace_op.apply(u_vec, f_approx_vec); // Compute error and print error norms. Here we create temporary smart // pointers that will not delete the underlying object since the // second argument to the constructor is false. e_vec.subtract(Pointer<SAMRAIVectorReal<NDIM, double> >(&f_vec, false), Pointer<SAMRAIVectorReal<NDIM, double> >(&f_approx_vec, false)); pout << "|e|_oo = " << e_vec.maxNorm() << "\n"; pout << "|e|_2 = " << e_vec.L2Norm() << "\n"; pout << "|e|_1 = " << e_vec.L1Norm() << "\n"; // Finally, we clean up the output by setting error values on patches // on coarser levels which are covered by finer levels to zero. for (int ln = 0; ln < finest_level; ++ln) { Pointer<PatchLevel<NDIM> > level = patch_hierarchy->getPatchLevel(ln); Pointer<PatchLevel<NDIM> > next_finer_level = patch_hierarchy->getPatchLevel(ln + 1); BoxArray<NDIM> refined_region_boxes = next_finer_level->getBoxes(); refined_region_boxes.coarsen(next_finer_level->getRatioToCoarserLevel()); for (PatchLevel<NDIM>::Iterator p(level); p; p++) { const Patch<NDIM>& patch = *level->getPatch(p()); const Box<NDIM>& patch_box = patch.getBox(); Pointer<CellData<NDIM, double> > e_cc_data = patch.getPatchData(e_cc_idx); for (int i = 0; i < refined_region_boxes.getNumberOfBoxes(); ++i) { const Box<NDIM>& refined_box = refined_region_boxes[i]; // Box::operator* returns the intersection of two boxes. const Box<NDIM>& intersection = patch_box * refined_box; if (!intersection.empty()) { e_cc_data->fillAll(0.0, intersection); } } } } // Output data for plotting. visit_data_writer->writePlotData(patch_hierarchy, 0, 0.0); } // At this point all SAMRAI, PETSc, and IBAMR objects have been cleaned // up, so we shut things down in the opposite order of initialization: SAMRAIManager::shutdown(); PetscFinalize(); return true; } // run_example
template <typename PointT> void pcl::MLSResult::computeMLSSurface (const pcl::PointCloud<PointT> &cloud, int index, const std::vector<int> &nn_indices, double search_radius, int polynomial_order, boost::function<double(const double)> weight_func) { // Compute the plane coefficients EIGEN_ALIGN16 Eigen::Matrix3d covariance_matrix; Eigen::Vector4d xyz_centroid; // Estimate the XYZ centroid pcl::compute3DCentroid (cloud, nn_indices, xyz_centroid); // Compute the 3x3 covariance matrix pcl::computeCovarianceMatrix (cloud, nn_indices, xyz_centroid, covariance_matrix); EIGEN_ALIGN16 Eigen::Vector3d::Scalar eigen_value; EIGEN_ALIGN16 Eigen::Vector3d eigen_vector; Eigen::Vector4d model_coefficients (0, 0, 0, 0); pcl::eigen33 (covariance_matrix, eigen_value, eigen_vector); model_coefficients.head<3> ().matrix () = eigen_vector; model_coefficients[3] = -1 * model_coefficients.dot (xyz_centroid); // Projected query point valid = true; query_point = cloud.points[index].getVector3fMap ().template cast<double> (); double distance = query_point.dot (model_coefficients.head<3> ()) + model_coefficients[3]; mean = query_point - distance * model_coefficients.head<3> (); curvature = covariance_matrix.trace (); // Compute the curvature surface change if (curvature != 0) curvature = std::abs (eigen_value / curvature); // Get a copy of the plane normal easy access plane_normal = model_coefficients.head<3> (); // Local coordinate system (Darboux frame) v_axis = plane_normal.unitOrthogonal (); u_axis = plane_normal.cross (v_axis); // Perform polynomial fit to update point and normal //////////////////////////////////////////////////// num_neighbors = static_cast<int> (nn_indices.size ()); order = polynomial_order; if (order > 1) { int nr_coeff = (order + 1) * (order + 2) / 2; if (num_neighbors >= nr_coeff) { // Note: The max_sq_radius parameter is only used if weight_func was not defined double max_sq_radius = 1; if (weight_func == 0) { max_sq_radius = search_radius * search_radius; weight_func = boost::bind (&pcl::MLSResult::computeMLSWeight, this, _1, max_sq_radius); } // Allocate matrices and vectors to hold the data used for the polynomial fit Eigen::VectorXd weight_vec (num_neighbors); Eigen::MatrixXd P (nr_coeff, num_neighbors); Eigen::VectorXd f_vec (num_neighbors); Eigen::MatrixXd P_weight; // size will be (nr_coeff_, nn_indices.size ()); Eigen::MatrixXd P_weight_Pt (nr_coeff, nr_coeff); // Update neighborhood, since point was projected, and computing relative // positions. Note updating only distances for the weights for speed std::vector<Eigen::Vector3d, Eigen::aligned_allocator<Eigen::Vector3d> > de_meaned (num_neighbors); for (size_t ni = 0; ni < (size_t) num_neighbors; ++ni) { de_meaned[ni][0] = cloud.points[nn_indices[ni]].x - mean[0]; de_meaned[ni][1] = cloud.points[nn_indices[ni]].y - mean[1]; de_meaned[ni][2] = cloud.points[nn_indices[ni]].z - mean[2]; weight_vec (ni) = weight_func (de_meaned[ni].dot (de_meaned[ni])); } // Go through neighbors, transform them in the local coordinate system, // save height and the evaluation of the polynome's terms double u_coord, v_coord, u_pow, v_pow; for (size_t ni = 0; ni < (size_t) num_neighbors; ++ni) { // Transforming coordinates u_coord = de_meaned[ni].dot (u_axis); v_coord = de_meaned[ni].dot (v_axis); f_vec (ni) = de_meaned[ni].dot (plane_normal); // Compute the polynomial's terms at the current point int j = 0; u_pow = 1; for (int ui = 0; ui <= order; ++ui) { v_pow = 1; for (int vi = 0; vi <= order - ui; ++vi) { P (j++, ni) = u_pow * v_pow; v_pow *= v_coord; } u_pow *= u_coord; } } // Computing coefficients P_weight = P * weight_vec.asDiagonal (); P_weight_Pt = P_weight * P.transpose (); c_vec = P_weight * f_vec; P_weight_Pt.llt ().solveInPlace (c_vec); } } }