Ejemplo n.º 1
0
    static bool testApply()
    {
        bool b, ret;
        // apply delta:
        Eigen::Matrix<double, 6, 1> delta = Eigen::Matrix<double, 6, 1>::Zero();
        Eigen::Matrix<double, 4, 4> expectedT = Eigen::Matrix<double, 4, 4>::Identity();
        Eigen::Matrix<double, 4, 4> diff;

        SE3<double> pose;
        pose.set( delta );
        delta[ 0 ] = Math::deg2Rad( 1.5 );
        delta[ 1 ] = Math::deg2Rad( 1.1 );
        delta[ 2 ] = Math::deg2Rad( 1.6 );
        delta[ 3 ] = 1;
        delta[ 4 ] = 1;
        delta[ 5 ] = 1;
        pose.apply( delta );

        expectedT( 0, 3 ) = delta[ 3 ];
        expectedT( 1, 3 ) = delta[ 4 ];
        expectedT( 2, 3 ) = delta[ 5 ];

        Eigen::Matrix<double, 3, 1> axis = delta.segment<3>( 0 );
        double angle = axis.norm();	axis /= angle;

        expectedT.block<3, 3>( 0, 0 ) = Eigen::AngleAxis<double>( angle, axis ).toRotationMatrix();
        diff = expectedT - pose.transformation();

        ret = b = ( diff.array().abs().sum() / 12 < 0.001 );

        if( !b ){
            std::cout << expectedT << std::endl;
            std::cout << pose.transformation() << std::endl;
            std::cout << "avg SAD: " << diff.array().abs().sum() / 12 << std::endl;
        }

        pose.apply( -delta );
        expectedT.setIdentity();

        b &= ( ( expectedT - pose.transformation() ).array().abs().sum() / 12 < 0.0001 );
        CVTTEST_PRINT( "apply", b );
        ret &= b;

        return ret;
    }
Ejemplo n.º 2
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.º 3
0
void SignedDistanceField::calculateSignedDistanceField(const GridMap& gridMap, const std::string& layer,
                                                       const double heightClearance)
{
  data_.clear();
  resolution_ = gridMap.getResolution();
  position_ = gridMap.getPosition();
  size_ = gridMap.getSize();
  Matrix map = gridMap.get(layer); // Copy!

  float minHeight = map.minCoeffOfFinites();
  if (!std::isfinite(minHeight)) minHeight = lowestHeight_;
  float maxHeight = map.maxCoeffOfFinites();
  if (!std::isfinite(maxHeight)) maxHeight = lowestHeight_;

  const float valueForEmptyCells = lowestHeight_; // maxHeight, minHeight (TODO Make this an option).
  for (size_t i = 0; i < map.size(); ++i) {
    if (std::isnan(map(i))) map(i) = valueForEmptyCells;
  }

  // Height range of the signed distance field is higher than the max height.
  maxHeight += heightClearance;

  Matrix sdfElevationAbove = Matrix::Ones(map.rows(), map.cols()) * maxDistance_;
  Matrix sdfLayer = Matrix::Zero(map.rows(), map.cols());
  std::vector<Matrix> sdf;
  zIndexStartHeight_ = minHeight;

  // Calculate signed distance field from bottom.
  for (float h = minHeight; h < maxHeight; h += resolution_) {
    Eigen::Matrix<bool, Eigen::Dynamic, Eigen::Dynamic> obstacleFreeField = map.array() < h;
    Eigen::Matrix<bool, Eigen::Dynamic, Eigen::Dynamic> obstacleField = obstacleFreeField.array() < 1;
    Matrix sdfObstacle = getPlanarSignedDistanceField(obstacleField);
    Matrix sdfObstacleFree = getPlanarSignedDistanceField(obstacleFreeField);
    Matrix sdf2d;
    // If 2d sdfObstacleFree calculation failed, neglect this SDF
    // to avoid extreme small distances (-INF).
    if ((sdfObstacleFree.array() >= INF).any()) sdf2d = sdfObstacle;
    else sdf2d = sdfObstacle - sdfObstacleFree;
    sdf2d *= resolution_;
    for (size_t i = 0; i < sdfElevationAbove.size(); ++i) {
      if(sdfElevationAbove(i) == maxDistance_ && map(i) <= h) sdfElevationAbove(i) = h - map(i);
      else if(sdfElevationAbove(i) != maxDistance_ && map(i) <= h) sdfElevationAbove(i) = sdfLayer(i) + resolution_;
      if (sdf2d(i) == 0) sdfLayer(i) = h - map(i);
      else if (sdf2d(i) < 0) sdfLayer(i) = -std::min(fabs(sdf2d(i)), fabs(map(i) - h));
      else sdfLayer(i) = std::min(sdf2d(i), sdfElevationAbove(i));
    }
    data_.push_back(sdfLayer);
  }
}
Ejemplo n.º 4
0
IGL_INLINE Eigen::Matrix<Scalar,3,1> igl::unproject(
  const    Eigen::Matrix<Scalar,3,1>&  win,
  const    Eigen::Matrix<Scalar,4,4>& model,
  const    Eigen::Matrix<Scalar,4,4>& proj,
  const    Eigen::Matrix<Scalar,4,1>&  viewport)
{
  Eigen::Matrix<Scalar,4,4> Inverse = (proj * model).inverse();

  Eigen::Matrix<Scalar,4,1> tmp;
  tmp << win, 1;
  tmp(0) = (tmp(0) - viewport(0)) / viewport(2);
  tmp(1) = (tmp(1) - viewport(1)) / viewport(3);
  tmp = tmp.array() * 2.0f - 1.0f;

  Eigen::Matrix<Scalar,4,1> obj = Inverse * tmp;
  obj /= obj(3);

  return obj.head(3);
}
Ejemplo n.º 5
0
Eigen::Matrix<Scalar,3,1> igl::project(
  const    Eigen::Matrix<Scalar,3,1>&  obj,
  const    Eigen::Matrix<Scalar,4,4>& model,
  const    Eigen::Matrix<Scalar,4,4>& proj,
  const    Eigen::Matrix<Scalar,4,1>&  viewport)
{
  Eigen::Matrix<Scalar,4,1> tmp;
  tmp << obj,1;

  tmp = model * tmp;

  tmp = proj * tmp;

  tmp = tmp.array() / tmp(3);
  tmp = tmp.array() * 0.5f + 0.5f;
  tmp(0) = tmp(0) * viewport(2) + viewport(0);
  tmp(1) = tmp(1) * viewport(3) + viewport(1);

  return tmp.head(3);
}
	PointCoordinateMatrices	ConverterPlaneFromTo3d::projectTo3d(Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> image)
	{
		PointCoordinateMatrices reshapedCoordinates;

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

		//As defined for the example data sets to get the distance in meters Z = depth / 5000 TODO change for kinect data (maybe is the same...)
		Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> z = image.array() / 1;// 5000;
		Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> x = z.cwiseProduct(xAdjustment_);
		Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> y = z.cwiseProduct(yAdjustment_);

		//std::cout << "x: " << std::endl << x << std::endl << std::endl;
		//std::cout << "y: " << std::endl << y << std::endl << std::endl;
		//std::cout << "z: " << std::endl << z << std::endl << std::endl;

		reshapedCoordinates.x = Eigen::Map<Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>>(x.data(), 1, image.size());
		reshapedCoordinates.y = Eigen::Map<Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>>(y.data(), 1, image.size());
		reshapedCoordinates.z = Eigen::Map<Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>>(z.data(), 1, image.size());

		return reshapedCoordinates;
	}
Ejemplo n.º 7
0
    static bool testHessian()
    {
        Eigen::Matrix<double, 6, 1> delta = Eigen::Matrix<double, 6, 1>::Zero();
        Eigen::Matrix<double, 24, 6> hN, hA;

        SE3<double> pose;
        pose.set( Math::deg2Rad( 10.0 ), Math::deg2Rad( 40.0 ), Math::deg2Rad( -120.0 ), -100.0, 200.0, 300.0 );

        Eigen::Matrix<double, 3, 3> K( Eigen::Matrix<double, 3, 3>::Zero() );
        K( 0, 0 ) = 650.0; K( 0, 2 ) = 320.0;
        K( 1, 1 ) = 650.0; K( 1, 2 ) = 240.0;
        K( 2, 2 ) = 1.0;

        Eigen::Matrix<double, 3, 1> point;
        Eigen::Matrix<double, 3, 1> p, ff, fb, bf, bb, xxf, xxb, hess;
        point[ 0 ] = 16;
        point[ 1 ] = 80;
        point[ 2 ] = 13;

        pose.transform( p, point );

        double h = 0.0001;
        for( size_t i = 0; i < 6; i++ ){
            for( size_t j = 0; j < 6; j++ ){
                delta.setZero();
                if( i == j ){
                    // +
                    delta[ j ] = h;
                    pose.apply( delta );
                    pose.transform( xxf, point );
                    pose.apply( -delta );

                    delta[ j ] = -h;
                    pose.apply( delta );
                    pose.transform( xxb, point );
                    pose.apply( -delta );

                    hess = ( xxb - 2 * p + xxf ) / ( h*h );
                } else {
                    delta[ i ] = h;
                    delta[ j ] = h;
                    pose.apply( delta );
                    pose.transform( ff, point );
                    pose.apply( -delta );

                    delta[ i ] = h;
                    delta[ j ] = -h;
                    pose.apply( delta );
                    pose.transform( fb, point );
                    pose.apply( -delta );

                    delta[ i ] = -h;
                    delta[ j ] =  h;
                    pose.apply( delta );
                    pose.transform( bf, point );
                    pose.apply( -delta );

                    delta[ i ] = -h;
                    delta[ j ] = -h;
                    pose.apply( delta );
                    pose.transform( bb, point );
                    pose.apply( -delta );

                    hess = ( ff - bf - fb + bb ) / ( 4 * h * h );
                }

                hN( 4 * i , j ) = hess[ 0 ];
                hN( 4 * i + 1 , j ) = hess[ 1 ];
                hN( 4 * i + 2 , j ) = hess[ 2 ];
                hN( 4 * i + 3 , j ) = 0.0;
            }
        }

        pose.hessian( hA, p );

        bool b, ret = true;
        Eigen::Matrix<double, 24, 6> jDiff;
        jDiff = hN - hA;
		b = ( jDiff.array().abs().sum() / ( double )( jDiff.rows() * jDiff.cols() ) ) < 0.00001;

        CVTTEST_PRINT( "Pose Hessian", b );
        if( !b ){
            std::cout << "Analytic:\n" << hA << std::endl;
            std::cout << "Numeric:\n" << hN << std::endl;
            std::cout << "Difference:\n" << jDiff << std::endl;
        }
        ret &= b;

        return ret;
    }
Ejemplo n.º 8
0
    static bool testScreenHessian()
    {
        Eigen::Matrix<double, 6, 1> delta = Eigen::Matrix<double, 6, 1>::Zero();
        Eigen::Matrix<double, 6, 6> shNumericX, shNumericY, shX, shY;


        SE3<double> pose;
        pose.set( Math::deg2Rad( 10.0 ), Math::deg2Rad( 40.0 ), Math::deg2Rad( -120.0 ), -100.0, 200.0, 300.0 );

        Eigen::Matrix<double, 3, 3> K( Eigen::Matrix<double, 3, 3>::Zero() );
        K( 0, 0 ) = 650.0; K( 0, 2 ) = 320.0;
        K( 1, 1 ) = 650.0; K( 1, 2 ) = 240.0;
        K( 2, 2 ) = 1.0;

        Eigen::Matrix<double, 3, 1> point, ptrans;
        Eigen::Matrix<double, 2, 1> sp, ff, fb, bf, bb, xxf, xxb, hess;
        point[ 0 ] = 100; point[ 1 ] = 200; point[ 2 ] = 300;

        // project the point with current parameters
        pose.transform( ptrans, point );
        projectWithCam( sp, ptrans, K );

        double h = 0.001;
        for( size_t i = 0; i < 6; i++ ){
            for( size_t j = 0; j < 6; j++ ){

                if( i == j ){
                    // +
                    delta[ j ] = h;
                    pose.apply( delta );
                    pose.transform( ptrans, point );
                    projectWithCam( xxf, ptrans, K );
                    delta[ j ] = -2 * h;
                    pose.apply( delta );
                    pose.transform( ptrans, point );
                    projectWithCam( xxb, ptrans, K );

                    hess = ( xxb - 2 * sp + xxf ) / ( h*h );

                    // back to start
                    delta[ j ] = h;
                    pose.apply( delta );
                    delta[ j ] = 0;
                } else {
                    delta[ i ] = h;
                    delta[ j ] = h;
                    pose.apply( delta );
                    pose.transform( ptrans, point );
                    projectWithCam( ff, ptrans, K );
                    pose.apply( -delta );

                    delta[ i ] = h;
                    delta[ j ] = -h;
                    pose.apply( delta );
                    pose.transform( ptrans, point );
                    projectWithCam( fb, ptrans, K );
                    pose.apply( -delta );

                    delta[ i ] = -h;
                    delta[ j ] =  h;
                    pose.apply( delta );
                    pose.transform( ptrans, point );
                    projectWithCam( bf, ptrans, K );
                    pose.apply( -delta );

                    delta[ i ] = -h;
                    delta[ j ] = -h;
                    pose.apply( delta );
                    pose.transform( ptrans, point );
                    projectWithCam( bb, ptrans, K );
                    pose.apply( -delta );

                    hess = ( ff - bf - fb + bb ) / ( 4 * h * h );
                    delta.setZero();
                }

                shNumericX( i, j ) = hess[ 0 ];
                shNumericY( i, j ) = hess[ 1 ];

            }
        }

        pose.transform( ptrans, point );
        pose.screenHessian( shX, shY, ptrans, K );

        bool b, ret = true;
        Eigen::Matrix<double, 6, 6> jDiff;
		jDiff = shNumericX - shX;
		b = ( jDiff.array().abs().sum() / ( double )( jDiff.rows() * jDiff.cols() ) ) < 0.0001;

        CVTTEST_PRINT( "Pose ScreenHessian X", b );
        if( !b ){
            std::cout << "Analytic:\n" << shX << std::endl;
            std::cout << "Numeric:\n" << shNumericX << std::endl;
            std::cout << "Difference:\n" << jDiff << std::endl;
        }
        ret &= b;

        jDiff = shNumericY - shY;
		b = ( jDiff.array().abs().sum() / ( double )( jDiff.rows() * jDiff.cols() ) ) < 0.0001;

        CVTTEST_PRINT( "Pose ScreenHessian Y", b );
        if( !b ){
            std::cout << "Analytic:\n" << shY << std::endl;
            std::cout << "Numeric:\n" << shNumericY << std::endl;
            std::cout << "Difference:\n" << jDiff << std::endl;
        }
        ret &= b;

        return ret;
    }
Ejemplo n.º 9
0
    static bool testScreenJacobian()
    {
        Eigen::Matrix<double, 6, 1> delta = Eigen::Matrix<double, 6, 1>::Zero();
        Eigen::Matrix<double, 2, 6> shNumeric, sh;

        SE3<double> pose;
        pose.set( Math::deg2Rad( 10.0 ), Math::deg2Rad( 40.0 ), Math::deg2Rad( -120.0 ), -100.0, 200.0, 300.0 );

        Eigen::Matrix<double, 3, 3> K( Eigen::Matrix<double, 3, 3>::Zero() );
        K( 0, 0 ) = 650.0; K( 0, 2 ) = 320.0;
        K( 1, 1 ) = 650.0; K( 1, 2 ) = 240.0;
        K( 2, 2 ) = 1.0;

        Eigen::Matrix<double, 3, 1> point, ptrans;
        Eigen::Matrix<double, 2, 1> sp, ff, bb, jac;
        point[ 0 ] = 100; point[ 1 ] = 200; point[ 2 ] = 300;

        // project the point with current parameters
        pose.transform( ptrans, point );
        projectWithCam( sp, ptrans, K );

        double h = 0.001;
        for( size_t i = 0; i < 6; i++ ){
            delta[ i ] = h;
            pose.apply( delta );
            pose.transform( ptrans, point );
            projectWithCam( ff, ptrans, K );
            pose.apply( -delta );

            delta[ i ] = -h;
            pose.apply( delta );
            pose.transform( ptrans, point );
            projectWithCam( bb, ptrans, K );
            pose.apply( -delta );

            jac = ( ff - bb ) / ( 2 * h );
            delta.setZero();

            shNumeric( 0, i ) = jac[ 0 ];
            shNumeric( 1, i ) = jac[ 1 ];

        }

        pose.transform( ptrans, point );
        pose.screenJacobian( sh, ptrans, K );

        bool b, ret = true;
        Eigen::Matrix<double, 2, 6> jDiff;
        jDiff = shNumeric - sh;
		b = ( jDiff.array().abs().sum() / ( double )( jDiff.rows() * jDiff.cols() ) ) < 0.0001;

        CVTTEST_PRINT( "Pose ScreenJacobian", b );
        if( !b ){
            std::cout << "Analytic:\n" << sh << std::endl;
            std::cout << "Numeric:\n" << shNumeric << std::endl;
            std::cout << "Difference:\n" << jDiff << std::endl;
        }
        ret &= b;

        return ret;
    }
IGL_INLINE igl::SolverStatus igl::active_set(
  const Eigen::SparseMatrix<AT>& A,
  const Eigen::PlainObjectBase<DerivedB> & B,
  const Eigen::PlainObjectBase<Derivedknown> & known,
  const Eigen::PlainObjectBase<DerivedY> & Y,
  const Eigen::SparseMatrix<AeqT>& Aeq,
  const Eigen::PlainObjectBase<DerivedBeq> & Beq,
  const Eigen::SparseMatrix<AieqT>& Aieq,
  const Eigen::PlainObjectBase<DerivedBieq> & Bieq,
  const Eigen::PlainObjectBase<Derivedlx> & p_lx,
  const Eigen::PlainObjectBase<Derivedux> & p_ux,
  const igl::active_set_params & params,
  Eigen::PlainObjectBase<DerivedZ> & Z
  )
{
//#define ACTIVE_SET_CPP_DEBUG
#ifdef ACTIVE_SET_CPP_DEBUG
#  warning "ACTIVE_SET_CPP_DEBUG"
#endif
  using namespace Eigen;
  using namespace std;
  SolverStatus ret = SOLVER_STATUS_ERROR;
  const int n = A.rows();
  assert(n == A.cols() && "A must be square");
  // Discard const qualifiers
  //if(B.size() == 0)
  //{
  //  B = Eigen::PlainObjectBase<DerivedB>::Zero(n,1);
  //}
  assert(n == B.rows() && "B.rows() must match A.rows()");
  assert(B.cols() == 1 && "B must be a column vector");
  assert(Y.cols() == 1 && "Y must be a column vector");
  assert((Aeq.size() == 0 && Beq.size() == 0) || Aeq.cols() == n);
  assert((Aeq.size() == 0 && Beq.size() == 0) || Aeq.rows() == Beq.rows());
  assert((Aeq.size() == 0 && Beq.size() == 0) || Beq.cols() == 1);
  assert((Aieq.size() == 0 && Bieq.size() == 0) || Aieq.cols() == n);
  assert((Aieq.size() == 0 && Bieq.size() == 0) || Aieq.rows() == Bieq.rows());
  assert((Aieq.size() == 0 && Bieq.size() == 0) || Bieq.cols() == 1);
  Eigen::Matrix<typename Derivedlx::Scalar,Eigen::Dynamic,1> lx;
  Eigen::Matrix<typename Derivedux::Scalar,Eigen::Dynamic,1> ux;
  if(p_lx.size() == 0)
  {
    lx = Eigen::PlainObjectBase<Derivedlx>::Constant(
      n,1,-numeric_limits<typename Derivedlx::Scalar>::max());
  }else
  {
    lx = p_lx;
  }
  if(ux.size() == 0)
  {
    ux = Eigen::PlainObjectBase<Derivedux>::Constant(
      n,1,numeric_limits<typename Derivedux::Scalar>::max());
  }else
  {
    ux = p_ux;
  }
  assert(lx.rows() == n && "lx must have n rows");
  assert(ux.rows() == n && "ux must have n rows");
  assert(ux.cols() == 1 && "lx must be a column vector");
  assert(lx.cols() == 1 && "ux must be a column vector");
  assert((ux.array()-lx.array()).minCoeff() > 0 && "ux(i) must be > lx(i)");
  if(Z.size() != 0)
  {
    // Initial guess should have correct size
    assert(Z.rows() == n && "Z must have n rows");
    assert(Z.cols() == 1 && "Z must be a column vector");
  }
  assert(known.cols() == 1 && "known must be a column vector");
  // Number of knowns
  const int nk = known.size();

  // Initialize active sets
  typedef int BOOL;
#define TRUE 1
#define FALSE 0
  Matrix<BOOL,Dynamic,1> as_lx = Matrix<BOOL,Dynamic,1>::Constant(n,1,FALSE);
  Matrix<BOOL,Dynamic,1> as_ux = Matrix<BOOL,Dynamic,1>::Constant(n,1,FALSE);
  Matrix<BOOL,Dynamic,1> as_ieq = Matrix<BOOL,Dynamic,1>::Constant(Aieq.rows(),1,FALSE);

  // Keep track of previous Z for comparison
  PlainObjectBase<DerivedZ> old_Z;
  old_Z = PlainObjectBase<DerivedZ>::Constant(
      n,1,numeric_limits<typename DerivedZ::Scalar>::max());

  int iter = 0;
  while(true)
  {
#ifdef ACTIVE_SET_CPP_DEBUG
    cout<<"Iteration: "<<iter<<":"<<endl;
    cout<<"  pre"<<endl;
#endif
    // FIND BREACHES OF CONSTRAINTS
    int new_as_lx = 0;
    int new_as_ux = 0;
    int new_as_ieq = 0;
    if(Z.size() > 0)
    {
      for(int z = 0;z < n;z++)
      {
        if(Z(z) < lx(z))
        {
          new_as_lx += (as_lx(z)?0:1);
          //new_as_lx++;
          as_lx(z) = TRUE;
        }
        if(Z(z) > ux(z))
        {
          new_as_ux += (as_ux(z)?0:1);
          //new_as_ux++;
          as_ux(z) = TRUE;
        }
      }
      if(Aieq.rows() > 0)
      {
        PlainObjectBase<DerivedZ> AieqZ;
        AieqZ = Aieq*Z;
        for(int a = 0;a<Aieq.rows();a++)
        {
          if(AieqZ(a) > Bieq(a))
          {
            new_as_ieq += (as_ieq(a)?0:1);
            as_ieq(a) = TRUE;
          }
        }
      }
#ifdef ACTIVE_SET_CPP_DEBUG
      cout<<"  new_as_lx: "<<new_as_lx<<endl;
      cout<<"  new_as_ux: "<<new_as_ux<<endl;
#endif
      const double diff = (Z-old_Z).squaredNorm();
#ifdef ACTIVE_SET_CPP_DEBUG
      cout<<"diff: "<<diff<<endl;
#endif
      if(diff < params.solution_diff_threshold)
      {
        ret = SOLVER_STATUS_CONVERGED;
        break;
      }
      old_Z = Z;
    }

    const int as_lx_count = count(as_lx.data(),as_lx.data()+n,TRUE);
    const int as_ux_count = count(as_ux.data(),as_ux.data()+n,TRUE);
    const int as_ieq_count = 
      count(as_ieq.data(),as_ieq.data()+as_ieq.size(),TRUE);
#ifndef NDEBUG
    {
      int count = 0;
      for(int a = 0;a<as_ieq.size();a++)
      {
        if(as_ieq(a))
        {
          assert(as_ieq(a) == TRUE);
          count++;
        }
      }
      assert(as_ieq_count == count);
    }
#endif

    // PREPARE FIXED VALUES
    PlainObjectBase<Derivedknown> known_i;
    known_i.resize(nk + as_lx_count + as_ux_count,1);
    PlainObjectBase<DerivedY> Y_i;
    Y_i.resize(nk + as_lx_count + as_ux_count,1);
    {
      known_i.block(0,0,known.rows(),known.cols()) = known;
      Y_i.block(0,0,Y.rows(),Y.cols()) = Y;
      int k = nk;
      // Then all lx
      for(int z = 0;z < n;z++)
      {
        if(as_lx(z))
        {
          known_i(k) = z;
          Y_i(k) = lx(z);
          k++;
        }
      }
      // Finally all ux
      for(int z = 0;z < n;z++)
      {
        if(as_ux(z))
        {
          known_i(k) = z;
          Y_i(k) = ux(z);
          k++;
        }
      }
      assert(k==Y_i.size());
      assert(k==known_i.size());
    }
    //cout<<matlab_format((known_i.array()+1).eval(),"known_i")<<endl;
    // PREPARE EQUALITY CONSTRAINTS
    VectorXi as_ieq_list(as_ieq_count,1);
    // Gather active constraints and resp. rhss
    PlainObjectBase<DerivedBeq> Beq_i;
    Beq_i.resize(Beq.rows()+as_ieq_count,1);
    Beq_i.head(Beq.rows()) = Beq;
    {
      int k =0;
      for(int a=0;a<as_ieq.size();a++)
      {
        if(as_ieq(a))
        {
          assert(k<as_ieq_list.size());
          as_ieq_list(k)=a;
          Beq_i(Beq.rows()+k,0) = Bieq(k,0);
          k++;
        }
      }
      assert(k == as_ieq_count);
    }
    // extract active constraint rows
    SparseMatrix<AeqT> Aeq_i,Aieq_i;
    slice(Aieq,as_ieq_list,1,Aieq_i);
    // Append to equality constraints
    cat(1,Aeq,Aieq_i,Aeq_i);


    min_quad_with_fixed_data<AT> data;
#ifndef NDEBUG
    {
      // NO DUPES!
      Matrix<BOOL,Dynamic,1> fixed = Matrix<BOOL,Dynamic,1>::Constant(n,1,FALSE);
      for(int k = 0;k<known_i.size();k++)
      {
        assert(!fixed[known_i(k)]);
        fixed[known_i(k)] = TRUE;
      }
    }
#endif
    
    Eigen::PlainObjectBase<DerivedZ> sol;
    if(known_i.size() == A.rows())
    {
      // Everything's fixed?
#ifdef ACTIVE_SET_CPP_DEBUG
      cout<<"  everything's fixed."<<endl;
#endif
      Z.resize(A.rows(),Y_i.cols());
      slice_into(Y_i,known_i,1,Z);
      sol.resize(0,Y_i.cols());
      assert(Aeq_i.rows() == 0 && "All fixed but linearly constrained");
    }else
    {
#ifdef ACTIVE_SET_CPP_DEBUG
      cout<<"  min_quad_with_fixed_precompute"<<endl;
#endif
      if(!min_quad_with_fixed_precompute(A,known_i,Aeq_i,params.Auu_pd,data))
      {
        cerr<<"Error: min_quad_with_fixed precomputation failed."<<endl;
        if(iter > 0 && Aeq_i.rows() > Aeq.rows())
        {
          cerr<<"  *Are you sure rows of [Aeq;Aieq] are linearly independent?*"<<
            endl;
        }
        ret = SOLVER_STATUS_ERROR;
        break;
      }
#ifdef ACTIVE_SET_CPP_DEBUG
      cout<<"  min_quad_with_fixed_solve"<<endl;
#endif
      if(!min_quad_with_fixed_solve(data,B,Y_i,Beq_i,Z,sol))
      {
        cerr<<"Error: min_quad_with_fixed solve failed."<<endl;
        ret = SOLVER_STATUS_ERROR;
        break;
      }
      //cout<<matlab_format((Aeq*Z-Beq).eval(),"cr")<<endl;
      //cout<<matlab_format(Z,"Z")<<endl;
#ifdef ACTIVE_SET_CPP_DEBUG
      cout<<"  post"<<endl;
#endif
      // Computing Lagrange multipliers needs to be adjusted slightly if A is not symmetric
      assert(data.Auu_sym);
    }

    // Compute Lagrange multiplier values for known_i
    SparseMatrix<AT> Ak;
    // Slow
    slice(A,known_i,1,Ak);
    Eigen::PlainObjectBase<DerivedB> Bk;
    slice(B,known_i,Bk);
    MatrixXd Lambda_known_i = -(0.5*Ak*Z + 0.5*Bk);
    // reverse the lambda values for lx
    Lambda_known_i.block(nk,0,as_lx_count,1) = 
      (-1*Lambda_known_i.block(nk,0,as_lx_count,1)).eval();

    // Extract Lagrange multipliers for Aieq_i (always at back of sol)
    VectorXd Lambda_Aieq_i(Aieq_i.rows(),1);
    for(int l = 0;l<Aieq_i.rows();l++)
    {
      Lambda_Aieq_i(Aieq_i.rows()-1-l) = sol(sol.rows()-1-l);
    }
    
    // Remove from active set
    for(int l = 0;l<as_lx_count;l++)
    {
      if(Lambda_known_i(nk + l) < params.inactive_threshold)
      {
        as_lx(known_i(nk + l)) = FALSE;
      }
    }
    for(int u = 0;u<as_ux_count;u++)
    {
      if(Lambda_known_i(nk + as_lx_count + u) < 
        params.inactive_threshold)
      {
        as_ux(known_i(nk + as_lx_count + u)) = FALSE;
      }
    }
    for(int a = 0;a<as_ieq_count;a++)
    {
      if(Lambda_Aieq_i(a) < params.inactive_threshold)
      {
        as_ieq(as_ieq_list(a)) = FALSE;
      }
    }

    iter++;
    //cout<<iter<<endl;
    if(params.max_iter>0 && iter>=params.max_iter)
    {
      ret = SOLVER_STATUS_MAX_ITER;
      break;
    }

  }

  return ret;
}
Ejemplo n.º 11
0
IGL_INLINE bool igl::lu_lagrange(
  const Eigen::SparseMatrix<T> & ATA,
  const Eigen::SparseMatrix<T> & C,
  Eigen::SparseMatrix<T> & L,
  Eigen::SparseMatrix<T> & U)
{
#if EIGEN_VERSION_AT_LEAST(3,0,92)
#if defined(_WIN32)
  #pragma message("lu_lagrange has not yet been implemented for your Eigen Version")
#else
  #warning lu_lagrange has not yet been implemented for your Eigen Version
#endif

  return false;
#else
  // number of unknowns
  int n = ATA.rows();
  // number of lagrange multipliers
  int m = C.cols();

  assert(ATA.cols() == n);
  if(m != 0)
  {
    assert(C.rows() == n);
    if(C.nonZeros() == 0)
    {
      // See note above about empty columns in C
      fprintf(stderr,"Error: lu_lagrange() C has columns but no entries\n");
      return false;
    }
  }

  // Check that each column of C has at least one entry
  std::vector<bool> has_entry; has_entry.resize(C.cols(),false);
  // Iterate over outside
  for(int k=0; k<C.outerSize(); ++k)
  {
    // Iterate over inside
    for(typename Eigen::SparseMatrix<T>::InnerIterator it (C,k); it; ++it)
    {
      has_entry[it.col()] = true;
    }
  }
  for(int i=0;i<(int)has_entry.size();i++)
  {
    if(!has_entry[i])
    {
      // See note above about empty columns in C
      fprintf(stderr,"Error: lu_lagrange() C(:,%d) has no entries\n",i);
      return false;
    }
  }



  // Cholesky factorization of ATA
  //// Eigen fails if you give a full view of the matrix like this:
  //Eigen::SparseLLT<SparseMatrix<T> > ATA_LLT(ATA);
  Eigen::SparseMatrix<T> ATA_LT = ATA.template triangularView<Eigen::Lower>();
  Eigen::SparseLLT<Eigen::SparseMatrix<T> > ATA_LLT(ATA_LT);

  Eigen::SparseMatrix<T> J = ATA_LLT.matrixL();

  //if(!ATA_LLT.succeeded())
  if(!((J*0).eval().nonZeros() == 0))
  {
    fprintf(stderr,"Error: lu_lagrange() failed to factor ATA\n");
    return false;
  }

  if(m == 0)
  {
    // If there are no constraints (C is empty) then LU decomposition is just L
    // and L' from cholesky decomposition
    L = J;
    U = J.transpose();
  }else
  {
    // Construct helper matrix M
    Eigen::SparseMatrix<T> M = C;
    J.template triangularView<Eigen::Lower>().solveInPlace(M);

    // Compute cholesky factorizaiton of M'*M
    Eigen::SparseMatrix<T> MTM = M.transpose() * M;

    Eigen::SparseLLT<Eigen::SparseMatrix<T> > MTM_LLT(MTM.template triangularView<Eigen::Lower>());

    Eigen::SparseMatrix<T> K = MTM_LLT.matrixL();

    //if(!MTM_LLT.succeeded())
    if(!((K*0).eval().nonZeros() == 0))
    {
      fprintf(stderr,"Error: lu_lagrange() failed to factor MTM\n");
      return false;
    }

    // assemble LU decomposition of Q
    Eigen::Matrix<int,Eigen::Dynamic,1> MI;
    Eigen::Matrix<int,Eigen::Dynamic,1> MJ;
    Eigen::Matrix<T,Eigen::Dynamic,1> MV;
    igl::find(M,MI,MJ,MV);

    Eigen::Matrix<int,Eigen::Dynamic,1> KI;
    Eigen::Matrix<int,Eigen::Dynamic,1> KJ;
    Eigen::Matrix<T,Eigen::Dynamic,1> KV;
    igl::find(K,KI,KJ,KV);

    Eigen::Matrix<int,Eigen::Dynamic,1> JI;
    Eigen::Matrix<int,Eigen::Dynamic,1> JJ;
    Eigen::Matrix<T,Eigen::Dynamic,1> JV;
    igl::find(J,JI,JJ,JV);

    int nnz = JV.size()  + MV.size() + KV.size();

    Eigen::Matrix<int,Eigen::Dynamic,1> UI(nnz);
    Eigen::Matrix<int,Eigen::Dynamic,1> UJ(nnz);
    Eigen::Matrix<T,Eigen::Dynamic,1> UV(nnz);
    UI << JJ,                        MI, (KJ.array() + n).matrix();
    UJ << JI, (MJ.array() + n).matrix(), (KI.array() + n).matrix(); 
    UV << JV,                        MV,                     KV*-1;
    igl::sparse(UI,UJ,UV,U);

    Eigen::Matrix<int,Eigen::Dynamic,1> LI(nnz);
    Eigen::Matrix<int,Eigen::Dynamic,1> LJ(nnz);
    Eigen::Matrix<T,Eigen::Dynamic,1> LV(nnz);
    LI << JI, (MJ.array() + n).matrix(), (KI.array() + n).matrix();
    LJ << JJ,                        MI, (KJ.array() + n).matrix(); 
    LV << JV,                        MV,                        KV;
    igl::sparse(LI,LJ,LV,L);
  }

  return true;
  #endif
}
Ejemplo n.º 12
0
Eigen::Matrix<Scalar, Eigen::Dynamic, 1> squareVector(Eigen::Matrix<Scalar, Eigen::Dynamic, 1> x) {
  return x.array() * x.array();
}
Ejemplo n.º 13
0
Eigen::Matrix<Scalar, Eigen::Dynamic, ColsAtCompileTime> squareMatrix(Eigen::Matrix<Scalar, Eigen::Dynamic, ColsAtCompileTime> x) {
  return x.array() * x.array();
}