00001 // reduced release of original file basis.c 00002 /*********************************************************************** 00003 * * 00004 * Basic functions: Declarations file (with types and macros) * 00005 * ---------------------------------------------------------- * 00006 * * 00007 * Programming language: ANSI C * 00008 * Compiler: Turbo C 2.0 * 00009 * Computer: IBM PS/2 70 with 80387 * 00010 * Author: Juergen Dietel, Computer Center, RWTH Aachen * 00011 * Date: 9.30.1992 * 00012 * * 00013 * C++ reduced Release By J-P Moreau, Paris. * 00014 * -------------------------------------------------------------------- * 00015 * REF.: "Numerical Algorithms with C, By Gisela Engeln-Muellges * 00016 * and Frank Uhlig, Springer-Verlag, 1996" [BIBLI 11]. * 00017 ***********************************************************************/ 00018 #include <basis.h> 00019 00020 00021 REAL sqr(REAL x) /* square a floating point number */ 00022 /*********************************************************************** 00023 * Compute the square of a floating point number. * 00024 * * 00025 * global names used: * 00026 * ================== * 00027 * REAL * 00028 ***********************************************************************/ 00029 { 00030 return x * x; 00031 } 00032 00033 REAL norm_max /* Find the maximum norm of a REAL vector .........*/ 00034 ( 00035 REAL vektor[], /* vector .................*/ 00036 int n /* length of vector .......*/ 00037 ) /* Maximum norm ...........*/ 00038 00039 /*********************************************************************** 00040 * Return the maximum norm of a [0..n-1] vector v. * 00041 * * 00042 * global names used: * 00043 * ================== * 00044 * REAL, FABS, ZERO * 00045 ***********************************************************************/ 00046 { 00047 REAL norm, /* local max */ 00048 betrag; /* magnitude of a component */ 00049 00050 for (n--, norm = ZERO; n >= 0; n--, vektor++) 00051 if ((betrag = FABS(*vektor)) > norm) 00052 norm = betrag; 00053 00054 return norm; 00055 } 00056 00057 void copy_vector /* copy a REAL vector ........................*/ 00058 ( 00059 REAL ziel[], /* copied vector ............*/ 00060 REAL quelle[], /* original vector ..........*/ 00061 int n /* length of vector .........*/ 00062 ) 00063 /*********************************************************************** 00064 * copy the n elements of the vector quelle into the vector ziel. * 00065 * * 00066 * global names used: * 00067 * ================== * 00068 * REAL * 00069 ***********************************************************************/ 00070 { 00071 for (n--; n >= 0; n--) 00072 *ziel++ = *quelle++; 00073 } 00074 00075 /*********************************************************************** 00076 * read a vector x of size n from input file fp (index begins at zero) * 00077 * * 00078 * global names used: * 00079 * ================== * 00080 * REAL * 00081 ***********************************************************************/ 00082 int ReadVec (FILE *fp, int n, REAL x[]) 00083 { 00084 int i; 00085 REAL tmp; 00086 00087 for (i = 0; i < n; i++) 00088 { 00089 if (fscanf (fp,FORMAT_IN, &tmp) <= 0) return (-1); 00090 x[i] = (REAL) tmp; 00091 } 00092 00093 return (0); 00094 } 00095 00096 /*********************************************************************** 00097 * read a vector x of size n from input file fp (index begins at one) * 00098 * * 00099 * global names used: * 00100 * ================== * 00101 * REAL * 00102 ***********************************************************************/ 00103 int ReadVec1 (FILE *fp, int n, REAL x[]) 00104 { 00105 int i; 00106 REAL tmp; 00107 00108 for (i = 1; i < n+1; i++) 00109 { 00110 if (fscanf (fp,FORMAT_IN, &tmp) <= 0) return (-1); 00111 x[i] = (REAL) tmp; 00112 } 00113 00114 return (0); 00115 } 00116 00117 void SetVec (int n, REAL x[], REAL val) 00118 { 00119 int i; 00120 00121 for (i = 0; i < n; i++) 00122 x[i] = val; 00123 } 00124 00125 int WriteVec (FILE *fp, int n, REAL x[]) 00126 /*====================================================================* 00127 * * 00128 * Put out vector of length n to output file. Index begins at zero. * 00129 * * 00130 *====================================================================* 00131 * * 00132 * Input parameters: * 00133 * ================ * 00134 * * 00135 * n int n; * 00136 * lenght of vector * 00137 * x REAL x[]; * 00138 * vector * 00139 * * 00140 * Return value : * 00141 * ============= * 00142 * = 0 All ok * 00143 * = -1 Error putting out to stdout * 00144 * * 00145 *====================================================================*/ 00146 { 00147 int i; 00148 00149 for (i = 0; i < n; i++) 00150 if (fprintf (fp,FORMAT_126LF, x[i]) <= 0) return (-1); 00151 if (fprintf (fp,"\n") <= 0) return (-1); 00152 00153 return 0; 00154 } 00155 00156 int WriteVec1 (FILE *fp, int n, REAL x[]) 00157 /*====================================================================* 00158 * * 00159 * Put out vector of length n to output file. Index begins at one. * 00160 * * 00161 *====================================================================* 00162 * * 00163 * Input parameters: * 00164 * ================ * 00165 * * 00166 * n int n; * 00167 * lenght of vector * 00168 * x REAL x[]; * 00169 * vector * 00170 * * 00171 * Return value : * 00172 * ============= * 00173 * = 0 All ok * 00174 * = -1 Error putting out to stdout * 00175 * * 00176 *====================================================================*/ 00177 { 00178 int i; 00179 00180 for (i = 1; i < n+1; i++) 00181 if (fprintf (fp,FORMAT_126LF, x[i]) <= 0) return (-1); 00182 if (fprintf (fp,"\n") <= 0) return (-1); 00183 00184 return 0; 00185 } 00186 00187 REAL pi() { 00188 return 4.0*atan(1.0); 00189 } 00190 00191 void CopyMat (int m, int n, REAL * source[], REAL * dest[]) 00192 /*====================================================================* 00193 * * 00194 * Copy the m x n matrix source to the m x n matrix dest. * 00195 * * 00196 *====================================================================* 00197 * * 00198 * Input parameters: * 00199 * ================ * 00200 * m int m; ( m > 0 ) * 00201 * numnber of rows of matrix * 00202 * n int n; ( n > 0 ) * 00203 * number of columns of matrix * 00204 * source REAL * source[]; * 00205 * matrix * 00206 * dest REAL * dest[]; * 00207 * matrix to be copied to * 00208 * * 00209 * Output parameter: * 00210 * ================ * 00211 * dest same as above * 00212 * * 00213 * ATTENTION : WE do not allocate storage for dest here. * 00214 * * 00215 *====================================================================*/ 00216 { 00217 int i, j; 00218 00219 for (i = 0; i < m; i++) 00220 for (j = 0; j < n; j++) 00221 dest[i][j] = source[i][j]; 00222 } 00223 00224 REAL maxroot(void) /* Root of the largest representable number ....*/ 00225 /*********************************************************************** 00226 * Compute the square root of the largest machine number 2 ^ (MAX_EXP/2)* 00227 * if not already done * 00228 * * 00229 * global names used: * 00230 * ================== * 00231 * REAL, boolean, FALSE, TRUE, SQRT, POSMAX * 00232 ***********************************************************************/ 00233 { 00234 static REAL save_maxroot; 00235 static boolean schon_berechnet = FALSE; 00236 REAL faktor; 00237 unsigned long int n; 00238 00239 if (! schon_berechnet) 00240 { 00241 save_maxroot = ONE; 00242 faktor = TWO; 00243 for (n = MAX_EXP / 2; n > 1; n /= 2, faktor *= faktor) 00244 if (n % 2 != 0) 00245 save_maxroot *= faktor; 00246 save_maxroot *= faktor; 00247 schon_berechnet = TRUE; 00248 } 00249 00250 return save_maxroot; 00251 } 00252 00253 00254 void quadsolv /* Complex quadratic equation ................*/ 00255 ( 00256 REAL ar, /* second degree coefficient .......*/ 00257 REAL ai, 00258 REAL br, /* linear coefficient ..............*/ 00259 REAL bi, 00260 REAL cr, /* polynomial constant .............*/ 00261 REAL ci, 00262 REAL * tr, /* solution ........................*/ 00263 REAL * ti 00264 ) 00265 /*====================================================================* 00266 * * 00267 * Compute the least magnitude solution of the quadratic equation * 00268 * a * t**2 + b * t + c = 0. Here a, b, c and t are complex. * 00269 * 2 * 00270 * Formeula used: t = 2c / (-b +/- sqrt (b - 4ac)). * 00271 * This formula is valid for a=0 . * 00272 * * 00273 *====================================================================* 00274 * * 00275 * Input parameters: * 00276 * ================ * 00277 * ar, ai coefficient of t**2 REAL ar, ai; * 00278 * br, bi coefficient of t REAL br, bi; * 00279 * cr, ci constant term REAL cr, ci; * 00280 * * 00281 * Output parameter: * 00282 * ================ * 00283 * tr, ti complex solution of minimal magnitude * 00284 * REAL *tr, *ti; * 00285 * * 00286 * Macro used : SQRT * 00287 * ============ * 00288 * * 00289 *====================================================================*/ 00290 { 00291 REAL pr, pi, qr, qi, h; 00292 00293 pr = br * br - bi * bi; 00294 pi = TWO * br * bi; /* p = b * b */ 00295 00296 qr = ar * cr - ai * ci; 00297 qi = ar * ci + ai * cr; /* q = a * c */ 00298 00299 pr = pr - (REAL)4.0 * qr; 00300 pi = pi - (REAL)4.0 * qi; /* p = b * b - 4 * a * c */ 00301 00302 h = SQRT (pr * pr + pi * pi); /* q = sqrt (p) */ 00303 00304 qr = h + pr; 00305 if (qr > ZERO) 00306 qr = SQRT (qr * HALF); 00307 else 00308 qr = ZERO; 00309 00310 qi = h - pr; 00311 if (qi > ZERO) 00312 qi = SQRT (qi * HALF); 00313 else 00314 qi = ZERO; 00315 00316 if (pi < ZERO) qi = -qi; 00317 00318 h = qr * br + qi * bi; /* p = -b +/- q, choose sign for large */ 00319 /* magnitude p */ 00320 if (h > ZERO) 00321 { 00322 qr = -qr; 00323 qi = -qi; 00324 } 00325 00326 pr = qr - br; 00327 pi = qi - bi; 00328 h = pr * pr + pi * pi; /* t = (2 * c) / p */ 00329 00330 if (h == ZERO) 00331 { 00332 *tr = ZERO; 00333 *ti = ZERO; 00334 } 00335 else 00336 { 00337 *tr = TWO * (cr * pr + ci * pi) / h; 00338 *ti = TWO * (ci * pr - cr * pi) / h; 00339 } 00340 } /* quadsolv */ 00341 00342 00343 REAL comabs /* Complex absolute value ....................*/ 00344 ( 00345 REAL ar, /* Real part .......................*/ 00346 REAL ai /* Imaginary part ..................*/ 00347 ) 00348 /*====================================================================* 00349 * * 00350 * Complex absolute value of a * 00351 * * 00352 *====================================================================* 00353 * * 00354 * Input parameters: * 00355 * ================ * 00356 * ar,ai REAL ar, ai; * 00357 * Real, imaginary parts of a * 00358 * * 00359 * Return value : * 00360 * ============= * 00361 * Absolute value of a * 00362 * * 00363 * Macros used : SQRT, ABS, SWAP * 00364 * ============= * 00365 * * 00366 *====================================================================*/ 00367 { 00368 if (ar == ZERO && ai == ZERO) return (ZERO); 00369 00370 ar = ABS (ar); 00371 ai = ABS (ai); 00372 00373 if (ai > ar) /* Switch ai and ar */ 00374 SWAP (REAL, ai, ar) 00375 00376 return ((ai == ZERO) ? (ar) : (ar * SQRT (ONE + ai / ar * ai / ar))); 00377 } 00378 00379 00380 int comdiv /* Complex division ..........................*/ 00381 ( 00382 REAL ar, /* Real part of numerator ..........*/ 00383 REAL ai, /* Imaginary part of numerator .....*/ 00384 REAL br, /* Real part of denominator ........*/ 00385 REAL bi, /* Imaginary part of denominator ...*/ 00386 REAL * cr, /* Real part of quotient ...........*/ 00387 REAL * ci /* Imaginary part of quotient ......*/ 00388 ) 00389 /*====================================================================* 00390 * * 00391 * Complex division c = a / b * 00392 * * 00393 *====================================================================* 00394 * * 00395 * Input parameters: * 00396 * ================ * 00397 * ar,ai REAL ar, ai; * 00398 * Real, imaginary parts of numerator * 00399 * br,bi REAL br, bi; * 00400 * Real, imaginary parts of denominator * 00401 * * 00402 * Output parameters: * 00403 * ================== * 00404 * cr,ci REAL *cr, *ci; * 00405 * Real , imaginary parts of the quotient * 00406 * * 00407 * Return value : * 00408 * ============= * 00409 * = 0 ok * 00410 * = 1 division by 0 * 00411 * * 00412 * Macro used : ABS * 00413 * ============ * 00414 * * 00415 *====================================================================*/ 00416 { 00417 REAL tmp; 00418 00419 if (br == ZERO && bi == ZERO) return (1); 00420 00421 if (ABS (br) > ABS (bi)) 00422 { 00423 tmp = bi / br; 00424 br = tmp * bi + br; 00425 *cr = (ar + tmp * ai) / br; 00426 *ci = (ai - tmp * ar) / br; 00427 } 00428 else 00429 { 00430 tmp = br / bi; 00431 bi = tmp * br + bi; 00432 *cr = (tmp * ar + ai) / bi; 00433 *ci = (tmp * ai - ar) / bi; 00434 } 00435 00436 return (0); 00437 } 00438 00439 int ReadMat (FILE *fp, int m, int n, REAL * a[]) 00440 /*====================================================================* 00441 * * 00442 * Read an m x n matrix from input file. Index starts at zero. * 00443 * * 00444 *====================================================================* 00445 * * 00446 * Input parameters : * 00447 * ================== * 00448 * m int m; ( m > 0 ) * 00449 * number of rows of matrix * 00450 * n int n; ( n > 0 ) * 00451 * column number of matrix * 00452 * a REAL * a[]; * 00453 * matrix * 00454 * * 00455 * Output parameter: * 00456 * ================ * 00457 * a matrix * 00458 * * 00459 * ATTENTION : WE do not allocate storage for a here. * 00460 * * 00461 *====================================================================*/ 00462 { 00463 int i, j; 00464 double x; 00465 00466 for (i = 0; i < m; i++) 00467 for (j = 0; j < n; j++) 00468 { 00469 if (fscanf (fp,FORMAT_IN, &x) <= 0) return (-1); 00470 a[i][j] = (REAL) x; 00471 } 00472 00473 return (0); 00474 } 00475 00476 /* same as ReadMat, but beginning at index 1 */ 00477 int ReadMat1 (FILE *fp, int m, int n, REAL * a[]) 00478 { 00479 int i, j; 00480 double x; 00481 00482 for (i = 1; i < m+1; i++) 00483 for (j = 1; j < n+1; j++) 00484 { 00485 if (fscanf (fp,FORMAT_IN, &x) <= 0) return (-1); 00486 a[i][j] = (REAL) x; 00487 } 00488 00489 return (0); 00490 } 00491 00492 int WriteMat (FILE *fp, int m, int n, REAL * a[]) 00493 /*====================================================================* 00494 * * 00495 * Put out an m x n matrix in output file. Index starts at zero. * 00496 * * 00497 *====================================================================* 00498 * * 00499 * Input parameters: * 00500 * ================ * 00501 * m int m; ( m > 0 ) * 00502 * row number of matrix * 00503 * n int n; ( n > 0 ) * 00504 * column number of matrix * 00505 * a REAL * a[]; * 00506 * matrix * 00507 * * 00508 * Return value : * 00509 * ============= * 00510 * = 0 all put out * 00511 * = -1 Error writing onto stdout * 00512 * * 00513 *====================================================================*/ 00514 { 00515 int i, j; 00516 00517 if (fprintf (fp,"\n") <= 0) return (-1); 00518 00519 for (i = 0; i < m; i++) 00520 { 00521 for (j = 0; j < n; j++) 00522 if (fprintf (fp,FORMAT_126LF, a[i][j]) <= 0) return (-1); 00523 00524 if (fprintf (fp,"\n") <= 0) return (-1); 00525 } 00526 if (fprintf (fp,"\n") <= 0) return (-1); 00527 00528 return (0); 00529 } 00530 00531 /* same as WriteMat, but beginning at index 1 */ 00532 int WriteMat1 (FILE *fp, int m, int n, REAL * a[]) 00533 { 00534 int i, j; 00535 00536 if (fprintf (fp,"\n") <= 0) return (-1); 00537 00538 for (i = 1; i < m+1; i++) 00539 { 00540 for (j = 1; j < n+1; j++) 00541 if (fprintf (fp,FORMAT_126LF, a[i][j]) <= 0) return (-1); 00542 00543 if (fprintf (fp,"\n") <= 0) return (-1); 00544 } 00545 if (fprintf (fp,"\n") <= 0) return (-1); 00546 00547 return (0); 00548 } 00549 00550 00551 void SetMat (int m, int n, REAL * a[], REAL val) 00552 /*====================================================================* 00553 * * 00554 * Initialize an m x n matrix with a constant value val . * 00555 * * 00556 *====================================================================* 00557 * * 00558 * Input parameters: * 00559 * ================ * 00560 * m int m; ( m > 0 ) * 00561 * row number of matrix * 00562 * n int n; ( n > 0 ) * 00563 * column number of matrix * 00564 * a REAL * a[]; * 00565 * matrix * 00566 * val constant value * 00567 * * 00568 * Output parameter: * 00569 * ================ * 00570 * a matrix with constant value val in every position * 00571 * * 00572 *====================================================================*/ 00573 { 00574 int i, j; 00575 00576 for (i = 0; i < m; i++) 00577 for (j = 0; j < n; j++) 00578 a[i][j] = val; 00579 } 00580 00581 static char Separator[] = 00582 "--------------------------------------------------------------------"; 00583 00584 int WriteHead (FILE *fp, char * string) 00585 /*====================================================================* 00586 * * 00587 * Put out header with text in string in file fp. * 00588 * * 00589 *====================================================================* 00590 * * 00591 * Input parameters: * 00592 * ================ * 00593 * string char *string; * 00594 * text of headertext (last byte is a 0) * 00595 * * 00596 * Return value : * 00597 * ============= * 00598 * = 0 All ok * 00599 * = -1 Error writing onto stdout * 00600 * = -2 Invalid text for header * 00601 * * 00602 *====================================================================*/ 00603 { 00604 if (string == NULL) return (-2); 00605 00606 if (fprintf (fp,"\n%s\n%s\n%s\n\n", Separator, string, Separator) <= 0) 00607 return (-1); 00608 00609 return 0; 00610 } 00611 00612 int WriteHead1( char * string) 00613 /*====================================================================* 00614 * * 00615 * Put out header with text in string in stdout. * 00616 * * 00617 *====================================================================* 00618 * * 00619 * Input parameters: * 00620 * ================ * 00621 * string char *string; * 00622 * text of headertext (last byte is a 0) * 00623 * * 00624 * Return value : * 00625 * ============= * 00626 * = 0 All ok * 00627 * = -1 Error writing onto stdout * 00628 * = -2 Invalid text for header * 00629 * * 00630 *====================================================================*/ 00631 { 00632 if (string == NULL) return (-2); 00633 00634 if (printf ("\n%s\n%s\n%s\n\n", Separator, string, Separator) <= 0) 00635 return (-1); 00636 00637 return 0; 00638 } 00639 00640 int WriteEnd (FILE *fp) 00641 /*====================================================================* 00642 * * 00643 * Put out end of writing onto file fp. * 00644 * * 00645 *====================================================================* 00646 * * 00647 * Return value : * 00648 * ============= * 00649 * = 0 All ok * 00650 * = -1 error writing onto stdout * 00651 * * 00652 *====================================================================*/ 00653 { 00654 if (fprintf (fp,"\n%s\n\n", Separator) <= 0) return (-1); 00655 return 0; 00656 } 00657 00658 int WriteEnd1(void) 00659 /*====================================================================* 00660 * * 00661 * Put out end of writing onto stdout. * 00662 * * 00663 *====================================================================* 00664 * * 00665 * Return value : * 00666 * ============= * 00667 * = 0 All ok * 00668 * = -1 error writing onto stdout * 00669 * * 00670 *====================================================================*/ 00671 { 00672 if (printf ("\n%s\n\n", Separator) <= 0) return (-1); 00673 return 0; 00674 } 00675 00676 void LogError (char * string, int rc, char * file, int line) 00677 /*====================================================================* 00678 * * 00679 * Put out error message onto stdout. * 00680 * * 00681 *====================================================================* 00682 * * 00683 * Input parameters: * 00684 * ================ * 00685 * string char *string; * 00686 * text of error massage (final byte is 0) * 00687 * rc int rc; * 00688 * error code * 00689 * file char *file; * 00690 * name of C++ file in which error was encountered * 00691 * line int line; * 00692 * line number of C++ file with error. * 00693 * * 00694 *====================================================================*/ 00695 { 00696 if (string == NULL) { 00697 printf ("Unknown ERROR in file %s at line %d\n", file, line); 00698 return; 00699 } 00700 00701 if (rc == 0) 00702 printf ("ERROR: %s, File %s, Line %d\n", string, file, line); 00703 else 00704 printf ("ERROR: %s, rc = %d, File %s, Line %d\n", 00705 string, rc, file, line); 00706 return; 00707 } 00708 00709 00710 REAL epsroot(void) /* Compute square root of the machine constant ...*/ 00711 /*********************************************************************** 00712 * Compute square root of the machine constant, if not already done. * 00713 * * 00714 * global names used: * 00715 * ================== * 00716 * REAL, boolean, FALSE, TRUE, SQRT, MACH_EPS * 00717 ***********************************************************************/ 00718 00719 { 00720 static REAL save_mach_eps_root; 00721 static boolean schon_berechnet = FALSE; 00722 00723 if (! schon_berechnet) 00724 schon_berechnet = TRUE, 00725 save_mach_eps_root = SQRT(MACH_EPS); 00726 00727 return save_mach_eps_root; 00728 } 00729 00730 00731 REAL epsquad(void) /* Find the machine constant squared .........*/ 00732 /*********************************************************************** 00733 * Compute the square of the machine constant, if not already done. * 00734 * * 00735 * global names used: * 00736 * ================== * 00737 * REAL, boolean, FALSE, TRUE, MACH_EPS * 00738 ***********************************************************************/ 00739 00740 { 00741 static REAL save_mach_eps_quad; 00742 static boolean schon_berechnet = FALSE; 00743 00744 if (! schon_berechnet) 00745 schon_berechnet = TRUE, 00746 save_mach_eps_quad = MACH_EPS * MACH_EPS; 00747 00748 return save_mach_eps_quad; 00749 } 00750 00751 // end of file basis_r.cpp