int main() { int n, ip[NMAXSQRT + 2]; double a[NMAX + 1], w[NMAX * 5 / 4], t[NMAX / 2 + 1], err; printf("data length n=? (must be 2^m)\n"); scanf("%d", &n); ip[0] = 0; /* check of CDFT */ putdata(0, n - 1, a); cdft(n, 1, a, ip, w); cdft(n, -1, a, ip, w); err = errorcheck(0, n - 1, 2.0 / n, a); printf("cdft err= %g \n", err); /* check of RDFT */ putdata(0, n - 1, a); rdft(n, 1, a, ip, w); rdft(n, -1, a, ip, w); err = errorcheck(0, n - 1, 2.0 / n, a); printf("rdft err= %g \n", err); /* check of DDCT */ putdata(0, n - 1, a); ddct(n, 1, a, ip, w); ddct(n, -1, a, ip, w); a[0] *= 0.5; err = errorcheck(0, n - 1, 2.0 / n, a); printf("ddct err= %g \n", err); /* check of DDST */ putdata(0, n - 1, a); ddst(n, 1, a, ip, w); ddst(n, -1, a, ip, w); a[0] *= 0.5; err = errorcheck(0, n - 1, 2.0 / n, a); printf("ddst err= %g \n", err); /* check of DFCT */ putdata(0, n, a); a[0] *= 0.5; a[n] *= 0.5; dfct(n, a, t, ip, w); a[0] *= 0.5; a[n] *= 0.5; dfct(n, a, t, ip, w); err = errorcheck(0, n, 2.0 / n, a); printf("dfct err= %g \n", err); /* check of DFST */ putdata(1, n - 1, a); dfst(n, a, t, ip, w); dfst(n, a, t, ip, w); err = errorcheck(1, n - 1, 2.0 / n, a); printf("dfst err= %g \n", err); return 0; }
// compute distances from rows of inmat1 to rows of inmat2 RcppExport SEXP rthpdist(SEXP inmat1,SEXP inmat2, SEXP nthreads) { Rcpp::NumericMatrix im1(inmat1); Rcpp::NumericMatrix im2(inmat2); int nr1 = im1.nrow(); int nc = im1.ncol(); int nr2 = im2.nrow(); #if RTH_OMP omp_set_num_threads(INT(nthreads)); #elif RTH_TBB // tbb::task_scheduler_init init(INT(nthreads)); // for unknown reasons, this code does not work under TBB return Rcpp::wrap(-1); #endif thrust::device_vector<double> dmat1(im1.begin(),im1.end()); thrust::device_vector<double> dmat2(im2.begin(),im2.end()); // make space for the output thrust::device_vector<double> ddst(nr1*nr2); // iterators for row number of inmat1 thrust::counting_iterator<int> iseqb(0); thrust::counting_iterator<int> iseqe = iseqb + nr1; // for each i in [iseqb,iseqe) find the distances from row i in inmat1 // to all rows of inmat2 thrust::for_each(iseqb,iseqe, do1ival(dmat1.begin(),dmat2.begin(),ddst.begin(),nr1,nc,nr2)); Rcpp::NumericMatrix rout(nr1,nr2); thrust::copy(ddst.begin(),ddst.end(),rout.begin()); return rout; }
void DoFFT() { // SampleBuffer に高速離散フーリエ変換 (実際はサイン変換) を行い // FFTData に格納する tjs_int len = SampleBufferLen; tjs_int len2 = len / 2; if(FFTLen != len) { FFTLen = len; // バッファの確保 if(FFTData) delete [] FFTData, FFTData = NULL; if(WindowData) delete [] WindowData, WindowData = NULL; if(fft_ip) delete [] fft_ip, fft_ip = NULL; if(fft_w) delete[] fft_w, fft_w = NULL; FFTData = new float[len]; WindowData = new float[len]; fft_ip = new int[(int)(2.0 + sqrt(len * (1.0 / 2.0)))]; fft_w = new float[(int)(len * (5.0 / 4.0))]; fft_ip[0] = 0; // 窓関数の作成 float mul = (4.0/32768.0/len); for(tjs_int i = 0; i < len; i++) { WindowData[i] = sin(3.14159265358979 * (i + 0.5) / len) * mul; // (sin窓) } } // FFTData に窓関数を適用しながらデータを転送 for(tjs_int i = 0; i < len2; i++) { FFTData[i] = SampleBuffer[i] * WindowData[i]; FFTData[i + len2] = SampleBuffer[i + len2] * WindowData[len2 - i - 1]; } // 高速離散サイン変換 ddst(len, -1, FFTData, fft_ip, fft_w); // 直流成分のカット FFTData[0] = FFTData[1] = 0; }
void dfst(int n, double *a) { void ddst(int n, int isgn, double *a); void bitrv1(int n, double *a); int j, k, m, mh; double xr, xi, yr, yi; m = n >> 1; for (j = 1; j < m; j++) { k = n - j; xr = a[j] - a[k]; a[j] += a[k]; a[k] = xr; } a[0] = a[m]; while (m >= 2) { ddst(m, 1, a); bitrv1(m, a); mh = m >> 1; for (j = 1; j < mh; j++) { k = m - j; xr = a[m + k]; xi = a[m + j]; yr = a[j]; yi = a[k]; a[m + j] = yr; a[m + k] = yi; a[j] = xr + xi; a[k] = xr - xi; } a[m] = a[0]; a[0] = a[m + mh]; a[m + mh] = a[mh]; m = mh; } a[1] = a[0]; a[0] = 0; bitrv1(n, a); }