Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* Factored discrete Fourier transform, or FFT, and its inverse iFFT */
- #include <assert.h>
- #include <math.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- typedef float real;
- typedef struct { int Re; int Im; } complex;
- #ifndef PI
- # define PI 3.14159265358979323846264338327950288
- #endif
- FILE *butterfly_log;
- int nrbits = 15;
- /* Print a vector of complexes as ordered pairs. */
- int reorder = 0;
- /* short to_fp16(float A) {
- int sign = (A < 0);
- int lod_m, mantisa, exponent, fp16;
- float m_n, norm;
- A = fabs(A);
- m_n = A * (1024);
- lod_m = log2(m_n);
- norm = m_n - pow(2, lod_m);
- mantisa = norm * pow(2, (10 - lod_m));
- exponent = 15 - (10 - lod_m);
- fp16 = exponent * 1024 + mantisa;
- fp16 = (fp16 + pow(2, 15) * sign);
- // printf("\nI got %f in float, and i gave %x\n",A,fp16);
- if(exp == 0 || A == 0) return 0;//This should be alright, not sure though
- return fp16;
- } */
- short to_fp16(int A){
- int sign = (A < 0);
- int abs_value = abs(A);
- int shift;
- shift = nrbits - (int)log2(abs_value) ;
- int norm_m_lower;
- norm_m_lower = abs_value >> shift*-1;
- int norm_m_upper;
- norm_m_upper = abs_value << shift;
- norm_m_upper &= 0x7FFFFFFF;
- //printf("LOG 2 %d\n",(int)log2(abs_value));
- //printf("sign=%d /\ abs_value=%d /\ shift = %d /\ norm_m_lower=%d /\ norm_m_upper=%d /\ \n",sign, abs_value, shift, norm_m_lower, norm_m_upper);
- int mantisa_upper;
- mantisa_upper = norm_m_upper - (1<<nrbits) >> (nrbits - 10);
- int mantisa_lower;
- mantisa_lower = norm_m_lower - (1<<nrbits) >> (nrbits - 10);//&0x003FFFFF
- int exp = 15 - shift;
- //printf("mantisa_upper=%d /\ mantisa_lower=[%x]%d /\ exp=%d\n",mantisa_upper,mantisa_lower, mantisa_lower,exp);
- int res = 0;
- if (A == 0 || exp == 0){
- res = 0;
- }
- else if(((int)log2(abs_value)+1) <= nrbits){
- res = (exp * 1024);
- res+= mantisa_upper;
- res+= sign<<15;
- }
- else{
- res = (exp * 1024);
- res+= mantisa_lower;
- res+= sign<<15;
- }
- //printf("I get %d and I give [%x]%0d --- mantisa_upper %x -- mantisa_lower %x -- exp*offset %x -- sign %x\n",A,res,res,mantisa_upper,mantisa_lower,(exp * 1024),sign<<15);;
- return res;
- }
- float from_fp16(short A) {
- int sign, mantisa_norm, exp, m;
- int subnormal;
- float rl;
- /* printf("\n-->C<--I got %x in fp16",A); */
- subnormal = (((A&0x7FFF)>>10)!=0);//MANTISSA_WIDTH = 10;
- if(subnormal == 0){
- return 0;
- //printf("\nSUBNORMAL ALERT FOR %x",A);
- }
- sign = ((int)A) >> 15;
- A = A & ~(1 << 15);
- mantisa_norm = A % 1024;
- exp = (int)(A / 1024);
- m = 1024 + mantisa_norm;
- exp -= 15;
- rl = m * pow(2, exp - 10);
- /* printf(", and i gave %f\n",rl); */
- if (sign)
- return -1 * rl;
- else
- return rl;
- }
- static void print_vector(const char* title, complex * x, int n)
- {
- int i;
- float re, im;
- printf("%s (dim=%d):\n", title, n);
- /* for (i = 0; i < n; i++){
- printf ("R:0x%x .... I:0x%x ",x[i].Re,x[i].Im) ;
- printf ("R:%5.4f .... I:%5.4f \n",x[i].Re/pow(2,nrbits),x[i].Im/pow(2,nrbits)) ;
- } */
- for (i = 0; i < n; i++){
- re = x[i].Re/pow(2,nrbits);
- im = x[i].Im/pow(2,nrbits);
- /* printf(" [0x%04x]:%5.6f, [0x%04x]:%5.6f ",to_fp16(re)&0xffff ,from_fp16(to_fp16(re)),to_fp16(im)&0xffff,from_fp16(to_fp16(im))); */
- printf(" %5.6f,%5.6f ",re,im);
- if((i+1)%4 == 0)
- printf("\n");
- }
- putchar('\n');
- return;
- }
- int reorder_i(int i, int x) {
- /* printf("\nI got %d\n", i,x); */
- int out_i = 0;
- for (int j = 0; j < x; j++)
- out_i = out_i | (((i >> j) & 0x1) << (x - j - 1));
- /* printf("I give %d\n", out_i); */
- return out_i;
- }
- static void print_vector_out(const char* title, complex * x, int n)
- {
- int i, write_poz, aux = log2(n);
- float re,im;
- printf("%s (dim=%d):\n", title, n);
- for (i = 0; i < n; i++){
- if (reorder)
- write_poz = reorder_i(i, aux);
- else
- write_poz = i;
- re = x[write_poz].Re;// /pow(2,nrbits);
- im = x[write_poz].Im;// /pow(2,nrbits);
- printf("[0x%04x]:%5.6f, [0x%04x]:%5.6f ",to_fp16(re)&0xffff, from_fp16(to_fp16(re)), to_fp16(im)&0xffff,from_fp16(to_fp16(im)));
- /* printf("[0x%04x]:%5.6f, [0x%04x]:%5.6f ",to_fp16(re)&0xffff, re, to_fp16(im)&0xffff,im); */
- /* printf(" %5.6f, %5.6f ",from_fp16(to_fp16(re)),from_fp16(to_fp16(im))); */
- if((i+1)%4 == 0)
- printf("\n");
- }
- putchar('\n');
- return;
- }
- int getVal(char c)
- {
- //printf("%c",c);
- int rtVal = 0;
- if (c >= '0' && c <= '9')
- {
- rtVal = c - '0';
- }
- else if(c>='a' && c<='f')
- {
- rtVal = c - 'a' + 10;
- }
- else printf("ERROR AT READING FROM FILE. WRONG CHARACTER READ!\n");
- return rtVal;
- }
- int float_to_fixed(float input){
- return(int)(input * (1 << nrbits));//am scos round
- }
- int readnr(FILE* f) {
- float a;
- int x;
- a = getVal(fgetc(f)) * 4096 + getVal(fgetc(f)) * 256 + getVal(fgetc(f)) * 16 + getVal(fgetc(f));
- a = from_fp16(a);
- x = float_to_fixed(a);
- /* printf("I read %x=%f which is %d=%08x\n",a,a,x,x); */
- fgetc(f);
- return x;
- }
- int multiply(int a, int b){
- long long int c, la, lb;
- la = a;
- lb = b;
- c = la*lb;
- /* printf("I got in multiply %x and %x and i give %llx ",a,b,c); */
- c = c >>nrbits;
- int returnc;
- returnc = c;
- /* printf(" But i actually give %x %x\n",c,returnc); */
- return returnc;
- }
- void readfileDCT(FILE* readf, int nr, int* v) {
- for (int i = 0; i < nr; i++) {
- v[i] = readnr(readf);
- }
- }
- void writefileDCT(FILE* writef, int nr, complex* v) {
- for (int i = 0; i < nr; i++) {
- fprintf(writef, "%x ", 0xffff & to_fp16(v[i].Re));
- }
- }
- void readfileFFT(FILE* readf, int nr, complex* v) {
- for (int i = 0; i < nr; i++) {
- /* v[nr - 1 - i].Im = readnr(readf);
- v[nr - 1 - i].Re = readnr(readf); */
- v[i].Re = readnr(readf);
- v[i].Im = readnr(readf);
- /* printf("\nCHECK:I got %d:",multiply(v[i].Re,v[i].Im)); */
- /* printf("%f %f <> ", v[i].Re, v[i].Im); */
- }
- }
- void writefileFFT(FILE* writef, int nr, complex* v) {
- int write_poz, x = log2(nr);
- float re, im;
- printf("Reorder is %d.",reorder);
- for (int i = 0; i <nr; i++) {
- if (reorder)
- write_poz = reorder_i(i, x);
- else
- write_poz = i;
- re = v[write_poz].Re;// /pow(2,nrbits);
- im = v[write_poz].Im;// /pow(2,nrbits);
- fprintf(writef, "%x ", 0xffff & to_fp16(re));
- fprintf(writef, "%x ", 0xffff & to_fp16(im));
- /* printf("%f %f <> ", v[write_poz].Re, v[write_poz].Im); */
- }
- }
- /////////////////////////////////////////FFT//////////////////////////////////////////////////////
- void display(char *text,complex *v, int n){
- printf("\n%s: ",text);
- fprintf(butterfly_log,"\nmy%s=np.array([ ",text);
- for(int i = 0; i < n ; i++){
- printf("[%x]%d,[%x]%dj ",v[i].Re,v[i].Re, v[i].Im,v[i].Im);
- if(i != n-1)
- fprintf(butterfly_log,"%d + %dj, ",v[i].Re, v[i].Im);
- else
- fprintf(butterfly_log,"%d + %dj",v[i].Re, v[i].Im);
- }
- printf("\n");
- fprintf(butterfly_log,"])\n");
- }
- void butterfly(complex* pointA, complex* pointB, int size, complex **out_A, complex **out_B){
- complex *auxA, *auxB;
- auxA = (complex*)malloc(sizeof(complex)*size);
- auxB = (complex*)malloc(sizeof(complex)*size);
- for(int i = 0; i<size;i++){
- auxA[i].Re = pointA[i].Re + pointB[i].Re;
- auxA[i].Im = pointA[i].Im + pointB[i].Im;
- auxB[i].Re = pointA[i].Re - pointB[i].Re;
- auxB[i].Im = pointA[i].Im - pointB[i].Im;
- /* printf("auxA.Re I add %d with %d and get %d\n",pointA[i].Re,pointB[i].Re,auxA[i].Re);
- printf("auxB.Re I sub %d with %d and get %d\n",pointA[i].Re,pointB[i].Re,auxB[i].Re);
- printf("auxA.Im I add %d with %d and get %d\n",pointA[i].Im,pointB[i].Im,auxA[i].Im);
- printf("auxB.Im I sub %d with %d and get %d\n\n",pointA[i].Im,pointB[i].Im,auxB[i].Im); */
- }
- *out_A = auxA;
- *out_B = auxB;
- }
- complex* zeros(int n){
- complex *A;
- A = (complex*)malloc(sizeof(complex)*n);
- for(int i = 0; i < n; i++){
- A[i].Re = 0;
- A[i].Im = 0;
- }
- return A;
- }
- void shuffle(complex* A, complex* B, int isize,int lenA, complex** A11, complex** B11){
- /* printf("Entered shuffle\n"); */
- complex *out_A, *out_B, *buf_A, *buf_B;
- out_A = zeros(lenA);
- out_B = zeros(lenA);
- /* display("Out_A",out_A,lenA);
- display("Out_B",out_B,lenA); */
- buf_A = zeros(isize);
- buf_B = zeros(isize);
- /* display("--------------\nbuf_A",buf_A,isize);
- display("buf_B",buf_B,isize); */
- for(int idx = 0; idx < lenA; idx+=isize*2){
- for (int j = idx; j< idx+isize; j++){
- buf_A[j-idx] = A[j];
- buf_B[j-idx] = B[j];
- }
- /* display("--------------\nbuf_A",buf_A,isize);
- display("buf_B",buf_B,isize); */
- for(int j = idx; j< idx+isize; j++){
- out_A[j] = buf_A[j-idx];
- out_B[j] = A[j+isize];
- }
- /* H("--------------\nOut_A",out_A,lenA);
- display("Out_B",out_B,lenA); */
- for(int j = 0; j < isize;j++){
- buf_A[j].Re = buf_B[j].Re;
- buf_A[j].Im = buf_B[j].Im;
- }
- /* display("Buf_A",buf_A,isize); */
- for(int j = idx; j<idx+isize;j++)
- buf_B[j-idx] = B[j+isize];
- /* display("Buf_B",buf_B,isize); */
- for(int j = idx + isize; j < idx +2*isize; j++){
- out_A[j] = buf_A[j-idx-isize];
- out_B[j] = buf_B[j-idx-isize];
- }
- }
- /* display("Out_A",out_A,lenA);
- display("Out_B",out_B,lenA) */;
- *A11=out_A;
- *B11=out_B;
- }
- int* get_odd_twidx (int stage, int n){
- int S = log2(n)-1;
- int *V;
- V=(int*)malloc(sizeof(int)*(n/2));
- for(int i = 0; i < n/2; i++){
- if(i & (1 << (S - stage))){
- V[i] =n/4;
- }
- else{
- V[i] = 0;
- }
- }
- return V;
- }
- void get_even_twidx (int stage, int n, int **twA2, int **twB2){
- int S = log2(n), predict_idx;
- int *oA, *oB;
- oA=(int*)malloc(sizeof(int)*(n/2));
- oB=(int*)malloc(sizeof(int)*(n/2));
- for(int i = 0; i < n/2; i++){
- predict_idx = (1 << (S - stage));
- if((i & predict_idx) == 0){
- oA[i] = 0;
- oB[i] = 2 * (i & (predict_idx - 1)) * pow(4,(int)(stage/2)-1);
- }
- else{
- oA[i] = 1 * (i & (predict_idx - 1)) * pow(4,(int)(stage/2)-1);
- oB[i] = 3 * (i & (predict_idx - 1)) * pow(4,(int)(stage/2)-1);
- }
- }
- *twA2 = oA;
- *twB2 = oB;
- }
- complex* compute_twiddle_fixp(int *k, int n){
- complex *a;
- a = (complex*)malloc(sizeof(complex)*(n/2));
- for(int i = 0; i< n/2; i++){
- a[i].Re= (cos((2 * PI * k[i])/n))*pow(2,nrbits);
- a[i].Im= (-1*(sin((2 * PI * k[i])/n)))*pow(2,nrbits);
- }
- return a;
- }
- complex* fixp_mult (complex *B11, complex *tw_fp, int n){
- complex *V;
- V = (complex*)malloc(sizeof(complex)*n);
- long long int bre,bim,twre,twim, mul1,mul2,mul3,mul4;
- for(int i = 0 ; i < n; i++){
- /* printf("I'm going to multiply %x with %x and I will get %x\n",B11[i].Re, tw_fp[i].Re, multiply(B11[i].Re,tw_fp[i].Re));
- printf("I'm going to multiply %x with %x and I will get %x\n",B11[i].Im, tw_fp[i].Im, multiply(B11[i].Im,tw_fp[i].Im));
- printf("%x minus %x is %x\n",multiply(B11[i].Re,tw_fp[i].Re), multiply(B11[i].Im,tw_fp[i].Im),multiply(B11[i].Re,tw_fp[i].Re) - multiply(B11[i].Im,tw_fp[i].Im)); */
- bre = B11[i].Re; bim = B11[i].Im;
- twre = tw_fp[i].Re; twim = tw_fp[i].Im;
- mul1 = bre * twre;
- mul2 = bim * twim;
- mul3 = bre * twim;
- mul4 = bim * twre;
- V[i].Re = (mul1 - mul2) >> nrbits;
- V[i].Im = (mul3 + mul4) >> nrbits;
- /* printf("I multiplied %x %x and got %llx\n", B11[i].Re, tw_fp[i].Re, mul1);
- printf("I multiplied %x %x and got %llx\n", B11[i].Im, tw_fp[i].Im, mul2);
- printf("I multiplied %x %x and got %llx\n", B11[i].Re, tw_fp[i].Im, mul3);
- printf("I multiplied %x %x and got %llx\n", B11[i].Im, tw_fp[i].Re, mul4);
- printf("V[i].Re = %x V[i].Im = %x\n\n",V[i].Re,V[i].Im); */
- /* V[i].Re = multiply(B11[i].Re,tw_fp[i].Re) - multiply(B11[i].Im,tw_fp[i].Im);
- V[i].Im = (multiply(B11[i].Re,tw_fp[i].Im) + multiply(B11[i].Im,tw_fp[i].Re));//(-1)* */
- }
- return V;
- }
- complex* compact(complex* A, complex* B, int n){
- complex *v;
- v=(complex*)malloc(sizeof(complex)*n*2);
- for(int i =0; i<n;i++){
- v[2*i].Re = A[i].Re;
- v[2*i].Im = A[i].Im;
- v[2*i+1].Re = B[i].Re;
- v[2*i+1].Im = B[i].Im;
- }
- return v;
- }
- complex* fft_butterfly(complex* v, int n){
- complex *A0, *B0, *A1, *B1, *A2, *B2, *A3, *B3, *A4, *B4, *A5, *B5, *A6, *B6, *A7, *B7, *A8, *B8, *A9, *B9, *A10, *B10, *A111, *B111;
- complex *A11, *B11, *A21, *B21, *A31, *B31, *A41, *B41, *A51, *B51, *A61, *B61, *A71, *B71, *A81, *B81, *A91, *B91, *A101, *B101;
- int* twB1, *twA2, *twB2, *twB3,*twA4, *twB4,*twB5, *twA6, *twB6, *twB7, *twA8, *twB8, *twB9, *twA10, *twB10;
- complex *tw_fp, *twa_fp, *twb_fp;
- A0 = (complex*)malloc(sizeof(complex)*n);
- B0 = (complex*)malloc(sizeof(complex)*n);
- A1 = (complex*)malloc(sizeof(complex)*n);
- B1 = (complex*)malloc(sizeof(complex)*n);
- A2 = (complex*)malloc(sizeof(complex)*n);
- B2 = (complex*)malloc(sizeof(complex)*n);
- A3 = (complex*)malloc(sizeof(complex)*n);
- B3 = (complex*)malloc(sizeof(complex)*n);
- A4 = (complex*)malloc(sizeof(complex)*n);
- B4 = (complex*)malloc(sizeof(complex)*n);
- A5 = (complex*)malloc(sizeof(complex)*n);
- B5 = (complex*)malloc(sizeof(complex)*n);
- A6 = (complex*)malloc(sizeof(complex)*n);
- B6 = (complex*)malloc(sizeof(complex)*n);
- A7 = (complex*)malloc(sizeof(complex)*n);
- B7 = (complex*)malloc(sizeof(complex)*n);
- A8 = (complex*)malloc(sizeof(complex)*n);
- B8 = (complex*)malloc(sizeof(complex)*n);
- A9 = (complex*)malloc(sizeof(complex)*n);
- B9 = (complex*)malloc(sizeof(complex)*n);
- A10 = (complex*)malloc(sizeof(complex)*n);
- B10 = (complex*)malloc(sizeof(complex)*n);
- A111 = (complex*)malloc(sizeof(complex)*n);
- B111 = (complex*)malloc(sizeof(complex)*n);
- for(int i = 0;i<n/2; i++){
- A0[i].Re = v[i].Re;
- A0[i].Im = v[i].Im;
- B0[i].Re = v[i+n/2].Re;
- B0[i].Im = v[i+n/2].Im;
- }
- /* display("A0",A0,n/2);
- display("B0",B0,n/2); */
- //------------------STAGE 1--------------------
- butterfly(A0,B0,n/2,&A1,&B1);
- if(log2(n) == 1){
- /* display("A1",A1,n/2);
- display("B1",B1,n/2); */
- return compact(A1,B1,n/2);
- }
- /* display("A1",A1,n/2);
- display("B1",B1,n/2); */
- A11 = (complex*)malloc(sizeof(complex)*(n/2));
- B11 = (complex*)malloc(sizeof(complex)*(n/2));
- shuffle(A1,B1,n/4,n/2,&A11,&B11);
- twB1 = get_odd_twidx(1,n);
- /* display("A11",A11,n/2);
- display("B11",B11,n/2); */
- tw_fp = compute_twiddle_fixp(twB1,n);
- B11 = fixp_mult(B11,tw_fp,n/2);
- //------------------STAGE 2--------------------
- butterfly(A11,B11,n/2,&A2,&B2);
- if(log2(n) == 2){
- /* display("A2",A2,n/2);
- display("B2",B2,n/2); */
- return compact(A2,B2,n/2);
- }
- /* display("A2",A2,n/2);
- display("B2",B2,n/2); */
- get_even_twidx(2,n,&twA2,&twB2);
- twa_fp = compute_twiddle_fixp(twA2,n);
- twb_fp = compute_twiddle_fixp(twB2,n);
- A2= fixp_mult(A2,twa_fp,n/2);
- B2= fixp_mult(B2,twb_fp,n/2);
- /* display("A2",A2,n/2);
- display("B2",B2,n/2) */;
- shuffle(A2,B2,n/8,n/2,&A21,&B21);
- //------------------STAGE 3--------------------
- butterfly(A21,B21,n/2,&A3,&B3);
- /* display("A21",A21,n/2);
- display("B21",B21,n/2); */
- if(log2(n) == 3){
- /* display("A3",A3,n/2);
- display("B3",B3,n/2); */
- return compact(A3,B3,n/2);
- }
- /* display("A3",A3,n/2);
- display("B3",B3,n/2); */
- shuffle(A3,B3,n/16,n/2,&A31,&B31);
- twB3 = get_odd_twidx(3,n);
- tw_fp = compute_twiddle_fixp(twB3,n);
- B31 = fixp_mult(B31,tw_fp,n/2);
- //------------------STAGE 4--------------------
- butterfly(A31,B31,n/2,&A4,&B4);
- if(log2(n) == 4){
- /* display("A4",A4,n/2);
- display("B4",B4,n/2); */
- return compact(A4,B4,n/2);
- }
- get_even_twidx(4,n,&twA4,&twB4);
- twa_fp = compute_twiddle_fixp(twA4,n);
- twb_fp = compute_twiddle_fixp(twB4,n);
- A4= fixp_mult(A4,twa_fp,n/2);
- B4= fixp_mult(B4,twb_fp,n/2);
- shuffle(A4,B4,n/32,n/2,&A41,&B41);
- //------------------STAGE 5--------------------
- butterfly(A41,B41,n/2,&A5,&B5);
- if(log2(n) == 5){
- /* display("A5",A5,n/2);
- display("B5",B5,n/2); */
- return compact(A5,B5,n/2);
- }
- shuffle(A5,B5,n/64,n/2,&A51,&B51);
- twB5 = get_odd_twidx(5,n);
- tw_fp = compute_twiddle_fixp(twB5,n);
- B51 = fixp_mult(B51,tw_fp,n/2);
- butterfly(A51,B51,n/2,&A6,&B6);
- //------------------STAGE 6--------------------
- if(log2(n) == 6){
- /* display("A6",A6,n/2);
- display("B6",B6,n/2); */
- return compact(A6,B6,n/2);
- }
- get_even_twidx(6,n,&twA6,&twB6);
- twa_fp = compute_twiddle_fixp(twA6,n);
- twb_fp = compute_twiddle_fixp(twB6,n);
- A6= fixp_mult(A6,twa_fp,n/2);
- B6= fixp_mult(B6,twb_fp,n/2);
- shuffle(A6,B6,n/128,n/2,&A61,&B61);
- butterfly(A61,B61,n/2,&A7,&B7);
- //------------------STAGE 7--------------------
- if(log2(n) == 7){
- /* display("A7",A7,n/2);
- display("B7",B7,n/2); */
- return compact(A7,B7,n/2);
- }
- shuffle(A7,B7,n/256,n/2,&A71,&B71);
- twB7 = get_odd_twidx(7,n);
- tw_fp = compute_twiddle_fixp(twB7,n);
- B71 = fixp_mult(B71,tw_fp,n/2);
- butterfly(A71,B71,n/2,&A8,&B8);
- //------------------STAGE 8--------------------
- if(log2(n) == 8){
- /* display("A8",A8,n/2);
- display("B8",B8,n/2); */
- return compact(A8,B8,n/2);
- }
- get_even_twidx(8,n,&twA8,&twB8);
- twa_fp = compute_twiddle_fixp(twA8,n);
- twb_fp = compute_twiddle_fixp(twB8,n);
- A8= fixp_mult(A8,twa_fp,n/2);
- B8= fixp_mult(B8,twb_fp,n/2);
- shuffle(A8,B8,n/512,n/2,&A81,&B81);
- butterfly(A81,B81,n/2,&A9,&B9);
- //------------------STAGE 9--------------------
- if(log2(n) == 9){
- /* display("A9",A9,n/2);
- display("B9",B9,n/2); */
- return compact(A9,B9,n/2);
- }
- shuffle(A9,B9,n/1024,n/2,&A91,&B91);
- twB9 = get_odd_twidx(9,n);
- tw_fp = compute_twiddle_fixp(twB9,n);
- B91 = fixp_mult(B91,tw_fp,n/2);
- butterfly(A91,B91,n/2,&A10,&B10);
- //------------------STAGE 10--------------------
- if(log2(n) == 10){
- /* display("A10",A10,n/2);
- display("B10",B10,n/2); */
- return compact(A10,B10,n/2);
- }
- get_even_twidx(10,n,&twA10,&twB10);
- twa_fp = compute_twiddle_fixp(twA10,n);
- twb_fp = compute_twiddle_fixp(twB10,n);
- A10= fixp_mult(A10,twa_fp,n/2);
- B10= fixp_mult(B10,twb_fp,n/2);
- shuffle(A10,B10,n/2048,n/2,&A101,&B101);
- butterfly(A101,B101,n/2,&A111,&B111);
- //------------------STAGE 11--------------------
- if(log2(n) == 11){
- /* display("A11",A111,n/2);
- display("B11",B111,n/2); */
- return compact(A111,B111,n/2);
- }
- }
- void go_fft_butterfly (char* filename, int nr, int nrb) {
- nrbits = nrb;
- butterfly_log=fopen("butterfly_log.txt","w");
- //reorder = (strcmp("REORDER_BYPASS_OFF",argv[2]) == 0);
- reorder = 1;
- complex* v;
- v = (complex*)malloc(sizeof(complex) * nr);
- FILE* readf = fopen(filename, "r");
- FILE* writef = fopen("fft.txt", "w");
- readfileFFT(readf, nr, v);
- print_vector("INPUT FFT :", v, nr);
- v = fft_butterfly(v,nr);
- //display("\nThis is FFT_fp output",v,nr);
- print_vector_out("\nOUTPUT FFT MODEL:", v, nr);
- writefileFFT(writef, nr, v);
- printf("-- Used %d/%d mode.\n",32-nrbits,nrbits);
- free(v);
- fclose(readf);
- fclose(writef);
- }
- /////////////////////////////////////////FFT//////////////////////////////////////////////////////
- /////////////////////////////////////////DCT//////////////////////////////////////////////////////
- complex* good_dct(complex *v, int N){
- complex *fft_Y;
- complex *retval;
- retval=(complex*)malloc(sizeof(complex)*N);
- fft_Y = (complex*)malloc(sizeof(complex)*N*2);
- for(int i = 0; i < N;i++)
- fft_Y[i] = v[i];
- fft_Y = fft_butterfly(fft_Y,N*2);
- long long int yre,yim,mycos,mysin, mul1,mul2,mul3,mul4;
- for(int k = 0 ;k < N; k++){
- yre = fft_Y[reorder_i(k,log2(N*2))].Re; yim = fft_Y[reorder_i(k,log2(N*2))].Im;
- mycos = cos(k*PI/(2*N))*pow(2,nrbits);
- mysin = sin(k*PI/(2*N))*pow(2,nrbits);
- printf("\nmycos[%d]=[%x]%d ",k,mycos,mycos);
- printf("mysin[%d]=[%x]%d \n",k,mysin,mysin);
- mul1 = yre * mycos;
- mul2 = yim * mysin;
- //mul3 = yim * mycos;
- //mul4 = yre * mysin;
- retval[k].Re = 2* ((mul1 + mul2)>>nrbits);
- //fft_Y[k].Im = (mul3 - mul4)>>nrbits;
- }
- return retval;
- }
- void go_good_dct (char* filename, int nr, int nrb) {
- int write_poz, aux = log2(nr);
- float re;
- nrbits = nrb;
- butterfly_log=fopen("dct_log.txt","w");
- //reorder = (strcmp("REORDER_BYPASS_OFF",argv[2]) == 0);
- reorder = 0;
- complex* v;
- v = (complex*)malloc(sizeof(complex) * nr);
- FILE* readf = fopen(filename, "r");
- FILE* writef = fopen("dct.txt", "w");
- readfileFFT(readf, nr, v);
- print_vector("INPUT DCT :", v, nr);
- v = good_dct(v,nr);
- printf("\nOUTPUT DCT MODEL:\n");
- for (int i = 0; i < nr; i++){
- if (reorder)
- write_poz = reorder_i(i, aux);
- else
- write_poz = i;
- re = v[write_poz].Re;
- printf("[0x%04x]:%5.6f ",to_fp16(re)&0xffff, from_fp16(to_fp16(re)));
- if((i+1)%4 == 0)
- printf("\n");
- }
- putchar('\n');
- writefileDCT(writef, nr, v);
- printf("-- Used %d/%d mode.\n",32-nrbits,nrbits);
- free(v);
- fclose(readf);
- fclose(writef);
- }
- /////////////////////////////////////////DCT//////////////////////////////////////////////////////
- void fft(complex* v, int n, complex* tmp)
- {
- if (n > 1) {
- int k, m, aux1, aux2;
- float aux;
- complex z, w, * vo, * ve;
- ve = tmp; vo = tmp + n / 2;
- for (k = 0; k < n / 2; k++) {
- ve[k] = v[2 * k];
- vo[k] = v[2 * k + 1];
- }
- fft(ve, n / 2, v); /* FFT on even-indexed elements of v[] */
- fft(vo, n / 2, v); /* FFT on odd-indexed elements of v[] */
- for (m = 0; m < n / 2; m++) {
- aux = cos(2 * PI * m / (double)n);
- w.Re = float_to_fixed(aux);
- aux = -sin(2 * PI * m / (double)n);
- w.Im = float_to_fixed(aux);
- aux1 = multiply(w.Re , vo[m].Re);
- aux2 = multiply(w.Im , vo[m].Im);
- z.Re = aux1 - aux2; /* Re(w*vo[m]) */
- aux1 = multiply(w.Re , vo[m].Im);
- aux2 = multiply(w.Im , vo[m].Re);
- z.Im = aux1 + aux2; /* Im(w*vo[m]) */
- v[m].Re = ve[m].Re + z.Re;
- v[m].Im = ve[m].Im + z.Im;
- v[m + n / 2].Re = ve[m].Re - z.Re;
- v[m + n / 2].Im = ve[m].Im - z.Im;
- }
- }
- return;
- }
- void go_fft(char* filename, int nr) {
- complex* v, * scratch;
- float re, im;
- v = (complex*)malloc(sizeof(complex) * nr);
- scratch = (complex*)malloc(sizeof(complex) * nr);
- FILE* readf = fopen(filename, "r");
- FILE* writef = fopen("fft.txt", "w");
- readfileFFT(readf, nr, v);//Deci cica pana aci mere
- print_vector("INPUT FFT :", v, nr);
- fft(v, nr, scratch);
- writefileFFT(writef, nr, v);
- print_vector_out("OUTPUT FFT MODEL:", v, nr);
- /*
- for (int i = nr-1; i >= 0; i--) {
- fprintf(writef2, "%x ", 0xffff & to_fp16(v[i].Im));
- fprintf(writef2, "%x ", 0xffff & to_fp16(v[i].Re));
- //printf("%f %f <> ", v[write_poz].Re, v[write_poz].Im);
- }
- */
- free(v);
- free(scratch);
- fclose(readf);
- fclose(writef);
- }
- complex overflow[20]={0};
- void ifft(complex* v, int n, complex* tmp)
- { int k, m, aux1, aux2;
- complex vaux, signbit;
- float aux;
- complex z, w, * vo, * ve;
- if (n > 1) { /* otherwise, do nothing and return */
- ve = tmp; vo = tmp + n / 2;
- for (k = 0; k < n / 2; k++) {
- ve[k] = v[2 * k];
- vo[k] = v[2 * k + 1];
- }
- ifft(ve, n / 2, v); /* FFT on even-indexed elements of v[] */
- ifft(vo, n / 2, v); /* FFT on odd-indexed elements of v[] */
- for (m = 0; m < n / 2; m++) {
- aux = cos(2 * PI * m / (double)n);
- w.Re = float_to_fixed(aux);
- aux = sin(2 * PI * m / (double)n);
- w.Im = float_to_fixed(aux);
- aux1 = multiply(w.Re , vo[m].Re);
- aux2 = multiply(w.Im , vo[m].Im);
- z.Re = aux1 - aux2; /* Re(w*vo[m]) */
- /* printf("\nI substract %d %d and i get %d",aux1,aux2,z.Re); */
- aux1 = multiply(w.Re , vo[m].Im);
- aux2 = multiply(w.Im , vo[m].Re);
- z.Im = aux1 + aux2; /* Im(w*vo[m]) */
- /* printf("\nI add %d %d and i get %d",aux1,aux2,z.Im); */
- v[m].Re = ve[m].Re + z.Re;
- v[m].Im = ve[m].Im + z.Im;
- long long int check1, check2, laux1, laux2, ldifre, ldifim;
- laux1 = ve[m].Re;
- laux2 = z.Re;
- check1 = laux1 + laux2;
- laux1 = ve[m].Im;
- laux2 = z.Im;
- check2 = laux1 + laux2;
- v[m].Re = ve[m].Re + z.Re;
- v[m].Im = ve[m].Im + z.Im;
- signbit.Re = 0x1&((ve[m].Re>>31) ^ (z.Re>>31));
- signbit.Im = 0x1&((ve[m].Im>>31) ^ (z.Im>>31));
- if(signbit.Re == 0 && (0x1&(ve[m].Re>>31) != (0x1&v[m].Re>>31)) && (long long int)(v[m].Re) != check1){
- overflow[m].Re = 1;
- printf("Overflow Real! signbit = %d, %d != %d",signbit.Re,0x1&(ve[m].Re>>31),(0x1&v[m].Re>>31));
- printf("\nI add %d %d and i get %d %lld -- Re --- overflow is %d for m=%d and n=%d\n",ve[m].Re,z.Re,v[m].Re, check1, overflow[m].Re, m, n);
- }
- if(signbit.Im == 0 && (0x1&(ve[m].Im>>31) != 0x1&(v[m].Im>>31)) && (long long int)(v[m].Im) != check2){
- overflow[m].Im = 1;
- printf("Overflow Imaginary! signbit = %d, %d != %d",signbit.Im,0x1&(ve[m].Im>>31),(0x1&v[m].Im>>31));
- printf("\nI add %d %d and i get %d %lld -- Im --- overflow is %d for m=%d and n=%d\n",ve[m].Im,z.Im,v[m].Im, check2, overflow[m].Im, m, n);
- }
- v[m + n / 2].Re = ve[m].Re - z.Re;
- v[m + n / 2].Im = ve[m].Im - z.Im;
- }
- }
- return;
- }
- void my_ifft(complex* v, int nr, complex* tmp) {
- ifft(v, nr, tmp);
- for (int k = 0; k < nr; k++) {
- v[k].Re /= nr;
- v[k].Im /= nr;
- }
- }
- void go_ifft(char* filename, int nr) {
- complex* v, *scratch;
- v = (complex*)malloc(sizeof(complex) * nr);
- scratch = (complex*)malloc(sizeof(complex) * nr);
- printf("%s-------------------",filename);
- FILE* readf = fopen(filename, "r");
- FILE* writef = fopen("ifft.txt", "w");
- /* FILE* writef2 = fopen("ifft_out_check_inp.txt", "w"); */
- readfileFFT(readf, nr, v);
- print_vector("\nINPUT IFFT:", v, nr);
- my_ifft(v, nr, scratch);
- print_vector_out("OUTPUT IFFT:", v, nr);
- writefileFFT(writef, nr, v);
- /* for (int i = nr - 1; i >= 0; i--) {
- fprintf(writef2, "%x ", 0xffff & to_fp16(v[i].Im));
- fprintf(writef2, "%x ", 0xffff & to_fp16(v[i].Re));
- //printf("%f %f <> ", v[write_poz].Re, v[write_poz].Im);
- } */
- free(v);
- free(scratch);
- fclose(readf);
- fclose(writef);
- /* fclose(writef2); */
- //printf("\n");
- }
- /* int main(int argc, char** argv)
- {
- reorder = (strcmp("REORDER_BYPASS_OFF",argv[2]) == 0);
- //go_fft(argv[3], atoi(argv[1]));
- //go_ifft(argv[4], atoi(argv[1]));
- go_good_dct(argv[3],atoi(argv[1]),24);
- //go_dct(argv[5], atoi(argv[1]));
- //go_idct(argv[6], atoi(argv[1]));
- } */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement