Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Laguerre.cpp
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 #include "Laguerre.hh"
26 #include "Base/Debug/Error.hh"
27 #include <Base/Common/BIASpragma.hh>
28 
29 #include <limits>
30 using namespace std;
31 using namespace BIAS;
32 
33 int LaguerreSolver::Solve(const std::vector< double >& coeffs,
34  std::vector< std::complex<double> >& roots,
35  const double eps)
36 {
37  std::vector< std::complex<double> > complcoeffs;
38  for(unsigned int i=0; i<coeffs.size(); i++)
39  {
40  //cout<<i<<" "<<coeffs[i]<<endl;
41  complcoeffs.push_back(complex<double>(coeffs[i],0));
42  }
43  return(Solve(complcoeffs,roots,eps));
44 }
45 
46 int LaguerreSolver::Solve(const std::vector< std::complex<double> >& coeffs,
47  std::vector< std::complex<double> >& roots,
48  const double eps)
49 {
50 
51  int i,iter;
52  complex<double> x,b,c;
53  roots.clear();
54  int m = coeffs.size()-1;
55  vector< complex<double> > ad(m+1);
56  for (int j=0;j<=m;j++)
57  {
58  ad[j]=coeffs[j];
59  }
60  for ( int j=m-1;j>=0;j--)
61  {
62  x = 0;
63  vector< complex<double> > ad_v(j+2);
64  for ( int jj=0;jj<j+2;jj++)
65  {
66  ad_v[jj]=ad[jj];
67  }
68  iter = _Laguerre(ad_v,x);
69  if(iter<0) return -1;
70  if (abs(imag(x)) <= 2.0*eps*abs(real(x)))
71  {
72  x=complex<double>(real(x),0.0);
73  }
74  roots.push_back(x);
75  b=ad[j+1];
76  for (int jj=j;jj>=0;jj--)
77  {
78  c=ad[jj];
79  ad[jj]=b;
80  b=x*b+c;
81  }
82  }
83  if (_doPolish)
84  {
85  for(int j=0;j<m;j++)
86  {
87  iter = _Laguerre(coeffs,roots[j]); //j is
88  if(iter<0) return -1;
89  }
90  }
91  for (int j=1;j<m;j++)
92  {
93  x=roots[j];
94  for(i=j-1;i>=0;i--)
95  {
96  if(real(roots[i])<=real(x)) break;
97  roots[i+1]=roots[i];
98  }
99  roots[i+1]=x;
100  }
101  return 0;
102 }
103 
104 int LaguerreSolver::_Laguerre(const std::vector< std::complex<double> >& coeffs,
105  std::complex<double>& x)
106 {
107  int iter = 0;
108  const int MR = 8;
109  const int MT = 10;
110  const int MAXIT = MT * MR;
111  const double EPS = numeric_limits<double>::epsilon();
112  static const double frac[MR+1] = {0.0,0.5,0.25,0.75,0.13,0.38,0.62,0.88,1.0};
113  complex<double> dx,x1,b,d,f,g,h,sq,gp,gm,g2;
114  unsigned int m=coeffs.size()-1;
115  for (int it=1;it<=MAXIT;it++)
116  {
117  iter=it;
118  b=coeffs[m];
119  double err=abs(b);
120  d=f=0.0;
121  double abx=abs(x);
122  for (int j=m-1;j>=0;j--)
123  {
124  f=x*f+d;
125  d=x*d+b;
126  b=x*b+coeffs[j];
127  err=abs(b)+abx*err;
128  }
129  err *= EPS;
130  if (abs(b) <= err) return iter;
131  g=d/b;
132  g2=g*g;
133  h=g2-2.0*f/b;
134  sq=sqrt(double(m-1)*(double(m)*h-g2));
135  gp=g+sq;
136  gm=g-sq;
137  double abp=abs(gp);
138  double abm=abs(gm);
139  if(abp < abm)
140  {
141  gp=gm;
142  }
143  if(max(abp,abm)>0.0)
144  {
145  dx = ((double) m)/gp;
146  }
147  else
148  {
149  dx = std::polar(1+abx,((double)it));
150  }
151  x1=x-dx;
152  if(x==x1)
153  {
154  return iter;
155  }
156  if((it%MT)!=0)
157  {
158  x=x1;
159  }
160  else
161  {
162  x -= frac[it/MT]*dx;
163  }
164  }
165  BIASWARN("too many iterations");
166  return -1;
167 }
168 
169