a question on loop efficiency

i was wondering
1
2
3
4
5
6
7
8
int determinant(int n){
    for(;n>0;n--){
        D*=A[n-1][n-1];
    }
    D/=ms;
    return 0; 
}
    


or
1
2
3
4
5
6
7
8
9
10
11
int determinant(int n){
    for(;n>0;n--){
        if(A[n-1][n-1]==0){
             D=0;
             return 0;
        }
    }
    D/=ms;
    return 0; 
}

which is more efficient?
in the 2nd version there is an xtra 'if' check but the loop only runs as long necessary
so is betr?
It's second if 0 is very likely,
It's first otherwise,
It's irrelevant as long as n is below a bajillion.
I agree with hamsterman, people spend far too much time worrying about this kind of thing. If speed is really that important in this particular project though then you should try to eliminate divisions which are notoriously slow. You can often get around divisions with bitshifting, or if for example ms is a constant by instead multiplying by 1/ms.
Last edited on
On the other hand a general-purpose matrix manipulation library needs to be fast if it is to handle larger matrices.

But it seems to me like the second one doesn't work -- at least, the two algorithms do not do the same thing with respect to D.

@jsmith: why do think the two r different?
they both work similarly for me

@quirkyusername: time is not really an issue . i was just think wondering which one should i use when handing in my assignment
i settled on the 2nd one
why do think the two r different?
Maybe because the forgot to add D*=A[n-1][n-1]; to the second one.

i settled on the 2nd one
Not that there's a difference, but I myself would go with the first one. Looks cleaner..
Last edited on
no i didnt forgrt 2 addD*=A[n-1][n-1];
this function is is called after transforming the martix to its row-echelon form
so any one zero in the diagonal will give D=0

Not that there's a difference, but I myself would go with the first one. Looks cleaner..


makes sense but now its too late :(
And what will D be if there is no 0 ?
no zero in diagonal[all one] will give D=1/ms

here the whole code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include<stdio.h>


float A[5][5],E[5][5],D=1,ms=1;
int n;

int getdata(int n){
    int x,y;
    for(x=0;x<n;x++){
        for(y=0;y<n;y++){
            printf("A[%d][%d] = ",x,y);//n*x+y+1);
            //A[x][y]=(float)n*x+y+1;
            scanf("%f",&A[x][y]);
        }
    }
    return 0;
}

int showdata(int n){
    int x,y;
    for(x=0;x<n;x++){
        printf("\n");
        for(y=0;y<n;y++){
            printf("\t%3.1f",A[x][y]);
        }
    }
    printf("\n");
    return 0;
}

int row_echelon(int n){
    int x,y,j;
    float m,s;
    for(x=y=0;y<n;y++,x=y){
        if((A[x][y]!=1)&&(A[x][y]!=0)){
            m=1/A[x][y];
            ms*=m;
            for(j=y;j<n;j++){
                A[x][j]*=m;
            }
        }
        for(x=y+1;x<n;x++){
            if(A[x][y]!=0){
                s=A[x][y];
                for(j=y;j<n;j++){
                    A[x][j]-=A[y][j]*s;
                }
            }
        }
    }
    return 0;
}
                
    
int determinant(int n){
    for(;n>0;n--){
        D*=A[n-1][n-1];
    }
    D/=ms;
    return 0; 
}
    
    



int main(){
    printf("Enter the size of the matrix : ");
    scanf("%d",&n);
    getdata(n);
    showdata(n);
    printf("\nThe row-echelon form of the matrix : \n");
    row_echelon(n);
    showdata(n);
    determinant(n);
    printf("\nThe Determinant of the matrix : %3.1f\n",D);
    system("pause");
    
    return 0;      
}
May I introduce you to the spacebar on your keyboard?
jsmits makes a good point, those nested fors and ifs are god-awful to read.
This will help a little...

$ perl -pe 's/\(([^)])/\( $1/g; s/([^(])\)/$1 \)/g; s/,/, /g; s/;([^\n])/; $1/g; s/' your.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include<stdio.h>


float A[5][5], E[5][5], D=1, ms=1;
int n;

int getdata( int n ){
    int x, y;
    for( x=0; x<n; x++ ){
        for( y=0; y<n; y++ ){
            printf( "A[%d][%d] = ", x, y ); //n*x+y+1 );
            //A[x][y]=( float )n*x+y+1;
            scanf( "%f", &A[x][y] );
        }
    }
    return 0;
}

int showdata( int n ){
    int x, y;
    for( x=0; x<n; x++ ){
        printf( "\n" );
        for( y=0; y<n; y++ ){
            printf( "\t%3.1f", A[x][y] );
        }
    }
    printf( "\n" );
    return 0;
}

int row_echelon( int n ){
    int x, y, j;
    float m, s;
    for( x=y=0; y<n; y++, x=y ){
        if( (A[x][y]!=1 )&&( A[x][y]!=0 )){
            m=1/A[x][y];
            ms*=m;
            for( j=y; j<n; j++ ){
                A[x][j]*=m;
            }
        }
        for( x=y+1; x<n; x++ ){
            if( A[x][y]!=0 ){
                s=A[x][y];
                for( j=y; j<n; j++ ){
                    A[x][j]-=A[y][j]*s;
                }
            }
        }
    }
    return 0;
}
                
    
int determinant( int n ){
    for( ; n>0; n-- ){
        D*=A[n-1][n-1];
    }
    D/=ms;
    return 0;  
}
    
    



int main(){
    printf( "Enter the size of the matrix : " );
    scanf( "%d", &n );
    getdata( n );
    showdata( n );
    printf( "\nThe row-echelon form of the matrix : \n" );
    row_echelon( n );
    showdata( n );
    determinant( n );
    printf( "\nThe Determinant of the matrix : %3.1f\n", D );
    system( "pause" );
    
    return 0;       
}
$ perl -pe 's/\(([^)])/\( $1/g; s/([^(])\)/$1 \)/g; s/,/, /g; s/;([^\n])/; $1/g; s/' your.cc

what is this?
That's the command that added the whitespace to the code above.
Topic archived. No new replies allowed.