Ejemplo n.º 1
0
IGL_INLINE bool igl::GeneralPolyVectorFieldFinder<DerivedV, DerivedF>::
                     solve(const Eigen::VectorXi &isConstrained,
                           const Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, Eigen::Dynamic> &cfW,
                           const Eigen::VectorXi &rootsIndex,
                           Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, Eigen::Dynamic> &output)
{

  // polynomial is of the form:
  // z^(2n) +
  // -c[0]z^(2n-1) +
  // c[1]z^(2n-2) +
  // -c[2]z^(2n-3) +
  // ... +
  // (-1)^n c[n-1]

  std::vector<Eigen::Matrix<std::complex<typename DerivedV::Scalar>, Eigen::Dynamic,1>> coeffs(n,Eigen::Matrix<std::complex<typename DerivedV::Scalar>, Eigen::Dynamic,1>::Zero(numF, 1));

  for (int i =0; i<n; ++i)
  {
    int degree = i+1;

    Eigen::Matrix<std::complex<typename DerivedV::Scalar>, Eigen::Dynamic,1> Ck;
    getGeneralCoeffConstraints(isConstrained,
                               cfW,
                               i,
                               rootsIndex,
                               Ck);

    Eigen::SparseMatrix<std::complex<typename DerivedV::Scalar> > DD;
    computeCoefficientLaplacian(degree, DD);
    Eigen::SparseMatrix<std::complex<typename DerivedV::Scalar> > f; f.resize(numF,1);

    if (isConstrained.sum() == numF)
      coeffs[i] = Ck;
    else
      minQuadWithKnownMini(DD, f, isConstrained, Ck, coeffs[i]);
  }

  std::vector<Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, 2> > pv;
  setFieldFromGeneralCoefficients(coeffs, pv);

  output.setZero(numF,3*n);
  for (int fi=0; fi<numF; ++fi)
  {
    const Eigen::Matrix<typename DerivedV::Scalar, 1, 3> &b1 = B1.row(fi);
    const Eigen::Matrix<typename DerivedV::Scalar, 1, 3> &b2 = B2.row(fi);
    for (int i=0; i<n; ++i)
      output.block(fi,3*i, 1, 3) = pv[i](fi,0)*b1 + pv[i](fi,1)*b2;
  }
  return true;
}
Ejemplo n.º 2
0
    void dare(const Eigen::Matrix<double,xDim,xDim> &A, const Eigen::Matrix<double,xDim,uDim> &B, Eigen::Matrix<double,xDim,xDim> &P) 
    {
      Eigen::Matrix<double,xDim,xDim> Ainv = A.inverse();
      Eigen::Matrix<double,xDim,xDim> ABRB = Ainv * B * _R.llt().solve(B.transpose());
      
      Eigen::Matrix<double,2*xDim,2*xDim> Z;
      Z.block(0,0,xDim,xDim) = Ainv;
      Z.block(0,xDim,xDim,xDim) = ABRB;
      Z.block(xDim,0,xDim,xDim) = _Q * Ainv;
      Z.block(xDim,xDim,xDim,xDim) = A.transpose() + _Q * ABRB;

      Eigen::ComplexEigenSolver <Eigen::Matrix<double,2*xDim,2*xDim> > ces;
      ces.compute(Z);

      Eigen::Matrix<std::complex<double>,2*xDim,1> eigVal = ces.eigenvalues();
      Eigen::Matrix<std::complex<double>,2*xDim,2*xDim> eigVec = ces.eigenvectors();

      Eigen::Matrix<std::complex<double>,2*xDim,xDim> unstableEigVec;
      
      int ctr = 0;
      for (int i = 0; i < 2*xDim; i++) {
        if (eigVal(i).real()*eigVal(i).real() + eigVal(i).imag()*eigVal(i).imag() > 1) {
          unstableEigVec.col(ctr) = eigVec.col(i);
          ctr++;
          if (ctr > xDim)
            break;
        }
      }
      
      Eigen::Matrix<std::complex<double>,xDim,xDim> U21inv = unstableEigVec.block(0,0,xDim,xDim).inverse();
      Eigen::Matrix<std::complex<double>,xDim,xDim> PP = unstableEigVec.block(xDim,0,xDim,xDim) * U21inv;
      
      for (int i = 0; i < xDim; i++) {
        for (int j = 0; j < xDim; j++) {
          P(i,j) = PP(i,j).real();
        }
      }
    }
Ejemplo n.º 3
0
IGL_INLINE void igl::repdiag(
  const Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> & A,
  const int d,
  Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> & B)
{
  int m = A.rows();
  int n = A.cols();
  B.resize(m*d,n*d);
  B.array() *= 0;
  for(int i = 0;i<d;i++)
  {
    B.block(i*m,i*n,m,n) = A;
  }
}
Ejemplo n.º 4
0
IGL_INLINE void igl::PolyVectorFieldFinder<DerivedV, DerivedF>::getGeneralCoeffConstraints(const Eigen::VectorXi &isConstrained,
                                                       const Eigen::Matrix<typename DerivedV::Scalar, Eigen::Dynamic, Eigen::Dynamic> &cfW,
                                                       int k,
                                                       Eigen::Matrix<std::complex<typename DerivedV::Scalar>, Eigen::Dynamic,1> &Ck)
{
  int numConstrained = isConstrained.sum();
  Ck.resize(numConstrained,1);
  int n = cfW.cols()/3;

  Eigen::MatrixXi allCombs;
  {
    Eigen::VectorXi V = Eigen::VectorXi::LinSpaced(n,0,n-1);
    igl::nchoosek(V,k+1,allCombs);
  }


  int ind = 0;
  for (int fi = 0; fi <numF; ++fi)
  {
    const Eigen::Matrix<typename DerivedV::Scalar, 1, 3> &b1 = B1.row(fi);
    const Eigen::Matrix<typename DerivedV::Scalar, 1, 3> &b2 = B2.row(fi);
    if(isConstrained[fi])
    {
      std::complex<typename DerivedV::Scalar> ck(0);

      for (int j = 0; j < allCombs.rows(); ++j)
      {
        std::complex<typename DerivedV::Scalar> tk(1.);
        //collect products
        for (int i = 0; i < allCombs.cols(); ++i)
        {
          int index = allCombs(j,i);

          const Eigen::Matrix<typename DerivedV::Scalar, 1, 3> &w = cfW.block(fi,3*index,1,3);
          typename DerivedV::Scalar w0 = w.dot(b1);
          typename DerivedV::Scalar w1 = w.dot(b2);
          std::complex<typename DerivedV::Scalar> u(w0,w1);
          tk*= u*u;
        }
        //collect sum
        ck += tk;
      }
      Ck(ind) = ck;
      ind ++;
    }
  }


}
Ejemplo n.º 5
0
void SFMViewer::update(std::vector<cv::Point3d> pcld,
		std::vector<cv::Vec3b> pcldrgb,
		std::vector<cv::Point3d> pcld_alternate,
		std::vector<cv::Vec3b> pcldrgb_alternate,
		std::vector<cv::Matx34d> cameras) {
	m_pcld = pcld;
	m_pcldrgb = pcldrgb;
	m_cameras = cameras;

	//get the scale of the result cloud using PCA
	{
		cv::Mat_<double> cldm(pcld.size(), 3);
		for (unsigned int i = 0; i < pcld.size(); i++) {
			cldm.row(i)(0) = pcld[i].x;
			cldm.row(i)(1) = pcld[i].y;
			cldm.row(i)(2) = pcld[i].z;
		}
		cv::Mat_<double> mean; //cv::reduce(cldm,mean,0,CV_REDUCE_AVG);
		cv::PCA pca(cldm, mean, CV_PCA_DATA_AS_ROW);
		scale_cameras_down = 1.0 / (3.0 * sqrt(pca.eigenvalues.at<double> (0)));
//		std::cout << "emean " << mean << std::endl;
//		m_global_transform = Eigen::Translation<double,3>(-Eigen::Map<Eigen::Vector3d>(mean[0]));
	}

	//compute transformation to place cameras in world
	m_cameras_transforms.resize(m_cameras.size());
	Eigen::Vector3d c_sum(0,0,0);
	for (int i = 0; i < m_cameras.size(); ++i) {
		Eigen::Matrix<double, 3, 4> P = Eigen::Map<Eigen::Matrix<double, 3, 4,
				Eigen::RowMajor> >(m_cameras[i].val);
		Eigen::Matrix3d R = P.block(0, 0, 3, 3);
		Eigen::Vector3d t = P.block(0, 3, 3, 1);
		Eigen::Vector3d c = -R.transpose() * t;
		c_sum += c;
		m_cameras_transforms[i] =
				Eigen::Translation<double, 3>(c) *
				Eigen::Quaterniond(R) *
				Eigen::UniformScaling<double>(scale_cameras_down)
				;
	}

	m_global_transform = Eigen::Translation<double,3>(-c_sum / (double)(m_cameras.size()));
//	m_global_transform = m_cameras_transforms[0].inverse();

	updateGL();
}
Ejemplo n.º 6
0
void ResultElementIpData::CalculateValues(const StructureBase& rStructure,
                                          Eigen::Matrix<double, 1, Eigen::Dynamic>& rValues) const
{
    const ElementBase* element(rStructure.ElementGetElementPtr(mElementId));

    std::map<Element::eOutput, std::shared_ptr<ElementOutputBase>> elementOutput;
    elementOutput[Element::eOutput::IP_DATA] = std::make_shared<ElementOutputIpData>(mIpDataType);

    const_cast<ElementBase*>(element)->Evaluate(elementOutput);

    const auto& ipDataResult = elementOutput.at(Element::eOutput::IP_DATA)->GetIpData().GetIpDataMap()[mIpDataType];

    // iterate over all ips
    assert(ipDataResult.cols() == element->GetNumIntegrationPoints());
    unsigned int numComponents = ipDataResult.rows();
    for (int iCol = 0; iCol < ipDataResult.cols(); ++iCol)
    {
        rValues.block(0, iCol * numComponents, 1, ipDataResult.rows()) = ipDataResult.col(iCol).transpose();
    }
}
Ejemplo n.º 7
0
geometry_msgs::Pose C_HunoLimbKinematics::ForwardKinematics(const double *thetas_C)
{ 
  geometry_msgs::Pose outLimbPose;
  Eigen::Vector3d rot_axis = Eigen::Vector3d::Zero();
  double rot_angle;

  Eigen::Matrix4d limbTF = Eigen::Matrix4d::Identity();
  Eigen::Matrix4d expXihatTheta = Eigen::Matrix4d::Identity();
  Eigen::Matrix<double, 6, 5> tempJacobian;
  tempJacobian.setZero(); // initialize temporary variable to zeros
  int limbCtr = 0;

  /* Lock jacobian matrix while being formed */
  m_isJacobianLocked = true;

  /* Calculate joint transformation matrices sequentially and populate jacobian */
  for (int jointIdx = 0; jointIdx < m_numJoints; jointIdx++)
  {
    /* use previous expXihatTheta to generate adjoint matrix
       and fill next column of jacobian */
    tempJacobian.col(limbCtr) = AdjointMatrix(expXihatTheta) * m_zetas_M.col(jointIdx);

    /* calculate for next joint */
    expXihatTheta = ExpXihatTheta(jointIdx, (*(thetas_C+jointIdx))*DEG2RAD);
    limbTF *= expXihatTheta;

    /* increment counter */
    limbCtr++; 
  }
  
  if (limbCtr == m_numJoints)
  {
    limbTF *= m_g0Mat_M; // apply configuration matrix 
    m_jacobian_M = tempJacobian.block(0,0, m_numJoints, m_numJoints); // save jacobian
    
    m_isJacobianLocked = false; // unlock jacobian matrix
  }
  else
  { // reset matrices since something didn't add up.
    limbTF.setZero();
    m_jacobian_M.setZero();
  }

  /* save limb transformation matrix into pose message */
  outLimbPose.position.x = limbTF(0,3);
  outLimbPose.position.y = limbTF(1,3);
  outLimbPose.position.z = limbTF(2,3);

  //back out rotation unit vector and angle from rotation matrix
  rot_angle = acos( ( ((limbTF.block<3,3>(0,0)).trace())-1 ) /2 );
  if (sin(rot_angle) != 0)
  {
    rot_axis(0) = (limbTF(2,1)-limbTF(1,2)) / (2*sin(rot_angle));
    rot_axis(1) = (limbTF(0,2)-limbTF(2,0)) / (2*sin(rot_angle));
    rot_axis(2) = (limbTF(1,0)-limbTF(0,1)) / (2*sin(rot_angle));
  }
  // else rot_axis is zeroes

  outLimbPose.orientation.x = rot_axis(0)*sin(rot_angle/2);
  outLimbPose.orientation.y = rot_axis(1)*sin(rot_angle/2);
  outLimbPose.orientation.z = rot_axis(2)*sin(rot_angle/2);
  outLimbPose.orientation.w = cos(rot_angle/2);

  return outLimbPose; 
} // end ForwardKinematics()
//! Function for updating common blocks of partial to current state.
void EmpiricalAccelerationPartial::update( const double currentTime )
{
    if( !( currentTime_ == currentTime ) )
    {

        using namespace tudat::basic_mathematics;
        using namespace tudat::linear_algebra;

        // Get current state and associated data.
        Eigen::Vector6d currentState = empiricalAcceleration_->getCurrentState( );
        Eigen::Vector3d angularMomentumVector = Eigen::Vector3d( currentState.segment( 0, 3 ) ).cross(
                    Eigen::Vector3d( currentState.segment( 3, 3 ) ) );
        Eigen::Vector3d crossVector = angularMomentumVector.cross( Eigen::Vector3d( currentState.segment( 0, 3 ) ) );

        // Compute constituent geometric partials.
        Eigen::Matrix3d normPositionWrtPosition = calculatePartialOfNormalizedVector( Eigen::Matrix3d::Identity( ), currentState.segment( 0, 3 ) );
        Eigen::Matrix3d angularMomentumWrtPosition = -getCrossProductMatrix( currentState.segment( 3, 3 ) );
        Eigen::Matrix3d angularMomentumWrtVelocity = getCrossProductMatrix( currentState.segment( 0, 3 ) );
        Eigen::Matrix3d normAngularMomentumWrtPosition = calculatePartialOfNormalizedVector( angularMomentumWrtPosition, angularMomentumVector );
        Eigen::Matrix3d normAngularMomentumWrtVelocity = calculatePartialOfNormalizedVector( angularMomentumWrtVelocity, angularMomentumVector );
        Eigen::Matrix3d crossVectorWrtPosition = getCrossProductMatrix( angularMomentumVector ) -
                angularMomentumWrtVelocity * angularMomentumWrtPosition;
        Eigen::Matrix3d crossVectorWrtVelocity = -getCrossProductMatrix( currentState.segment( 0, 3 ) ) *
                getCrossProductMatrix( currentState.segment( 0, 3 ) );
        Eigen::Matrix3d normCrossVectorWrtPosition = calculatePartialOfNormalizedVector( crossVectorWrtPosition, crossVector );
        Eigen::Matrix3d normCrossVectorWrtVelocity = calculatePartialOfNormalizedVector( crossVectorWrtVelocity, crossVector );

        // Retrieve current empirical acceleration
        Eigen::Vector3d localAcceleration = empiricalAcceleration_->getCurrentLocalAcceleration( );

        // Compute partial derivative contribution of derivative of rotation matrix from RSW to inertial frame
        currentPositionPartial_ = localAcceleration.x( ) * normPositionWrtPosition + localAcceleration.y( ) * normCrossVectorWrtPosition +
                localAcceleration.z( ) * normAngularMomentumWrtPosition;
        currentVelocityPartial_ = localAcceleration.y( ) * normCrossVectorWrtVelocity + localAcceleration.z( ) * normAngularMomentumWrtVelocity;

        // Compute partial derivative contribution of derivative of true anomaly
        Eigen::Matrix< double, 1, 6 > localTrueAnomalyPartial = calculateNumericalPartialOfTrueAnomalyWrtState(
                    empiricalAcceleration_->getCurrentState( ),
                    empiricalAcceleration_->getCurrentGravitationalParameter( ), cartesianStateElementPerturbations );
        Eigen::Matrix< double, 1, 6 > trueAnomalyPartial = localTrueAnomalyPartial;
        currentPositionPartial_ += empiricalAcceleration_->getCurrentToInertialFrame( ) * (
                    empiricalAcceleration_->getCurrentAccelerationComponent( basic_astrodynamics::sine_empirical ) *
                    std::cos( empiricalAcceleration_->getCurrentTrueAnomaly( ) ) -
                    empiricalAcceleration_->getCurrentAccelerationComponent( basic_astrodynamics::cosine_empirical ) *
                    std::sin( empiricalAcceleration_->getCurrentTrueAnomaly( ) )
                    ) * trueAnomalyPartial.block( 0, 0, 1, 3 );
        currentVelocityPartial_ +=
                ( empiricalAcceleration_->getCurrentToInertialFrame( ) * (
                      empiricalAcceleration_->getCurrentAccelerationComponent( basic_astrodynamics::sine_empirical ) *
                      std::cos( empiricalAcceleration_->getCurrentTrueAnomaly( ) ) -
                      empiricalAcceleration_->getCurrentAccelerationComponent( basic_astrodynamics::cosine_empirical ) *
                      std::sin( empiricalAcceleration_->getCurrentTrueAnomaly( ) ) ) ) * trueAnomalyPartial.block( 0, 3, 1, 3 );
        currentTime_ = currentTime;

        // Check output.
        if( currentPositionPartial_ != currentPositionPartial_ )
        {
            throw std::runtime_error( "Error, empirical acceleration position partials are NaN" );
        }
        if( currentVelocityPartial_ != currentVelocityPartial_ )
        {
            throw std::runtime_error( "Error, empirical acceleration velocity partials are NaN" );
        }
    }
}
	void SetUp() override
	{
		using SurgSim::Math::getSubVector;
		using SurgSim::Math::getSubMatrix;
		using SurgSim::Math::addSubMatrix;

		m_nodeIds[0] = 3;
		m_nodeIds[1] = 1;
		m_nodeIds[2] = 14;
		m_nodeIds[3] = 9;
		std::vector<size_t> m_nodeIdsVectorForm; // Useful for assembly helper function
		m_nodeIdsVectorForm.push_back(m_nodeIds[0]);
		m_nodeIdsVectorForm.push_back(m_nodeIds[1]);
		m_nodeIdsVectorForm.push_back(m_nodeIds[2]);
		m_nodeIdsVectorForm.push_back(m_nodeIds[3]);

		m_restState.setNumDof(3, 15);
		Vector& x0 = m_restState.getPositions();
		// Tet is aligned with the axis (X,Y,Z), centered on (0.1, 1.2, 2.3), embedded in a cube of size 1
		getSubVector(m_expectedX0, 0, 3) = getSubVector(x0, m_nodeIds[0], 3) = Vector3d(0.1, 1.2, 2.3);
		getSubVector(m_expectedX0, 1, 3) = getSubVector(x0, m_nodeIds[1], 3) = Vector3d(1.1, 1.2, 2.3);
		getSubVector(m_expectedX0, 2, 3) = getSubVector(x0, m_nodeIds[2], 3) = Vector3d(0.1, 2.2, 2.3);
		getSubVector(m_expectedX0, 3, 3) = getSubVector(x0, m_nodeIds[3], 3) = Vector3d(0.1, 1.2, 3.3);

		// The tet is part of a cube of size 1x1x1 (it occupies 1/6 of the cube's volume)
		m_expectedVolume = 1.0 / 6.0;

		m_rho = 1000.0;
		m_E = 1e6;
		m_nu = 0.45;

		m_expectedMassMatrix.setZero(3*15, 3*15);
		m_expectedDampingMatrix.setZero(3*15, 3*15);
		m_expectedStiffnessMatrix.setZero(3*15, 3*15);
		m_expectedStiffnessMatrix2.setZero(3*15, 3*15);
		m_vectorOnes.setOnes(3*15);

		Eigen::Matrix<double, 12, 12> M = Eigen::Matrix<double, 12, 12>::Zero();
		{
			M.diagonal().setConstant(2.0);
			M.block(0, 3, 9, 9).diagonal().setConstant(1.0);
			M.block(0, 6, 6, 6).diagonal().setConstant(1.0);
			M.block(0, 9, 3, 3).diagonal().setConstant(1.0);
			M.block(3, 0, 9, 9).diagonal().setConstant(1.0);
			M.block(6, 0, 6, 6).diagonal().setConstant(1.0);
			M.block(9, 0, 3, 3).diagonal().setConstant(1.0);
		}
		M *= m_rho * m_expectedVolume / 20.0;
		addSubMatrix(M, m_nodeIdsVectorForm, 3 , &m_expectedMassMatrix);

		Eigen::Matrix<double, 12, 12> K = Eigen::Matrix<double, 12, 12>::Zero();
		{
			// Calculation done by hand from
			// http://www.colorado.edu/engineering/CAS/courses.d/AFEM.d/AFEM.Ch09.d/AFEM.Ch09.pdf
			// ai = {}
			// bi = {-1 1 0 0}
			// ci = {-1 0 1 0}
			// di = {-1 0 0 1}
			Eigen::Matrix<double, 6, 12> B = Eigen::Matrix<double, 6, 12>::Zero();
			Eigen::Matrix<double, 6, 6> E = Eigen::Matrix<double, 6, 6>::Zero();

			B(0, 0) = -1; B(0, 3) = 1;
			B(1, 1) = -1; B(1, 7) = 1;
			B(2, 2) = -1; B(2, 11) = 1;
			B(3, 0) = -1; B(3, 1) = -1;  B(3, 4) = 1; B(3, 6) = 1;
			B(4, 1) = -1; B(4, 2) = -1;  B(4, 8) = 1; B(4, 10) = 1;
			B(5, 0) = -1; B(5, 2) = -1;  B(5, 5) = 1; B(5, 9) = 1;
			B *= 1.0 / (6.0 * m_expectedVolume);

			E.block(0, 0, 3, 3).setConstant(m_nu);
			E.block(0, 0, 3, 3).diagonal().setConstant(1.0 - m_nu);
			E.block(3, 3, 3, 3).diagonal().setConstant(0.5 - m_nu);
			E *= m_E / (( 1.0 + m_nu) * (1.0 - 2.0 * m_nu));

			K = m_expectedVolume * B.transpose() * E * B;
		}
		addSubMatrix(K, m_nodeIdsVectorForm, 3 , &m_expectedStiffnessMatrix);

		// Expecte stiffness matrix given for our case in:
		// http://www.colorado.edu/engineering/CAS/courses.d/AFEM.d/AFEM.Ch09.d/AFEM.Ch09.pdf
		double E = m_E / (12.0*(1.0 - 2.0*m_nu)*(1.0 + m_nu));
		double n0 = 1.0 - 2.0 * m_nu;
		double n1 = 1.0 - m_nu;
		K.setZero();

		// Fill up the upper triangle part first (without diagonal elements)
		K(0, 1) = K(0, 2) = K(1, 2) = 1.0;

		K(0, 3) = -2.0 * n1;   K(0, 4) = -n0; K(0, 5) = -n0;
		K(1, 3) = -2.0 * m_nu; K(1, 4) = -n0;
		K(2, 3) = -2.0 * m_nu; K(2, 5) = -n0;

		K(0, 6) = - n0; K(0, 7) = -2.0 * m_nu;
		K(1, 6) = - n0; K(1, 7) = -2.0 * n1; K(1, 8) = - n0;
		K(2, 7) = - 2.0 * m_nu; K(2, 8) = -n0;

		K(0, 9) = - n0; K(0, 11) = -2.0 * m_nu;
		K(1, 10) = - n0; K(1, 11) = -2.0 * m_nu;
		K(2, 9) = - n0; K(2, 10) = - n0; K(2, 11) = -2.0 * n1;

		K(3, 7) = K(3, 11) =  2.0 * m_nu;
		K(4, 6) = n0;
		K(5, 9) = n0;
		K(7, 11) = 2.0 * m_nu;
		K(8, 10) = n0;

		K += K.transpose().eval(); // symmetric part (do not forget the .eval() !)

		K.block(0,0,3,3).diagonal().setConstant(4.0 - 6.0 * m_nu); // diagonal elements
		K.block(3,3,9,9).diagonal().setConstant(n0); // diagonal elements
		K(3, 3) = K(7, 7) = K(11, 11) = 2.0 * n1; // diagonal elements

		K *= E;

		addSubMatrix(K, m_nodeIdsVectorForm, 3 , &m_expectedStiffnessMatrix2);
	}
		void compute_weights() {
			assert(m_samples.size() == m_values.size());

			using namespace std;
			using namespace cgra;

			// L = [ K    S ]   X = [ W ]   Y = [ V ]
			//     [ S^t  0 ],      [ A ],      [ 0 ]
			Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> L(m_samples.size() + 3, m_samples.size() + 3);
			Eigen::Matrix<T, Eigen::Dynamic, 1> x(m_samples.size() + 3);
			Eigen::Matrix<T, Eigen::Dynamic, 1> Y(m_samples.size() + 3);

			// build L and Y
			// zero out L and Y
			L.setConstant(0);
			Y.setConstant(0);
			for (int i = 0; i < m_samples.size(); i++) {

				// K = [ k(s0,s0)  k(s0,s1)  ..  k(s0,sn) ]
				//     [ k(s1,s0)  k(s1,s1)  ..  k(s1,sn) ]
				//     [    ..        ..     ..     ..    ]
				//     [ k(sn,s0)  k(sn,s1)  ..  k(sn,sn) ]
				for (int j = i + 1; j < m_samples.size(); j++) {
					T v = thin_plate_kernal(vector2<T>(m_samples[i]), vector2<T>(m_samples[j]));
					L(i, j) = v;
					L(j, i) = v;
				}

				// S = [  1  x0  y0 ]
				//     [  1  x1  y1 ]
				//     [ ..  ..  .. ]
				//     [  1  xn  yn ]
				L(i, m_samples.size() + 0) = 1;
				L(i, m_samples.size() + 1) = m_samples[i].x;
				L(i, m_samples.size() + 2) = m_samples[i].y;

				// S^t
				L(m_samples.size() + 0, i) = 1;
				L(m_samples.size() + 1, i) = m_samples[i].x;
				L(m_samples.size() + 2, i) = m_samples[i].y;

				// V = [ v0 ]
				//     [ v1 ]
				//     [ .. ]
				//     [ vn ]
				Y(i) = m_values[i];
			}


			// solve for X
			// Useing LU decomposition because L is symmetric
			Eigen::PartialPivLU<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>> solver(L);
			Eigen::Matrix<T, Eigen::Dynamic, 1> X = solver.solve(Y);

			// W = [ w0 ]
			//     [ w1 ]
			//     [ .. ]
			//     [ wn ]
			m_weights.clear();
			m_weights.reserve(m_samples.size() + 3);
			for (int i = 0; i < m_samples.size(); i++) {
				m_weights.push_back(X(i));
			}

			// A = [ a0 ]
			//     [ a1 ]
			//     [ a2 ]
			m_a0 = X(m_samples.size() + 0);
			m_a1 = X(m_samples.size() + 1);
			m_a2 = X(m_samples.size() + 2);

			// caculate the energy I = W^t K W
			Eigen::Matrix<T, Eigen::Dynamic, 1> W(X.block(0, 0, m_samples.size(), 1));
			Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> K(L.block(0, 0, m_samples.size(), m_samples.size()));
			m_energy = W.transpose() * K * W;

			std::cout << "W" << W << std::endl;
			std::cout << "K" << K << std::endl;
			std::cout << "m_energy" << m_energy << std::endl << std::endl;
		}
Ejemplo n.º 11
0
	Result iterate() {
		setupVariables();



		// for now we use a iteration counter to protect us from infinite loops
		// TODO< implement loop detection scheme, basic idea
		//       * we manage a fixed sized array as a sliding window or the hashes of the operations
		//       * if we detect a loop we apply bland's rule to resolve it (is the rule detection realy neccesary?)
		//
		//
		//       * every operation (pivot column, pivot row, number of pivot element itself) gets an hash
		//       * at each iteration we subtract the previous hash and add the current hash
		//       * if the hash doesn't change in n iteration(where n == 2 for the simple loop) we are looping
		// >

		// TODO< implement https://en.wikipedia.org/wiki/Bland's_rule >

		unsigned iterationCounter = 0;
		const unsigned MaximalIterationCounter = 128;

		for(;;) {
			iterationCounter++;
			if( iterationCounter > MaximalIterationCounter ) {
				return Result(Result::EnumSolverState::TOOMANYITERATIONS);
			}

			bool foundMaximumColumn;

			const int pivotColumnIndex = searchMinimumColumn(foundMaximumColumn);
			// all values in the target value row are < 0.0, done
			if( !foundMaximumColumn ) {
				return Result(Result::EnumSolverState::FOUNDSOLUTION);
			}

			//std::cout << "min column " << pivotColumnIndex << std::endl;

			if( areAllEntriesOfPivotColumnNegativeOrZero(pivotColumnIndex) ) {
				// solution is unbounded

				return Result(Result::EnumSolverState::UNBOUNDEDSOLUTION);
			}

			// divide numbers of pivot column with right side and store in temporary vector
			Eigen::Matrix<Type, Eigen::Dynamic, 1> minRatioVector = divideRightSideWithPivotColumnWhereAboveZero(pivotColumnIndex);

			//std::cout << "temporary vector" << std::endl;
			//std::cout << minRatioVector << std::endl;

			const int minIndexOfTargetFunctionCoefficient = getMinIndexOfMinRatioVector(minRatioVector);
			const bool positiveMinRatioExists = doesPositiveMinRatioExist(minRatioVector);
			if( !positiveMinRatioExists ) {
				// solution is unbounded

				return Result(Result::EnumSolverState::UNBOUNDEDSOLUTION);
			}

			const int pivotRowIndex = minIndexOfTargetFunctionCoefficient;

			//std::cout << "pivotRowIndex " << pivotRowIndex << std::endl;

			Type pivotElement = matrix(pivotRowIndex, pivotColumnIndex);

			// divide the pivot row with the pivot element
			matrix.block(pivotRowIndex,0, 1, matrix.cols()) /= pivotElement;

			// TODO< assert that pivot elemnt is roughtly 1.0 >



			// do pivot operation

			for(int pivotRowIteration = 0; pivotRowIteration < matrix.rows(); pivotRowIteration++ ) {
				if( pivotRowIteration == pivotRowIndex ) {
					continue;
				}

				Type iterationElementAtPivotColumn = matrix(pivotRowIteration, pivotColumnIndex);
				matrix.block(pivotRowIteration, 0, 1, matrix.cols()) -= (matrix.block(pivotRowIndex, 0, 1, matrix.cols()) * iterationElementAtPivotColumn);
			}

			// set the variable identifier that we know which row of the matrix is for which variable
			variables[pivotRowIndex] = Variable(Variable::EnumType::NAMEME, pivotColumnIndex);

			//std::cout << matrix << std::endl;
			
		}
	}
Ejemplo n.º 12
0
Eigen::Matrix<double, 4, Eigen::Dynamic> bb_cluster_confidence(Eigen::Matrix<
		double, 4, 20> const & iBB, Eigen::Matrix<double, 20, 1> const & iConf,
		int nD) {

	double SPACE_THR = 0.5;
	Eigen::VectorXd T;
	Eigen::VectorXd Tbak;
	unsigned int iBBcols = nD;
	Eigen::MatrixXd bdist;
	//Calculates the index of the bb that fits the best
	switch (iBBcols) {
	//0 cols, set indices to 1
	case 0:
		T = Eigen::VectorXd::Zero(1);
		break;
		//1 col, set index to 0;
	case 1:
		T.resize(1);
		T(0) = 0;
		break;
		//2 cols, set indices to zero; if above treshhold to 1
	case 2:
		T = Eigen::VectorXd::Zero(2);
		bdist = bb_distance(iBB);
		if (bdist(0, 0) > SPACE_THR) {
			T(1) = 1;
		}
		break;
		//workaround for clustering.
	default:
		Eigen::Vector4d meanBB = iBB.rowwise().mean();
		int maxIndex = 0;
		double maxDist = 10;
		for (int penis = 0; penis < nD; penis++) {
			Eigen::MatrixXd bd = bb_distance(iBB.col(penis), meanBB);
			//save the shortest distance
			if (bd(0, 0) < maxDist) {
				maxIndex = penis;
				maxDist = bd(0, 0);
			}
		}
		//set the indices to the index of the bounding box with the
		//shortest distance
		T = Eigen::VectorXd::Constant(iBBcols, maxIndex);
		break;
	}
	Eigen::VectorXd idx_cluster;
	idx_cluster.resize(0);
	bool breaker;
	//filter indices that occur twice
	for (int p = 0; p < T.size(); p++) {
		breaker = false;
		for (int j = 0; j < idx_cluster.size(); j++)
			if (idx_cluster(j) == T(p)) {
				breaker = true;
				break;
			}
		if (breaker)
			continue;
		Eigen::VectorXd unibak(idx_cluster.size());
		unibak = idx_cluster;
		idx_cluster.resize(unibak.size() + 1);
		idx_cluster << unibak, T(p);
	}
	int num_clusters = idx_cluster.size();

	Eigen::MatrixXd oBB = Eigen::MatrixXd::Constant(4, num_clusters,
			std::numeric_limits<double>::quiet_NaN());
	Eigen::MatrixXd oConf = Eigen::MatrixXd::Constant(4, num_clusters,
			std::numeric_limits<double>::quiet_NaN());
	Eigen::MatrixXd oSize = Eigen::MatrixXd::Constant(4, num_clusters,
			std::numeric_limits<double>::quiet_NaN());

	for (int k = 0; k < num_clusters; k++) {
		std::vector<int> idx;
		for (int u = 0; u < T.size(); u++)
			if (T(u) == idx_cluster(k))
				idx.push_back(u);

		Eigen::MatrixXd iBBidx(4, idx.size());

		for (unsigned int f = 0; f < idx.size(); f++) {
			iBBidx.col(f) = iBB.block(0, idx[f], 4, 1);
		}
		oBB.col(k) = iBBidx.rowwise().mean();
		Eigen::VectorXd iConfidx(idx.size());
		for (unsigned int f = 0; f < idx.size(); f++)
			iConfidx(f) = iConf(idx[f]);
		//save information how valid a certain bounding box is
		oConf(0, k) = iConfidx.mean();
		oSize(0, k) = idx.size();
	}
	Eigen::MatrixXd ret(4, 3 * num_clusters);
	ret << oBB, oConf, oSize;
	return ret;
}
Ejemplo n.º 13
0
int main()
{
	float width = 640.0f, height=480.0f;
	char buf[255];
	int n, pose; 
	AsfMatrix data;

	Eigen::Matrix<float,40*6,-1> Shapes; //240x116

	float mean_size = 0;
	for(n=0;n<40;n++)
	{
		for(pose=0;pose<6;pose++)
		{
			sprintf(buf,"../../../CIL/data/imm_face_db/%.2d-%dm.asf",n+1,pose+1);
			if(readAsf2Eigen(buf, data) != 0)
			{
				sprintf(buf,"../../../CIL/data/imm_face_db/%.2d-%df.asf",n+1,pose+1);
				if (readAsf2Eigen(buf, data) != 0)
					continue;		
			}

			//Initialize The Shapes Container
			if(Shapes.cols() == 0)
				Shapes.resize(40*6,data.cols()*2);
			
			

			//Copy the found data
			Shapes.block(n*6+pose,0,1,data.cols()) = data.row(2) * width;
			Shapes.block(n*6+pose,data.cols(),1,data.cols()) = data.row(3) * height;

			

			//Compute MeanShape
			auto mean_x		= Shapes.block(n*6+pose,0,1,data.cols()).mean();
			auto mean_y		= Shapes.block(n*6+pose,data.cols(),1,data.cols()).mean();
			auto mshape_x	= (Shapes.block(n*6+pose,0,1,data.cols()).array()-mean_x).pow(2) ;
			auto mshape_y	= (Shapes.block(n*6+pose,data.cols(),1,data.cols()).array()-mean_y).pow(2) ;
			mean_size		+= sqrt((mshape_x+mshape_y).sum());

		
			//std::cout << Shapes.block(n*pose+pose,0,1,data.cols()) << std::endl;
		//		std::cout << Shapes.block(0,0,1,5) << std::endl ;
	//std::cout << Shapes.block(1,0,1,5) << std::endl ;
	//std::cout << Shapes.block(2,0,1,5) << std::endl ;
	//std::cout << Shapes.block(3,0,1,5) << std::endl << std::endl;
		}

	}
	mean_size /= 40*6;
	int number_of_landmarks = data.cols();
	int number_of_shapes	= Shapes.rows();

	//Complex notation and Substracting Mean.
	Eigen::MatrixXcf X(number_of_shapes, number_of_landmarks);
	X.real() = Shapes.leftCols(number_of_landmarks);
	X.imag() = Shapes.rightCols(number_of_landmarks);
	X.array().colwise() -= X.rowwise().mean().array();

	//Eigen::MatrixXcd XX(10,10);

	//double test[10] = {0};
	//Eigen::Map<Eigen::MatrixXd> mat(test, 10, 1);
	Eigen::MatrixXcf C;
	Eigen::MatrixXcf Mean;
	cil::alg::gpa(X,C,Mean);
	std::cout << X.rows() << " , " << X.cols() << std::endl<< std::endl;
	std::cout << C.rows() << " , " << C.cols() << std::endl<< std::endl;
	std::cout << Mean.rows() << " , " << Mean.cols() << std::endl<< std::endl;
	std::cout << C.row(1).transpose() << std::endl<< std::endl;
	return 0;

	X.array().colwise() -= X.rowwise().mean().array();

	//Eigen::MatrixXcf X = Shapes.block(0,0,Shapes.rows(),data.cols()) * std::complex<float>(0,1) +
	//	Shapes.block(0,data.cols(),Shapes.rows(),data.cols())*std::complex<float>(1,0);
	//Eigen::VectorXcf Mean = X.rowwise().mean();

	//std::complex<float> *m_ptr = Mean.data();
	//for(n=0;n<Mean.rows();++n)
	//	X.row(n) = X.row(n).array() - *m_ptr++;

	//Solve Eigen Problem
	Eigen::MatrixXcf A = X.transpose().conjugate() * X;
	Eigen::ComplexEigenSolver<Eigen::MatrixXcf> solver;
	solver.compute(A);
	
//	std::cout << "The Eigenvales of A are:" << std::endl << solver.eigenvalues() <<std::endl<<std::endl;
//	std::complex<float> lambda = solver.eigenvalues()[57];
//	std::cout << "Consider the first eigenvalue, lambda = " << lambda << std::endl;
//	std::cout << "EigenVec for largest EigenVals of A are:" << std::endl << solver.eigenvectors().col(57) <<std::endl<<std::endl;

	auto eigvec_mean = solver.eigenvectors().col(solver.eigenvectors().cols()-1);

	// Full Procrusters fits
	Eigen::MatrixXcf f = (X * eigvec_mean).array() / (X * X.transpose().conjugate()).diagonal().array();

	//Transform
	
	auto f_conj = f.conjugate().array();
	for(n=0;n<X.cols();++n)
		X.col(n) = X.col(n).array() * f_conj;
	auto mf = f.mean();
	std::cout << mf << std::endl<< std::endl;
	mf = mf / sqrt(mf.real()*mf.real()+mf.imag()*mf.imag());
	std::cout << mf << std::endl<< std::endl;
	auto m = eigvec_mean * mf;
	X = X*mf;



	std::cout << X.row(0).transpose() << std::endl<< std::endl;

	return 0;
}
//! Function to numerical compute the partial derivative of an acceleration w.r.t. a vector parameter
Eigen::Matrix< double, 3, Eigen::Dynamic > calculateAccelerationWrtParameterPartials(
        boost::shared_ptr< estimatable_parameters::EstimatableParameter< Eigen::VectorXd > > parameter,
        boost::shared_ptr< basic_astrodynamics::AccelerationModel< Eigen::Vector3d > > accelerationModel,
        Eigen::VectorXd parameterPerturbation,
        boost::function< void( ) > updateDependentVariables,
        const double currentTime,
        boost::function< void( const double ) > timeDependentUpdateDependentVariables )
{
    // Store uperturbed value.

    Eigen::VectorXd unperturbedParameterValue = parameter->getParameterValue( );


    if( unperturbedParameterValue.size( ) != parameterPerturbation.size( ) )
    {
        throw std::runtime_error( "Error when calculating numerical parameter partial of acceleration, parameter and perturbations are not the same size" );
    }

    Eigen::Matrix< double, 3, Eigen::Dynamic > partialMatrix = Eigen::MatrixXd::Zero( 3, unperturbedParameterValue.size( ) );

    Eigen::VectorXd perturbedParameterValue;
    for( int i = 0; i < unperturbedParameterValue.size( ); i++ )
    {

        perturbedParameterValue = unperturbedParameterValue;
        perturbedParameterValue( i ) += parameterPerturbation( i );

        // Calculate up-perturbation
        parameter->setParameterValue( perturbedParameterValue );
        updateDependentVariables( );
        timeDependentUpdateDependentVariables( currentTime );
        Eigen::Vector3d upPerturbedAcceleration = basic_astrodynamics::updateAndGetAcceleration< Eigen::Vector3d >(
                    accelerationModel, currentTime );
        accelerationModel->resetTime( TUDAT_NAN );

        // Calculate down-perturbation.
        perturbedParameterValue = unperturbedParameterValue;
        perturbedParameterValue( i ) -= parameterPerturbation( i );
        parameter->setParameterValue( perturbedParameterValue );
        updateDependentVariables( );
        timeDependentUpdateDependentVariables( currentTime );
        Eigen::Vector3d downPerturbedAcceleration = basic_astrodynamics::updateAndGetAcceleration< Eigen::Vector3d >(
                    accelerationModel, currentTime );
        accelerationModel->resetTime( TUDAT_NAN );

        // Compute partial entry.
        partialMatrix.block( 0, i, 3, 1 ) =
                ( upPerturbedAcceleration - downPerturbedAcceleration ) / ( 2.0 * parameterPerturbation( i ) );

    }

    // Reset to original value.
    parameter->setParameterValue(
                unperturbedParameterValue ) ;
    updateDependentVariables( );
    timeDependentUpdateDependentVariables( currentTime );
    accelerationModel->resetTime( TUDAT_NAN );

    basic_astrodynamics::updateAndGetAcceleration< Eigen::Vector3d >(
                        accelerationModel, currentTime );

    // Calculate partial using central difference.
    return partialMatrix;
}