Example #1
0
LCP smooth_lcp(const sp_mat & smoother,
               const vector<sp_mat> & blocks,
               const mat & Q,
               const bvec & free_vars){
  uint n = smoother.n_rows;
  assert(n == smoother.n_cols);
  uint A = blocks.size();
  uint N = n*(A+1);
  assert(A >= 1);
  assert(size(n,n) == size(blocks.at(0)));
  assert(size(n,A+1) == size(Q));
  assert(N == free_vars.n_elem);
  
  // Smooth blocks
  vector<sp_mat> sblocks = block_rmult(smoother,blocks);

  // Smooth Q
  mat sQ = mat(size(Q));
  sQ.col(0) = Q.col(0); // State weights unchanged
  sQ.tail_cols(A) = smoother * Q.tail_cols(A);

  sp_mat M = build_M(sblocks);
  vec q = vectorise(sQ);
  return LCP(M,q,free_vars);
}
Example #2
0
LCP build_lcp(const Simulator * sim,
              const Discretizer * disc,
              double gamma,
              bool include_oob,
              bool value_nonneg){
  cout << "Generating transition matrices..."<< endl;
  vector<sp_mat> E_blocks = build_E_blocks(sim,disc,
                                           gamma,include_oob);
  sp_mat M = build_M(E_blocks);
  vec q = build_q_vec(sim,disc,gamma,include_oob);
  assert(q.n_elem == M.n_rows);
  assert(q.n_elem == M.n_cols);

  if(value_nonneg)
    return LCP(M,q);

  uint A = sim->num_actions();
  uint N;
  if(include_oob)
    N= disc->number_of_all_nodes();
  else
    N= disc->number_of_spatial_nodes();

  bvec free_vars = zeros<bvec>((A+1)*N);
  assert(size(q) == size(free_vars));
  
  free_vars.head(N).fill(1);
  return LCP(M,q,free_vars);
}
Example #3
0
File: vdw.c Project: tidatida/mpmc
//calculate energies for isolated molecules
//if we don't know it, calculate it and save the value
double calc_e_iso ( system_t * system, double * sqrtKinv, molecule_t * mptr ) {
    int nstart, nsize; // , curr_dimM;  (unused variable)
    double e_iso; //total vdw energy of isolated molecules
    struct mtx * Cm_iso; //matrix Cm_isolated
    double * eigvals; //eigenvalues of Cm_cm
    molecule_t * molecule_ptr;
    atom_t * atom_ptr;

    nstart=nsize=0; //loop through each individual molecule
    for ( molecule_ptr = system->molecules; molecule_ptr; molecule_ptr=molecule_ptr->next ) {
        if ( molecule_ptr != mptr ) {  //count atoms then skip to next molecule
            for ( atom_ptr = molecule_ptr->atoms; atom_ptr; atom_ptr = atom_ptr->next ) nstart++;
            continue;
        }

        //now that we've found the molecule of interest, count natoms, and calc energy
        for ( atom_ptr = molecule_ptr->atoms; atom_ptr; atom_ptr = atom_ptr->next ) nsize++;

        //build matrix for calculation of vdw energy of isolated molecule
        Cm_iso = build_M(3*(nsize), 3*nstart, system->A_matrix, sqrtKinv);
        //diagonalize M and extract eigenvales -> calculate energy
        eigvals=lapack_diag(Cm_iso,1); //no eigenvectors
        e_iso=eigen2energy(eigvals,Cm_iso->dim,system->temperature);

        //free memory
        free(eigvals);
        free_mtx(Cm_iso);

        //convert a.u. -> s^-1 -> K
        return e_iso * au2invsec * halfHBAR ;
    }

    //unmatched molecule
    return NAN; //we should never get here
}
Example #4
0
File: vdw.c Project: tidatida/mpmc
//returns interaction VDW energy
double vdw(system_t *system) {

    int N; //  dimC;  (unused variable)  //number of atoms, number of non-zero rows in C-Matrix
    double e_total, e_iso; //total energy, isolation energy (atoms @ infinity)
    double * sqrtKinv; //matrix K^(-1/2); cholesky decomposition of K
    double ** Am = system->A_matrix; //A_matrix
    struct mtx * Cm; //C_matrix (we use single pointer due to LAPACK requirements)
    double * eigvals; //eigenvales
    double fh_corr, lr_corr;

    N=system->natoms;

    //allocate arrays. sqrtKinv is a diagonal matrix. d,e are used for matrix diag.
    sqrtKinv = getsqrtKinv(system,N);

    //calculate energy vdw of isolated molecules
    e_iso = sum_eiso_vdw ( system, sqrtKinv );

    //Build the C_Matrix
    Cm = build_M (3*N, 0, Am, sqrtKinv);

    //setup and use lapack diagonalization routine dsyev_()
    eigvals = lapack_diag (Cm, system->polarvdw); //eigenvectors if system->polarvdw == 2
    if ( system->polarvdw == 2 )
        printevects(Cm);

    //return energy in inverse time (a.u.) units
    e_total = eigen2energy(eigvals, Cm->dim, system->temperature);
    e_total *= au2invsec * halfHBAR; //convert a.u. -> s^-1 -> K

    //vdw energy comparison
    if ( system->polarvdw == 3 )
        printf("VDW Two-Body | Many Body = %lf | %lf\n", twobody(system),e_total-e_iso);

    if ( system->feynman_hibbs ) {
        if ( system->vdw_fh_2be ) fh_corr = fh_vdw_corr_2be(system); //2be method
        else fh_corr = fh_vdw_corr(system); //mpfd
    }
    else fh_corr=0;

    if ( system->rd_lrc ) lr_corr = lr_vdw_corr(system);
    else lr_corr=0;

//cleanup and return
    free(sqrtKinv);
    free(eigvals);
    free_mtx(Cm);

    return e_total - e_iso + fh_corr + lr_corr;

}
Example #5
0
PLCP approx_lcp(const sp_mat & value_basis,
                const sp_mat & smoother,
                const vector<sp_mat> & blocks,
                const mat & Q,
                const bvec & free_vars){

  //Sizing and checking
  uint n = smoother.n_rows;
  assert(n == smoother.n_cols);
  uint A = blocks.size();
  assert(A >= 1);
  assert(size(n,n) == size(blocks.at(0)));
  assert(size(n,A+1) == size(Q));
  uint N = n*(A+1);
  assert(N == free_vars.n_elem);
  assert(n == value_basis.n_rows);

  // Smooth blocks
  vector<sp_mat> sblocks = block_rmult(smoother,blocks);

  // Build freebie flow bases for the smoothed problem
  bool ignore_q = false;
  vector<sp_mat> flow_bases;
  vec q;
  if(ignore_q){
    flow_bases = make_freebie_flow_bases_ignore_q(value_basis,
                                                  sblocks);
    // Project smoothed costs onto `freebie' basis
    mat sQ = mat(size(Q));  
    sQ.col(0) = Q.col(0);
    for(uint a = 0; a < A; a++){
      sp_mat F = flow_bases.at(a);
      sQ.col(a+1) = F * F.t() * smoother * Q.col(a+1);
    }
    q = vectorise(sQ);
  }
  else{
    mat sQ = mat(size(Q));  
    sQ.col(0) = Q.col(0);
    sQ.tail_cols(A) = smoother * Q.tail_cols(A);
    q = vectorise(sQ);

    flow_bases = make_freebie_flow_bases(value_basis,
                                         sblocks,
                                         sQ);
  }
  // Build the basis blocks and the basis matrix
  block_sp_vec p_blocks;
  p_blocks.reserve(A + 1);
  p_blocks.push_back(value_basis);
  p_blocks.insert(p_blocks.end(),
                  flow_bases.begin(),
                  flow_bases.end());
  assert((A+1) == p_blocks.size());
  sp_mat P = block_diag(p_blocks);

  // Build LCP matrix M and the U coefficient matrix
  sp_mat M = build_M(sblocks);// + 1e-10 * speye(N,N); // Regularize
  sp_mat U = P.t() * M * P * P.t();
  return PLCP(P,U,q,free_vars);

}