MOOCHO (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DenseLinAlgPack_DMatrixClass.cpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization
5 // Copyright (2003) 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 Roscoe A. Bartlett (rabartl@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 //
42 
43 #include <iomanip>
44 
46 
47 namespace DenseLinAlgPack {
48 
49 // ////////////////////////////////////////////////////////////////////////////////
50 // DMatrixSlice
51 
53  if(k > 0) {
55  // upper diagonal (k > 0)
56  return DVectorSlice( const_cast<value_type*>(col_ptr(1)) + k*max_rows()
57  , cols()-k > rows() ? rows() : cols()-k, max_rows()+1 );
58  }
59  // lower diagonal (k < 0) or center diagonal (k = 0)
61  return DVectorSlice( const_cast<value_type*>(col_ptr(1)) - k
62  , rows()+k > cols() ? cols() : rows()+k, max_rows()+1 );
63 }
64 
66 {
68 
70  *raw_ptr1 = col_ptr(1),
71  *raw_ptr2 = gms.col_ptr(1);
72 
73  if( !raw_ptr1 || !raw_ptr2 )
74  return NO_OVERLAP; // If one of the views is unbound there can't be any overlap
75 
77  max_rows1 = max_rows(),
78  max_rows2 = gms.max_rows(),
79  rows1 = rows(),
80  rows2 = gms.rows(),
81  cols1 = cols(),
82  cols2 = gms.cols();
83 
84  // Establish a frame of reference where raw_ptr1 < raw_ptr2
85  if(raw_ptr1 > raw_ptr2) {
86  std::swap(raw_ptr1,raw_ptr2);
87  std::swap(max_rows1,max_rows2);
88  std::swap(rows1,rows2);
89  std::swap(cols1,cols2);
90  }
91 
92  if( raw_ptr2 > (raw_ptr1 + (cols1 - 1) * max_rows1 + (rows1 - 1)) ) {
93  return NO_OVERLAP; // can't be any overlap
94  }
95 
97  start1 = 0,
98  start2 = raw_ptr2 - raw_ptr1;
99 
100  if(start1 == start2 && max_rows1 == max_rows2 && rows1 == rows2 && cols1 == cols2)
101  return SAME_MEM;
102  if(start1 + (rows1 - 1) + (cols1 - 1) * max_rows1 < start2)
103  return NO_OVERLAP; // start2 is past the last element in m1 so no overlap.
104  // There may be some overlap so determine if start2 lays in the region of m1.
105  // Determine the number of elements in v that start2 is past the start of a
106  // column of m1. If start2 was the first element in one of m1's cols
107  // row_i would be 1, and if it was just before for first element of the next
108  // column of m1 then row_i would equal to max_rows1.
109  size_type row_i = (start2 - start1 + 1) % max_rows1;
110  if(row_i <= rows1)
111  return SOME_OVERLAP; // start2 is in a column of m1 so there is some overlap
112  // Determine how many rows in the original matrix are below the last row in m1
113  size_type lower_rows = max_rows1 - (start1 % max_rows1 + rows1);
114  if(row_i < rows1 + lower_rows)
115  return NO_OVERLAP; // m2 lays below m1 in the original matrix
116  // If you get here start2 lays above m1 in original matix so if m2 has enough
117  // rows then the lower rows of m2 will overlap the upper rows of m1.
118  if(row_i + rows2 - 1 <= max_rows1)
119  return NO_OVERLAP; // m2 completely lays above m1
120  return SOME_OVERLAP; // Some lower rows of m2 extend into m1
121 }
122 
123 #ifdef LINALGPACK_CHECK_RANGE
125 {
126  if( i > rows() || !i )
127  throw std::out_of_range( "DMatrixSlice::validate_row_subscript(i) :"
128  "row index i is out of bounds" );
129 }
130 #endif
131 
132 #ifdef LINALGPACK_CHECK_RANGE
134 {
135  if( j > cols() || !j )
136  throw std::out_of_range( "DMatrixSlice::validate_col_subscript(j) :"
137  "column index j is out of bounds" );
138 }
139 #endif
140 
141 #ifdef LINALGPACK_CHECK_SLICE_SETUP
143 {
144  if( !ptr_ && !rows() && !cols() && !max_rows() )
145  return; // an unsized matrix slice is ok.
146  if( (rows() - 1) + (cols() - 1) * max_rows() + 1 > size )
147  throw std::out_of_range( "DMatrixSlice::validate_setup() : "
148  " DMatrixSlice constructed that goes past end of array" );
149 }
150 #endif
151 
152 // /////////////////////////////////////////////////////////////////////////////////
153 // DMatrix
154 
156  if(k > 0) {
158  // upper diagonal (k > 0)
159  return DVectorSlice( const_cast<value_type*>(col_ptr(1)) + k * rows()
160  , cols()-k > rows() ? rows() : cols()-k, rows()+1 );
161  }
162  // lower diagonal (k < 0) or center diagonal (k = 0)
164  return DVectorSlice( const_cast<value_type*>(col_ptr(1)) - k
165  , rows()+k > cols() ? cols() : rows()+k, rows()+1 );
166 }
167 
169  return (*this)().overlap(gms);
170 }
171 
172 #ifdef LINALGPACK_CHECK_RANGE
174  if( i > rows() || !i )
175  throw std::out_of_range("DMatrix::validate_row_subscript(i) : row index out of bounds");
176 }
177 #endif
178 
179 #ifdef LINALGPACK_CHECK_RANGE
181  if( j > cols() || !j )
182  throw std::out_of_range("DMatrix::validate_col_subscript(j) : column index out of bounds");
183 }
184 #endif
185 
186 } // end namespace DenseLinAlgPack
187 
188 // ///////////////////////////////////////////////////////////////////////////////
189 // Non-member funcitons
190 
192  , const DMatrixSlice& gms2, BLAS_Cpp::Transp trans2)
193 {
194  if (
195  (trans1 == trans2) ?
196  gms1.rows() == gms2.rows() && gms1.cols() == gms2.cols()
197  : gms1.rows() == gms2.cols() && gms1.cols() == gms2.rows()
198  )
199  return; // compatible sizes so exit
200  // not compatible sizes.
201  throw std::length_error("Matrix sizes are not the compatible");
202 }
EOverLap overlap(const DMatrixSlice &gms) const
DVectorSlice p_diag(difference_type k) const
size_type cols() const
Return the number of columns.
VectorSliceTmpl< value_type > DVectorSlice
void assert_gms_sizes(const DMatrixSlice &gms1, BLAS_Cpp::Transp trans1, const DMatrixSlice &gms2, BLAS_Cpp::Transp trans2)
Assert two matrices are the same size and throws length_error if they are not (LINALGPACK_CHECK_RHS_S...
DVectorSlice p_diag(difference_type k) const
size_type max_rows() const
Return the number of rows in the full matrix. Equivalent to BLAS LDA argument.
void validate_col_subscript(size_type j) const
size_type rows() const
Return the number of rows.
EOverLap
Enumeration for returning the amount of overlap between two objects.
DenseLinAlgPack::size_type size_type
size_type rows() const
Return the number of rows.
void swap(row_col_value_type< T > &v1, row_col_value_type< T > &v2)
Swap row_col_value_type<T> objects.
void validate_setup(size_type size) const
EOverLap overlap(const DMatrixSlice &gms) const
Transp
TRANS.
size_type cols() const
Return the number of columns.
void validate_row_subscript(size_type i) const