sinfo_solve_poly_root.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 "companion.c"*/
00023 /*#include "balance.c"*/
00024 /*#include "qr.c"*/
00025 #include "sinfo_solve_poly_root.h"
00026 
00035 gsl_poly_complex_workspace *
00036 sinfo_gsl_poly_complex_workspace_alloc (size_t n)
00037 {
00038   size_t nc ;
00039 
00040   gsl_poly_complex_workspace * w ;
00041  
00042   if (n == 0)
00043     {
00044       sinfo_msg_error ("sinfo_matrix size n must be positive integer");
00045       return NULL ;
00046     }
00047 
00048   w = (gsl_poly_complex_workspace *)
00049     cpl_malloc (sizeof(gsl_poly_complex_workspace));
00050 
00051   if (w == 0)
00052     {
00053       sinfo_msg_error ("failed to allocate space for struct");
00054       return NULL ;
00055     }
00056 
00057   nc = n - 1;
00058 
00059   w->nc = nc;
00060 
00061   w->sinfo_matrix = (double *) cpl_malloc (nc * nc * sizeof(double));
00062 
00063   if (w->sinfo_matrix == 0)
00064     {
00065       cpl_free (w) ;       /* error in constructor, avoid memory leak */
00066       sinfo_msg_error("failed to allocate for workspace sinfo_matrix") ;
00067       return  NULL ;
00068     }
00069 
00070   return w ;
00071 }
00072 
00073 void
00074 sinfo_gsl_poly_complex_workspace_free (gsl_poly_complex_workspace * w)
00075 {
00076   cpl_free(w->sinfo_matrix) ;
00077   cpl_free(w);
00078 }
00079 
00080 
00081 int
00082 sinfo_gsl_poly_complex_solve (const double *a, size_t n,
00083             gsl_poly_complex_workspace * w,
00084             gsl_complex_packed_ptr z)
00085 {
00086   int status;
00087   double *m;
00088 
00089   if (n == 0)
00090     {
00091       sinfo_msg_error ("number of terms must be a positive integer");
00092       return -1 ;
00093     }
00094 
00095   if (n == 1)
00096     {
00097       sinfo_msg_error ("cannot solve for only one term");
00098       return -1 ;
00099     }
00100 
00101   if (a[n - 1] == 0)
00102     {
00103       sinfo_msg_error ("leading term of polynomial must be non-zero") ;
00104       return -1 ;
00105     }
00106 
00107   if (w->nc != n - 1)
00108     {
00109       sinfo_msg_error ("size of workspace does not match polynomial");
00110       return -1 ;
00111     }
00112   
00113   m = w->sinfo_matrix;
00114 
00115   sinfo_set_companion_matrix (a, n - 1, m);
00116 
00117   sinfo_balance_companion_matrix (m, n - 1);
00118 
00119   status = sinfo_qr_companion (m, n - 1, z);
00120 
00121   if (status == -1)
00122     {
00123       sinfo_msg_error("root solving qr method failed to converge");
00124       return -1 ;
00125     }
00126 
00127   return 1;
00128 }
00129 

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