Teuchos - Trilinos Tools Package Version of the Day
Loading...
Searching...
No Matches
Teuchos_SerialSymDenseMatrix.hpp
Go to the documentation of this file.
1
2// @HEADER
3// *****************************************************************************
4// Teuchos: Common Tools Package
5//
6// Copyright 2004 NTESS and the Teuchos contributors.
7// SPDX-License-Identifier: BSD-3-Clause
8// *****************************************************************************
9// @HEADER
10
11#ifndef _TEUCHOS_SERIALSYMDENSEMATRIX_HPP_
12#define _TEUCHOS_SERIALSYMDENSEMATRIX_HPP_
18#include "Teuchos_BLAS.hpp"
22#include "Teuchos_Assert.hpp"
23#include <utility>
24#include <vector>
25
88namespace Teuchos {
89
90template<typename OrdinalType, typename ScalarType>
91class SerialSymDenseMatrix : public CompObject, public BLAS<OrdinalType,ScalarType>
92{
93 public:
94
99
101
102
112
114
124 SerialSymDenseMatrix(OrdinalType numRowsCols, bool zeroOut = true);
125
127
139
142
144
154
156 virtual ~SerialSymDenseMatrix ();
158
160
161
163
172 int shape(OrdinalType numRowsCols);
173
175
184 int shapeUninitialized(OrdinalType numRowsCols);
185
187
197 int reshape(OrdinalType numRowsCols);
198
200
202 void setLower();
203
205
207 void setUpper();
208
210
212
213
215
222
224
229
231
235
237
242 int putScalar( const ScalarType value = Teuchos::ScalarTraits<ScalarType>::zero(), bool fullMatrix = false );
243
245
249
251
254
256
258
259
261
268 ScalarType& operator () (OrdinalType rowIndex, OrdinalType colIndex);
269
271
278 const ScalarType& operator () (OrdinalType rowIndex, OrdinalType colIndex) const;
279
281
283 ScalarType* values() const { return(values_); }
284
286
288
289
291 bool upper() const {return(upper_);};
292
294 char UPLO() const {return(UPLO_);};
296
298
299
301
308
310
314
316
320
322
324
325
327
331
333
337
339
341
342
344 OrdinalType numRows() const { return(numRowCols_); }
345
347 OrdinalType numCols() const { return(numRowCols_); }
348
350 OrdinalType stride() const { return(stride_); }
351
353 bool empty() const { return(numRowCols_ == 0); }
354
356
358
359
362
365
369
371
372
373 virtual std::ostream& print(std::ostream& os) const;
374
376
377 protected:
378
379 // In-place scaling of matrix.
380 void scale( const ScalarType alpha );
381
382 // Copy the values from one matrix to the other.
387
388 // Copy the values from the active triangle of the matrix to the other to make the matrix full symmetric.
389 void copyUPLOMat(bool inputUpper, ScalarType* inputMatrix,
391
392 void deleteArrays();
393 void checkIndex( OrdinalType rowIndex, OrdinalType colIndex = 0 ) const;
394
395 static ScalarType*
396 allocateValues(const OrdinalType numRows,
397 const OrdinalType numCols)
398 {
399 const size_t size = size_t(numRows) * size_t(numCols);
400 return new ScalarType[size];
401 }
402
403 OrdinalType numRowCols_ = 0;
404 OrdinalType stride_ = 0;
405 bool valuesCopied_ = false;
406 ScalarType* values_ = nullptr;
407 bool upper_ = false;
408 char UPLO_ {'L'};
409};
410
411//----------------------------------------------------------------------------------------------------
412// Constructors and Destructor
413//----------------------------------------------------------------------------------------------------
414
415template<typename OrdinalType, typename ScalarType>
417 : numRowCols_(numRowCols_in), stride_(numRowCols_in), valuesCopied_(false), upper_(false), UPLO_('L')
418{
419 values_ = allocateValues(stride_, numRowCols_);
420 valuesCopied_ = true;
421 if (zeroOut) {
423 putScalar(ZERO, true);
424 }
425}
426
427template<typename OrdinalType, typename ScalarType>
430 )
431 : numRowCols_(numRowCols_in), stride_(stride_in), valuesCopied_(false),
432 values_(values_in), upper_(upper_in)
433{
434 if (upper_)
435 UPLO_ = 'U';
436 else
437 UPLO_ = 'L';
438
439 if(CV == Copy)
440 {
441 stride_ = numRowCols_;
442 values_ = allocateValues(stride_, numRowCols_);
443 copyMat(upper_in, values_in, stride_in, numRowCols_, upper_, values_, stride_, 0);
444 valuesCopied_ = true;
445 }
446}
447
448template<typename OrdinalType, typename ScalarType>
450 : CompObject(Source),
451 BLAS<OrdinalType, ScalarType>(Source),
452 numRowCols_(Source.numRowCols_), stride_(0), valuesCopied_(true),
453 values_(0), upper_(Source.upper_), UPLO_(Source.UPLO_)
454{
455 if (!Source.valuesCopied_)
456 {
457 stride_ = Source.stride_;
458 values_ = Source.values_;
459 valuesCopied_ = false;
460 }
461 else
462 {
463 stride_ = numRowCols_;
464 if(stride_ > 0 && numRowCols_ > 0) {
465 values_ = allocateValues(stride_, numRowCols_);
466 copyMat(Source.upper_, Source.values_, Source.stride_, numRowCols_, upper_, values_, stride_, 0);
467 }
468 else {
469 numRowCols_ = 0;
470 stride_ = 0;
471 valuesCopied_ = false;
472 }
473 }
474}
475
476template<typename OrdinalType, typename ScalarType>
481 numRowCols_(numRowCols_in), stride_(Source.stride_), valuesCopied_(false), upper_(Source.upper_), UPLO_(Source.UPLO_)
482{
483 if(CV == Copy)
484 {
485 stride_ = numRowCols_in;
486 values_ = allocateValues(stride_, numRowCols_in);
487 copyMat(Source.upper_, Source.values_, Source.stride_, numRowCols_in, upper_, values_, stride_, startRowCol);
488 valuesCopied_ = true;
489 }
490 else // CV == View
491 {
492 values_ = Source.values_ + (stride_ * startRowCol) + startRowCol;
493 }
494}
495
496template<typename OrdinalType, typename ScalarType>
501
502//----------------------------------------------------------------------------------------------------
503// Shape methods
504//----------------------------------------------------------------------------------------------------
505
506template<typename OrdinalType, typename ScalarType>
508{
509 deleteArrays(); // Get rid of anything that might be already allocated
510 numRowCols_ = numRowCols_in;
511 stride_ = numRowCols_;
512 values_ = allocateValues(stride_, numRowCols_);
513 putScalar( Teuchos::ScalarTraits<ScalarType>::zero(), true );
514 valuesCopied_ = true;
515 return(0);
516}
517
518template<typename OrdinalType, typename ScalarType>
520{
521 deleteArrays(); // Get rid of anything that might be already allocated
522 numRowCols_ = numRowCols_in;
523 stride_ = numRowCols_;
524 values_ = allocateValues(stride_, numRowCols_);
525 valuesCopied_ = true;
526 return(0);
527}
528
529template<typename OrdinalType, typename ScalarType>
531{
532 // Allocate space for new matrix
535 for(OrdinalType k = 0; k < numRowCols_in * numRowCols_in; k++)
536 {
537 values_tmp[k] = zero;
538 }
539 OrdinalType numRowCols_tmp = TEUCHOS_MIN(numRowCols_, numRowCols_in);
540 if(values_ != 0)
541 {
542 copyMat(upper_, values_, stride_, numRowCols_tmp, upper_, values_tmp, numRowCols_in, 0); // Copy principal submatrix of A to new A
543 }
544 deleteArrays(); // Get rid of anything that might be already allocated
545 numRowCols_ = numRowCols_in;
546 stride_ = numRowCols_;
547 values_ = values_tmp; // Set pointer to new A
548 valuesCopied_ = true;
549 return(0);
550}
551
552//----------------------------------------------------------------------------------------------------
553// Set methods
554//----------------------------------------------------------------------------------------------------
555
556template<typename OrdinalType, typename ScalarType>
558{
559 // Do nothing if the matrix is already a lower triangular matrix
560 if (upper_ != false) {
561 copyUPLOMat( true, values_, stride_, numRowCols_ );
562 upper_ = false;
563 UPLO_ = 'L';
564 }
565}
566
567template<typename OrdinalType, typename ScalarType>
569{
570 // Do nothing if the matrix is already an upper triangular matrix
571 if (upper_ == false) {
572 copyUPLOMat( false, values_, stride_, numRowCols_ );
573 upper_ = true;
574 UPLO_ = 'U';
575 }
576}
577
578template<typename OrdinalType, typename ScalarType>
580{
581 // Set each value of the dense matrix to "value".
582 if (fullMatrix == true) {
583 for(OrdinalType j = 0; j < numRowCols_; j++)
584 {
585 for(OrdinalType i = 0; i < numRowCols_; i++)
586 {
587 values_[i + j*stride_] = value_in;
588 }
589 }
590 }
591 // Set the active upper or lower triangular part of the matrix to "value"
592 else {
593 if (upper_) {
594 for(OrdinalType j = 0; j < numRowCols_; j++) {
595 for(OrdinalType i = 0; i <= j; i++) {
596 values_[i + j*stride_] = value_in;
597 }
598 }
599 }
600 else {
601 for(OrdinalType j = 0; j < numRowCols_; j++) {
602 for(OrdinalType i = j; i < numRowCols_; i++) {
603 values_[i + j*stride_] = value_in;
604 }
605 }
606 }
607 }
608 return 0;
609}
610
611template<typename OrdinalType, typename ScalarType> void
614{
615 std::swap(values_ , B.values_);
616 std::swap(numRowCols_, B.numRowCols_);
617 std::swap(stride_, B.stride_);
618 std::swap(valuesCopied_, B.valuesCopied_);
619 std::swap(upper_, B.upper_);
620 std::swap(UPLO_, B.UPLO_);
621}
622
623template<typename OrdinalType, typename ScalarType>
625{
627
628 // Set each value of the dense matrix to a random value.
629 std::vector<MT> diagSum( numRowCols_, Teuchos::ScalarTraits<MT>::zero() );
630 if (upper_) {
631 for(OrdinalType j = 0; j < numRowCols_; j++) {
632 for(OrdinalType i = 0; i < j; i++) {
633 values_[i + j*stride_] = ScalarTraits<ScalarType>::random();
634 diagSum[i] += Teuchos::ScalarTraits<ScalarType>::magnitude( values_[i + j*stride_] );
635 diagSum[j] += Teuchos::ScalarTraits<ScalarType>::magnitude( values_[i + j*stride_] );
636 }
637 }
638 }
639 else {
640 for(OrdinalType j = 0; j < numRowCols_; j++) {
641 for(OrdinalType i = j+1; i < numRowCols_; i++) {
642 values_[i + j*stride_] = ScalarTraits<ScalarType>::random();
643 diagSum[i] += Teuchos::ScalarTraits<ScalarType>::magnitude( values_[i + j*stride_] );
644 diagSum[j] += Teuchos::ScalarTraits<ScalarType>::magnitude( values_[i + j*stride_] );
645 }
646 }
647 }
648
649 // Set the diagonal.
650 for(OrdinalType i = 0; i < numRowCols_; i++) {
651 values_[i + i*stride_] = diagSum[i] + bias;
652 }
653 return 0;
654}
655
656template<typename OrdinalType, typename ScalarType>
659{
660 if(this == &Source)
661 return(*this); // Special case of source same as target
662 if((!valuesCopied_) && (!Source.valuesCopied_) && (values_ == Source.values_)) {
663 upper_ = Source.upper_; // Might have to change the active part of the matrix.
664 return(*this); // Special case of both are views to same data.
665 }
666
667 // If the source is a view then we will return a view, else we will return a copy.
668 if (!Source.valuesCopied_) {
669 if(valuesCopied_) {
670 // Clean up stored data if this was previously a copy.
671 deleteArrays();
672 }
673 numRowCols_ = Source.numRowCols_;
674 stride_ = Source.stride_;
675 values_ = Source.values_;
676 upper_ = Source.upper_;
677 UPLO_ = Source.UPLO_;
678 }
679 else {
680 // If we were a view, we will now be a copy.
681 if(!valuesCopied_) {
682 numRowCols_ = Source.numRowCols_;
683 stride_ = Source.numRowCols_;
684 upper_ = Source.upper_;
685 UPLO_ = Source.UPLO_;
686 if(stride_ > 0 && numRowCols_ > 0) {
687 values_ = allocateValues(stride_, numRowCols_);
688 valuesCopied_ = true;
689 }
690 else {
691 values_ = 0;
692 }
693 }
694 // If we were a copy, we will stay a copy.
695 else {
696 if((Source.numRowCols_ <= stride_) && (Source.numRowCols_ == numRowCols_)) { // we don't need to reallocate
697 numRowCols_ = Source.numRowCols_;
698 upper_ = Source.upper_;
699 UPLO_ = Source.UPLO_;
700 }
701 else { // we need to allocate more space (or less space)
702 deleteArrays();
703 numRowCols_ = Source.numRowCols_;
704 stride_ = Source.numRowCols_;
705 upper_ = Source.upper_;
706 UPLO_ = Source.UPLO_;
707 if(stride_ > 0 && numRowCols_ > 0) {
708 values_ = allocateValues(stride_, numRowCols_);
709 valuesCopied_ = true;
710 }
711 }
712 }
713 copyMat(Source.upper_, Source.values_, Source.stride_, Source.numRowCols_, upper_, values_, stride_, 0);
714 }
715 return(*this);
716}
717
718template<typename OrdinalType, typename ScalarType>
724
725template<typename OrdinalType, typename ScalarType>
727{
728 // Check for compatible dimensions
729 if ((numRowCols_ != Source.numRowCols_))
730 {
731 TEUCHOS_CHK_REF(*this); // Return *this without altering it.
732 }
733 copyMat(Source.upper_, Source.values_, Source.stride_, numRowCols_, upper_, values_, stride_, 0, ScalarTraits<ScalarType>::one());
734 return(*this);
735}
736
737template<typename OrdinalType, typename ScalarType>
739{
740 // Check for compatible dimensions
741 if ((numRowCols_ != Source.numRowCols_))
742 {
743 TEUCHOS_CHK_REF(*this); // Return *this without altering it.
744 }
745 copyMat(Source.upper_, Source.values_, Source.stride_, numRowCols_, upper_, values_, stride_, 0, -ScalarTraits<ScalarType>::one());
746 return(*this);
747}
748
749template<typename OrdinalType, typename ScalarType>
751 if(this == &Source)
752 return(*this); // Special case of source same as target
753 if((!valuesCopied_) && (!Source.valuesCopied_) && (values_ == Source.values_)) {
754 upper_ = Source.upper_; // We may have to change the active part of the matrix.
755 return(*this); // Special case of both are views to same data.
756 }
757
758 // Check for compatible dimensions
759 if ((numRowCols_ != Source.numRowCols_))
760 {
761 TEUCHOS_CHK_REF(*this); // Return *this without altering it.
762 }
763 copyMat(Source.upper_, Source.values_, Source.stride_, numRowCols_, upper_, values_, stride_, 0 );
764 return(*this);
765}
766
767//----------------------------------------------------------------------------------------------------
768// Accessor methods
769//----------------------------------------------------------------------------------------------------
770
771template<typename OrdinalType, typename ScalarType>
773{
774#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
775 checkIndex( rowIndex, colIndex );
776#endif
777 if ( rowIndex <= colIndex ) {
778 // Accessing upper triangular part of matrix
779 if (upper_)
780 return(values_[colIndex * stride_ + rowIndex]);
781 else
782 return(values_[rowIndex * stride_ + colIndex]);
783 }
784 else {
785 // Accessing lower triangular part of matrix
786 if (upper_)
787 return(values_[rowIndex * stride_ + colIndex]);
788 else
789 return(values_[colIndex * stride_ + rowIndex]);
790 }
791}
792
793template<typename OrdinalType, typename ScalarType>
795{
796#ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
797 checkIndex( rowIndex, colIndex );
798#endif
799 if ( rowIndex <= colIndex ) {
800 // Accessing upper triangular part of matrix
801 if (upper_)
802 return(values_[colIndex * stride_ + rowIndex]);
803 else
804 return(values_[rowIndex * stride_ + colIndex]);
805 }
806 else {
807 // Accessing lower triangular part of matrix
808 if (upper_)
809 return(values_[rowIndex * stride_ + colIndex]);
810 else
811 return(values_[colIndex * stride_ + rowIndex]);
812 }
813}
814
815//----------------------------------------------------------------------------------------------------
816// Norm methods
817//----------------------------------------------------------------------------------------------------
818
819template<typename OrdinalType, typename ScalarType>
824
825template<typename OrdinalType, typename ScalarType>
827{
829
830 OrdinalType i, j;
831
834
835 if (upper_) {
836 for (j=0; j<numRowCols_; j++) {
838 ptr = values_ + j*stride_;
839 for (i=0; i<j; i++) {
841 }
842 ptr = values_ + j + j*stride_;
843 for (i=j; i<numRowCols_; i++) {
845 ptr += stride_;
846 }
847 anorm = TEUCHOS_MAX( anorm, sum );
848 }
849 }
850 else {
851 for (j=0; j<numRowCols_; j++) {
853 ptr = values_ + j + j*stride_;
854 for (i=j; i<numRowCols_; i++) {
856 }
857 ptr = values_ + j;
858 for (i=0; i<j; i++) {
860 ptr += stride_;
861 }
862 anorm = TEUCHOS_MAX( anorm, sum );
863 }
864 }
865 return(anorm);
866}
867
868template<typename OrdinalType, typename ScalarType>
870{
872
873 OrdinalType i, j;
874
876
877 if (upper_) {
878 for (j = 0; j < numRowCols_; j++) {
879 for (i = 0; i < j; i++) {
880 sum += ScalarTraits<ScalarType>::magnitude(2.0*values_[i+j*stride_]*values_[i+j*stride_]);
881 }
882 sum += ScalarTraits<ScalarType>::magnitude(values_[j + j*stride_]*values_[j + j*stride_]);
883 }
884 }
885 else {
886 for (j = 0; j < numRowCols_; j++) {
887 sum += ScalarTraits<ScalarType>::magnitude(values_[j + j*stride_]*values_[j + j*stride_]);
888 for (i = j+1; i < numRowCols_; i++) {
889 sum += ScalarTraits<ScalarType>::magnitude(2.0*values_[i+j*stride_]*values_[i+j*stride_]);
890 }
891 }
892 }
894 return(anorm);
895}
896
897//----------------------------------------------------------------------------------------------------
898// Comparison methods
899//----------------------------------------------------------------------------------------------------
900
901template<typename OrdinalType, typename ScalarType>
903{
904 bool result = 1;
905 if((numRowCols_ != Operand.numRowCols_)) {
906 result = 0;
907 }
908 else {
909 OrdinalType i, j;
910 for(i = 0; i < numRowCols_; i++) {
911 for(j = 0; j < numRowCols_; j++) {
912 if((*this)(i, j) != Operand(i, j)) {
913 return 0;
914 }
915 }
916 }
917 }
918 return result;
919}
920
921template<typename OrdinalType, typename ScalarType>
926
927//----------------------------------------------------------------------------------------------------
928// Multiplication method
929//----------------------------------------------------------------------------------------------------
930
931template<typename OrdinalType, typename ScalarType>
933{
934 OrdinalType i, j;
936
937 if (upper_) {
938 for (j=0; j<numRowCols_; j++) {
939 ptr = values_ + j*stride_;
940 for (i=0; i<= j; i++) { *ptr = alpha * (*ptr); ptr++; }
941 }
942 }
943 else {
944 for (j=0; j<numRowCols_; j++) {
945 ptr = values_ + j*stride_ + j;
946 for (i=j; i<numRowCols_; i++) { *ptr = alpha * (*ptr); ptr++; }
947 }
948 }
949}
950
951/*
952template<typename OrdinalType, typename ScalarType>
953int SerialSymDenseMatrix<OrdinalType, ScalarType>::scale( const SerialSymDenseMatrix<OrdinalType,ScalarType>& A )
954{
955 OrdinalType i, j;
956 ScalarType* ptr;
957
958 // Check for compatible dimensions
959 if ((numRowCols_ != A.numRowCols_)) {
960 TEUCHOS_CHK_ERR(-1); // Return error
961 }
962
963 if (upper_) {
964 for (j=0; j<numRowCols_; j++) {
965 ptr = values_ + j*stride_;
966 for (i=0; i<= j; i++) { *ptr = A(i,j) * (*ptr); ptr++; }
967 }
968 }
969 else {
970 for (j=0; j<numRowCols_; j++) {
971 ptr = values_ + j*stride_;
972 for (i=j; i<numRowCols_; i++) { *ptr = A(i,j) * (*ptr); ptr++; }
973 }
974 }
975
976 return(0);
977}
978*/
979
980template<typename OrdinalType, typename ScalarType>
981std::ostream& SerialSymDenseMatrix<OrdinalType, ScalarType>::print(std::ostream& os) const
982{
983 os << std::endl;
984 if(valuesCopied_)
985 os << "Values_copied : yes" << std::endl;
986 else
987 os << "Values_copied : no" << std::endl;
988 os << "Rows / Columns : " << numRowCols_ << std::endl;
989 os << "LDA : " << stride_ << std::endl;
990 if (upper_)
991 os << "Storage: Upper" << std::endl;
992 else
993 os << "Storage: Lower" << std::endl;
994 if(numRowCols_ == 0) {
995 os << "(matrix is empty, no values to display)" << std::endl;
996 } else {
997 for(OrdinalType i = 0; i < numRowCols_; i++) {
998 for(OrdinalType j = 0; j < numRowCols_; j++){
999 os << (*this)(i,j) << " ";
1000 }
1001 os << std::endl;
1002 }
1003 }
1004 return os;
1005}
1006
1007//----------------------------------------------------------------------------------------------------
1008// Protected methods
1009//----------------------------------------------------------------------------------------------------
1010
1011template<typename OrdinalType, typename ScalarType>
1013 TEUCHOS_TEST_FOR_EXCEPTION(rowIndex < 0 || rowIndex >= numRowCols_, std::out_of_range,
1014 "SerialSymDenseMatrix<T>::checkIndex: "
1015 "Row index " << rowIndex << " out of range [0, "<< numRowCols_ << ")");
1016 TEUCHOS_TEST_FOR_EXCEPTION(colIndex < 0 || colIndex >= numRowCols_, std::out_of_range,
1017 "SerialSymDenseMatrix<T>::checkIndex: "
1018 "Col index " << colIndex << " out of range [0, "<< numRowCols_ << ")");
1019}
1020
1021template<typename OrdinalType, typename ScalarType>
1022void SerialSymDenseMatrix<OrdinalType, ScalarType>::deleteArrays(void)
1023{
1024 if (valuesCopied_)
1025 {
1026 delete [] values_;
1027 values_ = 0;
1028 valuesCopied_ = false;
1029 }
1030}
1031
1032template<typename OrdinalType, typename ScalarType>
1033void SerialSymDenseMatrix<OrdinalType, ScalarType>::copyMat(
1034 bool inputUpper, ScalarType* inputMatrix,
1035 OrdinalType inputStride, OrdinalType numRowCols_in,
1036 bool outputUpper, ScalarType* outputMatrix,
1037 OrdinalType outputStride, OrdinalType startRowCol,
1038 ScalarType alpha
1039 )
1040{
1041 OrdinalType i, j;
1042 ScalarType* ptr1 = 0;
1043 ScalarType* ptr2 = 0;
1044
1045 for (j = 0; j < numRowCols_in; j++) {
1046 if (inputUpper == true) {
1047 // The input matrix is upper triangular, start at the beginning of each column.
1048 ptr2 = inputMatrix + (j + startRowCol) * inputStride + startRowCol;
1049 if (outputUpper == true) {
1050 // The output matrix matches the same pattern as the input matrix.
1051 ptr1 = outputMatrix + j*outputStride;
1053 for(i = 0; i <= j; i++) {
1054 *ptr1++ += alpha*(*ptr2++);
1055 }
1056 } else {
1057 for(i = 0; i <= j; i++) {
1058 *ptr1++ = *ptr2++;
1059 }
1060 }
1061 }
1062 else {
1063 // The output matrix has the opposite pattern as the input matrix.
1064 // Copy down across rows of the output matrix, but down columns of the input matrix.
1065 ptr1 = outputMatrix + j;
1067 for(i = 0; i <= j; i++) {
1068 *ptr1 += alpha*(*ptr2++);
1069 ptr1 += outputStride;
1070 }
1071 } else {
1072 for(i = 0; i <= j; i++) {
1073 *ptr1 = *ptr2++;
1074 ptr1 += outputStride;
1075 }
1076 }
1077 }
1078 }
1079 else {
1080 // The input matrix is lower triangular, start at the diagonal of each row.
1081 ptr2 = inputMatrix + (startRowCol+j) * inputStride + startRowCol + j;
1082 if (outputUpper == true) {
1083 // The output matrix has the opposite pattern as the input matrix.
1084 // Copy across rows of the output matrix, but down columns of the input matrix.
1085 ptr1 = outputMatrix + j*outputStride + j;
1087 for(i = j; i < numRowCols_in; i++) {
1088 *ptr1 += alpha*(*ptr2++);
1089 ptr1 += outputStride;
1090 }
1091 } else {
1092 for(i = j; i < numRowCols_in; i++) {
1093 *ptr1 = *ptr2++;
1094 ptr1 += outputStride;
1095 }
1096 }
1097 }
1098 else {
1099 // The output matrix matches the same pattern as the input matrix.
1100 ptr1 = outputMatrix + j*outputStride + j;
1102 for(i = j; i < numRowCols_in; i++) {
1103 *ptr1++ += alpha*(*ptr2++);
1104 }
1105 } else {
1106 for(i = j; i < numRowCols_in; i++) {
1107 *ptr1++ = *ptr2++;
1108 }
1109 }
1110 }
1111 }
1112 }
1113}
1114
1115template<typename OrdinalType, typename ScalarType>
1116void SerialSymDenseMatrix<OrdinalType, ScalarType>::copyUPLOMat(
1117 bool inputUpper, ScalarType* inputMatrix,
1118 OrdinalType inputStride, OrdinalType inputRows
1119 )
1120{
1121 OrdinalType i, j;
1122 ScalarType * ptr1 = 0;
1123 ScalarType * ptr2 = 0;
1124
1125 if (inputUpper) {
1126 for (j=1; j<inputRows; j++) {
1127 ptr1 = inputMatrix + j;
1128 ptr2 = inputMatrix + j*inputStride;
1129 for (i=0; i<j; i++) {
1130 *ptr1 = *ptr2++;
1131 ptr1+=inputStride;
1132 }
1133 }
1134 }
1135 else {
1136 for (i=1; i<inputRows; i++) {
1137 ptr1 = inputMatrix + i;
1138 ptr2 = inputMatrix + i*inputStride;
1139 for (j=0; j<i; j++) {
1140 *ptr2++ = *ptr1;
1141 ptr1+=inputStride;
1142 }
1143 }
1144 }
1145}
1146
1148template<typename OrdinalType, typename ScalarType>
1156
1158template<typename OrdinalType, typename ScalarType>
1159std::ostream&
1160operator<<(std::ostream &out,
1162{
1163 printer.obj.print(out);
1164 return out;
1165}
1166
1168template<typename OrdinalType, typename ScalarType>
1169SerialSymDenseMatrixPrinter<OrdinalType,ScalarType>
1174
1175
1176} // namespace Teuchos
1177
1178#endif /* _TEUCHOS_SERIALSYMDENSEMATRIX_HPP_ */
Templated interface class to BLAS routines.
Object for storing data and providing functionality that is common to all computational classes.
Teuchos header file which uses auto-configuration information to include necessary C++ headers.
Teuchos::DataAccess Mode enumerable type.
Defines basic traits for the scalar field type.
Templated BLAS wrapper.
Functionality and data that is common to all computational classes.
Smart reference counting pointer class for automatic garbage collection.
Ptr< T > ptr() const
Get a safer wrapper raw C++ pointer to the underlying object.
This class creates and provides basic support for symmetric, positive-definite dense matrices of temp...
SerialSymDenseMatrix()=default
Default constructor; defines a zero size object.
bool operator==(const SerialSymDenseMatrix< OrdinalType, ScalarType > &Operand) const
Equality of two matrices.
int shapeUninitialized(OrdinalType numRowsCols)
Set dimensions of a Teuchos::SerialSymDenseMatrix object; don't initialize values.
int shape(OrdinalType numRowsCols)
Set dimensions of a Teuchos::SerialSymDenseMatrix object; init values to zero.
ScalarTraits< ScalarType >::magnitudeType normFrobenius() const
Returns the Frobenius-norm of the matrix.
ScalarType & operator()(OrdinalType rowIndex, OrdinalType colIndex)
Element access method (non-const).
OrdinalType stride() const
Returns the stride between the columns of this matrix in memory.
SerialSymDenseMatrix< OrdinalType, ScalarType > & operator-=(const SerialSymDenseMatrix< OrdinalType, ScalarType > &Source)
Subtract another matrix from this matrix.
virtual std::ostream & print(std::ostream &os) const
Print method. Defines the behavior of the std::ostream << operator.
SerialSymDenseMatrix< OrdinalType, ScalarType > & operator+=(const SerialSymDenseMatrix< OrdinalType, ScalarType > &Source)
Add another matrix to this matrix.
bool operator!=(const SerialSymDenseMatrix< OrdinalType, ScalarType > &Operand) const
Inequality of two matrices.
void swap(SerialSymDenseMatrix< OrdinalType, ScalarType > &B)
Swap values between this matrix and incoming matrix.
OrdinalType numCols() const
Returns the column dimension of this matrix.
int putScalar(const ScalarType value=Teuchos::ScalarTraits< ScalarType >::zero(), bool fullMatrix=false)
Set all values in the matrix to a constant value.
virtual ~SerialSymDenseMatrix()
Teuchos::SerialSymDenseMatrix destructor.
char UPLO() const
Returns character value of UPLO used by LAPACK routines.
SerialSymDenseMatrix< OrdinalType, ScalarType > & operator*=(const ScalarType alpha)
Inplace scalar-matrix product A = alpha*A.
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.
ScalarType scalarType
Typedef for scalar type.
bool upper() const
Returns true if upper triangular part of this matrix has and will be used.
ScalarTraits< ScalarType >::magnitudeType normInf() const
Returns the Infinity-norm of the matrix.
ScalarType * values() const
Returns the pointer to the ScalarType data array contained in the object.
SerialSymDenseMatrix< OrdinalType, ScalarType > & operator=(const SerialSymDenseMatrix< OrdinalType, ScalarType > &Source)
Copies values from one matrix to another.
bool empty() const
Returns whether this matrix is empty.
SerialSymDenseMatrix< OrdinalType, ScalarType > & assign(const SerialSymDenseMatrix< OrdinalType, ScalarType > &Source)
Copies values from one matrix to another.
void setLower()
Specify that the lower triangle of the this matrix should be used.
int reshape(OrdinalType numRowsCols)
Reshape a Teuchos::SerialSymDenseMatrix object.
OrdinalType numRows() const
Returns the row dimension of this matrix.
void setUpper()
Specify that the upper triangle of the this matrix should be used.
ScalarTraits< ScalarType >::magnitudeType normOne() const
Returns the 1-norm of the matrix.
OrdinalType ordinalType
Typedef for ordinal type.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos,...
SerialBandDenseMatrixPrinter< OrdinalType, ScalarType > printMat(const SerialBandDenseMatrix< OrdinalType, ScalarType > &obj)
Return SerialBandDenseMatrix ostream manipulator Use as:
This structure defines some basic traits for a scalar field type.
static magnitudeType magnitude(T a)
Returns the magnitudeType of the scalar type a.
T magnitudeType
Mandatory typedef for result of magnitude.
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.
Ostream manipulator for SerialSymDenseMatrix.