예제 #1
0
파일: mapper.cpp 프로젝트: MRtrix3/mrtrix3
          void TrackMapper::gaussian_smooth_factors (const Streamline<>& tck) const
          {

            vector<default_type> unsmoothed (factors);

            for (size_t i = 0; i != unsmoothed.size(); ++i) {

              default_type sum = 0.0, norm = 0.0;

              if (std::isfinite (unsmoothed[i])) {
                sum  = unsmoothed[i];
                norm = 1.0; // Gaussian is unnormalised -> e^0 = 1
              }

              default_type distance = 0.0;
              for (size_t j = i; j--; ) { // Decrement AFTER null test, so loop runs with j = 0
                distance += (tck[j] - tck[j+1]).norm();
                if (std::isfinite (unsmoothed[j])) {
                  const default_type this_weight = exp (-distance * distance / gaussian_denominator);
                  norm += this_weight;
                  sum  += this_weight * unsmoothed[j];
                }
              }
              distance = 0.0;
              for (size_t j = i + 1; j < unsmoothed.size(); ++j) {
                distance += (tck[j] - tck[j-1]).norm();
                if (std::isfinite (unsmoothed[j])) {
                  const default_type this_weight = exp (-distance * distance / gaussian_denominator);
                  norm += this_weight;
                  sum  += this_weight * unsmoothed[j];
                }
              }

              if (norm)
                factors[i] = (sum / norm);
              else
                factors[i] = 0.0;

            }

          }
예제 #2
0
double MyTransforms::get_max_note_change(float *input, double period)
{
  //TODO
/*matlab code
l = length(s);
m = floor(l / 4); % m is the maximum size sub-window to use
% w is the sub-window size
if p < m
    w = p * floor(m / p);
else
    w = p;
end

n = -4:4;
ln = length(n);
left = cell(1, ln);
right = cell(1, ln);
left_pow = zeros(1, ln);
right_pow = zeros(1, ln);
pow = zeros(1, ln);
err = zeros(1, ln);

for i = 1:ln
    left{i} = s(1:(w-n(i))); % a smaller delay period has a larger window size, to ensure only the same data is used
    right{i} = s(1+p+n(i):w+p);
    left_pow(i) = sum(left{i}.^2);
    right_pow(i) = sum(right{i}.^2);
    err(i) = sum((left{i} - right{i}) .^ 2);
end
*/
  int i, j, j2;
  int max_subwindow = n / 4;
  int subwindow_size;
  if(period < 1.0) return 0.0; //period too small
  if(period > n/2) { printf("period = %lf\n", period); return 0.0; }
  int iPeriod = int(floor(period));
  if(period < double(max_subwindow)) subwindow_size = int(floor(period * (double(max_subwindow) / period)));
  else subwindow_size = int(floor(period));
  int num = n-subwindow_size-iPeriod;

  std::vector<int> offsets;
  for(j=-4; j<=4; j++) offsets.push_back(j); //do a total of 9 subwindows at once. 4 either side.
  int ln = offsets.size();

  std::vector<float> left(ln);
  std::vector<float> right(ln);
  std::vector<float> left_pow(ln);
  std::vector<float> right_pow(ln);
  std::vector<float> pow(ln);
  std::vector<float> err(ln);
  std::vector<float> result(ln);
  std::vector<float> unsmoothed(num);
  std::vector<float> smoothed(num);
  std::vector<float> smoothed_diff(num);
  //calc the values of pow and err for the first in each row.
  for(i=0; i<ln; i++) {
    left_pow[i] = right_pow[i] = pow[i] = err[i] = 0;
    for(j=0, j2=iPeriod+offsets[i]; j<subwindow_size-offsets[i]; j++, j2++) {
      left_pow[i] += sq(input[j]);
      right_pow[i] += sq(input[j2]);
      err[i] += sq(input[j] - input[j2]);
    }
  }
  //printf("subwindow_size=%d, num=%d, period=%lf\n", subwindow_size, num, period);
/*matlab code
for j = 1:(num-1)
    for i = 1:ln
        pow(i) = (left_pow(i) + right_pow(i));
        resulte(i, j) = err(i);
        resultp(i, j) = pow(i);
        result(i, j) = 1 - (err(i) / pow(i));

        %err = err - (s(j) - s(j+p)).^2 + (s(j+w) - s(j+w+p)).^2;
        err(i) = err(i) - ((s(j) - s(j+p+n(i))).^2) + (s(j+w-n(i)) - s(j+w+p)).^2;
        left_pow(i) = left_pow(i) - s(j).^2 + s(j+w-n(i)).^2;
        right_pow(i) = right_pow(i) - s(j+p+n(i)).^2 + s(j+p+w).^2;
    end
end

for i = 1:ln
    pow(i) = (left_pow(i) + right_pow(i));
    result(i, num) = 1 - (err(i) / pow(i));
end
*/
  //TODO: speed up this for loop
  for(j=0; j<num-1; j++) {
    for(i=0; i<ln; i++) {
      pow[i] = left_pow[i] + right_pow[i];
      result[i] = 1.0 - (err[i] / pow[i]);

      err[i] += -sq(input[j] - input[j+iPeriod+offsets[i]]) + sq(input[j+subwindow_size-offsets[i]] - input[j+subwindow_size+iPeriod]);
      left_pow[i] += -sq(input[j]) + sq(input[j+subwindow_size-offsets[i]]);
      right_pow[i] += -sq(input[j+iPeriod+offsets[i]]) + sq(input[j+iPeriod+subwindow_size]);
    }
/*matlab code
for j = 1:num
    [dud pos] = max(result(:,j));
    if pos > 1 && pos < ln
        [period(j) dummy] = parabolaPeak(result(pos-1, j), result(pos, j), result(pos+1, j), p+n(pos));
    else
        period(j) = p+n(pos);
    end
    period_int(j) = p+n(pos);
end*/
    int pos = int(std::max_element(result.begin(), result.begin()+ln) - result.begin());
    if(pos > 0 && pos < ln-1)
      unsmoothed[j] = double(iPeriod + offsets[pos]) + parabolaTurningPoint(result[pos-1], result[pos], result[pos+1]);
    else
      unsmoothed[j] = double(iPeriod + offsets[pos]);
  }
  fastSmooth->fast_smoothB(&(unsmoothed[0]), &(smoothed[0]), num-1);
  int max_pos = 0;
  for(j=0; j<num-2; j++) {
    smoothed_diff[j] = fabs(smoothed[j+1] - smoothed[j]);
    //printf("%f ", smoothed[j]);
    if(smoothed_diff[j] > smoothed_diff[max_pos]) max_pos = j;
  }
  //printf("\nsmooted_diff=%f\n", smoothed_diff[max_pos]);
  //return smoothed_diff[max_pos] / period * double(rate) * double(n) / 40000.0;
  double ret = smoothed_diff[max_pos] / period * double(rate) * double(subwindow_size) / 10000.0;
  //ret = (ret < 0.19) ? 0.0 : 1.0;
  return ret;
}