SmallVector.h
Go to the documentation of this file.
1 /*
2  This file forms part of hpGEM. This package has been developed over a number of years by various people at the University of Twente and a full list of contributors can be found at
3  http://hpgem.org/about-the-code/team
4 
5  This code is distributed using BSD 3-Clause License. A copy of which can found below.
6 
7 
8  Copyright (c) 2014, University of Twente
9  All rights reserved.
10 
11  Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
12 
13  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
14 
15  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
16 
17  3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
18 
19  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20  */
21 
22 //Copyright (c) 2013-2023, The MercuryDPM Developers Team. All rights reserved.
23 //For the list of developers, see <http://www.MercuryDPM.org/Team>.
24 //
25 //Redistribution and use in source and binary forms, with or without
26 //modification, are permitted provided that the following conditions are met:
27 // * Redistributions of source code must retain the above copyright
28 // notice, this list of conditions and the following disclaimer.
29 // * Redistributions in binary form must reproduce the above copyright
30 // notice, this list of conditions and the following disclaimer in the
31 // documentation and/or other materials provided with the distribution.
32 // * Neither the name MercuryDPM nor the
33 // names of its contributors may be used to endorse or promote products
34 // derived from this software without specific prior written permission.
35 //
36 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
37 //ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
38 //WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39 //DISCLAIMED. IN NO EVENT SHALL THE MERCURYDPM DEVELOPERS TEAM BE LIABLE FOR ANY
40 //DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
41 //(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 //LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43 //ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44 //(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
45 //SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46 
47 //Note: This code is copied and adapted from hpGEM (see license above), version 22th of January 2016. It has been
48 //integrated into MercuryDPM at 16th of March 2017.
49 
50 #ifndef MERCURYDPM_SMALLVECTOR_H
51 #define MERCURYDPM_SMALLVECTOR_H
52 
53 #include "GeneralDefine.h"
54 #include "Logger.h"
55 #include <cmath>
56 #include <algorithm>
57 #include <numeric>
58 #include <array>
59 
60 template<unsigned int numberOfRows>
62 {
63 
64 public:
65 
67  : data_()
68  {
69  }
70 
71  SmallVector(const SmallVector& other)
72  : data_(other.data_)
73  {
74  }
75 
77  : data_(std::move(other.data_))
78  {
79  }
80 
81  SmallVector(const Mdouble array[])
82  : data_()
83  {
84  std::copy(array, array + numberOfRows, data_.begin());
85  }
86 
87  SmallVector(std::initializer_list<Mdouble> data)
88  : data_()
89  {
90  logger.assert_debug(data.size() == numberOfRows, "provided array has size %, but should have size %",
91  data.size(), numberOfRows);
92  std::copy(data.begin(), data.end(), data_.begin());
93  }
94 
96  {
97  std::copy(right.data_.begin(), right.data_.end(), data_.begin());
98  return *this;
99  }
100 
101  SmallVector& operator=(const std::array<Mdouble, numberOfRows> l)
102  {
103  std::copy(l.begin(), l.end(), data_.begin());
104  return *this;
105  }
106 
107  SmallVector operator+(const SmallVector& right) const
108  {
109  SmallVector result;
110  std::transform(data_.begin(), data_.end(), right.data_.begin(), result.data_.begin(), std::plus<Mdouble>());
111  return result;
112  }
113 
114  SmallVector operator-(const SmallVector& right) const
115  {
116  SmallVector result;
117  std::transform(data_.begin(), data_.end(), right.data_.begin(), result.data_.begin(), std::minus<Mdouble>());
118  return result;
119  }
120 
121  SmallVector operator*(const Mdouble& right) const
122  {
123  SmallVector result;
124  std::transform(data_.begin(), data_.end(), result.data_.begin(), std::bind(std::multiplies<Mdouble>(),
125  std::placeholders::_1, right));
126  return result;
127  }
128 
130  Mdouble operator*(const SmallVector& right) const
131  {
132  return std::inner_product(right.data_.begin(), right.data_.end(), data_.begin(), 0.0);
133  }
134 
136  {
137  std::transform(data_.begin(), data_.end(), data_.begin(), std::bind(std::divides<Mdouble>(),
138  std::placeholders::_1, right));
139  return *this;
140  }
141 
142  SmallVector operator/(const Mdouble& right) const
143  {
144  SmallVector result;
145  std::transform(data_.begin(), data_.end(), result.data_.begin(), std::bind(std::divides<Mdouble>(),
146  std::placeholders::_1, right));
147  return result;
148  }
149 
150  void axpy(Mdouble a, const SmallVector& x)
151  {
152  for (unsigned int i = 0; i < numberOfRows; ++i)
153  {
154  data_[i] += a * x[i];
155  }
156  }
157 
160  bool operator==(const SmallVector& right) const
161  {
162  for (unsigned int i = 0; i < numberOfRows; ++i)
163  {
164  if (data_[i] != right[i])
165  {
166  return false;
167  }
168  }
169  return true;
170  }
171 
174  bool operator<(const SmallVector& right) const
175  {
176  for (unsigned int i = 0; i < numberOfRows; ++i)
177  {
178  if (data_[i] < right[i])
179  {
180  return true;
181  }
182  if (data_[i] > right[i])
183  {
184  return false;
185  }
186  }
187  return false;
188  }
189 
191  {
192  std::transform(data_.begin(), data_.end(), right.data_.begin(), data_.begin(), std::plus<Mdouble>());
193  return *this;
194  }
195 
197  {
198  std::transform(data_.begin(), data_.end(), right.data_.begin(), data_.begin(), std::minus<Mdouble>());
199  return *this;
200  }
201 
202  SmallVector& operator*=(const double& right)
203  {
204  std::transform(data_.begin(), data_.end(), data_.begin(), std::bind(std::multiplies<Mdouble>(),
205  std::placeholders::_1, right));
206  return *this;
207  }
208 
209  Mdouble& operator[](unsigned int n)
210  {
211  logger.assert_debug(n < numberOfRows, "Requested entry %, but there are only % entries", n, numberOfRows);
212  return data_[n];
213  }
214 
215  const Mdouble& operator[](unsigned int n) const
216  {
217  logger.assert_debug(n < numberOfRows, "Requested entry %, but there are only % entries", n, numberOfRows);
218  return data_[n];
219  }
220 
221  Mdouble& operator()(unsigned int n)
222  {
223  logger.assert_debug(n < numberOfRows, "Requested entry %, but there are only % entries", n, numberOfRows);
224  return data_[n];
225  }
226 
227  const Mdouble& operator()(unsigned int n) const
228  {
229  logger.assert_debug(n < numberOfRows, "Requested entry %, but there are only % entries", n, numberOfRows);
230  return data_[n];
231  }
232 
233  unsigned int size() const
234  {
235  return numberOfRows;
236  }
237 
238  const Mdouble* data() const
239  {
240  return data_.data();
241  }
242 
244  {
245  return data_.data();
246  }
247 
249  {
250  return *this * -1.0;
251  }
252 
253  Mdouble length() const
254  {
255  Mdouble sum = 0;
256  for (Mdouble x : data_)
257  {
258  sum += x * x;
259  logger(DEBUG, "x: %, sum: %", x, sum);
260  }
261  return std::sqrt(sum);
262  }
263 
265  {
266  return (*this) / length();
267  }
268 
269 private:
270  std::array<Mdouble, numberOfRows> data_;
271 
272 };
273 
274 template<unsigned int numberOfRows>
276 {
277  return right * left;
278 }
279 
280 template<unsigned int numberOfRows>
281 std::ostream& operator<<(std::ostream& os, const SmallVector<numberOfRows>& A)
282 {
283  os << "(";
284  for (std::size_t i = 0; i < numberOfRows; ++i)
285  {
286  os << A[i] << " ";
287  }
288  os << ")";
289  return os;
290 }
291 
292 #endif //MERCURYDPM_SMALLVECTOR_H
const unsigned n
Definition: CG3DPackingUnitTest.cpp:32
double Mdouble
Definition: GeneralDefine.h:34
Logger< MERCURYDPM_LOGLEVEL > logger("MercuryKernel")
Definition of different loggers with certain modules. A user can define its own custom logger here.
@ DEBUG
std::ostream & operator<<(std::ostream &os, const SmallVector< numberOfRows > &A)
Definition: SmallVector.h:281
SmallVector< numberOfRows > operator*(const Mdouble &left, const SmallVector< numberOfRows > &right)
Definition: SmallVector.h:275
@ A
Definition: StatisticsVector.h:42
Definition: SmallVector.h:62
Mdouble operator*(const SmallVector &right) const
Computes inner product between two vectors.
Definition: SmallVector.h:130
SmallVector< numberOfRows > getNormalised() const
Definition: SmallVector.h:264
Mdouble length() const
Definition: SmallVector.h:253
const Mdouble & operator()(unsigned int n) const
Definition: SmallVector.h:227
bool operator<(const SmallVector &right) const
Definition: SmallVector.h:174
SmallVector & operator*=(const double &right)
Definition: SmallVector.h:202
unsigned int size() const
Definition: SmallVector.h:233
SmallVector(const Mdouble array[])
Definition: SmallVector.h:81
SmallVector operator*(const Mdouble &right) const
Definition: SmallVector.h:121
SmallVector operator/(const Mdouble &right) const
Definition: SmallVector.h:142
SmallVector & operator=(const std::array< Mdouble, numberOfRows > l)
Definition: SmallVector.h:101
Mdouble * data()
Definition: SmallVector.h:243
Mdouble & operator[](unsigned int n)
Definition: SmallVector.h:209
SmallVector(const SmallVector &other)
Definition: SmallVector.h:71
const Mdouble & operator[](unsigned int n) const
Definition: SmallVector.h:215
SmallVector(std::initializer_list< Mdouble > data)
Definition: SmallVector.h:87
SmallVector & operator=(const SmallVector &right)
Definition: SmallVector.h:95
std::array< Mdouble, numberOfRows > data_
Definition: SmallVector.h:270
SmallVector operator-() const
Definition: SmallVector.h:248
void axpy(Mdouble a, const SmallVector &x)
Definition: SmallVector.h:150
SmallVector(SmallVector &&other)
Definition: SmallVector.h:76
SmallVector & operator+=(const SmallVector &right)
Definition: SmallVector.h:190
Mdouble & operator()(unsigned int n)
Definition: SmallVector.h:221
SmallVector operator-(const SmallVector &right) const
Definition: SmallVector.h:114
const Mdouble * data() const
Definition: SmallVector.h:238
SmallVector & operator-=(const SmallVector &right)
Definition: SmallVector.h:196
SmallVector()
Definition: SmallVector.h:66
bool operator==(const SmallVector &right) const
Definition: SmallVector.h:160
SmallVector operator+(const SmallVector &right) const
Definition: SmallVector.h:107
SmallVector & operator/=(const Mdouble &right)
Definition: SmallVector.h:135
const std::complex< Mdouble > i
Definition: ExtendedMath.h:51