sinfo_balance.c

00001 /*
00002  * This file is part of the ESO SINFONI Pipeline
00003  * Copyright (C) 2004,2005 European Southern Observatory
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA
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 
00042 void
00043 sinfo_balance_companion_matrix (double *m, size_t nc)
00044 {
00045   int not_converged = 1;
00046 
00047   double row_norm = 0;
00048   double col_norm = 0;
00049 
00050   while (not_converged)
00051     {
00052       size_t i, j;
00053       double g, f, s;
00054 
00055       not_converged = 0;
00056 
00057       for (i = 0; i < nc; i++)
00058     {
00059       /* column norm, excluding the diagonal */
00060 
00061       if (i != nc - 1)
00062         {
00063           col_norm = fabs (MAT (m, i + 1, i, nc));
00064         }
00065       else
00066         {
00067           col_norm = 0;
00068 
00069           for (j = 0; j < nc - 1; j++)
00070         {
00071           col_norm += fabs (MAT (m, j, nc - 1, nc));
00072         }
00073         }
00074 
00075       /* row norm, excluding the diagonal */
00076 
00077       if (i == 0)
00078         {
00079           row_norm = fabs (MAT (m, 0, nc - 1, nc));
00080         }
00081       else if (i == nc - 1)
00082         {
00083           row_norm = fabs (MAT (m, i, i - 1, nc));
00084         }
00085       else
00086         {
00087           row_norm = (fabs (MAT (m, i, i - 1, nc)) 
00088                           + fabs (MAT (m, i, nc - 1, nc)));
00089         }
00090 
00091       if (col_norm == 0 || row_norm == 0)
00092         {
00093           continue;
00094         }
00095 
00096       g = row_norm / RADIX;
00097       f = 1;
00098       s = col_norm + row_norm;
00099 
00100       while (col_norm < g)
00101         {
00102           f *= RADIX;
00103           col_norm *= RADIX2;
00104         }
00105 
00106       g = row_norm * RADIX;
00107 
00108       while (col_norm > g)
00109         {
00110           f /= RADIX;
00111           col_norm /= RADIX2;
00112         }
00113 
00114       if ((row_norm + col_norm) < 0.95 * s * f)
00115         {
00116           not_converged = 1;
00117 
00118           g = 1 / f;
00119 
00120           if (i == 0)
00121         {
00122           MAT (m, 0, nc - 1, nc) *= g;
00123         }
00124           else
00125         {
00126           MAT (m, i, i - 1, nc) *= g;
00127           MAT (m, i, nc - 1, nc) *= g;
00128         }
00129 
00130           if (i == nc - 1)
00131         {
00132           for (j = 0; j < nc; j++)
00133             {
00134               MAT (m, j, i, nc) *= f;
00135             }
00136         }
00137           else
00138         {
00139           MAT (m, i + 1, i, nc) *= f;
00140         }
00141         }
00142     }
00143     }
00144 }

Generated on 3 Mar 2013 for SINFONI Pipeline Reference Manual by  doxygen 1.6.1