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
00023
00024
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) ;
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