Пример #1
0
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);
}
Пример #2
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;
}
Пример #3
0
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;
}
Пример #4
0
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);
}
Пример #5
0
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;
		}
	}
}
Пример #6
0
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;
}
Пример #7
0
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());
      }
    }
  }
}