#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

int main( int argc, char ** argv ) {

	double **A, *b, *x, sum; 
	long i, j, N = 10000;
	clock_t start_time;
	
	// Wenn ein Argument in der Kommandozeile uebergeben wird,
	// lese diesen Wert fuer N aus
	if ( argc > 1 )
		sscanf( argv[1], "%d", &N );

	// Allokation
	A = (double **) malloc( N * sizeof( double * ) );
	for ( i=0; i<N; i++)
		A[i] = (double *) malloc( N * sizeof( double ) );
	b = (double *) malloc( N * sizeof( double ) );
	x = (double *) malloc( N * sizeof( double ) );

	// Initialisierung von A und b
	for ( i=0; i<N; i++) {
		for ( j=0; j<N; j++)
			if ( i > j )
				A[i][j] = 0;
			else
				A[i][j] = M_PI / 3.0;
		b[i] = i+1;
	}

	start_time = clock();
	printf( "Spaltenbasierter Modus\n" );
	x[N-1] = b[N-1] / A[N-1][N-1];
	for ( j=N-2; j>=0; j--) {
		for ( i=0; i<=j; i++ )
			b[i] = b[i] - A[i][j+1] * x[j+1];
		x[j] = b[j] / A[j][j];
	}
	printf("Sekunden: %2.3f\n", ((double)(clock() - start_time))/CLOCKS_PER_SEC);
	// Ausgabe
	for ( i=N-3; i<N; i++) 
		printf( "x[%4d] = %lg\n", i, x[i] );
		
	start_time = clock();
	printf( "Zeilenbasierter Modus\n" );
	x[N-1] = b[N-1] / A[N-1][N-1];
	for ( i=N-2; i>=0; i-- ) {
		sum = b[i];
		for ( j=i+1; j<N; j++)
			sum = sum - A[i][j] * x[j];
		x[i] = sum / A[i][i];
	}
	printf("Sekunden: %2.3f\n", ((double)(clock() - start_time))/CLOCKS_PER_SEC);
	// Ausgabe
	for ( i=N-3; i<N; i++) 
		printf( "x[%4d] = %lg\n", i, x[i] );

	// Freigeben des dynamisch allokierten Speichers
	for ( i=0; i<N; i++)
		free( A[i] );
	free( A );
	free( b );
	free( x );
		
	return 0;
}

