DSPRelated.com
Forums

How do I solve this fixed point problem

Started by John McDermick February 3, 2011
Hi,

I have a bunch of floating point samples in two files:

For each floating point sample n the floating point output is
calculated as:

measure[n] = crossdot[n] * crossdot[n] * invenergy[n]

I am trying to come up with a fixed point implementation of that where
the variables are named fix_measure, fix_crossdot and fix_invenergy.

To avoid losing precision I have to keep invenergy in Q30. The
variable fix_crossdot has a range from 2 to 488979347. The other
variable fix_invenergy has a range from 0 to 5965232.

Can somebody please give me some tips...(I am about to lose my
mind).... :o)

Data can be downloaded here:

http://www.easy-share.com/1913759785/files.zip
John McDermick  <johnthedspguy@gmail.com> wrote:

>I have a bunch of floating point samples in two files:
By this do you mean IEEE double-precision floating point?
>For each floating point sample n the floating point output is >calculated as:
>measure[n] = crossdot[n] * crossdot[n] * invenergy[n]
>I am trying to come up with a fixed point implementation of that where >the variables are named fix_measure, fix_crossdot and fix_invenergy.
>To avoid losing precision I have to keep invenergy in Q30. The >variable fix_crossdot has a range from 2 to 488979347. The other >variable fix_invenergy has a range from 0 to 5965232. > >Can somebody please give me some tips...(I am about to lose my >mind).... :o)
These sort of measures can have a very wide dynamic range. Popular implementation choices are either a log domain, or a short floating-point format. It can be difficult to do what you're trying to do in fixed point if you're not in a log domain. What you can and probably should do is normalize the data so that the three factors being multiplied together all have a range of [0,1] or [-1,1], so that their product also has a magnitude no greater than one. Your problem then reduces to how much precision you need near zero. And, while some may disagree, I always recommend IEEE 1666 formats over the ancient archaic Q format. Steve
John McDermick  <johnthedspguy@gmail.com> wrote:

>I have a bunch of floating point samples in two files:
By this do you mean IEEE double-precision floating point?
>For each floating point sample n the floating point output is >calculated as:
>measure[n] = crossdot[n] * crossdot[n] * invenergy[n]
>I am trying to come up with a fixed point implementation of that where >the variables are named fix_measure, fix_crossdot and fix_invenergy.
>To avoid losing precision I have to keep invenergy in Q30. The >variable fix_crossdot has a range from 2 to 488979347. The other >variable fix_invenergy has a range from 0 to 5965232. > >Can somebody please give me some tips...(I am about to lose my >mind).... :o)
These sort of measures can have a very wide dynamic range. Popular implementation choices are either a log domain, or a short floating-point format. It can be difficult to do what you're trying to do in fixed point if you're not in a log domain. What you can and probably should do is normalize the data so that the three factors being multiplied together all have a range of [0,1] or [-1,1], so that their product also has a magnitude no greater than one. Your problem then reduces to how much precision you need near zero. And, while some may disagree, I always recommend IEEE 1666 formats over the ancient archaic Q format. Steve
> Popular implementation choices are either a log domain, or a
Yeah...that's where I am heading...Any pointers to where I can find a nice log10 and 10^x fixed point algorithm ?? Anyone??? Please :o)
John <john@nospam.thanks> wrote:

>> Popular implementation choices are either a log domain, or a
>Yeah...that's where I am heading...Any pointers to where I can find >a nice log10 and 10^x fixed point algorithm ??
>Anyone??? Please :o)
Is this an RTL design, or something else? Steve
> Is this an RTL design, or something else? >
Programming in C
John <john@nospam.thanks> wrote replies to my post,

>> Is this an RTL design, or something else?
>Programming in C
The math libraries that come with C have an adequate set of functions such as log() and pow(). Store all your data in variables of type double, and write routines to quantize the data to implement fixed point. (e.g. quantize, call pow(), then quantize the result). It would be somewhat easier to do this in C++ than in C, but it's doable in C. The most common mistake people make when doing this is trying to store the data in integer types...that creates much more work. Steve
> The math libraries that come with C have an adequate set of > functions such as log() and pow(). Store all your data in > variables of type double, and write routines to quantize the data to > implement fixed point. (e.g. quantize, call pow(), then quantize > the result). >
Write routines to quantize the data?? Call pow() ?? On a Blackfin processor a call to log results in these assembly instructions: y = log(45); [FFA0102C] R0 = 0 ; [FFA0102E] R0.H = 16948 ; [FFA01032] CALL __logf ; [FFA01036] CALL ___float32_to_int32_round_to_zero ; [FFA0103A] P1.L = 0x4 ; [FFA0103E] P1.H = 0x200 ; [FFA01042] [ P1 ] = R0 ; Now..I am no expert...but doesn't the above show that a floating point routine is called ?
John <john@nospam.thanks> wrote in reply to my post,

>> The math libraries that come with C have an adequate set of >> functions such as log() and pow(). Store all your data in >> variables of type double, and write routines to quantize the data to >> implement fixed point. (e.g. quantize, call pow(), then quantize >> the result).
>Write routines to quantize the data?? Call pow() ?? > >On a Blackfin processor a call to log results in these assembly >instructions: > > y = log(45); > >[FFA0102C] R0 = 0 ; >[FFA0102E] R0.H = 16948 ; >[FFA01032] CALL __logf ; >[FFA01036] CALL ___float32_to_int32_round_to_zero ; >[FFA0103A] P1.L = 0x4 ; >[FFA0103E] P1.H = 0x200 ; >[FFA01042] [ P1 ] = R0 ; > >Now..I am no expert...but doesn't the above show that a floating point >routine is >called ?
Correct, a floating point routine is called. I am suggesting (and I have done this many times) to the OP that he write a quantizing routine (about 10 lines of code) with a prototype something like as follows: double quant(double x, int n, int m); which implements quantization to n total bits and m integer bits. Then a fixed point log function would be: dout = quant(log(quant(din, N1, M1), N2, M2); where din, dout are double. There are of course other ways to do this, but the above is highly-readable and super easy. Steve
>Then a fixed point log function would be: > > dout = quant(log(quant(din, N1, M1), N2, M2); > > where din, dout are double.
If a call to log (as above) results in assembly calls to floating point code (as you confirmed), then the code is not a fixed point implementation of log, right? Or what am I missing here???