Exemple #1
0
    std::shared_ptr< VectorSpace > extractSubSpaceImpl( const VectorSpace& space,
                                                        unsigned global_id )
    {
        if ( is< ProductSpace::VectorCreator >( space.creator() ) )
        {
            const auto& product_space_creator =
                cast_ref< ProductSpace::VectorCreator >( space.creator() );
            const auto& subSpaces = product_space_creator.subSpaces();
            std::shared_ptr< VectorSpace > result;
            for ( auto i = 0u; i < subSpaces.size(); ++i )
            {
                if ( product_space_creator.inverseIdMap( i ) == global_id &&
                     !is< ProductSpace::VectorCreator >( subSpaces[ i ]->creator() ) )
                    return subSpaces[ i ];

                if ( is< ProductSpace::VectorCreator >( subSpaces[ i ]->creator() ) )
                {
                    auto result = extractSubSpaceImpl( *subSpaces[ i ], global_id );
                    if ( result )
                        return result;
                }
            }
        }

        return nullptr;
    }
template <class Scalar> inline
DefaultBlockVector<Scalar>
::DefaultBlockVector(const VectorSpace<Scalar>& space)
  : BlockVectorBase<Scalar>(), space_(space), blocks_(space.numBlocks())
{
  for (int i=0; i<space.numBlocks(); i++)
  {
    blocks_[i] = space.getBlock(i).createMember();
  }
}
bool VectorSpaceThyra::is_compatible(const VectorSpace& vec_spc ) const
{
  if( this->dim()==vec_spc.dim() && this->is_in_core() && vec_spc.is_in_core() )
    return true;
  const VectorSpaceThyra
    *thyra_vec_spc = dynamic_cast<const VectorSpaceThyra*>(&vec_spc);
  if( thyra_vec_spc->thyra_vec_spc()->isCompatible(*thyra_vec_spc_) )
    return true;
  return false;
}
 LinearOperatorCreator::LinearOperatorCreator( const VectorSpace& X, const VectorSpace& Y )
     : Generic::LinearOperatorCreator< LinearOperator >(
           [&X, &Y]( const VectorSpace* space ) {
               return LinearOperator(
                   ::Eigen::MatrixXd::Zero( cast_ref< VectorCreator >( X.creator() ).dim(),
                                            cast_ref< VectorCreator >( Y.creator() ).dim() ),
                   *space, X, Y );
           },
           X, Y )
 {
 }
template <class Scalar> inline
void BlockIterator<Scalar>
::goToStart(const VectorSpace<Scalar>& space,
  std::deque<int>& pos) const
{
  pos.push_back(0);
  if (space.isBlockSpace())
  {
    goToStart(space.getBlock(0), pos);
  }
}
SerialVector::SerialVector(const VectorSpace<double>& vs)
  : SingleChunkVector<double>(),
    vecSpace_(vs),
    data_(vs.dim()),
    dim_(vs.dim())
{
  const SerialVectorSpace* rvs 
    = dynamic_cast<const SerialVectorSpace*>(vs.ptr().get());
  TEUCHOS_TEST_FOR_EXCEPTION(rvs==0, std::runtime_error,
    "could not cast vector space to SerialVectorSpace in "
    "SerialVector ctor");
}
Exemple #7
0
/**********************************************************************
 * Function_Name: Intersection
 * Return 		: double
 * Comments 	: returns the dist_from_sphere, if the intersection
 * 				 	else it returns a -1
 **********************************************************************/
double Ellipse::Intersection(const Vertex& RayOrigin, const VectorSpace& Ray) const
{
	Vertex V_Point = GetInversection_v_Point(RayOrigin, Ray);

	VectorSpace RayOrig2EllipCenter(  RayOrigin.arr, Center.arr );
	VectorSpace RayOrig2Ellip_Norm;
	RayOrig2Ellip_Norm = RayOrig2EllipCenter;
	RayOrig2Ellip_Norm.DoNormalization();

	VectorSpace RayNorm;
	RayNorm = Ray;
	RayNorm.DoNormalization();

	double c_dot_v  = RayOrig2Ellip_Norm.Dot( RayNorm );

	if( c_dot_v > 0 || Ray.RayNVal != 1 ) // Sphere is not behind the ray origin
	{
		double r = mean_radius;
		double c = RayOrigin.Distance( Center );

		double v = V_Point.Distance( RayOrigin );

		double v2 = pow(v,2);
		double c2 = pow(c,2);
		double r2 = pow(r,2);
		double dSquare = r2 - c2 + v2;

		if( dSquare < 0 )
		{
			return -1;
		}
		else
		{
			double d = sqrt( dSquare );
			double t;

			if( Ray.RayNVal == 1)
			{
				t = v - d;
				return t;
			}
			else
			{
				t = v + d;
				return t;
			}
		}

	}

	return -1;
}
bool VectorSpaceSubSpace::is_compatible(const VectorSpace& another_space) const
{
  if( this->dim() == another_space.dim() && this->is_in_core() && another_space.is_in_core() )
    return true;
  const VectorSpaceSubSpace
    *a_space = dynamic_cast<const VectorSpaceSubSpace*>(&another_space);
  if(!a_space)
    return false;
  return
    ( this->full_space_.get() == NULL && a_space->full_space_.get() == NULL )
    ||
    ( this->rng_ == a_space->rng_ && this->full_space_->is_compatible(*a_space->full_space_) );
}
  IteratesVectorSpace::IteratesVectorSpace(const VectorSpace& x_space, const VectorSpace& s_space,
      const VectorSpace& y_c_space, const VectorSpace& y_d_space,
      const VectorSpace& z_L_space, const VectorSpace& z_U_space,
      const VectorSpace& v_L_space, const VectorSpace& v_U_space
                                          )
      :
      CompoundVectorSpace(8, x_space.Dim() + s_space.Dim()
                          + y_c_space.Dim() + y_d_space.Dim()
                          + z_L_space.Dim() + z_U_space.Dim()
                          + v_L_space.Dim() + v_U_space.Dim()
                         )
  {
    x_space_ = &x_space;
    s_space_ = &s_space;
    y_c_space_ = &y_c_space;
    y_d_space_ = &y_d_space;
    z_L_space_ = &z_L_space;
    z_U_space_ = &z_U_space;
    v_L_space_ = &v_L_space;
    v_U_space_ = &v_U_space;

    this->CompoundVectorSpace::SetCompSpace(0, *x_space_);
    this->CompoundVectorSpace::SetCompSpace(1, *s_space_);
    this->CompoundVectorSpace::SetCompSpace(2, *y_c_space_);
    this->CompoundVectorSpace::SetCompSpace(3, *y_d_space_);
    this->CompoundVectorSpace::SetCompSpace(4, *z_L_space_);
    this->CompoundVectorSpace::SetCompSpace(5, *z_U_space_);
    this->CompoundVectorSpace::SetCompSpace(6, *v_L_space_);
    this->CompoundVectorSpace::SetCompSpace(7, *v_U_space_);
  }
/**********************************************************************
 * Function_Name: RotAxis
 * Return 		:
 * Comments 	:
 **********************************************************************/
int Transformation::RotAxis( double(&Rw)[4][4],  VectorSpace w )
{

	w.DoNormalization();

	VectorSpace m;

	for( int i = 0; i < 3; i++ )
	{
		m.vs[i] = (double)(rand() % 1000)/1000;
	}

	m.DoNormalization();


	VectorSpace u;

	u = w;
	u.CrossProduct(m);
	u.DoNormalization();

	VectorSpace v;
	v = w;
	v.CrossProduct(u);


	// Filling Up Rw
	FillUpRw( Rw, u.vs, v.vs, w.vs);

	CheckRotationMat(Rw);

	return EXIT_SUCCESS;
}
VectorSpace<Type, N> VectorSpace<Type, N>::operator -(const VectorSpace<Type, N>& v2) const
{

	// Vectors should have same size
	VectorSpace<Type, N> result;

	for (int i= v2.MinIndex(); i <= v2.MaxIndex(); ++i)
	{
		result[i] = (*this)[i] - v2[i];
	}

	return result;

}
RCP<GhostImporter<double> > 
EpetraVectorType::createGhostImporter(const VectorSpace<double>& space,
                                      int nGhost,
                                      const int* ghostIndices) const
{
  const EpetraVectorSpace* p 
    = dynamic_cast<const EpetraVectorSpace*>(space.ptr().get());

  TEUCHOS_TEST_FOR_EXCEPTION(p==0, std::runtime_error,
                     "non-epetra vector space [" << space.description() << "] given as "
                     "argument to EpetraVectorType::createGhostImporter()");

  return rcp(new EpetraGhostImporter(p->epetraMap(), nGhost, ghostIndices));
  
}
template <class Scalar> inline
SimpleBlockOp<Scalar>::SimpleBlockOp(
  const VectorSpace<Scalar>& domain,
  const VectorSpace<Scalar>& range)
  : LinearOpWithSpaces<Scalar>(domain, range), blocks_(range.numBlocks())
{
  for (int i=0; i<blocks_.size(); i++) 
  {
    blocks_[i] = Array<LinearOperator<Scalar> >(domain.numBlocks());
    for (int j=0; j<blocks_[i].size(); j++)
    {
      blocks_[i][j] = zeroOperator(domain.getBlock(j), range.getBlock(i));
    }
  }
}
// Premultiplication by a field value
template <typename Type, int N, typename F> VectorSpace<Type, N> 
				operator * (const F& scalar, const VectorSpace<Type, N>& v)
{

	VectorSpace<Type, N> result;

	for (int i= v.MinIndex(); i <= v.MaxIndex(); ++i)
	{
		
		result[i]  = (scalar * v[i]);

	}

	return result;
}
void MatrixSymPosDefLBFGS::init_identity( const VectorSpace& space_diag, value_type alpha )
{
  // Validate input
  TEUCHOS_TEST_FOR_EXCEPTION(
    alpha <= 0.0, std::invalid_argument
    ,"MatrixSymPosDefLBFGS::init_identity(n,alpha) : Error, "
    "alpha = " << alpha << " <= 0 is not allowed!" );
  
  // Set the vector space
  vec_spc_ = space_diag.clone();
  vec_spc_.get();

  // Set storage
  S_ = vec_spc_->create_members(m_);
  Y_ = vec_spc_->create_members(m_);
  TEUCHOS_TEST_FOR_EXCEPT( !( S_.get() ) );
  TEUCHOS_TEST_FOR_EXCEPT( !( Y_.get() ) );
  STY_.resize( m_, m_ );
  STSYTY_.resize( m_+1, m_+1 );
  STSYTY_.diag(0) = 0.0;

  gamma_k_ = 1.0/alpha;

  // Initialize counters
  m_bar_	= 0;

  n_ = vec_spc_->dim();        // initialized;
  original_is_updated_ = true; // This will never change for now
  inverse_is_updated_  = true; // This will never change for now
  num_secant_updates_  = 0;    // reset this to zero
}
Exemple #16
0
ExperimentStorage<S_V,S_M,D_V,D_M>::ExperimentStorage(
  const VectorSpace<S_V,S_M>& scenarioSpace,
  unsigned int                numExperiments)
  :
  m_env                    (scenarioSpace.env()),
  m_scenarioSpace          (scenarioSpace),
  m_paper_n                (numExperiments),
  m_paper_n_ys_transformed (m_paper_n,0),
  m_paper_n_y              (0),
  m_addId                  (0),
  m_scenarioVecs_standard  (m_paper_n, (S_V*) NULL),
  m_dataVecs_transformed   (m_paper_n, (D_V*) NULL),
  m_covMats_transformed_inv(m_paper_n, (D_M*) NULL),
  m_y_space                (NULL),
  m_yVec_transformed       (NULL),
  m_Wy                     (NULL)
{
  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 2)) {
    *m_env.subDisplayFile() << "Entering ExperimentStorage<S_V,S_M,D_V,D_M>::constructor()"
                            << "\n  m_paper_n = " << m_paper_n
                            << std::endl;
  }

  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 2)) {
    *m_env.subDisplayFile() << "Leaving ExperimentStorage<S_V,S_M,D_V,D_M>::constructor()"
                            << std::endl;
  }
}
Exemple #17
0
SmartPtr<Vector> NLPScalingObject::apply_vector_scaling_d_LU_NonConst(
   const Matrix&                 Pd_LU,
   const SmartPtr<const Vector>& lu,
   const VectorSpace&            d_space
   )
{
   DBG_START_METH("NLPScalingObject::apply_vector_scaling_d_LU_NonConst", dbg_verbosity);
   SmartPtr<Vector> scaled_d_LU = lu->MakeNew();
   if( have_d_scaling() )
   {
      SmartPtr<Vector> tmp_d = d_space.MakeNew();

      // move to full d space
      Pd_LU.MultVector(1.0, *lu, 0.0, *tmp_d);

      // scale in full x space
      tmp_d = apply_vector_scaling_d_NonConst(ConstPtr(tmp_d));

      // move back to x_L space
      Pd_LU.TransMultVector(1.0, *tmp_d, 0.0, *scaled_d_LU);
   }
   else
   {
      scaled_d_LU->Copy(*lu);
   }

   return scaled_d_LU;
}
Exemple #18
0
VectorSpace<V,M>::VectorSpace(const VectorSpace<V,M>& aux)
  : VectorSet<V,M>(aux.env(),((std::string)(aux.m_prefix)).c_str(),INFINITY),
    m_dimGlobal(aux.m_dimGlobal),
    m_map(newMap()),
    m_dimLocal(m_map->NumMyElements()),
    m_componentsNamesArray(NULL),
    m_componentsNamesVec(NULL),
    m_emptyComponentName(""),
    m_zeroVector(new V(m_env,*m_map))
{
  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 5)) {
    *m_env.subDisplayFile() << "Entering VectorSpace<V,M>::constructor(2)"
                            << ": aux.m_componentsNamesArray = " << aux.m_componentsNamesArray
                            << ", aux.m_componentsNamesVec = "   << aux.m_componentsNamesVec
                            << std::endl;
  }

  if (aux.m_componentsNamesArray != NULL) {
    m_componentsNamesArray = new DistArray<std::string>(*(aux.m_componentsNamesArray));
  }

  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 5)) {
    *m_env.subDisplayFile() << "Leaving VectorSpace<V,M>::constructor(2)"
                            << std::endl;
  }
}
RCP<GhostImporter<double> > 
SerialVectorType::createGhostImporter(const VectorSpace<double>& space,
                                      int nGhost,
                                      const int* ghostIndices) const
{
  TEUCHOS_TEST_FOR_EXCEPTION(dynamic_cast<const SerialVectorSpace*>(space.ptr().get())==0, std::runtime_error, "expected " 
    << space << " to be a SerialVectorSpace");
  return rcp(new SerialGhostImporter());
}
Exemple #20
0
Array<Vector<double> > vecMaker(int nVecs, int n,
  int nProc, int rank, const VectorType<double>& vecType)
{
  /* This VS will go out of scope when the function is exited, but
   * its vectors will remember it */
  VectorSpace<double> space 
    = vecType.createEvenlyPartitionedSpace(MPIComm::world(), n);

  Rand::setLocalSeed(space.comm(), 314159);

  Array<Vector<double> > rtn(nVecs);
  for (int i=0; i<rtn.size(); i++)
  {
    rtn[i] = space.createMember();
    rtn[i].randomize();
  }
  return rtn;

}
Array<Vector<double> > vecMaker(int nVecs,
  int nProc, int rank, const VectorType<double>& vecType)
{
  int n1 = 3;
  int n2 = 4;
  int n3 = 2;
  int n4 = 5;
  int n5 = 6;
  int n6 = 4;

  /* This VS will go out of scope when the function is exited, but
   * its vectors will remember it */
  VectorSpace<double> vs1 
    = vecType.createEvenlyPartitionedSpace(MPIComm::world(), n1);
  VectorSpace<double> vs2 
    = vecType.createEvenlyPartitionedSpace(MPIComm::world(), n2);
  VectorSpace<double> vs3 
    = vecType.createEvenlyPartitionedSpace(MPIComm::world(), n3);
  VectorSpace<double> vs4 
    = vecType.createEvenlyPartitionedSpace(MPIComm::world(), n4);
  VectorSpace<double> vs5 
    = vecType.createEvenlyPartitionedSpace(MPIComm::world(), n5);
  VectorSpace<double> vs6
    = vecType.createEvenlyPartitionedSpace(MPIComm::world(), n6);

  VectorSpace<double> vs 
    = blockSpace(vs1, blockSpace(vs2, blockSpace(vs3, vs4)), 
      blockSpace(vs5, vs6));

  Out::root() << "space = " << vs << endl;

  Rand::setLocalSeed(vs.comm(), 314159);

  Array<Vector<double> > rtn(nVecs);
  for (int i=0; i<rtn.size(); i++)
  {
    rtn[i] = vs.createMember();
    rtn[i].randomize();
  }
  return rtn;
}
Exemple #22
0
ArrayOfOneDTables<V,M>::ArrayOfOneDTables(
  const char* prefix, 
  const VectorSpace<V,M>& rowSpace)
  :
  m_env       (rowSpace.env()),
  m_prefix    ((std::string)(prefix)+""),
  m_rowSpace  (rowSpace      ),
  m_oneDTables(m_rowSpace.map(),1)
{
  for (unsigned int i = 0; i < (unsigned int) m_oneDTables.MyLength(); ++i) {
    m_oneDTables(i,0) = NULL;
  }
}
RCP<MatrixFactory<double> >
EpetraVectorType::createMatrixFactory(const VectorSpace<double>& domain,
                                      const VectorSpace<double>& range) const
{
  RCP<const EpetraVectorSpace> pd 
    = rcp_dynamic_cast<const EpetraVectorSpace>(domain.ptr());

  RCP<const EpetraVectorSpace> pr 
    = rcp_dynamic_cast<const EpetraVectorSpace>(range.ptr());


  TEUCHOS_TEST_FOR_EXCEPTION(pd.get()==0, std::runtime_error, 
                     "incompatible domain space given to "
                     "EpetraVectorType::createMatrix()");

  TEUCHOS_TEST_FOR_EXCEPTION(pr.get()==0, std::runtime_error, 
                     "incompatible range space given to "
                     "EpetraVectorType::createMatrix()");

  //  RCP<SingleScalarTypeOp<double> > A = rcp(new EpetraMatrix(pd, pr));

  return rcp(new EpetraMatrixFactory(pd, pr));
}
PartitionedMatrixFactory::PartitionedMatrixFactory(
  const VectorSpace<double>& domain,
  int lowestLocalCol,
  const RCP<Array<int> >& isBCCol,
  const RCP<std::set<int> >& remoteBCCols,
  const VectorType<double>& domainVecType,
  const VectorSpace<double>& range,
  int lowestLocalRow,
  const RCP<Array<int> >& isBCRow,
  const VectorType<double>& rangeVecType
  )
  : 
  domain_(domain),
  internalDomain_(domain.getBlock(0)),
  bcDomain_(domain.getBlock(1)),
  isBCCol_(isBCCol),
  remoteBCCols_(remoteBCCols),
  domainVecType_(domainVecType),
  lowestLocalCol_(lowestLocalCol),
  highestLocalCol_(-1),
  range_(range),
  internalRange_(range.getBlock(0)),
  bcRange_(range.getBlock(1)),
  isBCRow_(isBCRow),
  rangeVecType_(rangeVecType),
  lowestLocalRow_(lowestLocalRow),
  highestLocalRow_(-1),
  blockFactory_(2),
  blockICMF_(2)
{
  highestLocalCol_ = lowestLocalCol_ + domain.numLocalElements();
  highestLocalRow_ = lowestLocalRow_ + range.numLocalElements();

  blockFactory_[0].resize(2);
  blockFactory_[1].resize(2);
  
  blockFactory_[0][0] = rangeVecType_.createMatrixFactory(internalDomain_, internalRange_);

  blockFactory_[0][1] = rangeVecType_.createMatrixFactory(bcDomain_, internalRange_);

  blockFactory_[1][1] = rangeVecType_.createMatrixFactory(bcDomain_, bcRange_);

  for (int i=0; i<2; i++)
  {
    blockICMF_[i].resize(2);
    for (int j=0; j<2; j++)
    {
      if (i==1 && j==0) continue;
      IncrementallyConfigurableMatrixFactory* icmf 
        = dynamic_cast<IncrementallyConfigurableMatrixFactory*>(blockFactory_[i][j].get());
      TEST_FOR_EXCEPTION(icmf==0, std::runtime_error,
        "block(" << i << ", " << j << ") is not an ICMF");
      blockICMF_[i][j] = icmf;
    }
  }
  
}
Exemple #25
0
ArrayOfOneDGrids<V,M>::ArrayOfOneDGrids(
  const char*                    prefix,
  const VectorSpace<V,M>& rowSpace)
  :
  m_env         (rowSpace.env()    ),
  m_prefix      ((std::string)(prefix)+""),
  m_rowSpace    (rowSpace          ),
  m_oneDGrids   (m_rowSpace.map(),1),
  m_sizes       (NULL),
  m_minPositions(NULL),
  m_maxPositions(NULL)
{
  for (unsigned int i = 0; i < (unsigned int) m_oneDGrids.MyLength(); ++i) {
    m_oneDGrids(i,0) = NULL;
  }
}
Exemple #26
0
BaseTKGroup<V,M>::BaseTKGroup(
  const char*                    prefix,
  const VectorSpace<V,M>& vectorSpace,
  const std::vector<double>&     scales)
  :
  m_emptyEnv             (NULL),
  m_env                  (vectorSpace.env()),
  m_prefix               (prefix),
  m_vectorSpace          (&vectorSpace),
  m_scales               (scales.size(),1.),
  m_preComputingPositions(scales.size()+1,NULL), // Yes, +1
  m_rvs                  (scales.size(),NULL) // IMPORTANT: it stays like this for scaledTK, but it will be overwritten to '+1' by hessianTK constructor
{
  for (unsigned int i = 0; i < m_scales.size(); ++i) {
    m_scales[i] = scales[i];
  }
}
Exemple #27
0
  SmartPtr<Vector> NLPScalingObject::apply_vector_scaling_x_LU_NonConst(
    const Matrix& Px_LU,
    const SmartPtr<const Vector>& lu,
    const VectorSpace& x_space)
  {
    SmartPtr<Vector> scaled_x_LU = lu->MakeNew();
    if (have_x_scaling()) {
      SmartPtr<Vector> tmp_x = x_space.MakeNew();

      // move to full x space
      Px_LU.MultVector(1.0, *lu, 0.0, *tmp_x);

      // scale in full x space
      tmp_x = apply_vector_scaling_x_NonConst(ConstPtr(tmp_x));

      // move back to x_L space
      Px_LU.TransMultVector(1.0, *tmp_x, 0.0, *scaled_x_LU);
    }
    else {
      scaled_x_LU->Copy(*lu);
    }

    return scaled_x_LU;
  }
int main(int argc, char *argv[]) 
{
  int stat = 0;
  try
    {
      GlobalMPISession session(&argc, &argv);
 
      /* create a distributed vector space for the multivector's vectors */
      VectorType<double> rowType = new EpetraVectorType();
      int nLocalRows = 2;
      VectorSpace<double> space 
        = rowType.createEvenlyPartitionedSpace(MPIComm::world(), nLocalRows);
      
      /* create a replicated vector space for the small space of columns */
      int nVecs = 3;
      VectorType<double> colType = new SerialVectorType();
      VectorSpace<double> replSpace 
        = colType.createEvenlyPartitionedSpace(MPIComm::world(), nVecs);

      /* create some random vectors */
      Teuchos::Array<Vector<double> > vecs(nVecs);
      for (int i=0; i<nVecs; i++)
      {
        vecs[i] = space.createMember();
        vecs[i].randomize();
      }

      /* Test multiplication by a multivector operator. We will compute
       * y1 by directly summing columns, and y2 by applying the operator */
      LinearOperator<double> A = multiVectorOperator<double>(vecs, replSpace);

      
      Vector<double> y1 = space.createMember();
      Vector<double> y2 = space.createMember();
      y1.zero(); 
      y2.zero(); 
      

      /* Sum columns, putting the weights into x */
      Vector<double> x = replSpace.createMember();

      Out::os() << "A=" << A << std::endl;
      
      for (int j=0; j<replSpace.numLocalElements(); j++)
        {
          
          x[j] = 2.0*(drand48()-0.5);
          y1 = y1 + x[j] * vecs[j];
          Out::os() << "x[" << j << "]=" << x[j] << std::endl;
          Out::os() << "vecs[j]=" << vecs[j] << std::endl;
        }  
      Out::os() << "y1=" << std::endl << y1 << std::endl;
      
      /* Apply the operator to the vector of weights */
      y2 = A * x;
      Out::os() << "y2=A*x=" << std::endl << y2 << std::endl;

      Vector<double> y12 = y1-y2;
      Vector<double> y21 = y2-y1;
      Out::os() << "y1-y2=" << std::endl << y12 << std::endl;
      Out::os() << "y2-y1=" << std::endl << y21 << std::endl;
      
      double errA = (y1-y2).norm2();

      Out::root() << "error in A*x = " << errA << std::endl;


      /* Now test z = A^T * y */
      LinearOperator<double> At = A.transpose();
      
      Vector<double> z1 = replSpace.createMember();
      z1.zero();
      Vector<double> z2 = replSpace.createMember();
      z2.zero();

      Vector<double> y = y1.copy();

      /* compute by vectorwise multiplication */
      for (int j=0; j<replSpace.numLocalElements(); j++)
      {
        z1[j] = vecs[j].dot(y);
      }
      /* compute with operator */
      z2 = At * y;
      

      double errAt = (z1-z2).normInf();
      Out::root() << "error in At*y = " << errA << std::endl;

      double tol = 1.0e-13;
      bool pass = errA + errAt < tol;
      pass = globalAnd(pass);
      if (pass)
        {
          Out::root() << "multivector op test PASSED" << std::endl;
        }
      else
        {
          stat = -1;
          Out::root() << "multivector op test FAILED" << std::endl;
        }
    }
  catch(std::exception& e)
    {
      stat = -1;
      std::cerr << "Caught exception: " << e.what() << std::endl;
    }
  return stat;
}
int main(int argc, char *argv[]) 
{
  int stat = 0;
  try
  {
    GlobalMPISession session(&argc, &argv);
    MPIComm::world().synchronize();

    Out::os() << "go!" << std::endl;
    VectorType<double> type = new EpetraVectorType();

    Array<int> domainBlockSizes = tuple(2,3,4);
    Array<int> rangeBlockSizes = tuple(2,2);

    Array<VectorSpace<double> > domainBlocks(domainBlockSizes.size());
    Array<VectorSpace<double> > rangeBlocks(rangeBlockSizes.size());

    for (int i=0; i<domainBlocks.size(); i++)
    {
      domainBlocks[i] = type.createEvenlyPartitionedSpace(MPIComm::world(),
        domainBlockSizes[i]);
    }

    for (int i=0; i<rangeBlocks.size(); i++)
    {
      rangeBlocks[i] = type.createEvenlyPartitionedSpace(MPIComm::world(),
        rangeBlockSizes[i]);
    }
      
    VectorSpace<double> domain = blockSpace(domainBlocks);
    VectorSpace<double> range = blockSpace(rangeBlocks);

    double blockDensity = 0.75;
    double onProcDensity = 0.5;
    double offProcDensity = 0.1;
      
    RandomBlockMatrixBuilder<double> builder(domain, range, 
      blockDensity,
      onProcDensity,
      offProcDensity,
      type);

    LinearOperator<double> A = builder.getOp();

    Out::os() << "A num block rows = " << A.numBlockRows() << std::endl;
    Out::os() << "A num block cols = " << A.numBlockCols() << std::endl;

    Vector<double> x = domain.createMember();
    Out::os() << "randomizing trial vector" << std::endl;
    x.randomize();

    Array<Vector<double> > xBlock(domain.numBlocks());
    for (int i=0; i<xBlock.size(); i++)
    {
      xBlock[i] = x.getBlock(i);
    }

    Vector<double> xx = x.copy();

      

    Out::os() << "------------------------------------------------------------" << std::endl;
    Out::os() << "computing A*x..." << std::endl;
    Vector<double> y0 = A * x;
    for (int i=0; i<y0.space().numBlocks(); i++)
    {
      Out::os() << "y0[" << i << "] = " << std::endl << y0.getBlock(i) << std::endl;
    }
      

    Vector<double> y1 = range.createMember();
    Out::os() << "------------------------------------------------------------" << std::endl;
    Out::os() << "computing A*x block-by-block..." << std::endl;
    Array<Vector<double> > yBlock(range.numBlocks());
    for (int i=0; i<yBlock.size(); i++)
    {
      yBlock[i] = range.getBlock(i).createMember();
      yBlock[i].zero();
      for (int j=0; j<xBlock.size(); j++)
      {
        LinearOperator<double> Aij = A.getBlock(i,j);
        if (Aij.ptr().get() != 0)
        {
          Out::os() << "A(" << i << ", " << j << ") = " << std::endl 
                    << Aij << std::endl;
        }
        else
        {
          Out::os() << "A(" << i << ", " << j << ") = 0 " << std::endl;
        }
        Out::os() << "x[" << j << "] = " << std::endl << xBlock[j] << std::endl;
        if (Aij.ptr().get()==0) continue;
        yBlock[i] = yBlock[i] + Aij * xBlock[j];
      }
      y1.setBlock(i, yBlock[i]);
    }

    for (int i=0; i<y1.space().numBlocks(); i++)
    {
      Out::os() << "y1[" << i << "] = " << std::endl << y1.getBlock(i) << std::endl;
    }
    double err = (y1 - y0).norm2();
    Out::os() << "error = " << err << std::endl;

    double tol = 1.0e-13;
    if (err < tol)
    {
      Out::os() << "block op test PASSED" << std::endl;
    }
    else
    {
      stat = -1;
      Out::os() << "block op test FAILED" << std::endl;
    }
  }
  catch(std::exception& e)
  {
    stat = -1;
    Out::os() << "Caught exception: " << e.what() << std::endl;
  }
  return stat;
}
 MultiVectorMatrixSpace::MultiVectorMatrixSpace(Index ncols,
     const VectorSpace& vec_space)
     :
     MatrixSpace(vec_space.Dim(), ncols),
     vec_space_(&vec_space)
 {}