Free Electron
DenseVector.h
Go to the documentation of this file.
1 /* Copyright (C) 2003-2021 Free Electron Organization
2  Any use of this software requires a license. If a valid license
3  was not distributed with this file, visit freeelectron.org. */
4 
5 /** @file */
6 
7 #ifndef __solve_DenseVector_h__
8 #define __solve_DenseVector_h__
9 
10 namespace fe
11 {
12 namespace ext
13 {
14 
15 /**************************************************************************//**
16  @brief Dense vector - size fixed at construction or reset
17 
18  @ingroup solve
19 *//***************************************************************************/
20 template<class T>
22 {
23  public:
24  DenseVector(U32 size=0);
25  DenseVector(const DenseVector<T> &other);
26  ~DenseVector(void);
27 
28  void reset(U32 size);
29  void clear(void);
30 
31  T &operator[](U32 index);
32  T operator[](U32 index) const;
33 
34  U32 size(void) const { return m_size; }
35 
36  DenseVector<T> &operator=(const DenseVector<T> &other);
37 
38  private:
39  void initialize(U32 size);
40 
41  U32 m_size;
42  T* m_pData;
43 };
44 
45 
46 template<class T>
47 inline DenseVector<T>::DenseVector(U32 size):
48  m_pData(NULL)
49 {
50  initialize(size);
51 }
52 
53 template<class T>
54 inline void DenseVector<T>::initialize(U32 size)
55 {
56  m_size=size;
57  if(m_size)
58  {
59  m_pData=new T[m_size];
60 // feLog("DenseVector<T>::initialize new m_pData %d\n",m_size);
61  }
62 
63  clear();
64 }
65 
66 template<class T>
67 inline DenseVector<T>::DenseVector(const DenseVector<T> &other):
68  m_size(0),
69  m_pData(NULL)
70 {
71  operator=(other);
72 }
73 
74 template<class T>
76 {
77  delete[] m_pData;
78 }
79 
80 template<class T>
81 inline void DenseVector<T>::reset(U32 size)
82 {
83  if(size==m_size)
84  {
85  clear();
86  }
87  else
88  {
89  delete[] m_pData;
90  initialize(size);
91  }
92 }
93 
94 template<class T>
95 inline void DenseVector<T>::clear(void)
96 {
97  for(U32 i=0; i<m_size; i++)
98  {
99  m_pData[i] = T(0);
100  }
101 }
102 
103 template<>
104 inline void DenseVector<F32>::clear(void)
105 {
106  if(m_size)
107  {
108  memset(m_pData,0,m_size*sizeof(F32));
109  }
110 }
111 
112 template<>
113 inline void DenseVector<F64>::clear(void)
114 {
115  if(m_size)
116  {
117  memset(m_pData,0,m_size*sizeof(F64));
118  }
119 }
120 
121 template<class T>
122 inline T &DenseVector<T>::operator[](U32 index)
123 {
124 #if FE_BOUNDSCHECK
125  if(index >= m_size) { feX(e_invalidRange); }
126 #endif
127  return m_pData[index];
128 }
129 
130 template<class T>
131 inline T DenseVector<T>::operator[](U32 index) const
132 {
133 #if FE_BOUNDSCHECK
134  if(index >= m_size) { feX(e_invalidRange); }
135 #endif
136  return m_pData[index];
137 }
138 
139 template<class T>
141 {
142  if(m_size!=other.m_size)
143  {
144  m_size=other.m_size;
145 
146  delete[] m_pData;
147  m_pData=new T[m_size];
148 // feLog("operator= new m_pData %d\n",m_size);
149  }
150 
151  FEASSERT(m_pData);
152 
153  if(this != &other)
154  {
155 #if FALSE
156  for(U32 i = 0; i < m_size; i++)
157  {
158  m_pData[i] = other[i];
159  }
160 #else
161  memcpy(m_pData,other.m_pData,m_size*sizeof(T));
162 #endif
163  }
164  return *this;
165 }
166 
167 /* non member operations */
168 
169 /** Set all the elements to zero
170  @relates DenseVector
171  */
172 template<class T>
174 {
175  lhs.clear();
176  return lhs;
177 }
178 
179 /** Set all the elements to the given value
180  @relates DenseVector
181  */
182 template<class T>
183 inline DenseVector<T>& setAll(DenseVector<T> &lhs,const T value)
184 {
185  const U32 size=lhs.size();
186  for(U32 i = 0; i < size; i++)
187  {
188  lhs[i] = value;
189  }
190  return lhs;
191 }
192 
193 /** Set the value at the index
194  @relates DenseVector
195  */
196 template<class T>
197 inline DenseVector<T> &setAt(DenseVector<T> &lhs, U32 index,const T value)
198 {
199  lhs[index]=value;
200  return lhs;
201 }
202 
203 /** Add with scaling
204 
205  lhs = lhs + rhs * scalar
206 
207  @relates DenseVector
208  */
209 template<class T,class U>
211  const DenseVector<T> &rhs)
212 {
213  const U32 size=lhs.size();
214 #if FE_BOUNDSCHECK
215  if(size != rhs.size()) { feX(e_invalidRange); }
216 #endif
217 
218  for(U32 i = 0; i < size; i++)
219  {
220  lhs[i] += rhs[i] * scalar;
221  }
222  return lhs;
223 }
224 
225 /** Scale then add
226 
227  lhs = lhs * scalar + rhs
228 
229  @relates DenseVector
230  */
231 template<class T,class U>
233  const DenseVector<T> &rhs)
234 {
235  const U32 size=lhs.size();
236 #if FE_BOUNDSCHECK
237  if(size != rhs.size()) { feX(e_invalidRange); }
238 #endif
239 
240  for(U32 i = 0; i < size; i++)
241  {
242  lhs[i] = lhs[i] * scalar + rhs[i];
243  }
244  return lhs;
245 }
246 
247 /** In place add operator
248  @relates DenseVector
249  */
250 template<class T>
252  const DenseVector<T> &rhs)
253 {
254  const U32 size=lhs.size();
255 #if FE_BOUNDSCHECK
256  if(size != rhs.size()) { feX(e_invalidRange); }
257 #endif
258 
259  for(U32 i = 0; i < size; i++)
260  {
261  lhs[i] += rhs[i];
262  }
263  return lhs;
264 }
265 
266 /** In place subtract operator
267  @relates DenseVector
268  */
269 template<class T>
271  const DenseVector<T> &rhs)
272 {
273  const U32 size=lhs.size();
274 #if FE_BOUNDSCHECK
275  if(size != rhs.size()) { feX(e_invalidRange); }
276 #endif
277 
278  for(U32 i = 0; i < size; i++)
279  {
280  lhs[i] -= rhs[i];
281  }
282  return lhs;
283 }
284 
285 /** Negate operation
286  @relates DenseVector
287  */
288 template<class T>
290 {
291  const U32 size=rhs.size();
292 
293  DenseVector<T> v(size);
294  for(U32 i = 0; i < size; i++)
295  {
296  v[i] = -rhs[i];
297  }
298  return v;
299 }
300 
301 /** In place piecewise multiply operator
302  @relates DenseVector
303  */
304 template<class T>
306  const DenseVector<T> &rhs)
307 {
308  const U32 size=lhs.size();
309 #if FE_BOUNDSCHECK
310  if(size != rhs.size()) { feX(e_invalidRange); }
311 #endif
312 
313  for(U32 i = 0; i < size; i++)
314  {
315  lhs[i] = lhs[i] * rhs[i];
316  }
317  return lhs;
318 }
319 
320 /** In place piecewise scale operator
321  @relates DenseVector
322  */
323 template<class T,class U>
325 {
326  const U32 size=lhs.size();
327 
328  for(U32 i = 0; i < size; i++)
329  {
330  lhs[i] *= scale;
331  }
332  return lhs;
333 }
334 
335 /** Dot (inner) product
336  @relates DenseVector
337  */
338 template<class T>
339 inline T dot(const DenseVector<T> &lhs, const DenseVector<T> &rhs)
340 {
341  const U32 size=lhs.size();
342 #if FE_BOUNDSCHECK
343  if(size != rhs.size()) { feX(e_invalidRange); }
344 #endif
345 
346  T t = (T)0;
347  for(U32 i = 0; i < size; i++)
348  {
349  t += lhs[i] * rhs[i];
350 // feLog("dot %d %.6G*%.6G=%.6G %.6G\n",i,lhs[i],rhs[i],lhs[i]*rhs[i],t);
351  }
352  return t;
353 }
354 
355 /** Frobenius norm operation
356  @relates DenseVector
357  */
358 template<class T>
359 inline T magnitude(const DenseVector<T> &rhs)
360 {
361  const U32 size=rhs.size();
362 
363  T mag = 0.0;
364  for(U32 i = 0; i < size; i++)
365  {
366  mag += (T)rhs[i] * (T)rhs[i];
367  }
368  return sqrt(mag);
369 }
370 
371 /** Square of the length
372  @relates DenseVector
373  */
374 template<class T>
375 inline T magnitudeSquared(const DenseVector<T> &rhs)
376 {
377  const U32 size=rhs.size();
378 
379  T mag = 0.0;
380  for(U32 i = 0; i < size; i++)
381  {
382  mag += (T)rhs[i] * (T)rhs[i];
383  }
384  return mag;
385 }
386 
387 /** Return normal
388  @relates DenseVector
389  */
390 template<class T>
392 {
393  const U32 size=rhs.size();
394 
395  const T mag = magnitude(rhs);
396  if(mag == 0.0)
397  {
398  feX("normal",
399  "attempt to normalize zero magnitude vector");
400  }
401  const T inv = 1.0/mag;
402  DenseVector<T> v(size);
403  for(U32 i = 0; i < size; i++)
404  {
405  v[i] = inv * rhs[i];
406  }
407  return v;
408 }
409 
410 /** In place normalize operator
411  @relates DenseVector
412  */
413 template<class T>
415 {
416  const U32 size=lhs.size();
417 
418  const T mag = magnitude(lhs);
419  if(mag == 0.0)
420  {
421  feX("DenseVector<T>::normal",
422  "attempt to normalize zero magnitude vector");
423  }
424  const T inv = 1.0/mag;
425  for(U32 i = 0; i < size; i++)
426  {
427  lhs[i] *= inv;
428  }
429  return lhs;
430 }
431 
432 /** add operation
433  @relates DenseVector
434  */
435 template<class T>
437  const DenseVector<T> &rhs)
438 {
439  const U32 size=lhs.size();
440 #if FE_BOUNDSCHECK
441  if(size != rhs.size()) { feX(e_invalidRange); }
442 #endif
443 
444  DenseVector<T> v(size);
445  for(U32 i = 0; i < size; i++)
446  {
447  v[i] = lhs[i] + rhs[i];
448  }
449  return v;
450 }
451 
452 /** subtractoperation
453  @relates DenseVector
454  */
455 template<class T>
457  const DenseVector<T> &rhs)
458 {
459  const U32 size=lhs.size();
460 #if FE_BOUNDSCHECK
461  if(size != rhs.size()) { feX(e_invalidRange); }
462 #endif
463 
464  DenseVector<T> v(size);
465  for(U32 i = 0; i < size; i++)
466  {
467  v[i] = lhs[i] - rhs[i];
468  }
469  return v;
470 }
471 
472 /** equality test
473  @relates DenseVector
474  */
475 template<class T>
476 inline bool operator==(const DenseVector<T> &lhs, const DenseVector<T> &rhs)
477 {
478  const U32 size=lhs.size();
479 #if FE_BOUNDSCHECK
480  if(size != rhs.size()) { feX(e_invalidRange); }
481 #endif
482 
483  for(U32 i = 0; i < size; i++)
484  {
485  if(rhs[i] != lhs[i])
486  {
487  return false;
488  }
489  }
490  return true;
491 }
492 
493 /** Equivalence test within the given tolerance @em margin
494  @relates DenseVector
495  */
496 template<class T>
497 inline bool equivalent(const DenseVector<T> &lhs, const DenseVector<T> &rhs,
498  T margin)
499 {
500  const U32 size=lhs.size();
501 #if FE_BOUNDSCHECK
502  if(size != rhs.size()) { feX(e_invalidRange); }
503 #endif
504 
505  for(U32 i = 0; i < size; i++)
506  {
507  if(FE_INVALID_SCALAR(lhs[i]) ||
508  FE_INVALID_SCALAR(rhs[i]) ||
509  fabs(rhs[i] - lhs[i]) > margin)
510  {
511  return false;
512  }
513  }
514  return true;
515 }
516 
517 /** Piecewise multiply operation
518  @relates DenseVector
519  */
520 template<class T>
522  const DenseVector<T> &rhs)
523 {
524  const U32 size=lhs.size();
525 #if FE_BOUNDSCHECK
526  if(size != rhs.size()) { feX(e_invalidRange); }
527 #endif
528 
529  DenseVector<T> v(size);
530  for(U32 i = 0; i < size; i++)
531  {
532  v[i] = lhs[i] * rhs[i];
533  }
534  return v;
535 }
536 
537 /** Scale operation
538  @relates DenseVector
539  */
540 template<class T,class U>
541 inline DenseVector<T> operator*(const U lhs, const DenseVector<T> &rhs)
542 {
543  const U32 size=rhs.size();
544 
545  DenseVector<T> v(size);
546  for(U32 i = 0; i < size; i++)
547  {
548  v[i] = rhs[i] * lhs;
549  }
550  return v;
551 }
552 
553 /** Scale operation
554  @relates DenseVector
555  */
556 template<class T,class U>
557 inline DenseVector<T> operator*(const DenseVector<T> &lhs, const U rhs)
558 {
559  const U32 size=lhs.size();
560 #if FE_BOUNDSCHECK
561  if(size != rhs.size()) { feX(e_invalidRange); }
562 #endif
563 
564  DenseVector<T> v(size);
565  for(U32 i = 0; i < size; i++)
566  {
567  v[i] = lhs[i] * rhs;
568  }
569  return v;
570 }
571 
572 /** Inverse Scale operation
573  @relates DenseVector
574  */
575 template<class T,class U>
576 inline DenseVector<T> operator/(const DenseVector<T> &lhs, const U rhs)
577 {
578  if(rhs==0.0f)
579  feX(e_unsolvable,"operator/(DenseVector<T>,T)","divide by zero");
580  return lhs*(1.0f/rhs);
581 }
582 
583 /** Return number of elements
584  @relates DenseVector
585  */
586 template<class T>
587 inline U32 size(const DenseVector<T> &lhs)
588 {
589  return lhs.size();
590 }
591 
592 /** Multiply each pair of components
593 
594  @relates DenseVector
595  */
596 template<class T>
598  const DenseVector<T> &lhs,const DenseVector<T> &rhs)
599 {
600  const U32 size=lhs.size();
601 #if FE_BOUNDSCHECK
602  if(size != rhs.size()) { feX(e_invalidRange); }
603 #endif
604 
605  for(U32 i = 0; i < size; i++)
606  {
607  result[i] = lhs[i] * rhs[i];
608  }
609  return result;
610 }
611 } /* namespace ext */
612 } /* namespace fe */
613 
614 namespace fe
615 {
616 
617 /** Print to a string
618  @relates DenseVector
619  */
620 template<class T>
621 inline String print(const ext::DenseVector<T> &rhs)
622 {
623  const U32 size=rhs.size();
624 
625  String s = "";
626  for(U32 i = 0; i < size; i++)
627  {
628  if(i)
629  {
630  s.cat(" ");
631  }
632  s.catf("%.6G", rhs[i]);
633  }
634  return s;
635 }
636 
637 } /* namespace fe */
638 
639 #endif /* __solve_DenseVector_h__ */
640 
T magnitudeSquared(const DenseVector< T > &rhs)
Square of the length.
Definition: DenseVector.h:375
DenseVector< T > & setAt(DenseVector< T > &lhs, U32 index, const T value)
Set the value at the index.
Definition: DenseVector.h:197
DenseVector< T > & scaleAndAdd(DenseVector< T > &lhs, U scalar, const DenseVector< T > &rhs)
Scale then add.
Definition: DenseVector.h:232
DenseVector< T > operator*(const DenseVector< T > &lhs, const DenseVector< T > &rhs)
Piecewise multiply operation.
Definition: DenseVector.h:521
DenseVector< T > operator*(const U lhs, const DenseVector< T > &rhs)
Scale operation.
Definition: DenseVector.h:541
DenseVector< T > & operator+=(DenseVector< T > &lhs, const DenseVector< T > &rhs)
In place add operator.
Definition: DenseVector.h:251
Dense vector - size fixed at construction or reset.
Definition: DenseVector.h:21
DenseVector< T > operator/(const DenseVector< T > &lhs, const U rhs)
Inverse Scale operation.
Definition: DenseVector.h:576
DenseVector< T > operator-(const DenseVector< T > &rhs)
Negate operation.
Definition: DenseVector.h:289
DenseVector< T > & operator-=(DenseVector< T > &lhs, const DenseVector< T > &rhs)
In place subtract operator.
Definition: DenseVector.h:270
bool operator==(const DenseVector< T > &lhs, const DenseVector< T > &rhs)
equality test
Definition: DenseVector.h:476
kernel
Definition: namespace.dox:3
DenseVector< T > & operator*=(DenseVector< T > &lhs, U scale)
In place piecewise scale operator.
Definition: DenseVector.h:324
DenseVector< T > normal(const DenseVector< T > &rhs)
Return normal.
Definition: DenseVector.h:391
bool equivalent(const DenseVector< T > &lhs, const DenseVector< T > &rhs, T margin)
Equivalence test within the given tolerance margin.
Definition: DenseVector.h:497
DenseVector< T > & addScaled(DenseVector< T > &lhs, U scalar, const DenseVector< T > &rhs)
Add with scaling.
Definition: DenseVector.h:210
DenseVector< T > & setAll(DenseVector< T > &lhs, const T value)
Set all the elements to the given value.
Definition: DenseVector.h:183
T dot(const DenseVector< T > &lhs, const DenseVector< T > &rhs)
Dot (inner) product.
Definition: DenseVector.h:339
DenseVector< T > & normalize(DenseVector< T > &lhs)
In place normalize operator.
Definition: DenseVector.h:414
DenseVector< T > operator+(const DenseVector< T > &lhs, const DenseVector< T > &rhs)
add operation
Definition: DenseVector.h:436
String & cat(const char *operand)
Append the current String with the given text.
Definition: String.cc:545
T magnitude(const DenseVector< T > &rhs)
Frobenius norm operation.
Definition: DenseVector.h:359
Automatically reference-counted string container.
Definition: String.h:128
DenseVector< T > operator*(const DenseVector< T > &lhs, const U rhs)
Scale operation.
Definition: DenseVector.h:557
U32 size(const DenseVector< T > &lhs)
Return number of elements.
Definition: DenseVector.h:587
String & catf(const char *fmt,...)
Populate the string as with sPrintf(), but by concatenating the results to the existing string...
Definition: String.cc:554
DenseVector< T > & componentMultiply(DenseVector< T > &result, const DenseVector< T > &lhs, const DenseVector< T > &rhs)
Multiply each pair of components.
Definition: DenseVector.h:597
DenseVector< T > operator-(const DenseVector< T > &lhs, const DenseVector< T > &rhs)
subtractoperation
Definition: DenseVector.h:456
DenseVector< T > & operator*=(DenseVector< T > &lhs, const DenseVector< T > &rhs)
In place piecewise multiply operator.
Definition: DenseVector.h:305