Lecture 15

 

In this lecture we will see more examples on establishing and proving loop invariants.

 

Dot_Product.

 

double dot_product ( int nelt, double *v1, double *v2 ) {

        int i;

        double t = 0.0;

 

        for ( i= 0; i < nelt; i++ ) {

                t += v1[i] * v2[i];

        }

 

        return t;

}

 

To establish the invariant first look into the specifications of the dot_product routine, i.e. the pre-conditions and the post-conditions.

 

Pre-conditions: nelt > 0;

                v1, v2 are vectors of length nelt.

 

Post-conditions: The routine must return ånelt - 1 v1[i] * v2[i]

                                                                              i=0

Hence, the loop invariant is:

        t = sum so far

          =  å i - 1 v1[j] * v2[j]

                j=0

 

 

Initially, i = 0 and t = 0.0.

Simulating the execution,

Assume t = å  i - 1 v1[j] * v2[j]

                     j=0

       t' = t + v1[i] * v2[i]

       i' = i + 1

 

Now, t' = å j = i - 1 v1[j] * v2[j] + v1[i] * v2[i]

                 j=0

        = å j = i  v1[j] * v2[j]

           j=0

 

But i = i' - 1

 

Therefore, t' = åi’ - 1 v1[j] * v2[j]

                         j=0

 

The loop terminates when i = nelt and hence:

        t = å j = nelt - 1 v1[j] * v2[j]

                j=0

        which satisfies the post-condition.

 

 

 

 

Loop Invariant for an if statement:

 

double exp ( double b, int e ) {

        double x = 1.0, y = b;

                // Imagine i=0

        while ( 0 != e ) { 

                if ( e odd ) {           

                        x = x * y;

                }

        y = y * y;

        e = e div 2; // imagine i = i+ 1

        }

 

        return x;

}

 

Explanation of strategy:

The binary expansion of e is e = e31 e30…e1 e0 = å31 2i * ei

                                                                                          i = 0

ð      be = b raised to ( å31 2i * ei )

                                                    i = 0

                            = Õ31 ( ( b raised to 2i ) raised to ei )

                                i=0                          

                            = ( b raised to e0 ) * ( ( b2 ) raised to e1) * ( ( b4 ) raised to e2 )…

 

Loop Invariant:

For all i from 0 to 31,            x = Õi ( ( b raised to 2j ) raised to ej )                   y = b raised to 2j

                                                   j = 0

 

 

At every iteration, y’ = y * y = y2 = ( (b raised to 2i) raised to 2 ) = b raised to 2i + 1

The only values of ei are 0 or 1.

if ei = 0,

x’ = x

When, i’ = i +1

x’ = Õi-1 ( ( b raised to 2j ) raised to ej ) * y

        j=0    

    = ( Õi-1 ( ( b raised to 2j ) raised to ej ) ) * ( ( b raised to 2i ) raised to ei )

          j=0

    = Õi ( (  b raised to 2j ) raised to ej )

        j=0

    = Õi’-1 ( ( b raised to 2j ) raised to ej )

       j=0

 

if ei = 1

x’ = x * y

    = Õi-1( ( b raised to 2j ) raised to ej ) * ( ( b raised to 2i ) raised to ei )

       j=0

    = Õi ( ( b raised 2j ) raised to ej )

       j=0