SINFONI Pipeline Reference Manual  2.6.0
sinfo_solve_poly_root.c
1 /*
2  * This file is part of the ESO SINFONI Pipeline
3  * Copyright (C) 2004,2005 European Southern Observatory
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
18  */
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22 /*#include "companion.c"*/
23 /*#include "balance.c"*/
24 /*#include "qr.c"*/
25 #include "sinfo_solve_poly_root.h"
26 
35 gsl_poly_complex_workspace *
36 sinfo_gsl_poly_complex_workspace_alloc (size_t n)
37 {
38  size_t nc ;
39 
40  gsl_poly_complex_workspace * w ;
41 
42  if (n == 0)
43  {
44  sinfo_msg_error ("sinfo_matrix size n must be positive integer");
45  return NULL ;
46  }
47 
48  w = (gsl_poly_complex_workspace *)
49  cpl_malloc (sizeof(gsl_poly_complex_workspace));
50 
51  if (w == 0)
52  {
53  sinfo_msg_error ("failed to allocate space for struct");
54  return NULL ;
55  }
56 
57  nc = n - 1;
58 
59  w->nc = nc;
60 
61  w->sinfo_matrix = (double *) cpl_malloc (nc * nc * sizeof(double));
62 
63  if (w->sinfo_matrix == 0)
64  {
65  cpl_free (w) ; /* error in constructor, avoid memory leak */
66  sinfo_msg_error("failed to allocate for workspace sinfo_matrix") ;
67  return NULL ;
68  }
69 
70  return w ;
71 }
72 
73 void
74 sinfo_gsl_poly_complex_workspace_free (gsl_poly_complex_workspace * w)
75 {
76  cpl_free(w->sinfo_matrix) ;
77  cpl_free(w);
78 }
79 
80 
81 int
82 sinfo_gsl_poly_complex_solve (const double *a, size_t n,
83  gsl_poly_complex_workspace * w,
84  gsl_complex_packed_ptr z)
85 {
86  int status;
87  double *m;
88 
89  if (n == 0)
90  {
91  sinfo_msg_error ("number of terms must be a positive integer");
92  return -1 ;
93  }
94 
95  if (n == 1)
96  {
97  sinfo_msg_error ("cannot solve for only one term");
98  return -1 ;
99  }
100 
101  if (a[n - 1] == 0)
102  {
103  sinfo_msg_error ("leading term of polynomial must be non-zero") ;
104  return -1 ;
105  }
106 
107  if (w->nc != n - 1)
108  {
109  sinfo_msg_error ("size of workspace does not match polynomial");
110  return -1 ;
111  }
112 
113  m = w->sinfo_matrix;
114 
115  sinfo_set_companion_matrix (a, n - 1, m);
116 
117  sinfo_balance_companion_matrix (m, n - 1);
118 
119  status = sinfo_qr_companion (m, n - 1, z);
120 
121  if (status == -1)
122  {
123  sinfo_msg_error("root solving qr method failed to converge");
124  return -1 ;
125  }
126 
127  return 1;
128 }
129 
#define sinfo_msg_error(...)
Print an error message.
Definition: sinfo_msg.h:69