comp.lang.ada
 help / color / mirror / Atom feed
From: "Randy Brukardt" <randy@rrsoftware.com>
Subject: Re: Numerical calculations: Why not use fixed point types for everything?
Date: Thu, 7 Feb 2013 00:03:33 -0600
Date: 2013-02-07T00:03:33-06:00	[thread overview]
Message-ID: <kevg3p$jnn$1@munin.nbi.dk> (raw)
In-Reply-To: 4b654b06-f2d2-4ced-8508-c10e5c84e29d@googlegroups.com

"Ada novice" <shai.lesh@gmx.com> wrote in message 
news:4b654b06-f2d2-4ced-8508-c10e5c84e29d@googlegroups.com...
> On Tuesday, February 5, 2013 3:27:58 AM UTC+1, Randy Brukardt wrote:
...
>> The main reason is that you almost always need to get your data from an
>> array somewhere, and you use the for loop parameter ("I" in this case) to
>> get the values from the array, and then use the float version of the step
>> for the calculation. With the exception of benchmarks, I don't think I've
>> ever written a loop that does exactly the same thing 300 times without
>> changing the input data. (When such things appear to happen, usually you 
>> can
>> refactor the expression to avoid the loop altogether, which is usually 
>> 300
>> times faster.)
>
> In this example, Frequency is changing at every index in the loop. Its 
> first value is -44.88 and its
> final value is 67.32. This Frequency can be used further in a calculation.
>
> If you would have read the code well, you would have seen that the loop is 
> not doing 300 times
> exactly the same thing.

I'm not talking about doing *exactly* the same thing (that is using the same 
values over and over). You clearly missed my point: unless there is some 
varying data in the loop, you can almost always use a reorganization of the 
loop in order to eliminate it completely, because you are executing the same 
*formula* each time thru the loop. And usually, you can apply various 
loop-hoisting transformations to pull the useful parts of the loop out. 
Consider this following version of your code using the frequency in a 
calculation:

    Total := 0.0;
    for I in 0 .. Step-1 loop
       Frequency := Frequency_Start + Frequency_Step * Long_Float (I);
       Total := Total + Frequency*Some_Constant;
    end loop;

Here, I've used the frequency in a calculation. "Some_Constant" is just that 
(or it could have been a variable not modified by the loop [a parameter, for 
instance], that wouldn't change anything). [Quick aside: The sorts of 
refactoring that I'm about to do might change the accuracy of the result --  
I didn't try to figure out whether that is a danger or not.]

Anyway, let's see if we can simplify this loop (this is the sort of thing a 
compiler would try to do, but it can't know if you can tolerate different 
accuracy, so it probably could not do everything you can do). First, let's 
get rid of the extra variable:

    Total := 0.0;
    for I in 0 .. Step-1 loop
        Total := Total + (Frequency_Start + Frequency_Step * Long_Float 
(I))*Some_Constant;
    end loop;

Now we can distribute Some_Constant and remove a set of parens:

    Total := 0.0;
    for I in 0 .. Step-1 loop
        Total := Total + Frequency_Start*Some_Constant + Frequency_Step* 
Long_Float (I)*Some_Constant;
    end loop;

Now, Frequency_Start*Some_Constant does not depend on the loop index, and it 
is going to be executed Step times. So there is no reason to execute it 
inside the loop. So let's pull that out of the loop:

    Total := Frequency_Start*Some_Constant*Long_Float(Step);
    for I in 0 .. Step-1 loop
        Total := Total + Frequency_Step* Long_Float (I)*Some_Constant;
    end loop;

What's left here can be refactored further by noting that 
Frequency_Step*Some_Constant don't depend on the loop index, either. So 
let's pull that out of the loop, too:

    Total := Frequency_Start*Some_Constant*Long_Float(Step);
    Sum := 0;
    for I in 0 .. Step-1 loop
         Sum := Sum + I;
    end loop;
    Total := Total + Frequency_Step* Some_Constant*Long_Float(Sum);

But, since Step is a constant, the value of Sum can be figured out once, 
declared as a constant and plugged in. (I know there is a formula for that 
which I forget at the moment, but that formula could be used in the constant 
declaration to avoid the magic number.)

    Total := Frequency_Start*Some_Constant*Long_Float(Step);
    Total := Total + Frequency_Step* Some_Constant*Long_Float(Sum_Constant);

And voila! No loop!

My point was that most loops can be refactored this way unless there is some 
varying data in them. (And the best loop execution-wise is no loop.) And 
indeed, most of the loops like this that I've written involve processing 
(summarizing, often) an array of data. In which case you need an array 
index; and usually you can convert that index into the factor by some 
technique. So iteration by fixed point values or the like makes for 
interesting examples, but won't happen that often in practice.

                                                      Randy.





  reply	other threads:[~2013-02-07  6:03 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-01-17 10:33 Numerical calculations: Why not use fixed point types for everything? Ada novice
2013-01-17 14:40 ` Nasser M. Abbasi
2013-01-17 16:16   ` Adam Beneschan
2013-01-17 17:00     ` Georg Bauhaus
2013-01-17 16:25 ` Adam Beneschan
2013-01-18  9:17   ` Ada novice
2013-01-18 17:24     ` J-P. Rosen
2013-01-18 17:52       ` Jeffrey Carter
2013-01-18 18:15     ` Dennis Lee Bieber
2013-01-18 18:59       ` Adam Beneschan
2013-01-19  4:41         ` Dennis Lee Bieber
2013-01-19  6:26           ` Jeffrey Carter
2013-01-19 14:14             ` Robert A Duff
2013-01-25 12:16               ` Paul Colin Gloster
2013-01-24 10:55             ` Ada novice
2013-01-24 11:47               ` Simon Wright
2013-01-24 14:21                 ` Ada novice
2013-01-20  0:05           ` Robin Vowels
2013-01-18 23:06       ` Robin Vowels
2013-01-18 19:09     ` Adam Beneschan
2013-01-18 21:39       ` Randy Brukardt
2013-01-19  7:02         ` Ada novice
2013-01-25 12:09         ` Paul Colin Gloster
2013-01-25 12:23     ` Paul Colin Gloster
2013-01-28  9:09       ` Ada novice
2013-02-01 10:53         ` Ada novice
2013-02-01 15:01           ` Shark8
2013-02-02 18:55             ` Ada novice
2013-02-03  4:05               ` Shark8
2013-02-04  6:23                 ` Ada novice
2013-02-04  6:43                   ` Niklas Holsti
2013-02-04  7:27                     ` Ada novice
2013-02-04  9:37                       ` Niklas Holsti
2013-02-04 10:09                         ` Ada novice
2013-02-04 14:24                           ` Niklas Holsti
2013-02-04 16:44                             ` Jeffrey Carter
2013-02-04 21:12                               ` Niklas Holsti
2013-02-04 17:31                             ` Robert A Duff
2013-02-04 21:20                               ` Niklas Holsti
2013-02-02 21:08           ` Nasser M. Abbasi
2013-02-04  6:17             ` Ada novice
2013-02-05  2:27               ` Randy Brukardt
2013-02-06  7:11                 ` Ada novice
2013-02-07  6:03                   ` Randy Brukardt [this message]
2013-02-07  8:43                     ` Shark8
2013-02-08  3:17                       ` Randy Brukardt
2013-02-08  6:20                     ` Ada novice
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox