void call_ref() { VectorXcf ca = VectorXcf::Random(10); VectorXf a = VectorXf::Random(10); RowVectorXf b = RowVectorXf::Random(10); MatrixXf A = MatrixXf::Random(10,10); RowVector3f c = RowVector3f::Random(); const VectorXf& ac(a); VectorBlock<VectorXf> ab(a,0,3); const VectorBlock<VectorXf> abc(a,0,3); VERIFY_EVALUATION_COUNT( call_ref_1(a,a), 0); VERIFY_EVALUATION_COUNT( call_ref_1(b,b.transpose()), 0); // call_ref_1(ac,a<c); // does not compile because ac is const VERIFY_EVALUATION_COUNT( call_ref_1(ab,ab), 0); VERIFY_EVALUATION_COUNT( call_ref_1(a.head(4),a.head(4)), 0); VERIFY_EVALUATION_COUNT( call_ref_1(abc,abc), 0); VERIFY_EVALUATION_COUNT( call_ref_1(A.col(3),A.col(3)), 0); // call_ref_1(A.row(3),A.row(3)); // does not compile because innerstride!=1 VERIFY_EVALUATION_COUNT( call_ref_3(A.row(3),A.row(3).transpose()), 0); VERIFY_EVALUATION_COUNT( call_ref_4(A.row(3),A.row(3).transpose()), 0); // call_ref_1(a+a, a+a); // does not compile for obvious reason MatrixXf tmp = A*A.col(1); VERIFY_EVALUATION_COUNT( call_ref_2(A*A.col(1), tmp), 1); // evaluated into a temp VERIFY_EVALUATION_COUNT( call_ref_2(ac.head(5),ac.head(5)), 0); VERIFY_EVALUATION_COUNT( call_ref_2(ac,ac), 0); VERIFY_EVALUATION_COUNT( call_ref_2(a,a), 0); VERIFY_EVALUATION_COUNT( call_ref_2(ab,ab), 0); VERIFY_EVALUATION_COUNT( call_ref_2(a.head(4),a.head(4)), 0); tmp = a+a; VERIFY_EVALUATION_COUNT( call_ref_2(a+a,tmp), 1); // evaluated into a temp VERIFY_EVALUATION_COUNT( call_ref_2(ca.imag(),ca.imag()), 1); // evaluated into a temp VERIFY_EVALUATION_COUNT( call_ref_4(ac.head(5),ac.head(5)), 0); tmp = a+a; VERIFY_EVALUATION_COUNT( call_ref_4(a+a,tmp), 1); // evaluated into a temp VERIFY_EVALUATION_COUNT( call_ref_4(ca.imag(),ca.imag()), 0); VERIFY_EVALUATION_COUNT( call_ref_5(a,a), 0); VERIFY_EVALUATION_COUNT( call_ref_5(a.head(3),a.head(3)), 0); VERIFY_EVALUATION_COUNT( call_ref_5(A,A), 0); // call_ref_5(A.transpose(),A.transpose()); // does not compile because storage order does not match VERIFY_EVALUATION_COUNT( call_ref_5(A.block(1,1,2,2),A.block(1,1,2,2)), 0); VERIFY_EVALUATION_COUNT( call_ref_5(b,b), 0); // storage order do not match, but this is a degenerate case that should work VERIFY_EVALUATION_COUNT( call_ref_5(a.row(3),a.row(3)), 0); VERIFY_EVALUATION_COUNT( call_ref_6(a,a), 0); VERIFY_EVALUATION_COUNT( call_ref_6(a.head(3),a.head(3)), 0); VERIFY_EVALUATION_COUNT( call_ref_6(A.row(3),A.row(3)), 1); // evaluated into a temp thouth it could be avoided by viewing it as a 1xn matrix tmp = A+A; VERIFY_EVALUATION_COUNT( call_ref_6(A+A,tmp), 1); // evaluated into a temp VERIFY_EVALUATION_COUNT( call_ref_6(A,A), 0); VERIFY_EVALUATION_COUNT( call_ref_6(A.transpose(),A.transpose()), 1); // evaluated into a temp because the storage orders do not match VERIFY_EVALUATION_COUNT( call_ref_6(A.block(1,1,2,2),A.block(1,1,2,2)), 0); VERIFY_EVALUATION_COUNT( call_ref_7(c,c), 0); }
FiffEvoked MNEEpochDataList::average(FiffInfo& info, fiff_int_t first, fiff_int_t last, VectorXi sel, bool proj) { FiffEvoked p_evoked; printf("Calculate evoked... "); MatrixXd matAverage; if(this->size() > 0) matAverage = MatrixXd::Zero(this->at(0)->epoch.rows(), this->at(0)->epoch.cols()); else { p_evoked.aspect_kind = FIFFV_ASPECT_STD_ERR; return p_evoked; } if(sel.size() > 0) { p_evoked.nave = sel.size(); for(qint32 i = 0; i < sel.size(); ++i) matAverage.array() += this->at(sel(i))->epoch.array(); } else { p_evoked.nave = this->size(); for(qint32 i = 0; i < this->size(); ++i) matAverage.array() += this->at(i)->epoch.array(); } matAverage.array() /= p_evoked.nave; printf("%d averages used [done]\n ", p_evoked.nave); p_evoked.setInfo(info, proj); p_evoked.aspect_kind = FIFFV_ASPECT_AVERAGE; p_evoked.first = first; p_evoked.last = last; RowVectorXf times = RowVectorXf(last-first+1); for (qint32 k = 0; k < times.size(); ++k) times[k] = ((float)(first+k)) / info.sfreq; p_evoked.times = times; p_evoked.comment = QString::number(this->at(0)->event); if(p_evoked.proj.rows() > 0) { matAverage = p_evoked.proj * matAverage; printf("\tSSP projectors applied to the evoked data\n"); } p_evoked.data = matAverage; return p_evoked; }
RowVectorXf operator*(const RowVectorXf& o, const SeedFeature& f) { eassert( o.size() == f.static_f_.rows() ); RowVectorXf r( f.static_f_.cols() + f.dynamic_f_.cols() ); r.head(f.static_f_.cols()) = o * f.static_f_; r.tail(f.dynamic_f_.cols()) = o * f.dynamic_f_; return r; }
void resizeLikeTest() { MatrixXf A(rows, cols); MatrixXf B; Matrix<double, rows, cols> C; B.resizeLike(A); C.resizeLike(B); // Shouldn't crash. VERIFY(B.rows() == rows && B.cols() == cols); VectorXf x(rows); RowVectorXf y; y.resizeLike(x); VERIFY(y.rows() == 1 && y.cols() == rows); y.resize(cols); x.resizeLike(y); VERIFY(x.rows() == cols && x.cols() == 1); }
void SeedFeature::update( int n ) { const float loc_w = 1.0; // compute the dynamic features int o=0; if( N_DYNAMIC_HAS_SEED ) { dynamic_f_(n,o++) = 1; } if( N_DYNAMIC_GEO>=gdist_.size() ) for( int i=0; i<gdist_.size(); i++ ) dynamic_f_.col(o++) = gdist_[i].update( n ).d(); if( N_DYNAMIC_COL ) { RowVectorXf col = col_.row(n); for( int i=0; i<col_.rows(); i++ ) { RowVectorXf cd = (col_.row(i)-col).array().square().matrix(); var_.row(i) += cd; if( N_DYNAMIC_COL >= 11 ) { float c1 = sqrt(cd.head(3).sum()), c2 = sqrt(cd.tail(3).sum()), d = (pos_.row(n).head(2)-pos_.row(i).head(2)).norm(); min_dist_(i,0) = std::min( min_dist_(i,0), c1 ); min_dist_(i,1) = std::min( min_dist_(i,1), c2 ); min_dist_(i,2) = std::min( min_dist_(i,2), c1+loc_w*d ); min_dist_(i,3) = std::min( min_dist_(i,3), c2+loc_w*d ); min_dist_(i,4) = std::min( min_dist_(i,4), d ); } } n_++; if( N_DYNAMIC_COL >= 6 ) { dynamic_f_.middleCols(o,6) = var_ / n_; o += 6; } if( N_DYNAMIC_COL >= 11 ) { dynamic_f_.middleCols(o,5) = min_dist_; o += 5; } } }
bool FiffEvoked::read(QIODevice& p_IODevice, FiffEvoked& p_FiffEvoked, QVariant setno, QPair<QVariant,QVariant> baseline, bool proj, fiff_int_t p_aspect_kind) { p_FiffEvoked.clear(); // // Open the file // FiffStream::SPtr t_pStream(new FiffStream(&p_IODevice)); QString t_sFileName = t_pStream->streamName(); printf("Reading %s ...\n",t_sFileName.toUtf8().constData()); FiffDirTree t_Tree; QList<FiffDirEntry> t_Dir; if(!t_pStream->open(t_Tree, t_Dir)) return false; // // Read the measurement info // FiffInfo info; FiffDirTree meas; if(!t_pStream->read_meas_info(t_Tree, info, meas)) return false; info.filename = t_sFileName; //move fname storage to read_meas_info member function // // Locate the data of interest // QList<FiffDirTree> processed = meas.dir_tree_find(FIFFB_PROCESSED_DATA); if (processed.size() == 0) { qWarning("Could not find processed data"); return false; } // QList<FiffDirTree> evoked_node = meas.dir_tree_find(FIFFB_EVOKED); if (evoked_node.size() == 0) { qWarning("Could not find evoked data"); return false; } // convert setno to an integer if(!setno.isValid()) { if (evoked_node.size() > 1) { QStringList comments; QList<fiff_int_t> aspect_kinds; QString t; if(!t_pStream->get_evoked_entries(evoked_node, comments, aspect_kinds, t)) t = QString("None found, must use integer"); qWarning("%d datasets present, setno parameter must be set. Candidate setno names:\n%s", evoked_node.size(), t.toLatin1().constData()); return false; } else setno = 0; } else { // find string-based entry bool t_bIsInteger = true; setno.toInt(&t_bIsInteger); if(!t_bIsInteger) { if(p_aspect_kind != FIFFV_ASPECT_AVERAGE && p_aspect_kind != FIFFV_ASPECT_STD_ERR) { qWarning("kindStat must be \"FIFFV_ASPECT_AVERAGE\" or \"FIFFV_ASPECT_STD_ERR\""); return false; } QStringList comments; QList<fiff_int_t> aspect_kinds; QString t; t_pStream->get_evoked_entries(evoked_node, comments, aspect_kinds, t); bool found = false; for(qint32 i = 0; i < comments.size(); ++i) { if(comments[i].compare(setno.toString()) == 0 && p_aspect_kind == aspect_kinds[i]) { setno = i; found = true; break; } } if(!found) { qWarning() << "setno " << setno << " (" << p_aspect_kind << ") not found, out of found datasets:\n " << t; return false; } } } if (setno.toInt() >= evoked_node.size() || setno.toInt() < 0) { qWarning("Data set selector out of range"); return false; } FiffDirTree my_evoked = evoked_node[setno.toInt()]; // // Identify the aspects // QList<FiffDirTree> aspects = my_evoked.dir_tree_find(FIFFB_ASPECT); if(aspects.size() > 1) printf("\tMultiple (%d) aspects found. Taking first one.\n", aspects.size()); FiffDirTree my_aspect = aspects[0]; // // Now find the data in the evoked block // fiff_int_t nchan = 0; float sfreq = -1.0f; QList<FiffChInfo> chs; fiff_int_t kind, pos, first=0, last=0; FiffTag::SPtr t_pTag; QString comment(""); qint32 k; for (k = 0; k < my_evoked.nent; ++k) { kind = my_evoked.dir[k].kind; pos = my_evoked.dir[k].pos; switch (kind) { case FIFF_COMMENT: FiffTag::read_tag(t_pStream.data(),t_pTag,pos); comment = t_pTag->toString(); break; case FIFF_FIRST_SAMPLE: FiffTag::read_tag(t_pStream.data(),t_pTag,pos); first = *t_pTag->toInt(); break; case FIFF_LAST_SAMPLE: FiffTag::read_tag(t_pStream.data(),t_pTag,pos); last = *t_pTag->toInt(); break; case FIFF_NCHAN: FiffTag::read_tag(t_pStream.data(),t_pTag,pos); nchan = *t_pTag->toInt(); break; case FIFF_SFREQ: FiffTag::read_tag(t_pStream.data(),t_pTag,pos); sfreq = *t_pTag->toFloat(); break; case FIFF_CH_INFO: FiffTag::read_tag(t_pStream.data(), t_pTag, pos); chs.append( t_pTag->toChInfo() ); break; } } if (comment.isEmpty()) comment = QString("No comment"); // // Local channel information? // if (nchan > 0) { if (chs.size() == 0) { qWarning("Local channel information was not found when it was expected."); return false; } if (chs.size() != nchan) { qWarning("Number of channels and number of channel definitions are different."); return false; } info.chs = chs; info.nchan = nchan; printf("\tFound channel information in evoked data. nchan = %d\n",nchan); if (sfreq > 0.0f) info.sfreq = sfreq; } qint32 nsamp = last-first+1; printf("\tFound the data of interest:\n"); printf("\t\tt = %10.2f ... %10.2f ms (%s)\n", 1000*(float)first/info.sfreq, 1000*(float)last/info.sfreq,comment.toUtf8().constData()); if (info.comps.size() > 0) printf("\t\t%d CTF compensation matrices available\n", info.comps.size()); // // Read the data in the aspect block // fiff_int_t aspect_kind = -1; fiff_int_t nave = -1; QList<FiffTag> epoch; for (k = 0; k < my_aspect.nent; ++k) { kind = my_aspect.dir[k].kind; pos = my_aspect.dir[k].pos; switch (kind) { case FIFF_COMMENT: FiffTag::read_tag(t_pStream.data(), t_pTag, pos); comment = t_pTag->toString(); break; case FIFF_ASPECT_KIND: FiffTag::read_tag(t_pStream.data(), t_pTag, pos); aspect_kind = *t_pTag->toInt(); break; case FIFF_NAVE: FiffTag::read_tag(t_pStream.data(), t_pTag, pos); nave = *t_pTag->toInt(); break; case FIFF_EPOCH: FiffTag::read_tag(t_pStream.data(), t_pTag, pos); epoch.append(FiffTag(t_pTag.data())); break; } } if (nave == -1) nave = 1; printf("\t\tnave = %d - aspect type = %d\n", nave, aspect_kind); qint32 nepoch = epoch.size(); MatrixXd all_data; if (nepoch == 1) { // // Only one epoch // all_data = epoch[0].toFloatMatrix().cast<double>(); all_data.transposeInPlace(); // // May need a transpose if the number of channels is one // if (all_data.cols() == 1 && info.nchan == 1) all_data.transposeInPlace(); } else { // // Put the old style epochs together // all_data = epoch[0].toFloatMatrix().cast<double>(); all_data.transposeInPlace(); qint32 oldsize; for (k = 1; k < nepoch; ++k) { oldsize = all_data.rows(); MatrixXd tmp = epoch[k].toFloatMatrix().cast<double>(); tmp.transposeInPlace(); all_data.conservativeResize(oldsize+tmp.rows(), all_data.cols()); all_data.block(oldsize, 0, tmp.rows(), tmp.cols()) = tmp; } } if (all_data.cols() != nsamp) { qWarning("Incorrect number of samples (%d instead of %d)", (int) all_data.cols(), nsamp); return false; } // // Calibrate // printf("\n\tPreprocessing...\n"); printf("\t%d channels remain after picking\n",info.nchan); typedef Eigen::Triplet<double> T; std::vector<T> tripletList; tripletList.reserve(info.nchan); for(k = 0; k < info.nchan; ++k) tripletList.push_back(T(k, k, info.chs[k].cal)); SparseMatrix<double> cals(info.nchan, info.nchan); cals.setFromTriplets(tripletList.begin(), tripletList.end()); all_data = cals * all_data; RowVectorXf times = RowVectorXf(last-first+1); for (k = 0; k < times.size(); ++k) times[k] = ((float)(first+k)) / info.sfreq; // // Set up projection // if(info.projs.size() == 0 || !proj) { printf("\tNo projector specified for these data.\n"); p_FiffEvoked.proj = MatrixXd(); } else { // Create the projector MatrixXd projection; qint32 nproj = info.make_projector(projection); if(nproj == 0) { printf("\tThe projection vectors do not apply to these channels\n"); p_FiffEvoked.proj = MatrixXd(); } else { printf("\tCreated an SSP operator (subspace dimension = %d)\n", nproj); p_FiffEvoked.proj = projection; } // The projection items have been activated FiffProj::activate_projs(info.projs); } if(p_FiffEvoked.proj.rows() > 0) { all_data = p_FiffEvoked.proj * all_data; printf("\tSSP projectors applied to the evoked data\n"); } // Run baseline correction all_data = MNEMath::rescale(all_data, times, baseline, QString("mean")); printf("Applying baseline correction ... (mode: mean)"); // Put it all together p_FiffEvoked.info = info; p_FiffEvoked.nave = nave; p_FiffEvoked.aspect_kind = aspect_kind; p_FiffEvoked.first = first; p_FiffEvoked.last = last; p_FiffEvoked.comment = comment; p_FiffEvoked.times = times; p_FiffEvoked.data = all_data; return true; }
void SeparableConvolution2d(const RowMatrixXf& image, const Eigen::RowVectorXf& kernel_x, const Eigen::RowVectorXf& kernel_y, const BorderType& border_type, RowMatrixXf* out) { const int full_size = kernel_x.size(); const int half_size = full_size / 2; out->resize(image.rows(), image.cols()); // Convolving a vertical filter across rows is the same thing as transpose // multiply i.e. kernel_y^t * rows. This will give us the convoled value for // each row. However, care must be taken at the top and bottom borders. const RowVectorXf reverse_kernel_y = kernel_y.reverse(); if (border_type == REFLECT) { for (int i = 0; i < half_size; i++) { const int forward_size = i + half_size + 1; const int reverse_size = full_size - forward_size; out->row(i) = kernel_y.tail(forward_size) * image.block(0, 0, forward_size, image.cols()) + reverse_kernel_y.tail(reverse_size) * image.block(1, 0, reverse_size, image.cols()); // Apply the same technique for the end rows. // TODO(csweeney): Move this to its own loop for cache exposure? out->row(image.rows() - i - 1) = kernel_y.head(forward_size) * image.block(image.rows() - forward_size, 0, forward_size, image.cols()) + reverse_kernel_y.head(reverse_size) * image.block(image.rows() - reverse_size - 1, 0, reverse_size, image.cols()); } } else { // Perform border with REPLICATE as the option. for (int i = 0; i < half_size; i++) { const int forward_size = i + half_size + 1; const int reverse_size = full_size - forward_size; out->row(i) = kernel_y.tail(forward_size) * image.block(0, 0, forward_size, image.cols()) + reverse_kernel_y.tail(reverse_size) * image.row(0).replicate(reverse_size, 1); // Apply the same technique for the end rows. out->row(image.rows() - i - 1) = kernel_y.head(forward_size) * image.block(image.rows() - forward_size, 0, forward_size, image.cols()) + reverse_kernel_y.head(reverse_size) * image.row(image.rows() - 1).replicate(reverse_size, 1); } } // Applying the rest of the y filter. #ifdef AKAZE_USE_OPENMP #pragma omp parallel for #endif for (int row = half_size; row < image.rows() - half_size; row++) { out->row(row) = kernel_y * image.block(row - half_size, 0, full_size, out->cols()); } // Convolving with the horizontal filter is easy. Rather than using the kernel // as a sliding indow, we use the row pixels as a sliding window around the // filter. We prepend and append the proper border values so that we are sure // to end up with the correct convolved values. if (border_type == REFLECT) { RowVectorXf temp_row(image.cols() + full_size - 1); #ifdef AKAZE_USE_OPENMP #pragma omp parallel for firstprivate(temp_row) #endif for (int row = 0; row < out->rows(); row++) { temp_row.head(half_size) = out->row(row).segment(1, half_size).reverse(); temp_row.segment(half_size, image.cols()) = out->row(row); temp_row.tail(half_size) = out->row(row) .segment(image.cols() - 1 - half_size, half_size) .reverse(); // Convolve the row. We perform the first step here explicitly so that we // avoid setting the row equal to zero. out->row(row) = kernel_x(0) * temp_row.head(image.cols()); for (int i = 1; i < full_size; i++) { out->row(row) += kernel_x(i) * temp_row.segment(i, image.cols()); } } } else { RowVectorXf temp_row(image.cols() + full_size - 1); #ifdef AKAZE_USE_OPENMP #pragma omp parallel for firstprivate(temp_row) #endif for (int row = 0; row < out->rows(); row++) { temp_row.head(half_size).setConstant((*out)(row, 0)); temp_row.segment(half_size, image.cols()) = out->row(row); temp_row.tail(half_size).setConstant((*out)(row, out->cols() - 1)); // Convolve the row. We perform the first step here explicitly so that we // avoid setting the row equal to zero. out->row(row) = kernel_x(0) * temp_row.head(image.cols()); for (int i = 1; i < full_size; i++) { out->row(row) += kernel_x(i) * temp_row.segment(i, image.cols()); } } } }