コード例 #1
0
ファイル: matrix.c プロジェクト: epakai/r_matrix
struct rational determinant(struct matrix M){
	set_error(NONE);
	struct rational det = int_to_r(0);
	if (M.rows == M.columns) {
		if(M.rows > 2) {
			for(int i=1; i<= M.rows; i++) {
				//alternate adding and subtracting
				if ((i%2) == 1 ) {
					struct matrix pos_subm = submatrix(M,i,1);
					det = r_add(det, r_multiply(get_element(M,i,1), determinant(pos_subm)));
					free_matrix(pos_subm);
				} else {
					struct matrix neg_subm = submatrix(M,i,1);
					det = r_subtract(det, r_multiply(get_element(M,i,1), determinant(neg_subm)));
					free_matrix(neg_subm);
				}
			}
		}
		if(M.rows == 2) {
			det = r_subtract (	r_multiply(get_element(M,1,1), get_element(M,2,2)),
								r_multiply(get_element(M,1,2), get_element(M,2,1)));
		}
		if(M.rows == 1) {
			det = get_element(M,1,1);
		}
	} else {
		det = int_to_r(-1);
		set_error(INCOMPATIBLE_MATRIX);
	}
	return det;
}
コード例 #2
0
ファイル: matrix.c プロジェクト: epakai/r_matrix
struct rational cofactor (struct matrix M, int row, int column){
	//TODO: test function
	
	if ((row%2) == (column%2)) {
		return(determinant(submatrix(M,row,column)));
	} else {
		return(r_multiply(int_to_r(-1), determinant(submatrix(M,row,column))));
	}
}
コード例 #3
0
Matrix<typename std::result_of<UnaryMatrixOperator(Matrix<ValueT>)>::type>
Matrix<ValueT>::unary_map(UnaryMatrixOperator &op) const
{
    typedef typename std::result_of<UnaryMatrixOperator(Matrix<ValueT>)>::type ReturnT;
    if (n_cols * n_rows == 0)
        return Matrix<ReturnT>(0, 0);

    Matrix<ReturnT> tmp(n_rows, n_cols);

    const auto radius = op.radius;
    const auto size = 2 * radius + 1;

    const auto start_i = radius;
    const auto end_i = n_rows - radius;
    const auto start_j = radius;
    const auto end_j = n_cols - radius;


    for (uint i = start_i; i < end_i; ++i) {
        for (uint j = start_j; j < end_j; ++j) {
            auto neighbourhood = submatrix(i - radius, j - radius, size, size);
            tmp(i, j) = op(neighbourhood);
        }
    }
    return tmp;
}
コード例 #4
0
ファイル: triangle.cpp プロジェクト: falceeffect/FRay
bool Triangle::intersect(const Ray& r, LocalGeometry& lgeo) {
    Mat4 TInv = this->transform.inverse();
    Vec3 dir = as_vec3(TInv*as_vec4(r.direction));
    Vec4 origin = TInv*r.origin;


    if (cross(dir, normal).is_zero())
        return false;

    double t = dot(as_vec3(origin-A), normal)/dot(dir, normal);

    if (t < 0.0)
        return false;
    else {
        Vec4 point = origin + (as_vec4(dir) * t);

        Vec3 bar_coords = barycentric_coordinates(A, B, C, point);

        double alpha = bar_coords.el(0);
        double beta = bar_coords.el(1);
        double gamma = bar_coords.el(2);

        if (alpha < 0.0 || beta < 0.0 || gamma < 0.0)
            return false;

        else {
            lgeo.normal = submatrix(transform).inverse().transpose() * normal;
            lgeo.point = transform * point;
            lgeo.geo = this;
            return true;
        }
    }
}
コード例 #5
0
ファイル: proj3.c プロジェクト: MKontra/projects-fit
int
main (int argc, char *argv[])
{
  int code;
  TParams tp = {.mat1.add = NULL,.mat2.add = NULL };
  if ((code = processParams (&tp, argc, argv)) != RET_OK)
    {
      errmsg (code);
      return EXIT_FAILURE;
    };
  switch (tp.function)
    {
    case 0:
      errmsg (RET_OK);
      break;
    case 1:
      code = sucet (&(tp.mat1), &(tp.mat2));
      break;
    case 2:
      code = sucin (&(tp.mat1), &(tp.mat2));
      break;
    case 3:
      code = submatrix (&(tp.mat1), &(tp.mat2));
      break;
    case 4:
      code = crot (&(tp.mat1));
      break;
    case 5:
      code = plough (&(tp.mat1));
      break;
    case 6:
      code = sudoku (&(tp.mat1));
      break;
    default:
      return EXIT_FAILURE;
    }

  if (tp.mat1.add != NULL)
    {
      freeMat (&(tp.mat1));
    }


  if (tp.mat2.add != NULL)
    {
      freeMat (&(tp.mat2));
    }


  if (code != RET_OK)
    {
      errmsg (code);
      return EXIT_FAILURE;
    }

  return EXIT_SUCCESS;
}
コード例 #6
0
ファイル: DenseFeatures.cpp プロジェクト: cwidmer/shogun
template<class ST> SGMatrix<ST> CDenseFeatures<ST>::get_feature_matrix()
{
	if (!m_subset_stack->has_subsets())
		return feature_matrix;

	SGMatrix<ST> submatrix(num_features, get_num_vectors());

	/* copy a subset vector wise */
	for (int32_t i=0; i<submatrix.num_cols; ++i)
	{
		int32_t real_i = m_subset_stack->subset_idx_conversion(i);
		memcpy(&submatrix.matrix[i*int64_t(num_features)],
				&feature_matrix.matrix[real_i * int64_t(num_features)],
				num_features * sizeof(ST));
	}

	return submatrix;
}
コード例 #7
0
ファイル: square_matrix.cpp プロジェクト: duplyakin/CppCourse
Matrix Matrix::submatrix(size_t row, size_t col) {
  Matrix submatrix(m_size - 1);
  size_t rk = 0;
  for (size_t r = 0; r < m_size; ++r) {
    if (r == row) {
      rk = -1;
      continue;
    }
    submatrix.m_data[r + rk] = new Matrix::value_type[m_size];
    size_t ck = 0;
    for (size_t c = 0; c < m_size; ++c) {
      if (c == col) {
        ck = -1;
        continue;
      }
      submatrix.m_data[r + rk][c + ck] = m_data[r][c];
    }
  }
  return submatrix;
}
コード例 #8
0
ファイル: test_matrices.c プロジェクト: RobotXiaoFeng/acado
/** Test matrix classes */
int main()
{
	hilbert();
	submatrix();
	sumOfSquares();
	indexDenseSubmatrix();

	spGetCol();
	spGetRow();
	spTimes();
	spIndTimes();

	sprGetCol();
	sprGetRow();
	sprTimes();
	sprIndTimes();

	Symmetry();

	return 0;
}
コード例 #9
0
ファイル: matrix.c プロジェクト: epakai/r_matrix
struct rational first_minor(struct matrix M, int row, int column){
	//TODO: test function
	return  determinant(submatrix(M,row,column));
}
コード例 #10
0
ファイル: fbnn.cpp プロジェクト: AthrunArthur/ffsae
  //trains a neural net
  void FBNN::train(const FMatrix & train_x, const FMatrix & train_y, const Opts & opts, const FMatrix & valid_x, const FMatrix & valid_y, const FBNN_ptr pFBNN)
  {
      int ibatchNum = train_x.rows() / opts.batchsize + (train_x.rows() % opts.batchsize != 0);
      FMatrix L = zeros(opts.numpochs * ibatchNum, 1);
      m_oLp = std::make_shared<FMatrix>(L);
      Loss loss;
//       std::cout << "numpochs = " << opts.numpochs << std::endl;
      for(int i = 0; i < opts.numpochs; ++i)
      {
	  std::cout << "start numpochs " << i << std::endl;	  
	  int elapsedTime = count_elapse_second([&train_x,&train_y,&L,&opts,i,pFBNN,ibatchNum,this]{
	    std::vector<int> iRandVec;
            randperm(train_x.rows(),iRandVec);
            std::cout << "start batch: ";
            for(int j = 0; j < ibatchNum; ++j)
            {
                std::cout << " " << j;
                if(pFBNN)//pull
                {
// 		    TMutex::scoped_lock lock;
// 		    lock.acquire(pFBNN->W_RWMutex,false);
// 		    lock.release();//reader lock tbb
		    boost::shared_lock<RWMutex> rlock(pFBNN->W_RWMutex);		    
                    set_m_oWs(pFBNN->get_m_oWs());
                    if(m_fMomentum > 0)
                        set_m_oVWs(pFBNN->get_m_oVWs());
		    rlock.unlock();
                }
                int curBatchSize = opts.batchsize;
                if(j == ibatchNum - 1 && train_x.rows() % opts.batchsize != 0)
                    curBatchSize = train_x.rows() % opts.batchsize;
                FMatrix batch_x(curBatchSize,train_x.columns());
                for(int r = 0; r < curBatchSize; ++r)//randperm()
                    row(batch_x,r) = row(train_x,iRandVec[j * opts.batchsize + r]);

                //Add noise to input (for use in denoising autoencoder)
                if(m_fInputZeroMaskedFraction != 0)
                    batch_x = bitWiseMul(batch_x,(rand(curBatchSize,train_x.columns())>m_fInputZeroMaskedFraction));

                FMatrix batch_y(curBatchSize,train_y.columns());
                for(int r = 0; r < curBatchSize; ++r)//randperm()
                    row(batch_y,r) = row(train_y,iRandVec[j * opts.batchsize + r]);

                L(i*ibatchNum+j,0) = nnff(batch_x,batch_y);
                nnbp();
                nnapplygrads();
                if(pFBNN)//push
                {
// 		    TMutex::scoped_lock lock;
// 		    lock.acquire(W_RWMutex);
// 		    lock.release();//writer lock tbb
		    boost::unique_lock<RWMutex> wlock(pFBNN->W_RWMutex);
                    pFBNN->set_m_odWs(m_odWs);
                    pFBNN->nnapplygrads();
		    wlock.unlock();
                }
// 	      std::cout << "end batch " << j << std::endl;
            }
            std::cout << std::endl;
	  });
	  std::cout << "elapsed time: " << elapsedTime << "s" << std::endl;
	  //loss calculate use nneval
	  if(valid_x.rows() == 0 || valid_y.rows() == 0){
	    nneval(loss, train_x, train_y);
	    std::cout << "Full-batch train mse = " << loss.train_error.back() << std::endl;
	  }
	  else{
	    nneval(loss, train_x, train_y, valid_x, valid_y);
	    std::cout << "Full-batch train mse = " << loss.train_error.back() << " , val mse = " << loss.valid_error.back() << std::endl;
	  }
	  std::cout << "epoch " << i+1 << " / " <<  opts.numpochs << " took " << elapsedTime << " seconds." << std::endl;
	  std::cout << "Mini-batch mean squared error on training set is " << columnMean(submatrix(L,i*ibatchNum,0UL,ibatchNum,L.columns())) << std::endl;      
	  m_iLearningRate *= m_fScalingLearningRate;    
	  
// 	  std::cout << "end numpochs " << i << std::endl;
      }

  }
コード例 #11
0
bool HomotopyConcrete< RT, FixedPrecisionHomotopyAlgorithm >::track(const MutableMatrix* inputs, MutableMatrix* outputs, 
                     MutableMatrix* output_extras,  
                     gmp_RR init_dt, gmp_RR min_dt,
                     gmp_RR epsilon, // o.CorrectorTolerance,
                     int max_corr_steps, 
                     gmp_RR infinity_threshold
                   ) 
{
  std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
  size_t solveLinearTime = 0, solveLinearCount = 0, evaluateTime = 0;
 
  // std::cout << "inside HomotopyConcrete<RT,FixedPrecisionHomotopyAlgorithm>::track" << std::endl;
  // double the_smallest_number = 1e-13;
  const Ring* matRing = inputs->get_ring();
  if (outputs->get_ring()!= matRing) { 
    ERROR("outputs and inputs are in different rings");
    return false;
  }
  auto inp = dynamic_cast<const MutableMat< DMat<RT> >*>(inputs);
  auto out = dynamic_cast<MutableMat< DMat<RT> >*>(outputs);
  auto out_extras = dynamic_cast<MutableMat< DMat<M2::ARingZZGMP> >*>(output_extras);
  if (inp == nullptr) { 
    ERROR("inputs: expected a dense mutable matrix");
    return false;
  }
  if (out == nullptr) { 
    ERROR("outputs: expected a dense mutable matrix");
    return false;
  }
  if (out_extras == nullptr) { 
    ERROR("output_extras: expected a dense mutable matrix");
    return false;
  }

  auto& in = inp->getMat();
  auto& ou = out->getMat();
  auto& oe = out_extras->getMat();
  size_t n_sols = in.numColumns();  
  size_t n = in.numRows()-1; // number of x vars

  if (ou.numColumns() != n_sols or ou.numRows() != n+2) { 
    ERROR("output: wrong shape");
    return false;
  }
  if (oe.numColumns() != n_sols or oe.numRows() != 2) { 
    ERROR("output_extras: wrong shape");
    return false;
  }
  
  const RT& C = in.ring();  
  typename RT::RealRingType R = C.real_ring();  

  typedef typename RT::ElementType ElementType;
  typedef typename RT::RealRingType::ElementType RealElementType;
  typedef MatElementaryOps< DMat< RT > > MatOps;
 
  RealElementType t_step;
  RealElementType min_step2;
  RealElementType epsilon2;
  RealElementType infinity_threshold2;
  R.init(t_step);
  R.init(min_step2);
  R.init(epsilon2);
  R.init(infinity_threshold2);
  R.set_from_BigReal(t_step,init_dt); // initial step
  R.set_from_BigReal(min_step2,min_dt);
  R.mult(min_step2, min_step2, min_step2); //min_step^2
  R.set_from_BigReal(epsilon2,epsilon); 
  int tolerance_bits = -R.log2abs(epsilon2);  
  R.mult(epsilon2, epsilon2, epsilon2); //epsilon^2
  R.set_from_BigReal(infinity_threshold2,infinity_threshold); 
  R.mult(infinity_threshold2, infinity_threshold2, infinity_threshold2);
  int num_successes_before_increase = 3;

  RealElementType t0,dt,one_minus_t0,dx_norm2,x_norm2,abs2dc;
  R.init(t0);
  R.init(dt);
  R.init(one_minus_t0);
  R.init(dx_norm2);
  R.init(x_norm2);
  R.init(abs2dc);
  
  // constants
  RealElementType one,two,four,six,one_half,one_sixth;
  RealElementType& dt_factor = one_half; 
  R.init(one);
  R.set_from_long(one,1);    
  R.init(two);
  R.set_from_long(two,2);    
  R.init(four);
  R.set_from_long(four,4);
  R.init(six);
  R.set_from_long(six,6);    
  R.init(one_half);
  R.divide(one_half,one,two);
  R.init(one_sixth);
  R.divide(one_sixth,one,six);

  ElementType c_init,c_end,dc,one_half_dc;
  C.init(c_init);
  C.init(c_end);
  C.init(dc);
  C.init(one_half_dc);

  // think: x_0..x_(n-1), c
  // c = the homotopy continuation parameter "t" upstair, varies on a (staight line) segment of complex plane (from c_init to c_end)  
  // t = a real running in the interval [0,1] 

  DMat<RT> x0c0(C,n+1,1); 
  DMat<RT> x1c1(C,n+1,1);
  DMat<RT> xc(C,n+1,1);
  DMat<RT> HxH(C,n,n+1);
  DMat<RT>& Hxt = HxH; // the matrix has the same shape: reuse memory  
  DMat<RT> LHSmat(C,n,n);
  auto LHS = submatrix(LHSmat); 
  DMat<RT> RHSmat(C,n,1);
  auto RHS = submatrix(RHSmat); 
  DMat<RT> dx(C,n,1);
  DMat<RT> dx1(C,n,1);
  DMat<RT> dx2(C,n,1);
  DMat<RT> dx3(C,n,1);
  DMat<RT> dx4(C,n,1);
  DMat<RT> Jinv_times_random(C,n,1);

  ElementType& c0 = x0c0.entry(n,0);
  ElementType& c1 = x1c1.entry(n,0);  
  ElementType& c = xc.entry(n,0);
  RealElementType& tol2 = epsilon2; // current tolerance squared
  bool linearSolve_success;
  for(size_t s=0; s<n_sols; s++) {
    SolutionStatus status = PROCESSING;
    // set initial solution and initial value of the continuation parameter
    //for(size_t i=0; i<=n; i++)   
    //  C.set(x0c0.entry(i,0), in.entry(i,s));
    submatrix(x0c0) = submatrix(const_cast<DMat<RT>&>(in), 0,s, n+1,1); 
    C.set(c_init,c0);
    C.set(c_end,ou.entry(n,s));

    R.set_zero(t0);
    bool t0equals1 = false;

    // t_step is actually the initial (absolute) length of step on the interval [c_init,c_end]
    // dt is an increment for t on the interval [0,1]
    R.set(dt,t_step);
    C.subtract(dc,c_end,c_init); 
    C.abs(abs2dc,dc); // don't wnat to create new temporary elts: reusing dc and abs2dc
    R.divide(dt,dt,abs2dc);

    int predictor_successes = 0;
    int count = 0; // number of steps
    // track the real segment (1-t)*c0 + t*c1, a\in [0,1]
    while (status == PROCESSING and not t0equals1) {
      if (M2_numericalAlgebraicGeometryTrace>3) {
        buffer o; 
        R.elem_text_out(o,t0,true,false,false);
        std::cout << "t0 = " << o.str();
        o.reset();
        C.elem_text_out(o,c0,true,false,false);
        std::cout << ", c0 = " << o.str() << std::endl;
      }
      R.subtract(one_minus_t0,one,t0);
      if (R.compare_elems(dt,one_minus_t0)>0) {
        R.set(dt,one_minus_t0);
        t0equals1 = true;
        C.subtract(dc,c_end,c0);
        C.set(c1,c_end);
      } else {
        C.subtract(dc,c_end,c0);
        C.mult(dc,dc,dt);
        C.divide(dc,dc,one_minus_t0);
        C.add(c1,c0,dc);
      }
      
      // PREDICTOR in: x0c0,dt
      //           out: dx
      /*  top-level code for Runge-Kutta-4 
          dx1 := solveHxTimesDXequalsMinusHt(x0,t0);
          dx2 := solveHxTimesDXequalsMinusHt(x0+(1/2)*dx1*dt,t0+(1/2)*dt);
          dx3 := solveHxTimesDXequalsMinusHt(x0+(1/2)*dx2*dt,t0+(1/2)*dt);
          dx4 := solveHxTimesDXequalsMinusHt(x0+dx3*dt,t0+dt);
          (1/6)*dt*(dx1+2*dx2+2*dx3+dx4)      
      */                    

      C.mult(one_half_dc, dc, one_half);

      // dx1
      submatrix(xc) = submatrix(x0c0);
      TIME(evaluateTime,
           mHxt.evaluate(xc,Hxt)
           )

      LHS = submatrix(Hxt, 0,0, n,n);
      RHS = submatrix(Hxt, 0,n, n,1);
      MatrixOps::negateInPlace(RHSmat);

      TIME(solveLinearTime,
           linearSolve_success = MatrixOps::solveLinear(LHSmat,RHSmat,dx1)
           );
      solveLinearCount++;

      // dx2
      if (linearSolve_success) { 
        submatrix(dx1) *= one_half_dc; // "dx1" := (1/2)*dx1*dt
        submatrix(xc, 0,0, n,1) += submatrix(dx1); 
        C.add(c,c,one_half_dc); 
       
        TIME(evaluateTime,
             mHxt.evaluate(xc,Hxt)
             )

        LHS = submatrix(Hxt, 0,0, n,n);
        RHS = submatrix(Hxt, 0,n, n,1);
        MatrixOps::negateInPlace(RHSmat);

        TIME(solveLinearTime,
             linearSolve_success = MatrixOps::solveLinear(LHSmat,RHSmat,dx2);
             )
        solveLinearCount++;
      }

      // dx3
      if (linearSolve_success) { 
        submatrix(dx2) *= one_half_dc; // "dx2" := (1/2)*dx2*dt
        submatrix(xc, 0,0, n,1) = submatrix(x0c0,  0,0, n,1);
        submatrix(xc, 0,0, n,1) += submatrix(dx2);
        // C.add(c,c,one_half_dc); // c should not change here??? or copy c two lines above??? 
       
        TIME(evaluateTime,
             mHxt.evaluate(xc,Hxt)
             );

        LHS = submatrix(Hxt, 0,0, n,n);
        RHS = submatrix(Hxt, 0,n, n,1);
        MatrixOps::negateInPlace(RHSmat);

        TIME(solveLinearTime,
             linearSolve_success = MatrixOps::solveLinear(LHSmat,RHSmat,dx3);
             );
        solveLinearCount++;
      }

      // dx4
      if (linearSolve_success) { 
        submatrix(dx3) *= dc; // "dx3" := dx3*dt
        submatrix(xc) = submatrix(x0c0); // sets c=c0 as well (not needed for dx2???,dx3)
        submatrix(xc, 0,0, n,1) += submatrix(dx3); 
        C.add(c,c,dc);

        TIME(evaluateTime,
             mHxt.evaluate(xc,Hxt)
             );

        LHS = submatrix(Hxt, 0,0, n,n);
        RHS = submatrix(Hxt, 0,n, n,1);
        MatrixOps::negateInPlace(RHSmat);

        TIME(solveLinearTime,
             linearSolve_success = MatrixOps::solveLinear(LHSmat,RHSmat,dx4);
             );
        solveLinearCount++;
      }
コード例 #12
0
END_TEST

/*
START_TEST(test_qrsolve_consistency) {
  u32 i, j, t;
  double norm;

  seed_rng();
  for (t = 0; t < LINALG_NUM; t++) {
    u32 n = sizerand(MSIZE_MAX);
    double x_gauss[n], x_qr[n];
    double A[n*n], Ainv[n*n], b[n];
    do {
      for (i = 0; i < n; i++) {
        b[i] = mrand;
        for (j = 0; j < n; j++)
          A[n*i + j] = mrand;
      }
    } while (matrix_inverse(n, A, Ainv) < 0);
    matrix_multiply(n, n, 1, Ainv, b, x_gauss);
    qrsolve(A, n, n, b, x_qr);

    norm = (vector_norm(n, x_qr) + vector_norm(n, x_gauss)) / 2;
    for (i = 0; i < n; i++)
      fail_unless(fabs(x_qr[i] - x_gauss[i]) < LINALG_TOL * norm,
                  "QR solve failure; difference was %lf for element %u",
                  x_qr[i] - x_gauss[i], i);
  }
}
END_TEST

START_TEST(test_qrsolve_rect) {
  s32 i;
  const double A[8] = {-0.0178505395610981, 1.4638781031761146,
                       -0.8242742209580581, -0.6843477128009663,
                       0.9155272861151404, -0.1651159277864960,
                       -0.9929037180867774, -0.1491537478964264};
  double Q[16], R[8];

  double buf[10] __attribute__((unused)) = {22, 22, 22, 22, 22,
                                            22, 22, 22, 22, 22};

  i = qrdecomp(A, 4, 2, Q, R);

  printf("i returned %d\n", i);

  MAT_PRINTF(A, 4, 2);
  MAT_PRINTF(Q, 4, 4);
  MAT_PRINTF(R, 4, 2);
}
END_TEST
*/

START_TEST(test_submatrix) {
  const double A[3 * 3] = {
    0, 1, 2,
    3, 4, 5,
    6, 7, 8
  };

  double A2[2 * 2];

  u32 row_map[2] = {1, 2};
  u32 col_map[2] = {0, 1};

  const double answer[2 * 2] = {
    3, 4,
    6, 7
  };

  submatrix(2, 2, 3, A, row_map, col_map, A2);

  for (u8 i = 0; i < 2*2; i++) {
    fail_unless(answer[i] == A2[i]);
  }
}
コード例 #13
0
int submatrix_formats(const Epetra_Comm& Comm, bool verbose)
{
  (void)verbose;
  //
  //This function simply verifies that the ROW_MAJOR/COLUMN_MAJOR switch works.
  //
  int numProcs = Comm.NumProc();
  int myPID = Comm.MyPID();

  int numLocalElements = 3;
  int numGlobalElements = numLocalElements*numProcs;
  int indexBase = 0;

  Epetra_Map map(numGlobalElements, numLocalElements, indexBase, Comm);

  Epetra_FECrsMatrix A(Copy, map, numLocalElements);

  Epetra_IntSerialDenseVector epetra_indices(numLocalElements);

  int firstGlobalElement = numLocalElements*myPID;

  int i, j;
  for(i=0; i<numLocalElements; ++i) {
    epetra_indices[i] = firstGlobalElement+i;
  }

  Epetra_SerialDenseMatrix submatrix(numLocalElements, numLocalElements);

  for(i=0; i<numLocalElements; ++i) {
    for(j=0; j<numLocalElements; ++j) {
      submatrix(i,j) = 1.0*(firstGlobalElement+i);
    }
  }

  EPETRA_CHK_ERR( A.InsertGlobalValues(epetra_indices, submatrix,
                               Epetra_FECrsMatrix::COLUMN_MAJOR) );

  EPETRA_CHK_ERR( A.GlobalAssemble() );

  int len = 20;
  int numIndices;
  int* indices = new int[len];
  double* coefs = new double[len];

  for(i=0; i<numLocalElements; ++i) {
    int row = firstGlobalElement+i;

    EPETRA_CHK_ERR( A.ExtractGlobalRowCopy(row, len, numIndices,
					   coefs, indices) );

    for(j=0; j<numIndices; ++j) {
      if (coefs[j] != 1.0*row) {
	return(-2);
      }
    }
  }

  //now reset submatrix (transposing the i,j indices)

  for(i=0; i<numLocalElements; ++i) {
    for(j=0; j<numLocalElements; ++j) {
      submatrix(j,i) = 1.0*(firstGlobalElement+i);
    }
  }

  //sum these values into the matrix using the ROW_MAJOR switch, which should
  //result in doubling what's already there from the above Insert operation.

  EPETRA_CHK_ERR( A.SumIntoGlobalValues(epetra_indices, submatrix,
					Epetra_FECrsMatrix::ROW_MAJOR) );

  EPETRA_CHK_ERR( A.GlobalAssemble() );

  for(i=0; i<numLocalElements; ++i) {
    int row = firstGlobalElement+i;

    EPETRA_CHK_ERR( A.ExtractGlobalRowCopy(row, len, numIndices,
					   coefs, indices) );

    for(j=0; j<numIndices; ++j) {
      if (coefs[j] != 2.0*row) {
	return(-3);
      }
    }
  }

  delete [] indices;
  delete [] coefs;

  return(0);
}