Exemplo n.º 1
0
vector<sp_mat> build_E_blocks(const Simulator * sim,
                              const Discretizer * disc,
                              double gamma,
                              bool include_oob){
  Points points = disc->get_spatial_nodes();
  uint N;
  if(include_oob)
    N = disc->number_of_all_nodes();
  else
    N = disc->number_of_spatial_nodes();
  
  uint A = sim->num_actions();
  uint Ad = sim->dim_actions();
  mat actions = sim->get_actions();
  assert(size(A,Ad) == size(actions));
  
  uint num_samples = 25;
  
  vector<sp_mat> E_blocks;
  sp_mat I = speye(N,N);  
  vec u;
  ElementDist P,Q;
  for(uint i = 0; i < A; i++){
    P = ElementDist(N,N);
    u = actions.row(i).t();
    cout << "\tAction [" << i << "]: u = " << u.t();
    for(uint j = 0; j < num_samples; j++){
      P += sim->transition_matrix(disc,u,include_oob);
    }
    P /= (double) num_samples;
    E_blocks.push_back(I - gamma * P);
  }
  assert(A == E_blocks.size());
  return E_blocks;
}
Exemplo n.º 2
0
vector<sp_mat> build_hallway_blocks(const uint N,
                       const double p_stick,
                       const double gamma){
  // Build the transition matrices for -1,0,1
  vector<sp_mat> blocks;
  // Left
  sp_mat P_left = build_hallway_P(N,p_stick,-1);
  blocks.push_back(speye(N,N) - gamma * P_left);
  
  // Stay
  blocks.push_back((1-gamma) * speye(N,N));

  //Right
  sp_mat P_right = build_hallway_P(N,p_stick,1);
  blocks.push_back(speye(N,N) - gamma * P_right);
  return blocks;
}
Exemplo n.º 3
0
sp_mat build_hallway_P(const uint N,
                       const double p_stick,
                       const int action){
  // Build the hallway transition matrix associated with
  // and action
  
  assert(action == -1 or action == 1);
  sp_mat P =  p_stick * speye(N,N)
    + spdiag((1-p_stick) * ones<vec>(N-1),action);
  if(action < 0)
    P(0,N-1) = (1 - p_stick);
  else
    P(N-1,0) = (1 - p_stick);
  return P;
}
Exemplo n.º 4
0
void newton_matrix(ode_workspace *odews)
{
    // Create a Newton matrix from the given step gamma and Jacobian in W
    cs *M, *eye;
    if (odews->mdeclared)
    {
        cs_nfree(odews->N);
    }
    else
    {
        odews->mdeclared = 1;
    }

    eye = speye(odews->W->J->m);
    M = cs_add(eye, odews->W->J, 1, -odews->dt);
    cs_spfree(eye);

    odews->N = cs_lu(M, odews->S, 1);
    cs_spfree(M);
}
Exemplo n.º 5
0
sp_mat Device1D::qCMatFunct(mat phin, mat phip, bool Equilibrum) {
	if ( phin.n_elem != sumPoint || ( phip.n_elem != sumPoint ) )
		std::cerr << "Error: input wrong phin/phip size!" << std::endl;
    sp_mat cp=speye(sumPoint, sumPoint);

	if (Equilibrum == true ) {
		for ( int i = 0; i < bandGapArray.size(); i++) {
			phip(i) = bandGapArray[i] - phin(i);
		}
	}

    int k=0;
    for ( int i=0; i < materialList.size(); i++) {
        for ( int j=0; j < nyList[i]; j++) {
            if (typeList[i] == Semiconductor) {
                cp(k + 1, k + 1) = materialList[i].quantumCapa((double)phin(k), (double)phip(k)); //TODO: why here used to be k+1, then "cp(0, 0) = cp(1, 1);"
            } else if (typeList[i]==Dielectric) {
             };
            k++;
        };
    };

    return ( cp );
}
Exemplo n.º 6
0
SolverResult KojimaSolver::solve(const LCP & lcp,
                                 vec & x,
                                 vec & y) const{
  superlu_opts opts;
  opts.equilibrate = true;
  opts.permutation = superlu_opts::COLAMD;
  opts.refine = superlu_opts::REF_SINGLE;
  
  vec q = lcp.q;
  sp_mat M = lcp.M + regularizer * speye(size(lcp.M));
  uint N = q.n_elem;

  assert(N == x.n_elem);
  assert(N == y.n_elem);

  // Figure out what is free (-inf,inf)
  // and what is bound to be non-negative [0,inf)
  bvec free_vars = lcp.free_vars;
  uvec bound_idx = find(0 == free_vars);
  uvec free_idx = find(1 == free_vars);
  assert(N == bound_idx.n_elem + free_idx.n_elem);
  uint NB = bound_idx.n_elem; // number of bound vars
  uint NF = free_idx.n_elem; // number of free vars
  
  /*
    In what follows, the primal variables x are partitioned into
    free variables and bound variables x = [f;b]'
    Likewise, the dual variables are partitioned into y = [0,s]'
   */
  
  /* The Newton system:
  [M_ff  M_fb  0][df]   [M_f x + q_f]
  [M_bf  M_bb -I][db] + [M_b x + q_b - s]
  [0     S     B][dv]   [u1 + VBe]
  Where "M_ff" is the free-free block
  Overwrite the S,B diagonals every iteration*/

  // Split M matrix into blocks based on free and bound indicies
  block_sp_mat M_part = sp_partition(M,free_idx,bound_idx);
  sp_mat M_recon = block_mat(M_part);
  assert(PRETTY_SMALL > norm(M_recon - M));
  vec qf = q(free_idx);
  vec qb = q(bound_idx);
  vec b = x(bound_idx);
  vec f = x(free_idx);
  vec s = y(bound_idx);

  // Build the Newton matrix
  vector<vector<sp_mat>> block_G;
  block_G.push_back(block_sp_vec{sp_mat(),sp_mat(),sp_mat(NB,NB)});
  block_G.push_back(block_sp_vec{-M_part[0][0],-M_part[0][1],sp_mat()});
  block_G.push_back(block_sp_vec{-M_part[1][0],-M_part[1][1],speye(NB,NB)});
 
  // Start iteration
  double mean_comp, steplen;
  double sigma = initial_sigma;
  uint iter;  
  for(iter = 0; iter < max_iter; iter++){
    if(verbose or iter_verbose)
      cout << "---Iteration " << iter << "---" << endl;
    assert(all(0 == y(free_idx)));

    // Mean complementarity
    mean_comp = dot(b,s) / (double) NB;
    if(mean_comp < comp_thresh)
      break;

    block_G[0][1] = spdiag(s);
    block_G[0][2] = spdiag(b);
    sp_mat G = block_mat(block_G);
    assert(size(N + NB,N + NB) == size(G));    
                    
    // Form RHS from residual and complementarity
    vec h = vec(N + NB);
    vec res_f = M_part[0][0]*f + M_part[0][1]*b + qf;
    vec res_b = M_part[1][0]*f + M_part[1][1]*b + qb - s;
    h.head(NB) = sigma * mean_comp - b % s;
    h.subvec(NB,size(res_f)) = res_f;
    h.tail(NB) = res_b;
    
    //Archiver arch;
    //arch.add_sp_mat("G",G);
    //arch.add_vec("h",h);
    //arch.write("test.sys");

    // Solve and extract directions
    vec dir = spsolve(G,h,"superlu",opts);
    assert((N+NB) == dir.n_elem);
    vec df = dir.head(NF);
    vec db = dir.subvec(NF,N-1);
    assert(NB == db.n_elem);
    vec ds = dir.tail(NB);    
    vec dir_recon = join_vert(df,join_vert(db,ds));
    assert(PRETTY_SMALL > norm(dir_recon-dir));

    steplen = steplen_heuristic(b,s,db,ds,0.9);
    sigma = sigma_heuristic(sigma,steplen);

    f += steplen * df;
    b += steplen * db;
    s += steplen * ds;

    if(verbose){
      double res = norm(join_vert(res_f,res_b));
      cout <<"\t Mean complementarity: " << mean_comp
           <<"\n\t Residual norm: " << res
           <<"\n\t |df|: " << norm(df)
           <<"\n\t |db|: " << norm(db)
           <<"\n\t |ds|: " << norm(ds)
           <<"\n\t Step length: " << steplen
           <<"\n\t Centering sigma: " << sigma << endl;
    }
  }
  if(verbose){
    cout << "Finished"
         <<"\n\t Final mean complementarity: " << mean_comp << endl;
  }
  x(free_idx) = f;
  x(bound_idx) = b;
  y(free_idx).fill(0);
  y(bound_idx) = s;
  return SolverResult(x,y,iter);
}
Exemplo n.º 7
0
SolverResult ProjectiveSolver::solve(const PLCP & plcp,
                            vec & x,
                            vec & y,
                            vec & w) const{
  sp_mat P = plcp.P;
  sp_mat U = plcp.U;
  vec q = plcp.q;
  uint N = P.n_rows;
  uint K = P.n_cols;
  assert(size(P.t()) == size(U));

  bvec free_vars = plcp.free_vars;
  uvec bound_idx = find(0 == free_vars);
  uvec free_idx = find(1 == free_vars);
  assert(N == bound_idx.n_elem + free_idx.n_elem);
  uint NB = bound_idx.n_elem; // number of bound vars
  uint NF = free_idx.n_elem; // number of free vars
  assert(NF == accu(conv_to<uvec>::from(free_vars)));

  assert(N == x.n_elem);
  assert(N == y.n_elem);
  assert(K == w.n_elem);
  assert(ALMOST_ZERO > norm(y(free_idx)));

  if(verbose)
    cout << "Free variables: \t" << NF << endl
         << "Non-neg variables:\t" << NB << endl;
  sp_mat J = join_vert(sp_mat(NF,NB),speye(NB,NB));
  assert(size(N,NB) == size(J));
  assert(PRETTY_SMALL > norm(y(free_idx)));

  if(verbose)
    cout << "Forming pre-computed products..." << endl;
  mat PtP = mat(P.t() * P);
  assert(size(K,K) == size(PtP));
  mat PtPU = PtP*U;
  assert(size(K,N) == size(PtPU));
  mat Pt_PtPU = P.t() - PtPU;
  assert(size(K,N) == size(Pt_PtPU));
  mat PtPUP = PtPU * P;
  assert(size(K,K) == size(PtPUP));

  vec Ptq = P.t() * q;
  if(verbose)
    cout << "Done..." << endl;

  
  double sigma = initial_sigma;

  uint iter;
  double mean_comp;
  for(iter = 0; iter < max_iter; iter++){    
    if(verbose or iter_verbose)
      cout << "---Iteration " << iter << "---" << endl;
    // Mean complementarity
    vec s = y(bound_idx);
    vec b = x(bound_idx);
    mean_comp = dot(s,b) / (double) NB;
    if(mean_comp < comp_thresh)
      break;

    // Generate reduced Netwon system
    mat C = s+b;
    vec g = sigma * mean_comp - s % b;
    assert(NB == g.n_elem);

    // NB: A,G,and h have opposite sign from python version    
    mat A = Pt_PtPU * J * spdiag(1.0 / C);
    assert(size(K,NB) == size(A));
     
    mat G = PtPUP + (A * spdiag(s)) * J.t() * P;
    assert(size(K,K) == size(G));

    vec Ptr = P.t() * (J *  s) - PtPU*x - Ptq;
    vec h = Ptr + A*g;
    assert(K == h.n_elem);

    // Options don't make much difference
    vec dw = arma::solve(G+1e-15*eye(K,K),h,
                         solve_opts::equilibrate);
    assert(K == dw.n_elem);

    // Recover dy
    vec Pdw = P * dw;
    vec JtPdw = J.t() * Pdw;
    assert(NB == JtPdw.n_elem);
    vec ds = (g - s % JtPdw) / C;
    assert(NB == ds.n_elem);
    
    // Recover dx
    vec dx = (J * ds) + (Pdw);
    assert(N == dx.n_elem);    

    double steplen = steplen_heuristic(x(bound_idx),s,dx(bound_idx),ds,0.9);
    sigma = sigma_heuristic(sigma,steplen);

    x += steplen * dx;
    s += steplen * ds;
    y(bound_idx) = s;
    w += steplen * dw;

    if(verbose){
      cout <<"\tMean complementarity: " << mean_comp
           <<"\n\tStep length: " << steplen
           <<"\n\tCentering sigma: " << sigma << endl;
    }
  }
  if(verbose){
    cout << "Finished"
         <<"\n\t Final mean complementarity: " << mean_comp << endl;
  }
  return SolverResult(x,y,iter);
}
Exemplo n.º 8
0
PLCP augment_plcp(const PLCP & original,
                  vec & x,
                  vec & y,
                  vec & w,
                  double scale){
  
  uint N = original.P.n_rows;
  uint K = original.P.n_cols;
  assert(size(K,N) == size(original.U));

  
  sp_mat P = sp_mat(original.P);
  double I_norm = norm(speye(K,K) - P.t() * P);
  if(norm(I_norm) >= PRETTY_SMALL){
    cerr << "Error: P does not look orthogonal ("
	 << I_norm << ")..." << endl;
  }
  assert(I_norm < PRETTY_SMALL);
  
  sp_mat U = sp_mat(original.U);
  vec q = vec(original.q);
  assert(all(q(find(1 == original.free_vars)) <= 0));


  vec q_neg = min(zeros<vec>(N),q);
  vec q_pos = max(zeros<vec>(N),q);
  x = ones<vec>(N) - q_neg;
  y = ones<vec>(N) + q_pos;
  y(find(1 == original.free_vars)).fill(0);
  assert(norm(q_pos(find(1 == original.free_vars))) < ALMOST_ZERO);
  
  assert(N == x.n_elem);
  assert(N == y.n_elem);
  assert(all(x >= 0));
  assert(all(y >= 0));

  vec res = x - y + q;
  w = spsolve(P.t()*P + 1e-15*speye(K,K),P.t()*(x - y + q));

  vec w_res = P * w - res;
  if(norm(w_res) >= PRETTY_SMALL){
    cerr << "Error: Reduced vector w residual large ("
	 << w_res << ")..." << endl;
  }

  assert(norm(w_res) < PRETTY_SMALL);
  
  vec b = P.t()*x - U*x - w;
  assert(K == b.n_elem);
  
  P.resize(N+1,K+1);
  U.resize(K+1,N+1);
  q.resize(N+1);
  
  P(N,K) = 1.0;
  U(span(0,K-1),N) = b;
  U(K,N) = scale;
  q(N) = 0;

  x.resize(N+1);
  y.resize(N+1);
  w.resize(K+1);

  x(N) = 1;
  y(N) = scale;
  w(K) = 1.0 - scale;
  
  bvec free_vars = bvec(N+1);
  free_vars.head(N) = original.free_vars;
  free_vars(N) = 0;
  
  return PLCP(P,U,q,free_vars);
}