#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <iostream>
#include <iomanip>
#include "awgn.h"

using namespace std;
// fixed-point header file
// Qm.f
// m: the number of bits for integer
// f: the number of bits for fraction 

typedef signed short fx_t;

#define M 3  // m
#define F 2  // f



#define F_MAX ( ( 1 << (M+F) ) - 1 )
#define F_MIN ( -1 * ( 1<<(M+F) ))
#define Fl2Fx(x) (fx_t) (x >= 0) ? ( (x * (1 << F)) + 0.5 ) : ( (x * (1 << F)) - 0.5 )    //floating to fixed-point (using integer)
#define Fx2Fl(x)  (((float)x)/(1 << F))


fx_t sat_check(fx_t x)
{
    if (x > F_MAX)
        return F_MAX;
    else if (x < F_MIN)
        return F_MIN;
    else
        return x;
}

int main(void){

    float R = 0.5;
    double snr = 3.0;
    double sigma;

    double max = 0;


    const int N = 100; //length

    float sample[N] = { 0 };
    fx_t f_sample[N] = { 0 };  //fixed point
    fx_t q_sample[N] = { 0 };  // quantized

    int q_bit = 4; // the number of bit for quatization
    int q_max = pow(2, q_bit) - 1;

    //fixed-point 에서의 maximum 값, overflow 처리 필요.

    cout << "Max. Fixed-Point :" << F_MAX << endl;
    cout << "Min. Fixed-Point :" << F_MIN << endl;
    //getchar();
    sigma = pow(10, -0.05*snr) / sqrt(2 * R);

    //cout << "Orig.\t\tFixed\t\tFx_int\t\tFx_fl" << endl;
    for (int i = 0; i < N; i++)
    {
        float temp;
        sample[i] = 1 + gaussian(0, sigma);

        f_sample[i] = Fl2Fx(sample[i]);
        //temp = (int)(sample[i] * (1 << F));
        //temp = (float)temp / (1 << F);
        //cout << setw(8) << sample[i] << "\t" << temp << "\t\t";

        //printf("%d\t\t", f_sample[i]);
        //printf("%f\n", Fx2Fl(f_sample[i]));
        //putchar('\n');
    }
    cout << "F_samp\t\tOrig.\t\tSat" << endl;
    fx_t temp = 0;
    for (int i = 0; i < N; i++)
    {

        temp += f_sample[i];
        cout << f_sample[i]<<"\t\t"<<temp << "\t\t" << sat_check(temp) << endl;
        getchar();
    }
    cout << endl;
    cout << "maximum:  " << max << endl;

    return 0;
}

fixed_point_proto.md


'C and C++' 카테고리의 다른 글

Fixed-point in C/C++  (0) 2016.04.05
main function arguments  (0) 2016.03.11
OpenMP in Macbook  (0) 2016.03.10
OpenMP  (0) 2016.03.09
C언어 최적화 기법  (0) 2016.02.05

fixed-point in C

original material: artist-embedded.org/EmbeddedControl Slides
reference 1: fixedpt.html
reference 2: Q_format

1. Fixed-point Representation

  • x: real number
  • X: fixed-point number
  • N: wordlength
  • m: integer (excluding sign bit)
  • f: number of fraction bit
  • “Q-format” : Qm.n
0/1101/011
sign bit/4bit integer/3bit fraction

2. Conversion to and from fixed-point

  • real to fixed

    • Multiply the floating point number by 2^f
    • Round to the nearest integer

      X=round(x˙2f)

  • fixed to real

    x=X˙2f

example) 13.4 to Q4.3 format

X=round(13.4˙23)=107(=011010112)

3. Range of fixed-point representation

  • negative number: 2’s complement

    • N=8, 2^(-8) ~ 2^(8-1)
      binary representation decimal
      00000000 0
      00000001 1
      00000010 2
      01111111 127
      10000000 -128
      10000001 -127
      11111111 -1
  • range of Qm.f [ref]

    [2m,2m2f]

4. Arithmetic operations of fixed-point

  • Satuation check
int16_t sat16(int32_t x)
{
    if (x > 0x7FFF) return 0x7FFF;
    else if (x < 0x8000) return 0x8000;
    else return (int16_t)x;
}
  • Addition
int16_t q_add_sat(int16_t a, int16_t b)
{
    int16_t result;
    int32_t tmp;

    tmp = (int32_t)a + (int32_t)b;
    if (tmp > 0x7FFF)
        tmp = 0x7FFF;
    if (tmp < -1 * 0x8000)
        tmp = -1 * 0x8000;
    result = (int16_t)tmp;

    return result;
}
  • Subtraction
int16_t q_sub(int16_t a, int16_t b)
{
    int16_t result;
    result = a - b;
    return result;
}
  • Multiplication
// precomputed value:
#define K   (1 << (f - 1))    // f: fraction of fixed-point

int16_t q_mul(int16_t a, int16_t b)
{
    int16_t result;
    int32_t temp;

    temp = (int32_t)a * (int32_t)b; // result type is operand's type
    // Rounding; mid values are rounded up
    temp += K;
    // Correct by dividing by base and saturate result
    result = sat16(temp >> Q);

    return result;
}
  • Division
int16_t q_div(int16_t a, int16_t b)
{
    int16_t result;
    int32_t temp;

    // pre-multiply by the base (Upscale to Q16 so that the result will be in Q8 format)
    temp = (int32_t)a << Q;
    // Rounding: mid values are rounded up (down for negative values).
    if ((temp >= 0 && b >= 0) || (temp < 0 && b < 0))
        temp += b / 2;
    else
        temp -= b / 2;
    result = (int16_t)(temp / b);

    return result;
}

'C and C++' 카테고리의 다른 글

Fixed Point Prototype  (0) 2016.04.09
main function arguments  (0) 2016.03.11
OpenMP in Macbook  (0) 2016.03.10
OpenMP  (0) 2016.03.09
C언어 최적화 기법  (0) 2016.02.05

bash script를 이용해 실험 여러 번 돌리기.

컴퓨터 한테 한꺼번에 많은 일들을 시키기 위해 결국 bash 스크립트도 조금 알아보았다. 대단한 것은 아니고, 인자들을 바꾸어가며 실험을 여러 번 돌리고, 매 번 실행되는 결과 파일을 파라메터에 맞게 네이밍 하는 것.

생각보다 bash script로는 많은 것을 할 수도 있었지만, 제약사항도 조금 있었다. 다들 그래서 python 을 사용하나보다.

#! /bin/bash

for (( i = 1.8 ; i <= 3.0 ; i+=0.2 ))
do
    ./a.out $i 2.3
    f=1.8+$i
    mv a.txt hey_$f.txt
#done

배포할 목적이 아니라 예외처리는 전혀 안되어 있지만, 그리고 실제로 실험에 사용한 코드도 이것이 아니긴 하지만, 무튼 이런 식으로 할 수 있다는 것. (()) 이 중첩 괄호 사이에 넣으면 C 구문도 넣을 수 있다고… 하지만 실수 연산이 안되기 때문에 뭔가 다른 방법을 사용했던 것 같은데, 지금 나는 절실히 필요한 것이 아니니 다음 기회로 넘기자.

우선 a.out 이라는 프로그램은 인자가 두 개 들어가는 실행 프로그램이다. $i 는 bash script 에서는 변수 i 를 뜻한다. 연산은 안되지만 실행할 때 대입은 되는 신기한 상황. 무튼, 변수를 바꿔가며 조건을 만족할 때까지 실행한다.

a.out 은 실험 결과로 a.txt를 생성하는데, 실행이 끝날 때마다 a.txthey_$f.txt로 이름을 바꾸어준다.

주말동안 열심히 서버에다가 일을 시켜 두었으니, 월요일에 출근해서 살펴봐야겠다.

윈도우용 .bat 파일도 이런 식으로 스크립트를 만들 수 있는 것 같으니, 서버 말고 연구실 메인 컴퓨터도 실험을 돌리자.

Do or do not. There’s no try. 아자.

'etc.' 카테고리의 다른 글

csh: Event Not Found  (0) 2020.11.24
VS code  (0) 2018.11.02

+ Recent posts