//fix phase of eigensystem and store phase of first entry of each eigenvector void fix_phase(Eigen::MatrixXcd& V, Eigen::MatrixXcd& V_fix, std::vector<double>& phase) { const int V3 = pars -> get_int("V3"); //helper variables: //Number of eigenvectors int n_ev; //negative imaginary std::complex<double> i_neg (0,-1); //tmp factor and phase std::complex<double> fac (1.,1.); double tmp_phase = 0; //get sizes right, resize if necessary n_ev = V.cols(); if (phase.size() != n_ev) phase.resize(n_ev); if (V_fix.cols() != n_ev) V_fix.resize(3*V3,n_ev); //loop over all eigenvectors of system for (int n = 0; n < n_ev; ++n) { tmp_phase = std::arg(V(0,n)); phase.at(n) = tmp_phase; fac = std::exp(i_neg*tmp_phase); //Fix phase of eigenvector with negative polar angle of first entry V_fix.col(n) = fac * V.col(n); } }
//TODO complex values as matrix entries too //TODO support endomorphisms over Rn too Expression EigenvectorsCommand::operator()(const QList< Analitza::Expression >& args) { Expression ret; QStringList errors; const Eigen::MatrixXcd eigeninfo = executeEigenSolver(args, true, errors); if (!errors.isEmpty()) { ret.addError(errors.first()); return ret; } const int neigenvectors = eigeninfo.rows(); QScopedPointer<Analitza::List> list(new Analitza::List); for (int j = 0; j < neigenvectors; ++j) { const Eigen::VectorXcd col = eigeninfo.col(j); QScopedPointer<Analitza::Vector> eigenvector(new Analitza::Vector(neigenvectors)); for (int i = 0; i < neigenvectors; ++i) { const std::complex<double> eigenvalue = col(i); const double realpart = eigenvalue.real(); const double imagpart = eigenvalue.imag(); if (std::isnan(realpart) || std::isnan(imagpart)) { ret.addError(QCoreApplication::tr("Returned eigenvalue is NaN", "NaN means Not a Number, is an invalid float number")); return ret; } else if (std::isinf(realpart) || std::isinf(imagpart)) { ret.addError(QCoreApplication::tr("Returned eigenvalue is too big")); return ret; } else { bool isonlyreal = true; if (std::isnormal(imagpart)) { isonlyreal = false; } Analitza::Cn * eigenvalueobj = 0; if (isonlyreal) { eigenvalueobj = new Analitza::Cn(realpart); } else { eigenvalueobj = new Analitza::Cn(realpart, imagpart); } eigenvector->appendBranch(eigenvalueobj); } } list->appendBranch(eigenvector.take()); } ret.setTree(list.take()); return ret; }
// ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- void LapH::OperatorsForMesons::build_rvdaggerv( const LapH::RandomVector& rnd_vec) { // check if 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 rvdaggerv:"; for(auto& rvdv_level1 : rvdaggerv) for(auto& rvdv_level2 : rvdv_level1) for(auto& rvdv_level3 : rvdv_level2) rvdv_level3 = Eigen::MatrixXcd::Zero(4*dilE, nb_ev); #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.rvdaggerv_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; for(const auto& rnd_id : operator_lookuptable.ricQ1_lookup[op.id_ricQ_lookup].rnd_vec_ids){ 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 * 4 + 4 * nb_ev * t; rvdaggerv[op.id][t][rid].block(vec_i%dilE + dilE*block, 0, 1, nb_ev) += vdv.row(vec_i) * std::conj(rnd_vec(rnd_id, blk)); }} 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; }
//Reads in Eigenvectors from one Timeslice in binary format to V void read_evectors_bin_ts(const char * path, const char* prefix, const int config_i, const int t, const int nb_ev, Eigen::MatrixXcd& V) { int V3 = pars -> get_int("V3"); //bool thorough = pars -> get_int("strict"); const int dim_row = 3 * V3; //TODO: Change path getting to something keyword independent //buffer for read in std::complex<double>* eigen_vec = new std::complex<double>[dim_row]; //setting up file char filename[200]; sprintf(filename, "%s/%s.%04d.%03d", path, prefix, config_i, t); std::cout << "Reading file: " << filename << std::endl; std::ifstream infile(filename, std::ifstream::binary); for (int nev = 0; nev < nb_ev; ++nev) { infile.read( reinterpret_cast<char*> (eigen_vec), 2*dim_row*sizeof(double)); V.col(nev) = Eigen::Map<Eigen::VectorXcd, 0 >(eigen_vec, dim_row); eof_check(t,nev,nb_ev,infile.eof()); } if(check_trace(V, nb_ev) != true){ std::cout << "Timeslice: " << t << ": Eigenvectors damaged, exiting" << std::endl; exit(0); } //clean up delete[] eigen_vec; infile.close(); }
void write_eig_sys_bin(const char* prefix, const int config_i, const int t, const int nb_ev, Eigen::MatrixXcd& V) { const int V3 = pars -> get_int("V3"); std::string path = pars -> get_path("res"); //set up filename char file [200]; sprintf(file, "%s/%s.%04d.%03d", path.c_str(), prefix, config_i, t); //sprintf(file, "%s.%04d.%03d", prefix, config_i, t); if(check_trace(V, nb_ev) != true){ std::cout << "Timeslice: " << t << ": Eigenvectors damaged, abort writing" << std::endl; exit(1); } std::cout << "Writing to file:" << file << std::endl; std::ofstream outfile(file, std::ofstream::binary); std::streamsize begin = outfile.tellp(); std::streamsize eigsys_bytes =2*3*V3*nb_ev*sizeof(double); outfile.write(reinterpret_cast<char*> (V.data()), eigsys_bytes); std::streamsize end = outfile.tellp(); if ( (end - begin)/eigsys_bytes != 1 ){ std::cout << "Timeslice: " << t << " Error: write incomplete, exiting" << std::endl; std::cout << (end-begin) << " bytes instead of expected "<< eigsys_bytes << " bytes" << std::endl; exit(1); } //std::cout << end - begin << " bytes written" << std::endl; outfile.close(); }
int main(int argc, char ** argv) { // initialize parameters ///////////////////////////////////////////////////// Parameters p; #ifdef DEBUG cout << "Memory usage of p: " << sizeof(p) << " bytes." << endl; Eigen::MatrixXcd H = p.Ham(); cout << "size of Hamiltonian: " << H.rows() << "x" << H.cols() << endl; cout << "Hamiltonian: " << H << endl; cout << "Second element of Hamiltonian: " << p.Ham(0,1) << endl; #endif // propagate ///////////////////////////////////////////////////////////////// return 0; }
// TODO: work on interface with eigenvector class // transform matrix of eigenvectors with gauge array Eigen::MatrixXcd GaugeField::trafo_ev(const Eigen::MatrixXcd &eig_sys) { const ssize_t dim_row = eig_sys.rows(); const ssize_t dim_col = eig_sys.cols(); Eigen::MatrixXcd ret(dim_row, dim_col); if (omega.shape()[0] == 0) build_gauge_array(1); // write_gauge_matrices("ev_trafo_log.bin",Omega); for (ssize_t nev = 0; nev < dim_col; ++nev) { for (ssize_t vol = 0; vol < dim_row; ++vol) { int ind_c = vol % 3; Eigen::Vector3cd tmp = omega[0][ind_c].adjoint() * (eig_sys.col(nev)).segment(ind_c, 3); (ret.col(nev)).segment(ind_c, 3) = tmp; } // end loop nev } // end loop vol return ret; }
// This returns a matrix that is the lower-triangular part (only column // index <= row index) of the square of matrixToSquare. Eigen::MatrixXcd SymmetricComplexMassMatrix::LowerTriangleOfSquareMatrix( Eigen::MatrixXcd const& matrixToSquare ) const { Eigen::MatrixXcd valuesSquaredMatrix( numberOfRows, numberOfRows ); for( size_t rowIndex( 0 ); rowIndex < numberOfRows; ++rowIndex ) { for( size_t columnIndex( 0 ); columnIndex <= rowIndex; ++columnIndex ) { valuesSquaredMatrix.coeffRef( rowIndex, columnIndex ).real(0.0); valuesSquaredMatrix.coeffRef( rowIndex, columnIndex ).imag(0.0); for( size_t sumIndex( 0 ); sumIndex < numberOfRows; ++sumIndex ) { double temp = valuesSquaredMatrix.coeffRef( rowIndex, columnIndex ).real() + ( ( matrixToSquare.coeff( sumIndex, rowIndex ).real() * matrixToSquare.coeff( sumIndex, columnIndex ).real() ) + ( matrixToSquare.coeff( sumIndex, rowIndex ).imag() * matrixToSquare.coeff( sumIndex, columnIndex ).imag() ) ); valuesSquaredMatrix.coeffRef( rowIndex, columnIndex ).real(temp); temp = valuesSquaredMatrix.coeffRef( rowIndex, columnIndex ).imag() + ( ( matrixToSquare.coeff( sumIndex, rowIndex ).real() * matrixToSquare.coeff( sumIndex, columnIndex ).imag() ) - ( matrixToSquare.coeff( sumIndex, rowIndex ).imag() * matrixToSquare.coeff( sumIndex, columnIndex ).real() ) ); valuesSquaredMatrix.coeffRef( rowIndex, columnIndex ).imag(temp); // The Eigen routines don't bother looking at elements of // valuesSquaredMatrix where columnIndex > rowIndex, so we don't even // bother filling them with the conjugates of the transpose. } } } return valuesSquaredMatrix; }
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); } } } }
int main() { const int dim_row = MAT_ENTRIES; const int dim_col = 120;// number of eigenvectors //Set up data structure Eigen::MatrixXcd V; Eigen::MatrixXcd V_dagger; Eigen::MatrixXcd S; V = Eigen::MatrixXcd::Zero( dim_row, dim_col); V_dagger = Eigen::MatrixXcd::Zero( dim_row, dim_col); S = Eigen::MatrixXcd::Zero( dim_row, dim_col); read_eigenvectors_from_binary_ts("eigenvectors", 600, 0, V); //read_eigenvectors_from_binary_ts("eigenvectors", 600, 0); std::cout << "Calculating v v_dagger" << std::endl; V_dagger = V.adjoint(); for(int i = 0; i < dim_row; ++i ){ for(int j = 0; j < dim_col; ++j) { //std::complex<double> entry = V.row(i) * V_dagger.col(j); if (std::abs(V(i,j)) > 1e-15) std::cout << i << " " << j << " " << V(i,j) << std::endl; } } }
static bool check_trace(const Eigen::MatrixXcd& V, const int nb_ev){ bool read_state = true; Eigen::MatrixXcd VdV(nb_ev,nb_ev); VdV = V.adjoint() * V; double eps = 10e-10; std::complex<double> trace (0.,0.), sum(0.,0.); trace = VdV.trace(); sum = VdV.sum(); std::cout << trace.real() << std::endl; if ( fabs( trace.real()) - nb_ev > eps || fabs(trace.imag()) > eps || fabs(sum.real()) - nb_ev > eps || fabs(sum.imag()) > eps) read_state = false; return read_state; }
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); }
std::string cmplxMatrixString(const Eigen::MatrixXcd& m) { // Make a string from the bytes return std::string((char *) m.data(), m.size() * sizeof(m(0, 0))); }
inline int size_pn() const { return coef_iat_ipn.cols(); }
inline int size_at() const { return coef_iat_ipn.rows(); }
// ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- 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; }
// ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- 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; }
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 LapH::distillery::create_source(const size_t dil_t, const size_t dil_e, std::complex<double>* source) { if(dil_t >= param.dilution_size_so[0] || dil_e >= param.dilution_size_so[1] ){ std::cout << "dilution is out of bounds in \"create_source\"" << std::endl; exit(0); } const size_t Lt = param.Lt; const size_t Ls = param.Ls; const size_t number_of_eigen_vec = param.nb_ev; const size_t Vs = Ls*Ls*Ls; const size_t dim_row = Vs*3; int numprocs = 0, myid = 0; MPI_Comm_size(MPI_COMM_WORLD, &numprocs); MPI_Comm_rank(MPI_COMM_WORLD, &myid); // setting source to zero for(size_t dil_d = 0; dil_d < param.dilution_size_so[2]; ++dil_d) for(size_t i = 0; i < 12*Vs*Lt/numprocs; ++i) source[dil_d*12*Vs*Lt/numprocs + i] = {0.0, 0.0}; // indices of timeslices with non-zero entries size_t nb_of_nonzero_t = Lt/param.dilution_size_so[0]; // TODO: think about smart pointer here! size_t* t_index = new size_t[nb_of_nonzero_t]; create_dilution_lookup(nb_of_nonzero_t, param.dilution_size_so[0], dil_t, param.dilution_type_so[0], t_index); // indices of eigenvectors to be combined size_t nb_of_ev_combined = number_of_eigen_vec/param.dilution_size_so[1]; size_t* ev_index = new size_t[nb_of_ev_combined]; create_dilution_lookup(nb_of_ev_combined, param.dilution_size_so[1], dil_e, param.dilution_type_so[1], ev_index); // indices of Dirac components to be combined // TODO: This is needed only once - could be part of class size_t nb_of_dirac_combined = 4/param.dilution_size_so[2]; size_t** d_index = new size_t*[param.dilution_size_so[2]]; for(size_t i = 0; i < param.dilution_size_so[2]; ++i) d_index[i] = new size_t[nb_of_dirac_combined]; for(size_t dil_d = 0; dil_d < param.dilution_size_so[2]; ++dil_d) create_dilution_lookup(nb_of_dirac_combined, param.dilution_size_so[2], dil_d, param.dilution_type_so[2], d_index[dil_d]); // creating the source // running over nonzero timeslices for(size_t t = 0; t < nb_of_nonzero_t; ++t){ // intermidiate memory Eigen::MatrixXcd S = Eigen::MatrixXcd::Zero(dim_row, 4); size_t time = t_index[t]; // helper index if((int) (time / (Lt/numprocs)) == myid) { size_t time_id = time % (Lt/numprocs); // helper index // building source on one timeslice for(size_t ev = 0; ev < nb_of_ev_combined; ++ev){ size_t ev_h = ev_index[ev] * 4; // helper index for(size_t d = 0; d < 4; ++d){ S.col(d) += random_vector[time](ev_h+d) * (V[time_id]).col(ev_index[ev]); } } // copy the created source into output array size_t t_h = time_id*Vs; // helper index for(size_t x = 0; x < Vs; ++x){ size_t x_h = (t_h + x)*12; // helper index size_t x_h2 = x*3; // helper index for(size_t d2 = 0; d2 < param.dilution_size_so[2]; ++d2){ for(size_t d3 = 0; d3 < nb_of_dirac_combined; ++d3){ size_t d_h = x_h + d_index[d2][d3]*3; // helper index for(size_t c = 0; c < 3; ++c){ source[d2*12*Vs*Lt/numprocs + d_h + c] = S(x_h2 + c, d_index[d2][d3]); } } } } } } // end of loop over nonzero timeslices MPI_Barrier(MPI_COMM_WORLD); // freeing memory delete[] t_index; delete[] ev_index; for(size_t i = 0; i < param.dilution_size_so[2]; ++i) delete[] d_index[i]; delete[] d_index; t_index = NULL; ev_index = NULL; d_index = NULL; }
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; }