MUQ  0.4.3
MultiIndex.cpp
Go to the documentation of this file.
2 
3 #include <iostream>
4 #include <stdexcept>
5 
6 using namespace muq::Utilities;
7 
8 
9 MultiIndex::MultiIndex(unsigned lengthIn) : length(lengthIn),
10  maxValue(0),
11  totalOrder(0)
12 {}
13 
14 MultiIndex::MultiIndex(unsigned lengthIn, unsigned val) : MultiIndex(lengthIn)
15 {
16  for(int i=0; i<length; ++i){
17  SetValue(i, val);
18  }
19 }
20 
21 MultiIndex::MultiIndex(Eigen::RowVectorXi const& indIn) : MultiIndex(indIn.size())
22 {
23  maxValue = 0;
24  totalOrder = 0;
25 
26  for(int i=0; i<indIn.size(); ++i){
27  if( indIn[i] > 0 ){
28  nzInds[i] = indIn[i];
29  maxValue = std::max<int>(maxValue, indIn[i]);
30  totalOrder += indIn[i];
31  }
32  }
33 }
34 
35 MultiIndex::MultiIndex(std::initializer_list<unsigned> const& indIn) : MultiIndex(indIn.size())
36 {
37  maxValue = 0;
38  totalOrder = 0;
39 
40  unsigned i = 0;
41  for(auto it = indIn.begin(); it != indIn.end(); ++it){
42  if( *it > 0 ){
43  nzInds[i] = *it;
44 
45  maxValue = std::max<int>(maxValue, *it);
46  totalOrder += *it;
47  }
48  i++;
49  }
50 }
51 
52 
53 Eigen::RowVectorXi MultiIndex::GetVector() const
54 {
55  Eigen::RowVectorXi output = Eigen::RowVectorXi::Zero(length);
56 
57  for(auto it = nzInds.begin(); it!=nzInds.end(); ++it)
58  output(it->first) = it->second;
59 
60  return output;
61 }
62 
63 bool MultiIndex::SetValue(unsigned ind, unsigned val)
64 {
65  if(ind>length){
66  throw std::out_of_range("Tried to set the value of index " + std::to_string(ind) + " on an multiindex with only " + std::to_string(length) + " components.");
67  }else{
68 
69  bool foundIndex;
70  if (val > 0) {
71  auto it = nzInds.find(ind);
72  foundIndex = it!=nzInds.end();
73  if(it != nzInds.end()){
74  it->second = val;
75  }else{
76  nzInds[ind] = val;
77  }
78  } else {
79  foundIndex = nzInds.erase(ind) > 0;
80  }
81 
82 
83  // Update the total and maximum order values after updating multi index
84  totalOrder = 0;
85  maxValue = 0;
86 
87  for (const auto& value : nzInds){
88  totalOrder += value.second;
89  maxValue = std::max(maxValue, value.second);
90  }
91 
92  return foundIndex;
93  }
94 }
95 
96 unsigned int MultiIndex::NumNz() const
97 {
98  unsigned int numNz = 0;
99  for(auto& part : nzInds)
100  numNz += int(part.second > 0);
101 
102  return numNz;
103 }
104 
105 
106 unsigned MultiIndex::MultiIndex::GetValue(unsigned ind) const
107 {
108  if(ind>length){
109  throw std::out_of_range("Tried to access index " + std::to_string(ind) + " of a multiindex with only " + std::to_string(length) + " components.");
110  }else{
111  auto searchIter = nzInds.find(ind);
112  if(searchIter != nzInds.end()){
113  return searchIter->second;
114  }else{
115  return 0;
116  }
117  }
118 }
119 
120 
121 void MultiIndex::SetLength(unsigned newLength)
122 {
123  if(newLength > length){
124  length = newLength;
125  }else{
126 
127  auto it = nzInds.begin();
128  while(it!= nzInds.end()){
129  if (it->first >= newLength) {
130  it = nzInds.erase(it);
131  } else {
132  it++;
133  }
134  }
135 
136  // Update the stored summaries
137  length = newLength;
138  maxValue = 0;
139  totalOrder = 0;
140  for(auto it = nzInds.begin(); it!=nzInds.end(); ++it){
141  maxValue = std::max(maxValue, it->second);
142  totalOrder += it->second;
143  }
144 
145  }
146 }
147 
148 bool MultiIndex::operator!=(const MultiIndex &b) const{
149 
150  if( (b.length != length) || (b.maxValue != maxValue) || (b.totalOrder != totalOrder))
151  return true;
152 
153  if(b.nzInds.size() != nzInds.size())
154  return true;
155 
156  // Loop through the nonzero indices
157  auto bit = b.nzInds.begin();
158  auto it = nzInds.begin();
159  for(; it!=nzInds.end(); ++it){
160  if(it->first != bit->first)
161  return true;
162  if(it->second != bit->second)
163  return true;
164  bit++;
165  }
166 
167  return false;
168 }
169 
170 bool MultiIndex::operator==(const MultiIndex &b) const{
171  return !( *this != b);
172 }
173 
174 bool MultiIndex::operator>(const MultiIndex &b) const{
175  return b<(*this);
176 }
177 
178 bool MultiIndex::operator<(const MultiIndex &b) const{
179 
180  if(totalOrder<b.totalOrder){
181  return true;
182  }else if(totalOrder>b.totalOrder){
183  return false;
184  }else if(maxValue<b.maxValue){
185  return true;
186  }else if(maxValue>b.maxValue){
187  return false;
188  }else{
189 
190  for(int i=0; i<std::min<unsigned>(length, b.length); ++i){
191  if(GetValue(i)<b.GetValue(i)){
192  return true;
193  }else if(GetValue(i)>b.GetValue(i)){
194  return false;
195  }
196  }
197 
198  // it should never get to this point unless the multiindices are equal
199  return false;
200  }
201 
202 }
203 
204 bool MultiIndex::operator>=(const MultiIndex &b) const{
205  return !(*this < b);
206 }
207 
208 bool MultiIndex::operator<=(const MultiIndex &b) const{
209  return !(*this > b);
210 }
211 
212 MultiIndex& MultiIndex::operator+=(const MultiIndex &b) {
213  for(int i=0; i<length; ++i){
214  SetValue(i, GetValue(i) + b.GetValue(i));
215  }
216  return *this;
217 }
218 
219 MultiIndex& MultiIndex::operator++() {
220  MultiIndex ones (this->GetLength(), 1);
221  return (*this)+=ones;
222 }
223 
224 MultiIndex MultiIndex::operator+(const MultiIndex &b) const{
225  MultiIndex ret(*this);
226  return ret += b;
227 }
228 
229 MultiIndex& MultiIndex::operator-=(const MultiIndex &b) {
230  for(int i=0; i<length; ++i){
231  unsigned diff = 0;
232  if (GetValue(i) > b.GetValue(i)) // Prevent "negative" unsigned result
233  diff = GetValue(i) - b.GetValue(i);
234  SetValue(i, diff);
235  }
236  return *this;
237 }
238 
239 MultiIndex& MultiIndex::operator--() {
240  MultiIndex ones (this->GetLength(), 1);
241  return (*this)-=ones;
242 }
243 
244 MultiIndex MultiIndex::operator-(const MultiIndex &b) const{
245  MultiIndex ret(*this);
246  return ret -= b;
247 }
248 
249 std::string MultiIndex::ToString() const {
250  std::string out;
251  for(int i=0; i<GetLength(); ++i){
252  if (i > 0)
253  out += " ";
254  out += std::to_string(GetValue(i));
255  }
256  return out;
257 }
258 
259 std::ostream& muq::Utilities::operator<< (std::ostream &out, const MultiIndex &ind)
260 {
261  out << ind.GetVector().transpose();
262  return out;
263 }
SumMean operator+(MeanType1 const &mu1, MeanType2 const &mu2)
std::shared_ptr< MultiIndexSet > operator+=(std::shared_ptr< MultiIndexSet > x, std::shared_ptr< MultiIndexSet > y)
int int FloatType value
Definition: json.h:15223
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition: json.h:3404
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition: json.h:25172