정확하지 않은 코드일 수 있으니 참고용으로 보시기 바랍니다~
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <math.h> #define SIGNAL_COUNT 100000 double gaussian(); double uniform(); // main 함수 ---------------------------------------- int main(void) { // 반복문용 변수들 int i, i1, diff; int j; int k, m; int l; int posi; int check1 = 1; int check2; int error_count; // 에러체크 double ber[11]; // BER int con_length; int decision; double EbN0, noise_pow; int* s_d_signal; int* con_out; double* s_a_signal; double* r_a_signal; int* pre_recon; int* check_code; int* check_result; int* route; int* route_sum_main; int* route_sum_sub; int route_sum_small; int last; int pos; int* r_d_signal; int state; // 에러확인 변수 FILE * file = fopen("output.txt", "wt"); if (file == NULL){ printf("파일 열기가 실패하였습니다.\n"); return 1; } printf("Constraint Length를 입력하세요.(3,5,7,9 중에서) : "); scanf("%d", &con_length); printf("신호결정 방식을 입력하세요.(1.hard/2.soft) : "); scanf("%d", &decision); // 부호처리용 수치 얻기 for (i = 0; i< con_length; i++){ check1 = check1 * 2; } // sender의 digital 신호 메모리 공간 할당 s_d_signal = (int *)calloc(SIGNAL_COUNT + ((con_length - 1) * 2), sizeof(int)); // 부호화한 값을 담을 공간 할당 con_out = (int *)calloc((SIGNAL_COUNT + (con_length - 1)) * 2, sizeof(int)); // sender의 analog 신호 메모리 공간 할당 s_a_signal = (double *)calloc((SIGNAL_COUNT + (con_length - 1)) * 2, sizeof(double)); // sender의 analog 신호 메모리 공간 할당 s_a_signal = (double *)calloc((SIGNAL_COUNT + (con_length - 1)) * 2, sizeof(double)); // receiver의 analog 신호 메모리 공간 할당 r_a_signal = (double *)calloc((SIGNAL_COUNT + (con_length - 1)) * 2, sizeof(double)); // receiver의 digital 신호 메모리 공간 할당 pre_recon = (int *)calloc((SIGNAL_COUNT + (con_length - 1)) * 2, sizeof(int)); // 부호확인용 비트열 메모리 공간 할당 check_code = (int *)calloc(con_length, sizeof(int)); // 얻어낸 부호값 저장 메모리 공간 할당 check_result = (int *)calloc(check1 * 2, sizeof(int)); // 경로 저장공간할당 route = (int *)calloc(((SIGNAL_COUNT + (con_length - 1))*(check1 / 2)), sizeof(int)); // 거리합 저장공간할당 route_sum_main = (int *)calloc((check1 / 2), sizeof(int)); route_sum_sub = (int *)calloc((check1 / 2), sizeof(int)); // 최종수신비트 저장공간 할당 r_d_signal = (int *)calloc(SIGNAL_COUNT + ((con_length - 1) * 2), sizeof(int)); for (j = 0; j< 11; j++){ EbN0 = pow(10.0, (double)j / 10.0); noise_pow = sqrt(1.0 / (2.0*EbN0)); // seed 값을 시간 함수로 처리 srand((int)time(NULL)); // 0과 1의 디지털 신호를 랜덤으로 생성 for (i = (con_length - 1); i< SIGNAL_COUNT + (con_length - 1); i++){ s_d_signal[i] = rand() % 2; } for (k = 0; k< SIGNAL_COUNT + (con_length - 1); k++){ switch (con_length) { case 3: con_out[(k * 2)] = (s_d_signal[k] + s_d_signal[k + 1] + s_d_signal[k + 2]) % 2; con_out[(k * 2) + 1] = (s_d_signal[k] + s_d_signal[k + 2]) % 2; break; case 5: con_out[(k * 2)] = (s_d_signal[k] + s_d_signal[k + 2] + s_d_signal[k + 3] + s_d_signal[k + 4]) % 2; con_out[(k * 2) + 1] = (s_d_signal[k] + s_d_signal[k + 1] + s_d_signal[k + 4]) % 2; break; case 7: con_out[(k * 2)] = (s_d_signal[k] + s_d_signal[k + 3] + s_d_signal[k + 4] + s_d_signal[k + 5] + s_d_signal[k + 6]) % 2; con_out[(k * 2) + 1] = (s_d_signal[k] + s_d_signal[k + 1] + s_d_signal[k + 3] + s_d_signal[k + 4] + s_d_signal[k + 6]) % 2; break; case 9: con_out[(k * 2)] = (s_d_signal[k] + s_d_signal[k + 1] + s_d_signal[k + 3] + s_d_signal[k + 5] + s_d_signal[k + 6] + s_d_signal[k + 7] + s_d_signal[k + 8]) % 2; con_out[(k * 2) + 1] = (s_d_signal[k] + s_d_signal[k + 4] + s_d_signal[k + 5] + s_d_signal[k + 6] + s_d_signal[k + 8]) % 2; break; } } // 0은 -1로, 1은 1로 mapping for (i = 0; i< (SIGNAL_COUNT + (con_length - 1)) * 2; i++){ if (con_out[i] == 0){ s_a_signal[i] = -1.0; } else{ s_a_signal[i] = 1.0; } } // 가우시안 통과 for (i = 0; i< (SIGNAL_COUNT + (con_length - 1)) * 2; i++){ r_a_signal[i] = s_a_signal[i] + (gaussian()*noise_pow); } switch (decision) { case 1: // digital 신호 결정 (hard) for (i = 0; i< (SIGNAL_COUNT + (con_length - 1)) * 2; i++){ if (r_a_signal[i] & gt; 0){ // s : 가우시간 무시, r : 가우시안 통과 pre_recon[i] = 1; } else{ pre_recon[i] = 0; } } break; case 2: // digital 신호 결정 (soft) for (i = 0; i< (SIGNAL_COUNT + (con_length - 1)) * 2; i++){ if (r_a_signal[i] & gt; = 0.8571){ // s : 가우시간 무시, r : 가우시안 통과 pre_recon[i] = 7; } else if ((r_a_signal[i] & lt; 0.8571) && (r_a_signal[i] & gt; = 0.5714)){ pre_recon[i] = 6; } else if ((r_a_signal[i] & lt; 0.5714) && (r_a_signal[i] & gt; = 0.2857)){ pre_recon[i] = 5; } else if ((r_a_signal[i] & lt; 0.2857) && (r_a_signal[i] & gt; = 0)){ pre_recon[i] = 4; } else if ((r_a_signal[i] & lt; 0) && (r_a_signal[i] & gt; = -0.2857)){ pre_recon[i] = 3; } else if ((r_a_signal[i] & lt; -0.2857) && (r_a_signal[i] & gt; = -0.5714)){ pre_recon[i] = 2; } else if ((r_a_signal[i] & lt; -0.5714) && (r_a_signal[i] & gt; = -0.8571)){ pre_recon[i] = 1; } else if (r_a_signal[i] & lt; -0.8571){ pre_recon[i] = 0; } } break; } // 복호처리시작================================================================= // 비트열당 부호변환값 얻기 switch (decision) { case 1: k = 0; for (i = 0; i< check1; i++){ // 십진수 나열을 이진수형태로 변환 check2 = i; posi = con_length - 1; for (l = 0; l< con_length; l++) { if (check2 > = 1){ check_code[posi] = check2 % 2; check2 = check2 / 2; } else{ check_code[posi] = 0; } posi = posi - 1; } switch (con_length) { case 3: check_result[(i * 2)] = (check_code[0] + check_code[1] + check_code[2]) % 2; check_result[(i * 2) + 1] = (check_code[0] + check_code[2]) % 2; break; case 5: check_result[(i * 2)] = (check_code[0] + check_code[2] + check_code[3] + check_code[4]) % 2; check_result[(i * 2) + 1] = (check_code[0] + check_code[1] + check_code[4]) % 2; break; case 7: check_result[(i * 2)] = (check_code[0] + check_code[3] + check_code[4] + check_code[5] + check_code[6]) % 2; check_result[(i * 2) + 1] = (check_code[0] + check_code[1] + check_code[3] + check_code[4] + check_code[6]) % 2; break; case 9: check_result[(i * 2)] = (check_code[0] + check_code[1] + check_code[3] + check_code[5] + check_code[6] + check_code[7] + check_code[8]) % 2; check_result[(i * 2) + 1] = (check_code[0] + check_code[4] + check_code[5] + check_code[6] + check_code[8]) % 2; break; } } break; case 2: k = 0; for (i = 0; i< check1; i++){ // 십진수 나열을 이진수형태로 변환 check2 = i; posi = con_length - 1; for (l = 0; l< con_length; l++) { if (check2 > = 1){ check_code[posi] = check2 % 2; check2 = check2 / 2; } else{ check_code[posi] = 0; } posi = posi - 1; } switch (con_length) { case 3: check_result[(i * 2)] = 7 * ((check_code[0] + check_code[1] + check_code[2]) % 2); check_result[(i * 2) + 1] = 7 * ((check_code[0] + check_code[2]) % 2); break; case 5: check_result[(i * 2)] = 7 * ((check_code[0] + check_code[2] + check_code[3] + check_code[4]) % 2); check_result[(i * 2) + 1] = 7 * ((check_code[0] + check_code[1] + check_code[4]) % 2); break; case 7: check_result[(i * 2)] = 7 * ((check_code[0] + check_code[3] + check_code[4] + check_code[5] + check_code[6]) % 2); check_result[(i * 2) + 1] = 7 * ((check_code[0] + check_code[1] + check_code[3] + check_code[4] + check_code[6]) % 2); break; case 9: check_result[(i * 2)] = 7 * ((check_code[0] + check_code[1] + check_code[3] + check_code[5] + check_code[6] + check_code[7] + check_code[8]) % 2); check_result[(i * 2) + 1] = 7 * ((check_code[0] + check_code[4] + check_code[5] + check_code[6] + check_code[8]) % 2); break; } } break; } //핵심부분 시작======================================================================== //거리합 초기화 for (m = 1; m< check1 / 2; m++){ route_sum_main[m] = 255; } // 비교시작 switch (decision) { case 1: for (i = 0; i< SIGNAL_COUNT + (con_length - 1); i++){ // 거리차 처리하기 위해 옮겨놓음 for (i1 = 0; i1< check1 / 2; i1++) { route_sum_sub[i1] = route_sum_main[i1]; } for (i1 = 0; i1< check1 / 2; i1++){ //차이처리 diff = 0; if (pre_recon[i * 2] != check_result[i1 * 2]){ diff++; } if (pre_recon[i * 2 + 1] != check_result[i1 * 2 + 1]){ diff++; } //차이가 0일때 if (diff == 0){ route_sum_main[i1] = route_sum_sub[i1 / 2]; route[i1*(SIGNAL_COUNT + (con_length - 1)) + i] = i1; } //차이가 1일때 if (diff == 1){ if (route_sum_sub[i1 / 2] & lt; = route_sum_sub[(i1 + check1 / 2) / 2]){ route_sum_main[i1] = route_sum_sub[i1 / 2] + diff; route[i1*(SIGNAL_COUNT + (con_length - 1)) + i] = i1; } else{ route_sum_main[i1] = route_sum_sub[(i1 + check1 / 2) / 2] + diff; route[i1*(SIGNAL_COUNT + (con_length - 1)) + i] = i1 + check1 / 2; } } //차이가 2일때 if (diff == 2){ route_sum_main[i1] = route_sum_sub[(i1 + check1 / 2) / 2]; route[i1*(SIGNAL_COUNT + (con_length - 1)) + i] = i1 + check1 / 2; } } } break; case 2: for (i = 0; i< SIGNAL_COUNT + (con_length - 1); i++){ // 거리차 처리하기 위해 옮겨놓음 for (i1 = 0; i1< check1 / 2; i1++) { route_sum_sub[i1] = route_sum_main[i1]; } for (i1 = 0; i1< check1 / 2; i1++){ //차이처리 if ((pre_recon[i * 2] - check_result[i1 * 2])*(pre_recon[i * 2] - check_result[i1 * 2]) + (pre_recon[i * 2 + 1] - check_result[i1 * 2 + 1])*(pre_recon[i * 2 + 1] - check_result[i1 * 2 + 1]) < (pre_recon[i * 2] - check_result[(i1 + check1 / 2) * 2])*(pre_recon[i * 2] - check_result[(i1 + check1 / 2) * 2]) + (pre_recon[i * 2 + 1] - check_result[(i1 + check1 / 2) * 2 + 1])*(pre_recon[i * 2 + 1] - check_result[(i1 + check1 / 2) * 2 + 1])) { route_sum_main[i1] = route_sum_sub[i1 / 2] + (pre_recon[i * 2] - check_result[i1 * 2])*(pre_recon[i * 2] - check_result[i1 * 2]) + (pre_recon[i * 2 + 1] - check_result[i1 * 2 + 1])*(pre_recon[i * 2 + 1] - check_result[i1 * 2 + 1]); route[i1*(SIGNAL_COUNT + (con_length - 1)) + i] = i1; } else if ((pre_recon[i * 2] - check_result[i1 * 2])*(pre_recon[i * 2] - check_result[i1 * 2]) + (pre_recon[i * 2 + 1] - check_result[i1 * 2 + 1])*(pre_recon[i * 2 + 1] - check_result[i1 * 2 + 1]) > (pre_recon[i * 2] - check_result[(i1 + check1 / 2) * 2])*(pre_recon[i * 2] - check_result[(i1 + check1 / 2) * 2]) + (pre_recon[i * 2 + 1] - check_result[(i1 + check1 / 2) * 2 + 1])*(pre_recon[i * 2 + 1] - check_result[(i1 + check1 / 2) * 2 + 1])) { route_sum_main[i1] = route_sum_sub[(i1 + check1 / 2) / 2] + (pre_recon[i * 2] - check_result[(i1 + check1 / 2) * 2])*(pre_recon[i * 2] - check_result[(i1 + check1 / 2) * 2]) + (pre_recon[i * 2 + 1] - check_result[(i1 + check1 / 2) * 2 + 1])*(pre_recon[i * 2 + 1] - check_result[(i1 + check1 / 2) * 2 + 1]); route[i1*(SIGNAL_COUNT + (con_length - 1)) + i] = (i1 + check1 / 2); } else { if (route_sum_sub[i1 / 2] & lt; = route_sum_sub[(i1 + check1 / 2) / 2]) { route_sum_main[i1] = route_sum_sub[i1 / 2] + (pre_recon[i * 2] - check_result[i1 * 2])*(pre_recon[i * 2] - check_result[i1 * 2]) + (pre_recon[i * 2 + 1] - check_result[i1 * 2 + 1])*(pre_recon[i * 2 + 1] - check_result[i1 * 2 + 1]); route[i1*(SIGNAL_COUNT + (con_length - 1)) + i] = i1; } else{ route_sum_main[i1] = route_sum_sub[(i1 + check1 / 2) / 2] + (pre_recon[i * 2] - check_result[(i1 + check1 / 2) * 2])*(pre_recon[i * 2] - check_result[(i1 + check1 / 2) * 2]) + (pre_recon[i * 2 + 1] - check_result[(i1 + check1 / 2) * 2 + 1])*(pre_recon[i * 2 + 1] - check_result[(i1 + check1 / 2) * 2 + 1]); route[i1*(SIGNAL_COUNT + (con_length - 1)) + i] = i1 + check1 / 2; } } } } break; } //역 경로추적 및 비트결정 last = SIGNAL_COUNT + 2 * (con_length - 1) - 1; route_sum_small = route_sum_main[0]; pos = 0; for (i = 0; i< check1 / 2 - 1; i++){ if (route_sum_main[i + 1] & lt; route_sum_small){ route_sum_small = route_sum_main[i + 1]; pos = i + 1; } } for (i = SIGNAL_COUNT + (con_length - 2); i > = 0; i--) { r_d_signal[last] = route[pos*(SIGNAL_COUNT + (con_length - 1)) + i] % 2; pos = route[pos*(SIGNAL_COUNT + (con_length - 1)) + i] / 2; last--; } //핵심부분 끝======================================================================= // BER 측정 error_count = 0; for (i = (con_length - 1); i< SIGNAL_COUNT + (con_length - 1); i++){ if (s_d_signal[i] != r_d_signal[i]){ error_count++; } } ber[j] = (double)error_count / SIGNAL_COUNT; printf("BER : %f \n", ber[j]); } for (i = 0; i< 11; i++){ if (i != 10){ fprintf(file, "%f ", ber[i]); } else{ fprintf(file, "%f", ber[i]); } } state = fclose(file); if (state != 0){ printf("파일 닫기가 실패하였습니다.\n"); return 1; } free(s_d_signal); free(s_a_signal); free(r_a_signal); free(pre_recon); free(check_code); free(check_result); free(route); free(route_sum_main); free(route_sum_sub); free(r_d_signal); free(con_out); return 0; } // gaussian 함수 ---------------------------------------- double gaussian() { static int ready = 0; static double gstore; double v1, v2, r, fac, gaus; double uniform(); if (ready == 0) { do { v1 = 2.*uniform(); v2 = 2.*uniform(); r = v1*v1 + v2*v2; } while (r > 1.0); fac = sqrt(-2.*log(r) / r); gstore = v1*fac; gaus = v2*fac; ready = 1; } else { ready = 0; gaus = gstore; } return(gaus); } // uniform 함수 ---------------------------------------- double uniform() { return((double)(rand() & RAND_MAX) / RAND_MAX - 0.5); }
'C언어' 카테고리의 다른 글
이중 포인터 간단정리 (0) | 2014.10.23 |
---|---|
2의 보수를 이용한 부호 바꾸기 (0) | 2014.09.26 |
QPSK (0) | 2014.09.04 |
BPSK (0) | 2014.09.03 |
매크로(macro) #define (0) | 2014.08.21 |