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; } }
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; }