1 // @HEADER
2 // ***********************************************************************
3 //
4 // Teuchos: Common Tools Package
5 // Copyright (2004) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41
42 #ifndef _TEUCHOS_SERIALBANDDENSEMATRIX_HPP_
43 #define _TEUCHOS_SERIALBANDDENSEMATRIX_HPP_
44 /*! \file Teuchos_SerialBandDenseMatrix.hpp
45 \brief Templated serial dense matrix class
46 */
47
48 #include "Teuchos_CompObject.hpp"
49 #include "Teuchos_BLAS.hpp"
50 #include "Teuchos_ScalarTraits.hpp"
51 #include "Teuchos_DataAccess.hpp"
52 #include "Teuchos_ConfigDefs.hpp"
53 #include "Teuchos_RCP.hpp"
54 #include "Teuchos_Assert.hpp"
55
56 /*! \class Teuchos::SerialBandDenseMatrix
57 \brief This class creates and provides basic support for banded dense matrices of templated type.
58
59 The Teuchos_SerialBandDenseMatrix class enables the construction and use of banded dense matrices of templated type.
60
61 The Teuchos::SerialBandDenseMatrix class is intended to provide full-featured support for solving
62 linear and eigen system problems for banded matrices. It is written on
63 top of BLAS and LAPACK and thus has excellent performance and numerical capabilities. Using this
64 class, one can either perform simple factorizations and solves or apply all the tricks available in
65 LAPACK to get the best possible solution for very ill-conditioned problems.
66
67 <b>Teuchos::SerialBandDenseMatrix vs. Teuchos::LAPACK</b>
68
69 The Teuchos::LAPACK class provides access to most of the same functionality as Teuchos::SerialBandDenseMatrix.
70 The primary difference is that Teuchos::LAPACK is a "thin" layer on top of LAPACK and
71 Teuchos::SerialBandDenseMatrix attempts to provide easy access to the more sophisticated aspects of
72 solving dense linear and eigensystems.
73 <ul>
74 <li> When you should use Teuchos::LAPACK: If you are simply looking for a convenient wrapper around
75 the Fortran LAPACK routines and you have a well-conditioned problem, you should probably use Teuchos::LAPACK directly.
76 <li> When you should use Teuchos::SerialBandDenseMatrix: If you want to (or potentially want to) solve ill-conditioned
77 problems or want to work with a more object-oriented interface, you should probably use Teuchos::SerialBandDenseMatrix.
78 </ul>
79
80 <b>Constructing Teuchos::SerialBandDenseMatrix Objects</b>
81
82 There are three Teuchos::SerialBandDenseMatrix constructors. The first constructs a zero-sized object
83 which should be made to appropriate length using the Shape() or Reshape() functions and then filled with
84 the [] or () operators. The second is a constructor that accepts user data as a 2D array, the third is a
85 copy constructor. The second constructor has two data access modes (specified by the Teuchos::DataAccess argument):
86 <ol>
87 <li> Copy mode - Allocates memory and makes a copy of the user-provided data. In this case, the
88 user data is not needed after construction.
89 <li> View mode - Creates a "view" of the user data. In this case, the
90 user data is required to remain intact for the life of the object.
91 </ol>
92
93 \warning View mode is \e extremely dangerous from a data hiding perspective. Therefore, we strongly encourage
94 users to develop code using Copy mode first and only use the View mode in a secondary optimization phase.
95
96 <b>Format of the matrix A</b>
97
98 The matrix A is stored as a banded matrix AB according to the LAPACK format. Consider using
99 the non-member conversion routines generalToBanded and bandedToGeneral if the full Teuchos::SerialDenseMatrix is
100 already in storage. However, it is more efficient to simply construct the Teuchos::SerialBandDenseMatrix with the desired
101 parameters and use the provided matrix access operators to assign (legal) entries so that the full
102 rectangular matrix does not need to be stored. A full description of the LAPACK banded format can be found at
103 http://www.netlib.org/lapack/lug/node124.html. Briefly, the banded storage format of AB used internally is as follows:
104 <ul>
105 <li> The dimension of AB is KL+KU+1 by N, where KL and KU are the lower and upper bandwidths, respectively.
106 <li> The entries are stored in a compressed format: AB(KU+i-j,j) = A(i,j) for max(0,j-KU)<=i<=min(M-1,j+KL).
107 </ul>
108
109 <b>Extracting Data from Teuchos::SerialBandDenseMatrix Objects</b>
110
111 Once a Teuchos::SerialBandDenseMatrix is constructed, it is possible to view the data via access functions.
112
113 \warning Use of these access functions cam be \e extremely dangerous from a data hiding perspective.
114
115 <b>Vector and Utility Functions</b>
116
117 Once a Teuchos::SerialBandDenseMatrix is constructed, several mathematical functions can be applied to
118 the object. Specifically:
119 <ul>
120 <li> Multiplication.
121 <li> Norms.
122 </ul>
123
124 */
125
126 /** \example DenseMatrix/cxx_main_band.cpp
127 This is an example of how to use the Teuchos::SerialBandDenseMatrix class.
128 */
129
130 namespace Teuchos {
131
132 template<typename OrdinalType, typename ScalarType>
133 class SerialBandDenseMatrix : public CompObject, public BLAS<OrdinalType, ScalarType>
134 {
135 public:
136
137 //! Typedef for ordinal type
138 typedef OrdinalType ordinalType;
139 //! Typedef for scalar type
140 typedef ScalarType scalarType;
141
142 //! @name Constructor/Destructor methods.
143 //@{
144
145 //! Default Constructor
146 /*! Creates a empty matrix of no dimension. The Shaping methods should be used to size this matrix.
147 Values of this matrix should be set using the [], (), or = operators.
148 */
149 SerialBandDenseMatrix();
150
151 //! Shaped Constructor
152 /*!
153 \param numRows - Number of rows in matrix.
154 \param numCols - Number of columns in matrix.
155 \param kl - Lower bandwidth of matrix.
156 \param ku - Upper bandwidth of matrix.
157 \param zeroOut - Initializes values to 0 if true (default)
158
159 Creates a shaped matrix with \c numRows rows and \c numCols cols. All values are initialized to 0 when \c zeroOut is true.
160 Values of this matrix should be set using the [] or the () operators.
161 */
162 SerialBandDenseMatrix(OrdinalType numRows, OrdinalType numCols, OrdinalType kl, OrdinalType ku, bool zeroOut = true);
163
164 //! Shaped Constructor with Values
165 /*!
166 \param CV - Enumerated type set to Teuchos::Copy or Teuchos::View.
167 \param values - Pointer to an array of ScalarType. The first column starts at \c values,
168 the second at \c values+stride, etc.
169 \param stride - The stride between the columns of the matrix in memory.
170 \param numRows - Number of rows in matrix.
171 \param numCols - Number of columns in matrix.
172 \param kl - Lower bandwidth of matrix.
173 \param ku - Upper bandwidth of matrix.
174 */
175 SerialBandDenseMatrix(DataAccess CV, ScalarType* values, OrdinalType stride, OrdinalType numRows, OrdinalType numCols, OrdinalType kl, OrdinalType ku);
176
177 //! Copy Constructor
178 /*! \note A deep copy of the \c Source transposed can be obtained if \c trans=Teuchos::TRANS, \c else
179 a non-transposed copy of \c Source is made. There is no storage of the transpose state of the matrix
180 within the SerialBandDenseMatrix class, so this information will not propogate to any operation performed
181 on a matrix that has been copy constructed in transpose.
182 */
183 SerialBandDenseMatrix(const SerialBandDenseMatrix<OrdinalType, ScalarType> &Source, ETransp trans = Teuchos::NO_TRANS);
184
185 //! Submatrix Copy Constructor
186 /*!
187 \param CV - Enumerated type set to Teuchos::Copy or Teuchos::View.
188 \param Source - Reference to another dense matrix from which values are to be copied.
189 \param numRows - The number of rows in this matrix.
190 \param numCols - The number of columns in this matrix.
191 \param kl - Lower bandwidth of matrix.
192 \param ku - Upper bandwidth of matrix.
193 \param startRow - The row of \c Source from which the submatrix copy should start.
194 \param startCol - The column of \c Source from which the submatrix copy should start.
195
196 Creates a shaped matrix with \c numRows rows and \c numCols columns, which is a submatrix of \c Source.
197 If \c startRow and \c startCol are not given, then the submatrix is the leading submatrix of \c Source.
198 Otherwise, the (1,1) entry in the copied matrix is the (\c startRow, \c startCol) entry of \c Source.
199 */
200 SerialBandDenseMatrix(DataAccess CV, const SerialBandDenseMatrix<OrdinalType, ScalarType> &Source, OrdinalType numRows, OrdinalType numCols, OrdinalType startCol=0);
201
202 //! Destructor
203 virtual ~SerialBandDenseMatrix();
204 //@}
205
206 //! @name Shaping methods.
207 //@{
208 //! Shape method for changing the size of a SerialBandDenseMatrix, initializing entries to zero.
209 /*!
210 \param numRows - The number of rows in this matrix.
211 \param numCols - The number of columns in this matrix.
212 \param kl - Lower bandwidth of matrix.
213 \param ku - Upper bandwidth of matrix.
214
215 This method allows the user to define the dimensions of a SerialBandDenseMatrix at any point. This method
216 can be called at any point after construction. Any values previously in this object will be destroyed
217 and the resized matrix starts of with all zero values.
218
219 \return Integer error code, set to 0 if successful.
220 */
221 int shape(OrdinalType numRows, OrdinalType numCols, OrdinalType kl, OrdinalType ku);
222
223 //! Same as <tt>shape()</tt> except leaves uninitialized.
224 int shapeUninitialized(OrdinalType numRows, OrdinalType numCols, OrdinalType kl, OrdinalType ku);
225
226 //! Reshaping method for changing the size of a SerialBandDenseMatrix, keeping the entries.
227 /*!
228 \param numRows - The number of rows in this matrix.
229 \param numCols - The number of columns in this matrix.
230 \param kl - Lower bandwidth of matrix.
231 \param ku - Upper bandwidth of matrix.
232
233 This method allows the user to redefine the dimensions of a SerialBandDenseMatrix at any point. This method
234 can be called at any point after construction. Any values previously in this object will be copied into
235 the reshaped matrix.
236
237 \return Integer error code, set 0 if successful.
238 */
239 int reshape(OrdinalType numRows, OrdinalType numCols, OrdinalType kl, OrdinalType ku);
240
241
242 //@}
243
244 //! @name Set methods.
245 //@{
246
247 //! Copies values from one matrix to another.
248 /*!
249 The operator= copies the values from one existing SerialBandDenseMatrix to another.
250 If \c Source is a view (i.e. CV = Teuchos::View), then this method will
251 return a view. Otherwise, it will return a copy of \c Source. \e this object
252 will be resized if it is not large enough to copy \c Source into.
253 */
254 SerialBandDenseMatrix<OrdinalType, ScalarType>& operator= (const SerialBandDenseMatrix<OrdinalType, ScalarType>& Source);
255
256 //! Copies values from one matrix to another.
257 /*!
258 The operator= copies the values from one existing SerialBandDenseMatrix to another
259 if the dimension of both matrices are the same. If not, \e this matrix
260 will be returned unchanged.
261 */
262 SerialBandDenseMatrix<OrdinalType, ScalarType>& assign (const SerialBandDenseMatrix<OrdinalType, ScalarType>& Source);
263
264 //! Set all values in the matrix to a constant value.
265 /*!
266 \param value - Value to use;
267 */
operator =(const ScalarType value)268 SerialBandDenseMatrix<OrdinalType, ScalarType>& operator= (const ScalarType value) { putScalar(value); return(*this); }
269
270 //! Set all values in the matrix to a constant value.
271 /*!
272 \param value - Value to use; zero if none specified.
273 \return Integer error code, set to 0 if successful.
274 */
275 int putScalar( const ScalarType value = Teuchos::ScalarTraits<ScalarType>::zero() );
276
277 //! Set all values in the matrix to be random numbers.
278 int random();
279
280 //@}
281
282 //! @name Accessor methods.
283 //@{
284
285 //! Element access method (non-const).
286 /*! Returns the element in the ith row and jth column if A(i,j) is specified, the
287 expression A[j][i] will return the same element.
288
289 \return Element from the specified \c rowIndex row and \c colIndex column.
290 \warning The validity of \c rowIndex and \c colIndex will only be checked if Teuchos is
291 configured with --enable-teuchos-abc.
292 */
293 ScalarType& operator () (OrdinalType rowIndex, OrdinalType colIndex);
294
295 //! Element access method (const).
296 /*! Returns the element in the ith row and jth column if A(i,j) is specified, the expression
297 A[j][i] will return the same element.
298
299 \return Element from the specified \c rowIndex row and \c colIndex column.
300 \warning The validity of \c rowIndex and \c colIndex will only be checked if Teuchos is
301 configured with --enable-teuchos-abc.
302 */
303 const ScalarType& operator () (OrdinalType rowIndex, OrdinalType colIndex) const;
304
305 //! Column access method (non-const).
306 /*! Returns the pointer to the ScalarType array at the jth column if A[j] is specified, the expression
307 A[j][i] will return the same element as A(i,j).
308
309 \return Pointer to the ScalarType array at the \c colIndex column ( \c values_+colIndex*stride_ ).
310 \warning The validity of \c colIndex will only be checked if Teuchos is configured with
311 --enable-teuchos-abc.
312 */
313 ScalarType* operator [] (OrdinalType colIndex);
314
315 //! Column access method (const).
316 /*! Returns the pointer to the ScalarType array at the jth column if A[j] is specified, the expression
317 A[j][i] will return the same element as A(i,j).
318
319 \return Pointer to the ScalarType array at the \c colIndex column ( \c values_+colIndex*stride_ ).
320 \warning The validity of \c colIndex will only be checked if Teuchos is configured with
321 --enable-teuchos-abc.
322 */
323 const ScalarType* operator [] (OrdinalType colIndex) const;
324
325 //! Data array access method.
326 /*! \return Pointer to the ScalarType data array contained in the object. */
values() const327 ScalarType* values() const { return(values_); }
328
329 //@}
330
331 //! @name Mathematical methods.
332 //@{
333
334 //! Add another matrix to \e this matrix.
335 /*! Add \c Source to \e this if the dimension of both matrices are the same. If not, \e this matrix
336 will be returned unchanged.
337 */
338 SerialBandDenseMatrix<OrdinalType, ScalarType>& operator+= (const SerialBandDenseMatrix<OrdinalType, ScalarType>& Source);
339
340 //! Subtract another matrix from \e this matrix.
341 /*! Subtract \c Source from \e this if the dimension of both matrices are the same. If not, \e this matrix
342 will be returned unchanged.
343 */
344 SerialBandDenseMatrix<OrdinalType, ScalarType>& operator-= (const SerialBandDenseMatrix<OrdinalType, ScalarType>& Source);
345
346 //! Scale \c this matrix by \c alpha; \c *this = \c alpha*\c *this.
347 /*!
348 \param alpha Scalar to multiply \e this by.
349 */
350 SerialBandDenseMatrix<OrdinalType, ScalarType>& operator*= (const ScalarType alpha);
351
352 //! Scale \c this matrix by \c alpha; \c *this = \c alpha*\c *this.
353 /*!
354 \param alpha Scalar to multiply \e this by.
355 \return Integer error code, set to 0 if successful.
356 */
357 int scale ( const ScalarType alpha );
358
359 //! Point-wise scale \c this matrix by \c A; i.e. *this(i,j) *= A(i,j)
360 /*! The values of \c *this matrix will be point-wise scaled by the values in A.
361 If A and \c this matrix are not the same dimension \c this will be returned unchanged.
362
363 \param B Teuchos::SerialBandDenseMatrix used to perform element-wise scaling of \e this.
364 \return Integer error code, set to 0 if successful.
365 */
366 int scale ( const SerialBandDenseMatrix<OrdinalType, ScalarType>& A );
367
368 //@}
369
370 //! @name Comparison methods.
371 //@{
372
373 //! Equality of two matrices.
374 /*! \return True if \e this matrix and \c Operand are of the same shape (rows and columns) and have
375 the same entries, else False will be returned.
376 */
377 bool operator== (const SerialBandDenseMatrix<OrdinalType, ScalarType> &Operand) const;
378
379 //! Inequality of two matrices.
380 /*! \return True if \e this matrix and \c Operand of not of the same shape (rows and columns) or don't
381 have the same entries, else False will be returned.
382 */
383 bool operator!= (const SerialBandDenseMatrix<OrdinalType, ScalarType> &Operand) const;
384
385 //@}
386
387 //! @name Attribute methods.
388 //@{
389
390 //! Returns the row dimension of this matrix.
numRows() const391 OrdinalType numRows() const { return(numRows_); }
392
393 //! Returns the column dimension of this matrix.
numCols() const394 OrdinalType numCols() const { return(numCols_); }
395
396 //! Returns the lower bandwidth of this matrix.
lowerBandwidth() const397 OrdinalType lowerBandwidth() const { return(kl_); }
398
399 //! Returns the upper bandwidth of this matrix.
upperBandwidth() const400 OrdinalType upperBandwidth() const { return(ku_); }
401
402 //! Returns the stride between the columns of this matrix in memory.
stride() const403 OrdinalType stride() const { return(stride_); }
404
405 //! Returns whether this matrix is empty.
empty() const406 bool empty() const { return(numRows_ == 0 || numCols_ == 0); }
407 //@}
408
409 //! @name Norm methods.
410 //@{
411
412 //! Returns the 1-norm of the matrix.
413 typename ScalarTraits<ScalarType>::magnitudeType normOne() const;
414
415 //! Returns the Infinity-norm of the matrix.
416 typename ScalarTraits<ScalarType>::magnitudeType normInf() const;
417
418 //! Returns the Frobenius-norm of the matrix.
419 typename ScalarTraits<ScalarType>::magnitudeType normFrobenius() const;
420 //@}
421
422 //! @name I/O methods.
423 //@{
424 //! Print method. Defines the behavior of the std::ostream << operator
425
426 virtual std::ostream& print(std::ostream& os) const;
427
428
429 //@}
430 protected:
431 void copyMat(ScalarType* inputMatrix, OrdinalType strideInput,
432 OrdinalType numRows, OrdinalType numCols, ScalarType* outputMatrix,
433 OrdinalType strideOutput, OrdinalType startCol, ScalarType alpha = ScalarTraits<ScalarType>::zero() );
434 void deleteArrays();
435 void checkIndex( OrdinalType rowIndex, OrdinalType colIndex = 0 ) const;
436 OrdinalType numRows_;
437 OrdinalType numCols_;
438 OrdinalType stride_;
439 OrdinalType kl_;
440 OrdinalType ku_;
441 bool valuesCopied_;
442 ScalarType* values_;
443
444 }; // class Teuchos_SerialBandDenseMatrix
445
446 //----------------------------------------------------------------------------------------------------
447 // Constructors and Destructor
448 //----------------------------------------------------------------------------------------------------
449
450 template<typename OrdinalType, typename ScalarType>
SerialBandDenseMatrix()451 SerialBandDenseMatrix<OrdinalType, ScalarType>::SerialBandDenseMatrix ()
452 : CompObject (),
453 BLAS<OrdinalType,ScalarType>(),
454 numRows_ (0),
455 numCols_ (0),
456 stride_ (0),
457 kl_ (0),
458 ku_ (0),
459 valuesCopied_ (false),
460 values_ (0)
461 {}
462
463 template<typename OrdinalType, typename ScalarType>
464 SerialBandDenseMatrix<OrdinalType, ScalarType>::
SerialBandDenseMatrix(OrdinalType numRows_in,OrdinalType numCols_in,OrdinalType kl_in,OrdinalType ku_in,bool zeroOut)465 SerialBandDenseMatrix (OrdinalType numRows_in,
466 OrdinalType numCols_in,
467 OrdinalType kl_in,
468 OrdinalType ku_in,
469 bool zeroOut)
470 : CompObject (),
471 BLAS<OrdinalType,ScalarType>(),
472 numRows_ (numRows_in),
473 numCols_ (numCols_in),
474 stride_ (kl_in+ku_in+1),
475 kl_ (kl_in),
476 ku_ (ku_in),
477 valuesCopied_ (true),
478 values_ (NULL) // for safety, in case allocation fails below
479 {
480 values_ = new ScalarType[stride_ * numCols_];
481 if (zeroOut) {
482 putScalar ();
483 }
484 }
485
486 template<typename OrdinalType, typename ScalarType>
487 SerialBandDenseMatrix<OrdinalType, ScalarType>::
SerialBandDenseMatrix(DataAccess CV,ScalarType * values_in,OrdinalType stride_in,OrdinalType numRows_in,OrdinalType numCols_in,OrdinalType kl_in,OrdinalType ku_in)488 SerialBandDenseMatrix (DataAccess CV,
489 ScalarType* values_in,
490 OrdinalType stride_in,
491 OrdinalType numRows_in,
492 OrdinalType numCols_in,
493 OrdinalType kl_in,
494 OrdinalType ku_in)
495 : CompObject (),
496 BLAS<OrdinalType,ScalarType>(),
497 numRows_ (numRows_in),
498 numCols_ (numCols_in),
499 stride_ (stride_in),
500 kl_ (kl_in),
501 ku_ (ku_in),
502 valuesCopied_ (false),
503 values_ (values_in)
504 {
505 if (CV == Copy) {
506 stride_ = kl_+ku_+1;
507 values_ = new ScalarType[stride_*numCols_];
508 copyMat (values_in, stride_in, numRows_, numCols_, values_, stride_, 0);
509 valuesCopied_ = true;
510 }
511 }
512
513 template<typename OrdinalType, typename ScalarType>
514 SerialBandDenseMatrix<OrdinalType, ScalarType>::
SerialBandDenseMatrix(const SerialBandDenseMatrix<OrdinalType,ScalarType> & Source,ETransp trans)515 SerialBandDenseMatrix (const SerialBandDenseMatrix<OrdinalType, ScalarType> &Source, ETransp trans)
516 : CompObject (),
517 BLAS<OrdinalType,ScalarType>(),
518 numRows_ (0),
519 numCols_ (0),
520 stride_ (0),
521 kl_ (0),
522 ku_ (0),
523 valuesCopied_ (true),
524 values_ (NULL)
525 {
526 if (trans == NO_TRANS) {
527 numRows_ = Source.numRows_;
528 numCols_ = Source.numCols_;
529 kl_ = Source.kl_;
530 ku_ = Source.ku_;
531 stride_ = kl_+ku_+1;
532 values_ = new ScalarType[stride_*numCols_];
533 copyMat (Source.values_, Source.stride_, numRows_, numCols_,
534 values_, stride_, 0);
535 }
536 else if (trans == CONJ_TRANS && ScalarTraits<ScalarType>::isComplex) {
537 numRows_ = Source.numCols_;
538 numCols_ = Source.numRows_;
539 kl_ = Source.ku_;
540 ku_ = Source.kl_;
541 stride_ = kl_+ku_+1;
542 values_ = new ScalarType[stride_*numCols_];
543 for (OrdinalType j = 0; j < numCols_; ++j) {
544 for (OrdinalType i = TEUCHOS_MAX(0,j-ku_);
545 i <= TEUCHOS_MIN(numRows_-1,j+kl_); ++i) {
546 values_[j*stride_ + (ku_+i-j)] =
547 ScalarTraits<ScalarType>::conjugate (Source.values_[i*Source.stride_ + (Source.ku_+j-i)]);
548 }
549 }
550 }
551 else {
552 numRows_ = Source.numCols_;
553 numCols_ = Source.numRows_;
554 kl_ = Source.ku_;
555 ku_ = Source.kl_;
556 stride_ = kl_+ku_+1;
557 values_ = new ScalarType[stride_*numCols_];
558 for (OrdinalType j=0; j<numCols_; j++) {
559 for (OrdinalType i = TEUCHOS_MAX(0,j-ku_);
560 i <= TEUCHOS_MIN(numRows_-1,j+kl_); ++i) {
561 values_[j*stride_ + (ku_+i-j)] = Source.values_[i*Source.stride_ + (Source.ku_+j-i)];
562 }
563 }
564 }
565 }
566
567 template<typename OrdinalType, typename ScalarType>
568 SerialBandDenseMatrix<OrdinalType, ScalarType>::
SerialBandDenseMatrix(DataAccess CV,const SerialBandDenseMatrix<OrdinalType,ScalarType> & Source,OrdinalType numRows_in,OrdinalType numCols_in,OrdinalType startCol)569 SerialBandDenseMatrix (DataAccess CV,
570 const SerialBandDenseMatrix<OrdinalType, ScalarType> &Source,
571 OrdinalType numRows_in,
572 OrdinalType numCols_in,
573 OrdinalType startCol)
574 : CompObject (),
575 BLAS<OrdinalType,ScalarType>(),
576 numRows_ (numRows_in),
577 numCols_ (numCols_in),
578 stride_ (Source.stride_),
579 kl_ (Source.kl_),
580 ku_ (Source.ku_),
581 valuesCopied_ (false),
582 values_ (Source.values_)
583 {
584 if (CV == Copy) {
585 values_ = new ScalarType[stride_ * numCols_in];
586 copyMat (Source.values_, Source.stride_, numRows_in, numCols_in,
587 values_, stride_, startCol);
588 valuesCopied_ = true;
589 } else { // CV = View
590 values_ = values_ + (stride_ * startCol);
591 }
592 }
593
594 template<typename OrdinalType, typename ScalarType>
~SerialBandDenseMatrix()595 SerialBandDenseMatrix<OrdinalType, ScalarType>::~SerialBandDenseMatrix()
596 {
597 deleteArrays();
598 }
599
600 //----------------------------------------------------------------------------------------------------
601 // Shape methods
602 //----------------------------------------------------------------------------------------------------
603
604 template<typename OrdinalType, typename ScalarType>
shape(OrdinalType numRows_in,OrdinalType numCols_in,OrdinalType kl_in,OrdinalType ku_in)605 int SerialBandDenseMatrix<OrdinalType, ScalarType>::shape(
606 OrdinalType numRows_in, OrdinalType numCols_in, OrdinalType kl_in, OrdinalType ku_in
607 )
608 {
609 deleteArrays(); // Get rid of anything that might be already allocated
610 numRows_ = numRows_in;
611 numCols_ = numCols_in;
612 kl_ = kl_in;
613 ku_ = ku_in;
614 stride_ = kl_+ku_+1;
615 values_ = new ScalarType[stride_*numCols_];
616 putScalar();
617 valuesCopied_ = true;
618
619 return(0);
620 }
621
622 template<typename OrdinalType, typename ScalarType>
shapeUninitialized(OrdinalType numRows_in,OrdinalType numCols_in,OrdinalType kl_in,OrdinalType ku_in)623 int SerialBandDenseMatrix<OrdinalType, ScalarType>::shapeUninitialized(
624 OrdinalType numRows_in, OrdinalType numCols_in, OrdinalType kl_in, OrdinalType ku_in
625 )
626 {
627 deleteArrays(); // Get rid of anything that might be already allocated
628 numRows_ = numRows_in;
629 numCols_ = numCols_in;
630 kl_ = kl_in;
631 ku_ = ku_in;
632 stride_ = kl_+ku_+1;
633 values_ = new ScalarType[stride_*numCols_];
634 valuesCopied_ = true;
635
636 return(0);
637 }
638
639 template<typename OrdinalType, typename ScalarType>
reshape(OrdinalType numRows_in,OrdinalType numCols_in,OrdinalType kl_in,OrdinalType ku_in)640 int SerialBandDenseMatrix<OrdinalType, ScalarType>::reshape(
641 OrdinalType numRows_in, OrdinalType numCols_in, OrdinalType kl_in, OrdinalType ku_in
642 )
643 {
644
645 // Allocate space for new matrix
646 ScalarType* values_tmp = new ScalarType[(kl_in+ku_in+1) * numCols_in];
647 ScalarType zero = ScalarTraits<ScalarType>::zero();
648 for(OrdinalType k = 0; k < (kl_in+ku_in+1) * numCols_in; k++) {
649 values_tmp[k] = zero;
650 }
651 OrdinalType numRows_tmp = TEUCHOS_MIN(numRows_, numRows_in);
652 OrdinalType numCols_tmp = TEUCHOS_MIN(numCols_, numCols_in);
653 if(values_ != 0) {
654 copyMat(values_, stride_, numRows_tmp, numCols_tmp, values_tmp,
655 kl_in+ku_in+1, 0); // Copy principal submatrix of A to new A
656 }
657 deleteArrays(); // Get rid of anything that might be already allocated
658 numRows_ = numRows_in;
659 numCols_ = numCols_in;
660 kl_ = kl_in;
661 ku_ = ku_in;
662 stride_ = kl_+ku_+1;
663 values_ = values_tmp; // Set pointer to new A
664 valuesCopied_ = true;
665
666 return(0);
667 }
668
669 //----------------------------------------------------------------------------------------------------
670 // Set methods
671 //----------------------------------------------------------------------------------------------------
672
673 template<typename OrdinalType, typename ScalarType>
putScalar(const ScalarType value_in)674 int SerialBandDenseMatrix<OrdinalType, ScalarType>::putScalar( const ScalarType value_in )
675 {
676
677 // Set each value of the dense matrix to "value".
678 for(OrdinalType j = 0; j < numCols_; j++) {
679 for (OrdinalType i=TEUCHOS_MAX(0,j-ku_); i<=TEUCHOS_MIN(numRows_-1,j+kl_); i++) {
680 values_[(ku_+i-j) + j*stride_] = value_in;
681 }
682 }
683
684 return 0;
685 }
686
687 template<typename OrdinalType, typename ScalarType>
random()688 int SerialBandDenseMatrix<OrdinalType, ScalarType>::random()
689 {
690
691 // Set each value of the dense matrix to a random value.
692 for(OrdinalType j = 0; j < numCols_; j++) {
693 for (OrdinalType i=TEUCHOS_MAX(0,j-ku_); i<=TEUCHOS_MIN(numRows_-1,j+kl_); i++) {
694 values_[(ku_+i-j) + j*stride_] = ScalarTraits<ScalarType>::random();
695 }
696 }
697
698 return 0;
699 }
700
701 template<typename OrdinalType, typename ScalarType>
702 SerialBandDenseMatrix<OrdinalType,ScalarType>&
operator =(const SerialBandDenseMatrix<OrdinalType,ScalarType> & Source)703 SerialBandDenseMatrix<OrdinalType, ScalarType>::operator=(
704 const SerialBandDenseMatrix<OrdinalType,ScalarType>& Source
705 )
706 {
707
708 if(this == &Source)
709 return(*this); // Special case of source same as target
710 if((!valuesCopied_) && (!Source.valuesCopied_) && (values_ == Source.values_))
711 return(*this); // Special case of both are views to same data.
712
713 // If the source is a view then we will return a view, else we will return a copy.
714 if (!Source.valuesCopied_) {
715 if(valuesCopied_) {
716 // Clean up stored data if this was previously a copy.
717 deleteArrays();
718 }
719 numRows_ = Source.numRows_;
720 numCols_ = Source.numCols_;
721 kl_ = Source.kl_;
722 ku_ = Source.ku_;
723 stride_ = Source.stride_;
724 values_ = Source.values_;
725 } else {
726 // If we were a view, we will now be a copy.
727 if(!valuesCopied_) {
728 numRows_ = Source.numRows_;
729 numCols_ = Source.numCols_;
730 kl_ = Source.kl_;
731 ku_ = Source.ku_;
732 stride_ = kl_+ku_+1;
733 const OrdinalType newsize = stride_ * numCols_;
734 if(newsize > 0) {
735 values_ = new ScalarType[newsize];
736 valuesCopied_ = true;
737 } else {
738 values_ = 0;
739 }
740 } else {
741 // If we were a copy, we will stay a copy.
742 if((Source.numRows_ <= stride_) && (Source.numCols_ == numCols_)) { // we don't need to reallocate
743 numRows_ = Source.numRows_;
744 numCols_ = Source.numCols_;
745 kl_ = Source.kl_;
746 ku_ = Source.ku_;
747 } else {
748 // we need to allocate more space (or less space)
749 deleteArrays();
750 numRows_ = Source.numRows_;
751 numCols_ = Source.numCols_;
752 kl_ = Source.kl_;
753 ku_ = Source.ku_;
754 stride_ = kl_+ku_+1;
755 const OrdinalType newsize = stride_ * numCols_;
756 if(newsize > 0) {
757 values_ = new ScalarType[newsize];
758 valuesCopied_ = true;
759 }
760 }
761 }
762 copyMat(Source.values_, Source.stride_, numRows_, numCols_, values_, stride_, 0);
763 }
764 return(*this);
765
766 }
767
768 template<typename OrdinalType, typename ScalarType>
operator +=(const SerialBandDenseMatrix<OrdinalType,ScalarType> & Source)769 SerialBandDenseMatrix<OrdinalType, ScalarType>& SerialBandDenseMatrix<OrdinalType, ScalarType>::operator+= (const SerialBandDenseMatrix<OrdinalType,ScalarType>& Source )
770 {
771
772 // Check for compatible dimensions
773 if ((numRows_ != Source.numRows_) || (numCols_ != Source.numCols_) || (kl_ != Source.kl_) || (ku_ != Source.ku_)) {
774 TEUCHOS_CHK_REF(*this); // Return *this without altering it.
775 }
776 copyMat(Source.values_, Source.stride_, numRows_, numCols_, values_, stride_, 0, ScalarTraits<ScalarType>::one());
777 return(*this);
778
779 }
780
781 template<typename OrdinalType, typename ScalarType>
operator -=(const SerialBandDenseMatrix<OrdinalType,ScalarType> & Source)782 SerialBandDenseMatrix<OrdinalType, ScalarType>& SerialBandDenseMatrix<OrdinalType, ScalarType>::operator-= (const SerialBandDenseMatrix<OrdinalType,ScalarType>& Source )
783 {
784
785 // Check for compatible dimensions
786 if ((numRows_ != Source.numRows_) || (numCols_ != Source.numCols_) || (kl_ != Source.kl_) || (ku_ != Source.ku_)) {
787 TEUCHOS_CHK_REF(*this); // Return *this without altering it.
788 }
789 copyMat(Source.values_, Source.stride_, numRows_, numCols_, values_, stride_, 0, -ScalarTraits<ScalarType>::one());
790 return(*this);
791
792 }
793
794 template<typename OrdinalType, typename ScalarType>
assign(const SerialBandDenseMatrix<OrdinalType,ScalarType> & Source)795 SerialBandDenseMatrix<OrdinalType,ScalarType>& SerialBandDenseMatrix<OrdinalType, ScalarType>::assign (const SerialBandDenseMatrix<OrdinalType,ScalarType>& Source) {
796
797 if(this == &Source)
798 return(*this); // Special case of source same as target
799 if((!valuesCopied_) && (!Source.valuesCopied_) && (values_ == Source.values_))
800 return(*this); // Special case of both are views to same data.
801
802 // Check for compatible dimensions
803 if ((numRows_ != Source.numRows_) || (numCols_ != Source.numCols_) || (kl_ != Source.kl_) || (ku_ != Source.ku_)) {
804 TEUCHOS_CHK_REF(*this); // Return *this without altering it.
805 }
806 copyMat(Source.values_, Source.stride_, numRows_, numCols_, values_, stride_, 0);
807 return(*this);
808
809 }
810
811 //----------------------------------------------------------------------------------------------------
812 // Accessor methods
813 //----------------------------------------------------------------------------------------------------
814
815 template<typename OrdinalType, typename ScalarType>
operator ()(OrdinalType rowIndex,OrdinalType colIndex)816 inline ScalarType& SerialBandDenseMatrix<OrdinalType, ScalarType>::operator () (OrdinalType rowIndex, OrdinalType colIndex)
817 {
818 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
819 checkIndex( rowIndex, colIndex );
820 #endif
821 return(values_[colIndex * stride_ + ku_+rowIndex-colIndex]);
822 }
823
824 template<typename OrdinalType, typename ScalarType>
operator ()(OrdinalType rowIndex,OrdinalType colIndex) const825 inline const ScalarType& SerialBandDenseMatrix<OrdinalType, ScalarType>::operator () (OrdinalType rowIndex, OrdinalType colIndex) const
826 {
827 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
828 checkIndex( rowIndex, colIndex );
829 #endif
830 return(values_[colIndex * stride_ + ku_+rowIndex-colIndex]);
831 }
832
833 template<typename OrdinalType, typename ScalarType>
operator [](OrdinalType colIndex) const834 inline const ScalarType* SerialBandDenseMatrix<OrdinalType, ScalarType>::operator [] (OrdinalType colIndex) const
835 {
836 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
837 checkIndex( 0, colIndex );
838 #endif
839 return(values_ + colIndex * stride_);
840 }
841
842 template<typename OrdinalType, typename ScalarType>
operator [](OrdinalType colIndex)843 inline ScalarType* SerialBandDenseMatrix<OrdinalType, ScalarType>::operator [] (OrdinalType colIndex)
844 {
845 #ifdef HAVE_TEUCHOS_ARRAY_BOUNDSCHECK
846 checkIndex( 0, colIndex );
847 #endif
848 return(values_ + colIndex * stride_);
849 }
850
851 //----------------------------------------------------------------------------------------------------
852 // Norm methods
853 //----------------------------------------------------------------------------------------------------
854
855 template<typename OrdinalType, typename ScalarType>
normOne() const856 typename ScalarTraits<ScalarType>::magnitudeType SerialBandDenseMatrix<OrdinalType, ScalarType>::normOne() const
857 {
858 OrdinalType i, j;
859 typename ScalarTraits<ScalarType>::magnitudeType anorm = ScalarTraits<ScalarType>::magnitude(ScalarTraits<ScalarType>::zero());
860 typename ScalarTraits<ScalarType>::magnitudeType absSum = ScalarTraits<ScalarType>::magnitude(ScalarTraits<ScalarType>::zero());
861
862 ScalarType* ptr;
863 for(j = 0; j < numCols_; j++) {
864 ScalarType sum = 0;
865 ptr = values_ + j * stride_ + TEUCHOS_MAX(0, ku_-j);
866 for (i=TEUCHOS_MAX(0,j-ku_); i<=TEUCHOS_MIN(numRows_-1,j+kl_); i++) {
867 sum += ScalarTraits<ScalarType>::magnitude(*ptr++);
868 }
869 absSum = ScalarTraits<ScalarType>::magnitude(sum);
870 if(absSum > anorm) {
871 anorm = absSum;
872 }
873 }
874 updateFlops((kl_+ku_+1) * numCols_);
875
876 return(anorm);
877 }
878
879 template<typename OrdinalType, typename ScalarType>
normInf() const880 typename ScalarTraits<ScalarType>::magnitudeType SerialBandDenseMatrix<OrdinalType, ScalarType>::normInf() const
881 {
882 OrdinalType i, j;
883 typename ScalarTraits<ScalarType>::magnitudeType sum, anorm = ScalarTraits<ScalarType>::magnitude(ScalarTraits<ScalarType>::zero());
884
885 for (i = 0; i < numRows_; i++) {
886 sum = ScalarTraits<ScalarType>::magnitude(ScalarTraits<ScalarType>::zero());
887 for (j=TEUCHOS_MAX(0,i-kl_); j<=TEUCHOS_MIN(numCols_-1,i+ku_); j++) {
888 sum += ScalarTraits<ScalarType>::magnitude(*(values_+(ku_+i-j)+j*stride_));
889 }
890 anorm = TEUCHOS_MAX( anorm, sum );
891 }
892 updateFlops((kl_+ku_+1) * numCols_);
893
894 return(anorm);
895 }
896
897 template<typename OrdinalType, typename ScalarType>
normFrobenius() const898 typename ScalarTraits<ScalarType>::magnitudeType SerialBandDenseMatrix<OrdinalType, ScalarType>::normFrobenius() const
899 {
900 OrdinalType i, j;
901 typename ScalarTraits<ScalarType>::magnitudeType anorm = ScalarTraits<ScalarType>::magnitude(ScalarTraits<ScalarType>::zero());
902
903 for (j = 0; j < numCols_; j++) {
904 for (i=TEUCHOS_MAX(0,j-ku_); i<=TEUCHOS_MIN(numRows_-1,j+kl_); i++) {
905 anorm += ScalarTraits<ScalarType>::magnitude(values_[(ku_+i-j)+j*stride_]*values_[(ku_+i-j)+j*stride_]);
906 }
907 }
908 anorm = ScalarTraits<ScalarType>::magnitude(ScalarTraits<ScalarType>::squareroot(anorm));
909 updateFlops((kl_+ku_+1) * numCols_);
910
911 return(anorm);
912 }
913
914 //----------------------------------------------------------------------------------------------------
915 // Comparison methods
916 //----------------------------------------------------------------------------------------------------
917
918 template<typename OrdinalType, typename ScalarType>
operator ==(const SerialBandDenseMatrix<OrdinalType,ScalarType> & Operand) const919 bool SerialBandDenseMatrix<OrdinalType, ScalarType>::operator== (const SerialBandDenseMatrix<OrdinalType, ScalarType> &Operand) const
920 {
921 bool result = 1;
922
923 if((numRows_ != Operand.numRows_) || (numCols_ != Operand.numCols_) || (kl_ != Operand.kl_) || (ku_ != Operand.ku_)) {
924 result = 0;
925 } else {
926 OrdinalType i, j;
927 for(j = 0; j < numCols_; j++) {
928 for (i=TEUCHOS_MAX(0,j-ku_); i<=TEUCHOS_MIN(numRows_-1,j+kl_); i++) {
929 if((*this)(i, j) != Operand(i, j)) {
930 return 0;
931 }
932 }
933 }
934 }
935
936 return result;
937 }
938
939 template<typename OrdinalType, typename ScalarType>
operator !=(const SerialBandDenseMatrix<OrdinalType,ScalarType> & Operand) const940 bool SerialBandDenseMatrix<OrdinalType, ScalarType>::operator!= (const SerialBandDenseMatrix<OrdinalType, ScalarType> &Operand) const
941 {
942 return !((*this) == Operand);
943 }
944
945 //----------------------------------------------------------------------------------------------------
946 // Multiplication method
947 //----------------------------------------------------------------------------------------------------
948
949 template<typename OrdinalType, typename ScalarType>
operator *=(const ScalarType alpha)950 SerialBandDenseMatrix<OrdinalType, ScalarType>& SerialBandDenseMatrix<OrdinalType, ScalarType>::operator*= (const ScalarType alpha )
951 {
952 this->scale( alpha );
953 return(*this);
954 }
955
956 template<typename OrdinalType, typename ScalarType>
scale(const ScalarType alpha)957 int SerialBandDenseMatrix<OrdinalType, ScalarType>::scale( const ScalarType alpha )
958 {
959
960 OrdinalType i, j;
961 ScalarType* ptr;
962
963 for (j=0; j<numCols_; j++) {
964 ptr = values_ + j*stride_ + TEUCHOS_MAX(0, ku_-j);
965 for (i=TEUCHOS_MAX(0,j-ku_); i<=TEUCHOS_MIN(numRows_-1,j+kl_); i++) {
966 *ptr = alpha * (*ptr); ptr++;
967 }
968 }
969 updateFlops( (kl_+ku_+1)*numCols_ );
970
971 return(0);
972 }
973
974 template<typename OrdinalType, typename ScalarType>
scale(const SerialBandDenseMatrix<OrdinalType,ScalarType> & A)975 int SerialBandDenseMatrix<OrdinalType, ScalarType>::scale( const SerialBandDenseMatrix<OrdinalType,ScalarType>& A )
976 {
977
978 OrdinalType i, j;
979 ScalarType* ptr;
980
981 // Check for compatible dimensions
982 if ((numRows_ != A.numRows_) || (numCols_ != A.numCols_) || (kl_ != A.kl_) || (ku_ != A.ku_)) {
983 TEUCHOS_CHK_ERR(-1); // Return error
984 }
985 for (j=0; j<numCols_; j++) {
986 ptr = values_ + j*stride_ + TEUCHOS_MAX(0, ku_-j);
987 for (i=TEUCHOS_MAX(0,j-ku_); i<=TEUCHOS_MIN(numRows_-1,j+kl_); i++) {
988 *ptr = A(i,j) * (*ptr); ptr++;
989 }
990 }
991 updateFlops( (kl_+ku_+1)*numCols_ );
992
993 return(0);
994 }
995
996 template<typename OrdinalType, typename ScalarType>
print(std::ostream & os) const997 std::ostream& SerialBandDenseMatrix<OrdinalType, ScalarType>::print(std::ostream& os) const
998 {
999 os << std::endl;
1000 if(valuesCopied_)
1001 os << "Values_copied : yes" << std::endl;
1002 else
1003 os << "Values_copied : no" << std::endl;
1004 os << "Rows : " << numRows_ << std::endl;
1005 os << "Columns : " << numCols_ << std::endl;
1006 os << "Lower Bandwidth : " << kl_ << std::endl;
1007 os << "Upper Bandwidth : " << ku_ << std::endl;
1008 os << "LDA : " << stride_ << std::endl;
1009 if(numRows_ == 0 || numCols_ == 0) {
1010 os << "(matrix is empty, no values to display)" << std::endl;
1011 } else {
1012
1013 for(OrdinalType i = 0; i < numRows_; i++) {
1014 for (OrdinalType j=TEUCHOS_MAX(0,i-kl_); j<=TEUCHOS_MIN(numCols_-1,i+ku_); j++) {
1015 os << (*this)(i,j) << " ";
1016 }
1017 os << std::endl;
1018 }
1019 }
1020 return os;
1021 }
1022
1023 //----------------------------------------------------------------------------------------------------
1024 // Protected methods
1025 //----------------------------------------------------------------------------------------------------
1026
1027 template<typename OrdinalType, typename ScalarType>
checkIndex(OrdinalType rowIndex,OrdinalType colIndex) const1028 inline void SerialBandDenseMatrix<OrdinalType, ScalarType>::checkIndex( OrdinalType rowIndex, OrdinalType colIndex ) const {
1029
1030 TEUCHOS_TEST_FOR_EXCEPTION(rowIndex < 0 || rowIndex >= numRows_ ||
1031 rowIndex < TEUCHOS_MAX(0,colIndex-ku_) || rowIndex > TEUCHOS_MIN(numRows_-1,colIndex+kl_),
1032 std::out_of_range,
1033 "SerialBandDenseMatrix<T>::checkIndex: "
1034 "Row index " << rowIndex << " out of range [0, "<< numRows_ << ")");
1035 TEUCHOS_TEST_FOR_EXCEPTION(colIndex < 0 || colIndex >= numCols_, std::out_of_range,
1036 "SerialBandDenseMatrix<T>::checkIndex: "
1037 "Col index " << colIndex << " out of range [0, "<< numCols_ << ")");
1038
1039 }
1040
1041 template<typename OrdinalType, typename ScalarType>
deleteArrays(void)1042 void SerialBandDenseMatrix<OrdinalType, ScalarType>::deleteArrays(void)
1043 {
1044 if (valuesCopied_) {
1045 delete [] values_;
1046 values_ = 0;
1047 valuesCopied_ = false;
1048 }
1049 }
1050
1051 template<typename OrdinalType, typename ScalarType>
copyMat(ScalarType * inputMatrix,OrdinalType strideInput,OrdinalType numRows_in,OrdinalType numCols_in,ScalarType * outputMatrix,OrdinalType strideOutput,OrdinalType startCol,ScalarType alpha)1052 void SerialBandDenseMatrix<OrdinalType, ScalarType>::copyMat(
1053 ScalarType* inputMatrix, OrdinalType strideInput, OrdinalType numRows_in,
1054 OrdinalType numCols_in, ScalarType* outputMatrix, OrdinalType strideOutput, OrdinalType startCol, ScalarType alpha
1055 )
1056 {
1057 OrdinalType i, j;
1058 ScalarType* ptr1 = 0;
1059 ScalarType* ptr2 = 0;
1060
1061 for(j = 0; j < numCols_in; j++) {
1062 ptr1 = outputMatrix + (j * strideOutput) + TEUCHOS_MAX(0, ku_-j);
1063 ptr2 = inputMatrix + (j + startCol) * strideInput + TEUCHOS_MAX(0, ku_-j);
1064 if (alpha != Teuchos::ScalarTraits<ScalarType>::zero() ) {
1065 for (i=TEUCHOS_MAX(0,j-ku_); i<=TEUCHOS_MIN(numRows_in-1,j+kl_); i++) {
1066 *ptr1++ += alpha*(*ptr2++);
1067 }
1068 } else {
1069 for (i=TEUCHOS_MAX(0,j-ku_); i<=TEUCHOS_MIN(numRows_in-1,j+kl_); i++) {
1070 *ptr1++ = *ptr2++;
1071 }
1072 }
1073 }
1074 }
1075
1076 /// \brief Ostream manipulator for SerialBandDenseMatrix
1077 template<typename OrdinalType, typename ScalarType>
1078 struct SerialBandDenseMatrixPrinter {
1079 public:
1080 const SerialBandDenseMatrix<OrdinalType,ScalarType> &obj;
SerialBandDenseMatrixPrinterTeuchos::SerialBandDenseMatrixPrinter1081 SerialBandDenseMatrixPrinter(
1082 const SerialBandDenseMatrix<OrdinalType,ScalarType> &obj_in)
1083 : obj(obj_in) {}
1084 };
1085
1086 /// \brief Output SerialBandDenseMatrix object through its stream manipulator.
1087 template<typename OrdinalType, typename ScalarType>
1088 std::ostream&
operator <<(std::ostream & out,const SerialBandDenseMatrixPrinter<OrdinalType,ScalarType> printer)1089 operator<<(std::ostream &out,
1090 const SerialBandDenseMatrixPrinter<OrdinalType,ScalarType> printer)
1091 {
1092 printer.obj.print(out);
1093 return out;
1094 }
1095
1096 /// \brief Return SerialBandDenseMatrix ostream manipulator Use as:
1097 template<typename OrdinalType, typename ScalarType>
1098 SerialBandDenseMatrixPrinter<OrdinalType,ScalarType>
printMat(const SerialBandDenseMatrix<OrdinalType,ScalarType> & obj)1099 printMat(const SerialBandDenseMatrix<OrdinalType,ScalarType> &obj)
1100 {
1101 return SerialBandDenseMatrixPrinter<OrdinalType,ScalarType>(obj);
1102 }
1103
1104
1105 } // namespace Teuchos
1106
1107
1108 #endif /* _TEUCHOS_SERIALBANDDENSEMATRIX_HPP_ */
1109