Epetra Package Browser (Single Doxygen Collection) Development
Loading...
Searching...
No Matches
Epetra_LongLongSerialDenseMatrix.cpp
Go to the documentation of this file.
1
2//@HEADER
3// ************************************************************************
4//
5// Epetra: Linear Algebra Services Package
6// Copyright 2011 Sandia Corporation
7//
8// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9// the U.S. Government retains certain rights in this software.
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#include "Epetra_ConfigDefs.h"
45#include "Epetra_Util.h"
46
47#ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
48
49//=============================================================================
51 : Epetra_Object("Epetra::LongLongSerialDenseMatrix"),
52 CV_(Copy),
53 A_Copied_(false),
54 M_(0),
55 N_(0),
56 LDA_(0),
57 A_(0)
58{
59}
60
61//=============================================================================
63 : Epetra_Object("Epetra::LongLongSerialDenseMatrix"),
64 CV_(Copy),
65 A_Copied_(false),
66 M_(0),
67 N_(0),
68 LDA_(0),
69 A_(0)
70{
71 if(NumRows < 0)
72 throw ReportError("NumRows = " + toString(NumRows) + ". Should be >= 0", -1);
73 if(NumCols < 0)
74 throw ReportError("NumCols = " + toString(NumCols) + ". Should be >= 0", -1);
75
76 int errorcode = Shape(NumRows, NumCols);
77 if(errorcode != 0)
78 throw ReportError("Shape returned non-zero (" + toString(errorcode) + ").", -2);
79}
80//=============================================================================
82 int NumRows, int NumCols)
83 : Epetra_Object("Epetra::LongLongSerialDenseMatrix"),
84 CV_(CV_in),
85 A_Copied_(false),
86 M_(NumRows),
87 N_(NumCols),
88 LDA_(lda),
89 A_(A_in)
90{
91 if(A_in == 0)
92 throw ReportError("Null pointer passed as A_in parameter.", -3);
93 if(NumRows < 0)
94 throw ReportError("NumRows = " + toString(NumRows) + ". Should be >= 0", -1);
95 if(NumCols < 0)
96 throw ReportError("NumCols = " + toString(NumCols) + ". Should be >= 0", -1);
97 if(lda < 0)
98 throw ReportError("LDA = " + toString(lda) + ". Should be >= 0", -1);
99
100 if(CV_in == Copy) {
101 LDA_ = M_;
102 const int newsize = LDA_ * N_;
103 if(newsize > 0) {
104 A_ = new long long[newsize];
105 CopyMat(A_in, lda, M_, N_, A_, LDA_);
106 A_Copied_ = true;
107 }
108 else {
109 A_ = 0;
110 }
111 }
112}
113//=============================================================================
115 : Epetra_Object(Source),
116 CV_(Source.CV_),
117 A_Copied_(false),
118 M_(Source.M_),
119 N_(Source.N_),
120 LDA_(Source.LDA_),
121 A_(Source.A_)
122{
123 if(CV_ == Copy) {
124 LDA_ = M_;
125 const int newsize = LDA_ * N_;
126 if(newsize > 0) {
127 A_ = new long long[newsize];
128 CopyMat(Source.A_, Source.LDA_, M_, N_, A_, LDA_);
129 A_Copied_ = true;
130 }
131 else {
132 A_ = 0;
133 A_Copied_ = false;
134 }
135 }
136}
137//=============================================================================
138int Epetra_LongLongSerialDenseMatrix::Reshape(int NumRows, int NumCols) {
139 if(NumRows < 0 || NumCols < 0)
140 return(-1);
141
142 long long* A_tmp = 0;
143 const int newsize = NumRows * NumCols;
144
145 if(newsize > 0) {
146 // Allocate space for new matrix
147 A_tmp = new long long[newsize];
148 for(int k = 0; k < newsize; k++)
149 A_tmp[k] = 0; // Zero out values
150 int M_tmp = EPETRA_MIN(M_, NumRows);
151 int N_tmp = EPETRA_MIN(N_, NumCols);
152 if(A_ != 0)
153 CopyMat(A_, LDA_, M_tmp, N_tmp, A_tmp, NumRows); // Copy principal submatrix of A to new A
154 }
155
156 CleanupData(); // Get rid of anything that might be already allocated
157 M_ = NumRows;
158 N_ = NumCols;
159 LDA_ = M_;
160 A_ = A_tmp; // Set pointer to new A
161 A_Copied_ = (newsize>0);
162 return(0);
163}
164//=============================================================================
165int Epetra_LongLongSerialDenseMatrix::Shape(int NumRows, int NumCols) {
166 if(NumRows < 0 || NumCols < 0)
167 return(-1);
168
169 CleanupData(); // Get rid of anything that might be already allocated
170 M_ = NumRows;
171 N_ = NumCols;
172 LDA_ = M_;
173 const int newsize = LDA_ * N_;
174 if(newsize > 0) {
175 A_ = new long long[newsize];
176#ifdef EPETRA_HAVE_OMP
177#pragma omp parallel for
178#endif
179 for(int k = 0; k < newsize; k++)
180 A_[k] = 0; // Zero out values
181 A_Copied_ = true;
182 }
183
184 return(0);
185}
186//=============================================================================
188{
189 CleanupData();
190}
191//=============================================================================
193{
194 if(A_Copied_)
195 delete[] A_;
196 A_ = 0;
197 A_Copied_ = false;
198 M_ = 0;
199 N_ = 0;
200 LDA_ = 0;
201}
202//=============================================================================
204 if(this == &Source)
205 return(*this); // Special case of source same as target
206 if((CV_ == View) && (Source.CV_ == View) && (A_ == Source.A_))
207 return(*this); // Special case of both are views to same data.
208
209 if(std::strcmp(Label(), Source.Label()) != 0)
210 throw ReportError("operator= type mismatch (lhs = " + std::string(Label()) +
211 ", rhs = " + std::string(Source.Label()) + ").", -5);
212
213 if(Source.CV_ == View) {
214 if(CV_ == Copy) { // C->V only
215 CleanupData();
216 CV_ = View;
217 }
218 M_ = Source.M_; // C->V and V->V
219 N_ = Source.N_;
220 LDA_ = Source.LDA_;
221 A_ = Source.A_;
222 }
223 else {
224 if(CV_ == View) { // V->C
225 CV_ = Copy;
226 M_ = Source.M_;
227 N_ = Source.N_;
228 LDA_ = Source.M_;
229 const int newsize = LDA_ * N_;
230 if(newsize > 0) {
231 A_ = new long long[newsize];
232 A_Copied_ = true;
233 }
234 else {
235 A_ = 0;
236 A_Copied_ = false;
237 }
238 }
239 else { // C->C
240 if((Source.M_ <= LDA_) && (Source.N_ == N_)) { // we don't need to reallocate
241 M_ = Source.M_;
242 N_ = Source.N_;
243 }
244 else { // we need to allocate more space (or less space)
245 CleanupData();
246 M_ = Source.M_;
247 N_ = Source.N_;
248 LDA_ = Source.M_;
249 const int newsize = LDA_ * N_;
250 if(newsize > 0) {
251 A_ = new long long[newsize];
252 A_Copied_ = true;
253 }
254 }
255 }
256 CopyMat(Source.A_, Source.LDA_, M_, N_, A_, LDA_); // V->C and C->C
257 }
258
259 return(*this);
260}
261
262//=============================================================================
264{
265 if (M_ != rhs.M_ || N_ != rhs.N_) return(false);
266
267 const long long* A_tmp = A_;
268 const long long* rhsA = rhs.A_;
269
270 for(int j=0; j<N_; ++j) {
271 int offset = j*LDA_;
272 int rhsOffset = j*rhs.LDA_;
273 for(int i=0; i<M_; ++i) {
274 if (A_tmp[offset+i] != rhsA[rhsOffset+i]) {
275 return(false);
276 }
277 }
278 }
279
280 return(true);
281}
282
283//=============================================================================
285 if(std::strcmp(Label(), Source.Label()) != 0)
286 return(-1);
287
288 if(CV_ == Copy) {
289 CleanupData();
290 CV_ = View;
291 }
292 M_ = Source.M_;
293 N_ = Source.N_;
294 LDA_ = Source.LDA_;
295 A_ = Source.A_;
296
297 return(0);
298}
299
300//=============================================================================
301void Epetra_LongLongSerialDenseMatrix::CopyMat(long long* Source, int Source_LDA, int NumRows, int NumCols,
302 long long* Target, int Target_LDA)
303{
304 int i, j;
305 long long* targetPtr = Target;
306 long long* sourcePtr = 0;
307 for(j = 0; j < NumCols; j++) { // for each column
308 targetPtr = Target + j * Target_LDA; // set pointers to correct stride
309 sourcePtr = Source + j * Source_LDA;
310 for(i = 0; i < NumRows; i++) // for each row
311 *targetPtr++ = *sourcePtr++; // copy element (i,j) and increment pointer to (i,j+1)
312 }
313 return;
314}
315
316//=============================================================================
318 long long anorm = 0;
319 long long* ptr = 0;
320 for(int j = 0; j < N_; j++) {
321 long long sum = 0;
322 ptr = A_ + j*LDA_;
323 for(int i = 0; i < M_; i++)
324 {
325 const long long val = *ptr++;
326 sum += (val > 0 ? val : -val); // No std::abs(long long) on VS2005.
327 }
328 anorm = EPETRA_MAX(anorm, sum);
329 }
330 return(anorm);
331}
332
333//=============================================================================
335 long long anorm = 0;
336 long long* ptr = 0;
337 // Loop across columns in inner loop. Most expensive memory access, but
338 // requires no extra storage.
339 for(int i = 0; i < M_; i++) {
340 long long sum = 0;
341 ptr = A_ + i;
342 for(int j = 0; j < N_; j++) {
343 const long long val = *ptr;
344 sum += (val > 0 ? val : -val); // No std::abs(long long) on VS2005.
345 ptr += LDA_;
346 }
347 anorm = EPETRA_MAX(anorm, sum);
349 return(anorm);
350}
351
352//=========================================================================
353void Epetra_LongLongSerialDenseMatrix::Print(std::ostream& os) const {
354 if(CV_ == Copy)
355 os << "Data access mode: Copy" << std::endl;
356 else
357 os << "Data access mode: View" << std::endl;
358 if(A_Copied_)
359 os << "A_Copied: yes" << std::endl;
360 else
361 os << "A_Copied: no" << std::endl;
362 os << "Rows(M): " << M_ << std::endl;
363 os << "Columns(N): " << N_ << std::endl;
364 os << "LDA: " << LDA_ << std::endl;
365 if(M_ == 0 || N_ == 0)
366 os << "(matrix is empty, no values to display)" << std::endl;
367 else
368 for(int i = 0; i < M_; i++) {
369 for(int j = 0; j < N_; j++){
370 os << (*this)(i,j) << " ";
371 }
372 os << std::endl;
373 }
374}
375
376//=========================================================================
378
379 Epetra_Util util;
380
381 for(int j = 0; j < N_; j++) {
382 long long* arrayPtr = A_ + (j * LDA_);
383 for(int i = 0; i < M_; i++) {
384 *arrayPtr++ = util.RandomInt();
385 }
386 }
387
388 return(0);
389}
390
391#endif // EPETRA_NO_64BIT_GLOBAL_INDICES
#define EPETRA_MIN(x, y)
#define EPETRA_MAX(x, y)
Epetra_DataAccess
@ View
@ Copy
Epetra_LongLongSerialDenseMatrix: A class for constructing and using general dense integer matrices.
virtual void Print(std::ostream &os) const
Print service methods; defines behavior of ostream << operator.
virtual long long OneNorm()
Computes the 1-Norm of the this matrix.
int Reshape(int NumRows, int NumCols)
Reshape a Epetra_LongLongSerialDenseMatrix object.
virtual ~Epetra_LongLongSerialDenseMatrix()
Epetra_LongLongSerialDenseMatrix destructor.
int Random()
Set matrix values to random numbers.
bool operator==(const Epetra_LongLongSerialDenseMatrix &rhs) const
Comparison operator.
Epetra_LongLongSerialDenseMatrix()
Default constructor; defines a zero size object.
int Shape(int NumRows, int NumCols)
Set dimensions of a Epetra_LongLongSerialDenseMatrix object; init values to zero.
virtual long long InfNorm()
Computes the Infinity-Norm of the this matrix.
int MakeViewOf(const Epetra_LongLongSerialDenseMatrix &Source)
Reset an existing LongLongSerialDenseMatrix to point to another Matrix.
Epetra_LongLongSerialDenseMatrix & operator=(const Epetra_LongLongSerialDenseMatrix &Source)
Copy from one matrix to another.
void CopyMat(long long *Source, int Source_LDA, int NumRows, int NumCols, long long *Target, int Target_LDA)
Epetra_Object: The base Epetra class.
Definition: Epetra_Object.h:57
virtual int ReportError(const std::string Message, int ErrorCode) const
Error reporting method.
virtual const char * Label() const
Epetra_Object Label access funtion.
std::string toString(const int &x) const
Epetra_Util: The Epetra Util Wrapper Class.
Definition: Epetra_Util.h:79
unsigned int RandomInt()
Returns a random integer on the interval (0, 2^31-1)
Definition: Epetra_Util.cpp:71