Beispiel #1
0
void BasicOperator::mult_dirac(const Eigen::MatrixXcd& matrix,
                               Eigen::MatrixXcd& reordered, 
                               const size_t index) const {

  const vec_pdg_Corr op_Corr = global_data->get_lookup_corr();

  const size_t rows = matrix.rows();
  const size_t cols = matrix.cols();
  const size_t col = cols/4;
  if( (rows != reordered.rows()) || (cols != reordered.cols()) ){
    std::cout << "Error! In BasicOperator::mult_dirac: size of matrix and "
                 "reordered must be equal" << std::endl;
    exit(0);
  }

  for(const auto& dirac : op_Corr[index].gamma){
    if(dirac != 4){
      for(size_t block = 0; block < 4; block++){
        reordered.block(0, block * col, rows, col) = 
          gamma[dirac].value[block] *
          matrix.block(0, gamma[dirac].row[block]*col, rows, col);
      }
    }
  }

}
void CCorrelationFilters::build_mmcf(struct CDataStruct *img, struct CParamStruct *params, struct CFilterStruct *filt)
{
    /*
	 * This function calls the correlation filter design proposed in the following publications.
     *
	 * A. Rodriguez, Vishnu Naresh Boddeti, B.V.K. Vijaya Kumar and A. Mahalanobis, "Maximum Margin Correlation Filter: A New Approach for Localization and Classification", IEEE Transactions on Image Processing, 2012.
     *
	 * Vishnu Naresh Boddeti, "Advances in Correlation Filters: Vector Features, Structured Prediction and Shape Alignment" PhD thesis, Carnegie Mellon University, Pittsburgh, PA, USA, 2012.
     *
	 * Vishnu Naresh Boddeti and B.V.K. Vijaya Kumar, "Maximum Margin Vector Correlation Filters," Arxiv 1404.6031 (April 2014).
	 *
	 * Notes: This currently the best performing Correlation Filter design, especially when the training sample size is larger than the dimensionality of the data.
	 */
	
	filt->params = *params;
	filt->filter.size_data = params->size_filt_freq;
	filt->filter.size_data_freq = params->size_filt_freq;
	
	filt->filter.num_elements_freq = img->num_elements_freq;
	params->num_elements_freq = img->num_elements_freq;
	filt->filter.data_freq = new complex<double>[img->num_elements_freq*img->num_channels];
	
	Eigen::ArrayXcd filt_freq = Eigen::ArrayXcd::Zero(params->num_elements_freq*img->num_channels);
	
	// If not set default to 1
	if (params->wpos < 1) params->wpos = 1;
	filt->params.wpos = params->wpos;
	
	compute_psd_matrix(img, params);
	Eigen::MatrixXcd Y = Eigen::MatrixXcd::Zero(img->num_elements_freq*img->num_channels,img->num_data);
	Eigen::MatrixXcd u = Eigen::MatrixXcd::Zero(img->num_data,1);
	Eigen::MatrixXd temp = Eigen::MatrixXd::Zero(img->num_data,img->num_data);
	
	Eigen::Map<Eigen::MatrixXcd> X(img->data_freq,img->num_elements_freq*img->num_channels,img->num_data);
	
	Eigen::ArrayXXcd temp1 = Eigen::ArrayXXcd::Zero(img->num_elements_freq,img->num_channels);
	Eigen::ArrayXXcd temp2 = Eigen::ArrayXXcd::Zero(img->num_elements_freq,img->num_channels);
	Eigen::Vector2i num_blocks_1, num_blocks_2;
	
	num_blocks_1 << img->num_channels,img->num_channels;
	num_blocks_2 << img->num_channels,1;
	
	for (int k=0;k<img->num_data;k++){
        
        temp2 = X.block(0,k,img->num_elements_freq*img->num_channels,1).array();
        temp2.resize(img->num_elements_freq,img->num_channels);
        fusion_matrix_multiply(temp1, img->Sinv, temp2, num_blocks_1, num_blocks_2);
        temp1.resize(img->num_elements_freq*img->num_channels,1);
        Y.block(0,k,img->num_elements_freq*img->num_channels,1) = temp1.matrix();
        temp1.resize(img->num_elements_freq,img->num_channels);
        
		if (img->labels[k] == 1)
		{
			u(k) = std::complex<double>(params->wpos,0);
		}
		else
		{
			u(k) = std::complex<double>(-1,0);
		}
	}
	
	esvm::SVMClassifier libsvm;
	
	libsvm.setC(params->C);
	libsvm.setKernel(params->kernel_type);
	libsvm.setWpos(params->wpos);
	
	temp = (X.conjugate().transpose()*Y).real();
	Eigen::Map<Eigen::MatrixXd> y(img->labels,img->num_data,1);
	
	libsvm.train(temp, y);
	temp.resize(0,0);
	
	int nSV;
	libsvm.getNSV(&nSV);
	Eigen::VectorXi sv_indices = Eigen::VectorXi::Zero(nSV);
	Eigen::VectorXd sv_coef = Eigen::VectorXd::Zero(nSV);
	libsvm.getSI(sv_indices);
	libsvm.getCoeff(sv_coef);
	
	for (int k=0; k<nSV; k++) {
		filt_freq += (Y.block(0,sv_indices[k]-1,img->num_elements_freq*img->num_channels,1)*sv_coef[k]).array();
	}
	
	Y.resize(0,0);
	
	Eigen::Map<Eigen::ArrayXcd>(filt->filter.data_freq,img->num_elements_freq*img->num_channels) = filt_freq;
	filt->filter.num_data = 1;
	filt->filter.num_channels = img->num_channels;
	filt->filter.ptr_data.reserve(filt->filter.num_data);
	filt->filter.ptr_data_freq.reserve(filt->filter.num_data);
	ifft_data(&filt->filter);
    fft_data(&filt->filter);
}
void CCorrelationFilters::build_otsdf(struct CDataStruct *img, struct CParamStruct *params, struct CFilterStruct *filt)
{
    /*
	 * This function implements the correlation filter design proposed in the following publications.
	 * 
     * [1] Optimal trade-off synthetic discriminant function filters for arbitrary devices, B.V.K.Kumar, D.W.Carlson, A.Mahalanobis - Optics Letters, 1994.
	 *
	 * [2] Jason Thornton, "Matching deformed and occluded iris patterns: a probabilistic model based on discriminative cues." PhD thesis, Carnegie Mellon University, Pittsburgh, PA, USA, 2007.
	 *
	 * [3] Vishnu Naresh Boddeti, Jonathon M Smereka, and B. V. K. Vijaya Kumar, "A comparative evaluation of iris and ocular recognition methods on challenging ocular images." IJCB, 2011.
	 *
     * [4] A. Mahalanobis, B.V.K. Kumar, D. Casasent, "Minimum average correlation energy filters," Applied Optics, 1987
     *
	 * Notes: This filter design is good when the dimensionality of the data is greater than the training sample size. Setting the filter parameter params->alpha=0 results in the popular MACE filter. However, it is usually better to set alpha to a small number rather than setting it to 0. If you use MACE cite [4].
	 */

	filt->params = *params;
	filt->filter.size_data = params->size_filt_freq;
	filt->filter.size_data_freq = params->size_filt_freq;

	filt->filter.num_elements_freq = img->num_elements_freq;
	params->num_elements_freq = img->num_elements_freq;
	filt->filter.data_freq = new complex<double>[img->num_elements_freq*img->num_channels];
	
	Eigen::ArrayXcd filt_freq = Eigen::ArrayXcd::Zero(params->num_elements_freq*img->num_channels);
	
	// If not set default to 1
	if (params->wpos < 1) params->wpos = 1;
	filt->params.wpos = params->wpos;
	
	compute_psd_matrix(img, params);
	Eigen::MatrixXcd Y = Eigen::MatrixXcd::Zero(img->num_elements_freq*img->num_channels,img->num_data);
	Eigen::MatrixXcd u = Eigen::MatrixXcd::Zero(img->num_data,1);
	Eigen::MatrixXcd temp = Eigen::MatrixXcd::Zero(img->num_data,img->num_data);
	Eigen::MatrixXd tmp = Eigen::MatrixXd::Zero(img->num_data,img->num_data);
	
	Eigen::Map<Eigen::MatrixXcd> X(img->data_freq,img->num_elements_freq*img->num_channels,img->num_data);
	
	Eigen::ArrayXXcd temp1 = Eigen::ArrayXXcd::Zero(img->num_elements_freq,img->num_channels);
	Eigen::ArrayXXcd temp2 = Eigen::ArrayXXcd::Zero(img->num_elements_freq,img->num_channels);
	Eigen::Vector2i num_blocks_1, num_blocks_2;
	
	num_blocks_1 << img->num_channels,img->num_channels;
	num_blocks_2 << img->num_channels,1;
	
	for (int k=0;k<img->num_data;k++){
        temp2 = X.block(0,k,img->num_elements_freq*img->num_channels,1).array();
        temp2.resize(img->num_elements_freq,img->num_channels);
        fusion_matrix_multiply(temp1, img->Sinv, temp2, num_blocks_1, num_blocks_2);
        temp1.resize(img->num_elements_freq*img->num_channels,1);
        Y.block(0,k,img->num_elements_freq*img->num_channels,1) = temp1.matrix();
        temp1.resize(img->num_elements_freq,img->num_channels);
        
		if (img->labels[k] == 1)
		{
			u(k) = std::complex<double>(params->wpos,0);
		}
		else
		{
			u(k) = std::complex<double>(1,0);
		}
	}

	temp = X.conjugate().transpose()*Y;
	temp = temp.ldlt().solve(u);
	filt_freq = Y*temp;
	
	Y.resize(0,0);
	
	Eigen::Map<Eigen::ArrayXcd>(filt->filter.data_freq,img->num_elements_freq*img->num_channels) = filt_freq;
	filt->filter.num_data = 1;
	filt->filter.num_channels = img->num_channels;
	filt->filter.ptr_data.reserve(filt->filter.num_data);
	filt->filter.ptr_data_freq.reserve(filt->filter.num_data);
	ifft_data(&filt->filter);
    fft_data(&filt->filter);
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void LapH::OperatorsForMesons::build_rvdaggervr(
                                            const LapH::RandomVector& rnd_vec) {

  // check of vdaggerv is already build
  if(not is_vdaggerv_set){
    std::cout << "\n\n\tCaution: vdaggerv is not set and rvdaggervr cannot be" 
              << " computed\n\n" << std::endl;
    exit(0);
  }

  clock_t t2 = clock();
  std::cout << "\tbuild rvdaggervr:";

  for(auto& rvdvr_level1 : rvdaggervr)
    for(auto& rvdvr_level2 : rvdvr_level1)
      for(auto& rvdvr_level3 : rvdvr_level2)
        rvdvr_level3 = Eigen::MatrixXcd::Zero(4*dilE, 4*dilE);

#pragma omp parallel for schedule(dynamic)
  for(size_t t = 0; t < Lt; t++){

  // rvdaggervr is calculated by multiplying vdaggerv with the same quantum
  // numbers with random vectors from right and left.
  for(const auto& op : operator_lookuptable.rvdaggervr_lookuptable){

    Eigen::MatrixXcd vdv;
    if(op.need_vdaggerv_daggering == false)
      vdv = vdaggerv[op.id_vdaggerv][t];
    else
      vdv = vdaggerv[op.id_vdaggerv][t].adjoint();

    size_t rid = 0;
    int check = -1;
    Eigen::MatrixXcd M; // Intermediate memory
    for(const auto& rnd_id : 
              operator_lookuptable.ricQ2_lookup[op.id_ricQ_lookup].rnd_vec_ids){

      if(check != rnd_id.first){ // this avoids recomputation
        M = Eigen::MatrixXcd::Zero(nb_ev, 4*dilE);
        for(size_t block = 0; block < 4; block++){
        for(size_t vec_i = 0; vec_i < nb_ev; vec_i++) {
          size_t blk =  block + (vec_i + nb_ev * t) * 4;
          M.block(0, vec_i%dilE + dilE*block, nb_ev, 1) += 
               vdv.col(vec_i) * rnd_vec(rnd_id.first, blk);
        }}
      }
      for(size_t block_x = 0; block_x < 4; block_x++){
      for(size_t block_y = 0; block_y < 4; block_y++){
      for(size_t vec_y = 0; vec_y < nb_ev; ++vec_y) {
        size_t blk =  block_y + (vec_y + nb_ev * t) * 4;
        rvdaggervr[op.id][t][rid].block(
                            dilE*block_y + vec_y%dilE, dilE*block_x, 1, dilE) +=
                M.block(vec_y, dilE*block_x, 1, dilE) * 
                std::conj(rnd_vec(rnd_id.second, blk));
      }}} 
      check = rnd_id.first;
      rid++;
    }
  }}// time and operator loops end here

  t2 = clock() - t2;
  std::cout << std::setprecision(1) << "\t\tSUCCESS - " << std::fixed 
    << ((float) t2)/CLOCKS_PER_SEC << " seconds" << std::endl;
}
Beispiel #5
0
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void LapH::Quarklines::build_Q2L(const Perambulator& peram,
               const OperatorsForMesons& meson_operator,
               const std::vector<QuarklineQ2Indices>& ql_lookup,
               const std::vector<RandomIndexCombinationsQ2>& ric_lookup){

  std::cout << "\tcomputing Q2L:";
  clock_t time = clock();
#pragma omp parallel 
  {
  Eigen::MatrixXcd M = Eigen::MatrixXcd::Zero(4 * dilE, 4 * nev);

  for(size_t t1 = 0; t1 < Lt; t1++){                  
  for(size_t t2 = 0; t2 < Lt/dilT; t2++){
    for(size_t op = 0; op < ql_lookup.size(); op++){ 
      size_t nb_rnd = ric_lookup[(ql_lookup[op]).
                                 id_ric_lookup].rnd_vec_ids.size();
      for(size_t rnd1 = 0; rnd1 < nb_rnd; rnd1++){
        Q2L[t1][t2][op][rnd1].setZero(); 
      } 
    }               
  }}              

#pragma omp for schedule(dynamic)
  for(size_t t1 = 0; t1 < Lt; t1++){                  
  for(const auto& qll : ql_lookup){
    size_t rnd_counter = 0;
    int check = -1;
    for(const auto& rnd_id : ric_lookup[qll.id_ric_lookup].rnd_vec_ids){
      if(check != rnd_id.first){ // this avoids recomputation
        for(size_t row = 0; row < 4; row++){
        for(size_t col = 0; col < 4; col++){
          if(!qll.need_vdaggerv_dag)
            M.block(col*dilE, row*nev, dilE, nev) =
              peram[rnd_id.first].block((t1*4 + row)*nev, 
                                        (t1/dilT*4 + col)*dilE, 
                                        nev, dilE).adjoint() *
              meson_operator.return_vdaggerv(qll.id_vdaggerv, t1);
          else
            M.block(col*dilE, row*nev, dilE, nev) =
              peram[rnd_id.first].block((t1*4 + row)*nev, 
                                        (t1/dilT*4 + col)*dilE, 
                                        nev, dilE).adjoint() *
              meson_operator.return_vdaggerv(qll.id_vdaggerv, t1).adjoint();
          // gamma_5 trick
          if( ((row + col) == 3) || (abs(row - col) > 1) )
            M.block(col*dilE, row*nev, dilE, nev) *= -1.;
        }}
      }
      for(size_t t2 = 0; t2 < Lt/dilT; t2++){
        Q2L[t1][t2][qll.id][rnd_counter].setZero(4*dilE, 4*dilE);

        const size_t gamma_id = qll.gamma[0]; 

        for(size_t block_dil = 0; block_dil < 4; block_dil++) {
          const cmplx value = gamma[gamma_id].value[block_dil];
          const size_t gamma_index = gamma[gamma_id].row[block_dil];
          for(size_t row = 0; row < 4; row++){
          for(size_t col = 0; col < 4; col++){

          Q2L[t1][t2][qll.id][rnd_counter].
                        block(row*dilE, col*dilE, dilE, dilE) +=
               value * 
               M.block(row*dilE, block_dil*nev, dilE, nev) *
               peram[rnd_id.second].block(
                          (t1*4 + gamma_index)*nev, 
                          (t2*4 + col)*dilE, nev, dilE);

          }}
        }
      }
      check = rnd_id.first;
      rnd_counter++;
    }
  }}
} // pragma omp ends

  time = clock() - time;
  std::cout << "\t\t\tSUCCESS - " << ((float) time) / CLOCKS_PER_SEC 
            << " seconds" << std::endl;
}
Beispiel #6
0
void BasicOperator::init_operator(const char dilution,
                                  const LapH::VdaggerV& vdaggerv, 
                                  const LapH::Perambulator& peram){

  const int Lt = global_data->get_Lt();
  const size_t nb_ev = global_data->get_number_of_eigen_vec();
  const std::vector<quark> quarks = global_data->get_quarks();
  const size_t nb_rnd = quarks[0].number_of_rnd_vec;
  const size_t dilE = quarks[0].number_of_dilution_E;
  const int dilT = quarks[0].number_of_dilution_T;
  const size_t Q2_size = 4 * dilE;
  
  const vec_pdg_Corr op_Corr = global_data->get_lookup_corr();

  const size_t nb_op = op_Corr.size();

  std::cout << "\n" << std::endl;
  clock_t time = clock();
  #pragma omp parallel 
  {
  Eigen::MatrixXcd M = Eigen::MatrixXcd::Zero(Q2_size, 4 * nb_ev);
  #pragma omp for schedule(dynamic)
  for(int t_0 = 0; t_0 < Lt; t_0++){

    if(omp_get_thread_num() == 0)
      std::cout << "\tcomputing double quarkline: " 
                << std::setprecision(2) << (float) t_0/Lt*100 << "%\r" 
                << std::flush;

    for(const auto& op : op_Corr){

      for(size_t rnd_i = 0; rnd_i < nb_rnd; ++rnd_i) {
        for(int t = 0; t < Lt/dilT; t++){
          // new momentum -> recalculate M[0]
          // M only depends on momentum and displacement. first_vdv 
          // prevents repeated calculation for different gamma structures
          if(op.first_vdv == true){

            for(size_t col = 0; col < 4; ++col) {
            for(size_t row = 0; row < 4; ++row) {
              if(op.negative_momentum == false){
                M.block(dilE * col, nb_ev * row, dilE, nb_ev) = 
                  (peram(1, rnd_i).block(nb_ev * (4 * t_0 + row), 
                                      dilE * (4 * t + col), 
                                      nb_ev, dilE)).adjoint() *
                  vdaggerv.return_vdaggerv(op.id_vdv, t_0);
              }
              else {
                M.block(dilE * col, nb_ev * row, dilE, nb_ev) = 
                  (peram(1, rnd_i).block(nb_ev * (4 * t_0 + row), 
                                      dilE * (4 * t + col), 
                                      nb_ev, dilE)).adjoint() *
                  // TODO: calculate V^daggerV Omega from op.negative_momentum 
                  // == false and multiply Omega from the left
                  // and then (V^daggerV Omega)^dagger * Omega
                  (vdaggerv.return_vdaggerv(op.id_vdv, t_0)).adjoint();
              }  

              // gamma_5 trick. It changes the sign of the two upper right and two
              // lower left blocks in dirac space
              if( ((row + col) == 3) || (abs(row - col) > 1) )
                M.block(dilE * col, row * nb_ev, dilE, nb_ev) *= -1.;
            }}// loops over row and col end here
          }//if over same gamma structure ends here

          for(int ti = 0; ti < 3; ti++){
          // getting the neighbour blocks
          const int tend = (Lt/dilT+t + ti - 1)%(Lt/dilT);  
          for(size_t rnd_j = 0; rnd_j < nb_rnd; ++rnd_j) {
            if(rnd_i != rnd_j){

              //dilution of d-quark from left
              for(size_t block_dil = 0; block_dil < 4; block_dil++){
                cmplx value = 1.;
                value_dirac(op.id, block_dil, value);

                  for(size_t col = 0; col < 4; col++){
                  for(size_t row = 0; row < 4; row++){

                    Q2[t_0][t][ti][op.id][rnd_i][rnd_j]
                        .block(row*dilE, col*dilE, dilE, dilE) += value * 
                      M.block(row*dilE, block_dil* nb_ev, dilE, nb_ev) * 
                      peram(0, rnd_j)
                        .block(4*nb_ev*t_0 + order_dirac(op.id, block_dil)*nb_ev, 
                          Q2_size*tend + col*dilE, nb_ev, dilE);

              }}}//dilution ends here

          }}}// loops over rnd_j and ti block end here 
        }// loop over t ends here
      }// loop over rnd_i ends here
    }//loop operators
  }// loops over t_0 ends here
  }// pragma omp ends

  std::cout << "\tcomputing double quarkline: 100.00%" << std::endl;
  time = clock() - time;
  std::cout << "\t\tSUCCESS - " << ((float) time) / CLOCKS_PER_SEC 
            << " seconds" << std::endl;
}