Exemplo n.º 1
0
Alignment::Alignment(PharmacophoreMap& fMap) :
	_refMap(),
	_dbMap(),
	_refCenter(),
	_dbCenter(),
	_refRotMat(3,3,0.0),
	_dbRotMat(3,3,0.0),
	_dCdq(4,0.0),
	_d2Cdq2(4,4,0.0),
	_grad(4,0.0),
	_AkA(fMap.size()),
	_nbrPoints(0),
	_nbrExcl(0)
{
	// compute centers of the two pharmacophore sets
	PharmacophoreMap::iterator mi;

	unsigned int nbrMatch(0);
		
	// compute the centroid of the pharmacophores
	double V1(0.0), v1(0.0), V2(0.0), v2(0.0);
	for (mi = fMap.begin(); mi != fMap.end(); ++mi)
	{
		if (mi->first->func == EXCL)
		{
			_nbrExcl++;
			continue; // do not use exclusion spheres when computing the center
		}

		_nbrPoints++;
		
		v1 = GCI * pow(PI/mi->first->alpha,1.5);
		V1 += v1;
		_refCenter.x += v1 * mi->first->point.x;
		_refCenter.y += v1 * mi->first->point.y;
		_refCenter.z += v1 * mi->first->point.z;
			
		v2 = GCI * pow(PI/mi->second->alpha,1.5);
		V2 += v2;
		_dbCenter.x += v2 * mi->second->point.x;
		_dbCenter.y += v2 * mi->second->point.y;
		_dbCenter.z += v2 * mi->second->point.z;
		++nbrMatch;
	}
	_refCenter.x /= V1;
	_refCenter.y /= V1;
	_refCenter.z /= V1;
	
	_dbCenter.x /= V2;
	_dbCenter.y /= V2;
	_dbCenter.z /= V2;

	// translate the pharmacophores to the centers
	// and compute center of mass matrix
	SiMath::Matrix mass1(3,3,0.0);
	SiMath::Matrix mass2(3,3,0.0);
	for (mi = fMap.begin(); mi != fMap.end(); ++mi)
	{
		PharmacophorePoint p1, p2;

		p1.point.x = mi->first->point.x - _refCenter.x;
		p1.point.y = mi->first->point.y - _refCenter.y;
		p1.point.z = mi->first->point.z - _refCenter.z;
		p1.func = mi->first->func;
		p1.alpha = mi->first->alpha;
		p1.normal.x = mi->first->normal.x - mi->first->point.x;
		p1.normal.y = mi->first->normal.y - mi->first->point.y;
		p1.normal.z = mi->first->normal.z - mi->first->point.z;
		
		p2.point.x = mi->second->point.x - _dbCenter.x;
		p2.point.y = mi->second->point.y - _dbCenter.y;
		p2.point.z = mi->second->point.z - _dbCenter.z;
		p2.func = mi->second->func;
		p2.alpha = mi->second->alpha;
		p2.normal.x = mi->second->normal.x - mi->second->point.x;
		p2.normal.y = mi->second->normal.y - mi->second->point.y;
		p2.normal.z = mi->second->normal.z - mi->second->point.z;

		if (mi->first->func != EXCL)
		{
			v1 = GCI * pow(PI/mi->first->alpha,1.5);
			mass1[0][0] += v1 * p1.point.x * p1.point.x;
			mass1[0][1] += v1 * p1.point.x * p1.point.y;
			mass1[0][2] += v1 * p1.point.x * p1.point.z;
			mass1[1][1] += v1 * p1.point.y * p1.point.y;
			mass1[1][2] += v1 * p1.point.y * p1.point.z;
			mass1[2][2] += v1 * p1.point.z * p1.point.z;
		
			v2 = GCI * pow(PI/mi->second->alpha,1.5);

			mass2[0][0] += v2 * p2.point.x * p2.point.x;
			mass2[0][1] += v2 * p2.point.x * p2.point.y;
			mass2[0][2] += v2 * p2.point.x * p2.point.z;
			mass2[1][1] += v2 * p2.point.y * p2.point.y;
			mass2[1][2] += v2 * p2.point.y * p2.point.z;
			mass2[2][2] += v2 * p2.point.z * p2.point.z;
		}
		// add new points to local maps
		_refMap.push_back(p1);
		_dbMap.push_back(p2);		
	}
	
	// use SVD to compute best rotations
	// set lower triangle
	mass1[1][0] = mass1[0][1];
	mass1[2][0] = mass1[0][2];
	mass1[2][1] = mass1[1][2];
	
	// normalize mass matrix
	mass1 /= V1;
   
	// compute SVD of the mass matrix
	SiMath::SVD svd(mass1, true, true);
	_refRotMat = svd.getU();
   
	// check if determinant is 1, otherwise it is a mirroring instead of rotation
	double det = _refRotMat[0][0]*_refRotMat[1][1]*_refRotMat[2][2]
		+ _refRotMat[2][1]*_refRotMat[1][0]*_refRotMat[0][2]
		+ _refRotMat[0][1]*_refRotMat[1][2]*_refRotMat[2][0] 
		- _refRotMat[0][0]*_refRotMat[1][2]*_refRotMat[2][1]
		- _refRotMat[1][1]*_refRotMat[2][0]*_refRotMat[0][2]
		- _refRotMat[2][2]*_refRotMat[0][1]*_refRotMat[1][0];
		
	// check if it is a rotation matrix and not a mirroring
	if (det < 0)
	{
		// switch sign of third column
		_refRotMat[0][2] = -_refRotMat[0][2];
		_refRotMat[1][2] = -_refRotMat[1][2];
		_refRotMat[2][2] = -_refRotMat[2][2];
	}
	
	// set lower triangle
	mass2[1][0] = mass2[0][1];
	mass2[2][0] = mass2[0][2];
	mass2[2][1] = mass2[1][2];
	
	// normalize mass matrix
	mass2 /= V2;
   
	// compute SVD of the mass matrix
	SiMath::SVD svd2(mass2, true, true);
	_dbRotMat = svd2.getU();
	
	// check if determinant is 1, otherwise it is a mirroring instead of rotation
	det = _dbRotMat[0][0]*_dbRotMat[1][1]*_dbRotMat[2][2]
		+ _dbRotMat[2][1]*_dbRotMat[1][0]*_dbRotMat[0][2]
		+ _dbRotMat[0][1]*_dbRotMat[1][2]*_dbRotMat[2][0] 
		- _dbRotMat[0][0]*_dbRotMat[1][2]*_dbRotMat[2][1]
		- _dbRotMat[1][1]*_dbRotMat[2][0]*_dbRotMat[0][2]
		- _dbRotMat[2][2]*_dbRotMat[0][1]*_dbRotMat[1][0];
		
	// checif if it is a rotation matrix and not a mirroring
	if (det < 0)
	{
		// switch sign of third column
		_dbRotMat[0][2] = -_dbRotMat[0][2];
		_dbRotMat[1][2] = -_dbRotMat[1][2];
		_dbRotMat[2][2] = -_dbRotMat[2][2];
	}
	
	// rotate points towards main axes
	for (unsigned int i(0); i < _refMap.size(); ++i)
	{
		// Rotate points
		double x = _refMap[i].point.x;
		double y = _refMap[i].point.y;
		double z = _refMap[i].point.z;
		_refMap[i].point.x = _refRotMat[0][0]*x + _refRotMat[1][0]*y + _refRotMat[2][0]*z;
		_refMap[i].point.y = _refRotMat[0][1]*x + _refRotMat[1][1]*y + _refRotMat[2][1]*z;
		_refMap[i].point.z = _refRotMat[0][2]*x + _refRotMat[1][2]*y + _refRotMat[2][2]*z;

		x = _dbMap[i].point.x;
		y = _dbMap[i].point.y;
		z = _dbMap[i].point.z;
		_dbMap[i].point.x = _dbRotMat[0][0]*x + _dbRotMat[1][0]*y + _dbRotMat[2][0]*z;
		_dbMap[i].point.y = _dbRotMat[0][1]*x + _dbRotMat[1][1]*y + _dbRotMat[2][1]*z;
		_dbMap[i].point.z = _dbRotMat[0][2]*x + _dbRotMat[1][2]*y + _dbRotMat[2][2]*z;
		
		double dx = _refMap[i].point.x - _dbMap[i].point.x;
		double dx2 = dx * dx;
		double dy = _refMap[i].point.y - _dbMap[i].point.y;
		double dy2 = dy * dy;
		double dz = _refMap[i].point.z - _dbMap[i].point.z;
		double dz2 = dz * dz;
		double sx = _refMap[i].point.x + _dbMap[i].point.x;
		double sx2 = sx * sx;
		double sy = _refMap[i].point.y + _dbMap[i].point.y;
		double sy2 = sy * sy;
		double sz = _refMap[i].point.z + _dbMap[i].point.z;
		double sz2 = sz * sz;
		
		_AkA[i] = new SiMath::Matrix(4,4,0.0);
		(*_AkA[i])[0][0] = dx2 + dy2 + dz2;
		(*_AkA[i])[0][1] = dy*sz - sy*dz;
		(*_AkA[i])[0][2] = sx*dz - dx*sz;
		(*_AkA[i])[0][3] = dx*sy - sx*dy;
		(*_AkA[i])[1][0] = (*_AkA[i])[0][1];
		(*_AkA[i])[1][1] = dx2 + sy2 + sz2;
		(*_AkA[i])[1][2] = dx*dy - sx*sy;
		(*_AkA[i])[1][3] = dx*dz - sx*sz;
		(*_AkA[i])[2][0] = (*_AkA[i])[0][2];
		(*_AkA[i])[2][1] = (*_AkA[i])[1][2];
		(*_AkA[i])[2][2] = sx2 + dy2 + sz2;
		(*_AkA[i])[2][3] = dy*dz - sy*sz;
		(*_AkA[i])[3][0] = (*_AkA[i])[0][3];
		(*_AkA[i])[3][1] = (*_AkA[i])[1][3];
		(*_AkA[i])[3][2] = (*_AkA[i])[2][3];
		(*_AkA[i])[3][3] = sx2 + sy2 + dz2;

		// Rotate normals
		x = _refMap[i].normal.x;
		y = _refMap[i].normal.y;
		z = _refMap[i].normal.z;
		_refMap[i].normal.x = _refRotMat[0][0]*x + _refRotMat[1][0]*y + _refRotMat[2][0]*z;
		_refMap[i].normal.y = _refRotMat[0][1]*x + _refRotMat[1][1]*y + _refRotMat[2][1]*z;
		_refMap[i].normal.z = _refRotMat[0][2]*x + _refRotMat[1][2]*y + _refRotMat[2][2]*z;
		x = _dbMap[i].normal.x;
		y = _dbMap[i].normal.y;
		z = _dbMap[i].normal.z;
		_dbMap[i].normal.x = _dbRotMat[0][0]*x + _dbRotMat[1][0]*y + _dbRotMat[2][0]*z;
		_dbMap[i].normal.y = _dbRotMat[0][1]*x + _dbRotMat[1][1]*y + _dbRotMat[2][1]*z;
		_dbMap[i].normal.z = _dbRotMat[0][2]*x + _dbRotMat[1][2]*y + _dbRotMat[2][2]*z;		
	}
	
	return;
}
Exemplo n.º 2
0
  void qrstep (gsl_vector * d, gsl_vector * f, gsl_matrix * U, 
	       gsl_matrix * V) {

    const size_t M=U->size1;
    const size_t N=V->size1;
    const size_t n=d->size;
    double y, z;
    double ak, bk, zk, ap, bp, aq, bq;
    size_t i, k;

    //std::cout << "M,N,n: " << M << " " << N << " " << n << std::endl;

    if (n == 1)
      return;  /* shouldn't happen */

    /* Compute 2x2 svd directly */

    if (n == 2)
      {
	svd2 (d, f, U, V);
	return;
      }

    /* Chase out any zeroes on the diagonal */

    for (i=0; i < n - 1; i++)
      {
	double d_i=gsl_vector_get (d, i);
	//std::cout << "d_i: " << i << " " << n << " "
	//<< d_i << std::endl;
      
	if (d_i == 0.0)
	  {
	    chase_out_intermediate_zero (d, f, U, i);
	    return;
	  }
      }

    /* Chase out any zero at the end of the diagonal */

    {
      double d_nm1=gsl_vector_get (d, n - 1);
      //std::cout << "d_nm1: " << d_nm1 << std::endl;

      if (d_nm1 == 0.0) 
	{
	  chase_out_trailing_zero (d, f, V);
	  return;
	}
    }


    /* Apply QR reduction steps to the diagonal and offdiagonal */

    {
      double d0=gsl_vector_get (d, 0);
      double f0=gsl_vector_get (f, 0);
    
      double d1=gsl_vector_get (d, 1);
      double f1=gsl_vector_get (f, 1);
      //std::cout << "d0,f0,d1,f1: " << d0 << " " << f0 << " " << d1 << " "
      //<< f1 << std::endl;
    
      {
	double mu=trailing_eigenvalue (d, f);
    
	y=d0 * d0 - mu;
	z=d0 * f0;
      }
    
      /* Set up the recurrence for Givens rotations on a bidiagonal matrix */
    
      ak=0;
      bk=0;
    
      ap=d0;
      bp=f0;
    
      aq=d1;
      bq=f1;
    }

    for (k=0; k < n - 1; k++)
      {
	double c, s;
	create_givens (y, z, &c, &s);

	/* Compute V <= V G */

	for (i=0; i < N; i++)
	  {
	    double Vip=gsl_matrix_get (V, i, k);
	    double Viq=gsl_matrix_get (V, i, k + 1);
	    //std::cout << "Vip,Viq: " << Vip << " " << Viq << std::endl;
	    gsl_matrix_set (V, i, k, c * Vip - s * Viq);
	    gsl_matrix_set (V, i, k + 1, s * Vip + c * Viq);
	  }

	/* compute B <= B G */

	{
	  double bk1=c * bk - s * z;

	  double ap1=c * ap - s * bp;
	  double bp1=s * ap + c * bp;
	  double zp1=-s * aq;

	  double aq1=c * aq;

	  if (k > 0)
	    {
	      gsl_vector_set (f, k - 1, bk1);
	    }

	  ak=ap1;
	  bk=bp1;
	  zk=zp1;

	  ap=aq1;

	  if (k < n - 2)
	    {
	      bp=gsl_vector_get (f, k + 1);
	    }
	  else
	    {
	      bp=0.0;
	    }

	  y=ak;
	  z=zk;
	}

	create_givens (y, z, &c, &s);

	/* Compute U <= U G */

	for (i=0; i < M; i++)
	  {
	    double Uip=gsl_matrix_get (U, i, k);
	    double Uiq=gsl_matrix_get (U, i, k + 1);
	    //std::cout << "Uip2,Uiq2: " << Uip << " " << Uiq << std::endl;
	    gsl_matrix_set (U, i, k, c * Uip - s * Uiq);
	    gsl_matrix_set (U, i, k + 1, s * Uip + c * Uiq);
	  }

	/* compute B <= G^T B */
	
	//std::cout << "k,bk,ap2: " << k << " " << bk << " " << ap << std::endl;
	//std::cout << "ak,zk,bp: " << ak << " " << zk << " " 
	// << bp << std::endl;

	{
	  //std::cout << "prod1: " << c*ak << " " << s*zk << std::endl;
	  //std::cout << "prod2: " << c*bk << " " << s*ap << std::endl;
	  //std::cout << "prod3: " << s*bk << " " << c*ap << std::endl;
	  double ak1=c * ak - s * zk;
	  double bk1=c * bk - s * ap;
	  double zk1=-s * bp;

	  double ap1=s * bk + c * ap;
	  double bp1=c * bp;

	  gsl_vector_set (d, k, ak1);

	  ak=ak1;
	  bk=bk1;
	  zk=zk1;

	  ap=ap1;
	  bp=bp1;
	  //std::cout << "c,s: " << c << " " << s << std::endl;
	  //std::cout << "k,bk,ap: " << k << " " << bk << " " << ap << std::endl;

	  if (k < n - 2)
	    {
	      aq=gsl_vector_get (d, k + 2);
	    }
	  else
	    {
	      aq=0.0;
	    }

	  y=bk;
	  z=zk;
	}
      }

    gsl_vector_set (f, n - 2, bk);
    gsl_vector_set (d, n - 1, ap);
    //std::cout << "bk,ap: " << bk << " " << ap << std::endl;
  }
Exemplo n.º 3
0
matf GetExtrinsicsFromEssential(const matf & essMat_, const TrackedPoint & one_point,
				bool correct_essMat, int c) {
  matf essMat;
  if (correct_essMat) {
    SVD svd2(essMat_);
    matf D = matf(3,3,0.0f);
    D(0,0) = D(1,1) = (svd2.w.at<float>(0,0) + svd2.w.at<float>(1,0)) * 0.5f;
    essMat = svd2.u * D * svd2.vt;
  } else  {
    matf essMat = essMat_;
  }
  SVD svd(essMat);
  //assert(epsEqual(D(0,0) / D(1,0), 1.0, 0.1) && epsEqual(D(2,0), 0.0f));
  matf W(3,3,0.0f); //TODO do not recreate at each call
  W(0,1) = -1.0f;
  W(1,0) = W(2,2) = 1.0f;
  
  matf extr(3,4);
  matf tmp;
  //case 1
  tmp = svd.u*W*svd.vt;
  for (int i = 0; i < 3; ++i)
    for (int j = 0; j < 3; ++j)
      extr(i,j) = tmp(i,j);
  for (int i = 0; i < 3; ++i)
    extr(i, 3) = svd.u.at<float>(i, 2);
  //cout << extr << endl;
  if ((c == 1) || ((c == -1) && IsExtrinsicsPossible(extr, one_point))) {
    //cout << "case 1" << endl;
    return extr;
  }
  //case 2
  for (int i = 0; i < 3; ++i)
    extr(i, 3) = -svd.u.at<float>(i, 2);
  //cout << extr << endl;
  if ((c == 2) || ((c == -1) && IsExtrinsicsPossible(extr, one_point))) {
    //cout << "case 2" << endl;
    return extr;
  }
  //case 3
  tmp = svd.u*W.t()*svd.vt;
  for (int i = 0; i < 3; ++i)
    for (int j = 0; j < 3; ++j)
      extr(i,j) = tmp(i,j);
  //cout << extr << endl;
  if ((c == 3) || ((c == -1) && IsExtrinsicsPossible(extr, one_point))) {
    //cout << "case 3" << endl;
    return extr;
  }
  //case 4
  for (int i = 0; i < 3; ++i)
    extr(i, 3) = svd.u.at<float>(i, 2);
  //cout << extr << endl;
  if ((c == 4) || ((c == -1) && IsExtrinsicsPossible(extr, one_point))) {
    //cout << "case 4" << endl;
    return extr;
  }
  //assert(false); //this should not happen. If it does, sth is wrong
  // (the point might be the on the principal plane, or there is a bug)
  return matf(0,0); // remove warning
}