00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifdef HAVE_CONFIG_H
00020 # include <config.h>
00021 #endif
00022 #include "sinfo_solve_poly_root.h"
00023
00024
00025 #define RADIX 2
00026 #define RADIX2 (RADIX*RADIX)
00027
00041 void
00042 sinfo_balance_companion_matrix (double *m, size_t nc)
00043 {
00044 int not_converged = 1;
00045
00046 double row_norm = 0;
00047 double col_norm = 0;
00048
00049 while (not_converged)
00050 {
00051 size_t i, j;
00052 double g, f, s;
00053
00054 not_converged = 0;
00055
00056 for (i = 0; i < nc; i++)
00057 {
00058
00059
00060 if (i != nc - 1)
00061 {
00062 col_norm = fabs (MAT (m, i + 1, i, nc));
00063 }
00064 else
00065 {
00066 col_norm = 0;
00067
00068 for (j = 0; j < nc - 1; j++)
00069 {
00070 col_norm += fabs (MAT (m, j, nc - 1, nc));
00071 }
00072 }
00073
00074
00075
00076 if (i == 0)
00077 {
00078 row_norm = fabs (MAT (m, 0, nc - 1, nc));
00079 }
00080 else if (i == nc - 1)
00081 {
00082 row_norm = fabs (MAT (m, i, i - 1, nc));
00083 }
00084 else
00085 {
00086 row_norm = (fabs (MAT (m, i, i - 1, nc))
00087 + fabs (MAT (m, i, nc - 1, nc)));
00088 }
00089
00090 if (col_norm == 0 || row_norm == 0)
00091 {
00092 continue;
00093 }
00094
00095 g = row_norm / RADIX;
00096 f = 1;
00097 s = col_norm + row_norm;
00098
00099 while (col_norm < g)
00100 {
00101 f *= RADIX;
00102 col_norm *= RADIX2;
00103 }
00104
00105 g = row_norm * RADIX;
00106
00107 while (col_norm > g)
00108 {
00109 f /= RADIX;
00110 col_norm /= RADIX2;
00111 }
00112
00113 if ((row_norm + col_norm) < 0.95 * s * f)
00114 {
00115 not_converged = 1;
00116
00117 g = 1 / f;
00118
00119 if (i == 0)
00120 {
00121 MAT (m, 0, nc - 1, nc) *= g;
00122 }
00123 else
00124 {
00125 MAT (m, i, i - 1, nc) *= g;
00126 MAT (m, i, nc - 1, nc) *= g;
00127 }
00128
00129 if (i == nc - 1)
00130 {
00131 for (j = 0; j < nc; j++)
00132 {
00133 MAT (m, j, i, nc) *= f;
00134 }
00135 }
00136 else
00137 {
00138 MAT (m, i + 1, i, nc) *= f;
00139 }
00140 }
00141 }
00142 }
00143 }