All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SparseVector.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_SPARSEVECTOR_H_
23 #define _BLAZE_MATH_SPARSEVECTOR_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
30 #include <boost/type_traits/remove_reference.hpp>
46 #include <blaze/math/shims/Equal.h>
49 #include <blaze/math/Vector.h>
50 #include <blaze/util/Assert.h>
51 #include <blaze/util/Types.h>
52 
53 
54 namespace blaze {
55 
56 //=================================================================================================
57 //
58 // GLOBAL OPERATORS
59 //
60 //=================================================================================================
61 
62 //*************************************************************************************************
65 template< typename T1, bool TF1, typename T2, bool TF2 >
66 inline bool operator==( const SparseVector<T1,TF1>& lhs, const SparseVector<T2,TF2>& rhs );
67 
68 template< typename T1, bool TF1, typename T2, bool TF2 >
69 inline bool operator!=( const SparseVector<T1,TF1>& lhs, const SparseVector<T2,TF2>& rhs );
71 //*************************************************************************************************
72 
73 
74 //*************************************************************************************************
82 template< typename T1 // Type of the left-hand side sparse vector
83  , bool TF1 // Transpose flag of the left-hand side sparse vector
84  , typename T2 // Type of the right-hand side sparse vector
85  , bool TF2 > // Transpose flag of the right-hand side sparse vector
86 inline bool operator==( const SparseVector<T1,TF1>& lhs, const SparseVector<T2,TF2>& rhs )
87 {
88  typedef typename T1::CompositeType CT1;
89  typedef typename T2::CompositeType CT2;
90  typedef typename boost::remove_reference<CT1>::type::ConstIterator LhsConstIterator;
91  typedef typename boost::remove_reference<CT2>::type::ConstIterator RhsConstIterator;
92 
93  // Early exit in case the vector sizes don't match
94  if( (~lhs).size() != (~rhs).size() ) return false;
95 
96  // Evaluation of the two sparse vector operands
97  CT1 a( ~lhs );
98  CT2 b( ~rhs );
99 
100  // In order to compare the two vectors, the data values of the lower-order data
101  // type are converted to the higher-order data type within the equal function.
102  const LhsConstIterator lend( a.end() );
103  const RhsConstIterator rend( b.end() );
104 
105  LhsConstIterator lelem( a.begin() );
106  RhsConstIterator relem( b.begin() );
107 
108  while( lelem < lend && relem < rend )
109  {
110  if( isDefault( lelem->value() ) ) { ++lelem; continue; }
111  if( isDefault( relem->value() ) ) { ++relem; continue; }
112 
113  if( lelem->index() != relem->index() || !equal( lelem->value(), relem->value() ) ) {
114  return false;
115  }
116  else {
117  ++lelem;
118  ++relem;
119  }
120  }
121 
122  while( lelem < lend ) {
123  if( !isDefault( lelem->value() ) )
124  return false;
125  ++lelem;
126  }
127 
128  while( relem < rend ) {
129  if( !isDefault( relem->value() ) )
130  return false;
131  ++relem;
132  }
133 
134  return true;
135 }
136 //*************************************************************************************************
137 
138 
139 //*************************************************************************************************
147 template< typename T1 // Type of the left-hand side sparse vector
148  , bool TF1 // Transpose flag of the left-hand side sparse vector
149  , typename T2 // Type of the right-hand side sparse vector
150  , bool TF2 > // Transpose flag of the right-hand side sparse vector
151 inline bool operator!=( const SparseVector<T1,TF1>& lhs, const SparseVector<T2,TF2>& rhs )
152 {
153  return !( lhs == rhs );
154 }
155 //*************************************************************************************************
156 
157 
158 
159 
160 //=================================================================================================
161 //
162 // GLOBAL FUNCTIONS
163 //
164 //=================================================================================================
165 
166 //*************************************************************************************************
169 template< typename VT, bool TF >
170 inline const typename VT::ElementType min( const SparseVector<VT,TF>& sv );
171 
172 template< typename VT, bool TF >
173 inline const typename VT::ElementType max( const SparseVector<VT,TF>& sv );
175 //*************************************************************************************************
176 
177 
178 //*************************************************************************************************
198 template< typename VT // Type of the sparse vector
199  , bool TF > // Transpose flag
200 inline const typename VT::ElementType min( const SparseVector<VT,TF>& sv )
201 {
202  using boost::remove_reference;
203  using blaze::min;
204 
205  typedef typename VT::ElementType ET;
206  typedef typename VT::CompositeType SV;
207  typedef typename remove_reference<SV>::type::ConstIterator ConstIterator;
208 
209  SV a( ~sv ); // Evaluation of the sparse vector operand
210 
211  const ConstIterator end( a.end() );
212  ConstIterator element( a.begin() );
213 
214  if( element == end ) {
215  return ET();
216  }
217  else if( a.nonZeros() == a.size() ) {
218  ET minimum( element->value() );
219  ++element;
220  for( ; element!=end; ++element )
221  minimum = min( minimum, element->value() );
222  return minimum;
223  }
224  else {
225  ET minimum = ET();
226  for( ; element!=end; ++element )
227  minimum = min( minimum, element->value() );
228  return minimum;
229  }
230 }
231 //*************************************************************************************************
232 
233 
234 //*************************************************************************************************
254 template< typename VT // Type of the sparse vector
255  , bool TF > // Transpose flag
256 inline const typename VT::ElementType max( const SparseVector<VT,TF>& sv )
257 {
258  using boost::remove_reference;
259  using blaze::max;
260 
261  typedef typename VT::ElementType ET;
262  typedef typename VT::CompositeType SV;
263  typedef typename remove_reference<SV>::type::ConstIterator ConstIterator;
264 
265  SV a( ~sv ); // Evaluation of the sparse vector operand
266 
267  const ConstIterator end( a.end() );
268  ConstIterator element( a.begin() );
269 
270  if( element == end ) {
271  return ET();
272  }
273  else if( a.nonZeros() == a.size() ) {
274  ET maximum( element->value() );
275  ++element;
276  for( ; element!=end; ++element )
277  maximum = max( maximum, element->value() );
278  return maximum;
279  }
280  else {
281  ET maximum = ET();
282  for( ; element!=end; ++element )
283  maximum = max( maximum, element->value() );
284  return maximum;
285  }
286 }
287 //*************************************************************************************************
288 
289 } // namespace blaze
290 
291 #endif