Teuchos Package Browser (Single Doxygen Collection)  Version of the Day
Teuchos_SerialSymDenseMatrix.hpp
Go to the documentation of this file.
1 
2 // @HEADER
3 // ***********************************************************************
4 //
5 // Teuchos: Common Tools Package
6 // Copyright (2004) Sandia Corporation
7 //
8 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
9 // license for use of this work by or on behalf of the U.S. Government.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
39 //
40 // ***********************************************************************
41 // @HEADER
42 
43 #ifndef _TEUCHOS_SERIALSYMDENSEMATRIX_HPP_
44 #define _TEUCHOS_SERIALSYMDENSEMATRIX_HPP_
45 
49 #include "Teuchos_CompObject.hpp"
50 #include "Teuchos_BLAS.hpp"
51 #include "Teuchos_ScalarTraits.hpp"
52 #include "Teuchos_DataAccess.hpp"
53 #include "Teuchos_ConfigDefs.hpp"
54 #include "Teuchos_Assert.hpp"
55 #include <vector>
56 
119 namespace Teuchos {
120 
121 template<typename OrdinalType, typename ScalarType>
122 class SerialSymDenseMatrix : public CompObject, public Object, public BLAS<OrdinalType,ScalarType>
123 {
124  public:
125 
127  typedef OrdinalType ordinalType;
129  typedef ScalarType scalarType;
130 
132 
133 
143 
145 
155  SerialSymDenseMatrix(OrdinalType numRowsCols, bool zeroOut = true);
156 
158 
169  SerialSymDenseMatrix(DataAccess CV, bool upper, ScalarType* values, OrdinalType stride, OrdinalType numRowsCols);
170 
173 
175 
184  SerialSymDenseMatrix(DataAccess CV, const SerialSymDenseMatrix<OrdinalType, ScalarType> &Source, OrdinalType numRowCols, OrdinalType startRowCol=0);
185 
187  virtual ~SerialSymDenseMatrix ();
189 
191 
192 
194 
203  int shape(OrdinalType numRowsCols);
204 
206 
215  int shapeUninitialized(OrdinalType numRowsCols);
216 
218 
228  int reshape(OrdinalType numRowsCols);
229 
231 
233  void setLower();
234 
236 
238  void setUpper();
239 
241 
243 
244 
246 
253 
255 
260 
262 
265  SerialSymDenseMatrix<OrdinalType, ScalarType>& operator= (const ScalarType value) { putScalar(value); return(*this); }
266 
268 
273  int putScalar( const ScalarType value = Teuchos::ScalarTraits<ScalarType>::zero(), bool fullMatrix = false );
274 
276 
278  int random( const ScalarType bias = 0.1*Teuchos::ScalarTraits<ScalarType>::one() );
279 
281 
283 
284 
286 
293  ScalarType& operator () (OrdinalType rowIndex, OrdinalType colIndex);
294 
296 
303  const ScalarType& operator () (OrdinalType rowIndex, OrdinalType colIndex) const;
304 
306 
308  ScalarType* values() const { return(values_); }
309 
311 
313 
314 
316  bool upper() const {return(upper_);};
317 
319  char UPLO() const {return(UPLO_);};
321 
323 
324 
326 
333 
335 
339 
341 
345 
347 
349 
350 
352 
356 
358 
362 
364 
366 
367 
369  OrdinalType numRows() const { return(numRowCols_); }
370 
372  OrdinalType numCols() const { return(numRowCols_); }
373 
375  OrdinalType stride() const { return(stride_); }
376 
378  bool empty() const { return(numRowCols_ == 0); }
379 
381 
383 
384 
387 
390 
394 
396 
397  virtual void print(std::ostream& os) const;
399 
401 
402  protected:
403 
404  // In-place scaling of matrix.
405  void scale( const ScalarType alpha );
406 
407  // Copy the values from one matrix to the other.
408  void copyMat(bool inputUpper, ScalarType* inputMatrix, OrdinalType inputStride,
409  OrdinalType numRowCols, bool outputUpper, ScalarType* outputMatrix,
410  OrdinalType outputStride, OrdinalType startRowCol,
411  ScalarType alpha = ScalarTraits<ScalarType>::zero() );
412 
413  // Copy the values from the active triangle of the matrix to the other to make the matrix full symmetric.
414  void copyUPLOMat(bool inputUpper, ScalarType* inputMatrix,
415  OrdinalType inputStride, OrdinalType inputRows);
416 
417  void deleteArrays();
418  void checkIndex( OrdinalType rowIndex, OrdinalType colIndex = 0 ) const;
419  OrdinalType numRowCols_;
420  OrdinalType stride_;
422  ScalarType* values_;
423  bool upper_;
424  char UPLO_;
425 
426 
427 };
428 
429 //----------------------------------------------------------------------------------------------------
430 // Constructors and Destructor
431 //----------------------------------------------------------------------------------------------------
432 
433 template<typename OrdinalType, typename ScalarType>
435  : CompObject(), Object(), BLAS<OrdinalType,ScalarType>(),
436  numRowCols_(0), stride_(0), valuesCopied_(false), values_(0), upper_(false), UPLO_('L')
437 {}
438 
439 template<typename OrdinalType, typename ScalarType>
441  : CompObject(), Object(), BLAS<OrdinalType,ScalarType>(),
442  numRowCols_(numRowCols_in), stride_(numRowCols_in), valuesCopied_(false), upper_(false), UPLO_('L')
443 {
444  values_ = new ScalarType[stride_*numRowCols_];
445  valuesCopied_ = true;
446  if (zeroOut == true)
448 }
449 
450 template<typename OrdinalType, typename ScalarType>
452  DataAccess CV, bool upper_in, ScalarType* values_in, OrdinalType stride_in, OrdinalType numRowCols_in
453  )
454  : CompObject(), Object(), BLAS<OrdinalType,ScalarType>(),
455  numRowCols_(numRowCols_in), stride_(stride_in), valuesCopied_(false),
456  values_(values_in), upper_(upper_in)
457 {
458  if (upper_)
459  UPLO_ = 'U';
460  else
461  UPLO_ = 'L';
462 
463  if(CV == Copy)
464  {
466  values_ = new ScalarType[stride_*numRowCols_];
467  copyMat(upper_in, values_in, stride_in, numRowCols_, upper_, values_, stride_, 0);
468  valuesCopied_ = true;
469  }
470 }
471 
472 template<typename OrdinalType, typename ScalarType>
474  : CompObject(), Object(), BLAS<OrdinalType,ScalarType>(),
475  numRowCols_(Source.numRowCols_), stride_(0), valuesCopied_(true),
476  values_(0), upper_(Source.upper_), UPLO_(Source.UPLO_)
477 {
478  if (!Source.valuesCopied_)
479  {
480  stride_ = Source.stride_;
481  values_ = Source.values_;
482  valuesCopied_ = false;
483  }
484  else
485  {
487  const OrdinalType newsize = stride_ * numRowCols_;
488  if(newsize > 0) {
489  values_ = new ScalarType[newsize];
490  copyMat(Source.upper_, Source.values_, Source.stride_, numRowCols_, upper_, values_, stride_, 0);
491  }
492  else {
493  numRowCols_ = 0; stride_ = 0;
494  valuesCopied_ = false;
495  }
496  }
497 }
498 
499 template<typename OrdinalType, typename ScalarType>
501  DataAccess CV, const SerialSymDenseMatrix<OrdinalType,
502  ScalarType> &Source, OrdinalType numRowCols_in, OrdinalType startRowCol )
503  : CompObject(), Object(), BLAS<OrdinalType,ScalarType>(),
504  numRowCols_(numRowCols_in), stride_(Source.stride_), valuesCopied_(false), upper_(Source.upper_), UPLO_(Source.UPLO_)
505 {
506  if(CV == Copy)
507  {
508  stride_ = numRowCols_in;
509  values_ = new ScalarType[stride_ * numRowCols_in];
510  copyMat(Source.upper_, Source.values_, Source.stride_, numRowCols_in, upper_, values_, stride_, startRowCol);
511  valuesCopied_ = true;
512  }
513  else // CV == View
514  {
515  values_ = Source.values_ + (stride_ * startRowCol) + startRowCol;
516  }
517 }
518 
519 template<typename OrdinalType, typename ScalarType>
521 {
522  deleteArrays();
523 }
524 
525 //----------------------------------------------------------------------------------------------------
526 // Shape methods
527 //----------------------------------------------------------------------------------------------------
528 
529 template<typename OrdinalType, typename ScalarType>
531 {
532  deleteArrays(); // Get rid of anything that might be already allocated
533  numRowCols_ = numRowCols_in;
534  stride_ = numRowCols_;
535  values_ = new ScalarType[stride_*numRowCols_];
536  putScalar( Teuchos::ScalarTraits<ScalarType>::zero(), true );
537  valuesCopied_ = true;
538  return(0);
539 }
540 
541 template<typename OrdinalType, typename ScalarType>
543 {
544  deleteArrays(); // Get rid of anything that might be already allocated
545  numRowCols_ = numRowCols_in;
546  stride_ = numRowCols_;
547  values_ = new ScalarType[stride_*numRowCols_];
548  valuesCopied_ = true;
549  return(0);
550 }
551 
552 template<typename OrdinalType, typename ScalarType>
554 {
555  // Allocate space for new matrix
556  ScalarType* values_tmp = new ScalarType[numRowCols_in * numRowCols_in];
557  ScalarType zero = ScalarTraits<ScalarType>::zero();
558  for(OrdinalType k = 0; k < numRowCols_in * numRowCols_in; k++)
559  {
560  values_tmp[k] = zero;
561  }
562  OrdinalType numRowCols_tmp = TEUCHOS_MIN(numRowCols_, numRowCols_in);
563  if(values_ != 0)
564  {
565  copyMat(upper_, values_, stride_, numRowCols_tmp, upper_, values_tmp, numRowCols_in, 0); // Copy principal submatrix of A to new A
566  }
567  deleteArrays(); // Get rid of anything that might be already allocated
568  numRowCols_ = numRowCols_in;
569  stride_ = numRowCols_;
570  values_ = values_tmp; // Set pointer to new A
571  valuesCopied_ = true;
572  return(0);
573 }
574 
575 //----------------------------------------------------------------------------------------------------
576 // Set methods
577 //----------------------------------------------------------------------------------------------------
578 
579 template<typename OrdinalType, typename ScalarType>
581 {
582  // Do nothing if the matrix is already a lower triangular matrix
583  if (upper_ != false) {
584  copyUPLOMat( true, values_, stride_, numRowCols_ );
585  upper_ = false;
586  UPLO_ = 'L';
587  }
588 }
589 
590 template<typename OrdinalType, typename ScalarType>
592 {
593  // Do nothing if the matrix is already an upper triangular matrix
594  if (upper_ == false) {
595  copyUPLOMat( false, values_, stride_, numRowCols_ );
596  upper_ = true;
597  UPLO_ = 'U';
598  }
599 }
600 
601 template<typename OrdinalType, typename ScalarType>
602 int SerialSymDenseMatrix<OrdinalType, ScalarType>::putScalar( const ScalarType value_in, bool fullMatrix )
603 {
604  // Set each value of the dense matrix to "value".
605  if (fullMatrix == true) {
606  for(OrdinalType j = 0; j < numRowCols_; j++)
607  {
608  for(OrdinalType i = 0; i < numRowCols_; i++)
609  {
610  values_[i + j*stride_] = value_in;
611  }
612  }
613  }
614  // Set the active upper or lower triangular part of the matrix to "value"
615  else {
616  if (upper_) {
617  for(OrdinalType j = 0; j < numRowCols_; j++) {
618  for(OrdinalType i = 0; i <= j; i++) {
619  values_[i + j*stride_] = value_in;
620  }
621  }
622  }
623  else {
624  for(OrdinalType j = 0; j < numRowCols_; j++) {
625  for(OrdinalType i = j; i < numRowCols_; i++) {
626  values_[i + j*stride_] = value_in;
627  }
628  }
629  }
630  }
631  return 0;
632 }
633 
634 template<typename OrdinalType, typename ScalarType>
636 {
638 
639  // Set each value of the dense matrix to a random value.
640  std::vector<MT> diagSum( numRowCols_, Teuchos::ScalarTraits<MT>::zero() );
641  if (upper_) {
642  for(OrdinalType j = 0; j < numRowCols_; j++) {
643  for(OrdinalType i = 0; i < j; i++) {
644  values_[i + j*stride_] = ScalarTraits<ScalarType>::random();
645  diagSum[i] += Teuchos::ScalarTraits<ScalarType>::magnitude( values_[i + j*stride_] );
646  diagSum[j] += Teuchos::ScalarTraits<ScalarType>::magnitude( values_[i + j*stride_] );
647  }
648  }
649  }
650  else {
651  for(OrdinalType j = 0; j < numRowCols_; j++) {
652  for(OrdinalType i = j+1; i < numRowCols_; i++) {
653  values_[i + j*stride_] = ScalarTraits<ScalarType>::random();
654  diagSum[i] += Teuchos::ScalarTraits<ScalarType>::magnitude( values_[i + j*stride_] );
655  diagSum[j] += Teuchos::ScalarTraits<ScalarType>::magnitude( values_[i + j*stride_] );
656  }
657  }
658  }
659 
660  // Set the diagonal.
661  for(OrdinalType i = 0; i < numRowCols_; i++) {
662  values_[i + i*stride_] = diagSum[i] + bias;
663  }
664  return 0;
665 }
666 
667 template<typename OrdinalType, typename ScalarType>
670 {
671  if(this == &Source)
672  return(*this); // Special case of source same as target
673  if((!valuesCopied_) && (!Source.valuesCopied_) && (values_ == Source.values_)) {
674  upper_ = Source.upper_; // Might have to change the active part of the matrix.
675  return(*this); // Special case of both are views to same data.
676  }
677 
678  // If the source is a view then we will return a view, else we will return a copy.
679  if (!Source.valuesCopied_) {
680  if(valuesCopied_) {
681  // Clean up stored data if this was previously a copy.
682  deleteArrays();
683  }
684  numRowCols_ = Source.numRowCols_;
685  stride_ = Source.stride_;
686  values_ = Source.values_;
687  upper_ = Source.upper_;
688  UPLO_ = Source.UPLO_;
689  }
690  else {
691  // If we were a view, we will now be a copy.
692  if(!valuesCopied_) {
693  numRowCols_ = Source.numRowCols_;
694  stride_ = Source.numRowCols_;
695  upper_ = Source.upper_;
696  UPLO_ = Source.UPLO_;
697  const OrdinalType newsize = stride_ * numRowCols_;
698  if(newsize > 0) {
699  values_ = new ScalarType[newsize];
700  valuesCopied_ = true;
701  }
702  else {
703  values_ = 0;
704  }
705  }
706  // If we were a copy, we will stay a copy.
707  else {
708  if((Source.numRowCols_ <= stride_) && (Source.numRowCols_ == numRowCols_)) { // we don't need to reallocate
709  numRowCols_ = Source.numRowCols_;
710  upper_ = Source.upper_;
711  UPLO_ = Source.UPLO_;
712  }
713  else { // we need to allocate more space (or less space)
714  deleteArrays();
715  numRowCols_ = Source.numRowCols_;
716  stride_ = Source.numRowCols_;
717  upper_ = Source.upper_;
718  UPLO_ = Source.UPLO_;
719  const OrdinalType newsize = stride_ * numRowCols_;
720  if(newsize > 0) {
721  values_ = new ScalarType[newsize];
722  valuesCopied_ = true;
723  }
724  }
725  }
726  copyMat(Source.upper_, Source.values_, Source.stride_, Source.numRowCols_, upper_, values_, stride_, 0);
727  }
728  return(*this);
729 }
730 
731 template<typename OrdinalType, typename ScalarType>
733 {
734  this->scale(alpha);
735  return(*this);
736 }
737 
738 template<typename OrdinalType, typename ScalarType>
740 {
741  // Check for compatible dimensions
742  if ((numRowCols_ != Source.numRowCols_))
743  {
744  TEUCHOS_CHK_REF(*this); // Return *this without altering it.
745  }
746  copyMat(Source.upper_, Source.values_, Source.stride_, numRowCols_, upper_, values_, stride_, 0, ScalarTraits<ScalarType>::one());
747  return(*this);
748 }
749 
750 template<typename OrdinalType, typename ScalarType>
752 {
753  // Check for compatible dimensions
754  if ((numRowCols_ != Source.numRowCols_))
755  {
756  TEUCHOS_CHK_REF(*this); // Return *this without altering it.
757  }
758  copyMat(Source.upper_, Source.values_, Source.stride_, numRowCols_, upper_, values_, stride_, 0, -ScalarTraits<ScalarType>::one());
759  return(*this);
760 }
761 
762 template<typename OrdinalType, typename ScalarType>
764  if(this == &Source)
765  return(*this); // Special case of source same as target
766  if((!valuesCopied_) && (!Source.valuesCopied_) && (values_ == Source.values_)) {
767  upper_ = Source.upper_; // We may have to change the active part of the matrix.
768  return(*this); // Special case of both are views to same data.
769  }
770 
771  // Check for compatible dimensions
772  if ((numRowCols_ != Source.numRowCols_))
773  {
774  TEUCHOS_CHK_REF(*this); // Return *this without altering it.
775  }
776  copyMat(Source.upper_, Source.values_, Source.stride_, numRowCols_, upper_, values_, stride_, 0 );
777  return(*this);
778 }
779 
780 //----------------------------------------------------------------------------------------------------
781 // Accessor methods
782 //----------------------------------------------------------------------------------------------------
783 
784 template<typename OrdinalType, typename ScalarType>
785 inline ScalarType& SerialSymDenseMatrix<OrdinalType, ScalarType>::operator () (OrdinalType rowIndex, OrdinalType colIndex)
786 {
787 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
788  checkIndex( rowIndex, colIndex );
789 #endif
790  if ( rowIndex <= colIndex ) {
791  // Accessing upper triangular part of matrix
792  if (upper_)
793  return(values_[colIndex * stride_ + rowIndex]);
794  else
795  return(values_[rowIndex * stride_ + colIndex]);
796  }
797  else {
798  // Accessing lower triangular part of matrix
799  if (upper_)
800  return(values_[rowIndex * stride_ + colIndex]);
801  else
802  return(values_[colIndex * stride_ + rowIndex]);
803  }
804 }
805 
806 template<typename OrdinalType, typename ScalarType>
807 inline const ScalarType& SerialSymDenseMatrix<OrdinalType, ScalarType>::operator () (OrdinalType rowIndex, OrdinalType colIndex) const
808 {
809 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
810  checkIndex( rowIndex, colIndex );
811 #endif
812  if ( rowIndex <= colIndex ) {
813  // Accessing upper triangular part of matrix
814  if (upper_)
815  return(values_[colIndex * stride_ + rowIndex]);
816  else
817  return(values_[rowIndex * stride_ + colIndex]);
818  }
819  else {
820  // Accessing lower triangular part of matrix
821  if (upper_)
822  return(values_[rowIndex * stride_ + colIndex]);
823  else
824  return(values_[colIndex * stride_ + rowIndex]);
825  }
826 }
827 
828 //----------------------------------------------------------------------------------------------------
829 // Norm methods
830 //----------------------------------------------------------------------------------------------------
831 
832 template<typename OrdinalType, typename ScalarType>
834 {
835  return(normInf());
836 }
837 
838 template<typename OrdinalType, typename ScalarType>
840 {
841  typedef typename ScalarTraits<ScalarType>::magnitudeType MT;
842 
843  OrdinalType i, j;
844 
845  MT sum, anorm = ScalarTraits<MT>::zero();
846  ScalarType* ptr;
847 
848  if (upper_) {
849  for (j=0; j<numRowCols_; j++) {
850  sum = ScalarTraits<MT>::zero();
851  ptr = values_ + j*stride_;
852  for (i=0; i<j; i++) {
853  sum += ScalarTraits<ScalarType>::magnitude( *ptr++ );
854  }
855  ptr = values_ + j + j*stride_;
856  for (i=j; i<numRowCols_; i++) {
858  ptr += stride_;
859  }
860  anorm = TEUCHOS_MAX( anorm, sum );
861  }
862  }
863  else {
864  for (j=0; j<numRowCols_; j++) {
865  sum = ScalarTraits<MT>::zero();
866  ptr = values_ + j + j*stride_;
867  for (i=j; i<numRowCols_; i++) {
868  sum += ScalarTraits<ScalarType>::magnitude( *ptr++ );
869  }
870  ptr = values_ + j;
871  for (i=0; i<j; i++) {
873  ptr += stride_;
874  }
875  anorm = TEUCHOS_MAX( anorm, sum );
876  }
877  }
878  return(anorm);
879 }
880 
881 template<typename OrdinalType, typename ScalarType>
883 {
884  typedef typename ScalarTraits<ScalarType>::magnitudeType MT;
885 
886  OrdinalType i, j;
887 
888  MT sum = ScalarTraits<MT>::zero(), anorm = ScalarTraits<MT>::zero();
889 
890  if (upper_) {
891  for (j = 0; j < numRowCols_; j++) {
892  for (i = 0; i < j; i++) {
893  sum += ScalarTraits<ScalarType>::magnitude(2.0*values_[i+j*stride_]*values_[i+j*stride_]);
894  }
895  sum += ScalarTraits<ScalarType>::magnitude(values_[j + j*stride_]*values_[j + j*stride_]);
896  }
897  }
898  else {
899  for (j = 0; j < numRowCols_; j++) {
900  sum += ScalarTraits<ScalarType>::magnitude(values_[j + j*stride_]*values_[j + j*stride_]);
901  for (i = j+1; i < numRowCols_; i++) {
902  sum += ScalarTraits<ScalarType>::magnitude(2.0*values_[i+j*stride_]*values_[i+j*stride_]);
903  }
904  }
905  }
907  return(anorm);
908 }
909 
910 //----------------------------------------------------------------------------------------------------
911 // Comparison methods
912 //----------------------------------------------------------------------------------------------------
913 
914 template<typename OrdinalType, typename ScalarType>
916 {
917  bool result = 1;
918  if((numRowCols_ != Operand.numRowCols_)) {
919  result = 0;
920  }
921  else {
922  OrdinalType i, j;
923  for(i = 0; i < numRowCols_; i++) {
924  for(j = 0; j < numRowCols_; j++) {
925  if((*this)(i, j) != Operand(i, j)) {
926  return 0;
927  }
928  }
929  }
930  }
931  return result;
932 }
933 
934 template<typename OrdinalType, typename ScalarType>
936 {
937  return !((*this) == Operand);
938 }
939 
940 //----------------------------------------------------------------------------------------------------
941 // Multiplication method
942 //----------------------------------------------------------------------------------------------------
943 
944 template<typename OrdinalType, typename ScalarType>
946 {
947  OrdinalType i, j;
948  ScalarType* ptr;
949 
950  if (upper_) {
951  for (j=0; j<numRowCols_; j++) {
952  ptr = values_ + j*stride_;
953  for (i=0; i<= j; i++) { *ptr = alpha * (*ptr); ptr++; }
954  }
955  }
956  else {
957  for (j=0; j<numRowCols_; j++) {
958  ptr = values_ + j*stride_ + j;
959  for (i=j; i<numRowCols_; i++) { *ptr = alpha * (*ptr); ptr++; }
960  }
961  }
962 }
963 
964 /*
965 template<typename OrdinalType, typename ScalarType>
966 int SerialSymDenseMatrix<OrdinalType, ScalarType>::scale( const SerialSymDenseMatrix<OrdinalType,ScalarType>& A )
967 {
968  OrdinalType i, j;
969  ScalarType* ptr;
970 
971  // Check for compatible dimensions
972  if ((numRowCols_ != A.numRowCols_)) {
973  TEUCHOS_CHK_ERR(-1); // Return error
974  }
975 
976  if (upper_) {
977  for (j=0; j<numRowCols_; j++) {
978  ptr = values_ + j*stride_;
979  for (i=0; i<= j; i++) { *ptr = A(i,j) * (*ptr); ptr++; }
980  }
981  }
982  else {
983  for (j=0; j<numRowCols_; j++) {
984  ptr = values_ + j*stride_;
985  for (i=j; i<numRowCols_; i++) { *ptr = A(i,j) * (*ptr); ptr++; }
986  }
987  }
988 
989  return(0);
990 }
991 */
992 
993 template<typename OrdinalType, typename ScalarType>
995 {
996  os << std::endl;
997  if(valuesCopied_)
998  os << "Values_copied : yes" << std::endl;
999  else
1000  os << "Values_copied : no" << std::endl;
1001  os << "Rows / Columns : " << numRowCols_ << std::endl;
1002  os << "LDA : " << stride_ << std::endl;
1003  if (upper_)
1004  os << "Storage: Upper" << std::endl;
1005  else
1006  os << "Storage: Lower" << std::endl;
1007  if(numRowCols_ == 0) {
1008  os << "(matrix is empty, no values to display)" << std::endl;
1009  } else {
1010  for(OrdinalType i = 0; i < numRowCols_; i++) {
1011  for(OrdinalType j = 0; j < numRowCols_; j++){
1012  os << (*this)(i,j) << " ";
1013  }
1014  os << std::endl;
1015  }
1016  }
1017 }
1018 
1019 //----------------------------------------------------------------------------------------------------
1020 // Protected methods
1021 //----------------------------------------------------------------------------------------------------
1022 
1023 template<typename OrdinalType, typename ScalarType>
1024 inline void SerialSymDenseMatrix<OrdinalType, ScalarType>::checkIndex( OrdinalType rowIndex, OrdinalType colIndex ) const {
1025  TEUCHOS_TEST_FOR_EXCEPTION(rowIndex < 0 || rowIndex >= numRowCols_, std::out_of_range,
1026  "SerialSymDenseMatrix<T>::checkIndex: "
1027  "Row index " << rowIndex << " out of range [0, "<< numRowCols_ << ")");
1028  TEUCHOS_TEST_FOR_EXCEPTION(colIndex < 0 || colIndex >= numRowCols_, std::out_of_range,
1029  "SerialSymDenseMatrix<T>::checkIndex: "
1030  "Col index " << colIndex << " out of range [0, "<< numRowCols_ << ")");
1031 }
1032 
1033 template<typename OrdinalType, typename ScalarType>
1035 {
1036  if (valuesCopied_)
1037  {
1038  delete [] values_;
1039  values_ = 0;
1040  valuesCopied_ = false;
1041  }
1042 }
1043 
1044 template<typename OrdinalType, typename ScalarType>
1046  bool inputUpper, ScalarType* inputMatrix,
1047  OrdinalType inputStride, OrdinalType numRowCols_in,
1048  bool outputUpper, ScalarType* outputMatrix,
1049  OrdinalType outputStride, OrdinalType startRowCol,
1050  ScalarType alpha
1051  )
1052 {
1053  OrdinalType i, j;
1054  ScalarType* ptr1 = 0;
1055  ScalarType* ptr2 = 0;
1056 
1057  for (j = 0; j < numRowCols_in; j++) {
1058  if (inputUpper == true) {
1059  // The input matrix is upper triangular, start at the beginning of each column.
1060  ptr2 = inputMatrix + (j + startRowCol) * inputStride + startRowCol;
1061  if (outputUpper == true) {
1062  // The output matrix matches the same pattern as the input matrix.
1063  ptr1 = outputMatrix + j*outputStride;
1064  if (alpha != Teuchos::ScalarTraits<ScalarType>::zero() ) {
1065  for(i = 0; i <= j; i++) {
1066  *ptr1++ += alpha*(*ptr2++);
1067  }
1068  } else {
1069  for(i = 0; i <= j; i++) {
1070  *ptr1++ = *ptr2++;
1071  }
1072  }
1073  }
1074  else {
1075  // The output matrix has the opposite pattern as the input matrix.
1076  // Copy down across rows of the output matrix, but down columns of the input matrix.
1077  ptr1 = outputMatrix + j;
1078  if (alpha != Teuchos::ScalarTraits<ScalarType>::zero() ) {
1079  for(i = 0; i <= j; i++) {
1080  *ptr1 += alpha*(*ptr2++);
1081  ptr1 += outputStride;
1082  }
1083  } else {
1084  for(i = 0; i <= j; i++) {
1085  *ptr1 = *ptr2++;
1086  ptr1 += outputStride;
1087  }
1088  }
1089  }
1090  }
1091  else {
1092  // The input matrix is lower triangular, start at the diagonal of each row.
1093  ptr2 = inputMatrix + (startRowCol+j) * inputStride + startRowCol + j;
1094  if (outputUpper == true) {
1095  // The output matrix has the opposite pattern as the input matrix.
1096  // Copy across rows of the output matrix, but down columns of the input matrix.
1097  ptr1 = outputMatrix + j*outputStride + j;
1098  if (alpha != Teuchos::ScalarTraits<ScalarType>::zero() ) {
1099  for(i = j; i < numRowCols_in; i++) {
1100  *ptr1 += alpha*(*ptr2++);
1101  ptr1 += outputStride;
1102  }
1103  } else {
1104  for(i = j; i < numRowCols_in; i++) {
1105  *ptr1 = *ptr2++;
1106  ptr1 += outputStride;
1107  }
1108  }
1109  }
1110  else {
1111  // The output matrix matches the same pattern as the input matrix.
1112  ptr1 = outputMatrix + j*outputStride + j;
1113  if (alpha != Teuchos::ScalarTraits<ScalarType>::zero() ) {
1114  for(i = j; i < numRowCols_in; i++) {
1115  *ptr1++ += alpha*(*ptr2++);
1116  }
1117  } else {
1118  for(i = j; i < numRowCols_in; i++) {
1119  *ptr1++ = *ptr2++;
1120  }
1121  }
1122  }
1123  }
1124  }
1125 }
1126 
1127 template<typename OrdinalType, typename ScalarType>
1129  bool inputUpper, ScalarType* inputMatrix,
1130  OrdinalType inputStride, OrdinalType inputRows
1131  )
1132 {
1133  OrdinalType i, j;
1134  ScalarType * ptr1 = 0;
1135  ScalarType * ptr2 = 0;
1136 
1137  if (inputUpper) {
1138  for (j=1; j<inputRows; j++) {
1139  ptr1 = inputMatrix + j;
1140  ptr2 = inputMatrix + j*inputStride;
1141  for (i=0; i<j; i++) {
1142  *ptr1 = *ptr2++;
1143  ptr1+=inputStride;
1144  }
1145  }
1146  }
1147  else {
1148  for (i=1; i<inputRows; i++) {
1149  ptr1 = inputMatrix + i;
1150  ptr2 = inputMatrix + i*inputStride;
1151  for (j=0; j<i; j++) {
1152  *ptr2++ = *ptr1;
1153  ptr1+=inputStride;
1154  }
1155  }
1156  }
1157 }
1158 
1159 } // namespace Teuchos
1160 
1161 #endif /* _TEUCHOS_SERIALSYMDENSEMATRIX_HPP_ */
ScalarTraits< ScalarType >::magnitudeType normInf() const
Returns the Infinity-norm of the matrix.
virtual void print(std::ostream &os) const
Print method. Defines the behavior of the std::ostream << operator inherited from the Object class...
OrdinalType numCols() const
Returns the column dimension of this matrix.
void copyUPLOMat(bool inputUpper, ScalarType *inputMatrix, OrdinalType inputStride, OrdinalType inputRows)
SerialSymDenseMatrix()
Default constructor; defines a zero size object.
void checkIndex(OrdinalType rowIndex, OrdinalType colIndex=0) const
Templated interface class to BLAS routines.
bool empty() const
Returns whether this matrix is empty.
ScalarType & operator()(OrdinalType rowIndex, OrdinalType colIndex)
Element access method (non-const).
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
int shape(OrdinalType numRowsCols)
Set dimensions of a Teuchos::SerialSymDenseMatrix object; init values to zero.
Teuchos header file which uses auto-configuration information to include necessary C++ headers...
Templated BLAS wrapper.
This class creates and provides basic support for symmetric, positive-definite dense matrices of temp...
bool operator==(const SerialSymDenseMatrix< OrdinalType, ScalarType > &Operand) const
Equality of two matrices.
Object for storing data and providing functionality that is common to all computational classes...
int reshape(OrdinalType numRowsCols)
Reshape a Teuchos::SerialSymDenseMatrix object.
This structure defines some basic traits for a scalar field type.
void setLower()
Specify that the lower triangle of the this matrix should be used.
void setUpper()
Specify that the upper triangle of the this matrix should be used.
Functionality and data that is common to all computational classes.
OrdinalType numRows() const
Returns the row dimension of this matrix.
bool upper() const
Returns true if upper triangular part of this matrix has and will be used.
SerialSymDenseMatrix< OrdinalType, ScalarType > & operator*=(const ScalarType alpha)
Inplace scalar-matrix product A = alpha*A.
The base Teuchos class.
int putScalar(const ScalarType value=Teuchos::ScalarTraits< ScalarType >::zero(), bool fullMatrix=false)
Set all values in the matrix to a constant value.
SerialSymDenseMatrix< OrdinalType, ScalarType > & operator+=(const SerialSymDenseMatrix< OrdinalType, ScalarType > &Source)
Add another matrix to this matrix.
#define TEUCHOS_MAX(x, y)
int random(const ScalarType bias=0.1 *Teuchos::ScalarTraits< ScalarType >::one())
Set all values in the active area (upper/lower triangle) of this matrix to be random numbers...
virtual ~SerialSymDenseMatrix()
Teuchos::SerialSymDenseMatrix destructor.
static magnitudeType magnitude(T a)
Returns the magnitudeType of the scalar type a.
SerialSymDenseMatrix< OrdinalType, ScalarType > & operator-=(const SerialSymDenseMatrix< OrdinalType, ScalarType > &Source)
Subtract another matrix from this matrix.
OrdinalType ordinalType
Typedef for ordinal type.
SerialSymDenseMatrix< OrdinalType, ScalarType > & operator=(const SerialSymDenseMatrix< OrdinalType, ScalarType > &Source)
Copies values from one matrix to another.
int shapeUninitialized(OrdinalType numRowsCols)
Set dimensions of a Teuchos::SerialSymDenseMatrix object; don&#39;t initialize values.
ScalarTraits< ScalarType >::magnitudeType normOne() const
Returns the 1-norm of the matrix.
Defines basic traits for the scalar field type.
static T zero()
Returns representation of zero for this scalar type.
static T random()
Returns a random number (between -one() and +one()) of this scalar type.
char UPLO() const
Returns character value of UPLO used by LAPACK routines.
#define TEUCHOS_CHK_REF(a)
SerialSymDenseMatrix< OrdinalType, ScalarType > & assign(const SerialSymDenseMatrix< OrdinalType, ScalarType > &Source)
Copies values from one matrix to another.
#define TEUCHOS_MIN(x, y)
Teuchos::DataAccess Mode enumerable type.
ScalarType * values() const
Returns the pointer to the ScalarType data array contained in the object.
OrdinalType stride() const
Returns the stride between the columns of this matrix in memory.
void copyMat(bool inputUpper, ScalarType *inputMatrix, OrdinalType inputStride, OrdinalType numRowCols, bool outputUpper, ScalarType *outputMatrix, OrdinalType outputStride, OrdinalType startRowCol, ScalarType alpha=ScalarTraits< ScalarType >::zero())
ScalarType scalarType
Typedef for scalar type.
ScalarTraits< ScalarType >::magnitudeType normFrobenius() const
Returns the Frobenius-norm of the matrix.
bool operator!=(const SerialSymDenseMatrix< OrdinalType, ScalarType > &Operand) const
Inequality of two matrices.