예제 #1
0
  void
  MultiVectorMatrix::AddRightMultMatrix(Number a,
                                        const MultiVectorMatrix& U,
                                        const Matrix& C,
                                        Number b)
  {
    DBG_ASSERT(NRows()==U.NRows());
    DBG_ASSERT(U.NCols()==C.NRows());
    DBG_ASSERT(NCols()==C.NCols());

    if (b==0.) {
      FillWithNewVectors();
    }

    // ToDo: For now, we simply use MatrixVector multiplications, but
    // we might be more efficient (at least in the non-parallel case)
    // if we used Level 3 Blas
    SmartPtr<const DenseVectorSpace> mydspace = new DenseVectorSpace(C.NRows());
    SmartPtr<DenseVector> mydvec = mydspace->MakeNewDenseVector();

    const DenseGenMatrix* dgm_C = static_cast<const DenseGenMatrix*>(&C);
    DBG_ASSERT(dynamic_cast<const DenseGenMatrix*>(&C));
    for (Index i=0; i<NCols(); i++) {
      const Number* CValues = dgm_C->Values();
      Number* myvalues = mydvec->Values();
      for (Index j=0; j<U.NCols(); j++) {
        myvalues[j] = CValues[i*C.NRows() + j];
      }
      U.MultVector(a, *mydvec, b, *Vec(i));
    }
    ObjectChanged();
  }
  void DenseSymMatrix::HighRankUpdateTranspose(Number alpha,
      const MultiVectorMatrix& V1,
      const MultiVectorMatrix& V2,
      Number beta)
  {
    DBG_ASSERT(Dim()==V1.NCols());
    DBG_ASSERT(Dim()==V2.NCols());
    DBG_ASSERT(beta==0. || initialized_);

    const Index dim = Dim();
    if (beta==0.) {
      for (Index j=0; j<dim; j++) {
        for (Index i=j; i<dim; i++) {
          values_[i+j*dim] = alpha*V1.GetVector(i)->Dot(*V2.GetVector(j));
        }
      }
    }
    else {
      for (Index j=0; j<dim; j++) {
        for (Index i=j; i<dim; i++) {
          values_[i+j*dim] = alpha*V1.GetVector(i)->Dot(*V2.GetVector(j))
                             + beta*values_[i+j*dim];
        }
      }
    }
    initialized_ = true;
    ObjectChanged();
  }
예제 #3
0
  void
  MultiVectorMatrix::AddOneMultiVectorMatrix(Number a,
      const MultiVectorMatrix& mv1,
      Number c)
  {
    DBG_ASSERT(NRows()==mv1.NRows());
    DBG_ASSERT(NCols()==mv1.NCols());

    if (c==0.) {
      FillWithNewVectors();
    }

    for (Index i=0; i<NCols(); i++) {
      Vec(i)->AddOneVector(a, *mv1.GetVector(i), c);
    }
    ObjectChanged();
  }
예제 #4
0
ESymSolverStatus LowRankAugSystemSolver::SolveMultiVector(
   const Vector*                 D_x,
   double                        delta_x,
   const Vector*                 D_s,
   double                        delta_s,
   const Matrix&                 J_c,
   const Vector*                 D_c,
   double                        delta_c,
   const Matrix&                 J_d,
   const Vector*                 D_d,
   double                        delta_d,
   const Vector&                 proto_rhs_x,
   const Vector&                 proto_rhs_s,
   const Vector&                 proto_rhs_c,
   const Vector&                 proto_rhs_d,
   const MultiVectorMatrix&      V,
   const SmartPtr<const Matrix>& P_LM,
   SmartPtr<MultiVectorMatrix>&  V_x,
   SmartPtr<MultiVectorMatrix>&  Vtilde,
   SmartPtr<MultiVectorMatrix>&  Vtilde_x,
   bool                          check_NegEVals,
   Index                         numberOfNegEVals
   )
{
   DBG_START_METH("LowRankAugSystemSolver::SolveMultiVector",
      dbg_verbosity);

   ESymSolverStatus retval;

   Index nrhs = V.NCols();
   DBG_ASSERT(nrhs > 0);

   SmartPtr<MultiVectorMatrixSpace> V_xspace = new MultiVectorMatrixSpace(nrhs, *proto_rhs_x.OwnerSpace());
   V_x = V_xspace->MakeNewMultiVectorMatrix();

   // Create the right hand sides
   std::vector<SmartPtr<const Vector> > rhs_xV(nrhs);
   std::vector<SmartPtr<const Vector> > rhs_sV(nrhs);
   std::vector<SmartPtr<const Vector> > rhs_cV(nrhs);
   std::vector<SmartPtr<const Vector> > rhs_dV(nrhs);

   for( Index i = 0; i < nrhs; i++ )
   {
      if( IsNull(P_LM) )
      {
         rhs_xV[i] = V.GetVector(i);
         DBG_ASSERT(rhs_xV[i]->Dim() == proto_rhs_x.Dim());
      }
      else
      {
         SmartPtr<Vector> fullx = proto_rhs_x.MakeNew();
         P_LM->MultVector(1., *V.GetVector(i), 0., *fullx);
         rhs_xV[i] = ConstPtr(fullx);
      }
      V_x->SetVector(i, *rhs_xV[i]);
      SmartPtr<Vector> tmp;
      tmp = proto_rhs_s.MakeNew();
      tmp->Set(0.);
      rhs_sV[i] = ConstPtr(tmp);
      tmp = proto_rhs_c.MakeNew();
      tmp->Set(0.);
      rhs_cV[i] = ConstPtr(tmp);
      tmp = proto_rhs_d.MakeNew();
      tmp->Set(0.);
      rhs_dV[i] = ConstPtr(tmp);
   }

   // now get space for the solution
   std::vector<SmartPtr<Vector> > sol_xV(nrhs);
   std::vector<SmartPtr<Vector> > sol_sV(nrhs);
   std::vector<SmartPtr<Vector> > sol_cV(nrhs);
   std::vector<SmartPtr<Vector> > sol_dV(nrhs);
   for( Index i = 0; i < nrhs; i++ )
   {
      sol_xV[i] = proto_rhs_x.MakeNew();
      sol_sV[i] = proto_rhs_s.MakeNew();
      sol_cV[i] = proto_rhs_c.MakeNew();
      sol_dV[i] = proto_rhs_d.MakeNew();
   }

   // Call the actual augmented system solver to obtain Vtilde
   retval = aug_system_solver_->MultiSolve(GetRawPtr(Wdiag_), 1.0, D_x, delta_x, D_s, delta_s, &J_c, D_c, delta_c, &J_d,
      D_d, delta_d, rhs_xV, rhs_sV, rhs_cV, rhs_dV, sol_xV, sol_sV, sol_cV, sol_dV, check_NegEVals, numberOfNegEVals);

   if( aug_system_solver_->ProvidesInertia() )
   {
      num_neg_evals_ = aug_system_solver_->NumberOfNegEVals();
   }
   if( retval != SYMSOLVER_SUCCESS )
   {
      return retval;
   }

   // Pack the results into Vtilde
   if( IsNull(compound_sol_vecspace_) )
   {
      Index dimx = proto_rhs_x.Dim();
      Index dims = proto_rhs_s.Dim();
      Index dimc = proto_rhs_c.Dim();
      Index dimd = proto_rhs_d.Dim();
      Index dimtot = dimx + dims + dimc + dimd;
      SmartPtr<CompoundVectorSpace> vecspace = new CompoundVectorSpace(4, dimtot);
      vecspace->SetCompSpace(0, *proto_rhs_x.OwnerSpace());
      vecspace->SetCompSpace(1, *proto_rhs_s.OwnerSpace());
      vecspace->SetCompSpace(2, *proto_rhs_c.OwnerSpace());
      vecspace->SetCompSpace(3, *proto_rhs_d.OwnerSpace());
      compound_sol_vecspace_ = ConstPtr(vecspace);
   }
   SmartPtr<MultiVectorMatrixSpace> V1space = new MultiVectorMatrixSpace(nrhs, *compound_sol_vecspace_);
   Vtilde = V1space->MakeNewMultiVectorMatrix();
   Vtilde_x = V_xspace->MakeNewMultiVectorMatrix();
   for( Index i = 0; i < nrhs; i++ )
   {
      Vtilde_x->SetVector(i, *sol_xV[i]);
      SmartPtr<CompoundVector> cvec = compound_sol_vecspace_->MakeNewCompoundVector(false);
      cvec->SetCompNonConst(0, *sol_xV[i]);
      cvec->SetCompNonConst(1, *sol_sV[i]);
      cvec->SetCompNonConst(2, *sol_cV[i]);
      cvec->SetCompNonConst(3, *sol_dV[i]);
      Vtilde->SetVectorNonConst(i, *cvec);
   }

   return retval;
}