PEXSI
 All Classes Namespaces Files Functions Variables Typedefs Pages
NumVec_impl.hpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 2012 The Regents of the University of California,
3  through Lawrence Berkeley National Laboratory.
4 
5 Authors: Lexing Ying, Mathias Jacquelin and Lin Lin
6 
7 This file is part of PEXSI. All rights reserved.
8 
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions are met:
11 
12 (1) Redistributions of source code must retain the above copyright notice, this
13 list of conditions and the following disclaimer.
14 (2) Redistributions in binary form must reproduce the above copyright notice,
15 this list of conditions and the following disclaimer in the documentation
16 and/or other materials provided with the distribution.
17 (3) Neither the name of the University of California, Lawrence Berkeley
18 National Laboratory, U.S. Dept. of Energy nor the names of its contributors may
19 be used to endorse or promote products derived from this software without
20 specific prior written permission.
21 
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
23 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
26 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 
33 You are under no obligation whatsoever to provide any bug fixes, patches, or
34 upgrades to the features, functionality or performance of the source code
35 ("Enhancements") to anyone; however, if you choose to make your Enhancements
36 available either publicly, or directly to Lawrence Berkeley National
37 Laboratory, without imposing a separate written license agreement for such
38 Enhancements, then you hereby grant the following license: a non-exclusive,
39 royalty-free perpetual license to install, use, modify, prepare derivative
40 works, incorporate into other computer software, distribute, and sublicense
41 such enhancements or derivative works thereof, in binary and source code form.
42  */
46 #ifndef _PEXSI_NUMVEC_IMPL_HPP_
47 #define _PEXSI_NUMVEC_IMPL_HPP_
48 
49 
50 namespace PEXSI{
51 
52  // Templated form of numerical vectors
53  //
54  // The main advantage of this portable NumVec structure is that it can
55  // either own (owndata == true) or view (owndata == false) a piece of
56  // data.
57 
58  template <class F> NumVec<F>::NumVec () : m_(0), owndata_(true), data_(NULL), bufsize_(0)
59  {
60 #ifndef _RELEASE_
61  PushCallStack("NumVec<F>::NumVec");
62 #endif // ifndef _RELEASE_
63  m_ = 0;
64 #ifndef _RELEASE_
65  PopCallStack();
66 #endif // ifndef _RELEASE_
67  } // ----- end of method NumVec<F>::NumVec -----
68 
69 
70  template <class F> NumVec<F>::NumVec ( Int m ) : m_(m), owndata_(true), data_(NULL), bufsize_(0)
71  {
72 #ifndef _RELEASE_
73  PushCallStack("NumVec<F>::NumVec");
74 #endif // ifndef _RELEASE_
75 
76  this->allocate();
77 
78 #ifndef _RELEASE_
79  PopCallStack();
80 #endif // ifndef _RELEASE_
81  } // ----- end of method NumVec<F>::NumVec -----
82 
83  template <class F> NumVec<F>::NumVec ( Int m, bool owndata, F* data ) : m_(m), owndata_(owndata), data_(NULL), bufsize_(0)
84  {
85 #ifndef _RELEASE_
86  PushCallStack("NumVec<F>::NumVec");
87 #endif // ifndef _RELEASE_
88 
89  this->allocate(data);
90 
91 #ifndef _RELEASE_
92  PopCallStack();
93 #endif // ifndef _RELEASE_
94  } // ----- end of method NumVec<F>::NumVec -----
95 
96  template <class F> NumVec<F>::NumVec ( const NumVec<F>& C ) : m_(C.m_), owndata_(C.owndata_), data_(NULL), bufsize_(0)
97  {
98 #ifndef _RELEASE_
99  PushCallStack("NumVec<F>::NumVec");
100 #endif // ifndef _RELEASE_
101  this->allocate(C.data_);
102 #ifndef _RELEASE_
103  PopCallStack();
104 #endif // ifndef _RELEASE_
105  } // ----- end of method NumVec<F>::NumVec -----
106 
107 
108  template < class F > NumVec<F>::~NumVec ( )
109  {
110 #ifndef _RELEASE_
111  PushCallStack("NumVec<F>::~NumVec");
112 #endif // ifndef _RELEASE_
113  this->deallocate();
114 #ifndef _RELEASE_
115  PopCallStack();
116 #endif // ifndef _RELEASE_
117 
118  } // ----- end of method NumVec<F>::~NumVec -----
119 
120 
121  template < class F > inline NumVec<F>& NumVec<F>::operator = ( const NumVec& C )
122  {
123 #ifndef _RELEASE_
124  PushCallStack("NumVec<F>::operator=");
125 #endif // ifndef _RELEASE_
126  this->deallocate();
127  m_ = C.m_;
128  owndata_ = C.owndata_;
129  this->allocate(C.data_);
130 #ifndef _RELEASE_
131  PopCallStack();
132 #endif // ifndef _RELEASE_
133 
134  return *this;
135  } // ----- end of method NumVec<F>::operator= -----
136 
137 
138  template < class F > inline void NumVec<F>::Resize ( const Int m )
139  {
140 #ifndef _RELEASE_
141  PushCallStack("NumVec<F>::Resize");
142 #endif // ifndef _RELEASE_
143  if( owndata_ == false ){
144 #ifdef USE_ABORT
145  abort();
146 #endif
147  throw std::logic_error("Vector being resized must own data.");
148  }
149  if(m > bufsize_) {
150  this->deallocate();
151  m_ = m;
152  this->allocate();
153  }
154  else{
155  m_ = m;
156  }
157 #ifndef _RELEASE_
158  PopCallStack();
159 #endif // ifndef _RELEASE_
160  return ;
161  } // ----- end of method NumVec<F>::Resize -----
162 
163  template < class F > inline void NumVec<F>::Clear ( )
164  {
165 #ifndef _RELEASE_
166  PushCallStack("NumVec<F>::Clear");
167 #endif // ifndef _RELEASE_
168  if( owndata_ == false ){
169  data_ = NULL;
170  }
171  else{
172  this->deallocate();
173  }
174 #ifndef _RELEASE_
175  PopCallStack();
176 #endif // ifndef _RELEASE_
177  return ;
178  } // ----- end of method NumVec<F>::Clear -----
179 
180 
181 
182  template <class F> inline F& NumVec<F>::operator() ( Int i )
183  {
184 #ifndef _RELEASE_
185  PushCallStack("NumVec<F>::operator()");
186  if( i < 0 || i >= m_ ){
187 #ifdef USE_ABORT
188  abort();
189 #endif
190  throw std::logic_error( "Index is out of bound." );
191  }
192  PopCallStack();
193 #endif // ifndef _RELEASE_
194  return data_[i];
195 
196  } // ----- end of method NumVec<F>::operator() -----
197 
198 
199  template <class F>
200  inline const F&
201  NumVec<F>::operator() ( Int i ) const
202  {
203 #ifndef _RELEASE_
204  PushCallStack("NumVec<F>::operator()");
205  if( i < 0 || i >= m_ ){
206 #ifdef USE_ABORT
207  abort();
208 #endif
209  throw std::logic_error( "Index is out of bound." );
210  }
211  PopCallStack();
212 #endif // ifndef _RELEASE_
213  return data_[i];
214 
215  } // ----- end of method NumVec<F>::operator() -----
216 
217 
218  template <class F> inline F& NumVec<F>::operator[] ( Int i )
219  {
220 #ifndef _RELEASE_
221  PushCallStack("NumVec<F>::operator[]");
222  if( i < 0 || i >= m_ ){
223 #ifdef USE_ABORT
224  abort();
225 #endif
226  throw std::logic_error( "Index is out of bound." );
227  }
228  PopCallStack();
229 #endif // ifndef _RELEASE_
230  return data_[i];
231  } // ----- end of method NumVec<F>::operator[] -----
232 
233 
234  template <class F> inline const F& NumVec<F>::operator[] ( Int i ) const
235  {
236 #ifndef _RELEASE_
237  PushCallStack("NumVec<F>::operator[]");
238  if( i < 0 || i >= m_ ){
239 #ifdef USE_ABORT
240  abort();
241 #endif
242  throw std::logic_error( "Index is out of bound." );
243  }
244  PopCallStack();
245 #endif // ifndef _RELEASE_
246  return data_[i];
247 
248  } // ----- end of method NumVec<F>::operator[] -----
249 
250  template <class F> inline void NumVec<F>::allocate(F* data) {
251  if(owndata_) {
252  if(m_>0) {
253  data_ = new F[m_];
254  if( data_ == NULL ) {
255 #ifdef USE_ABORT
256  abort();
257 #endif
258  throw std::runtime_error("Cannot allocate memory.");
259  }
260  }
261  else{
262  data_=NULL;
263  }
264  if(data!=NULL){
265  std::copy(data,data+m_,data_);
266  }
267  }
268  else {
269  data_ = data;
270  }
271  bufsize_ = m_;
272  } // ----- end of method NumVec<F>::allocate -----
273 
274  template <class F> inline void NumVec<F>::deallocate() {
275  if(owndata_) {
276  if(bufsize_>0) { delete[] data_; data_ = NULL; bufsize_=0; m_=0; }
277  }
278  } // ----- end of method NumVec<F>::deallocate -----
279 
280 
281 
282 
283  template <class F> inline void SetValue( NumVec<F>& vec, F val )
284  {
285  std::fill(vec.Data(),vec.Data()+vec.m(),val);
286  }
287 
288  template <class F> inline Real Energy( const NumVec<F>& vec )
289  {
290  Real sum = 0;
291  for(Int i=0; i<vec.m(); i++){
292  sum += std::abs(vec(i)*vec(i));
293  }
294  return sum;
295  }
296 
297 
298 } // namespace PEXSI
299 
300 #endif // _PEXSI_NUMVEC_IMPL_HPP_
Numerical vector.
Definition: NumVec.hpp:60
Real Energy(const NumMat< F > &M)
Energy computes the L2 norm of a matrix (treated as a vector).
Definition: NumMat_impl.hpp:176
void SetValue(NumMat< F > &M, F val)
SetValue sets a numerical matrix to a constant val.
Definition: NumMat_impl.hpp:171