コード例 #1
0
ファイル: lcp.cpp プロジェクト: order/lcp-research
void PLCP::write(const string & filename){
  Archiver arch;
  arch.add_sp_mat("P",P);
  arch.add_sp_mat("U",U);
  arch.add_vec("q",q);
  arch.write(filename);
}
コード例 #2
0
int main(int argc, char** argv)
{
  arma_rng::set_seed_random();
  // Set up 2D space

  cout << "Generating initial mesh..." << endl;
  TriMesh mesh = generate_initial_mesh();
  Points points = mesh.get_spatial_nodes();
  uint N = points.n_rows;
  assert(N == mesh.number_of_spatial_nodes());
  assert(N > 0);
  
  DoubleIntegratorSimulator di = build_di_simulator();
  uint A = di.num_actions();
  assert(A >= 2);
  
  // Reference blocks
  cout << "Building LCP blocks..." << endl;
  vector<sp_mat> blocks = di.lcp_blocks(&mesh,GAMMA);
  assert(A == blocks.size());
  assert(size(N,N) == size(blocks.at(0)));

  // Build smoother
  cout << "Building smoother matrix..." << endl;
  sp_mat smoother = gaussian_smoother(points,SMOOTH_BW,SMOOTH_THRESH);
  assert(size(N,N) == size(smoother));

  // Build and pertrub the q
  cout << "Building RHS Q..." << endl;
  mat Q = di.q_mat(&mesh);
  
  bvec free_vars = zeros<bvec>((A+1)*N);
  free_vars.head(N).fill(1);

  cout << "Making value basis..." << endl;
  sp_mat value_basis = make_value_basis(points);
  
  cout << "Building reference approximate PLCP..." << endl;
  PLCP ref_plcp = approx_lcp(value_basis,smoother,blocks,Q,free_vars);

  ProjectiveSolver psolver = ProjectiveSolver();
  psolver.comp_thresh = 1e-8;
  psolver.initial_sigma = 0.25;
  psolver.verbose = false;
  psolver.iter_verbose = false;

  cout << "Starting reference augmented PLCP solve..."  << endl;
  SolverResult ref_sol = psolver.aug_solve(ref_plcp);
  mat ref_P = reshape(ref_sol.p,N,A+1);
  vec ref_V = ref_P.col(0);
  vec ref_res = bellman_residual_at_nodes(&mesh,&di,ref_V,GAMMA);  
  vec ref_res_norm = vec{norm(ref_res,1),norm(ref_res,2),norm(ref_res,"inf")};

  //////////////////////////
  // SETUP FOR EXPERIMENT //
  //////////////////////////
  vec bandwidths = logspace<vec>(-3,1,NUM_BW); // 0.01 to 1
  uint num_points = bandwidths.n_elem;
  mat res_diff = mat(num_points,3);
  
  for(uint i = 0; i < num_points; i++){
    cout << "Running " << i << "/" << num_points  << endl;

    mat new_vects = mat(N,2);
    new_vects.col(0) = gaussian(points,NEW_CENTER,bandwidths(i));
    new_vects.col(1) = gaussian(points,-NEW_CENTER,bandwidths(i));
    
    sp_mat new_basis = sp_mat(orth(join_horiz(mat(value_basis),
					      new_vects)));

    PLCP plcp = approx_lcp(new_basis,smoother,
			   blocks,Q,free_vars);

    SolverResult sol = psolver.aug_solve(plcp);

    // Interpret results
    mat P = reshape(sol.p,N,A+1);
    vec V = P.col(0);
    vec res = bellman_residual_at_nodes(&mesh,&di,V,GAMMA);
    vec res_norm = vec{norm(res,1),norm(res,2),norm(res,"inf")};
    res_diff.row(i) = (res_norm - ref_res_norm).t();
  }
  
  mesh.write_cgal("test.mesh");
  Archiver arch = Archiver();
  arch.add_vec("ref_res",ref_res);
  arch.add_mat("res_diff",res_diff);
  arch.add_mat("bandwidths",bandwidths);

  arch.write("test.data");
}
コード例 #3
0
////////////////////////////////////////////////////////////
// MAIN FUNCTION ///////////////////////////////////////////
////////////////////////////////////////////////////////////
int main(int argc, char** argv)
{
  po::variables_map var_map = read_command_line(argc,argv);
  arma_rng::set_seed_random();

  // Read in the CGAL mesh
  TriMesh mesh;
  string file_base = var_map["outfile_base"].as<string>();
  double edge_length = var_map["edge_length"].as<double>();
  generate_minop_mesh(mesh,file_base,edge_length);
  mesh.freeze();

  // Stats
  uint N = mesh.number_of_vertices();
  uint F = mesh.number_of_faces();
  cout << "Mesh stats:"
       << "\n\tNumber of vertices: " << N
       << "\n\tNumber of faces: " << F
       << endl;

  // Build value basis
  uint num_value_basis = 25;
  uint num_flow_basis = 10;
  Points points = mesh.get_spatial_nodes();
  cout << "Generating Radial Fourier basis for value..." << endl;
  mat value_basis = make_radial_fourier_basis(points,
                                              num_value_basis,
                                              (double)num_value_basis);
  cout << "\tOrthogonalizing..." << endl;
  value_basis = orth(value_basis);

  cout << "Generating Voronoi basis for flow..." << endl;
  sp_mat sp_value_basis = sp_mat(value_basis);
  
  Points centers = 2 * randu(10,2) - 1;
  mat flow_basis = make_voronoi_basis(points,
                                      centers);
  cout << "\tOrthogonalizing..." << endl;
  flow_basis = orth(flow_basis);
  sp_mat sp_flow_basis = sp_mat(flow_basis);

  cout << "Building LCP..." << endl;
  vec ref_weights = ones<vec>(N) / (double)N;
  LCP ref_lcp;
  vec ans;
  build_minop_lcp(mesh,ref_weights,ref_lcp,ans);
  assert(N == ans.n_elem);

  cout << "Building PLCP..." << endl;
  block_sp_vec D = {sp_value_basis,
                    sp_flow_basis,
                    sp_flow_basis};  
  sp_mat P = block_diag(D);
  double regularizer = 1e-12;
  sp_mat U = P.t() * (ref_lcp.M + regularizer*speye(size(ref_lcp.M)));
  vec q =  P *(P.t() * ref_lcp.q);
  assert(3*N == P.n_rows);
  assert(3*N == q.n_rows);

  bvec free_vars = zeros<bvec>(3*N);
  free_vars.head(N).fill(1);
  
  PLCP ref_plcp = PLCP(P,U,q,free_vars);
  ref_plcp.write(file_base + ".plcp");
  ProjectiveSolver psolver;
  psolver.comp_thresh = 1e-12;
  psolver.max_iter = 250;
  psolver.aug_rel_scale = 5;
  psolver.verbose = false;
  psolver.initial_sigma = 0.3;

  cout << "Starting reference solve..." << endl;
  SolverResult ref_sol = psolver.aug_solve(ref_plcp);
  cout << "\tDone." << endl;
  cout << "Reference solution error: "
       << norm(ans - ref_sol.p.head(N)) << endl;
  assert(ALMOST_ZERO > norm(ref_sol.d.head(N))); // Essentially zero
  ref_sol.write(file_base + ".sol");
  
  psolver.comp_thresh = 1e-8;
  // Exactish
  vec twiddle = vec(N);
  for(uint i = 0; i < N; i++){
    cout << "Component: " << i << endl;
    LCP twiddle_lcp;
    vec et = zeros<vec>(N);
    et(i) += 1.0 / (double) N;
    assert(size(ref_weights) == size(et));
    build_minop_lcp(mesh,ref_weights + et,twiddle_lcp,ans);
    vec twiddle_q =  P *(P.t() * twiddle_lcp.q);

    PLCP twiddle_plcp = PLCP(P,U,twiddle_q,free_vars);
    SolverResult twiddle_sol = psolver.aug_solve(twiddle_plcp);
    twiddle(i) = twiddle_sol.p(i) - ref_sol.p(i);
  }

  uint R = 75;
  mat jitter = mat(N,R);
  mat noise = mat(N,R);
  for(uint i = 0; i < R; i++){
    cout << "Jitter round: " << i << endl;
    LCP jitter_lcp;
    noise.col(i) = max(1e-4*ones<vec>(N), 0.075 * randn<vec>(N));
    build_minop_lcp(mesh,ref_weights + noise.col(i),jitter_lcp,ans);
    vec jitter_q =  P *(P.t() * jitter_lcp.q);

    PLCP jitter_plcp = PLCP(P,U,jitter_q,free_vars);
    SolverResult jitter_sol = psolver.aug_solve(jitter_plcp);
                                                 
    jitter.col(i) = (jitter_sol.p.head(N) - ref_sol.p.head(N)); 
  }
  
  Archiver arch;
  arch.add_vec("p",ref_sol.p.head(N));
  arch.add_vec("twiddle",twiddle);
  arch.add_mat("jitter",jitter);
  arch.add_mat("noise",noise);
  arch.add_sp_mat("flow_basis",sp_flow_basis);
  arch.write(file_base + ".exp_res");
  
}
コード例 #4
0
ファイル: solver.cpp プロジェクト: order/lcp-research
void SolverResult::write(const string & filename) const{
  Archiver arch;
  arch.add_vec("p",p);
  arch.add_vec("d",d);
  arch.write(filename);
}
コード例 #5
0
ファイル: minop_refine.cpp プロジェクト: order/lcp-research
int main(int argc, char** argv)
{
  po::variables_map var_map = read_command_line(argc,argv);

  string mesh_file = var_map["infile_base"].as<string>() + ".tri";

  // Read in the CGAL mesh
  TriMesh mesh;
  cout << "Reading in cgal mesh file [" << mesh_file << ']'  << endl;
  mesh.read_cgal(mesh_file);
  mesh.freeze();
  uint V = mesh.number_of_vertices();
  uint N = mesh.number_of_all_nodes();
  assert(N == V+1);
  uint F = mesh.number_of_faces();
  cout << "Mesh stats:"
       << "\n\tNumber of vertices: " << V
       << "\n\tNumber of faces: " << F
       << endl;
  Points centers = mesh.get_cell_centers();

  // Find boundary from the mesh and create the simulator object
  mat bbox = mesh.find_bounding_box();
  vec lb = bbox.col(0);
  vec ub = bbox.col(1);
  cout << "\tLower bound:" << lb.t()
       << "\tUpper bound:" << ub.t();

  // Read in solution information
  string soln_file = var_map["infile_base"].as<string>() + ".sol";
  cout << "Reading in LCP solution file [" << soln_file << ']'  << endl;
  Unarchiver sol_unarch(soln_file);
  vec p = sol_unarch.load_vec("p");

  string lcp_file = var_map["infile_base"].as<string>() + ".lcp";
  Unarchiver lcp_unarch(lcp_file);
  vec q = lcp_unarch.load_vec("q");

  Archiver arch;
  
  // Make sure that the primal information makes sense
  assert(0 == p.n_elem % V);
  uint A = p.n_elem / V;
  assert(A == 3);
  cout << "Blocking primal solution..."
       << "\n\tLength of primal solution: " << p.n_elem
       << "\n\tRatio of primal length to vertex number: " << A << endl;
  mat P = reshape(p,size(V,A));
  P = join_vert(P,datum::inf * ones<rowvec>(3)); // Pad
  vec value = P.col(0);
  mat flows = P.tail_cols(2);

  mat Q = reshape(q,size(V,A));
  Q = join_vert(Q,datum::inf * ones<rowvec>(3)); // Pad
  vec recon_b = mesh.interpolate(centers,
                                 conv_to<vec>::from(Q.col(1)));
  vec recon_c = mesh.interpolate(centers,
                                 conv_to<vec>::from(Q.col(2)));
  arch.add_vec("recon_b",recon_b);
  arch.add_vec("recon_c",recon_c);


  vec area = mesh.cell_area();
  arch.add_vec("area",area);

  // True values
  vec sq_dist = sum(pow(centers,2),1);
  vec b = sq_dist;
  vec c = max(zeros<vec>(F),1 - sq_dist);
  vec x = arma::min(b,c);
  assert(all(x >= 0));
  assert(F == x.n_elem);
  
  uvec pi = arma::index_min(join_horiz(b,c),1);
  assert(F == pi.n_elem);
  arch.add_uvec("pi",pi);

  // Approx policy
  assert(2 == flows.n_cols);
  mat interp_flows = mesh.interpolate(centers,flows);
  uvec flow_pi = arma::index_max(interp_flows,1);
  arch.add_uvec("flow_pi",flow_pi);

  assert(F == flow_pi.n_elem);
  uvec diff = zeros<uvec>(F);
  diff(find(flow_pi != pi)).fill(1);
  arch.add_uvec("policy_diff",diff);

  // Approx value
  vec interp_value = mesh.interpolate(centers,value);
  assert(F == interp_value.n_elem);
  vec res = abs(x - interp_value);
  arch.add_vec("residual",res);

  vec heuristic = res;
  heuristic(find(flow_pi != pi)) *= 4;
  arch.add_vec("heuristic",heuristic);

  double quant = 0.9;
  cout << "Quantile:" << quant << endl;
  double cutoff = quantile(heuristic,quant);
  cout << "\t Cutoff: " << cutoff
       << "\n\t Max:" << max(heuristic)
       << "\n\t Min:" << min(heuristic) << endl;

  // Split the cells if they have a large heuristic_1 or
  // policies disagree on them.
  TriMesh new_mesh(mesh);  
  Point center;
  uint new_nodes = 0;
  for(uint f = 0; f < F; f++){
    if(area(f) < 2e-4){
      continue;
    }
    if(new_nodes > 200) break;
    if(heuristic(f) > cutoff){
      center = convert(mesh.center_of_face(f));
      new_mesh.insert(center);
      new_nodes++;
    }
  }
  cout << "Added " << new_nodes << " new nodes..." << endl;
  
  cout << "Refining..." << endl;
  new_mesh.refine(0.125,1.0);
  new_mesh.lloyd(10);
  //new_mesh.insert(Point(0,0));
  new_mesh.freeze();

  // Write out all the information
  string out_file_base = var_map["outfile_base"].as<string>();
  arch.write(out_file_base + ".stats");
  cout << "Writing..."
       << "\n\tCGAL mesh file: " << out_file_base << ".tri"
       << "\n\tShewchuk node file: " << out_file_base << ".node"
       << "\n\tShewchuk ele file: " << out_file_base << ".ele" << endl;
  new_mesh.write_cgal(out_file_base + ".tri");
  new_mesh.write_shewchuk(out_file_base);
}
コード例 #6
0
ファイル: lcp.cpp プロジェクト: order/lcp-research
void LCP::write(const string & filename){
  Archiver arch;
  arch.add_sp_mat("M",M);
  arch.add_vec("q",q);
  arch.write(filename);
}