void UnknownVars::Solve(const AAndBVars& aAndBVars)
	{
		// solve Ax = b using UmfPack:
		Eigen::SparseMatrix<double> A = aAndBVars.GetA();
		A.transpose();
		Eigen::SparseLU<Eigen::SparseMatrix<double>,Eigen::UmfPack> lu_of_A(A);
		wxASSERT(lu_of_A.succeeded());
		bool success = lu_of_A.solve(aAndBVars.GetBVarsConst(),&m_u);
		wxASSERT(success);
	}
int main()
{
  int n = 10;
  Eigen::SparseMatrix<double> S = Eigen::MatrixXd::Random(n,n).sparseView(0.5,1);
  S = S.transpose()*S;

  MatrixReplacement A;
  A.attachMyMatrix(S);

  Eigen::VectorXd b(n), x;
  b.setRandom();

  // Solve Ax = b using various iterative solver with matrix-free version:
  {
    Eigen::ConjugateGradient<MatrixReplacement, Eigen::Lower|Eigen::Upper, Eigen::IdentityPreconditioner> cg;
    cg.compute(A);
    x = cg.solve(b);
    std::cout << "CG:       #iterations: " << cg.iterations() << ", estimated error: " << cg.error() << std::endl;
  }

  {
    Eigen::BiCGSTAB<MatrixReplacement, Eigen::IdentityPreconditioner> bicg;
    bicg.compute(A);
    x = bicg.solve(b);
    std::cout << "BiCGSTAB: #iterations: " << bicg.iterations() << ", estimated error: " << bicg.error() << std::endl;
  }

  {
    Eigen::GMRES<MatrixReplacement, Eigen::IdentityPreconditioner> gmres;
    gmres.compute(A);
    x = gmres.solve(b);
    std::cout << "GMRES:    #iterations: " << gmres.iterations() << ", estimated error: " << gmres.error() << std::endl;
  }

  {
    Eigen::DGMRES<MatrixReplacement, Eigen::IdentityPreconditioner> gmres;
    gmres.compute(A);
    x = gmres.solve(b);
    std::cout << "DGMRES:   #iterations: " << gmres.iterations() << ", estimated error: " << gmres.error() << std::endl;
  }

  {
    Eigen::MINRES<MatrixReplacement, Eigen::Lower|Eigen::Upper, Eigen::IdentityPreconditioner> minres;
    minres.compute(A);
    x = minres.solve(b);
    std::cout << "MINRES:   #iterations: " << minres.iterations() << ", estimated error: " << minres.error() << std::endl;
  }
}
IGL_INLINE double igl::polyvector_field_poisson_reconstruction(
  const Eigen::PlainObjectBase<DerivedV> &Vcut,
  const Eigen::PlainObjectBase<DerivedF> &Fcut,
  const Eigen::PlainObjectBase<DerivedS> &sol3D_combed,
  Eigen::PlainObjectBase<DerivedSF> &scalars,
  Eigen::PlainObjectBase<DerivedS> &sol3D_recon,
  Eigen::PlainObjectBase<DerivedE> &max_error )
  {
    Eigen::SparseMatrix<typename DerivedV::Scalar> gradMatrix;
    igl::grad(Vcut, Fcut, gradMatrix);

    Eigen::VectorXd FAreas;
    igl::doublearea(Vcut, Fcut, FAreas);
    FAreas = FAreas.array() * .5;

    int nf = FAreas.rows();
    Eigen::SparseMatrix<typename DerivedV::Scalar> M,M1;
    Eigen::VectorXi II = igl::colon<int>(0, nf-1);

    igl::sparse(II, II, FAreas, M1);
    igl::repdiag(M1, 3, M) ;

    int half_degree = sol3D_combed.cols()/3;

    sol3D_recon.setZero(sol3D_combed.rows(),sol3D_combed.cols());

    int numF = Fcut.rows();
    scalars.setZero(Vcut.rows(),half_degree);

    Eigen::SparseMatrix<typename DerivedV::Scalar> Q = gradMatrix.transpose()* M *gradMatrix;

    //fix one point at Ik=fix, value at fixed xk=0
    int fix = 0;
    Eigen::VectorXi Ik(1);Ik<<fix;
    Eigen::VectorXd xk(1);xk<<0;

    //unknown indices
    Eigen::VectorXi Iu(Vcut.rows()-1,1);
    Iu<<igl::colon<int>(0, fix-1),  igl::colon<int>(fix+1,Vcut.rows()-1);

    Eigen::SparseMatrix<typename DerivedV::Scalar> Quu, Quk;
    igl::slice(Q, Iu, Iu, Quu);
    igl::slice(Q, Iu, Ik, Quk);
    Eigen::SimplicialLDLT<Eigen::SparseMatrix<typename DerivedV::Scalar> > solver;
    solver.compute(Quu);


    Eigen::VectorXd vec; vec.setZero(3*numF,1);
    for (int i =0; i<half_degree; ++i)
    {
      vec<<sol3D_combed.col(i*3+0),sol3D_combed.col(i*3+1),sol3D_combed.col(i*3+2);
      Eigen::VectorXd b = gradMatrix.transpose()* M * vec;
      Eigen::VectorXd bu = igl::slice(b, Iu);

      Eigen::VectorXd rhs = bu-Quk*xk;
      Eigen::MatrixXd yu = solver.solve(rhs);

      Eigen::VectorXi index = i*Eigen::VectorXi::Ones(Iu.rows(),1);
      igl::slice_into(yu, Iu, index, scalars);scalars(Ik[0],i)=xk[0];
    }

    //    evaluate gradient of found scalar function
    for (int i =0; i<half_degree; ++i)
    {
      Eigen::VectorXd vec_poisson = gradMatrix*scalars.col(i);
      sol3D_recon.col(i*3+0) = vec_poisson.segment(0*numF, numF);
      sol3D_recon.col(i*3+1) = vec_poisson.segment(1*numF, numF);
      sol3D_recon.col(i*3+2) = vec_poisson.segment(2*numF, numF);
    }

    max_error.setZero(numF,1);
    for (int i =0; i<half_degree; ++i)
    {
      Eigen::VectorXd diff = (sol3D_recon.block(0, i*3, numF, 3)-sol3D_combed.block(0, i*3, numF, 3)).rowwise().norm();
      diff = diff.array() / sol3D_combed.block(0, i*3, numF, 3).rowwise().norm().array();
      max_error = max_error.cwiseMax(diff.cast<typename DerivedE::Scalar>());
    }

    return max_error.mean();
  }
Example #4
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
}
Example #5
0
// [[Rcpp::export]]
List predictLong_cpp(Rcpp::List in_list)
{


  //**********************************
  //      basic parameter
  //**********************************

  int nSim       = Rcpp::as< int > (in_list["nSim"]);
  int nBurnin    = Rcpp::as< int > (in_list["nBurnin"] );
  int silent     = Rcpp::as< int > (in_list["silent"]);

  //**********************************
  //     setting up the main data
  //**********************************
  //if(silent == 0){
  //  Rcpp::Rcout << " Setup data\n";
  //}
  Rcpp::List obs_list  = Rcpp::as<Rcpp::List> (in_list["obs_list"]);
  int nindv = obs_list.length(); //count number of patients
  std::vector< Eigen::SparseMatrix<double,0,int> > As( nindv);
  std::vector< Eigen::SparseMatrix<double,0,int> > As_pred( nindv);
  std::vector< Eigen::VectorXd > Ys( nindv);
  std::vector< Eigen::MatrixXd > pred_ind(nindv);
  std::vector< Eigen::MatrixXd > obs_ind(nindv);
  std::vector< Eigen::MatrixXd > Bfixed_pred(nindv);
  std::vector< Eigen::MatrixXd > Brandom_pred(nindv);
  int count;
  count = 0;
  for( List::iterator it = obs_list.begin(); it != obs_list.end(); ++it ) {
    List obs_tmp = Rcpp::as<Rcpp::List>(*it);
    As[count]            = Rcpp::as<Eigen::SparseMatrix<double,0,int> >(obs_tmp["A"]);
    As_pred[count]       = Rcpp::as<Eigen::SparseMatrix<double,0,int> >(obs_tmp["Apred"]);
    pred_ind[count]      = Rcpp::as<Eigen::MatrixXd>(obs_tmp["pred_ind"]);
    obs_ind[count]       = Rcpp::as<Eigen::MatrixXd>(obs_tmp["obs_ind"]);
    Ys[count]            = Rcpp::as<Eigen::VectorXd>(obs_tmp["Y"]);
    Brandom_pred[count]  = Rcpp::as<Eigen::MatrixXd>(obs_tmp["Brandom_pred"]);
    Bfixed_pred[count]   = Rcpp::as<Eigen::MatrixXd>(obs_tmp["Bfixed_pred"]);
    count++;
  }



  //**********************************
  //operator setup
  //***********************************
  //if(silent == 0){
  //  Rcpp::Rcout << " Setup operator\n";
  //}
  Rcpp::List operator_list  = Rcpp::as<Rcpp::List> (in_list["operator_list"]);
  std::string type_operator = Rcpp::as<std::string>(operator_list["type"]);
  operator_list["nIter"] = 1;
  operatorMatrix* Kobj;
  //Kobj = new MaternMatrixOperator;
  operator_select(type_operator, &Kobj);
  Kobj->initFromList(operator_list, List::create(Rcpp::Named("use.chol") = 1));

  Eigen::VectorXd h = Rcpp::as<Eigen::VectorXd>( operator_list["h"]);

  //Prior solver
  cholesky_solver Qsolver;
  Qsolver.init( Kobj->d, 0, 0, 0);
  Qsolver.analyze( Kobj->Q);
  Qsolver.compute( Kobj->Q);

  //Create solvers for each patient
  std::vector<  cholesky_solver >  Solver( nindv);
  Eigen::SparseMatrix<double, 0, int> Q;

  count = 0;
  for( List::iterator it = obs_list.begin(); it != obs_list.end(); ++it ) {
    List obs_tmp = Rcpp::as<Rcpp::List>( *it);
    Solver[count].init(Kobj->d, 0, 0, 0);
    Q = Eigen::SparseMatrix<double,0,int>(Kobj->Q.transpose());
    Q = Q  * Kobj->Q;
    Q = Q + As[count].transpose()*As[count];
    Solver[count].analyze(Q);
    Solver[count].compute(Q);
    count++;
  }
  //**********************************
  // mixed effect setup
  //***********************************
  //if(silent == 0){
  //  Rcpp::Rcout << " Setup mixed effect\n";
  //}
  Rcpp::List mixedEffect_list  = Rcpp::as<Rcpp::List> (in_list["mixedEffect_list"]);
  std::string type_mixedEffect = Rcpp::as<std::string> (mixedEffect_list["noise"]);
  MixedEffect *mixobj;
  if(type_mixedEffect == "Normal")
    mixobj = new NormalMixedEffect;
  else
    mixobj   = new NIGMixedEffect;

  mixobj->initFromList(mixedEffect_list);

  //**********************************
  // measurement setup
  //***********************************
  //if(silent == 0){
  //  Rcpp::Rcout << " Setup noise\n";
  //}
  MeasurementError *errObj;
  Rcpp::List measurementError_list  = Rcpp::as<Rcpp::List> (in_list["measurementError_list"]);
  std::string type_MeasurementError= Rcpp::as <std::string> (measurementError_list["noise"]);
  if(type_MeasurementError == "Normal")
    errObj = new GaussianMeasurementError;
  else
    errObj = new NIGMeasurementError;

  errObj->initFromList(measurementError_list);





  //**********************************
  // stochastic processes setup
  //***********************************
  //if(silent == 0){
  //  Rcpp::Rcout << " Setup process\n";
  //}
  Rcpp::List processes_list   = Rcpp::as<Rcpp::List>  (in_list["processes_list"]);
  Rcpp::List V_list           = Rcpp::as<Rcpp::List>  (processes_list["V"]);

  std::string type_processes  = Rcpp::as<std::string> (processes_list["noise"]);


  Process *process;

  if (type_processes != "Normal"){
    process  = new GHProcess;
  }else{ process  = new GaussianProcess;}

  process->initFromList(processes_list, h);
  /*
  Simulation objects
  */
  std::mt19937 random_engine;
  std::normal_distribution<double> normal;
  std::default_random_engine gammagenerator;
  random_engine.seed(std::chrono::high_resolution_clock::now().time_since_epoch().count());
  gig rgig;
  rgig.seed(std::chrono::high_resolution_clock::now().time_since_epoch().count());
  Eigen::VectorXd  z;
  z.setZero(Kobj->d);

  Eigen::VectorXd b, Ysim;
  b.setZero(Kobj->d);

  std::vector<int> longInd;
  for (int i=0; i< nindv; i++) longInd.push_back(i);

  Eigen::SparseMatrix<double,0,int> K = Eigen::SparseMatrix<double,0,int>(Kobj->Q);
  K *= sqrt(Kobj->tau);

  std::vector< Eigen::MatrixXd > WVec(nindv);
  std::vector< Eigen::MatrixXd > XVec(nindv);

  for(int i = 0; i < nindv; i++ ) {
    if(silent == 0){
      Rcpp::Rcout << " Compute prediction for patient " << i << "\n";
    }

    XVec[i].resize(As_pred[i].rows(), nSim);
    WVec[i].resize(As_pred[i].rows(), nSim);
    Eigen::MatrixXd random_effect = mixobj->Br[i];
    Eigen::MatrixXd fixed_effect = mixobj->Bf[i];
    for(int ipred = 0; ipred < pred_ind[i].rows(); ipred++){
      //if(silent == 0){
      //  Rcpp::Rcout << " location = " << ipred << ": "<< obs_ind[i](ipred,0)<< " " << obs_ind[i](ipred,1) << "\n";
      //  Rcpp::Rcout << " A size = " <<  As[i].rows() << " " << As[i].cols() << "\n";
      //  Rcpp::Rcout << " Y size = " <<  Ys[i].size() << ", re = " << random_effect.rows() << ", fe = "<< fixed_effect.size() << "\n";
      //}
      //extract data to use for prediction:
      Eigen::SparseMatrix<double,0,int> A = As[i].middleRows(obs_ind[i](ipred,0),obs_ind[i](ipred,1));
      Eigen::VectorXd  Y = Ys[i].segment(obs_ind[i](ipred,0),obs_ind[i](ipred,1));
      mixobj->Br[i] = random_effect.middleRows(obs_ind[i](ipred,0),obs_ind[i](ipred,1));
      mixobj->Bf[i] = fixed_effect.middleRows(obs_ind[i](ipred,0),obs_ind[i](ipred,1));
      //Rcpp::Rcout  << "here1111\n";
      for(int ii = 0; ii < nSim + nBurnin; ii ++){
        //Rcpp::Rcout << "iter = " << ii << "\n";
        Eigen::VectorXd  res = Y;
        //***************************************
        //***************************************
        //   building the residuals and sampling
        //***************************************
        //***************************************

        // removing fixed effect from Y
        mixobj->remove_cov(i, res);
        res -= A * process->Xs[i];
        //***********************************
        // mixobj sampling
        //***********************************
        //Rcpp::Rcout << "here2\n";
        if(type_MeasurementError == "Normal")
          mixobj->sampleU( i, res, 2 * log(errObj->sigma));
        else
          //errObj->Vs[i] = errObj->Vs[i].head(ipred+1);
          mixobj->sampleU2( i,
                            res,
                            errObj->Vs[i].segment(obs_ind[i](ipred,0),obs_ind[i](ipred,1)).cwiseInverse(),
                            2 * log(errObj->sigma));

          mixobj->remove_inter(i, res);

        //***********************************
        // sampling processes
        //***********************************
        //Rcpp::Rcout << "here3\n";
        Eigen::SparseMatrix<double,0,int> Q = Eigen::SparseMatrix<double,0,int>(K.transpose());
        Eigen::VectorXd iV(process->Vs[i].size());
        iV.array() = process->Vs[i].array().inverse();
        Q =  Q * iV.asDiagonal();
        Q =  Q * K;

        for(int j =0; j < Kobj->d; j++)
          z[j] =  normal(random_engine);

        res += A * process->Xs[i];
        //Sample X|Y, V, sigma

        if(type_MeasurementError == "Normal")
          process->sample_X(i,
                            z,
                            res,
                            Q,
                            K,
                            A,
                            errObj->sigma,
                            Solver[i]);
        else
          process->sample_Xv2( i,
                               z,
                               res,
                               Q,
                               K,
                               A,
                               errObj->sigma,
                               Solver[i],
                               errObj->Vs[i].segment(obs_ind[i](ipred,0),obs_ind[i](ipred,1)).cwiseInverse());
        res -= A * process->Xs[i];

        //if(res.cwiseAbs().sum() > 1e16){
        //  throw("res outof bound\n");
        //}

        // sample V| X
        process->sample_V(i, rgig, K);

        //***********************************
        // random variance noise sampling
        //***********************************
        //Rcpp::Rcout << "here4\n";
        if(type_MeasurementError != "Normal"){
          errObj->sampleV(i, res,obs_ind[i](ipred,0)+obs_ind[i](ipred,1));
        }
        // save samples
        if(ii >= nBurnin){
          //if(silent == 0){
          //  Rcpp::Rcout << " save samples << " << i << ", " << ipred << ", " << ii << "\n";
          //}
          //Rcpp::Rcout << "here 1\n";
          Eigen::SparseMatrix<double,0,int> Ai = As_pred[i];
          Ai = Ai.middleRows(pred_ind[i](ipred,0),pred_ind[i](ipred,1));
          //Rcpp::Rcout << "here 2\n";
          Eigen::VectorXd random_effect = Bfixed_pred[i]*mixobj->beta_fixed;
          //Rcpp::Rcout << "here 3\n";
          random_effect += Brandom_pred[i]*(mixobj->U.col(i)+mixobj->beta_random);
          //Rcpp::Rcout << "here 4\n";
          Eigen::VectorXd random_effect_c = random_effect.segment(pred_ind[i](ipred,0),pred_ind[i](ipred,1));
          Eigen::VectorXd AX = Ai * process->Xs[i];
          //Rcpp::Rcout << "here 5\n";
          WVec[i].block(pred_ind[i](ipred,0), ii - nBurnin, pred_ind[i](ipred,1), 1) = AX;
          XVec[i].block(pred_ind[i](ipred,0), ii - nBurnin, pred_ind[i](ipred,1), 1) = random_effect_c + AX;
          //Rcpp::Rcout << "here 6\n";
        }
      }
    }
  }
  Rcpp::Rcout << "store results\n";
  // storing the results
  Rcpp::List out_list;
  out_list["XVec"] = XVec;
  out_list["WVec"] = WVec;
  return(out_list);
}