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 
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       /* column norm, excluding the diagonal */
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       /* row norm, excluding the diagonal */
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 }

Generated on 8 Mar 2011 for SINFONI Pipeline Reference Manual by  doxygen 1.6.1