contrib/oxl/mvl/HMatrix1DComputeOptimize1.cxx
Go to the documentation of this file.
00001 #include "HMatrix1DComputeOptimize1.h"
00002 #include "HMatrix1DComputeDesign.h"
00003 
00004 #include <vcl_cassert.h>
00005 #include <vcl_iostream.h>
00006 #include <vcl_iomanip.h>
00007 
00008 #include <vnl/vnl_least_squares_function.h>
00009 #include <vnl/algo/vnl_levenberg_marquardt.h>
00010 #include <vgl/vgl_homg_point_1d.h>
00011 #include <mvl/HMatrix1D.h>
00012 
00013 //********************************************************************************
00014 //
00015 //
00016 //
00017 //********************************************************************************
00018 
00019 
00020 class XXX : public vnl_least_squares_function
00021 {
00022   unsigned N;
00023   const vcl_vector<double> &z1,z2;
00024  public:
00025   XXX(const vcl_vector<double> &z1_,const vcl_vector<double> &z2_)
00026     : vnl_least_squares_function(3, z1_.size(), no_gradient)
00027     , N(z1_.size())
00028     , z1(z1_) , z2(z2_)
00029     {
00030       assert(N == z1.size());
00031       assert(N == z2.size());
00032       //      vcl_cerr << "N=" << N << vcl_endl;
00033     }
00034   ~XXX() { N=0; }
00035 
00036   void boo(const vnl_vector<double> &x) {
00037     assert(x.size()==3);
00038     vcl_cerr << vcl_showpos << vcl_fixed; // <iomanip>
00039     double z,y;
00040     for (unsigned i=0;i<N;i++) {
00041       z=z1[i];
00042       y=(z+x[0])/(x[1]*z+1+x[2]);
00043       vcl_cerr << z << ' ' << y << '[' << z2[i] << ']' << vcl_endl;
00044     }
00045   }
00046 
00047   //    the matrix is   [ 1.0    x[0] ]
00048   //                    [ x[1] 1+x[2] ]
00049   void f(const vnl_vector<double>& x, vnl_vector<double>& fx) {
00050     assert(x.size()==3);
00051     assert(fx.size()==N);
00052     double z,y;
00053     for (unsigned k=0;k<N;k++) {
00054       z=z1[k];
00055       y=(z+x[0])/(x[1]*z+1+x[2]);
00056       fx[k]=z2[k]-y;
00057     }
00058   }
00059 };
00060 
00061 static
00062 void do_compute(const vcl_vector<double> &z1,const vcl_vector<double> &z2,HMatrix1D &M)
00063 {
00064   //
00065   // **** minimise over the set of 2x2 matrices of the form [  1     x[0] ] ****
00066   // ****                                                   [ x[1] 1+x[2] ] ****
00067   //
00068 
00069   // Set up a compute object :
00070   XXX f(z1,z2);
00071 
00072   // Set up the initial guess :
00073   vnl_vector<double> x(3);
00074   x.fill(0);
00075 
00076   // Make a Levenberg Marquardt minimizer and attach f to it :
00077   vnl_levenberg_marquardt LM(f);
00078 
00079   // Run minimiser :
00080   //    f.boo(x);
00081   LM.minimize(x);
00082   //    f.boo(x);
00083 
00084   // convert back to matrix format.
00085   vnl_double_2x2 T;
00086   T(0,0)=1; T(0,1)=x[0];
00087   T(1,0)=x[1]; T(1,1)=1+x[2];
00088   M.set(T);
00089 }
00090 
00091 HMatrix1DComputeOptimize1::HMatrix1DComputeOptimize1(void) : HMatrix1DCompute() { }
00092 HMatrix1DComputeOptimize1::~HMatrix1DComputeOptimize1() { }
00093 
00094 bool
00095 HMatrix1DComputeOptimize1::compute_cool_homg(const vcl_vector<vgl_homg_point_1d<double> >&p1,
00096                                              const vcl_vector<vgl_homg_point_1d<double> >&p2,
00097                                              HMatrix1D *M)
00098 {
00099   unsigned N=p1.size();
00100   assert(N==p2.size());
00101   if (N<3) return false;
00102 
00103   vcl_vector<double> z1(N,0.0),z2(N,0.0);
00104   HMatrix1DComputeDesign C;
00105   C.compute(p1,p2,M);
00106 
00107   // map the points in p1 under M so that we are looking for a correction near the identity :
00108   for (unsigned i=0;i<N;i++) {
00109     vgl_homg_point_1d<double> v = (*M)(p1[i]);
00110     if (v.w() == 0.0) return false;
00111     z1[i] = v.x()/v.w(); // make nonhomogeneous
00112     if (p2[i].w()) return false;
00113     z2[i] = p2[i].x()/p2[i].w(); // make nonhomogeneous
00114   }
00115 
00116   HMatrix1D K;
00117   do_compute(z1,z2,K);
00118   *M=HMatrix1D(K,*M);      // refine M using the correction K.
00119   return true;
00120 }
00121