Пример #1
0
/*
  pA: the pointer of the Matrix A|b
  rowMax,colMax:size of matirx
  pX: solution vector
  return value: -1 solving equation failed
  		 		1 resolve result successfully
*/
int gaussLesung(double *pA, int rowMax,int colMax, double *pX)
{
 	 double *pMatrix = pA;
 	 int i;
 	 double product;
 	 product = 1;
 	 if((1+rowMax)!=colMax) return -1;
 	 
 	 for(i = 0; i < rowMax; i++)
 	 {
  	   int l;
 	   printf("%d,\n",i);
 	   
 	   l = findMax(pMatrix, rowMax, colMax, i,i);
 	   exchangeRow(pMatrix, rowMax, colMax, l, i);
 	   eliminate(pMatrix, rowMax, colMax, i, i);
       outputMatrix(pMatrix, rowMax, colMax);
     }
     
     
     for(i = 0; i < rowMax; i++)product = product * pMatrix[i*colMax+i];
     if(product==0)return -1;
 	 
	  solveX(pMatrix, rowMax,colMax, pX);
	  return 1;
}
void PointCloudProcessing::getRTGeometricLinearSystem(PointCloudC::Ptr corrRef,
                                                      PointCloudC::Ptr corrNew,
                                                      Eigen::Matrix4f &transMat)
{
  // build linear system Ax = b;
  int rows = 3*corrRef->points.size();
  int cols = 6;
  Eigen::MatrixXf A(rows, cols); A.setZero();
  Eigen::MatrixXf b(rows, 1); b.setZero();
  for(int i=0; i<corrRef->points.size(); i++)
    {
      float X1 = corrRef->points.at(i).x;
      float Y1 = corrRef->points.at(i).y;
      float Z1 = corrRef->points.at(i).z;
      float X0 = corrNew->points.at(i).x;
      float Y0 = corrNew->points.at(i).y;
      float Z0 = corrNew->points.at(i).z;
      A(3*i,   0) = 0;      A(3*i,   1) = Z0+Z1;  A(3*i,   2) = -Y0-Y1; A(3*i,   3) = 1;
      A(3*i+1, 0) = -Z0-Z1; A(3*i+1, 1) = 0;      A(3*i+1, 2) = X0+X1;  A(3*i+1, 4) = 1;
      A(3*i+2, 0) = Y0+Y1;  A(3*i+1, 1) = -X0-X1; A(3*i+2, 2) = 0;      A(3*i+2, 5) = 1;

      b(3*i,   0) = X1-X0;
      b(3*i+1, 0) = Y1-Y0;
      b(3*i+2, 0) = Z1-Z0;
    }
  //    std::cout<<"A = "<<A<<std::endl;
  //    std::cout<<"b = "<<b<<std::endl;
  Eigen::MatrixXf solveX(rows, 1); solveX.setZero();
  solveX = A.jacobiSvd(Eigen::ComputeThinU | Eigen::ComputeThinV).solve(b);
  //    std::cout<<"solveX: "<<solveX<<"\n";

  // solveX = [Rx, Ry, Rz, T'x, T'y, T'z];
  Eigen::Matrix3f I_Vx; I_Vx.setOnes();
  I_Vx(0,0) = 1;          I_Vx(0,1) = solveX(2);  I_Vx(0,2) = -solveX(1);
  I_Vx(1,0) = -solveX(2); I_Vx(1,1) = 1;          I_Vx(1,2) = solveX(0);
  I_Vx(2,0) = solveX(1);  I_Vx(2,1) = -solveX(0); I_Vx(2,2) = 1;
  Eigen::Vector3f Tx; Tx.setZero();
  Tx(0) = solveX(3); Tx(1) = solveX(4); Tx(2) = solveX(5);
  Eigen::Vector3f tx; tx.setZero();
  tx = I_Vx.inverse()*Tx;
  transMat(0,3) = tx(0); transMat(1,3) = tx(1); transMat(2,3) = tx(2);

  Eigen::Matrix3f IplusVx; IplusVx.setOnes();
  IplusVx(0,0) = 1;          IplusVx(0,1) = -solveX(2);  IplusVx(0,2) = solveX(1);
  IplusVx(1,0) = solveX(2);  IplusVx(1,1) = 1;           IplusVx(1,2) = -solveX(0);
  IplusVx(2,0) = -solveX(1); IplusVx(2,1) = solveX(0);   IplusVx(2,2) = 1;
  Eigen::Matrix3f Ro; Ro.setZero();
  Ro = I_Vx.inverse()*IplusVx;
  transMat(0,0) = Ro(0,0); transMat(0,1) = Ro(0,1); transMat(0,2) = Ro(0,2); transMat(0,3) = tx(0);
  transMat(1,0) = Ro(1,0); transMat(1,1) = Ro(1,1); transMat(1,2) = Ro(1,2); transMat(1,3) = tx(1);
  transMat(2,0) = Ro(2,0); transMat(2,1) = Ro(2,1); transMat(2,2) = Ro(2,2); transMat(2,3) = tx(2);
  //    std::cout<<"transMat Geometric: "<<transMat<<"\n";
}
Пример #3
0
// bi-conjugate linear equation solver
// overwrites pyramid!
static void linbcg(pyramid_t* pyramid, pyramid_t* pC, float* const b, float* const x, const int itmax, const float tol, pfstmo_progress_callback progress_cb)
{
  const int rows = pyramid->rows;
  const int cols = pyramid->cols;
  const int n = rows*cols;
  const float tol2 = tol*tol;
	
  float* const z = matrix_alloc(n);
  float* const zz = matrix_alloc(n);
  float* const p = matrix_alloc(n);
  float* const pp = matrix_alloc(n);
  float* const r = matrix_alloc(n);
  float* const rr = matrix_alloc(n);	
  float* const x_save = matrix_alloc(n);	
	
  const float bnrm2 = matrix_DotProduct(n, b, b);
	
  multiplyA(pyramid, pC, x, r); // r = A*x = divergence(x)
  matrix_subtract(n, b, r); // r = b - r
  float err2 = matrix_DotProduct(n, r, r); // err2 = r.r

  // matrix_copy(n, r, rr); // rr = r
  multiplyA(pyramid, pC, r, rr); // rr = A*r
  
  float bkden = 0;
  float saved_err2 = err2;
  matrix_copy(n, x, x_save);

  const float ierr2 = err2;
  const float percent_sf = 100.0f/logf(tol2*bnrm2/ierr2);

  int iter = 0;
  bool reset = true;
  int num_backwards = 0;
  const int num_backwards_ceiling = 3;
  for (; iter < itmax; iter++)
    {
      if( progress_cb != NULL )
	progress_cb( (int) (logf(err2/ierr2)*percent_sf));    
      
      solveX(n, r, z);   //  z = ~A(-1) *  r = -0.25 *  r
      solveX(n, rr, zz); // zz = ~A(-1) * rr = -0.25 * rr
		
      const float bknum = matrix_DotProduct(n, z, rr);
		
      if(reset)
	{
	  reset = false;
	  matrix_copy(n, z, p);
	  matrix_copy(n, zz, pp); 
	}
      else
	{
	  const float bk = bknum / bkden; // beta = ...
#pragma omp parallel for schedule(static)
	  for (int i = 0; i < n; i++)
	    {
	      p[i]  =  z[i] + bk *  p[i];
	      pp[i] = zz[i] + bk * pp[i];
	    }
	}
		
      bkden = bknum; // numerato becomes the dominator for the next iteration
      
      multiplyA(pyramid, pC,  p,  z); //  z = A* p = divergence( p)
      multiplyA(pyramid, pC, pp, zz); // zz = A*pp = divergence(pp)
      
      const float ak = bknum / matrix_DotProduct(n, z, pp); // alfa = ...
#pragma omp parallel for schedule(static)
      for(int i = 0 ; i < n ; i++ )
	{
	  r[i]  -= ak *  z[i];	// r =  r - alfa * z
	  rr[i] -= ak * zz[i];	//rr = rr - alfa * zz
	}
      
      const float old_err2 = err2;
      err2 = matrix_DotProduct(n, r, r);

      // Have we gone unstable?
      if (err2 > old_err2)
	{
	  // Save where we've got to if it's the best yet
	  if (num_backwards == 0 && old_err2 < saved_err2)
	    {
	      saved_err2 = old_err2;
	      matrix_copy(n, x, x_save);
	    }
	  
	  num_backwards++;
	}
      else
	{
	  num_backwards = 0;
	}

#pragma omp parallel for schedule(static)
      for(int i = 0 ; i < n ; i++ )
	x[i] += ak * p[i];	// x =  x + alfa * p

      if (num_backwards > num_backwards_ceiling)
	{
	  // Reset
	  reset = true;
	  num_backwards = 0;
	  
	  // Recover saved value
	  matrix_copy(n, x_save, x);
	  
	  // r = Ax
	  multiplyA(pyramid, pC, x, r);
	  
	  // r = b - r
	  matrix_subtract(n, b, r);
	  
	  // err2 = r.r
	  err2 = matrix_DotProduct(n, r, r);
	  saved_err2 = err2;

	  // rr = A*r
	  multiplyA(pyramid, pC, r, rr);
	}
      
      // fprintf(stderr, "iter:%d err:%f\n", iter+1, sqrtf(err2/bnrm2));
      if(err2/bnrm2 < tol2)
	break;
    }

  // Use the best version we found
  if (err2 > saved_err2)
    {
      err2 = saved_err2;
      matrix_copy(n, x_save, x);
    }

  if (err2/bnrm2 > tol2)
    {
      // Not converged
      if( progress_cb != NULL )
	progress_cb( (int) (logf(err2/ierr2)*percent_sf));    
      if (iter == itmax)
	fprintf(stderr, "\npfstmo_mantiuk06: Warning: Not converged (hit maximum iterations), error = %g (should be below %g).\n", sqrtf(err2/bnrm2), tol);  
      else
	fprintf(stderr, "\npfstmo_mantiuk06: Warning: Not converged (going unstable), error = %g (should be below %g).\n", sqrtf(err2/bnrm2), tol);  
    }
  else if (progress_cb != NULL)
    progress_cb(100);
    
  
  matrix_free(x_save);
  matrix_free(p);
  matrix_free(pp);
  matrix_free(z);
  matrix_free(zz);
  matrix_free(r);
  matrix_free(rr);
}