예제 #1
0
int main(int argc, char **argv)
{
    print_version(argv[0]);

    if(argc==1)
    {
        cerr << "Not enough arguments \nPlease try \"" << argv[0] << " -h\" or \"" << argv[0] << " --help \" \n" << endl;
        return 0;
    }

    if ((!strcmp(argv[1],"-h")) | (!strcmp(argv[1],"--help"))) getHelp(argv);

    disp_argv(argc,argv);

    // Start Chrono
    cpuChrono C;
    C.start();

    SymMatrix HeadMat;

    HeadMat.load(argv[1]);
    HeadMat.invert(); // invert inplace
    HeadMat.save(argv[2]);

    // Stop Chrono
    C.stop();
    C.dispEllapsed();

    return 0;
}
예제 #2
0
int main(int argc, char **argv)
{
    print_version(argv[0]);

    if(argc==1)
    {
        cerr << "Not enough arguments \nPlease try \"" << argv[0] << " -h\" or \"" << argv[0] << " --help \" \n" << endl;
        return 0;
    }

    if ((!strcmp(argv[1],"-h")) | (!strcmp(argv[1],"--help"))) getHelp(argv);

    disp_argv(argc,argv);

    // Start Chrono
    auto start_time = std::chrono::system_clock::now();

    SymMatrix HeadMat;

    HeadMat.load(argv[1]);
    HeadMat.invert(); // invert inplace
    HeadMat.save(argv[2]);

    // Stop Chrono
    auto end_time = std::chrono::system_clock::now();
    dispEllapsed(end_time-start_time);

    return 0;
}
예제 #3
0
    typename make_triangular_matrix<SymMatrix, boost::numeric::ublas::lower>::type
    cholesky_decomposition(SymMatrix const & A)
    {
        assert(A.size1() == A.size2());

        auto L = matrix_lower_trianle(A);

        for(size_t i = 0; i != A.size1(); ++ i)
        {
            for(size_t j = 0; j != i; ++ j)
            {
                for(size_t k = 0; k != j; ++ k)
                {
                    L(i, j) -= L(i, k) * L(j, k);
                }

                L(i, j) /= L(j, j);

                using ural::square;
                L(i, i) -= square(L(i, j));
            }

            assert(L(i, i) >= 0);

            using std::sqrt;
            L(i, i) = sqrt(L(i, i));
        }

        return L;
    }
예제 #4
0
bool isPSD (const SymMatrix &M)
/* Check a Matrix is both Symetric and Positive Semi Definite
 *  Creates a temporary copy
 *  
 * Numerics of Algorithm:
 *  Use UdUfactor and checks reciprocal condition number >=0
 *  Algorithms using UdUfactor will will therefore succeed if isPSD(M) is true
 *  Do NOT assume because isPSD is true that M will appear to be PSD to other numerical algorithms
 * Return:
 *  true iff M isSymetric and is PSD by the above algorithm
 */
{
	RowMatrix UD(M.size1(),M.size1());

	RowMatrix::value_type rcond = UdUfactor(UD, M);
	return rcond >= 0.;
}
예제 #5
0
    void assemble_HM(const Geometry& geo, SymMatrix& mat, const unsigned gauss_order) 
    {
        mat = SymMatrix((geo.size()-geo.outermost_interface().nb_triangles()));
        mat.set(0.0);
        double K = 1.0 / (4.0 * M_PI);

        // We iterate over the meshes (or pair of domains) to fill the lower half of the HeadMat (since its symmetry)
        for ( Geometry::const_iterator mit1 = geo.begin(); mit1 != geo.end(); ++mit1) {

            for ( Geometry::const_iterator mit2 = geo.begin(); (mit2 != (mit1+1)); ++mit2) {

                // if mit1 and mit2 communicate, i.e they are used for the definition of a common domain
                const int orientation = geo.oriented(*mit1, *mit2); // equals  0, if they don't have any domains in common
                                                                       // equals  1, if they are both oriented toward the same domain
                                                                       // equals -1, if they are not

                if ( orientation != 0 ) {

                    double Scoeff =   orientation * geo.sigma_inv(*mit1, *mit2) * K;
                    double Dcoeff = - orientation * geo.indicator(*mit1, *mit2) * K;
                    double Ncoeff;

                    if ( !(mit1->outermost() || mit2->outermost()) ) {
                        // Computing S block first because it's needed for the corresponding N block
                        operatorS(*mit1, *mit2, mat, Scoeff, gauss_order);
                        Ncoeff = geo.sigma(*mit1, *mit2)/geo.sigma_inv(*mit1, *mit2);
                    } else {
                        Ncoeff = orientation * geo.sigma(*mit1, *mit2) * K;
                    }

                    if ( !mit1->outermost() ) {
                        // Computing D block
                        operatorD(*mit1, *mit2, mat, Dcoeff, gauss_order);
                    }
                    if ( ( *mit1 != *mit2 ) && ( !mit2->outermost() ) ) {
                        // Computing D* block
                        operatorD(*mit1, *mit2, mat, Dcoeff, gauss_order, true);
                    }

                    // Computing N block
                    operatorN(*mit1, *mit2, mat, Ncoeff, gauss_order);
                }
            }
        }

        // Deflate the diagonal block (N33) of 'mat' : (in order to have a zero-mean potential for the outermost interface)
        const Interface i = geo.outermost_interface();
        unsigned i_first = (*i.begin()->mesh().vertex_begin())->index();
        deflat(mat, i, mat(i_first, i_first) / (geo.outermost_interface().nb_vertices()));
    }
예제 #6
0
Vector<T> CholeskyDecomp<T>::operator()(const SymMatrix<T>& m, 
  const Vector<T>& sol) const
{
  ulong rows = m.numRows();
  Vector<T> retval(rows);
  T ki;
  
  LowerTriangular<T> lower(rows);
  for(unsigned long k = 0; k < rows; k++)
  {
    for(unsigned long i = 0; i <= k; i++)
    {
      ki = m(k,i);
      for(unsigned long j = 0; j < i; j++)
        ki -= lower(i, j) * lower(k, j);
      if(i == k)
        ki = sqrt(ki);
      else
        ki /= lower(i,i);
      lower.at(k,i) = ki;
    }
  }
  Matrix<T> upper(lower);
  Vector<T> temp(rows);
  upper.transpose();

  for(unsigned long i = 0; i < rows; i++)
  {
    ki = sol[i];
    for(unsigned long j = 0; j < i; j++)
    {
      ki -= lower(i,j) * temp[j];
    }
    temp.at(i) = ki/lower(i,i);
  }

  for(unsigned long i = rows; i > 0; i--)
  {
    ki = temp[i-1];
    for(unsigned long j = rows; j > i; j--)
    {
      ki -= upper(i-1, j-1) * retval[j-1];
    }
    retval.at(i-1) = ki/upper(i-1, i-1);
  }

  return retval;
}
  void PDFullSpaceSolver::ComputeResiduals(
    const SymMatrix& W,
    const Matrix& J_c,
    const Matrix& J_d,
    const Matrix& Px_L,
    const Matrix& Px_U,
    const Matrix& Pd_L,
    const Matrix& Pd_U,
    const Vector& z_L,
    const Vector& z_U,
    const Vector& v_L,
    const Vector& v_U,
    const Vector& slack_x_L,
    const Vector& slack_x_U,
    const Vector& slack_s_L,
    const Vector& slack_s_U,
    const Vector& sigma_x,
    const Vector& sigma_s,
    Number alpha,
    Number beta,
    const IteratesVector& rhs,
    const IteratesVector& res,
    IteratesVector& resid)
  {
    DBG_START_METH("PDFullSpaceSolver::ComputeResiduals", dbg_verbosity);

    DBG_PRINT_VECTOR(2, "res", res);
    IpData().TimingStats().ComputeResiduals().Start();

    // Get the current sizes of the perturbation factors
    Number delta_x;
    Number delta_s;
    Number delta_c;
    Number delta_d;
    perturbHandler_->CurrentPerturbation(delta_x, delta_s, delta_c, delta_d);

    SmartPtr<Vector> tmp;

    // x
    W.MultVector(1., *res.x(), 0., *resid.x_NonConst());
    J_c.TransMultVector(1., *res.y_c(), 1., *resid.x_NonConst());
    J_d.TransMultVector(1., *res.y_d(), 1., *resid.x_NonConst());
    Px_L.MultVector(-1., *res.z_L(), 1., *resid.x_NonConst());
    Px_U.MultVector(1., *res.z_U(), 1., *resid.x_NonConst());
    resid.x_NonConst()->AddTwoVectors(delta_x, *res.x(), -1., *rhs.x(), 1.);

    // s
    Pd_U.MultVector(1., *res.v_U(), 0., *resid.s_NonConst());
    Pd_L.MultVector(-1., *res.v_L(), 1., *resid.s_NonConst());
    resid.s_NonConst()->AddTwoVectors(-1., *res.y_d(), -1., *rhs.s(), 1.);
    if (delta_s!=0.) {
      resid.s_NonConst()->Axpy(delta_s, *res.s());
    }

    // c
    J_c.MultVector(1., *res.x(), 0., *resid.y_c_NonConst());
    resid.y_c_NonConst()->AddTwoVectors(-delta_c, *res.y_c(), -1., *rhs.y_c(), 1.);

    // d
    J_d.MultVector(1., *res.x(), 0., *resid.y_d_NonConst());
    resid.y_d_NonConst()->AddTwoVectors(-1., *res.s(), -1., *rhs.y_d(), 1.);
    if (delta_d!=0.) {
      resid.y_d_NonConst()->Axpy(-delta_d, *res.y_d());
    }

    // zL
    resid.z_L_NonConst()->Copy(*res.z_L());
    resid.z_L_NonConst()->ElementWiseMultiply(slack_x_L);
    tmp = z_L.MakeNew();
    Px_L.TransMultVector(1., *res.x(), 0., *tmp);
    tmp->ElementWiseMultiply(z_L);
    resid.z_L_NonConst()->AddTwoVectors(1., *tmp, -1., *rhs.z_L(), 1.);

    // zU
    resid.z_U_NonConst()->Copy(*res.z_U());
    resid.z_U_NonConst()->ElementWiseMultiply(slack_x_U);
    tmp = z_U.MakeNew();
    Px_U.TransMultVector(1., *res.x(), 0., *tmp);
    tmp->ElementWiseMultiply(z_U);
    resid.z_U_NonConst()->AddTwoVectors(-1., *tmp, -1., *rhs.z_U(), 1.);

    // vL
    resid.v_L_NonConst()->Copy(*res.v_L());
    resid.v_L_NonConst()->ElementWiseMultiply(slack_s_L);
    tmp = v_L.MakeNew();
    Pd_L.TransMultVector(1., *res.s(), 0., *tmp);
    tmp->ElementWiseMultiply(v_L);
    resid.v_L_NonConst()->AddTwoVectors(1., *tmp, -1., *rhs.v_L(), 1.);

    // vU
    resid.v_U_NonConst()->Copy(*res.v_U());
    resid.v_U_NonConst()->ElementWiseMultiply(slack_s_U);
    tmp = v_U.MakeNew();
    Pd_U.TransMultVector(1., *res.s(), 0., *tmp);
    tmp->ElementWiseMultiply(v_U);
    resid.v_U_NonConst()->AddTwoVectors(-1., *tmp, -1., *rhs.v_U(), 1.);

    DBG_PRINT_VECTOR(2, "resid", resid);

    if (Jnlst().ProduceOutput(J_MOREVECTOR, J_LINEAR_ALGEBRA)) {
      resid.Print(Jnlst(), J_MOREVECTOR, J_LINEAR_ALGEBRA, "resid");
    }

    if (Jnlst().ProduceOutput(J_MOREDETAILED, J_LINEAR_ALGEBRA)) {
      Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
                     "max-norm resid_x  %e\n", resid.x()->Amax());
      Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
                     "max-norm resid_s  %e\n", resid.s()->Amax());
      Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
                     "max-norm resid_c  %e\n", resid.y_c()->Amax());
      Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
                     "max-norm resid_d  %e\n", resid.y_d()->Amax());
      Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
                     "max-norm resid_zL %e\n", resid.z_L()->Amax());
      Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
                     "max-norm resid_zU %e\n", resid.z_U()->Amax());
      Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
                     "max-norm resid_vL %e\n", resid.v_L()->Amax());
      Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
                     "max-norm resid_vU %e\n", resid.v_U()->Amax());
    }
    IpData().TimingStats().ComputeResiduals().End();
  }
  bool PDFullSpaceSolver::SolveOnce(bool resolve_with_better_quality,
                                    bool pretend_singular,
                                    const SymMatrix& W,
                                    const Matrix& J_c,
                                    const Matrix& J_d,
                                    const Matrix& Px_L,
                                    const Matrix& Px_U,
                                    const Matrix& Pd_L,
                                    const Matrix& Pd_U,
                                    const Vector& z_L,
                                    const Vector& z_U,
                                    const Vector& v_L,
                                    const Vector& v_U,
                                    const Vector& slack_x_L,
                                    const Vector& slack_x_U,
                                    const Vector& slack_s_L,
                                    const Vector& slack_s_U,
                                    const Vector& sigma_x,
                                    const Vector& sigma_s,
                                    Number alpha,
                                    Number beta,
                                    const IteratesVector& rhs,
                                    IteratesVector& res)
  {
    // TO DO LIST:
    //
    // 1. decide for reasonable return codes (e.g. fatal error, too
    //    ill-conditioned...)
    // 2. Make constants parameters that can be set from the outside
    // 3. Get Information out of Ipopt structures
    // 4. add heuristic for structurally singular problems
    // 5. see if it makes sense to distinguish delta_x and delta_s,
    //    or delta_c and delta_d
    // 6. increase pivot tolerance if number of get evals so too small
    DBG_START_METH("PDFullSpaceSolver::SolveOnce",dbg_verbosity);

    IpData().TimingStats().PDSystemSolverSolveOnce().Start();

    // Compute the right hand side for the augmented system formulation
    SmartPtr<Vector> augRhs_x = rhs.x()->MakeNewCopy();
    Px_L.AddMSinvZ(1.0, slack_x_L, *rhs.z_L(), *augRhs_x);
    Px_U.AddMSinvZ(-1.0, slack_x_U, *rhs.z_U(), *augRhs_x);

    SmartPtr<Vector> augRhs_s = rhs.s()->MakeNewCopy();
    Pd_L.AddMSinvZ(1.0, slack_s_L, *rhs.v_L(), *augRhs_s);
    Pd_U.AddMSinvZ(-1.0, slack_s_U, *rhs.v_U(), *augRhs_s);

    // Get space into which we can put the solution of the augmented system
    SmartPtr<IteratesVector> sol = res.MakeNewIteratesVector(true);

    // Now check whether any data has changed
    std::vector<const TaggedObject*> deps(13);
    deps[0] = &W;
    deps[1] = &J_c;
    deps[2] = &J_d;
    deps[3] = &z_L;
    deps[4] = &z_U;
    deps[5] = &v_L;
    deps[6] = &v_U;
    deps[7] = &slack_x_L;
    deps[8] = &slack_x_U;
    deps[9] = &slack_s_L;
    deps[10] = &slack_s_U;
    deps[11] = &sigma_x;
    deps[12] = &sigma_s;
    void* dummy;
    bool uptodate = dummy_cache_.GetCachedResult(dummy, deps);
    if (!uptodate) {
      dummy_cache_.AddCachedResult(dummy, deps);
      augsys_improved_ = false;
    }
    // improve_current_solution can only be true, if that system has
    // been solved before
    DBG_ASSERT((!resolve_with_better_quality && !pretend_singular) || uptodate);

    ESymSolverStatus retval;
    if (uptodate && !pretend_singular) {

      // Get the perturbation values
      Number delta_x;
      Number delta_s;
      Number delta_c;
      Number delta_d;
      perturbHandler_->CurrentPerturbation(delta_x, delta_s, delta_c, delta_d);

      // No need to go through the pain of finding the appropriate
      // values for the deltas, because the matrix hasn't changed since
      // the last call.  So, just call the Solve Method
      //
      // Note: resolve_with_better_quality is true, then the Solve
      // method has already asked the augSysSolver to increase the
      // quality at the end solve, and we are now getting the solution
      // with that better quality
      retval = augSysSolver_->Solve(&W, 1.0, &sigma_x, delta_x,
                                    &sigma_s, delta_s, &J_c, NULL,
                                    delta_c, &J_d, NULL, delta_d,
                                    *augRhs_x, *augRhs_s, *rhs.y_c(), *rhs.y_d(),
                                    *sol->x_NonConst(), *sol->s_NonConst(),
                                    *sol->y_c_NonConst(), *sol->y_d_NonConst(),
                                    false, 0);
      if (retval!=SYMSOLVER_SUCCESS) {
        IpData().TimingStats().PDSystemSolverSolveOnce().End();
        return false;
      }
    }
    else {
      const Index numberOfEVals=rhs.y_c()->Dim()+rhs.y_d()->Dim();
      // counter for the number of trial evaluations
      // (ToDo is not at the correct place)
      Index count = 0;

      // Get the very first perturbation values from the perturbation
      // Handler
      Number delta_x;
      Number delta_s;
      Number delta_c;
      Number delta_d;
      perturbHandler_->ConsiderNewSystem(delta_x, delta_s, delta_c, delta_d);

      retval = SYMSOLVER_SINGULAR;
      bool fail = false;

      while (retval!= SYMSOLVER_SUCCESS && !fail) {

        if (pretend_singular) {
          retval = SYMSOLVER_SINGULAR;
          pretend_singular = false;
        }
        else {
          count++;
          Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
                         "Solving system with delta_x=%e delta_s=%e\n                    delta_c=%e delta_d=%e\n",
                         delta_x, delta_s, delta_c, delta_d);
          bool check_inertia = true;
          if (neg_curv_test_tol_ > 0.) {
            check_inertia = false;
          }
          retval = augSysSolver_->Solve(&W, 1.0, &sigma_x, delta_x,
                                        &sigma_s, delta_s, &J_c, NULL,
                                        delta_c, &J_d, NULL, delta_d,
                                        *augRhs_x, *augRhs_s, *rhs.y_c(), *rhs.y_d(),
                                        *sol->x_NonConst(), *sol->s_NonConst(),
                                        *sol->y_c_NonConst(), *sol->y_d_NonConst(),                                     check_inertia, numberOfEVals);
        }
        if (retval==SYMSOLVER_FATAL_ERROR) return false;
        if (retval==SYMSOLVER_SINGULAR &&
            (rhs.y_c()->Dim()+rhs.y_d()->Dim() > 0) ) {

          // Get new perturbation factors from the perturbation
          // handlers for the singular case
          bool pert_return = perturbHandler_->PerturbForSingularity(delta_x, delta_s,
                             delta_c, delta_d);
          if (!pert_return) {
            Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
                           "PerturbForSingularity can't be done\n");
            IpData().TimingStats().PDSystemSolverSolveOnce().End();
            return false;
          }
        }
        else if (retval==SYMSOLVER_WRONG_INERTIA &&
                 augSysSolver_->NumberOfNegEVals() < numberOfEVals) {
          Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
                         "Number of negative eigenvalues too small!\n");
          // If the number of negative eigenvalues is too small, then
          // we first try to remedy this by asking for better quality
          // solution (e.g. increasing pivot tolerance), and if that
          // doesn't help, we assume that the system is singular
          bool assume_singular = true;
          if (!augsys_improved_) {
            Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
                           "Asking augmented system solver to improve quality of its solutions.\n");
            augsys_improved_ = augSysSolver_->IncreaseQuality();
            if (augsys_improved_) {
              IpData().Append_info_string("q");
              assume_singular = false;
            }
            else {
              Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
                             "Quality could not be improved\n");
            }
          }
          if (assume_singular) {
            bool pert_return =
                               perturbHandler_->PerturbForSingularity(delta_x, delta_s,
                                                                      delta_c, delta_d);
            if (!pert_return) {
              Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
                             "PerturbForSingularity can't be done for assume singular.\n");
              IpData().TimingStats().PDSystemSolverSolveOnce().End();
              return false;
            }
            IpData().Append_info_string("a");
          }
        }
        else if (retval==SYMSOLVER_WRONG_INERTIA ||
                 retval==SYMSOLVER_SINGULAR) {
          // Get new perturbation factors from the perturbation
          // handlers for the case of wrong inertia
          bool pert_return = perturbHandler_->PerturbForWrongInertia(delta_x, delta_s,
                             delta_c, delta_d);
          if (!pert_return) {
            Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
                           "PerturbForWrongInertia can't be done for wrong interia or singular.\n");
            IpData().TimingStats().PDSystemSolverSolveOnce().End();
            return false;
          }
        }
        else if (neg_curv_test_tol_ > 0.) {
          DBG_ASSERT(augSysSolver_->ProvidesInertia());
          // we now check if the inertia is possible wrong
          Index neg_values = augSysSolver_->NumberOfNegEVals();
          if (neg_values != numberOfEVals) {
            // check if we have a direction of sufficient positive curvature
            SmartPtr<Vector> x_tmp = sol->x()->MakeNew();
            W.MultVector(1., *sol->x(), 0., *x_tmp);
            Number xWx = x_tmp->Dot(*sol->x());
            x_tmp->Copy(*sol->x());
            x_tmp->ElementWiseMultiply(sigma_x);
            xWx += x_tmp->Dot(*sol->x());
            SmartPtr<Vector> s_tmp = sol->s()->MakeNewCopy();
            s_tmp->ElementWiseMultiply(sigma_s);
            xWx += s_tmp->Dot(*sol->s());
            if (neg_curv_test_reg_) {
              x_tmp->Copy(*sol->x());
              x_tmp->Scal(delta_x);
              xWx += x_tmp->Dot(*sol->x());

              s_tmp->Copy(*sol->s());
              s_tmp->Scal(delta_s);
              xWx += s_tmp->Dot(*sol->s());
            }
            Number xs_nrmsq = pow(sol->x()->Nrm2(),2) + pow(sol->s()->Nrm2(),2);
            Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
                           "In inertia heuristic: xWx = %e xx = %e\n",
                           xWx, xs_nrmsq);
            if (xWx < neg_curv_test_tol_*xs_nrmsq) {
              Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
                             "    -> Redo with modified matrix.\n");
              bool pert_return = perturbHandler_->PerturbForWrongInertia(delta_x, delta_s,
                                 delta_c, delta_d);
              if (!pert_return) {
                Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
                               "PerturbForWrongInertia can't be done for inertia heuristic.\n");
                IpData().TimingStats().PDSystemSolverSolveOnce().End();
                return false;
              }
              retval = SYMSOLVER_WRONG_INERTIA;
            }
          }
        }
      } // while (retval!=SYMSOLVER_SUCCESS && !fail) {

      // Some output
      Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
                     "Number of trial factorizations performed: %d\n",
                     count);
      Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
                     "Perturbation parameters: delta_x=%e delta_s=%e\n                         delta_c=%e delta_d=%e\n",
                     delta_x, delta_s, delta_c, delta_d);
      // Set the perturbation values in the Data object
      IpData().setPDPert(delta_x, delta_s, delta_c, delta_d);
    }

    // Compute the remaining sol Vectors
    Px_L.SinvBlrmZMTdBr(-1., slack_x_L, *rhs.z_L(), z_L, *sol->x(), *sol->z_L_NonConst());
    Px_U.SinvBlrmZMTdBr(1., slack_x_U, *rhs.z_U(), z_U, *sol->x(), *sol->z_U_NonConst());
    Pd_L.SinvBlrmZMTdBr(-1., slack_s_L, *rhs.v_L(), v_L, *sol->s(), *sol->v_L_NonConst());
    Pd_U.SinvBlrmZMTdBr(1., slack_s_U, *rhs.v_U(), v_U, *sol->s(), *sol->v_U_NonConst());

    // Finally let's assemble the res result vectors
    res.AddOneVector(alpha, *sol, beta);

    IpData().TimingStats().PDSystemSolverSolveOnce().End();

    return true;
  }
예제 #9
0
int main( int argc, char **argv)
{
    print_version(argv[0]);
    //TODO doesn't say txt, if you don't specify it

    command_usage("Provides informations on a Matrix generated with OpenMEEG");
    const char *filename = command_option("-i",(const char *) NULL,"Matrix file");
    const char *txt = command_option("-txt",(const char *) 0,"Force reading data stored in ascii format");
    const char *sym = command_option("-sym",(const char *) 0,"Data are symmetric matrices");
    const char *sparse = command_option("-sparse",(const char *) 0,"Data are sparse matrices");
    const char *mat = command_option("-mat",(const char *) 0,"Data are matlab format");
    const char *bin = command_option("-bin",(const char *) 0,"Data are binary format");
    if (command_option("-h",(const char *)0,0)) return 0;

    if (!filename) {
        cerr << "Please set Matrix File" << endl;
        exit(1);
    }

    cout << "Loading : " << filename << endl;

    if (sym) {
        if (txt) {
            SymMatrix M;
            M.load(filename);
            cout << "Format : ASCII" << endl;
            print_infos(M);
        } else if (mat) {
            cerr << "Unsupported Format : MAT for symmetric matrices" << endl;
            exit(1);
        } else if (bin) {
            SymMatrix M;
            M.load(filename);
            cout << "Format : BINARY" << endl;
            print_infos(M);
        } else {
            SymMatrix M;
            M.load(filename);
            print_infos(M);
        }
    } else if (sparse) {
        if (txt) {
            SparseMatrix M;
            M.load(filename);
            cout << "Format : ASCII" << endl;
            print_infos(M);
        } else if (mat) {
            SparseMatrix M;
            M.load(filename);
            cout << "Format : MAT" << endl;
            print_infos(M);
        } else if (bin) {
            SparseMatrix M;
            M.load(filename);
            cout << "Format : BINARY" << endl;
            print_infos(M);
        } else {
            SparseMatrix M;
            M.load(filename);
            print_infos(M);
        }
    } else {
        if (txt) {
            Matrix M;
            M.load(filename);
            cout << "Format : ASCII" << endl;
            print_infos(M);
        } else if (mat) {
            Matrix M;
            M.load(filename);
            cout << "Format : MAT" << endl;
            print_infos(M);
        } else if (bin) {
            Matrix M;
            M.load(filename);
            cout << "Format : BINARY" << endl;
            print_infos(M);
        } else {
            Matrix M;
            M.load(filename);
            print_infos(M);
        }
    }

    return 0;
}
예제 #10
0
파일: QpGenData.C 프로젝트: fqiang/PIPS
void QpGenData::putCIntoAt( SymMatrix& M, int row, int col )
{
  M.symAtPutSubmatrix( row, col, *C, 0, 0, mz, nx );
}
예제 #11
0
파일: QpGenData.C 프로젝트: fqiang/PIPS
void QpGenData::putQIntoAt( SymMatrix& M, int row, int col )
{
  M.symAtPutSubmatrix( row, col, *Q, 0, 0, nx, nx );
}
예제 #12
0
 Vector::Vector(SymMatrix& A) {
     nlin()=A.nlin()*(A.nlin()+1)/2;
     value = A.value;
 }
예제 #13
0
  // Initialize the local copy of the positions of the nonzero
  // elements
  ESymSolverStatus
  TSymLinearSolver::InitializeStructure(const SymMatrix& sym_A)
  {
    DBG_START_METH("TSymLinearSolver::InitializeStructure",
                   dbg_verbosity);
    DBG_ASSERT(!initialized_);

    ESymSolverStatus retval;

    // have_structure_ is already true if this is a warm start for a
    // problem with identical structure
    if (!have_structure_) {

      dim_ = sym_A.Dim();
      nonzeros_triplet_ = TripletHelper::GetNumberEntries(sym_A);

      delete [] airn_;
      delete [] ajcn_;
      airn_ = new Index[nonzeros_triplet_];
      ajcn_ = new Index[nonzeros_triplet_];

      TripletHelper::FillRowCol(nonzeros_triplet_, sym_A, airn_, ajcn_);

      // If the solver wants the compressed format, the converter has to
      // be initialized
      const Index *ia;
      const Index *ja;
      Index nonzeros;
      if (matrix_format_ == SparseSymLinearSolverInterface::Triplet_Format) {
        ia = airn_;
        ja = ajcn_;
        nonzeros = nonzeros_triplet_;
      }
      else {
        if (HaveIpData()) {
          IpData().TimingStats().LinearSystemStructureConverter().Start();
          IpData().TimingStats().LinearSystemStructureConverterInit().Start();
        }
        nonzeros_compressed_ =
          triplet_to_csr_converter_->InitializeConverter(dim_, nonzeros_triplet_,
              airn_, ajcn_);
        if (HaveIpData()) {
          IpData().TimingStats().LinearSystemStructureConverterInit().End();
        }
        ia = triplet_to_csr_converter_->IA();
        ja = triplet_to_csr_converter_->JA();
        if (HaveIpData()) {
          IpData().TimingStats().LinearSystemStructureConverter().End();
        }
        nonzeros = nonzeros_compressed_;
      }

      retval = solver_interface_->InitializeStructure(dim_, nonzeros, ia, ja);
      if (retval != SYMSOLVER_SUCCESS) {
        return retval;
      }

      // Get space for the scaling factors
      delete [] scaling_factors_;
      if (IsValid(scaling_method_)) {
        if (HaveIpData()) {
          IpData().TimingStats().LinearSystemScaling().Start();
        }
        scaling_factors_ = new double[dim_];
        if (HaveIpData()) {
          IpData().TimingStats().LinearSystemScaling().End();
        }
      }

      have_structure_ = true;
    }
    else {
      ASSERT_EXCEPTION(dim_==sym_A.Dim(), INVALID_WARMSTART,
                       "TSymLinearSolver called with warm_start_same_structure, but the problem is solved for the first time.");
      // This is a warm start for identical structure, so we don't need to
      // recompute the nonzeros location arrays
      const Index *ia;
      const Index *ja;
      Index nonzeros;
      if (matrix_format_ == SparseSymLinearSolverInterface::Triplet_Format) {
        ia = airn_;
        ja = ajcn_;
        nonzeros = nonzeros_triplet_;
      }
      else {
        IpData().TimingStats().LinearSystemStructureConverter().Start();
        ia = triplet_to_csr_converter_->IA();
        ja = triplet_to_csr_converter_->JA();
        IpData().TimingStats().LinearSystemStructureConverter().End();
        nonzeros = nonzeros_compressed_;
      }
      retval = solver_interface_->InitializeStructure(dim_, nonzeros, ia, ja);
    }
    initialized_=true;
    return retval;
  }
예제 #14
0
  ESymSolverStatus
  TSymLinearSolver::MultiSolve(const SymMatrix& sym_A,
                               std::vector<SmartPtr<const Vector> >& rhsV,
                               std::vector<SmartPtr<Vector> >& solV,
                               bool check_NegEVals,
                               Index numberOfNegEVals)
  {
    DBG_START_METH("TSymLinearSolver::MultiSolve",dbg_verbosity);
    DBG_ASSERT(!check_NegEVals || ProvidesInertia());

    // Check if this object has ever seen a matrix If not,
    // allocate memory of the matrix structure and copy the nonzeros
    // structure (it is assumed that this will never change).
    if (!initialized_) {
      ESymSolverStatus retval = InitializeStructure(sym_A);
      if (retval != SYMSOLVER_SUCCESS) {
        return retval;
      }
    }

    DBG_ASSERT(nonzeros_triplet_== TripletHelper::GetNumberEntries(sym_A));

    // Check if the matrix has been changed
    DBG_PRINT((1,"atag_=%d sym_A->GetTag()=%d\n",atag_,sym_A.GetTag()));
    bool new_matrix = sym_A.HasChanged(atag_);
    atag_ = sym_A.GetTag();

    // If a new matrix is encountered, get the array for storing the
    // entries from the linear solver interface, fill in the new
    // values, compute the new scaling factors (if required), and
    // scale the matrix
    if (new_matrix || just_switched_on_scaling_) {
      GiveMatrixToSolver(true, sym_A);
      new_matrix = true;
    }

    // Retrieve the right hand sides and scale if required
    Index nrhs = (Index)rhsV.size();
    double* rhs_vals = new double[dim_*nrhs];
    for (Index irhs=0; irhs<nrhs; irhs++) {
      TripletHelper::FillValuesFromVector(dim_, *rhsV[irhs],
                                          &rhs_vals[irhs*(dim_)]);
      if (Jnlst().ProduceOutput(J_MOREMATRIX, J_LINEAR_ALGEBRA)) {
        Jnlst().Printf(J_MOREMATRIX, J_LINEAR_ALGEBRA,
                       "Right hand side %d in TSymLinearSolver:\n", irhs);
        for (Index i=0; i<dim_; i++) {
          Jnlst().Printf(J_MOREMATRIX, J_LINEAR_ALGEBRA,
                         "Trhs[%5d,%5d] = %23.16e\n", irhs, i,
                         rhs_vals[irhs*(dim_)+i]);
        }
      }
      if (use_scaling_) {
        if (HaveIpData()) {
          IpData().TimingStats().LinearSystemScaling().Start();
        }
        for (Index i=0; i<dim_; i++) {
          rhs_vals[irhs*(dim_)+i] *= scaling_factors_[i];
        }
        if (HaveIpData()) {
          IpData().TimingStats().LinearSystemScaling().End();
        }
      }
    }

    bool done = false;
    // Call the linear solver through the interface to solve the
    // system.  This is repeated, if the return values is S_CALL_AGAIN
    // after the values have been restored (this might be necessary
    // for MA27 if the size of the work space arrays was not large
    // enough).
    ESymSolverStatus retval;
    while (!done) {
      const Index* ia;
      const Index* ja;
      if (matrix_format_==SparseSymLinearSolverInterface::Triplet_Format) {
        ia = airn_;
        ja = ajcn_;
      }
      else {
        if (HaveIpData()) {
          IpData().TimingStats().LinearSystemStructureConverter().Start();
        }
        ia = triplet_to_csr_converter_->IA();
        ja = triplet_to_csr_converter_->JA();
        if (HaveIpData()) {
          IpData().TimingStats().LinearSystemStructureConverter().End();
        }
      }

      retval = solver_interface_->MultiSolve(new_matrix, ia, ja,
                                             nrhs, rhs_vals, check_NegEVals,
                                             numberOfNegEVals);
      if (retval==SYMSOLVER_CALL_AGAIN) {
        DBG_PRINT((1, "Solver interface asks to be called again.\n"));
        GiveMatrixToSolver(false, sym_A);
      }
      else {
        done = true;
      }
    }

    // If the solve was successful, unscale the solution (if required)
    // and transfer the result into the Vectors
    if (retval==SYMSOLVER_SUCCESS) {
      for (Index irhs=0; irhs<nrhs; irhs++) {
        if (use_scaling_) {
          if (HaveIpData()) {
            IpData().TimingStats().LinearSystemScaling().Start();
          }
          for (Index i=0; i<dim_; i++) {
            rhs_vals[irhs*(dim_)+i] *= scaling_factors_[i];
          }
          if (HaveIpData()) {
            IpData().TimingStats().LinearSystemScaling().End();
          }
        }
        if (Jnlst().ProduceOutput(J_MOREMATRIX, J_LINEAR_ALGEBRA)) {
          Jnlst().Printf(J_MOREMATRIX, J_LINEAR_ALGEBRA,
                         "Solution %d in TSymLinearSolver:\n", irhs);
          for (Index i=0; i<dim_; i++) {
            Jnlst().Printf(J_MOREMATRIX, J_LINEAR_ALGEBRA,
                           "Tsol[%5d,%5d] = %23.16e\n", irhs, i,
                           rhs_vals[irhs*(dim_)+i]);
          }
        }
        TripletHelper::PutValuesInVector(dim_, &rhs_vals[irhs*(dim_)],
                                         *solV[irhs]);
      }
    }

    delete[] rhs_vals;

    return retval;
  }