Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ExampleLaguerre.cpp
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003, 2004 (see file CONTACTS 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 
26 
27 /** @example ExampleLaguerre.cpp
28  @relates Laguerre
29  @ingroup g_examples
30  @brief Example for usage of Laguerre Solver for Polynomials
31  @author MIP
32 */
33 
34 #include "Base/Debug/Error.hh"
35 #include <MathAlgo/Laguerre.hh>
36 #include <Base/Common/CompareFloatingPoint.hh>
37 #include <iostream>
38 #include <algorithm>
39 #ifdef WIN32
40 #include <functional>
41 #endif
42 
43 
44 using namespace BIAS;
45 using namespace std;
46 
47 double frand(double min = -10.0 , double max = 10.0)
48 {
49  double tmin = min;
50  double tmax = max;
51  const unsigned int res = 10000000;
52  unsigned int i=rand()%res;
53  double scale = ((double) i) / ((double) res);
54  double diff = tmax - tmin;
55  return(tmin+scale*diff);
56 }
57 
58 //bitmask looks like 00001111
59 unsigned int GetNumberOfBinaryOnes(unsigned int val,
60  unsigned int mask)
61 {
62  unsigned int bitmask = mask;
63  unsigned int temp = val;
64  unsigned int count = 0;
65  while((bitmask)!=0) //dont use the full size of unsigned int
66  {
67  if((temp&1)==1)
68  {
69  count++;
70  }
71  temp = temp>>1;
72  bitmask = bitmask>>1;
73  }
74  return count;
75 }
76 
77 void GetIndexListFromBinaryZeros(unsigned int val,
78  unsigned int mask,
79  std::vector<unsigned int>& indices)
80 {
81  indices.clear();
82  unsigned int bitmask = mask;
83  unsigned int temp = val;
84  unsigned int count = 0;
85  while((bitmask)!=0) //dont use the full size of unsigned int
86  {
87  if((temp&1)==0)
88  {
89  indices.push_back(count);
90  }
91  temp = temp>>1;
92  bitmask = bitmask>>1;
93  count++;
94  }
95 }
96 
97 // create a polynomial from random roots
98 // idea: use bit pattern of numbers between 0 and (2^degree)-1
99 // to decide which roots are multiplied and added to get the coefficients
100 void CreateRandomPolynomial(unsigned int degree,
101  vector< complex<double> >& coeffs,
102  vector< complex<double> >& roots)
103 {
104  BIASASSERT(degree>0);
105  roots.clear();
106  coeffs.clear();
107  std::vector<unsigned int> tempIDs;
108  unsigned int coeffidx ;
109  //create random roots ... (x-z0)(x-z1)(x-z2)...(x-zdegree)
110  for(unsigned int r=0; r<degree; r++)
111  {
112  roots.push_back(frand());
113  }
114  coeffs.resize(degree+1,complex<double>(0,0)); //2
115 // //create coeffs for random roots
116  unsigned int maxiter = 1<<(degree);
117  unsigned int bitmask = maxiter - 1; // 00111
118  for(unsigned int c=0; c<maxiter; c++)
119  {
120  GetIndexListFromBinaryZeros(c,bitmask,tempIDs);
121  coeffidx = GetNumberOfBinaryOnes(c,bitmask);
122  complex<double> someroots(1,0);
123  for(unsigned int r=0;r<tempIDs.size();r++)
124  {
125  someroots = someroots * (-roots[tempIDs[r]]);
126  }
127  // cout<<c<<" "<<"coeffidx: "<<coeffidx<<endl;
128  BIASASSERT(coeffidx<coeffs.size());
129  coeffs[coeffidx]= coeffs[coeffidx] + someroots;
130  }
131 
132 }
133 
134 struct complex_comp :
135  public binary_function< complex<double>, complex<double>, bool>
136 {
137  bool operator()(complex<double> x, complex< double> y)
138  {
139  if(x.real()<=y.real())
140  {
141  if(x.real()==y.real())
142  {
143  return(x.imag()<y.imag());
144  }
145  return(true);
146  }
147  return(false);
148  }
149 };
150 
151 
152 double MeanError(vector< complex<double> >& v1,
153  vector< complex<double> >& v2,
154  double& min, double& max)
155 {
156  BIASASSERT(v1.size()==v2.size())
157 
158  sort(v1.begin(),v1.end(),complex_comp());
159  sort(v2.begin(),v2.end(),complex_comp());
160 
161 // cout<<endl;
162 // copy(v1.begin(),v1.end(), ostream_iterator<complex<double> >(cout, " "));
163 // cout<<endl<<"--------------------------"<<endl;
164 // copy(v2.begin(),v2.end(), ostream_iterator<complex<double> >(cout, " "));
165 //
166  double error =0 ;
167  double tmax=0, tmin=10000000;
168  for(unsigned int roo=0;roo<v1.size(); roo++)
169  {
170  double n = norm(v2[roo]-v1[roo]);
171  if(n>tmax)tmax= n;
172  if(n<tmin)tmin= n;
173  error+= n; //sum deviation from 0.0
174  }
175  max=tmax;
176  min=tmin;
177  return (error/v1.size());
178 
179 }
180 
181 bool Equal(const complex<double>& a,
182  const complex<double>& b)
183 {
184  return((Equal(a.real(),b.real(),10e-12))&&
185  ((Equal(a.imag(),b.imag(),10e-12))));
186 }
187 
188 
189 int main(int argc, char *argv[])
190 {
191  LaguerreSolver l;
192  vector< complex<double> > realcoeff;
193  vector< complex<double> > expectedroots;
194  vector< complex<double> > roots;
195 
196  unsigned int deg = 8; //<------------------------------- hier!!!
197 
198  double max = -10e6; // small number
199  double min = 10e6; // large number
200  double meanmeanerror=0;
201  double meanmin = 10000000;
202  double meanmax = 0;
203  double tmin;
204  double tmax;
205  for(unsigned run=0; run<100; run++)
206  {
207  CreateRandomPolynomial(deg,realcoeff,expectedroots);
208  l.Solve(realcoeff, roots);
209  double err;
210  if(run==0)
211  err=MeanError(expectedroots,roots,min,max);
212  else
213  {
214  err=MeanError(expectedroots,roots,tmin,tmax);
215  if(min>tmin)min=tmin;
216  if(max<tmax)max=tmax;
217  }
218  cout<<err<<" min: "<< min<<" max: "<< max<<endl;
219 
220  if(err<meanmin)meanmin=err;
221  if(err>meanmax)meanmax=err;
222  meanmeanerror +=err;
223  }
224  meanmeanerror /= 100.0;
225  cout<<"-----------------------------------------------------------"<<endl;
226  cout<<"min error (no mean):"<< min <<endl;
227  cout<<"max error (no mean):"<< max <<endl;
228  cout<<"mean min error:"<< meanmin <<endl;
229  cout<<"mean max error:"<< meanmax <<endl;
230  cout<<"mean mean error:"<< meanmeanerror <<endl;
231  return 0;
232 }
233 
int Solve(const std::vector< std::complex< double > > &coeffs, std::vector< std::complex< double > > &roots, const double eps=1.0e-14)
compute roots of a polynomial using the laguerre method
Definition: Laguerre.cpp:46
class encapsulating a laguerre solver for polynomials
Definition: Laguerre.hh:39
bool Equal(const T left, const T right, const T eps)
comparison function for floating point values See http://www.boost.org/libs/test/doc/components/test_...