replaced huge 2d twiddle arrays by smaller 1d arrays. Now it uses very low memory
This commit is contained in:
105
C/FP_math.c
105
C/FP_math.c
@ -4,91 +4,12 @@
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
|
||||
#define DATA_L 1024
|
||||
#define DATA_L (1<<16)
|
||||
#define FP_acc 1000
|
||||
|
||||
#define PI 3.141592653589793238462643383279502884197169399375105820974944
|
||||
#include "FFT_FP_realisation.h"
|
||||
|
||||
|
||||
|
||||
int64_t cos_delta_FP_arr[DATA_L] = {0,};
|
||||
int64_t sin_delta_FP_arr[DATA_L] = {0,};
|
||||
int64_t wr_arr[DATA_L][DATA_L / 2] = {0,};
|
||||
int64_t wi_arr[DATA_L][DATA_L / 2] = {0,};
|
||||
|
||||
void FFT_fp(int64_t* inp, uint32_t inp_L, int64_t* buf){
|
||||
|
||||
// buf имеет длину inp_L * 2 (Re, Im, Re, Im, ...)
|
||||
// inp содержит inp_L значений uint32_t
|
||||
|
||||
uint32_t i, j, bit;
|
||||
// uint32_t N = inp_L / 2; // длина комплексного массива (inp содержит только Re-часть)
|
||||
uint32_t N = inp_L; // длина комплексного массива (inp содержит только Re-часть)
|
||||
|
||||
// --- копирование входных данных в буфер ---
|
||||
for (i = 0; i < inp_L; i++) {
|
||||
buf[i * 2] = inp[i];
|
||||
buf[i * 2 + 1] = 0;
|
||||
}
|
||||
|
||||
// --- bit-reversal перестановка ---
|
||||
j = 0;
|
||||
for (i = 1; i < N; i++) {
|
||||
bit = N >> 1;
|
||||
while (j & bit) {
|
||||
j ^= bit;
|
||||
bit >>= 1;
|
||||
}
|
||||
j |= bit;
|
||||
if (i < j) {
|
||||
int64_t tmp_re = buf[i * 2];
|
||||
int64_t tmp_im = buf[i * 2 + 1];
|
||||
buf[i * 2] = buf[j * 2];
|
||||
buf[i * 2 + 1] = buf[j * 2 + 1];
|
||||
buf[j * 2] = tmp_re;
|
||||
buf[j * 2 + 1] = tmp_im;
|
||||
}
|
||||
}
|
||||
|
||||
// --- уровни бабочек ---
|
||||
uint32_t m = 2;
|
||||
while (m <= N) {
|
||||
uint32_t half = m >> 1;
|
||||
|
||||
for (uint32_t start = 0; start < N; start += m) {
|
||||
int64_t *twiddle_re = wr_arr[m - 2];
|
||||
int64_t *twiddle_im = wi_arr[m - 2];
|
||||
|
||||
for (uint32_t k = 0; k < half; k++) {
|
||||
int64_t wr = twiddle_re[k];
|
||||
int64_t wi = twiddle_im[k];
|
||||
int64_t u_re = buf[(start + k) * 2];
|
||||
int64_t u_im = buf[(start + k) * 2 + 1];
|
||||
int64_t v_re = buf[(start + k + half) * 2];
|
||||
int64_t v_im = buf[(start + k + half) * 2 + 1];
|
||||
|
||||
// t = w * v (в фиксированной точке)
|
||||
int64_t t_re = (wr * v_re - wi * v_im) / FP_acc;
|
||||
int64_t t_im = (wr * v_im + wi * v_re) / FP_acc;
|
||||
|
||||
// верх/низ
|
||||
buf[(start + k) * 2] = u_re + t_re;
|
||||
buf[(start + k) * 2 + 1] = u_im + t_im;
|
||||
buf[(start + k + half) * 2] = u_re - t_re;
|
||||
buf[(start + k + half) * 2 + 1] = u_im - t_im;
|
||||
|
||||
}
|
||||
}
|
||||
m <<= 1;
|
||||
}
|
||||
for (uint32_t i = 0; i < inp_L; ++i){
|
||||
//buf[i*2] /= inp_L;
|
||||
//buf[i*2+1] /= inp_L;
|
||||
printf("re,im: %lld, %lld\n", (long long)buf[i*2], (long long)buf[i*2 +1]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void imagery2abs(int64_t* inp, uint32_t inp_L, int64_t *out){
|
||||
printf("+++++++++++++++++++++\n");
|
||||
printf("calculating abs^2\n");
|
||||
@ -100,26 +21,6 @@ void imagery2abs(int64_t* inp, uint32_t inp_L, int64_t *out){
|
||||
out[i] = val;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void sin_cos_filler(int64_t* sin_arr, int64_t* cos_arr, uint32_t L){
|
||||
//[int(-sin(2.0 * pi / m) * FP_acc) for m in range(2,inp_L//2 + 2)]
|
||||
for (uint32_t i = 0; i < L; ++i){
|
||||
int m = i + 2;
|
||||
double angle = 2.0* PI/m;
|
||||
sin_arr[i] = lround(-sin(angle) * FP_acc);
|
||||
cos_arr[i] = lround(cos(angle) * FP_acc);
|
||||
uint32_t half = m >> 1;
|
||||
for (uint32_t k = 0; k < half; ++k){
|
||||
double tw_angle = angle * k;
|
||||
wr_arr[i][k] = lround(cos(tw_angle) * FP_acc);
|
||||
wi_arr[i][k] = lround(-sin(tw_angle) * FP_acc);
|
||||
}
|
||||
printf("i, angle, sin, cos: %d %g %lld %lld\n", i, angle, (long long)sin_arr[i], (long long)cos_arr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void data_generator(int64_t* X, int64_t* Y, uint32_t N){
|
||||
for (int i = 0; i < N; ++i){
|
||||
X[i] = (int64_t)i;
|
||||
@ -135,7 +36,7 @@ void main(){
|
||||
int64_t data_res_FFT_imag[DATA_L*2] = {0,};
|
||||
int64_t data_res_FFT_abs[DATA_L] = {0,};
|
||||
|
||||
sin_cos_filler(sin_delta_FP_arr, cos_delta_FP_arr, DATA_L);
|
||||
fft_fp_prepare();
|
||||
|
||||
data_generator(data_X, data_Y, DATA_L);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user