c - How to generate a very large non singular matrix A in Ax = b? -
i solving system of linear algebraic equations ax = b using jacobian method taking manual inputs. want analyze performance of solver large system. there method generate matrix i.e non singular? attaching code here.`
#include<stdio.h> #include<stdlib.h> #include<math.h> #define tol = 0.0001 void main() { int size,i,j,k = 0; printf("\n enter number of equations: "); scanf("%d",&size); double reci = 0.0; double *x = (double *)malloc(size*sizeof(double)); double *x_old = (double *)malloc(size*sizeof(double)); double *b = (double *)malloc(size*sizeof(double)); double *coeffmat = (double *)malloc(size*size*sizeof(double)); printf("\n enter coefficient matrix: \n"); for(i = 0; < size; i++) { for(j = 0; j < size; j++) { printf(" coeffmat[%d][%d] = ",i,j); scanf("%lf",&coeffmat[i*size+j]); printf("\n"); //coeffmat[i*size+j] = 1.0; } } printf("\n enter b vector: \n"); for(i = 0; < size; i++) { x[i] = 0.0; printf(" b[%d] = ",i); scanf("%lf",&b[i]); } double sum = 0.0; while(k < size) { for(i = 0; < size; i++) { x_old[i] = x[i]; } for(i = 0; < size; i++) { sum = 0.0; for(j = 0; j < size; j++) { if(i != j) { sum += (coeffmat[i * size + j] * x_old[j] ); } } x[i] = (b[i] -sum) / coeffmat[i * size + i]; } k = k+1; } printf("\n solution is: "); for(i = 0; < size; i++) { printf(" x[%d] = %lf \n ",i,x[i]); } }
talonmies' comment mentions http://www.eecs.berkeley.edu/pubs/techrpts/1991/csd-91-658.pdf right approach (at least in principle, , in full generality).
however, not handling "very large" matrixes (e.g. because program use naive algorithms, , because don't run on large supercomputer lot of ram). naive approach of generating matrix random coefficients , testing afterwards non-singular enough.
very large matrixes have many billions of coefficients, , need powerful supercomputer e.g. terabytes of ram. don't have that, if did, program run long (you don't have parallelism), might give wrong results (read http://floating-point-gui.de/ more) don't care.
a matrix of million coefficients (e.g. 1024*1024) considered small current hardware standards (and more enough test code on current laptops or desktops, , test parallel implementations), , generating randomly of them (and computing determinant test not singular) enough, , doable. might generate them and/or check regularity external tool, e.g. scilab, r, octave, etc. once program computed solution x0, use tool (or write program) compute ax0 - b , check close 0 vector (there cases disappointed or surprised, since round-off errors matter).
you'll need enough pseudo random number generator perhaps simple drand48(3) considered obsolete (you should find , use better); seed random source (e.g. /dev/urandom
on linux).
btw, compile code warnings & debug info (e.g. gcc -wall -wextra -g
). #define tol = 0.0001
wrong (should #define tol 0.0001
or const double tol = 0.0001;
). use debugger (gdb
) & valgrind. add optimizations (-o2 -mcpu=native
) when benchmarking. read documentation of every used function, notably <stdio.h>
. check result count scanf
... in c99, should not cast result of malloc
, forgot test against failure, code:
double *b = malloc(size*sizeof(double)); if (!b) {perror("malloc b"); exit(exit_failure); };
you'll rather end, not start, printf
control strings \n
because stdout
(not always!) line buffered. see fflush
.
you should read basic linear algebra textbook...
notice writing robust , efficient programs invert matrixes or solve linear systems difficult art (which don't know @ : has programming issues, algorithmic issues, , mathematical issues; read numerical analysis book). can still phd , spend whole life working on that. please understand need ten years learn programming (or many other things).
Comments
Post a Comment