/* * guaranteed out-of-place transform. Does the necessary * copying if the plan is in-place. */ static void rfftw_out_of_place(fftw_plan plan, int n, fftw_real *in, fftw_real *out) { if (plan->flags & FFTW_IN_PLACE) { rarray_copy(out, in, n); rfftw(plan, 1, out, 1, n, (fftw_real *)0, 1, n); } else { rfftw(plan, 1, in, 1, n, out, 1, n); } }
static void *real2c_overlap_aux_thread1(fftw_loop_data *ldata) { rexec2_thread_data *d = (rexec2_thread_data *) ldata->data; int n = d->plan->n; rfftw(d->plan, ldata->max - ldata->min, ldata->min * d->idist + (fftw_real *) d->in, d->istride, d->idist, d->work + n * ldata->min, 1, n); return 0; }
static void *c2real_overlap_aux_thread2(fftw_loop_data *ldata) { rexec2_thread_data *d = (rexec2_thread_data *) ldata->data; int n = d->plan->n; rfftw(d->plan, ldata->max - ldata->min, d->work + n * ldata->min, 1, n, ldata->min * d->odist + (fftw_real *) d->out, d->ostride, d->odist); return 0; }
void rfftw_c2real_overlap_aux(fftw_plan plan, int howmany, fftw_complex *in, int istride, int idist, fftw_real *out, int ostride, int odist, fftw_real *work) { int n = plan->n; int j; /* copy from in to work: */ for (j = 0; j < howmany; ++j, in += idist) rfftw_c2hc(n, in, istride, work + j * n); rfftw(plan, howmany, work, 1, n, out, ostride, odist); }
/* * The following two functions are similar to the ones above, BUT: * * work must contain n * howmany elements (stride 1) * * Can handle out == in for any stride/dist. */ void rfftw_real2c_overlap_aux(fftw_plan plan, int howmany, fftw_real *in, int istride, int idist, fftw_complex *out, int ostride, int odist, fftw_real *work) { int n = plan->n; int j; rfftw(plan, howmany, in, istride, idist, work, 1, n); /* copy from work to out: */ for (j = 0; j < howmany; ++j, work += n, out += odist) rfftw_hc2c(n, work, out, ostride); }
void test_speed_aux(int n, fftw_direction dir, int flags, int specific) { fftw_real *in, *out; fftw_plan plan; double t; fftw_time begin, end; in = (fftw_real *) fftw_malloc(n * howmany_fields * sizeof(fftw_real)); out = (fftw_real *) fftw_malloc(n * howmany_fields * sizeof(fftw_real)); if (specific) { begin = fftw_get_time(); plan = rfftw_create_plan_specific(n, dir, speed_flag | flags | wisdom_flag | no_vector_flag, in, howmany_fields, out, howmany_fields); end = fftw_get_time(); } else { begin = fftw_get_time(); plan = rfftw_create_plan(n, dir, speed_flag | flags | wisdom_flag | no_vector_flag); end = fftw_get_time(); } CHECK(plan != NULL, "can't create plan"); t = fftw_time_to_sec(fftw_time_diff(end, begin)); WHEN_VERBOSE(2, printf("time for planner: %f s\n", t)); WHEN_VERBOSE(2, rfftw_print_plan(plan)); FFTW_TIME_FFT(rfftw(plan, howmany_fields, in, howmany_fields, 1, out, howmany_fields, 1), in, n * howmany_fields, t); rfftw_destroy_plan(plan); WHEN_VERBOSE(1, printf("time for one fft: %s", smart_sprint_time(t))); WHEN_VERBOSE(1, printf(" (%s/point)\n", smart_sprint_time(t / n))); WHEN_VERBOSE(1, printf("\"mflops\" = 5/2 (n log2 n) / (t in microseconds)" " = %f\n", 0.5 * howmany_fields * mflops(t, n))); fftw_free(in); fftw_free(out); WHEN_VERBOSE(1, printf("\n")); }
/* * Class: jfftw_real_Plan * Method: transform * Signature: (I[DII[DII)V */ JNIEXPORT void JNICALL Java_jfftw_real_Plan_transform__I_3DII_3DII( JNIEnv *env, jobject obj, jint howmany, jdoubleArray in, jint istride, jint idist, jdoubleArray out, jint ostride, jint odist ) { jdouble *cin, *cout; int i; jclass clazz = (*env)->GetObjectClass( env, obj ); jfieldID id = (*env)->GetFieldID( env, clazz, "plan", "[B" ); jbyteArray arr = (jbyteArray)(*env)->GetObjectField( env, obj, id ); unsigned char* carr = (*env)->GetByteArrayElements( env, arr, 0 ); rfftw_plan plan = *(rfftw_plan*)carr; if( (howmany - 1) * idist + plan->n * istride != (*env)->GetArrayLength( env, in ) ) { (*env)->ThrowNew( env, (*env)->FindClass( env, "java/lang/IndexOutOfBoundsException" ), "the Plan was created for a different length (in)" ); (*env)->ReleaseByteArrayElements( env, arr, carr, 0 ); return; } if( (howmany - 1) * odist + plan->n * ostride != (*env)->GetArrayLength( env, out ) ) { (*env)->ThrowNew( env, (*env)->FindClass( env, "java/lang/IndexOutOfBoundsException" ), "the Plan was created for a different length (out)" ); (*env)->ReleaseByteArrayElements( env, arr, carr, 0 ); return; } cin = (*env)->GetDoubleArrayElements( env, in, 0 ); cout = (*env)->GetDoubleArrayElements( env, out, 0 ); if( ! plan->flags & FFTW_THREADSAFE ) { // synchronization (*env)->MonitorEnter( env, obj ); } rfftw( plan, howmany, cin, istride, idist, cout, ostride, odist ); if( ! plan->flags & FFTW_THREADSAFE ) { // synchronization (*env)->MonitorExit( env, obj ); } (*env)->ReleaseByteArrayElements( env, arr, carr, 0 ); (*env)->ReleaseDoubleArrayElements( env, in, cin, 0 ); (*env)->ReleaseDoubleArrayElements( env, out, cout, 0 ); }
void F77_FUNC_(rfftw_f77,RFFTW_F77) (fftw_plan *p, int *howmany, fftw_real *in, int *istride, int *idist, fftw_real *out, int *ostride, int *odist) { rfftw(*p,*howmany,in,*istride,*idist,out,*ostride,*odist); }
void test_in_place(int n, int istride, int howmany, fftw_direction dir, fftw_plan validated_plan, int specific) { fftw_complex *in2, *out2; fftw_real *in1, *out1, *out3; fftw_plan plan; int i, j; int ostride = istride; int flags = measure_flag | wisdom_flag | FFTW_IN_PLACE; if (coinflip()) flags |= FFTW_THREADSAFE; in1 = (fftw_real *) fftw_malloc(istride * n * sizeof(fftw_real) * howmany); in2 = (fftw_complex *) fftw_malloc(n * sizeof(fftw_complex)); out1 = in1; out2 = (fftw_complex *) fftw_malloc(n * sizeof(fftw_complex)); out3 = (fftw_real *) fftw_malloc(n * sizeof(fftw_real)); if (!specific) plan = rfftw_create_plan(n, dir, flags); else plan = rfftw_create_plan_specific(n, dir, flags, in1, istride, out1, ostride); CHECK(plan != NULL, "can't create plan"); /* generate random inputs */ fill_random(in1, n, istride); for (j = 1; j < howmany; ++j) for (i = 0; i < n; ++i) in1[(j * n + i) * istride] = in1[i * istride]; /* copy random inputs to complex array for comparison with fftw: */ if (dir == FFTW_REAL_TO_COMPLEX) for (i = 0; i < n; ++i) { c_re(in2[i]) = in1[i * istride]; c_im(in2[i]) = 0.0; } else { int n2 = (n + 1) / 2; c_re(in2[0]) = in1[0]; c_im(in2[0]) = 0.0; for (i = 1; i < n2; ++i) { c_re(in2[i]) = in1[i * istride]; c_im(in2[i]) = in1[(n - i) * istride]; } if (n2 * 2 == n) { c_re(in2[n2]) = in1[n2 * istride]; c_im(in2[n2]) = 0.0; ++i; } for (; i < n; ++i) { c_re(in2[i]) = c_re(in2[n - i]); c_im(in2[i]) = -c_im(in2[n - i]); } } /* * fill in other positions of the array, to make sure that * rfftw doesn't overwrite them */ for (j = 1; j < istride; ++j) for (i = 0; i < n * howmany; ++i) in1[i * istride + j] = i * istride + j; WHEN_VERBOSE(2, rfftw_print_plan(plan)); /* fft-ize */ if (howmany != 1 || istride != 1 || coinflip()) rfftw(plan, howmany, in1, istride, n * istride, 0, 0, 0); else rfftw_one(plan, in1, NULL); rfftw_destroy_plan(plan); /* check for overwriting */ for (j = 1; j < ostride; ++j) for (i = 0; i < n * howmany; ++i) CHECK(out1[i * ostride + j] == i * ostride + j, "output has been overwritten"); fftw(validated_plan, 1, in2, 1, n, out2, 1, n); if (dir == FFTW_REAL_TO_COMPLEX) { int n2 = (n + 1) / 2; out3[0] = c_re(out2[0]); for (i = 1; i < n2; ++i) { out3[i] = c_re(out2[i]); out3[n - i] = c_im(out2[i]); } if (n2 * 2 == n) out3[n2] = c_re(out2[n2]); } else { for (i = 0; i < n; ++i) out3[i] = c_re(out2[i]); } for (j = 0; j < howmany; ++j) CHECK(compute_error(out1 + j * n * ostride, ostride, out3, 1, n) < TOLERANCE, "test_in_place: wrong answer"); WHEN_VERBOSE(2, printf("OK\n")); fftw_free(in1); fftw_free(in2); fftw_free(out2); fftw_free(out3); }