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
How do I solve this fixed point problem
Started by ●February 3, 2011
Reply by ●February 3, 20112011-02-03
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
Reply by ●February 3, 20112011-02-03
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
Reply by ●February 3, 20112011-02-03
> Popular implementation choices are either a log domain, or aYeah...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)
Reply by ●February 3, 20112011-02-03
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
Reply by ●February 3, 20112011-02-03
Reply by ●February 3, 20112011-02-03
John <john@nospam.thanks> wrote replies to my post,>> Is this an RTL design, or something else?>Programming in CThe 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
Reply by ●February 3, 20112011-02-03
> 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 ?
Reply by ●February 3, 20112011-02-03
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
Reply by ●February 3, 20112011-02-03
>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???






